Skip to content

Instantly share code, notes, and snippets.

@scottlepp
Created December 15, 2017 15:40
Show Gist options
  • Save scottlepp/d27b274845f321b38a8ef8f24d71d3f4 to your computer and use it in GitHub Desktop.
Save scottlepp/d27b274845f321b38a8ef8f24d71d3f4 to your computer and use it in GitHub Desktop.
Track Login Event
function getBrowser() {
"use strict";
var tem, ua = navigator.userAgent,
M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
return /trident/i.test(M[1]) ? (tem = /\brv[ :]+(\d+)/g.exec(ua) || [], "IE " + (tem[1] || "")) : "Chrome" === M[1] && (tem = ua.match(/\bOPR\/(\d+)/), null !== tem) ? "Opera " + tem[1] : (M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, "-?"], null !== (tem = ua.match(/version\/(\d+)/i)) && M.splice(1, 1, tem[1]), {
name: M[0],
version: M[1]
})
}
var vs;
! function(t) {
var n;
! function(t) {
"use strict";
var n = function() {
function t(t) {
t.debugEnabled(!0)
}
return t.$inject = ["$logProvider"], t
}();
t.Config = n
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
"use strict";
var n = function() {
function t(t) {
t.debug("runBlock end")
}
return t.$inject = ["$log"], t
}();
t.RunBlock = n
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools", []).config(t.Config).run(t.RunBlock).constant("config", config)
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.appearance", [])
}(n = t.appearance || (t.appearance = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {})), angular.module("vs.tools.appearance").factory("appearanceResource", ["$http", "$q", function(t, n) {
"use strict";
function r() {
return t.get(e).then(function(t) {
return t.data
}, function(t) {
return console.log(t), t
})
}
function o(n) {
return t.post(s, {
docActions: n
}).then(function(t) {
return t
}, function(t) {
return console.log(t), t
})
}
var e = config.root + "api/rest/appearance",
s = config.root + "api/rest/appearance/actions";
return {
fetch: function() {
return r()
},
saveActions: function(t) {
return o(t)
}
}
}]);
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.catalog", [])
}(n = t.catalog || (t.catalog = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {})), angular.module("vs.tools.catalog").factory("catalogResource", ["$http", "$q", function(t, n) {
"use strict";
function r() {
return t.get(e).then(function(t) {
return t.data.servers
}, function(t) {
return console.log(t), t
})
}
function o(o) {
return r().then(function(r) {
var o = [];
return r.forEach(function(n) {
if (angular.isDefined(n.url)) {
var r = n.url + s,
e = t.get(r, {
withCredentials: !1
}).then(function(t) {
return t
});
o.push(e)
}
}), n.all(o).then(function(t) {
return t
}, function(t) {
return t
})
})
}
var e = config.root + "api/rest/index/config/federation.json",
s = "api/rest/i18n/field/location.json";
return {
fetch: r,
loadRemoteLocations: o
}
}]);
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.displayConfig", [])
}(n = t.displayConfig || (t.displayConfig = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {})), angular.module("vs.tools.displayConfig").factory("displayConfigResource", ["$http", function(t) {
"use strict";
function n() {
var t = i + "list";
return t += "?rand=" + Math.random()
}
function r(t) {
var n = i + t;
return n += "?rand=" + Math.random()
}
function o() {
return t.get(n()).then(function(t) {
return t
}, function(t) {
return console.log(t), t
})
}
function e(n) {
return t.get(r(n)).then(function(t) {
return t
}, function(t) {
return console.log(t), t
})
}
function s(n) {
return t.delete(r(n)).then(function(t) {
return t
}, function(t) {
return console.log(t), t
})
}
function a(n) {
return t.post(i, n).then(function(t) {
return t
}, function(t) {
return console.log(t), t
})
}
var i = config.root + "api/rest/display/config/";
return {
getDisplayConfigs: function() {
return o()
},
getDisplayConfig: function(t) {
return e(t)
},
deleteDisplayConfig: function(t) {
return s(t)
},
saveDisplayConfig: function(t) {
return a(t)
}
}
}]);
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
var n = function() {
function t(t, n) {
this.config = t, this.$http = n
}
return t.isString = function(t) {
return "string" == typeof t || t instanceof String
}, t.getInstance = function(n, r) {
return new t(n, r)
}, t.prototype.toMap = function(t, n) {
var r = {};
return n.forEach(function(n) {
r[n[t]] = n
}), r
}, t.prototype.toStringMap = function(t) {
var n = {};
return t.forEach(function(t) {
n[t] = t
}), n
}, t.prototype.pluck = function(t, n, r) {
var o = [];
return t.forEach(function(t) {
r && r(t) ? o.push(t[n]) : angular.isUndefined(r) && o.push(t[n])
}), o
}, t.prototype.postForm = function(t, n) {
var r = this.config.root + t;
return this.$http({
method: "POST",
url: r,
data: n,
withCredentials: !0,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
}, t.prototype.parseQueryString = function(t) {
var n, r = t.slice(1).split("&"),
o = {};
return r.forEach(function(t) {
n = t.split("="), o[n[0]] = decodeURIComponent(n[1] || "")
}), JSON.parse(JSON.stringify(o))
}, t.prototype.postJson = function(t, n, r) {
return this.$http({
method: "POST",
url: config.root + "api/rest/" + n + "/" + r + ".json",
data: t,
headers: {
"Content-Type": "application/json"
}
})
}, t
}();
t.Sugar = n
}(n = t.util || (t.util = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
var n = function() {
function t(t) {
var n = this;
this.sugar = t, this.fetch = function(r) {
var o = r || "name,stype,category,docs,disp_en,sortable,filterable,tableable,displayable,editable";
return t.postForm("solr/fields/select?rand=" + Math.random(), n.getFieldsParams(o)).then(function(t) {
return n.ensureTagsFieldExist(t.data.response.docs), t.data.response.docs
})
}, this.ensureTagsFieldExist = function(t) {
for (var n = !1, r = t.length - 1; r >= 0; r--)
if ("tag_tags" === t[r].name) {
n = !0;
break
}
n || t.push({
category: "TEXT",
disp_en: "Tags",
displayable: !0,
docs: 0,
filterable: !0,
name: "tag_tags",
sortable: !1,
stype: "string",
tableable: !1
})
}, this.fetchHydrationStats = function(r) {
return n.fetch().then(function(o) {
var e = t.pluck(o, "name", function(t) {
return 0 !== t.name.indexOf("_") && t.docs > 0
});
return t.postForm("solr/v0/select?" + r, n.getStatsParams(e)).then(function(t) {
var r = t.data.facet_counts.facet_fields,
e = t.data.response.numFound;
return n.applyHydration(r, o, e), o
})
})
}
}
return t.$inject = ["sugar"], t.prototype.getFieldsParams = function(t) {
return "q=*:*&fl=" + t + "&rows=100000&sort=name%20asc&wt=json&rand=" + Math.random()
}, t.prototype.getStatsParams = function(t) {
return "facet=true&facet.limit=100000&facet.mincount=100&rows=0&wt=json&facet.field=" + t.join("&facet.field=") + "&rand=" + Math.random()
}, t.prototype.applyHydration = function(t, n, r) {
for (var o, e, s = 0; s < n.length; s++) o = t[n[s].name], o && o.length > 0 && (n[s].id = n[s].name, e = this.getCount(o), n[s].hydration = e / r * 100);
return s
}, t.prototype.getCount = function(t) {
for (var n = 0, r = 1; r < t.length; r += 2) n += t[r];
return n
}, t.refName = "fieldsResource", t
}();
t.FieldsResource = n
}(n = t.fields || (t.fields = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.fields", ["vs.tools.util"]).service(t.FieldsResource.refName, t.FieldsResource)
}(n = t.fields || (t.fields = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.filters", []).filter("replaceString", function() {
return function(t, n, r) {
return t.replace(new RegExp(n, "g"), r)
}
})
}(n = t.filters || (t.filters = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.savedSearch", ["vs.tools.util"])
}(n = t.savedSearch || (t.savedSearch = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {})), angular.module("vs.tools.savedSearch").factory("savedSearchResource", ["$http", "sugar", function(t, n) {
"use strict";
function r(t) {
return n.postJson(t, "display", "ssearch")
}
function o(t) {
var n = 150,
r = config.root + "solr/ssearch/select?";
return r += "rows=" + n + "&rand=" + Math.random(), r += "&fl=id,title,description,owner,path,share,query,config,order,saved,private,view,_version_,config_title:[configTitle],param*,labels,display_override", r += "&wt=json&json.wrf=JSON_CALLBACK", angular.isDefined(t) && (r += "&fq=id:" + t), r
}
function e(n) {
return t.jsonp(o(n)).then(function(t) {
return t.data.response.docs
}, function(t) {
return console.log(t), t
})
}
return {
getSavedSearches: function() {
return e()
},
fetch: function(t) {
return e(t).then(function(t) {
return t[0]
})
},
saveSearch: function(t, n) {
return r(t)
},
deleteSearch: function(n) {
return t.delete(config.root + "api/rest/display/ssearch/" + n).then(function() {})
},
wipe: function() {
return t.delete(config.root + "api/rest/display/ssearch/wipe")
},
restore: function() {
return n.postForm("api/rest/display/restore", "")
},
order: function(t, n, r) {
var o = "";
null !== n && (o += "before=" + n), "" !== o && (o += "&"), null !== r && (o += "after=" + r)
},
fetchLabels: function() {
var n = config.root + "solr/ssearch/select?rows=0&facet=true&facet.field=labels&wt=json&r=" + (new Date).getTime();
return t.get(n).then(function(t) {
return t.data.facet_counts.facet_fields.labels
}, function() {
return []
})
}
}
}]);
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
var n = function() {
function t(t, n, r) {
var o = this;
this.config = t, this.$http = n, this.$q = r, this.fields = null, this.removePrefixHash = {};
var e = ["fs_", "ft_", "fh_", "fi_", "fl_", "fd_", "ff_", "fu_", "fp_", "fy_", "fm_", "fb_", "tag_", "meta_", "fss_", "grp_"];
e.forEach(function(t) {
o.removePrefixHash[t] = !0;
var n = t.substring(1, 2),
r = t.replace("_", n + "_");
o.removePrefixHash[r] = !0
})
}
return t.$inject = ["config", "$http", "$q"], t.prototype.load = function() {
var t = this,
n = this.config.root + "api/rest/i18n/fields/standard.json";
return this.fields ? this.$q.when() : this.$http.get(n).then(function(n) {
return t.fields = n.data, n.data
})
}, t.prototype.translateField = function(t) {
var n = t.indexOf("_");
if (n > -1) {
var r = t.substring(0, n + 1);
this.removePrefixHash[r] && (t = t.replace(r, ""))
}
var o = this.fields.FIELD[t];
return angular.isDefined(o) ? o : this.classify(t)
}, t.prototype.classify = function(t) {
return t = t.replace(/_/g, " "), t.replace(/\w\S*/g, function(t) {
return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase()
})
}, t
}();
t.Translator = n
}(n = t.translate || (t.translate = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.translate", []).factory("translator", ["config", "$http", "$q", function(n, r, o) {
return new t.Translator(n, r, o)
}]).constant("config", config)
}(n = t.translate || (t.translate = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var vs;
! function(t) {
var n;
! function(t) {
var n;
! function(t) {
"use strict";
angular.module("vs.tools.util", []).factory("sugar", ["config", "$http", function(n, r) {
return t.Sugar.getInstance(n, r)
}])
}(n = t.util || (t.util = {}))
}(n = t.tools || (t.tools = {}))
}(vs || (vs = {}));
var browser = getBrowser();
if ("IE" === browser.name || "MSIE" === browser.name) {
var globalHtml = $("html"),
version = parseInt(browser.version);
version < 9 && globalHtml.addClass("lt-ie9"), version < 8 && globalHtml.addClass("lt-ie8"), version < 7 && globalHtml.addClass("lt-ie7")
}
angular.element(document).ready(function() {
"use strict";
var slash = config.root.charAt(config.root.length - 1);
if ("/" !== slash) return void alert(NaN)
}), angular.module("portalApp", ["ngResource", "ngSanitize", "ngTable", "ngTableResizableColumns", "ngAria", "angularSpinner", "ui.router", "ui.bootstrap", "ui.slider", "ui.select2", "ui.sortable", "LocalStorageModule", "cart", "taskRunner", "voyager.config", "voyager.security", "voyager.filters", "voyager.map", "voyager.util", "voyager.modal", "voyager.layout", "voyager.home", "voyager.search", "voyager.results", "voyager.details", "voyager.tagging", "voyager.component", "tree.directive", "angulartics", "angulartics.google.analytics", "voyager.common.featured"]).factory("httpRequestInterceptor", function($analytics, $injector, $q, $log) {
"use strict";
return {
response: function(response) {
var err = response.headers("x-access-token-error");
if (!_.isEmpty(err)) {
$log.error("Error with JWT Token", err);
var $state = $injector.get("$state");
$state.go("login")
}
return response
},
responseError: function(response) {
if (419 === response.status) {
$log.error("token timed out");
var $state = $injector.get("$state");
$state.go("login")
} else {
var url = "unknown";
response.config && (url = response.config.url), $analytics.eventTrack("error", {
category: "http",
label: url,
value: response.status
})
}
return $q.reject(response)
}
}
}), angular.module("portalApp").config(function($stateProvider, $httpProvider, $urlRouterProvider, $analyticsProvider, $locationProvider, $logProvider, toastrConfig) {
"use strict";
function _loadIfAllowed(authService, $q, configLoader, $location) {
return authService.getPrivileges().then(function() {
return authService.hasPermission("view") ? configLoader.load($location.search().disp, $location.search().all) : $q.reject("Not Authorized")
})
}
function _canProcess(authService, $q) {
return authService.getPrivileges().then(function() {
return authService.hasPermission("process") ? $q.when({}) : $q.reject("Not Authorized")
})
}
$locationProvider.html5Mode(!0), $logProvider.debugEnabled(!1), $stateProvider.state("search", {
url: "/search?fq&q&vw&place",
reloadOnSearch: !1,
views: {
"": {
templateUrl: "src/search/search.html"
},
"filters@search": {
templateUrl: "src/filters/filters.html",
controller: "FiltersCtrl"
},
"card-results@search": {
templateUrl: "src/results/card-results.html"
},
"table-results@search": {
templateUrl: "src/results/table-results.html"
},
"grid-results@search": {
templateUrl: "src/results/grid-results.html"
},
"selected-filters@search": {
templateUrl: "src/filters/selected-filters.html",
controller: "SelectedFiltersCtrl"
}
},
resolve: {
load: function(configLoader, $location, $q, authService) {
return _loadIfAllowed(authService, $q, configLoader, $location)
}
}
}).state("home", {
url: "/home",
templateUrl: "src/home/home.html",
resolve: {
load: function(configLoader, $location, $q, authService) {
return config.homepage.showHomepage === !0 ? _loadIfAllowed(authService, $q, configLoader, $location) : $q.reject("Not Visible")
}
}
}).state("details", {
reloadOnSearch: !0,
url: "/show?id&disp&shard",
views: {
"": {
templateUrl: "src/details/details.html"
},
"preview@details": {
templateUrl: "src/details/preview.html"
}
},
resolve: {
load: function(detailConfig, $location, $q, authService) {
return _loadIfAllowed(authService, $q, detailConfig, $location)
}
}
}).state("login", {
url: "/login",
templateUrl: "common/security/login.html",
controller: "AuthPageCtrl",
resolve: {
load: function($q, authService) {
return authService.loadPrivileges()
}
}
}).state("queue", {
url: "/queue",
templateUrl: "src/cart/cart.html",
resolve: {
load: function($q, authService) {
return _canProcess(authService, $q)
}
}
}).state("tasks", {
url: "/tasks",
templateUrl: "src/taskrunner/tasks.html",
resolve: {
load: function($q, authService) {
return _canProcess(authService, $q)
}
}
}).state("task", {
url: "/task?type",
templateUrl: "src/taskrunner/task.html",
params: {
task: {},
type: ""
},
resolve: {
load: function($q, authService, configLoader, $location, translateService) {
return _canProcess(authService, $q).then(function() {
return configLoader.prepare().then(function() {
translateService.init()
})
})
}
}
}).state("history", {
url: "/history",
templateUrl: "src/jobs/view-jobs.html",
resolve: {
load: function($q, authService) {
return _canProcess(authService, $q)
}
}
}).state("status", {
url: "/status?id",
templateUrl: "src/taskrunner/status.html",
resolve: {
load: function($q, authService) {
return _canProcess(authService, $q)
}
}
}).state("chart", {
url: "/chart",
templateUrl: "src/chart/chart.html"
}).state("links", {
url: "/links?page",
templateUrl: "src/bot/bot-page.html"
}), $urlRouterProvider.otherwise(function($injector) {
$injector.invoke(function($state, config) {
config.homepage.showHomepage === !0 ? $state.go("home") : $state.go("search")
})
}), $httpProvider.defaults.withCredentials = !0, $httpProvider.interceptors.push("httpRequestInterceptor"), $analyticsProvider.registerPageTrack(function() {
window.piTracker && window.piTracker()
}), $analyticsProvider.registerEventTrack(function(action, properties) {
if (config.trackAnalytics) {
properties.action = action;
var analyticsUrl = config.root + "api/rest/analytics/track";
$.ajax({
type: "POST",
url: analyticsUrl,
data: JSON.stringify(properties),
success: function() {},
contentType: "application/json",
dataType: "json"
})
}
}), angular.extend(toastrConfig, {
closeButton: !0,
positionClass: "toast-top-center",
allowHtml: !0
})
}).constant("config", config), angular.module("portalApp").run(function($rootScope, $location, authService, $state, config, $timeout) {
"use strict";
_.mixin(_.str.exports()), _.isEmpty(config.homepage.bannerHTML) || ($rootScope.hasBanner = !0, $rootScope.banner = config.homepage.bannerHTML, $timeout(function() {
var $topBanner = $("#top-banner");
$topBanner.height($topBanner.children(":first").height())
})), "true" === $location.search().widget && ($rootScope.isWidget = !0), $rootScope.title = config.title, $rootScope.footer = config.homepage.footerHTML, 0 !== $rootScope.footer.indexOf("<li>") && ($rootScope.footer = "<li>" + $rootScope.footer + "</li>"), $rootScope.$on("searchEvent", function(event, args) {
$rootScope.$broadcast("doSearch", args)
}), $rootScope.$on("bboxChangeEvent", function(event, args) {
$rootScope.$broadcast("updateBBox", args)
}), $rootScope.$on("saveSearchSuccess", function(event, args) {
$rootScope.$broadcast("updateSearchSaveStatus", args)
}), $rootScope.$on("filterEvent", function(event, args) {
$rootScope.$broadcast("filterChanged", args)
}), $rootScope.$on("removeFilterEvent", function(event, args) {
$rootScope.$broadcast("removeFilter", args)
}), $rootScope.$on("clearSearchEvent", function(event, args) {
$rootScope.$broadcast("clearSearch", args)
}), $rootScope.$on("clearBboxEvent", function(event, args) {
$rootScope.$broadcast("clearBbox", args)
}), $rootScope.$on("changeViewEvent", function(event, args) {
$rootScope.$broadcast("changeView", args)
}), $rootScope.$on("searchComplete", function(event, args) {
$rootScope.$broadcast("searchResults", args)
}), $rootScope.$on("addAllToCartEvent", function(event, args) {
$rootScope.$broadcast("addAllToCart", args)
}), $rootScope.$on("removeAllCartEvent", function(event, args) {
$rootScope.$broadcast("removeAllCart", args)
}), $rootScope.$on("resultHoverEvent", function(event, args) {
$rootScope.$broadcast("resultHover", args)
}), $rootScope.$on("searchDrawingTypeChanged", function(event, args) {
$rootScope.$broadcast("updateDrawingTool", args)
}), $rootScope.$on("drawingToolChanged", function(event, args) {
$rootScope.$broadcast("updateSearchDrawingType", args)
}), $rootScope.$on("searchTypeChanged", function(event, args) {
$rootScope.$broadcast("updateSearchType", args)
}), $rootScope.$on("selectedDrawingTypeChanged", function(event, args) {
$rootScope.$broadcast("drawingTypeChanged", args)
}), $rootScope.$on("$stateChangeError", function(e, toState, toParams, fromState, fromParams, error) {
"Not Authorized" === error ? $state.go("login") : "Not Visible" === error ? $state.go("search") : "bot" === error && $state.go("bot")
}), $rootScope.$on("taskStatusEvent", function(event, args) {
$rootScope.$broadcast("taskStatusChanged", args)
}), $rootScope.$on("expandedQueryToggle", function(event, args) {
$rootScope.$broadcast("expandedQueryToggled", args)
}), L.Icon.Default.imagePath = "assets/img"
}), angular.module("voyager.util", []), angular.module("voyager.util").factory("loading", function($timeout) {
"use strict";
var spinner, isLoading = !1,
delayedShow = function(element) {
if (isLoading && !spinner) {
spinner = new Spinner({
radius: 3
}).spin();
var indicatorDiv = $(element);
indicatorDiv.append(spinner.el)
}
};
return {
show: function(element) {
isLoading = !0, $timeout(function() {
delayedShow(element)
}, 250)
},
done: function() {
isLoading = !1, spinner && (spinner.stop(), spinner = null)
}
}
}), angular.module("voyager.util").factory("sugar", function($http) {
"use strict";
function _convertExtent(val) {
if (val.indexOf("bbox") >= 0) {
val = val.replace(/["\)]/g, "");
var bboxInfo = val.split("("),
mode = bboxInfo[0].replace("Is", "").toUpperCase();
mode = mode.replace("BBOX:", "");
var bbox = bboxInfo[1];
return "bbox=" + bbox + "/bbox.mode=" + mode
}
return val
}
function _cleanSlash(val) {
var newVal = val.replace(/\\/g, "");
return newVal = newVal.replace(/\//g, "\\/"), newVal = _convertExtent(newVal)
}
function _removeFunk(params) {
angular.isDefined(params.fq) && (angular.isArray(params.fq) ? $.each(params.fq, function(index, value) {
params.fq[index] = _cleanSlash(value)
}) : params.fq = _cleanSlash(params.fq))
}
function _separateOr(value) {
var separated = value.substring(value.indexOf("}") + 1),
sep = "",
parenStart = separated.indexOf("(");
if (parenStart !== -1) {
var filter = separated.substring(0, parenStart),
facets = separated.substring(parenStart + 1, separated.indexOf(")"));
facets = facets.split(" "), separated = "", _.each(facets, function(val) {
separated += sep + filter + val, sep = "&fq="
})
}
return separated
}
function _loadMapItem(mapList, key, item) {
var mapItem = mapList[key];
void 0 === mapItem && (mapItem = {
key: key,
list: []
}), mapItem.list.push(item), mapList[key] = mapItem
}
function _safeUrlEncode(string) {
return string.indexOf("%") === -1 ? encodeURIComponent(string) : string
}
var DATE_REGEX = new RegExp("^\\d{4}(-\\d{2}){2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,3})?)?Z$", "i");
return {
retroParams: function(params) {
_removeFunk(params);
var retro = $.param(params, !0);
return retro = retro.replace(/\+/g, " "), retro = retro.replace(/ /g, "%20"), retro = retro.replace(/\\/g, ""), retro = retro.replace(/&/g, "/"), retro = retro.replace(/%3A/g, ":"), retro = retro.replace(/%5C%2F/g, "%252F"), retro = retro.replace(/fq=/g, "f."), retro = retro.replace(/path_path/g, "path"), retro = retro.replace("f.path", "path"), retro = retro.replace("f.bbox", "bbox"), retro = retro.replace("shard", "catalog"), retro = retro.replace(/:/g, "="), retro = retro.replace("*=*", "*:*")
},
bytesToSize: function(bytes) {
var sizes = ["Bytes", "KB", "MB", "GB", "TB"];
if (0 === bytes) return "0 Bytes";
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + " " + sizes[i]
},
isDate: function(input) {
return !isNaN(new Date(input).getDate()) && DATE_REGEX.test(input)
},
toArray: function(val) {
return "string" == typeof val ? [val] : _.isUndefined(val) ? [] : val.slice()
},
toMap: function(key, array) {
var map = {};
return $.each(array, function(index, value) {
map[value[key]] = value
}), map
},
toMapList: function(key, sourceList) {
var listItem, mapList = {};
return sourceList.forEach(function(item) {
listItem = item[key], void 0 !== listItem && (Array.isArray(listItem) ? item[key].forEach(function(sub) {
_loadMapItem(mapList, sub, item)
}) : _loadMapItem(mapList, listItem, item))
}), mapList
},
hasField: function(list, field) {
var has = !1;
return $.each(list, function(index, item) {
return has = angular.isDefined(item[field]), !has
}), has
},
trim: function(val, toTrim) {
return val.lastIndexOf(toTrim) === val.length - 1 && (val = val.substring(0, val.length - 1)), 0 === val.indexOf(toTrim) && (val = val.substring(1)), val
},
getIndex: function(array, val) {
var i = 0;
for (i; i < array.length; i++)
if (array[i].indexOf(val) > -1) return i;
return -1
},
toQueryString: function(params) {
var queryString = "",
sep = "";
return $.each(params, function(key, value) {
$.isArray(value) ? $.each(value, function(index, val) {
queryString += sep + key + "=" + val, sep = "&"
}) : ("q" === key && value.indexOf("id:") === -1 && (value = _safeUrlEncode(value)), queryString += sep + key + "=" + value, sep = "&")
}), queryString
},
toQueryStringEncoded: function(params) {
var queryString = "",
sep = "";
return $.each(params, function(key, value) {
$.isArray(value) ? $.each(value, function(index, val) {
queryString += sep + key + "=" + _safeUrlEncode(val), sep = "&"
}) : (queryString += sep + key + "=" + _safeUrlEncode(value), sep = "&")
}), queryString
},
toNavigoQueryString: function(params) {
var filterValue, queryString = "",
sep = "";
return $.each(params, function(key, value) {
$.isArray(value) ? $.each(value, function(index, val) {
queryString += sep + key + "=" + val, sep = "&"
}) : (filterValue = value, filterValue.indexOf("{!tag=") !== -1 && (filterValue = _separateOr(filterValue)), queryString += sep + key + "=" + filterValue, sep = "&")
}), queryString
},
copy: function(value) {
return JSON.parse(JSON.stringify(value))
},
decodeParams: function(params) {
$.each(params, function(index, param) {
"string" == typeof param ? params[index] = decodeURIComponent(param) : $.each(param, function(index, value) {
param[index] = decodeURIComponent(value)
})
})
},
formatBBox: function(bbox) {
var bboxRange = bbox.split(" ");
return _.each(bboxRange, function(item, index) {
bboxRange[index] = Number(item).toFixed(2)
}), bboxRange.join(" ")
},
postJson: function(request, api, action) {
return $http({
method: "POST",
url: config.root + "api/rest/" + api + "/" + action + ".json",
data: request,
headers: {
"Content-Type": "application/json"
}
})
},
postForm: function(url, data) {
var service = config.root + url,
headerConfig = {
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
}
};
return $http.post(service, data, headerConfig)
},
canOpen: function(doc) {
return 0 === doc.download.indexOf("file:") || "Service" === doc.format_type || "Server" === doc.format_type || "Map" === doc.format_type || "Application" === doc.format_type
},
paramDelimiter: function(url) {
var sep = "?";
return url.indexOf("?") !== -1 && (sep = "&"), sep
},
isValidDate: function(dateString) {
var regEx = /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d)/;
return null !== dateString.match(regEx)
},
contains: function(check, value) {
return check.indexOf(value) > -1
},
containsAny: function(check, values) {
for (var contains = !1, i = 0; i < values.length && !(contains = check.indexOf(values[i]) > -1); i++);
return contains
},
mapToList: function(map) {
var list = [];
return Object.keys(map).forEach(function(key) {
list.push(map[key])
}), list
},
toGroupedList: function(key, list) {
var categoryMap = this.toMapList(key, list);
return this.mapToList(categoryMap)
},
isUrl: function(string) {
var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
return regexp.test(string)
},
safeUrlEncode: function(string) {
return _safeUrlEncode(string)
},
removeDoubleQuotes: function(query) {
angular.isDefined(query.fq) && (_.isArray(query.fq) ? _.each(query.fq, function(value, index) {
query.fq[index] = value.replace(/"/g, "")
}) : query.fq = query.fq.replace(/"/g, ""))
}
}
}), angular.module("voyager.util").factory("converter", function($q, config, sugar) {
"use strict";
function getPolygon(west, north, east, south) {
var wkt = "POLYGON ((" + west + " " + north + ", " + east + " " + north + ", " + east + " " + south + ", " + west + " " + south + ", " + west + " " + north + "))";
return wkt
}
function toPolygon(bbox) {
var coords = bbox.split(" ");
return getPolygon(coords[0], coords[3], coords[2], coords[1])
}
function _mercatorToLatLon(mercX, mercY) {
var rMajor = 6378137,
shift = Math.PI * rMajor,
lon = mercX / shift * 180,
lat = mercY / shift * 180;
return lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2), [lat, lon]
}
function _getGeometries(extent) {
var geometries = [];
return geometries.push({
x: extent.xmin,
y: extent.ymin
}), geometries.push({
x: extent.xmax,
y: extent.ymax
}), geometries
}
function _solrReady(name) {
if (0 === name.indexOf("(") && name.indexOf(")") === name.length - 1) {
name = name.replace(" )", ")").replace(")", "").replace("(", "");
var facets = name.split(" ");
name = "(", facets.forEach(function(facet) {
name += _solrReady(facet) + " "
}), name += ")", name = name.replace(" )", ")")
} else name.indexOf("\\") === -1 && (name = name.replace(/[\s\/\+\-!\(\){}\^"~*?:]|&&|\|\|/g, "\\$&"));
return name
}
function _toClassic(params, from, to) {
var converted = "";
if (angular.isDefined(params[from])) {
var f, filter, filterValue, pArr = sugar.toArray(params[from]);
"shards" === from && (pArr = params[from].split(",")), $.each(pArr, function(index, value) {
to.indexOf("links.") > -1 ? converted += "/" + to + "=" + encodeURIComponent(encodeURIComponent(value)) : value.indexOf(":") !== -1 ? (f = value.split(":"), filter = f[0], filterValue = f[1], f.length > 2 && (f.splice(0, 1), filterValue = f.join(":")), filterValue = filterValue.replace(/\\/g, ""), converted += "/" + to + "." + filter + "=" + encodeURIComponent(encodeURIComponent(filterValue))) : ("bbox.mode" === to && (value = "w" === value ? "WITHIN" : "INTERSECTS"), converted += "/" + to + "=" + value)
})
}
return converted
}
return {
toPolygon: function(bbox) {
return toPolygon(bbox)
},
toWebMercator: function(extent, spatialReference) {
var geometries = _getGeometries(extent),
svc = config.arcGisRoot + "rest/services/Geometry/GeometryServer/project?";
svc += "inSR=" + spatialReference.wkid, svc += "&outSR=102100", svc += '&geometries={"geometryType":"esriGeometryPoint","geometries":' + JSON.stringify(geometries) + "}";
var deferred = $q.defer();
if (102100 !== spatialReference.wkid && 102113 !== spatialReference.wkid) $.getJSON(svc + "&f=json&callback=?", function(data) {
var bounds = [_mercatorToLatLon(data.geometries[0].x, data.geometries[0].y), _mercatorToLatLon(data.geometries[1].x, data.geometries[1].y)];
deferred.resolve(bounds)
});
else {
var bounds = [_mercatorToLatLon(geometries[0].x, geometries[0].y), _mercatorToLatLon(geometries[1].x, geometries[1].y)];
deferred.resolve(bounds)
}
return deferred.promise
},
toLatLng: function(extent, spatialReference) {
var geometries = _getGeometries(extent),
svc = config.arcGisRoot + "rest/services/Geometry/GeometryServer/project?";
svc += "inSR=" + spatialReference.wkid, svc += "&outSR=4326", svc += '&geometries={"geometryType":"esriGeometryPoint","geometries":' + JSON.stringify(geometries) + "}";
var deferred = $q.defer();
if (4326 !== spatialReference.wkid && 4269 !== spatialReference.wkid) $.getJSON(svc + "&f=json&callback=?", function(data) {
var bounds = [
[data.geometries[0].x, data.geometries[0].y],
[data.geometries[1].x, data.geometries[1].y]
];
deferred.resolve(bounds)
});
else {
var bounds = [
[geometries[0].x, geometries[0].y],
[geometries[1].x, geometries[1].y]
];
deferred.resolve(bounds)
}
return deferred.promise
},
solrReady: function(value) {
return _solrReady(value)
},
toSolrParams: function(filters) {
var name, fq = [],
orFilters = {};
return $.each(filters, function(index, facet) {
if (name = "" !== facet.filter ? _solrReady(facet.name) : facet.name, "CHECK" === facet.style) orFilters[facet.filter] ? orFilters[facet.filter].push(name) : orFilters[facet.filter] = [name];
else if ("RANGE" === facet.style || "STATS" === facet.style || "DATE" === facet.style)
if (facet.filter !== facet.name) fq.push(facet.filter + ":" + _solrReady(facet.name));
else if (facet.model) fq.push(facet.filter + ":[" + facet.model[0] + " TO " + facet.model[1] + "]");
else {
var filterValue = facet.humanized.substring(facet.humanized.indexOf(":") + 1);
fq.push(facet.filter + ":" + _solrReady(filterValue))
} else "" === facet.filter ? fq.push(name) : fq.push(facet.filter + ":" + _solrReady(name))
}), $.each(orFilters, function(name, orFilter) {
fq.push("{!tag=" + name + "}" + name + ":(" + orFilter.join(" ") + ")")
}), "&" + sugar.toQueryStringEncoded({
fq: fq
})
},
toSolrQueryList: function(filters) {
var name, filterQuery = [],
orFilters = {};
return $.each(filters, function(index, facet) {
name = "" !== facet.filter ? _solrReady(facet.name) : facet.name, "CHECK" === facet.style ? orFilters[facet.filter] ? orFilters[facet.filter].push(name) : orFilters[facet.filter] = [name] : "RANGE" === facet.style || "STATS" === facet.style ? filterQuery.push(facet.filter + ":" + facet.name) : "" === facet.filter ? filterQuery.push(name) : filterQuery.push(facet.filter + ":" + name)
}), $.each(orFilters, function(name, orFilter) {
filterQuery.push("{!tag=" + name + "}" + name + ":(" + orFilter.join(" ") + ")")
}), filterQuery
},
toClassicParams: function(params, savedSearch) {
var voyagerParams = "";
return angular.isDefined(params.q) && (voyagerParams += savedSearch ? "/q=" + sugar.safeUrlEncode(params.q) : _toClassic(params, "q", "q")), voyagerParams += _toClassic(params, "fq", "f"), voyagerParams += _toClassic(params, "place", "place"), voyagerParams += _toClassic(params, "place.op", "place.op"), voyagerParams += _toClassic(params, "voyager.list", "voyager.list"), voyagerParams += _toClassic(params, "links.to", "links.to"), voyagerParams += _toClassic(params, "links.from", "links.from"), voyagerParams += _toClassic(params, "shards", "catalog"), angular.isDefined(params.view) && "card" !== params.view && (voyagerParams += "/view=" + params.view), angular.isDefined(params.sort) && (voyagerParams += "/sort=" + params.sort), angular.isDefined(params.sortdir) && "desc" === params.sortdir && (voyagerParams += "/sort.reverse=true"), voyagerParams
},
toIdTextArray: function(source) {
return source = source.replace(/ /g, "").split(","), _.transform(source, function(arr, val, idx) {
arr[idx] = {
id: val,
text: val
}
})
},
toPlaceFilter: function(params) {
var placeFq = "";
return angular.isDefined(params["place.op"]) && (placeFq += " place.op=" + params["place.op"], delete params["place.op"]), angular.isDefined(params["place.id"]) && (placeFq += " place.id=" + params["place.id"], delete params["place.id"]), placeFq = "{!" + placeFq + '}place:"' + params.place + '"', delete params.place, placeFq
}
}
}), angular.module("voyager.util").factory("queryBuilder", function(config, filterService, configService, sugar, catalogService, converter) {
function getActionFields() {
if (null !== actionFields) return actionFields;
var fields = [],
actions = config.docActions,
pos = -1,
fieldArr = [];
return actions.forEach(function(action) {
_.isString(action.visible) && (pos = action.visible.indexOf("doc."), pos > -1 && (fieldArr = action.visible.split("doc."), fieldArr.forEach(function(field) {
"" === field || sugar.containsAny(field, ["canCart", "isService", "hasDownload", "isEsriLayer"]) || fields.push(field.substring(0, field.indexOf(" ")))
})))
}), actionFields = fields.join(",")
}
function _convertPlaceFilter(params) {
var placeFilter = "";
return angular.isDefined(params.place) && (placeFilter = "&fq=" + converter.toPlaceFilter(params)), placeFilter
}
function _getRequestFields() {
var fields = STATIC_FIELDS;
return fields += configService.getSolrFields(), fields += getActionFields(),
configService.getTableFieldNames().length && (fields += "," + configService.getTableFieldNames().join(",")), fields = fields.replace(/, /g, ","), fields = _.indexBy(fields.split(",")), _.values(fields).join(",")
}
function _getFilters(placeFilter) {
var queryString = "";
return queryString += filterService.getFilterParams(), queryString += placeFilter
}
function build2(solrParams, page, itemsPerPage, sortDirection, sortField, disableJSONP) {
var placeFilter = "";
solrParams ? (delete solrParams.fq, placeFilter = _convertPlaceFilter(solrParams)) : solrParams = {}, angular.isDefined(solrParams.shards) && (solrParams.shards = catalogService.removeInvalid(solrParams.shards));
var queryString = config.root + selectPath;
queryString += "?" + sugar.toQueryString(solrParams);
var rows = 0;
if (page) {
var start = (page - 1) * itemsPerPage;
rows = itemsPerPage, queryString += "&start=" + start, queryString += "&fl=" + _getRequestFields()
}
return queryString += "&rows=" + rows, queryString += "&extent.bbox=true&block=false", queryString += _getFilters(placeFilter), angular.isDefined(configService.getConfigId()) && angular.isUndefined(solrParams["voyager.config.id"]) && (queryString += "&voyager.config.id=" + configService.getConfigId()), angular.isDefined(sortField) && (angular.isUndefined(sortDirection) && (sortDirection = angular.isDefined(config.defaultSortDirection) ? config.defaultSortDirection : "desc"), queryString += "&sort=" + sortField + " " + sortDirection), queryString += "&rand=" + Math.random(), queryString += "&wt=json", disableJSONP || (queryString += "&json.wrf=JSON_CALLBACK"), queryString
}
function buildByIds(ids) {
var queryString = config.root + selectPath + "?q=";
return queryString += "id:(", $.each(ids, function(index, id) {
queryString += " " + id
}), queryString += ")", queryString += "&fl=id,name:[name],thumb:[thumbURL],format:[format]&extent.bbox=true&rows=999999", queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _buildIdList(solrParams) {
var placeFilter = _convertPlaceFilter(solrParams);
delete solrParams.fq, angular.isDefined(solrParams.shards) && (solrParams.shards = catalogService.removeInvalid(solrParams.shards)), solrParams.q = getInput(solrParams.q);
var queryString = config.root + selectPath;
return queryString += "?" + sugar.toQueryString(solrParams), queryString += "&fl=id&rows=999999", queryString += _getFilters(placeFilter), queryString += "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _buildBboxList(solrParams) {
var placeFilter = _convertPlaceFilter(solrParams);
delete solrParams.fq, angular.isDefined(solrParams.shards) && (solrParams.shards = catalogService.removeInvalid(solrParams.shards)), solrParams.q = getInput(solrParams.q);
var queryString = config.root + selectPath;
return queryString += "?" + sugar.toQueryString(solrParams), queryString += "&fl=bbox,name,id&rows=" + config.markerLimit + "&fq=bbox:[-90,-180 TO 90,180]", queryString += _getFilters(placeFilter), queryString += "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
var actionFields = null,
selectPath = "solr/v0/select",
customFields = ["shards", "discoveryStatus"],
STATIC_FIELDS = "id,title, name:[name],format,abstract,fullpath:[absolute],absolute_path:[absolute],thumb:[thumbURL], path_to_thumb, subject,download:[downloadURL],format_type,bytes,modified,shard:[shard],bbox,geo:[geo],format_category, component_files, ags_fused_cache, linkcount__children, contains_name, wms_layer_name,tag_flags,hasMissingData,layerURL:[lyrURL]",
getFacetParams = function(field) {
var facetParams = "";
if (field && !($.inArray(field, customFields) >= 0)) {
var fieldConfig = _.find(config.settings.data.filters, function(filter) {
return filter.field === field
});
return angular.isDefined(fieldConfig.minCount) && (facetParams += "&f." + fieldConfig.field + ".facet.mincount=" + fieldConfig.minCount), angular.isDefined(fieldConfig.sort) && (facetParams += "&f." + fieldConfig.field + ".facet.sort=" + fieldConfig.sort), facetParams += "CHECK" === fieldConfig.style ? "&facet.field={!ex=" + field + "}" + field : "&facet.field=" + field
}
var filters = config.settings.data.filters;
return $.each(filters, function(index, filter) {
$.inArray(filter.field, customFields) >= 0 || (facetParams += "CHECK" === filter.style ? "&facet.field={!ex=" + filter.field + "}" + filter.field : "STATS" === filter.style ? "&facet.field=" + filter.field : "&facet.field=" + filter.field, angular.isDefined(filter.minCount) && (facetParams += "&f." + filter.field + ".facet.mincount=" + filter.minCount), angular.isDefined(filter.sort) && (facetParams += "&f." + filter.field + ".facet.sort=" + filter.sort))
}), facetParams
},
getInput = function(query) {
var input = "*:*";
return angular.isDefined(query) && (input = query), input
};
return {
doBuild2: function(params, page, itemsPerPage, sortDirection, sortField, disableJSONP) {
return build2(params, page, itemsPerPage, sortDirection, sortField, disableJSONP)
},
doByIds: function(ids) {
return buildByIds(ids)
},
buildAllFacets: function(params, field) {
var placeFilter = _convertPlaceFilter(params);
delete params.fq, delete params.sort, angular.isDefined(params.shards) && (params.shards = catalogService.removeInvalid(params.shards)), params.q = getInput(params.q);
var queryString = config.root + selectPath,
facetLimit = -1,
rows = 0;
queryString += "?" + sugar.toQueryString(params), queryString += "&rows=" + rows, queryString += "&facet=true&facet.mincount=1&facet.limit=" + facetLimit + getFacetParams(field);
var fieldConfig = _.find(config.settings.data.filters, function(filter) {
return filter.field === field
});
return "shards" !== field && (queryString += "CHECK" === fieldConfig.style ? "&facet.field={!ex=" + field + "}" + field : "&facet.field=" + field), queryString += _getFilters(placeFilter), queryString += "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
},
buildAllIds: function(params) {
return _buildIdList(params)
},
buildAllBboxes: function(params) {
return _buildBboxList(params)
},
buildBulkUpdaterUrl: function(url, params) {
var placeFilter = _convertPlaceFilter(params);
delete params.fq, delete params.sort, delete params.view, angular.isDefined(params.shards) && (params.shards = catalogService.removeInvalid(params.shards)), params.q = getInput(params.q);
var queryString = config.root + url,
rows = 999999;
return queryString += "?" + sugar.toQueryString(params), queryString += "&rows=" + rows, queryString += _getFilters(placeFilter), queryString += "&rand=" + Math.random(), queryString += "&wt=json"
},
buildEsriGeocodeServiceTestQuery: function() {
return config.root + selectPath + "?" + $.param({
wt: "json",
"json.wrf": "JSON_CALLBACK",
rows: 0,
place: "california",
"place.finder": "esri"
})
},
buildFacetParams: function(field) {
return getFacetParams(field)
}
}
}), angular.module("voyager.util").factory("translateService", function($log) {
"use strict";
function _init() {
try {
field_names = config.fields.data.FIELD, field_descriptions = config.fields.data.FIELD_DESCR, file_formats = config.fileFormats.data.VALUE.format, locations = config.locations.data.VALUE.location, $.each(removePrefixList, function(index, item) {
removePrefixHash[item] = !0;
var c = item.substring(1, 2),
key = item.replace("_", c + "_");
removePrefixHash[key] = !0
})
} catch (err) {
$log.error(err)
}
}
var locations, file_formats = {
"text/calendar": "iCalendar",
"text/x-tcl": "Tcl script",
"text/x-prolog": "Prolog source code",
"application/vnd.ms-excel.template.macroenabled.12": "Office Open XML Workbook Template (macro-enabled)",
"image/x-vnd.vrt": "VRT",
"text/x-lex": "Lex/Flex source code",
"video/x-ms-wmv": "Windows Media Video",
"application/x-tika-java-web-archive": "Java Web Archive",
"image/x-rpf-combatc_50": "Combat Chart (1:50,000)",
"application/vnd.esri.connection.wms": "WMS Connection File",
"application/x-sharedlib": "Shared Library",
"application/vnd.esri.e00": "ESRI ArcInfo interchange file (E00)",
"application/x-arcgis-search-server": "ArcGIS Search Service (SearchServer)",
"application/x-tika-msoffice-embedded; format=ole10_native": "OLE10 Native Embedded Document",
"image/nitf": "National Imagery Transmission Format (NITF)",
"application/vnd.visio": "Microsoft Visio Diagram",
"application/fgdc+xml": "FGDC XML",
"image/x-vnd.kap": "BSB Charts",
"application/x-object": "X-Object",
"text/vnd.wap.wmlscript": "WML Script",
"text/x-haml": "HAML source code",
"application/vnd.ogc.wms_layer_xml": "WMS Layer",
"application/x-webservice-json": "JSON REST Web Service",
"application/javascript": "JavaScript Source Code",
"audio/x-aiff": "Audio Interchange File Format (AIFF)",
"image/x-rpf-tlm-50": "Topographic Line Map (1:50,000) (TLM_50)",
"image/x-rpf-cityg_15_500": "City Graphics (1:15,500)",
"application/xquery": "XQuery source code",
"application/x-arcgis-na-server": "ArcGIS Network Analysis Service (NASerice)",
"application/vnd.esri.connection.sde": "SDE Connection File",
"image/x-vnd.gsat": "GSat",
"application/x-font-adobe-metric": "Adobe Font Metric",
"application/xml+xsd": "XML Schema (XSD)",
"application/vnd.oasis.opendocument.spreadsheet-template": "OpenDocument v1.0: Spreadsheet document used as template",
"text/x-vbscript": "VBScript source code",
"image/x-ms-bmp": "Windows bitmap (BMP)",
"application/x-geocortex-server": "Geocortex Server",
"application/zip": "Compressed Archive File (ZIP)",
"image/x-rpf-cib10x": "CIB >10m (CIB10X)",
"application/vnd.esri.lyr": "ESRI Layer File",
"text/x-php": "PHP script",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Office Open XML Document",
"image/x-rpf-joga": "Joint Operations Graphic - Air (JOGA)",
"text/x-awk": "AWK script",
"application/rdf+xml": "XML syntax for RDF graphs (RDF/XML)",
"application/vnd.oasis.opendocument.text-web": "OpenDocument v1.0: Text document used as template for HTML documents",
"image/x-rpf-jogr": "Joint Operations Graphic - Radar (JOGR)",
"application/vnd.apple.iwork": "Apple IWork",
"application/x-tika-unix-dump": "Tika Coredump",
"image/x-rpf-tlm-25": "Topographic Line Map (1:25,000) (TLM_25)",
"image/x-rpf-tlm-24": "Topographic Line Map (1:24,000) (TLM_24)",
"text/css": "Cascading Style Sheet",
"text/csv": "Comma Separated Values (CSV)",
"application/x-sas": "SAS Program",
"application/x-gtar": "GNU tar Compressed File Archive (GNU Tape Archive)",
"image/jp2": "JPEG 2000 Part 1 (JP2)",
"image/x-rpf-tlm_other": "Topographic Line Map (other 1:50,000) (TLM_OTHER)",
"image/x-vnd.erdas_gis": "ERDAS 7.5 GIS",
"image/x-vnd.blx": "BLX",
"application/vnd.esri.gdb.file.data": "Data in a File Geodatabase (FileGDB Data)",
"audio/ogg": "Ogg Vorbis Codec Compressed WAV File",
"application/x-webservice": "Web Services",
"application/vnd.esri.gdb.personal": "Personal Geodatabase",
"application/xhtml+xml": "XHTML",
"image/x-vnd.bsq": "Arc/Info & Space Imaging BSQ",
"image/png": "Portable Network Graphics (PNG)",
"application/vnd.esri.diinfo": "Derived Image Info (DIInfo)",
"application/dita+xml; format=topic": "DITA Topic",
"text/x-pascal": "Pascal source code",
"model/iges": "Initial Graphics Exchange Specification Format (IGES)",
"text/x-objcsrc": "Objective-C source code",
"image/x-xbitmap": "X11 Bitmap Graphic",
"application/x-tika-msoffice-embedded; format=comp_obj": "CompObj OLE2 Embedded Document",
"video/mpeg": "MPEG Movie Clip",
"application/vnd.oasis.opendocument.image-template": "OpenDocument v1.0: Image document used as template",
"model/vnd.parasolid.transmit.binary": "Parasolid (Binary)",
"text/x-actionscript": "ActionScript source code",
"application/vnd.oasis.opendocument.image": "OpenDocument v1.0: Image document",
"application/dita+xml; format=concept": "DITA Concept Topic",
"application/bizagi-modeler": "BizAgi Process Modeler",
"application/x-tika-ooxml-protected": "Password Protected OOXML File",
"text/uri-list": "URI List",
"image/x-dted-level-1": "DTED Level 1",
"image/x-dted-level-0": "DTED Level 0",
"image/x-dted-level-3": "DTED Level 3",
"image/x-dted-level-2": "DTED Level 2",
"image/x-vnd.ndf": "NDF",
"image/x-xcf": "GIMP Image File",
"image/x-rpf-combatc_25": "Combat Chart (1:25,000)",
"application/vnd.esri.isdef": "Image Service Definition (ISDef)",
"application/vnd.voyager.testsuite": "Voyager test suite",
"image/x-vnd.bil": "ESRI binary interleaved format (BIL)",
"image/x-rpf-cityg_12_800": "City Graphics (1:12,800)",
"image/x-vnd.bip": "Arc/Info & Space Imaging BIP",
"application/x-msdownload": "Dynamic Link Library",
"text/x-scala": "Scala source code",
"image/x-rpf-tlm_200": "Topographic Line Map (1:200,000) (TLM_200)",
"image/x-rpf-cityg_10_560": "City Graphics (1:10,560)",
"image/x-rpf-combatc_10": "Combat Chart (1:10,000)",
"image/jpx": "JPEG 2000 Part 2 (JPX) (JP2)",
"text/x-vbdotnet": "VB.NET source code",
"image/x-vnd.ter": "Terragen Heightfield (TER)",
"application/vnd.esri.connection": "ESRI Connection File",
"application/x-dosexec": "DOS/Windows executable (EXE)",
"application/vnd.ms-xpsdocument": "XML Paper Specification (XPS)",
"application/rtf": "Rich Text Format File (RTF)",
"image/x-rpf": "Raster Product (RPF)",
"application/vnd.esri.gdb.personal.data": "Data in a Personal Geodatabase (Access Data)",
"application/vnd.esri.gp.toolbox": "GP Toolbox (TBX)",
"application/x-executable": "Executable",
"image/x-rpf-rm_50": "Riverine Map (1:50,000)",
"application/vnd.ms-powerpoint.presentation.macroenabled.12": "Office Open XML Presentation (macro-enabled)",
"image/x-rpf-tfc-day": "Transit Flying Chart (Day) (TFC_day)",
"video/quicktime": "Apple QuickTime Movie",
"application/x-arcgis-feature-server-layer": "ArcGIS FeatureService Layer",
"application/x-font-ttf": "TrueType Font (TTF)",
"application/x-netcdf": "Mastercam Numerical Control File",
"application/vnd.ogc.se_xml": "OGC Webservice Error",
"application/x-staroffice-template": "StarOffice Template",
"text/x-ocaml": "Ocaml source code",
"image/x-vnd.srtm_hgt": "SRTM HGT",
"text/x-modula": "Modula source code",
"text/x-vcard": "vCard",
"image/x-xpixmap": "X11 Pixmap Graphic",
"image/x-rpf-cityg_17_500": "City Graphics (1:17,500)",
"application/vnd.oasis.opendocument.text": "OpenDocument v1.0: Text document",
"application/ddms3.1+xml": "DDMS 3.1",
"image/x-rpf-hac": "Harbor and Approach Charts",
"application/vnd.microsoft.url": "Windows URL Shortcut",
"text/x-less": "LESS source code",
"application/vnd.esri.mxd": "ArcMap Document (MXD)",
"image/x-vnd.ers": "ER Mapper",
"application/vnd.ms-works": "Microsoft Works",
"image/x-vnd.pci.pix": "PCI Geomatics Database File",
"image/x-rpf-lfc-1": "Low Flying Chart 1 (LFC_1)",
"text/x-jsp": "Java Server Page (JSP)",
"application/x-fictionbook+xml": "FictionBook document",
"text/x-fortran": "Fortran source code",
"image/x-rpf-cib10": "CIB 10m (CIB10)",
"image/x-rpf-hfc": "High Flying Chart (HFC)",
"application/gpx+xml": "GPS eXchange Format (GPX)",
"image/x-rpf-lfc-4": "Low Flying Chart 4 (LFC_4)",
"image/x-rpf-lfc-5": "Low Flying Chart 5 (LFC_5)",
"model/vnd.collada+xml": "COLLADA",
"image/x-rpf-lfc-2": "Low Flying Chart 2 (LFC_2)",
"video/mp4": "MP4",
"image/x-rpf-lfc-3": "Low Flying Chart 3 (LFC_3)",
"application/x-gzip": "Gzip Compressed Archive",
"application/x-cpio": "UNIX CPIO Archive",
"model/x-sat": "Standard ACIS Text (SAT)",
"application/x-tika-ooxml": "Open Office XML Format",
"text/x-rst": "reStructuredText source code",
"application/dita+xml": "Darwin Information Typing Architecture",
"image/tiff": "Tagged Image File Format (TIFF)",
"image/x-rpf-lfc-night": "Low Flying Chart (night) (LFC_night)",
"application/dita+xml; format=map": "DITA Map",
"image/x-vnd.grib": "GRIB",
"application/mbox": "MBox - Mailbox Text Archive",
"image/vnd.dxf": "AutoCAD DXF",
"application/x-tika-msworks-spreadsheet": "MSWorks Spreadsheet",
"application/mathml+xml": "Math Markup Language",
"audio/x-wav": "WAVE Audio",
"image/x-vnd.intergraphcit": "Intergraph CIT",
"image/vnd.dwg": "AutoCad Drawing (DWG)",
"application/vnd.esri.gdb.sde": "SDE Geodatabase",
"text/x-sql": "SQL code",
"application/vnd.openxmlformats-officedocument.presentationml.template": "Office Open XML Presentation Template",
"image/x-rpf-tlm_100": "Topographic Line Map (1:100,000) (TLM_100)",
"application/vnd.esri.gdb.sde.data": "Data in an SDE (SDE Data)",
"image/svg+xml": "Scalable Vector Graphics (SVG)",
"application/java-vm": "Java class file",
"application/x-tar": "TAR Archive",
"image/x-vnd.intergraphcot": "Intergraph COT",
"text/x-erlang": "Erlang source code",
"image/jpeg": "Joint Photographic Experts Group (JPEG)",
"text/x-asciidoc": "Asciidoc source code",
"application/dita+xml; format=val": "DITA Conditional Processing Profile",
"image/x-raw-sony": "Sony raw image",
"application/x-ibooks+zip": "Apple iBooks Author publication format",
"application/vnd.apple.keynote": "Apple Keynote",
"image/x-rpf-vnc": "Visual Navigation Charts (VNC)",
"application/x-arcgis-map-server-layer": "ArcGIS Map Service Layer (MapService Layer)",
"image/x-rpf-mmc": "Miscellaneous Maps & Charts",
"text/x-clojure": "Clojure source code",
"text/tab-separated-values": "Tab Separated Values (TSV)",
"model/vnd.parasolid.transmit.text": "Parasolid (Text)",
"application/vnd.ms-powerpoint": "Microsoft Powerpoint Presentation",
"image/x-rpf-hrc": "Helicopter Route Chart (HRC)",
"application/x-arcgis-service": "ArcGIS Service",
"application/rss+xml": "RSS",
"application/json": "JSON",
"image/x-rpf-mim": "Military Installation Maps (MIM)",
"text/x-cgi": "CGI script",
"image/x-rpf-tfc-night": "Transit Flying Chart (Night) (TFC_night)",
"application/x-fme-server": "FME Server",
"application/msword": "Microsoft Word Document",
"video/x-flv": "Flash Video File",
"text/x-d": "D source code",
"application/iso19115+xml": "ISO 19115",
"application/epub+zip": "Electronic Publication (EPUB)",
"application/vnd.ms-excel.sheet.binary.macroenabled.12": "Microsoft Excel 2007 Binary Spreadsheet",
"application/vnd.ogc.csw_xml": "Catalog Service (CSW)",
"text/plain": "Plain Text",
"application/ddms5+xml": "DDMS 5.0",
"image/x-vnd.erdas_lan": "ERDAS 7.5 LAN",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Office Open XML Workbook",
"application/vnd.esri.sdc": "Smart Data Compression (SDC)",
"application/vnd.ms-powerpoint.addin.macroenabled.12": "Office Open XML Presentation Add-in (macro-enabled)",
"application/gsip+xml": "NMIS XML",
"application/vnd.esri.gdb.file": "File Geodatabase (FileGDB)",
"application/x-tika-java-enterprise-archive": "Java Enterprise Archive File",
"application/java-archive": "Java Archive",
"application/vnd.google-earth.kmz": "Keyhole Markup Language (KMZ)",
"application/vnd.oasis.opendocument.spreadsheet": "OpenDocument v1.0: Spreadsheet document",
"text/x-sed": "Sed code",
"application/x-tika-iworks-protected": "Password Protected iWorks File",
"text/x-ruby": "Ruby source code",
"text/x-haxe": "Haxe source code",
"application/x-fme-server-workspace": "FME Server Workspace",
"application/x-coredump": "Coredump",
"image/vnd.erdas.ecw": "ER Mapper ECW",
"text/troff": "Roff/nroff/troff/groff Unformatted Manual Page (UNIX)",
"image/x-rpf-nroac": "Naval Range Operating Area Chart",
"image/x-rpf-cibh": "CIB .5m",
"application/dita+xml; format=task": "DITA Task Topic",
"image/x-rpf-cityg_12_500": "City Graphics (1:12,500)",
"application/vnd.sun.xml.writer": "OpenOffice v1.0: Writer Document",
"application/x-arcgis-server": "ArcGIS Server",
"application/x-rpf-a-toc": "RPF Table Of Contents (A.TOC)",
"image/x-rpf-cib5": "CIB 5m",
"image/x-rpf-cib2": "CIB 2m",
"image/x-rpf-cib1": "CIB 1m",
"text/x-matlab": "Matlab source code",
"text/x-aspectj": "AspectJ source code",
"application/vnd.ms-project": "Microsoft Project",
"application/x-tika-msoffice-embedded": "MS Office Embedded",
"text/x-python": "Python script",
"image/x-vnd.jaxa": "JAXA",
"image/vnd.wap.wbmp": "Wireless Bitmap File Format",
"application/vnd.oasis.opendocument.presentation-template": "OpenDocument v1.0: Presentation document used as template",
"image/x-raw-panasonic": "Panasonic raw image",
"text/x-scheme": "Scheme source code",
"text/x-ml": "ML source code",
"text/vnd.iptc.anpa": "American Newspaper Publishers Association Wire Feeds (ANPA)",
"audio/mpeg": "MPEG-1 Audio Layer 3 (MP3)",
"text/x-perl": "Perl script",
"application/vnd.apple.webloc": "Mac OS X Website Location (Webloc)",
"application/vnd.esri.shapefile": "Shapefile (SHP)",
"text/x-coffeescript": "CoffeeScript source code",
"text/x-web-markdown": "Markdown source code",
"application/vnd.ms-word.document.macroenabled.12": "Office Open XML Document (macro-enabled)",
"model/x-step": "STEP",
"text/x-emacs-lisp": "Emacs Lisp source code",
"application/gsip3+xml": "NMIS 3.0",
"image/x-vnd.psi": "Pictometry Oblique Image (PSI)",
"video/x-m4v": "iTunes Video",
"application/vnd.google-earth.kml.object": "Object within KML (KML Object)",
"application/x-arcgis-globe-server": "ArcGIS Globe Service (GlobeService)",
"image/x-img": "Macintosh Disk Image (IMG)",
"application/vnd.oasis.opendocument.presentation": "OpenDocument v1.0: Presentation document",
"application/x-arcgis-geocode-server": "ArcGIS Geocode Service (GeocodeService)",
"application/x-arcgis-online": "ArcGIS Online Server",
"application/x-debian-package": "Debian Software Package",
"application/vnd.esri.rpdef": "Raster Process Definition (RPDef)",
"image/x-rpf-cityg_11_800": "City Graphics (1:11,800)",
"image/x-vnd.isis": "ISIS",
"text/x-yacc": "Yacc/Bison source code",
"application/vnd.ogc.wms_xml": "Web Map Service (WMS)",
"application/vnd.openxmlformats-officedocument.wordprocessingml.template": "Office Open XML Document Template",
"application/x-bzip": "Bzip Compressed File",
"application/ic-pubs+xml": "PUBS IntelDoc",
"image/x-rpf-tfc-4": "Transit Flying Chart - 4 (TFC_4)",
"image/x-rpf-tfc-5": "Transit Flying Chart - 5 (TFC_5)",
"image/x-rpf-tfc-2": "Transit Flying Chart - 2 (TFC_2)",
"image/x-rpf-tfc-3": "Transit Flying Chart - 3 (TFC_3)",
"application/vnd.esri.gp.tool.category": "GP Tool Category",
"image/x-rpf-tfc-1": "Transit Flying Chart - 1 (TFC_1)",
"image/x-vnd.intergraphctb": "Intergraph CTB",
"image/x-vnd.intergraphctc": "Intergraph CTC",
"application/vnd.microstation.dgn": "MicroStation Design File (DGN)",
"application/vnd.oasis.opendocument.chart": "OpenDocument v1.0: Chart document",
"text/sgml": "Standard Generalized Markup Language File",
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "Office Open XML Presentation",
"text/x-ini": "Configuration file",
"application/gsip5+xml": "NMIS 5.0",
"application/vnd.ms-powerpoint.slideshow.macroenabled.12": "Office Open XML Presentation Slideshow (macro-enabled)",
"application/x-xmind": "XMind Pro",
"audio/basic": "uLaw/AU Audio File",
"text/x-idl": "Inteface Definition Language",
"text/x-c++hdr": "C++ source code header",
"application/vnd.oasis.opendocument.chart-template": "OpenDocument v1.0: Chart document used as template",
"image/x-vnd.idrisirst": "IDRISI Raster",
"application/vnd.oasis.opendocument.formula": "OpenDocument v1.0: Formula document",
"application/atom+xml": "Atom feed",
"text/x-java-source": "Java source code",
"text/x-java": "Java source code",
"message/rfc822": "E-mail Message",
"application/xml": "Extensible Markup Language (XML)",
"application/vnd.oasis.opendocument.graphics-template": "OpenDocument v1.0: Graphics document used as template",
"image/x-rpf-gnc": "Global Navigation Chart (GNC)",
"text/x-stsrc": "Smalltalk source code",
"application/x-geocortex-site": "Geocortex Site",
"application/x-adobe-indesign-interchange": "Adobe InDesign Interchange format (INX)",
"text/x-applescript": "AppleScript source code",
"text/x-yaml": "YAML source code",
"text/x-haskell": "Haskell source code",
"application/pdf": "Portable Document Format (PDF)",
"image/x-raw-nikon": "Nikon raw image",
"application/x-bzip2": "Bzip 2 UNIX Compressed File",
"text/x-forth": "Forth source code",
"text/x-go": "Go source code",
"application/x-arcgis-feature-server": "ArcGIS FeatureService",
"image/x-vnd.adrg_legend": "ADRG Legend",
"text/x-vcalendar": "vCal",
"text/html": "HyperText Markup Language (HTML)",
"image/vnd.adobe.photoshop": "Photoshop Image",
"application/x-arcgis-gp-server-task": "ArcGIS Geoprocessing Service Task (GPServer Task)",
"application/x-arcgis-image-server": "ArcGIS Image Service (ImageService)",
"application/ddms3+xml": "DDMS 3.0",
"text/x-csharp": "C# source code",
"text/x-basic": "Basic source code",
"application/x-arcgis-gp-server": "ArcGIS Geoprocessing Service (GPServer)",
"application/vnd.esri.connection.ags": "ArcGIS Server Connection File",
"application/x-arcgis-online-map": "ArcGIS Online Map",
"text/x-diff": "Diff",
"image/x-rpf-cc": "Coastal Charts",
"image/x-rpf-vfr_tac": "VFR Terminal Area Chart",
"video/x-msvideo": "Audio Video Interleave File",
"image/x-rpf-mim2": "Military Installation Maps, 2 (MIM2)",
"image/x-rpf-mim1": "Military Installation Maps, 1 (MIM1)",
"application/vnd.ms-excel.sheet.macroenabled.12": "Office Open XML Workbook (macro-enabled)",
"application/vnd.openxmlformats-officedocument.spreadsheetml.template": "Office Open XML Workbook Template",
"text/richtext": "Rich Text",
"text/x-c++src": "C++ source code",
"application/xml-dtd": "XML Document Type Definition",
"application/x-xz": "XZ Archive",
"application/vnd.ms-powerpoint.slide.macroenabled.12": "PowerPoint Slide with Macros",
"application/vnd.oasis.opendocument.formula-template": "OpenDocument v1.0: Formula document used as template",
"application/x-sh": "UNIX/LINUX Shell Script",
"application/x-arcgis-geometry-server": "ArcGIS Geometry Service (GeometryService)",
"image/x-vnd.gxf": "GXF (Grid eXchange File)",
"image/x-rpf-combatc_100": "Combat Chart (1:100,000)",
"application/x-arcgis-globe-server-layer": "ArcGIS Globe Service Layer (GlobeService Layer)",
"application/x-arcgis-online-item": "ArcGIS Online",
"model/vnd.dwf": "Design Web Format (DWF)",
"image/x-rpf-cityg_14_700": "City Graphics (1:14,700)",
"text/x-assembly": "Assembler source code",
"image/vnd.adobe.premiere": "Premiere 6 Project",
"application/vnd.mapinfo": "MapInfo Interchange Format",
"image/x-rpf-cityg_21": "City Graphics (1:21,000)",
"image/x-rpf-cityg_22": "City Graphics (1:22,000)",
"image/x-rpf-cityg_23": "City Graphics (1:23,000)",
"image/x-rpf-cityg_25": "City Graphics (1:25,000)",
"image/x-rpf-cityg_26": "City Graphics (1:26,000)",
"text/x-vhdl": "VHDL source code",
"image/x-rpf-cityg_20": "City Graphics (1:20,000)",
"application/x-ascii-log": "ASCII Log",
"image/x-rpf-cityg_18": "City Graphics (1:18,000)",
"application/vnd.google-earth.kml+xml": "Keyhole Markup Language (KML)",
"image/x-rpf-cityg_12": "City Graphics (1:12,000)",
"image/x-rpf-cityg_10": "City Graphics (1:10,000)",
"image/x-rpf-cityg_11": "City Graphics (1:11,000)",
"application/ddms4.1+xml": "DDMS 4.1",
"image/x-rpf-cityg_16": "City Graphics (1:16,000)",
"image/x-rpf-cityg_17": "City Graphics (1:17,000)",
"image/x-rpf-cityg_14": "City Graphics (1:14,000)",
"image/x-rpf-cityg_15": "City Graphics (1:15,000)",
"text/x-cobol": "COBOL source code",
"application/x-arcgis-mobile-server": "ArcGIS Mobile Service (MobileService)",
"application/vnd.ogc_sld": "Styled Layer Descriptor (SLD)",
"application/xv+xml": "Flex MXML",
"text/vnd.graphviz": "Graphviz DOT",
"image/x-vnd.grd": "Golden Software Grid",
"image/x-rpf-cityg_36": "City Graphics (1:36,000)",
"image/x-rpf-cityg_35": "City Graphics (1:35,000)",
"application/vnd.adobe.air-application-installer-package+zip": "Adobe AIR Installer",
"image/x-dted": "Digital Terrain Elevation Data (DTED)",
"application/x-tika-msoffice": "MS Office File",
"image/x-rpf-cityg_21_120": "City Graphics (1:21,120)",
"image/x-rpf-cityg_16_666": "City Graphics (1:16,666)",
"image/x-rpf-lfc-day": "Low Flying Chart (day) (LFC_day)",
"text/asp": "Active Server Page (ASP)",
"application/vnd.ogc_xml": "OGC XML WebService",
"image/x-rpf-tpc": "Tactical Pilotage Chart (TPC)",
"text/x-chdr": "C source code header",
"application/vnd.ms-outlook": "Microsoft Outlook Message",
"text/x-common-lisp": "Common Lisp source code",
"application/vnd.esri.gp.tool": "GP Tool",
"application/vnd.ms-excel": "Microsoft Excel Spreadsheet",
"application/ddms2+xml": "DDMS 2.0",
"application/smil+xml": "SMIL Multimedia",
"image/x-rpf-opg": "Operational Planning Graphic (OPG)",
"image/x-rpf-vfr_hrc": "VFR Helicopter Route Chart (VFR_HRC)",
"application/x-archive": "Archiver",
"text/x-vbasic": "Visual basic source code",
"text/aspdotnet": "ASP .NET (ASP.NET)",
"application/vnd.safe.fmw": "FME Workbench (FMW)",
"application/x-hdf": "Hierarchical Data Format File",
"application/x-arcgis-map-server": "ArcGIS Map Service (MapService)",
"application/xslt+xml": "XSL Transformations (XSLT)",
"application/vnd.apple.pages": "Apple Pages",
"application/vnd.oasis.opendocument.text-master": "OpenDocument v1.0: Global Text document",
"application/vnd.ms-powerpoint.template.macroenabled.12": "PowerPoint Template with Macros",
"text/x-verilog": "Verilog source code",
"application/vnd.ms-word.template.macroenabled.12": "Office Open XML Document Template (macro-enabled)",
"text/x-rsrc": "R source code",
"image/x-rpf-jnc": "Jet Navigation Chart (JNC)",
"application/x-las": "Lidar (LIDAR)",
"audio/midi": "Musical Instrument Digital Interface (MIDI)",
"application/x-arcgis-geodata-server": "ArcGIS GeoData Service (GeoDataService)",
"application/x-laz": "Compressed Lidar File (LIDAR)",
"text/x-eiffel": "Eiffel source code",
"application/x-fme-server-repository": "FME Server Repository",
"image/x-mrsid": "MrSID",
"text/x-groovy": "Groovy source code",
"text/x-csrc": "C source code",
"text/x-rexx": "Rexx source code",
"image/x-rpf-jog": "Joint Operations Graphic (JOG)",
"text/x-coldfusion": "ColdFusion source code",
"text/x-log": "application log",
"image/gif": "Graphics Interchange Format (GIF)",
"application/vnd.oasis.opendocument.graphics": "OpenDocument v1.0: Graphics document (Drawing)",
"image/x-vnd.adrg_overview": "ADRG Overview",
"image/x-vnd.dem": "USGS ASCII DEM",
"application/vnd.openxmlformats-officedocument.presentationml.slideshow": "Office Open XML Presentation Slideshow",
"application/x-mspublisher": "Microsoft Publisher",
"image/x-rpf-cityg": "City Graphics",
"image/x-vnd.ddf": "USGS SDTS DEM",
"application/ddms+xml": "DDMS",
"application/vnd.mindjet.mindmanager": "MindManager",
"text/x-expect": "Expect Script",
"application/wsdl+xml": "WSDL",
"application/vnd.ms-excel.addin.macroenabled.12": "Office Open XML Workbook Add-in (macro-enabled)",
"image/x-rpf-combatc": "Combat Chart",
"video/ogg": "Ogg Video File",
"image/x-rpf-onc": "Operational Navigation Chart (ONC)",
"text/x-lua": "Lua source code",
"application/vnd.oasis.opendocument.text-template": "OpenDocument v1.0: Text document used as template",
"image/x-rpf-atc": "Series 200 Air Target Chart (ATC)",
"application/vnd.apple.numbers": "Apple Numbers",
"text/x-ada": "Ada source code",
"application/x-iso9660-image": "ISO 9660 CD-ROM filesystem data",
"video/x-f4v": "Flash MP4 Video",
"model/x-sldasm": "SolidWorks Assembly Document",
"application/vnd.kde.kword": "KWord File",
"image/vnd.microsoft.icon": "Icon File (ICO)",
"application/x-rpm": "RedHat Package Manager",
"application/x-ole-storage": "Windows Installer",
"application/vnd.esri.layer": "ESRI Document Layer",
"video/x-ms-wmx": "Windows Media Redirector",
"application/vnd.voyager": "Voyager Base Mime Type",
"application/vnd.esri.3dd": "ArcGlobe Document (3DD)",
"application/vnd.wordperfect": "WordPerfect",
"audio/x-mod": "MOD",
"application/x-sas-putility": "SAS Permanent Utility",
"application/x-msmetafile": "Windows Metafile (WMF)",
"application/postscript": "PostScript",
"image/x-portable-pixmap": "UNIX Portable Bitmap Graphic (PXM)",
"application/vnd.esri.lpk": "ESRI Layer Package (LPK)",
"application/vnd.esri.loc": "Address Locator",
"application/vnd.lotus-freelance": "Lotus Freelance",
"application/vnd.esri.layer.cad": "CAD Layer",
"application/matlab-mat": "Matlab File",
"application/x-vnd.rsets": "WinRAR",
"image/x-portable-bitmap": "Portable Bit Map (PBM)",
"application/vnd.esri.sxd": "ArcScene Document (SXD)",
"audio/x-pn-realaudio-plugin": "RealMedia Player Plug-in",
"audio/x-ms-wma": "Windows Media Audio",
"application/mp4": "MPEG-4",
"image/x-raw-minolta": "Minolta raw image",
"audio/x-mpegurl": "MP3 Playlist File",
"application/vnd.ms-fontobject": "Embedded OpenType",
"application/vnd.ms.vs.sln": "VisualStudio Solution",
"application/vnd.ms-wpl": "Web Protection Library",
"image/x-raw-sigma": "Sigma raw image",
"application/vnd.lotus-approach": "Lotus Approach",
"image/x-raw-imacon": "Imacon raw image",
"application/x-adobe-indesign": "Adobe InDesign document (INDD)",
"video/x-mng": "Multiple Network Graphic",
"image/x-niff": "Navy Interchange File Format",
"application/vnd.ms-cab-compressed": "Cabinet",
"application/x-vnd.nasa_pds": "Nice Label Template",
"video/x-ms-wvx": "Windows Media Video",
"application/vnd.esri.document": "ESRI Document",
"application/vnd.esri.map.data.frame": "Map Frame",
"application/x-stuffitx": "StuffIt X Archive",
"application/x-sas-catalog": "SAS Catalog",
"model/x-stl": "Stereolithography (STL)",
"image/x-raw-kodak": "Kodak raw image",
"application/vnd.kde.kchart": "KChart File",
"image/jpm": "JPEG 2000 Part 6 (JPM) (JP2)",
"application/vnd.voyager.unknown": "Unknown Mime Type",
"application/x-compress": "Unix Compressed File",
"application/x-elc": "Emacs Lisp bytecode",
"audio/adpcm": "ADP Audio File",
"application/x-onc-dir": "ONC (Operational Nautical Chart) Directory",
"application/x-vnd.googlecache": "Google Earth Cache",
"video/mj2": "JPEG 2000 Part 3 (Motion JPEG, MJ2)",
"application/x-emf": "Extended Metafile (EMF)",
"application/vnd.esri.topology": "Topology",
"application/winhlp": "WinHelp",
"application/x-font-otf": "OpenType Font (OTF)",
"audio/x-aac": "Advanced Audio Coding",
"application/vnd.esri.mpk": "ESRI Map Package (MPK)",
"application/x-filemaker": "FileMaker Pro 7 (FP7)",
"application/vnd.openxmlformats-officedocumentument.presentationml.presentation": "PowerPoint Presentation",
"application/vnd.esri.layer.service": "WebService Layer",
"application/x-silverlight-app": "Silverlight Application Package",
"application/x-7z-compressed": "7-zip archive (7zip)",
"model/vrml": "VRML World",
"image/x-rgb": "Silicon Graphics RGB Bitmap",
"application/vnd.esri.layer.mosaic": "Mosaic Layer",
"application/x-mapservice-bing": "Bing Map Service",
"application/vnd.esri.layer.missing": "Missing Data Layer",
"image/x-raw-epson": "Epson raw image",
"application/x-sas-fdb": "SAS FDB Consolidation Database File",
"application/vnd.ms-batch": "Batch file",
"application/x-coreldraw": "Corel Drawing",
"application/x-latex": "LaTeX Source Document",
"model/x-sab": "Standard ACIS Binary (SAB)",
"application/x-sas-audit": "SAS Audit",
"image/x-jp2-container": "JPEG 2000 Container Format",
"application/vnd.wap.wmlc": "Compiled WML Document",
"application/vnd.esri.geometric.network": "Geometric Network",
"application/vnd.openxmlformats-officedocumentument.wordprocessingml.template": "Micosoft Word Template",
"application/x-futuresplash": "Macromedia FutureSplash File",
"application/x-sas-dmdb": "SAS DMDB Data Mining Database File",
"application/msword2": "Microsoft Word 2 Document",
"application/msword5": "Microsoft Word 5 Document",
"application/vnd.apple.ds_store": "Desktop Services Store",
"application/x-tex": "TeX Source",
"application/x-killustrator": "KIllustrator File",
"audio/x-ms-wax": "Windows Media Audio Redirect",
"application/x-mapservice-osm": "Open Street Map",
"video/x-flc": "FLIC Animation",
"video/x-fli": "FLI File Extension",
"application/vnd.esri.layer.raster": "Raster Layer",
"application/x-font-bdf": "Glyph Bitmap Distribution Format",
"image/x-raw-olympus": "Olympus raw image",
"application/x-font-pcf": "PaintCAD Font",
"application/x-sas-itemstor": "SAS Item Store (ItemStor) File",
"application/onenote": "Micosoft OneNote",
"application/x-sas-mddb": "SAS MDDB Multi-Dimensional Database File",
"image/x-raw-pentax": "Pentax raw image",
"application/x-vnd.vtp_bt": "VTP Binary Terrain",
"application/x-sas-data": "SAS Data Set",
"application/x-sas-program-data": "SAS Stored Program (DATA Step)",
"application/x-sas-access": "SAS Access Descriptor",
"application/x-seismic-unix": "Seismic Unix",
"application/vnd.mif": "FrameMaker Interchange Format",
"audio/x-flac": "Free Lossless Audio Codec (FLAC)",
"application/vnd.esri.dataset": "ESRI Dataset",
"image/x-raw-hasselblad": "Hasselblad raw image",
"application/x-sas-view": "SAS Data Set View",
"image/x-raw-phaseone": "Phase One raw image",
"application/vnd.esri.connection.ims": "ArcIMS Connection File",
"application/x-swb": "SolidWorks Older Macro",
"application/x-swp": "SolidWorks Macro",
"application/x-dvi": "TeX Device Independent Document",
"application/vnd.openxmlformats-officedocumentument.presentationml.template": "PowerPoint Template",
"application/x-font-printer-metric": "Printer Font Metric",
"application/vnd.esri.layer.annotation.coverage": "Coverage Annotation Layer",
"application/x-nga-vpf": "Vector Product (VPF)",
"application/x-dbase": "dBase",
"application/vnd.esri.layer.graphics": "Graphics Layer",
"application/x-bittorrent": "BitTorrent",
"application/ogg": "Ogg",
"video/x-ms-asf": "Advanced Systems Format",
"application/x-rar-compressed": "RAR archive",
"image/x-raw-casio": "Casio raw image",
"image/x-raw-red": "Red raw image",
"application/vnd.esri": "ESRI",
"image/x-raw-logitech": "Logitech raw image",
"audio/x-pn-realaudio": "Real Audio",
"application/vnd.esri.arcinfo.workspace": "ArcInfo Workspace",
"chemical/x-pdb": "Brookhaven Protein Databank File",
"application/x-java-jnlp-file": "Java Web Start",
"application/vnd.kde.kpresenter": "KPresenter File",
"application/vnd.esri.relationship.class": "Relationship Class",
"application/vnd.voyager.folder": "Folder",
"application/vnd.esri.afr": "Function Raster Dataset (AFR)",
"application/vnd.lotus-wordpro": "Lotus WordPro",
"application/x-nga-vpf-folder": "Vector Product Folder (VPF)",
"application/x-shockwave-flash": "Adobe Flash",
"application/vnd.tcpdump.pcap": "TCPDump pcap packet capture",
"application/vnd.esri.layer.dimension": "Dimension Layer",
"application/vnd.kde.kspread": "KSpread File",
"application/vnd.lotus-organizer": "Lotus Organizer",
"application/mathematica": "Mathematica",
"image/x-raw-rawzor": "Rawzor raw image",
"application/vnd.esri.layer.tracking.analyst": "Tracking Analyst Layer",
"application/vnd.esri.layer.arcgis.server": "ArcGIS Server Layer",
"application/x-font-linux-psf": "Photoshop Proof Settings File",
"application/fits": "Flexible Image Transport System (FITS)",
"application/vnd.esri.layer.group": "Group Layer",
"x-conference/x-cooltalk": "Cooltalk Audio",
"application/x-ms-thumbs-db": "Thumbs.db",
"application/vnd.openofficeorg.extension": "OpenOffice Extension",
"image/x-raw-leaf": "Leaf raw image",
"application/vnd.esri.layer.raster.catalog.gdb": "Geodatabase Raster Catalog Layer",
"model/x-slddrt": "SolidWorks Sheet Document",
"model/x-slddrw": "SolidWorks Drawing Document",
"image/x-raw-mamiya": "Mamiya raw image",
"application/vnd.esri.layer.feature": "Feature Layer",
"application/x-director": "Shockwave Movie",
"model/x-sldprt": "SolidWorks Part Document",
"application/vnd.esri.avl": "ArcView Legend",
"application/vnd.esri.layer.ims": "IMS Layer",
"application/x-java-pack200": "Pack200 Packed Jar File",
"application/vnd.esri.axl": "ArcXML Document",
"image/x-jp2-codestream": "JPEG 2000 Codestream",
"video/3gpp": "3GPP Multimedia",
"audio/mp4": "MPEG-4 Video",
"application/x-e57": "E57",
"application/vnd.voyager.folder.info": "Folder Info",
"application/vnd.openxmlformats-officedocumentument.spreadsheetml.template": "Excel Template",
"application/vnd.openxmlformats-officedocumentument.presentationml.slideshow": "PowerPoint Slide Show",
"application/x-sas-data-index": "SAS Data Set Index",
"image/x-raw-adobe": "Adobe Digital Negative (DNG)",
"application/vnd.koan": "SSEYO Koan File",
"application/vnd.openxmlformats-officedocumentument.presentationml.slide": "PowerPoint Slide",
"image/x-raw-fuji": "Fuji raw image",
"application/vnd.openxmlformats-officedocumentument.spreadsheetml.sheet": "Excel Workbook",
"application/vnd.esri.pmf": "Published Map (PMF)",
"application/x-vnd.quickbird.til": "Quickbird Tile Info (TIL)",
"application/x-sas-transport": "SAS Transport File",
"application/vnd.esri.memory.dataset": "Memory Dataset",
"image/x-raw-canon": "Canon raw image",
"application/x-font-type1": "ASCII Printer Font",
"image/x-portable-graymap": "Portable Graymap Graphic (PGM)",
"application/vnd.esri.gdb": "ESRI Geodatabase",
"application/vnd.adobe.aftereffects.template": "Adobe After Effects Template",
"video/vnd.mpegurl": "MPEG URL",
"application/vnd.adobe.aftereffects.project": "Adobe After Effects Project",
"application/vnd.openxmlformats-officedocumentument.wordprocessingml.documentument": "Micosoft Word Doc",
"application/vnd.ms-word.documentument.macroenabled.12": "Office Open with Macros",
"application/x-cdlink": "Virtual CD-ROM CD Image File",
"video/x-ms-wm": "Windows Media File Extension",
"application/x-sas-utility": "SAS Utility",
"image/x-pict": "Apple Macintosh QuickDraw/PICT Format",
"image/cgm": "Computer Graphics Metafile (CGM)",
"application/vnd.esri.layer.annotation": "Annotation Layer",
"application/illustrator": "Adobe Illustrator Artwork (AI)",
"image/x-portable-anymap": "Portable Any Map (PNM)",
"application/vnd.ms-htmlhelp": "MS Help",
"image/x-xwindowdump": "X Windows Dump",
"video/vnd.vivo": "VivoActive Video",
"application/x-sas-backup": "SAS Backup",
"application/seismic-segy": "SEG-Y Seismic Data",
"application/vnd.wap.wmlscriptc": "Compiled WML Script",
"application/x-foxmail": "Foxmail Email File",
"video/x-sgi-movie": "QuickTime Movie",
"application/x-stuffit": "Stuffit",
"application/vnd.ms.vs.dsw": "Visual C++ Project"
},
field_names = {
bytes: "File Size",
extent_rough: "Extent (General)",
available: "Available",
downloadable: "Downloadable",
has_aux_files: "Has Aux Files",
metafs: "MetaFS",
ondemand: "On Demand",
onfs: "On Filesystem",
crawled: "Last Crawled",
created: "Created",
creation_date: "Creation Date",
discovered: "Discovered Time",
end_time: "End Time",
ags_type: "ArcGIS Online Type",
ags_format_keyword: "ArcGIS Online Keyword",
indexed: "Last Indexed",
last_printed: "Last Printed",
last_saved: "Last Saved",
modified: "Modified",
modified_date: "Modified Date",
start_time: "Start Time",
hrefs: "Links",
aux_file_count: "Aux File Count",
character_count: "Character Count",
columnCount: "Column Count",
dataCount: "Data Count",
discoveredCount: "Discovered Count",
docCount: "Document Count",
first_crawl: "First Crawl",
hpsecurity: "Hpfs Security",
last_crawl: "Last Crawl",
layerCount: "Layer Count",
line_count: "Line Count",
numBands: "Number of Bands",
num_points: "Number of Points",
num_segments: "Number of Segments",
page_count: "Page Count",
paragraph_count: "Paragraph Count",
rowCount: "Row Count",
scale: "Scale",
slide_count: "Slide Count",
tableJoinCount: "Table Join Count",
thumb_try_count: "Thumb Try Count",
timeToBuildLayer: "Time To Build Layer",
timeToDrawSmall: "Time To Draw Small",
timeToOpen: "Time To Open",
timeToParse: "Time To Parse",
transparency: "Transparency",
word_count: "Word Count",
edit_time: "Edit Time",
indexingTimeout: "Indexing Timeout",
metaBytes: "Metadata Size",
mime: "Format",
format_type: "Format Type",
format_category: "Format Category",
format_keyword: "Format Keyword",
format_company: "Format Company",
format_app: "Format Application",
"Content-Type": "Content-Type",
application_name: "Application Name",
application_version: "Application Version",
author: "Author",
comments: "Comments",
company: "Company",
contentHash: "Content Hash",
content_status: "Content Status",
copyright: "Copyright",
creator: "Creator",
extent: "Extent",
extent_norm: "Extent WGS84",
fgdc_access_constraint: "FGDC Access Constraint",
fgdc_caldate: "FGDC Calendar Date",
fgdc_meta_address: "FGDC Metadata Contact Address",
fgdc_meta_address_type: "FGDC Metdata Contract Address Type",
fgdc_meta_city: "FGDC Metadata Contact City",
fgdc_meta_org: "FGDC Metadata Organization",
fgdc_meta_person: "FGDC Metadata Person",
fgdc_meta_postal_code: "FGDC Metadata Contact Postal Code",
fgdc_meta_state: "FGDC Metadata Contact State",
fgdc_originator: "FGDC Originator",
fgdc_progress: "FGDC Progress",
fgdc_pubdate: "FGDC Publication Date",
fgdc_purpose: "FGDC Purpose",
fgdc_title: "FGDC Title",
fgdc_update: "FGDC Update",
fgdc_use_constraint: "FGDC Use Constraint",
fileExtension: "File Extension",
folder: "Folder",
geometryType: "Geometry Type",
host: "Host",
hotLinkType: "Hot Link Type",
id: "Id",
iso_abstract: "ISO Abstract",
iso_dataset_creation_date: "ISO Dataset Creation Date",
iso_dataset_language: "ISO Dataset Language",
iso_dataset_title: "ISO Dataset Title",
iso_metadata_classification: "ISO Metadata Classification",
iso_metadata_file_identifier: "ISO Metadata File Identifier",
iso_metadata_hierarchy_level: "ISO Metadata Hierarchy Level",
iso_metadata_language: "ISO Metadata Language",
iso_metadata_parent_identifier: "ISO Metadata Parent Identifier",
iso_metadata_releasability: "ISO Metadata Releasability",
iso_reference_system: "ISO Reference System",
iso_resource_classification: "ISO Resource Classification",
iso_resource_releasability: "ISO Resource Releasability",
iso_spatial_representation: "ISO Spatial Representation",
language: "Language",
last_author: "Last Author",
layerDesc: "Layer Description",
manager: "Manager",
nato_abstract: "NATO Abstract",
nato_dataset_creation_date: "NATO Dataset Creation Date",
nato_dataset_language: "NATO Dataset Language",
nato_dataset_title: "NATO Dataset Title",
nato_metadata_classification: "NATO Metadata Classification",
nato_metadata_file_identifier: "NATO Metadata File Identifier",
nato_metadata_hierarchy_level: "NATO Metadata Hierarchy Level",
nato_metadata_language: "NATO Metadata Language",
nato_metadata_parent_identifier: "NATO Metadata Parent Identifier",
nato_metadata_releasability: "NATO Metadata Releasability",
nato_reference_system: "NATO Reference System",
nato_resource_classification: "NATO Resource Classification",
nato_resource_releasability: "NATO Resource Releasability",
nato_spatial_representation: "NATO Spatial Representation",
nato_topic_category: "NATO Topic Category",
pixelType: "Pixel Type",
point_dd: "Point (Decimal Degrees)",
presentation_format: "Presentation format",
producer: "Producer",
product: "Product",
rasterSize: "Raster Size",
rasterType: "Raster Type",
revision_number: "Revision Number",
schemaHash: "Schema Hash",
series: "Series",
server: "Server",
service: "Service",
source: "Source",
srs_code: "Spatial Reference (code)",
template: "Template",
title: "Title",
uri: "Uri",
version: "Version",
CADLayers: "CAD Layer",
parameter_type: "Parameter Type",
ags_formats: "Supported Formats",
ags_interface: "Supported Interfaces",
ags_operation: "Supported Operations",
ags_view_in: "View In",
category: "Category",
column: "Column",
dpath: "Path",
fgdc_place: "FGDC Place",
fgdc_theme: "FGDC Theme",
fme_role: "FME Role",
fme_cmdline: "FME Command Line",
fme_service: "FME Service",
fme_transformer: "FME Transformer",
framework: "Framework",
indexingError: "Indexing Error",
indexingWarning: "Indexing Warning",
iso_thematic_keyword: "ISO Thematic Keyword",
iso_topic_category: "ISO Topic Category",
keywords: "Keywords",
missingDataPath: "Missing Data",
missing_meta_fields: "Missing Metadata Fields",
nato_thematic_keyword: "NATO Thematic Keyword",
subject: "Subject",
unknownField: "Unknown Field",
ft_fgdc_abstract: "FGDC Abstract",
ftt_notes: "Notes",
ftt_text: "Text",
fu_area: "Area",
fu_brightness: "Brightness",
fu_contrast: "Contrast",
fu_extent_aspect: "Extent Aspect",
fu_maxScale: "Maximum Scale",
fu_minScale: "Minimum Scale",
fu_pixHeight: "Pixel Height",
fu_pixWidth: "Pixel Width",
list: "List",
list_order: "List Order",
location: "Location",
name: "Name",
path: "Path",
properties: "Properties",
score: "Relevance",
srs: "Spatial Reference",
subtype: "Subtype",
thumbTimeout: "Thumb Timeout",
type: "Type",
_absolute_path: "Absolute Path",
_explain: "Query Explanation",
sec_class: "Security Classification",
sec_class_list: "All Classificaions",
sec_class_orig: "Original Classification"
},
field_descriptions = {
bytes: "File size (on disk)",
extent_rough: "Low precision",
available: "false if data is missing",
downloadable: "Downloadable",
has_aux_files: "Has auxiliary files",
metafs: "Metadata is stored as a file",
ondemand: "Draw the image when it is requested",
crawled: "Last time the crawler found the entry",
created: "Created",
creation_date: "Creation Date",
discovered: "When the crawler first found the entry",
end_time: "End Time",
indexed: "Last time entry was indexed",
last_printed: "Last Printed",
last_saved: "Last Saved",
modified: "Last modified time",
modified_date: "Modified Date",
start_time: "Start Time",
aux_file_count: "How many auxiliary files exist",
character_count: "Character Count",
columnCount: "Number of Columns",
dataCount: "How many data sources are used",
discoveredCount: "Number of times the Crawler has found this entry",
docCount: "How many documents does this appear in",
first_crawl: "First Crawl",
hpsecurity: "Hpfs Security",
last_crawl: "Last Crawl",
layerCount: "For Maps -- how many layers are in the map? For Data -- in how many layers (across all maps) does the data set appear?",
line_count: "Line Count",
numBands: "Number of Bands",
num_points: "Number of Points",
num_segments: "Number of Segments",
page_count: "Page Count",
paragraph_count: "Paragraph Count",
rowCount: "Number of Rows",
scale: "Scale",
slide_count: "Slide Count",
tableJoinCount: "Number of Table Joins",
thumb_try_count: "How many times has the thumbnail tried to draw",
timeToBuildLayer: "How long it takes the indexer to build the layer file",
timeToDrawSmall: "How long it takes to draw the small image",
timeToOpen: "How long it takes the indexer to open this entry",
timeToParse: "How long it takes the indexer to parse this entry",
transparency: "Layer transparency value (0-100)",
word_count: "Word Count",
edit_time: "Edit Time",
indexingTimeout: "How long it too for indexing to timeout (in MS)",
metaBytes: "Size of the Metadata (in bytes)",
"Content-Type": "Content-Type",
application_name: "Application Name",
application_version: "Application Version",
author: "Author",
comments: "Comments",
company: "Company",
contentHash: "Hashed value for the content -- identical values represent various entries with identical content",
content_status: "Content Status",
copyright: "Copyright",
creator: "Creator",
extent: "Extent",
extent_norm: "Extent normalized to WGS84",
fileExtension: "File Extension",
folder: "Containing Folder",
host: "Host",
hotLinkType: "Hot Link Type",
id: "Id",
language: "Language",
last_author: "Last Author",
layerDesc: "Descriptive text or comments about the layer",
manager: "Manager",
pixelType: "Pixel Type",
point_dd: "Point in Decimal Degrees",
presentation_format: "Presentation Format",
producer: "Producer",
product: "Product",
rasterSize: "Raster Size",
rasterType: "Raster Type",
revision_number: "Revision Number",
schemaHash: "Hashed value for the schema -- identical values represent various entries with identical schemas",
series: "Series",
server: "Server",
service: "Service",
source: "Source",
template: "Template",
title: "Title",
uri: "Uri",
version: "Version",
CADLayers: "CAD Layers",
ags_interface: "ArcGIS Interface",
ags_view_in: "ArcGIS Server View In",
category: "Category",
column: "Name of the Columns available in the data set",
dpath: "Navigable Path",
framework: "The framework suppored by this item (ESRI, GDAL, PDF, etc)",
keywords: "Keywords",
subject: "Subject",
unknownField: "Collection of unknown fields",
ftt_notes: "Notes",
ftt_text: "Text",
fu_area: "Geographic area of the entry (in XXX units)",
fu_brightness: "image brightness",
fu_contrast: "Image Contrast",
fu_extent_aspect: "Extent Aspect",
fu_maxScale: "Layer setting -- maximum scale",
fu_minScale: "Layer setting -- minimum scale",
fu_pixHeight: "Pixel Height in Map Units",
fu_pixWidth: "Pixel Width in Map Units",
list: "List",
list_order: "List Order",
location: "The crawler location that found this data",
name: "Name",
path: "Path",
properties: "Attributes",
score: "Query Relevance",
srs: "Spatial Reference for the given entry",
subtype: "Subtype",
thumbTimeout: "How long the thumb has tried building",
type: "Entry Type"
},
field_values = {
ags_operation: {
SubmitJob: "Submit Job",
Cut: "Cut",
Query: "Query",
Offset: "Offset",
ExportMap: "Export Map",
Densify: "Densify",
Lengths: "Lengths",
Buffer: "Buffer",
ConvexHul: "Convex Hull",
Simplify: "Simplify",
GenerateKML: "Generate KML",
TrimExtend: "Trim/Extend",
FindAddressCandidates: "Find Address Candidates",
Reshape: "Reshape",
RelationOperation: "Relation Operation",
ExportImage: "Export Image",
Project: "Project",
Download: "Download",
Relation: "Relation",
Find: "Find",
Distance: "Distance",
Union: "Union",
ExecuteTask: "Execute Task",
ReverseGeocode: "Reverse Geocode",
Intersect: "Intersect",
Generalize: "Generalize",
Difference: "Difference",
AreasAndLengths: "Areas And Lengths",
Identify: "Identify",
LabelPoints: "Label Points",
AutoComplete: "Auto Complete"
},
ags_view_in: {
ArcGisExplorer: "ArcGIS Explorer",
GoogleEarth: "Google Earth",
ArcGisJavascript: "ArcGIS Javascript",
BingMaps: "Bing Maps",
ArcGisDotCom: "ArcGIS.com",
VirtualEarth: "Virtual Earth",
GoogleMaps: "Google Maps"
},
indexingError: {
indexingTimeout: "Indexing Timeout",
errorReadingStructure: "Error Reading Structure",
errorSavingConnection: "Error Saving Connection"
},
indexingWarning: {
errorSavingLayer: "Error Saving Layer",
errorSavingImage: "Error Saving Image",
md5Timeout: "MD5 Timeout"
},
properties: {
hasMetadata: "Has Metadata",
spatial: "Spatial Data",
hotLinks: "Layer supports ArcView 3x style hot links",
stub: "Placeholder",
hasMissingData: "Contains Missing Data",
indexingError: "Indexing Error",
absolutePaths: "Absolute Paths",
misingThumbnail: "Missing Thumbnail",
hasTransparency: "Has Transparency",
thumbTimedOut: "Thumbnail Timed Out",
downloadable: "Downloadable",
missingRequiredMetadataFields: "Missing Required Metadata Fields",
hyperLinks: "Layer supports Hyper Links",
pyramids: "Pyramids Built",
rasterized: "Rasterized",
thumb_stopped_trying: "Thumbnail Won't Draw",
mapTips: "Layer uses Map Tips",
hasVisibleRange: "Has Visible Range",
hasBrightness: "Has Brightness",
hasContrast: "Has Contrast",
ags_fused_cache: "ArcGIS Fused Cache",
memoryDataset: "Uses Memory Dataset"
},
srs: {
Unknown: "Unknown Spatial Reference",
Custom: "Custom Spatial Reference"
},
subtype: {
esriDTCadastralFabric: "Cadastral Fabric",
wms_server: "WMS Server",
esriDTRasterBand: "Raster Band",
pdf: "PDF Document",
esriDTContainer: "Any Container Dataset",
esriDTNetworkDataset: "Network Dataset",
python: "Python Script",
missing: "Missing Data",
esriDTTopology: "Topology",
file: "File",
FeatureServer: "Feature Server",
esriGPServerTool: "GP Server Tool",
esriDTRepresentationClass: "Feature Class Representation",
ImageServer: "Image Server",
workbench: "Workbench",
gpx: "GPX",
wms: "WMS Service",
esriDTToolbox: "Toolbox",
esriDTLocator: "Address Locator",
GPServer: "Geoprocessing Server",
esriDTTin: "Tin Dataset",
esriGPCustomTool: "GP Custom Tool",
esriGPScriptTool: "GP Script Tool",
GeocodeServer: "Geocode Server",
MapServer: "Map Server",
esriDTText: "Text Dataset",
Access: "Personal Geodatabase",
esriDTAny: "Any Dataset",
esriDTRasterCatalog: "Raster Catalog",
esriDTTerrain: "Terrain dataset",
csw_server: "CSW Server",
esriGPFunctionTool: "GP Function Tool",
esriDTGeometricNetwork: "Geometric Network",
GlobeServer: "Globe Server",
workspace: "Workspace",
Sde: "ArcSDE Geodatabase",
esriDTCadDrawing: "CadDrawing Dataset",
GeoDataServer: "GeoData Server",
esriDTRelationshipClass: "Relationship Class",
FileGDB: "File Geodatabase",
repository: "Repository",
AGS: "ArcGIS Server",
map: "Map",
esriDTFeatureClass: "Feature Class",
esriDTTool: "Tool",
NAServer: "Network Analyst Server",
esriDTFeatureDataset: "Feature Dataset",
esriDTSchematicDataset: "Schematic Dataset",
esriDTTable: "Table Dataset",
layer: "Layer",
esriDTGeo: "Any Geo Dataset",
esriDTPlanarGraph: "Planar Graph",
Vpf: "VPF",
esriGPModelTool: "GP Model Tool",
dataset: "Dataset",
server: "Server",
GeometryServer: "Geometry Server"
},
type: {
connection: "Connection",
fmeserver: "FME Server",
toolbox: "Toolbox",
error: "Error",
service_layer: "Service Layer",
tool: "Tool",
data: "Data",
dataFrame: "Data Frame",
layer: "Layer",
script: "Script",
database: "Database",
folder: "Folder",
file: "File",
service: "Service",
fme: "FME",
doc: "Document",
server: "Server"
},
sec_class: {
U: "Unclassified",
S: "Secret",
R: "Restricted",
C: "Confidential",
NS: "NATO Secret",
NR: "NATO Restricted",
O: "Official",
TS: "Top Secret",
NC: "NATO Confidential",
CTS: "Cosmic Top Secret"
},
sec_class_list: {
U: "Unclassified",
S: "Secret",
R: "Restricted",
C: "Confidential",
NS: "NATO Secret",
NR: "NATO Restricted",
O: "Official",
TS: "Top Secret",
NC: "NATO Confidential",
CTS: "Cosmic Top Secret"
},
sec_class_orig: {
U: "Unclassified",
S: "Secret",
R: "Restricted",
C: "Confidential",
NS: "NATO Secret",
NR: "NATO Restricted",
O: "Official",
TS: "Top Secret",
NC: "NATO Confidential",
CTS: "Cosmic Top Secret"
}
},
removePrefixList = ["fs_", "ft_", "fh_", "fi_", "fl_", "fd_", "ff_", "fu_", "fp_", "fy_", "fm_", "fb_", "tag_", "meta_", "fss_", "grp_"],
removePrefixHash = {},
humanize = function(value) {
return value.replace(/_/g, " ").replace(/(\w+)/g, function(match) {
return match.charAt(0).toUpperCase() + match.slice(1)
})
},
lookup = function(key, map, doHumanize) {
var translated = map[key];
return translated ? (translated.indexOf("(") !== -1 && (translated = translated.replace(/.*\(|\)/gi, "")), translated) : doHumanize ? humanize(key) : key
};
return {
getType: function(key) {
return lookup(key, file_formats)
},
getTypeAbbr: function(key) {
var val = lookup(key, file_formats),
pos = val.indexOf("(");
if (pos !== -1) {
var endpos = val.indexOf(")");
val = val.substring(pos + 1, endpos)
}
return val
},
getFieldName: function(key) {
var idx = key.indexOf("_");
if (idx > -1) {
var prefix = key.substring(0, idx + 1);
removePrefixHash[prefix] && (key = key.replace(prefix, ""))
}
return lookup(key, field_names, !0)
},
getFieldDesc: function(key) {
return lookup(key, field_descriptions)
},
getLocation: function(key) {
return key = key.replace("_crawl", ""), lookup(key, locations)
},
getText: function(type, key) {
var typeOptions = field_values[type];
if (typeOptions) {
var translation = typeOptions[key];
if (translation) return translation
}
return humanize(key)
},
translateFilterNames: function(filters) {
var self = this;
$.each(filters, function(index, item) {
"" === item.value && (item.value = self.getFieldName(item.field))
})
},
init: _init
}
}), angular.module("voyager.util").factory("urlUtil", function(filterService) {
"use strict";
var lastUrl = "search",
getPrefix = function(url) {
var prefix = "&";
return url.indexOf("?") === -1 && (prefix = "?"), prefix
};
return {
buildSearchUrl2: function(solrParams, page, mapView, view, sort) {
var url = "search",
sep = "?";
return $.each(solrParams, function(key, value) {
"*:*" !== value && "sort" !== key && (url += sep + key + "=" + value, sep = "&")
}), $.each(filterService.getFilters(), function(index, facet) {
url += "" !== facet.filter ? sep + "fq=" + facet.filter + ":" + facet.name : sep + "fq=" + encodeURIComponent(facet.name), sep = "&"
}), page > 1 && (url += getPrefix(url) + "pg=" + page), mapView || (mapView = "0 0 0"), url += getPrefix(url) + "vw=" + mapView, view && (url += getPrefix(url) + "view=" + view), sort && (url += getPrefix(url) + "sort=" + sort), lastUrl = url, url
},
getLastUrl: function() {
return lastUrl
},
updateParam: function(name, oldValue, value) {
var toReplace = name + "=" + oldValue,
update = name + "=" + value;
lastUrl.indexOf(toReplace) !== -1 ? lastUrl = lastUrl.replace(toReplace, update) : this.addParam(name, value)
},
addParam: function(name, value) {
lastUrl += "&" + name + "=" + value
},
removeParam: function(name, value) {
var toReplace = "&" + name + "=" + value;
lastUrl = lastUrl.replace(toReplace, "")
}
}
}), angular.module("voyager.util").factory("solrUtil", function(config, $http) {
"use strict";
function _toFilters(ids) {
return ids = _toArray(ids), "fq=id:" + ids.join("+")
}
function _getFilters(params, $scope) {
var filters;
return !_.isUndefined(params.id) && params.id.length > 0 ? ($scope.idsFilter = !0, filters = _toFilters(params.id)) : ($scope.idsFilter = !1, filters = $.param(params, !0)), filters
}
function _toSolrQuery(url, params) {
var qs = $.extend({}, params);
return "rows" in qs || (qs.rows = 999999), qs.rand = Math.random(), qs.wt = "json", config.root + url + "?" + $.param(qs, !0)
}
function _stripAugmented(value) {
if (value.indexOf(":[") !== -1) {
var name = value.substring(0, value.indexOf(":["));
return 0 === name.indexOf("_") && (name = name.replace("_", "")), name
}
return value
}
var _toArray = function(val) {
return "string" == typeof val ? [val] : _.isUndefined(val) ? [] : val.slice()
};
return {
toSolrFilters: function(params, $scope) {
return _getFilters(params, $scope)
},
toSolrQuery: function(url, params) {
return _toSolrQuery(url, params)
},
search: function(q, fq, fl) {
_.isEmpty(q) && (q = "*:*"), _.isEmpty(fl) && (fl = "*");
var p = {
q: q,
fl: fl
};
return _.isEmpty(fq) || (p.fq = fq), $http({
method: "GET",
url: _toSolrQuery("solr/v0/select", p)
})
},
heatmap: function(bbox, query, level) {
var bounds = bbox.split(/ *, */),
params = {
q: "*:*",
rows: 0,
facet: !0,
"facet.heatmap": "geohash",
"facet.heatmap.geom": _.template('["<%=w%> <%=s%>" TO "<%=e%> <%=n%>"]')({
w: Math.max(-180, bounds[0]),
s: Math.max(-90, bounds[1]),
e: Math.min(180, bounds[2]),
n: Math.min(90, bounds[3])
})
};
return level > -1 && (params["facet.heatmap.gridLevel"] = level), params = $.extend(params, query || {}), $http({
url: _toSolrQuery("solr/v0/select", params)
})
},
stripAugmented: _stripAugmented
}
}), angular.module("voyager.util").factory("solrGrunt", function() {
"use strict";
function _getSolrParams(params) {
var solrParams = {};
return $.each(params, function(key, value) {
angular.isUndefined(_nonSolrParams[key]) && "" !== value && (solrParams[key] = value)
}), angular.isDefined(solrParams.sort) && (angular.isDefined(solrParams.sortdir) ? solrParams.sort = solrParams.sort + " " + solrParams.sortdir : solrParams.sort = solrParams.sort + " desc"), delete solrParams.sortdir, solrParams
}
var _nonSolrParams = {
vw: !0,
view: !0,
pg: !0,
bbox: !0,
bboxt: !0,
filter: !0
};
return {
getSolrParams: function(params) {
return _getSolrParams(params)
},
getInput: function(value) {
var input = "*:*";
return angular.isDefined(value) && (input = value), input
}
}
}), angular.module("voyager.util").directive("iframeLoad", function() {
return {
link: function(scope, element, attrs) {
scope.frameLoading = "frame-loading", element.on("load", function() {
scope.frameLoading = "", scope.$apply()
}), attrs.$observe("src", function() {
scope.frameLoading = "frame-loading"
})
}
}
}), angular.module("voyager.util").factory("systemService", function($http, $timeout, config, authService) {
function _doRestart() {
return $http({
method: "POST",
url: config.root + restartAPI,
headers: {
"Content-Type": "application/json"
}
})
}
function _startPollUserInfo(successCallback, interval, initialInterval) {
initialInterval = initialInterval || interval, _pollSuccessCallback = successCallback, _pollInterval = interval, _nextPoll(_pollUserInfo, initialInterval)
}
function _pollUserInfo() {
authService.getUserInfo().then(function(resp) {
resp ? (_pollSuccessCallback(), _pollPromise = void 0, _pollInterval = void 0, _pollSuccessCallback = void 0) : _nextPoll(_pollUserInfo, _pollInterval)
}).catch(function() {
_nextPoll(_pollUserInfo, _pollInterval)
})
}
function _nextPoll(pollCallback, interval) {
interval = interval || 1e3, $timeout.cancel(_pollPromise), _pollPromise = $timeout(pollCallback, interval)
}
var _pollPromise, _pollSuccessCallback, _pollInterval, restartAPI = "api/rest/system/restart";
return {
doRestart: function() {
return _doRestart()
},
checkForLife: function(successCallback, pollInterval, initialInterval) {
_startPollUserInfo(successCallback, pollInterval, initialInterval)
}
}
}), angular.module("voyager.security", []), angular.module("voyager.security").controller("AuthBaseCtrl", function($scope, authService, $window, config, localStorageService, configService) {
"use strict";
function authFail(response) {
error = response.data.error, $scope.error = error
}
var error;
$scope.canRemember = config.rememberMe, $scope.hideDefault = config.homepage.showDefaultCredentials === !1, $scope.consentTextFile = config.customizedLogin.consentTextFile, $scope.setDefaultCred = function() {
$scope.user = "admin", $scope.pass = "admin"
}, $scope.removeDefault = function() {
configService.hideDefaultCredentials().then(function() {
$scope.hideDefault = !0
})
}, $scope.authSuccess = function() {
"function" == typeof ga && ga("set", "&uid", $scope.user), error = null, $scope.error = error
}, $scope.handleEnter = function(ev) {
13 === ev.which && $scope.ok()
}, $scope.hasError = function() {
return !!error
}, $scope.ok = function() {
_.isEmpty($scope.user) || _.isEmpty($scope.pass) ? (error = !0, $scope.error = "Please enter your username and password") : (error = !1, authService.doLogin($scope, $scope.authSuccess, authFail))
}, $scope.methods = authService.getMethods(), $scope.methods.external && 1 === $scope.methods.all.length && ($window.location.href = $scope.methods.external[0].url), $scope.goExternal = function(method) {
$window.location.href = method.url
}
}), angular.module("voyager.security").controller("AuthCtrl", function($scope, $uibModalInstance, $controller) {
"use strict";
$controller("AuthBaseCtrl", {
$scope: $scope
});
var successCallback = $scope.authSuccess;
$scope.authSuccess = function() {
successCallback(), $uibModalInstance.close()
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}
}), angular.module("voyager.security").factory("authService", function($http, config, $q, $log, $analytics) {
function _setLoginState(response) {
return response && (_isAnonymous = angular.isUndefined(response.data.state) || "anonymous" === response.data.state, _state = response.data.state, _user = response.data.user, response.data.permissions && (permissions = response.data.permissions), response.data.user ? (loggedIn = !0, _sso = !0, _groups = response.data.user.groups) : loggedIn = !1, response.data.methods && (_methods = response.data.methods), observers.forEach(function(entry) {
entry(response)
}), authCallback && (authCallback(response), authCallback = null)), response
}
function _getInfoUrl() {
var url = config.root + "api/rest/auth/info.json?" + _PERMISSIONS_LIST + "&r=" + (new Date).getTime();
return _sso === !1 && (url += "&sso=false"), url
}
function _getPrivileges() {
return $http.get(_getInfoUrl(), {
cache: !1,
headers: {
"Cache-Control": "no-cache"
}
}).then(_setLoginState, defaultErrorCallback)
}
var errorCallback, authCallback, _user, _state, observers = [],
loggedIn = !1,
permissions = {},
_groups = [],
_sso = !0,
_isAnonymous = !0,
_PERMISSIONS = ["manage", "download", "process", "configure_view", "save_search", "share_saved_search", "view", "tag", "edit_fields", "flag", "view_tags", "show_metadata", "export", "shutdown_restart", "show_rss", "view_analytics"],
_PERMISSIONS_LIST = "check=" + _PERMISSIONS.join("&check="),
_methods = [],
defaultErrorCallback = function(response) {
return response.error ? $log.error(response.error) : $log.error("auth failed: " + JSON.stringify(response)),
response
},
doPost = function(request, action) {
return $http({
method: "POST",
url: config.root + "api/rest/auth/" + action + ".json",
data: request,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
}).then(function(response) {
response.action = action, _setLoginState(response), $analytics.eventTrack("search", {category: action, user: _user.id})
}, errorCallback)
};
return {
doLogin: function($scope, successHandler, errorHandler) {
errorCallback = errorHandler, authCallback = successHandler;
var request = "user=" + encodeURIComponent($scope.user) + "&pass=" + encodeURIComponent($scope.pass) + "&" + _PERMISSIONS_LIST;
return $scope.keepLoggedIn === !0 && (request += "&rememberMe=true"), doPost(request, "login")
},
doLogout: function() {
authCallback = null;
var request = "check=manage";
doPost(request, "logout"), loggedIn = !1, _sso = !1
},
getPrivileges: function() {
return _getPrivileges()
},
loadPrivileges: function() {
return _.isEmpty(permissions) ? _getPrivileges() : $q.when()
},
addObserver: function(obs) {
var index = _.findIndex(observers, function(item) {
return obs === item
});
index === -1 && observers.push(obs)
},
removeObserver: function(obs) {
observers = _.without(observers, function(item) {
return item === obs
})
},
isLoggedIn: function() {
return loggedIn
},
isAnonymous: function() {
return _isAnonymous
},
hasPermission: function(type) {
return permissions[type] && permissions[type] === !0
},
getUser: function() {
return _user
},
getGroups: function() {
return _groups
},
getGroupsJoined: function() {
return _groups.join()
},
getUserInfo: function() {
return $http.get(_getInfoUrl()).then(function(res) {
return res.data.user
})
},
fetchGroups: function() {
return $http.get(config.root + "api/rest/auth/info/groups").then(function(res) {
return res.data.groups
})
},
checkAccess: function() {
return _sso = !0, $http.get(_getInfoUrl()).then(function(res) {
var hasAccess = res.data.permissions.use_voyager;
return hasAccess && _setLoginState(res), hasAccess
})
},
getMethods: function() {
var methods = {
all: _methods
};
if (angular.isDefined(_methods)) {
methods.all = _methods.filter(function(method) {
return method.enabled === !0
});
var _this = this;
methods.all.forEach(function(method) {
method.displayName = _this.createDisplayName(method.name)
}), methods.external = _.filter(_methods, function(method) {
return method.displayName = _this.createDisplayName(method.name), angular.isDefined(method.url) && method.enabled === !0
}), 0 === methods.external.length && delete methods.external
} else methods.all = [];
return methods
},
createDisplayName: function(name) {
return config && config.customizedLogin && config.customizedLogin.customizeLoginText && config.customizedLogin.customizeLoginText[name] ? config.customizedLogin.customizeLoginText[name] : "Sign in with " + _.classify(name)
},
showLogout: function() {
var show = !0,
methods = this.getMethods().all;
if (1 === methods.length && "windows" === methods[0].name) {
var windowsAuth = methods[0];
windowsAuth.enableNtlm !== !0 && windowsAuth.enableNegotiate !== !0 || (show = !windowsAuth.hideLogout)
} else if (methods.length > 1) {
var self = this;
_.each(methods, function(method) {
"windows" !== method.name || self.hasPermission("manage") || method.enableNtlm !== !0 && method.enableNegotiate !== !0 || (show = !method.hideLogout)
})
}
return show
},
getState: function() {
return _state
}
}
}), angular.module("voyager.security").controller("AuthPageCtrl", function($scope, $state, $controller) {
"use strict";
$controller("AuthBaseCtrl", {
$scope: $scope
});
var successCallback = $scope.authSuccess;
$scope.authSuccess = function() {
successCallback(), $state.go("home")
}, $scope.authPage = !0
}), angular.module("voyager.modal", []), angular.module("voyager.modal").factory("vsModalService", function($uibModal) {
function _showModal(title, message, buttonText, cancelText) {
buttonText = buttonText || "OK";
var modal = $uibModal.open({
templateUrl: "common/modal/info-modal.html",
controller: "vsModalCtrl as vm",
resolve: {
model: function() {
return {
title: title,
message: message,
buttonText: buttonText,
cancelText: cancelText
}
}
}
});
return modal.result.then(function() {
return !0
}, function() {
return !1
})
}
return {
showModal: _showModal
}
}), angular.module("voyager.modal").controller("vsModalCtrl", function($scope, $uibModalInstance, model) {
var vm = this;
_.extend(vm, model), vm.ok = function() {
$uibModalInstance.close()
}, vm.cancel = function() {
$uibModalInstance.dismiss()
}
}), angular.module("voyager.modal").controller("ConfirmModalCtrl", function($scope, $uibModalInstance) {
var vm = this;
vm.modalHeader = "Please Confirm", vm.modalText = [], vm.confirmButtonText = "Confirm", vm.cancelLinkText = "Cancel", vm.confirm = function() {
$uibModalInstance.close(vm.confirmButtonText)
}, vm.cancel = function() {
$uibModalInstance.dismiss(vm.cancelLinkText)
}
}), angular.module("voyager.common.featured", []), angular.module("voyager.common.featured").factory("featuredService", function($http, $q) {
"use strict";
function _postForm(url, data) {
var service = config.root + url,
headerConfig = {
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
}
};
return $http.post(service, data, headerConfig)
}
function _toFormParam(key, value) {
var param = "&" + key + "=";
return param += _.isArray(value) ? value.join("&" + key + "=") : value
}
function _buildRequest(id) {
var service = config.root + "solr/v0/select?fq=id:" + id + "&fl=tag_flags";
return service + _type + "&rand=" + Math.random()
}
var _type = "&wt=json&json.wrf=JSON_CALLBACK",
_features = {};
return {
save: function(id, field, value, mode) {
var url = "api/rest/tag/record/" + id,
data = "field=" + field + _toFormParam("value", value);
return angular.isDefined(mode) && (data += "&mode=" + mode), _postForm(url, data)
},
fetch: function(id) {
return $http.jsonp(_buildRequest(id)).then(function(data) {
return data.data.response.docs[0]
})
},
fetchFeatures: function() {
var service = config.root + "api/rest/display/extensions/config";
return $http.get(service).then(function(res) {
return _features = _.indexBy(res.data.featureContentGroupList, "id")
})
},
getFeature: function(id) {
return _features[id]
},
getFeatures: function() {
return _features
}
}
});
var SavedSearchQuery = function() {
function _getQueryString(rows, filter) {
var queryString = _config.root + "solr/ssearch/select?";
return queryString += "rows=" + rows + "&rand=" + Math.random(), angular.isDefined(filter) && (queryString += "&fq=" + filter), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _execute(rows, filter) {
return _http.jsonp(_getQueryString(rows, filter)).then(function(data) {
return data.data.response.docs
}, function(error) {
return console.log(error), error
})
}
function _getSavedSearchParams(savedSearch) {
var solrParams = querystring.parse(_sugar.trim(savedSearch.query, "&"));
if (delete solrParams.facet, delete solrParams["facet.field"], delete solrParams["facet.mincount"], delete solrParams["extent.bbox"], angular.isUndefined(solrParams.shards) && savedSearch.path.indexOf("catalog=") !== -1) {
var voyagerParams = querystring.parse(_sugar.trim(savedSearch.path.replace(/\//g, "&"), "&"));
solrParams.shards = voyagerParams.catalog
}
return _sugar.decodeParams(solrParams), solrParams.disp = savedSearch.config, solrParams
}
var _config, _http, _sugar;
return function(config, $http, sugar) {
return _config = config, _http = $http, _sugar = sugar, {
execute: function() {
return _execute(100)
},
fetchDefault: function() {
return _execute(1)
},
fetch: function(id) {
return _execute(1, "id:" + id)
},
fetchDefaultParams: function() {
return _execute(1).then(function(docs) {
if (docs && docs.length > 0) {
var savedSearch = docs[0];
return _getSavedSearchParams(savedSearch)
}
return {}
})
}
}
}
}();
angular.module("voyager.common.savedsearch", ["voyager.util"]).factory("savedSearchQuery", function(config, $http, sugar) {
return new SavedSearchQuery(config, $http, sugar)
}), angular.module("simpleSearch", ["angularSpinner"]), angular.module("simpleSearch").factory("simpleSearch", function($http, config, $q, facetService, translateService) {
"use strict";
function _bytesToSize(bytes) {
var sizes = ["Bytes", "KB", "MB", "GB", "TB"];
if (0 === bytes) return "0 Bytes";
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + " " + sizes[i]
}
function _decorate(docs) {
return angular.forEach(docs, function(doc, index) {
doc.bytes && (doc.size = _bytesToSize(doc.bytes)), angular.isDefined(doc.thumb) && doc.thumb.indexOf("vres/mime") !== -1 && (doc.defaultThumb = !0)
}), docs
}
function _getParams(input, query, page) {
return query.q = getInput(input), query.rows = 100, query.start = 100 * (page - 1), query.wt = "json", query["json.wrf"] = "JSON_CALLBACK", query.block = !1, query.fl && (query.fl += ",name"), query
}
function _search(input, query, page, records) {
var params = _getParams(input, query, page);
return params.facet === !0 && (angular.isUndefined(params.facet.limit) && (params["facet.limit"] = 11), angular.isUndefined(params.facet.mincount) && (params["facet.mincount"] = 1)), $http.jsonp(config.root + "solr/v0/select", {
params: params
}).then(function(res) {
var docs = res.data.response.docs;
if (docs.length > 0 && page > 1 ? (docs = _decorate(docs), $.merge(records, docs)) : 1 === page && (docs = _decorate(docs), records.splice(0, records.length), $.merge(records, docs)), res.data.facet_counts && res.data.facet_counts.facet_fields) {
var facetFilters = facetService.buildAllFacets(res.data.facet_counts.facet_fields),
facetFields = [];
_.each(facetFilters, function(facets, name) {
facetFields.push({
filter: name,
display: translateService.getFieldName(name),
facets: facets
})
}), res.data.facetFields = facetFields
}
return res.data
})
}
var getInput = function(query) {
var input = "*:*";
return query && (input = query), input
};
return {
search: function(input, query, page, records) {
return angular.isUndefined(query) && (query = {}), _search(input, query, page, records)
}
}
}), angular.module("simpleSearch").directive("vgScroll", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
function _scroll() {
var spot = raw.scrollTop + raw.offsetHeight;
spot >= raw.scrollHeight - 50 && spot >= lastSpot && (scope.$emit("resultsBottom", {}), scope.$apply()), lastSpot = spot
}
var raw = element[0],
lastSpot = 0;
element.bind("scroll", _scroll), scope.$on("simpleSearch", function() {
element[0].scrollTop = 0
}), scope.$on("$destroy", function() {
element.unbind("scroll", _scroll)
})
}
}
}).controller("SimpleSearchCtrl", function($scope, $http, config, $window, $document, usSpinnerService, simpleSearch, $timeout, translateService) {
function _flagSelected() {
_.each($scope.facetFields, function(filter) {
_.each(filter.facets, function(facet) {
selectedFacets[facet.name] && (facet.isSelected = !0, lastSelected === filter.filter && (filter.displayState = "in"))
})
})
}
function _search(page) {
usSpinnerService.spin("simple-spinner"), simpleSearch.search($scope.searchInput, $scope.queryCriteria.query, page, $scope.docs).then(function(data) {
_busy = !1, $scope.facetFields = data.facetFields, _flagSelected(), 1 === page && $scope.$broadcast("simpleSearch", {}), usSpinnerService.stop("simple-spinner")
})
}
function _initQuery() {
$scope.queryCriteria.query || ($scope.queryCriteria.query = {}), $scope.queryCriteria.query.fq || ($scope.queryCriteria.query.fq = [])
}
function _addFilter(facet) {
lastSelected = facet.filter, facet.isSelected = !0, selectedFacets[facet.name] = facet, _initQuery(), $scope.queryCriteria.query.fq.push(facet.filter + ":" + facet.name)
}
function _removeFilter(facet) {
facet.isSelected = !1, delete selectedFacets[facet.name], _initQuery(), $scope.queryCriteria.query.fq = _.without($scope.queryCriteria.query.fq, facet.filter + ":" + facet.name)
}
function _loadNextChunk() {
_page += 1, _busy = !0, _search(_page)
}
var _busy = !1,
_page = 1,
selectedFacets = {},
lastSelected = "";
$scope.filterState = "Show", $scope.fields = ["name", "format"];
var showFields = $scope.queryCriteria.fields;
showFields && showFields.length > 0 && ($scope.fields = showFields), $scope.displayFields = [], _.each($scope.fields, function(field) {
$scope.displayFields.push(translateService.getFieldName(field))
}), $scope.queryCriteria.query && $scope.queryCriteria.query["facet.field"] && ($scope.facetFields = $scope.queryCriteria.query["facet.field"]), $scope.fieldWidth = 100 / $scope.fields.length, $scope.docs = [], $("#voyagerSearch").removeClass("container"), $timeout(function() {
_search(1)
}), $scope.searchClick = function() {
_search(1)
}, $scope.clearSearch = function() {
delete $scope.searchInput, _search(1)
}, $scope.toggleFilters = function() {
$scope.showFilters = !$scope.showFilters, $scope.filterState = $scope.showFilters ? "Hide" : "Show"
}, $scope.filterResults = function(facet) {
facet.isSelected ? _removeFilter(facet) : _addFilter(facet), _search(1)
}, $scope.toggleDisplayState = function(filter) {
$timeout(function() {
_.each($scope.facetFields, function(f) {
filter.filter !== f.filter && (f.displayState = "")
}), "in" !== filter.displayState ? filter.displayState = "in" : filter.displayState = ""
}, 0)
}, $scope.handleEnter = function(ev) {
13 === ev.which && _search(1)
}, $scope.$on("resultsBottom", function() {
_busy === !1 && _loadNextChunk()
}), $scope.setItem = function(item) {
$("#voyagerSearch").trigger("selectedItem", $scope.item), $scope.ok(item)
}, $scope.closeBrowser = function() {
$("#voyagerSearch").trigger("cancelSearch"), $scope.cancel()
}
}), angular.module("voyager.fields", []), angular.module("voyager.fields").factory("fieldService", function($http, config) {
"use strict";
return {
fetchFields: function() {
return $http.jsonp(config.root + "solr/fields/select?q=*:*&wt=json&rows=10000&json.wrf=JSON_CALLBACK").then(function(res) {
return res.data.response.docs
})
}
}
}), angular.module("voyager.heatmap", ["voyager.util"]), angular.module("voyager.heatmap").service("colorizer", function() {
function toHex(c) {
var hex = c.toString(16);
return 1 === hex.length ? "0" + hex : hex
}
function RGB(r, g, b, a) {
this.r = r, this.g = g, this.b = b, this.a = angular.isDefined(a) ? a : 1, this.push(r, g, b, this.a)
}
function HSL(h, s, l) {
this.h = h, this.s = s, this.l = l, this.push(h, s, l)
}
RGB.prototype = new Array, RGB.fromHex = function(hex) {
var res = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(hex);
return new RGB(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16), "undefined" != typeof res[4] ? parseInt(res[4], 16) / 255 : void 0)
}, RGB.prototype.hsl = function() {
var h, s, r = this.r / 255,
g = this.g / 255,
b = this.b / 255,
max = Math.max(r, g, b),
min = Math.min(r, g, b),
l = (max + min) / 2;
if (max === min) h = s = 0;
else {
var d = max - min;
switch (s = l > .5 ? d / (2 - max - min) : d / (max + min), max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4
}
h /= 6
}
return new HSL(h, s, l)
}, RGB.prototype.hex = function() {
return "#" + toHex(this.r) + toHex(this.g) + toHex(this.b)
}, RGB.prototype.rgba = function() {
return "rgba(" + this.join(",") + ")"
}, RGB.prototype.opacity = function(a) {
return new RGB(this.r, this.g, this.b, a)
}, RGB.prototype.opacify = function(a) {
return new RGB(this.r, this.g, this.b, this.a * a)
}, HSL.prototype = new Array, HSL.prototype.rgb = function() {
var r, g, b, h = this.h,
s = this.s,
l = this.l;
if (0 === s) r = g = b = l;
else {
var hue2rgb = function(p, q, t) {
return t < 0 && (t += 1), t > 1 && (t -= 1), t < 1 / 6 ? p + 6 * (q - p) * t : t < .5 ? q : t < 2 / 3 ? p + (q - p) * (2 / 3 - t) * 6 : p
},
q = l < .5 ? l * (1 + s) : l + s - l * s,
p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3), g = hue2rgb(p, q, h), b = hue2rgb(p, q, h - 1 / 3)
}
return new RGB(Math.round(255 * r), Math.round(255 * g), Math.round(255 * b))
};
this.rgb = function(r, g, b, a) {
return "string" == typeof r ? RGB.fromHex(r) : new RGB(r, g, b, a)
}, this.hsl = function(h, s, l) {
return new HSL(h, s, l)
}, this.interpolate = function(rgb1, rgb2, val) {
var hsl1 = rgb1.hsl(),
hsl2 = rgb2.hsl(),
hsl = hsl1.map(function(start, index) {
return start + val * (hsl2[index] - start)
}),
alpha = rgb1.a + val * (rgb2.a - rgb1.a);
return new HSL(hsl[0], hsl[1], hsl[2]).rgb().opacity(alpha)
}
}), angular.module("voyager.heatmap").service("heatmapService", function($q, $timeout, solrUtil, colorizer, $rootScope) {
function interpolate(min, max, method) {
var fx, delta = max - min;
if ("linear" === method) fx = function(x) {
return delta * x
};
else if ("exp" === method) fx = function(x) {
return Math.exp(x * Math.log(1 + delta)) - 1
};
else {
if ("log" !== method) throw "not supported: " + method;
fx = function(x) {
return delta * Math.log(x + 1) / Math.log(2)
}
}
return function(x) {
return min + fx(x)
}
}
function doFetch(bbox, level, offset, d) {
solrUtil.heatmap(bbox, query, level).then(function(result) {
var hm = result.data.facet_counts.facet_heatmaps.geohash;
0 !== offset ? doFetch(bbox, hm[1] + offset, 0, d) : (hm = _.zipObject(_.filter(hm, function(val, i) {
return i % 2 === 0
}), _.filter(hm, function(val, i) {
return i % 2 !== 0
})), d.resolve(hm))
})
}
function fire(evt, obj) {
_.forEach(callbacks[evt], function(cb) {
cb.call(null, obj)
})
}
var query = {
q: "*:*"
},
blur = 5,
offset = 0,
interpMethod = "linear",
callbacks = {
render: []
},
stats = !1,
opacity = config.searchMap.heatmapOpacity,
color1 = colorizer.rgb(config.searchMap.heatmapColor1),
color2 = colorizer.rgb(config.searchMap.heatmapColor2),
self = this;
this.fetch = function(bbox, level) {
var d = $q.defer();
return doFetch(bbox, level, offset, d), d.promise
}, this.init = function(map) {
var throttle = null,
HeatmapLayer = L.CanvasLayer.extend({
clear: function() {
var can = this.getCanvas(),
ctx = can.getContext("2d");
ctx.clearRect(0, 0, can.width, can.height)
},
renderGrid: function(hm) {
var hmRect = {
ul: map.latLngToContainerPoint({
lng: hm.minX,
lat: hm.maxY
}),
lr: map.latLngToContainerPoint({
lng: hm.maxX,
lat: hm.minY
})
};
hmRect.width = hmRect.lr.x - hmRect.ul.x, hmRect.height = hmRect.lr.y - hmRect.ul.y;
var can = this.getCanvas(),
ctx = can.getContext("2d");
ctx.strokeStyle = "rgb(0,255,0)", ctx.strokeRect(hmRect.ul.x, hmRect.ul.y, hmRect.width, hmRect.height)
},
render: function() {
$rootScope.$broadcast("renderHeatmapStarting", {
message: "started heatmap rendering"
}), null !== throttle && $timeout.cancel(throttle);
var layer = this;
layer.clear(), throttle = $timeout(function() {
self.fetch(map.getBounds().toBBoxString()).then(function(hm) {
layer.clear();
var values = hm.counts_ints2D;
if (!_.isEmpty(values)) {
if (stats === !0) {
var flatValues = _.flatten(values);
flatValues = _.filter(flatValues, function(val) {
return null !== val
}), hm.std = _.stdDeviation(flatValues), hm.max = _.max(flatValues), hm.min = _.min(flatValues)
} else hm.max = _.max(values.map(_.max)), hm.min = _.min(values.map(_.min));
var interp = interpolate(0, 1, interpMethod),
dx = (hm.maxX - hm.minX) / hm.columns,
dy = (hm.maxY - hm.minY) / hm.rows,
can = layer.getCanvas();
can.style.webkitFilter = "blur(" + blur + "px)";
for (var ctx = can.getContext("2d"), y = hm.maxY, i = 0; i < hm.rows; i++) {
var row = values[i];
if (!_.isEmpty(row))
for (var x = hm.minX, j = 0; j < hm.columns; j++) {
var p1 = map.latLngToContainerPoint({
lng: x,
lat: y
}),
p2 = map.latLngToContainerPoint({
lng: x + dx,
lat: y - dy
}),
val = interp(values[i][j] / hm.max);
if (val > 0) {
var rgb = colorizer.interpolate(color1, color2, val);
rgb = rgb.opacify(opacity), ctx.fillStyle = rgb.rgba(), ctx.fillRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y)
}
x += dx
}
y -= dy
}
fire("render", hm), $rootScope.$broadcast("renderHeatmapEnding", {
message: "started heatmap rendering"
})
}
})
}, 200)
}
}),
heatmap = new HeatmapLayer;
return map.on("zoomstart", function() {
heatmap.clear()
}), this.layer = heatmap, heatmap
}, this.on = function(evt, handler) {
callbacks[evt].push(handler)
}, this.filter = function(q) {
return query = q, self
}, this.blur = function(b) {
return blur = b, self
}, this.interpMethod = function(m) {
return interpMethod = m, self
}, this.offset = function(o) {
return offset = 0, self
}, this.stats = function(s) {
return stats = s, self
}, this.opacity = function(o) {
return opacity = o, self
}
}), angular.module("voyager.tagging", ["voyager.util"]), angular.module("voyager.tagging").controller("TagDialog", function($scope, $uibModalInstance, $analytics, tagService, doc) {
"use strict";
$scope.doc = doc, $scope.getDoc = function() {
return doc
}, $scope.ok = function() {
tagService.save($scope.id, $scope.field, $scope.value).then(function(response) {
$uibModalInstance.close(), $analytics.eventTrack("tag", {
category: "results",
id: $scope.id
})
}, function(error) {
console.log(error.data)
})
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}
}), angular.module("voyager.tagging").controller("TaggingCtrl", function($scope, tagService) {
"use strict";
function _fetch() {
tagService.fetch($scope.doc.id).then(function(res) {
$scope.tags = res.data.response.docs, $scope.working = !1
})
}
$scope.doc = $scope.getDoc(), $scope.field = config.tagFields[0].field, $scope.tagFields = config.tagFields, _fetch(), $scope.save = function() {
$scope.hasError = !1, $scope.working = !0, tagService.save($scope.doc.id, $scope.field, $scope.value).then(function() {
$scope.value = "", $scope.isSuccess = !0, _fetch()
}, function(error) {
$scope.working = !1, $scope.hasError = !0, $scope.error = error.data.error
})
}, $scope.humanize = function(value) {
return value.replace(/_/g, " ").replace(/(\w+)/g, function(match) {
return match.charAt(0).toUpperCase() + match.slice(1)
})
}, $scope.delete = function(pk) {
tagService.delete(pk).then(function() {
_fetch()
})
}
}), angular.module("voyager.tagging").factory("tagService", function($http, $q, $location, queryBuilder, sugar, solrUtil, config, solrGrunt) {
function _save(field, value, query, mode) {
angular.isUndefined(mode) && (mode = "REPLACE");
var service = solrUtil.toSolrQuery("solr/v0/usertag", query),
val = sugar.toArray(value);
"REMOVE" === mode && (val = null);
var updateMode = "UPDATE_DOCUMENT",
formBody = {
params: {
update: updateMode,
tags: [{
field: field,
value: val,
mode: mode
}]
}
};
return $http.post(service, formBody).then(function(response) {
return response.data.tagging
})
}
function _fetchTags(field) {
var deferred = $q.defer(),
service = config.root + "solr/usertags/select?q=*:*&rows=0&facet=true&facet.field=fss_tag_" + field + "&facet.mincount=1&facet.limit=1000&wt=json&json.wrf=JSON_CALLBACK&rand=" + Math.random();
return $http.jsonp(service).then(function(response) {
var tags = response.data.facet_counts.facet_fields["fss_tag_" + field];
tags = _.reject(tags, function(val) {
return _.isNumber(val)
}), deferred.resolve(tags)
}), deferred.promise
}
return {
save: function(id, field, value, action) {
return _save(field, value, {
fq: "id:" + id
}, action)
},
fetch: function(id) {
var service = config.root + "solr/usertags/select?q=*:*&fq=id:" + id + "&sort=when%20desc&wt=json&json.wrf=JSON_CALLBACK&rand=" + Math.random();
return $http.jsonp(service)
},
delete: function(pk) {
var service = config.root + "api/rest/tag/remove/" + pk;
return $http.delete(service)
},
lookup: function(id, field) {
var deferred = $q.defer();
return this.fetch(id).then(function(res) {
var tags = res.data.response.docs;
deferred.resolve(_.find(tags, {
field: field
}))
}), deferred.promise
},
deleteByField: function(id, field) {
return this.save(id, field, "", "REMOVE")
},
saveLabels: function(id, value) {
return _.isEmpty(value) ? void this.deleteByField(id, "tag_tags") : this.save(id, "tag_tags", value)
},
replace: function(id, field, value) {
return this.save(id, field, value, "REPLACE")
},
fetchTags: function() {
return _fetchTags("tags")
},
fetchFlags: function() {
return _fetchTags("flags")
},
saveBulkField: function(tagValue, field, docId) {
var query;
return query = angular.isDefined(docId) ? {
fq: "id:" + docId
} : solrGrunt.getSolrParams($location.search()), _save(field, tagValue, query)
},
removeBulkField: function(field) {
return _save(field, "", $location.search(), "REMOVE")
},
applyTag: function(tag, $scope, filterService) {
return $location.path().indexOf("/search") > -1 ? (filterService.clear(), $location.search("q", null), $location.search("place", null), $location.search("recent", null), $scope.$emit("removeFilterEvent", {})) : $location.path("search"), $location.search("fq", "tag_flags:" + tag), filterService.setFilters({
fq: "tag_flags:" + tag
}), $scope.$emit("filterEvent"), !1
}
}
}), angular.module("taskRunner", ["voyager.map", "fileBrowser", "ui.select2", "voyager.fields", "simpleSearch", "dialogs.main", "cart"]), angular.module("taskRunner").directive("vsGhostItems", function(taskService) {
"use strict";
function _setFilterParams($scope) {
$scope.param.ids = taskService.getItems()
}
return {
template: "<div></div>",
controller: function($scope) {
_setFilterParams($scope)
}
}
}), angular.module("taskRunner").directive("vsViewItems", function() {
return {
templateUrl: "src/taskrunner/params/view-items.html",
controller: function($scope) {
$scope.items = $scope.param.response.docs
}
}
}), angular.module("taskRunner").factory("templateService", function() {
"use strict";
var advancedIcon = '<i ng-show="param.advanced" class="fa fa-gear" title="Advanced"></i>',
requiredIcon = '<i ng-show="param.required" class="fa fa-asterisk" title="Required" style="margin-left: 2px; color: darkred; font-size: x-small"></i>',
errorTpl = '<div class="process-control alert alert-danger" style="color:red" ng-show="param.error"><span class="glyphicon glyphicon-arrow-up"/> {{param.error}}</div>',
labelTpl = '<dl style="margin-bottom: 5px"><dt>' + advancedIcon + "{{param.label}}" + requiredIcon + "<dt><dd>{{param.desc}}</dd></dl>",
selectTpl = '<select ui-select2="{dropdownAutoWidth: \'true\', minimumResultsForSearch: 5}" ng-model="param.value"> <option ng-repeat="option in param.choices" value="{{option}}">{{param.values[option]}}</option></select>',
projectionSelect = '<input type="hidden" ui-select2="select2Options" ng-model="param.selected">',
textInputTpl = '<input type="text" class="form-control" ng-model="param.value" style="width: 40%">',
intInputTpl = '<input type="number" class="form-control" ng-model="param.value" ng-blur="isInteger()" style="width: 30%">',
pwdInputTpl = '<input type="password" class="form-control" style="width: 40%" ng-model="param.value">',
fieldList = '<input vs-field-param param="param">',
fieldListTpl = '<div ng-hide="param.advanced && !show">' + labelTpl + fieldList + errorTpl + "</div>",
field = '<input vs-field-param param="param" multi="false">',
fieldTpl = '<div ng-hide="param.advanced && !show">' + labelTpl + field + errorTpl + "</div>",
permissions = '<input vs-list-param param="param" list="permissions" multi="true" data-placeholder="Private">',
permissionsTpl = '<div ng-hide="param.advanced && !show">' + labelTpl + permissions + errorTpl + "</div>",
combo = '<input vs-list-param param="param" list="permissions" multi="false" data-placeholder="">',
comboTpl = '<div ng-hide="param.advanced && !show">' + labelTpl + combo + errorTpl + "</div>",
projection = '<div ng-hide="param.advanced && !show" class="process-control">' + labelTpl + projectionSelect + errorTpl + "</div>",
stringChoice = '<div ng-hide="param.advanced && !show" class="process-control">' + labelTpl + selectTpl + errorTpl + "</div>",
textArea = '<div ng-hide="param.advanced && !show" class="process-control">' + labelTpl + '<textarea ng-model="param.value" style="width: 96%"></textarea>' + errorTpl + "</div>",
stringTpl = '<div ng-hide="param.advanced && !show" class="process-control">' + labelTpl + textInputTpl + errorTpl + "</div>",
checkBox = '<div ng-hide="param.advanced && !show" class="process-control"><dl style="margin-bottom: 5px"><dt>' + advancedIcon + '{{param.label}}<dt><dd><label style="font-weight: normal"><input type="checkbox" ng-model="param.value"> {{param.desc}}</label></dd></dl>' + errorTpl + "</div>",
missing = '<div class="process-control" style="color:red">Missing {{param.name}} template</div>',
intTpl = '<div ng-hide="param.advanced && !show" class="process-control">' + labelTpl + intInputTpl + errorTpl + "</div>",
pwdTpl = '<div ng-hide="param.advanced && !show" class="process-control">' + labelTpl + pwdInputTpl + errorTpl + "</div>",
readOnlyLabelTpl = '<label style="width:100%; padding-left: 5px; margin-bottom: 0px; border-color: #eeeeee; border-bottom-style: solid; border-width: 1px;color:#999999">{{param.label}} </label>',
readOnlyTpl = '<div class="process-control" style>' + readOnlyLabelTpl + '<div style="padding-left: 5px;">{{param.value}}</div></div>',
readOnlyListTpl = '<div class="process-control" style>' + readOnlyLabelTpl + '<div style="padding-left: 5px;">{{param.value.join()}}</div></div>',
pwdReadOnlyTpl = '<div class="process-control" style>' + readOnlyLabelTpl + '<input type="password" ng-model="param.value" ng-disabled="true" style="padding-left: 5px;"></div>',
dateTpl = labelTpl + '<div class="input-group date"><input type="text" placeholder="yyyy-mm-dd" class="form-control" uib-datepicker-popup="yyyy-MM-dd" is-open="isDateOpen" ng-click="openDatePicker($event)" ng-model="param.value" close-text="Close" ng-required="true"><span class="input-group-addon" style="width: 0" ng-click="openDatePicker($event)"><span class="glyphicon glyphicon-calendar" ng-click="openDatePicker($event)"></span></span></div>',
datePickOnlyTpl = labelTpl + '<div class="input-group date"><input type="text" readonly="true" placeholder="yyyy-mm-dd" class="form-control" uib-datepicker-popup="yyyy-MM-dd" is-open="isDateOpen" ng-click="openDatePicker($event)" ng-model="param.value" close-text="Close" ng-required="true"><span class="input-group-addon" style="width: 0" ng-click="openDatePicker($event)"><span class="glyphicon glyphicon-calendar" ng-click="openDatePicker($event)"></span></span></div>',
browseTpl = '<div class="input-group" style="width: 100%"><input type="text" class="form-control" ng-model="param.value"><span class="input-group-btn"><button class="btn btn-default" type="button" ng-click="open(\'lg\')"> Browse</button></span></div>',
searchInput = '<div class="input-group" style="width: 100%"><input type="text" class="form-control" ng-model="param.display"><span class="input-group-btn"><button class="btn btn-default" type="button" ng-click="search(\'lg\')"> Search</button></span></div>',
locationTpl = '<div class="process-control">' + labelTpl + browseTpl + errorTpl + "</div>",
searchTpl = '<div class="process-control">' + labelTpl + searchInput + errorTpl + "</div>",
templates = {
VoyagerResults: "<div vs-ghost-items></div>",
Projection: projection,
StringChoice: stringChoice,
Geometry: '<div style="height:100%; width:100%; max-width: 800px; display: inline-block" class="map">' + labelTpl + '<div vs-clip-map class="clip-map" />' + errorTpl + "</div>",
MapView: '<div style="height:100%; width:100%; max-width: 800px; display: inline-block" class="map">' + labelTpl + '<div vs-view-map class="clip-map" />' + errorTpl + "</div>",
TextArea: textArea,
String: stringTpl,
CheckBox: checkBox,
CatalogPath: locationTpl,
FolderLocation: locationTpl,
Integer: intTpl,
Password: pwdTpl,
FieldList: fieldListTpl,
Field: fieldTpl,
Permissions: permissionsTpl,
Combo: comboTpl,
IndexItem: searchTpl,
QueryIndex: searchTpl,
Date: dateTpl,
"VoyagerResults-readOnly": "<div>" + readOnlyLabelTpl + "<div vs-view-items></div></div>",
"Projection-readOnly": readOnlyTpl,
"StringChoice-readOnly": readOnlyTpl,
"Geometry-readOnly": '<div class="read-only-map">' + readOnlyLabelTpl + '<div vs-read-only-map class="clip-map" /></div>',
"MapView-readOnly": '<div class="read-only-map">' + readOnlyLabelTpl + '<div vs-read-only-map class="clip-map" /></div>',
"TextArea-readOnly": readOnlyTpl,
"String-readOnly": readOnlyTpl,
"CheckBox-readOnly": readOnlyTpl,
"CatalogPath-readOnly": readOnlyTpl,
"FolderLocation-readOnly": readOnlyTpl,
"Integer-readOnly": readOnlyTpl,
"Password-readOnly": pwdReadOnlyTpl,
"FieldList-readOnly": readOnlyListTpl,
"Permissions-readOnly": readOnlyListTpl,
"Combo-readOnly": readOnlyListTpl,
"Field-readOnly": readOnlyTpl,
"QueryIndex-readOnly": readOnlyTpl,
"Date-readOnly": datePickOnlyTpl
};
return {
get: function(type, readOnly) {
var suffix = "";
readOnly === !0 && (suffix = "-readOnly");
var template = templates[type + suffix];
return template || (template = missing), template
}
}
}), angular.module("taskRunner").factory("paramService", function(localStorageService, savedSearchService, $http) {
"use strict";
function _getParamDisplay(param, displayData) {
var paramData = displayData.params[param.name];
return _.isUndefined(paramData) && (paramData = {
display: "",
description: ""
}, paramData.display = _.str.humanize(param.name), paramData.display = _.str.titleize()), paramData
}
function _decorate(param, displayData) {
var paramDisplay = _getParamDisplay(param, displayData);
param.label = paramDisplay.display, param.desc = paramDisplay.description
}
function _initReadOnly(response, displayData) {
var readOnlyParams = {
params: [],
inputItems: [],
hasMap: !1
};
return $.each(response.data.params, function(index, param) {
"Projection" === param.type && (param.value = param.code), "Geometry" !== param.type && "MapView" !== param.type || (readOnlyParams.hasMap = !0, param.hasMap = !0), _decorate(param, displayData), "input_items" === param.name ? readOnlyParams.inputItems.push(param) : readOnlyParams.params.push(param)
}), readOnlyParams
}
function _applyChoicesAsValues(param) {
_.isUndefined(param.values) && !_.isUndefined(param.choices) && (param.values = {}, $.each(param.choices, function(index, value) {
param.values[value] = value
}))
}
function _initParam(param) {
"Geometry" !== param.type && "MapView" !== param.type || (param.hasMap = !0), angular.isUndefined(param.readOnly) && (param.readOnly = !1)
}
function _initParams(response, reload) {
var params = [],
mapParams = [];
_params.hasMap = !1, _params.hasAdvanced = !1, $.each(response[0].data.params, function(index, param) {
_initParam(param), param.hasMap ? (_params.hasMap = !0, param.reload = reload, mapParams.push(param)) : params.push(param), _decorate(param, response[1].data), _applyChoicesAsValues(param), param.advanced && (_params.hasAdvanced = !0), angular.isUndefined(param.readOnly) && (param.readOnly = !1)
}), _params.params = params, _params.mapParams = mapParams
}
var _params = {},
_projections = [],
_groups = {};
return $http.get("projections.json").then(function(response) {
$.each(response.data, function(name, value) {
var info = name.split("/"),
group = info[1];
_groups[group] ? _groups[group].children.push({
name: info[info.length - 1],
value: value,
group: info[1]
}) : _groups[group] = {
children: [{
name: info[info.length - 1],
value: value,
group: info[1]
}],
text: group
}, _projections.push({
name: info[info.length - 1],
value: value,
group: info[1]
})
})
}), {
initParams: function(response, reload) {
var lastRanParams = null;
return "export_result_list" !== response[0].data.task && "create_saved_search" !== response[0].data.task && (lastRanParams = localStorageService.get(response[0].data.task)),
null === lastRanParams ? _initParams(response, reload) : (_params = lastRanParams, _params.mapParams.length > 0 && (_params.mapParams[0].reload = reload, delete _params.mapParams[0].wkt)), _params
},
initReadOnly: function(response, displayData) {
return _initReadOnly(response, displayData)
},
getParams: function() {
return _params
},
getAllParams: function() {
$.each(_params.params, function(index, value) {
"Projection" === value.type && angular.isDefined(value.code.id) && (value.code = value.code.id)
});
var all = _params.params;
return _.isUndefined(_params.mapParams) || (all = all.concat(_params.mapParams)), JSON.parse(JSON.stringify(all))
},
setParams: function(params) {
_params = params
},
getStorable: function() {
var params = $.extend(!0, {}, _params);
return params.reload = !1, $.each(params.params, function(index, param) {
"input_items" === param.name && (delete param.query, delete param.ids), delete param.error
}), angular.isDefined(params.mapParams) && $.each(params.mapParams, function(index, param) {
delete param.wkt, delete param.extent, delete param.center, delete param.zoom, delete param.error
}), params
},
getProjections: function() {
return _groups
},
applyErrors: function(params, validations) {
$.each(validations, function(index, validated) {
validated.error && $.each(params, function(index, param) {
if (param.name === validated.name) return void(param.error = validated.error)
})
})
}
}
}), angular.module("taskRunner").directive("vsParam", function($compile, templateService, leafletData, paramService, $timeout, mapUtil) {
"use strict";
function _isGeometry($scope) {
return $scope.param.type && "Geometry" === $scope.param.type
}
function _isProjection($scope) {
return $scope.param.type && "Projection" === $scope.param.type
}
function _isCatalogPath($scope) {
return $scope.param.type && "CatalogPath" === $scope.param.type
}
function _setMapHeight(scope) {
var mapId = "view-map";
_isGeometry(scope) && (mapId = "clip-map");
scope.param.type;
scope.param.readOnly === !0 && (mapId = "read-only-map"), leafletData.getMap(mapId).then(function(map) {
var width = $(map.getContainer()).width(),
height = Math.round(width / 4 * 3);
0 === height && (height = 250), $(map.getContainer()).css("height", height), map.invalidateSize(!1), scope.param.resultsExtent && mapUtil.fitToBBox(map, scope.param.resultsExtent)
})
}
function _link(scope, element, attrs) {
if (!scope.param.hidden) {
var type = scope.param.type,
name = scope.param.name;
"List" === type && "groups" === name && (type = "Permissions"), "List" === type && "saved_searches" === name && (type = "Combo");
var template = templateService.get(type, scope.param.readOnly);
element.html(template).show(), $compile(element.contents())(scope), scope.param.hasMap === !0 && $timeout(function() {
_setMapHeight(scope)
})
}
}
function _controller($scope, $uibModal) {
var lastTerm = "",
filteredGroups = [];
if ($scope.browserType = "folder", _isCatalogPath($scope) && ($scope.browserType = "file"), _isProjection($scope)) {
var defaultSelect = {
id: 0,
text: "Same As Input"
};
$scope.param.selected && (defaultSelect = $scope.param.selected), $scope.select2Options = {
dropdownAutoWidth: "true",
minimumResultsForSearch: 5,
minimumInputLength: 3,
initSelection: function(element, callback) {
callback(defaultSelect)
},
query: function(query) {
var groups;
groups = 3 === query.term.length ? paramService.getProjections() : query.term.length > lastTerm.length ? filteredGroups.slice() : paramService.getProjections(), filteredGroups = [], lastTerm = query.term;
var name, term, data = {
results: []
};
$.each(groups, function(key, group) {
var filteredGroup = {
text: group.text,
children: []
};
$.each(group.children, function(i, projection) {
name = projection.name.toLowerCase(), term = query.term.toLowerCase(), name.indexOf(term) !== -1 && (projection.id = projection.value, projection.text = projection.name, filteredGroup.children.push(projection))
}), filteredGroup.children.length > 0 && filteredGroups.push(filteredGroup)
}), data.results = filteredGroups, query.callback(data)
}
}
}
$scope.open = function(size) {
var modalInstance = $uibModal.open({
templateUrl: "common/filebrowser/file-browser.html",
controller: "ModalBrowseCtrl",
size: size,
resolve: {
type: function() {
return $scope.browserType
},
path: function() {
return $scope.param.value
}
}
});
modalInstance.result.then(function(path) {
$scope.param.value = path
})
}, $scope.search = function(size) {
var modalInstance = $uibModal.open({
templateUrl: "common/simple-search/search.html",
controller: "ModalSearchCtrl",
size: size,
resolve: {
queryCriteria: function() {
return {
query: $scope.param.query,
fields: $scope.param.fields
}
}
}
});
modalInstance.result.then(function(item) {
$scope.param.value = item, $scope.param.display = item.name
})
}, $scope.openDatePicker = function($event) {
$event.stopPropagation(), $scope.isDateOpen = !0
}, $scope.isInteger = function() {
Number.isInteger($scope.param.value) ? $scope.param.error = null : $scope.param.error = "Must be an integer value"
}
}
return {
restrict: "E",
replace: !0,
link: _link,
controller: _controller,
scope: {
param: "=",
show: "="
}
}
}), angular.module("taskRunner").directive("vsFieldParam", function(fieldService) {
return {
replace: !0,
scope: {
param: "=",
show: "="
},
template: '<input type="hidden" ui-select2="fieldOptions" ng-model="param.value" style="width: 100%;">',
controller: function($scope, $element, $attrs) {
var _fields = [],
isMultiple = "false" !== $attrs.multi;
$scope.fieldOptions = {
multiple: isMultiple,
simple_tags: !0,
dropdownAutoWidth: !0,
minimumResultsForSearch: 10,
data: function() {
return {
results: _fields
}
}
}, fieldService.fetchFields().then(function(fields) {
_.each(fields, function(field) {
0 !== field.name.indexOf("_") && _fields.push({
id: field.name,
text: field.disp_en
})
})
})
}
}
}), angular.module("taskRunner").directive("vsListParam", function($compile, authService, savedSearchService) {
return {
replace: !0,
scope: {
param: "=",
show: "=",
list: "@list",
multi: "="
},
template: '<input type="hidden" ui-select2="listOptions" ng-model="param.value" ng-change="onChange()" style="width: 50%">',
controller: function($scope, $element, $attrs) {
var _options = [],
_searches = [],
_coreRoles = [{
id: "_EVERYONE",
text: "EVERYONE"
}, {
id: "_LOGGEDIN",
text: "LOGGEDIN"
}, {
id: "_ANONYMOUS",
text: "ANONYMOUS"
}],
isMultiple = "false" !== $attrs.multi;
!!$scope.multi == !1 && ($scope.onChange = function() {
angular.isDefined($scope.param.value) && $scope.param.value.length > 1 && ($scope.param.value = [$scope.param.value[1]])
}), !!$scope.multi == !1 ? $scope.listOptions = {
multiple: isMultiple,
dropdownAutoWidth: !0,
minimumResultsForSearch: 5,
tags: _searches
} : $scope.listOptions = {
multiple: isMultiple,
simple_tags: !0,
dropdownAutoWidth: !0,
minimumResultsForSearch: 5,
data: function() {
return {
results: _options
}
}
}, !!$scope.multi == !1 && savedSearchService.getSavedSearches().then(function(savedSearches) {
var sortedSavedSearches = savedSearchService.sortSavedSearches(savedSearches);
angular.forEach(sortedSavedSearches.personal, function(value) {
_searches.indexOf(value.title) === -1 && _searches.push(value.title)
})
}), "permissions" == $scope.list && authService.getPrivileges().then(function() {
authService.hasPermission("manage") ? ($.merge(_options, _coreRoles), authService.fetchGroups().then(function(groups) {
$.merge(_options, groups)
})) : authService.fetchGroups().then(function(groups) {
$.merge(_options, groups)
})
})
}
}
}), angular.module("taskRunner").factory("taskService", function($http, config, $q, cartService, cartItemsQuery, translateService, taskModalService, converter) {
"use strict";
function _buildQuery(isAdmin) {
var filter = "&fq=available:true";
return isAdmin && (filter = ""), config.root + "solr/tasks/select?q=*:*" + filter + "&rows=1000&sort=display_sort+asc&wt=json&json.wrf=JSON_CALLBACK&rand=" + Math.random()
}
function _post(request, validate) {
return $http({
method: "POST",
url: config.root + "api/rest/process/task?validate=" + validate,
data: request,
headers: {
"Content-Type": "application/json"
}
})
}
function _decorator(data) {
var groups = {};
return _.each(data, function(item) {
_.each(item.category, function(cat) {
"undefined" == typeof groups[cat] ? (groups[cat] = [], groups[cat].push(item)) : groups[cat].push(item)
})
}), groups
}
function _convertPlaceFilter(request) {
var inputItems = request.params.filter(function(item) {
return "input_items" === item.name
});
if (inputItems) {
var inputItemsParam = inputItems[0];
if (inputItemsParam.query && angular.isDefined(inputItemsParam.query.place)) {
var placeFq = converter.toPlaceFilter(inputItemsParam.query),
fq = [];
angular.isDefined(inputItemsParam.query.fq) && (fq = inputItemsParam.query.fq), fq.push(placeFq), inputItemsParam.query.fq = fq
}
}
}
var _items = [],
_extent = null,
errorMessage = "All the items in the cart are invalid formats";
return angular.isDefined(config.defaultTask) && !_.isEmpty(config.defaultTask) && (errorMessage = "All the items in the cart are invalid formats for: " + _.classify(config.defaultTask)), {
findAllTasks: function(isAdmin) {
return $http.jsonp(_buildQuery(isAdmin)).then(function(data) {
return _decorator(data.data.response.docs)
}, function(error) {
return error
})
},
lookupTaskType: function(type) {
var taskPromise = $http.get(config.root + "api/rest/process/task/" + type + "/init.json"),
taskDisplayPromise = $http.get(config.root + "api/rest/process/task/" + type + "/display.json?lang=en");
return $q.all([taskPromise, taskDisplayPromise])
},
lookupTask: function(type) {
return $http.get(config.root + "api/rest/process/task/" + type + "/init.json")
},
lookupTaskDisplay: function(type) {
return $http.get(config.root + "api/rest/process/task/" + type + "/display.json?lang=en")
},
execute: function(request) {
return _convertPlaceFilter(request), _post(request, !1)
},
validate: function(request) {
return _post(request, !0)
},
getTaskQueryCriteria: function(constraints, invalidItemsOnly) {
var query = cartService.getQuery(),
items = cartService.getItemsArray();
return query || (query = cartItemsQuery.getQueryCriteria({})), angular.isUndefined(query.solrFilters) && (query.solrFilters = []), angular.isUndefined(query.constraintFilters) && (query.constraintFilters = []), _.each(constraints, function(value) {
invalidItemsOnly === !0 ? (query.invalidItems = !0, 0 === items.length ? query.solrFilters.push("-(" + value + ")") : query.constraintFilters.push("-(" + value + ")")) : 0 === items.length ? query.solrFilters.push(value) : query.constraintFilters.push(value)
}), query
},
getTaskConstraintFormats: function(taskConstraints) {
var constraintFormats = [];
return _.each(taskConstraints, function(value) {
value = value.split(":")[1];
var values = value.split(" ");
values ? angular.forEach(values, function(value) {
value = value.replace("(", ""), value = value.replace(")", ""), value = translateService.getType(value), constraintFormats.push(value)
}) : (value = translateService.getType(value), constraintFormats.push(value))
}), constraintFormats
},
showTaskValidationError: function(constraintFormats) {
taskModalService.showTaskValidationError(errorMessage, constraintFormats)
},
validateTaskItems: function(constraints, invalidItemsOnly) {
var severity = 0,
items = cartService.getItemIds(),
query = this.getTaskQueryCriteria(constraints, invalidItemsOnly, items);
return query.constraints = !0, query.count = cartService.getCount(), invalidItemsOnly === !0 ? cartItemsQuery.execute(query, items) : cartItemsQuery.fetchItems(query, items).then(function(data) {
var count = data.count;
return angular.isDefined(data.bbox) && (_extent = data.bbox), count === query.count ? severity = 0 : 0 === count ? severity = 2 : count < query.count && (severity = 1), severity
})
},
checkStatus: function(id) {
return $http.get(config.root + "api/rest/process/job/" + id + ".json")
},
checkProgress: function(id) {
return $http.get(config.root + "api/rest/process/job/" + id + "/status.json")
},
cancel: function(id) {
return $http.delete(config.root + "api/rest/process/job/" + id + ".json")
},
notify: function(id, email) {
return $http.put(config.root + "api/rest/process/job/" + id + "/callback.json?email=" + email)
},
cancelNotify: function(id, email) {
return $http.delete(config.root + "api/rest/process/job/" + id + "/callback.json?email=" + email)
},
getFileUrl: function(id, name) {
return config.root + "api/rest/process/job/" + id + "/output/" + name
},
getFileDisplayName: function(name) {
return name.indexOf("stdout") > 0 ? "Processing Output" : name.indexOf("stderr") > 0 ? "Processing Error Log" : name
},
refresh: function() {
return $http.post(config.root + "api/rest/process/tasks/refresh.json")
},
getFileData: function(file, withoutMime) {
return withoutMime = withoutMime || !1, $http.get(file.downloadUrl + (withoutMime ? "" : "?mime=application/json"))
},
setItems: function(items) {
_items = items
},
getExtent: function() {
return _extent
},
getItems: function() {
return _items
},
getFiles: function(statusResponse) {
var _self = this,
files = [];
return statusResponse.data.output && statusResponse.data.output.children && $.each(statusResponse.data.output.children, function(index, file) {
file.format && 0 !== file.name.lastIndexOf("_", 0) && (file.downloadUrl = _self.getFileUrl(statusResponse.data.id, file.name), files.push(file))
}), files
},
getLogFiles: function(statusResponse) {
var _self = this,
files = [];
return statusResponse.data.output && statusResponse.data.output.children && $.each(statusResponse.data.output.children, function(index, file) {
file.format && 0 === file.name.lastIndexOf("_", 0) && (file.name.indexOf("stderr") > -1 || file.name.indexOf("stdout") > -1) && (file.downloadUrl = _self.getFileUrl(statusResponse.data.id, file.name), file.displayName = _self.getFileDisplayName(file.name), files.push(file))
}), files
},
getReport: function(statusResponse) {
var file = this.getReportFile(statusResponse);
return file ? $http.get(file.downloadUrl).then(function(response) {
return response.data
}) : $q.reject()
},
getReportFile: function(statusResponse) {
var _file, _self = this;
return statusResponse.data.output && statusResponse.data.output.children && $.each(statusResponse.data.output.children, function(index, file) {
file.format && 0 === file.name.lastIndexOf("_", 0) && file.name.indexOf("report") > -1 && (file.downloadUrl = _self.getFileUrl(statusResponse.data.id, file.name) + "/", file.displayName = _self.getFileDisplayName(file.name), _file = file)
}), _file
},
getCopyUrl: function(id) {
return config.root + "api/rest/process/job/" + id + "/run.json"
}
}
}), angular.module("taskRunner").controller("TaskCtrl", function($scope, taskService, taskModalService, usSpinnerService, paramService, localStorageService, cartService, cartItemsQuery, sugar, $location, $stateParams, $state) {
"use strict";
function _applyExtentToMapParams() {
_.isEmpty($scope.extent) || _.forEach(_.filter($scope.mapParams, function(p) {
return p.initWithResultsExtent === !0
}), function(p) {
p.resultsExtent = $scope.extent
})
}
function _prepare() {
var params = $scope.params.concat($scope.mapParams);
$.each(params, function(index, param) {
angular.isUndefined(param) || ("Projection" === param.type && (param.code = param.selected.id, param.value = param.code), delete param.error)
});
var inputItems = _.find(params, {
type: "VoyagerResults"
}),
query = _getQuery(cartService.getQuery(), cartService.getItemIds());
return query ? (inputItems.query = query, delete inputItems.ids) : (inputItems.ids = cartService.getItemIds(), delete inputItems.query), params
}
function _validate(params) {
_.each(params, function(param) {
angular.isDefined(param.required) && angular.isDefined(param.value) && 0 === param.value.length && delete param.value
});
var request = {
task: $scope.task.name,
params: params
};
return taskService.validate(request)
}
function _errorHandler(error, params) {
$scope.isRunning = !1, $scope.hasError = !0, $scope.errors = error.data.errors, paramService.applyErrors(params, error.data.params), usSpinnerService.stop("tasks-spinner")
}
function _applyItems(queryCriteria, items) {
var itemsStr = "",
sep = "";
items && items.length > 0 && (itemsStr = "id:(" + items.join(" ") + ")", sep = " OR "), angular.isDefined(queryCriteria.params.q) ? queryCriteria.params.q = itemsStr + sep + queryCriteria.params.q : "" !== itemsStr && (queryCriteria.params.q = itemsStr)
}
function _getQuery(queryCriteria, items) {
var query = {
params: {}
},
hasItems = !1;
return queryCriteria && (query = _.clone(queryCriteria)), _.isEmpty(items) || (_applyItems(query, items), hasItems = !0), angular.isDefined(query.solrFilters) && hasItems ? (query.params.q += " OR (" + query.solrFilters.join(" AND "), _.isEmpty(query.bounds) || (query.params.q += " AND " + query.bounds.replace("&fq=", "")), query.params.q += ")") : hasItems && !_.isEmpty(query.bounds) ? query.params.q += " OR (" + query.bounds.replace("&fq=", "") + ")" : angular.isDefined(query.filters) ? query.filters.search("&fq=") > -1 && (query.params.fq = query.filters.split("&fq=")) : angular.isDefined(query.solrFilters) && (query.params.fq = query.solrFilters), delete query.params.bbox, delete query.params.bboxt, query.params
}
$scope.task = $stateParams.task, $scope.taskList = $stateParams.taskList, $scope.extent = taskService.getExtent(), $scope.params = [], $scope.hasMap = !0, $scope.showAdvanced = !1;
var _init = function() {
$scope.hasError = !1, $scope.errors = {}, $scope.hasAdvanced = !1, $scope.showAdvanced = !1, $scope.displayCategory = cartService.getCount() > 100, usSpinnerService.spin("tasks-spinner"), _.isEmpty($scope.task) && ($scope.task = {
name: $stateParams.type
}), taskService.lookupTaskType($scope.task.name).then(function(response) {
$scope.task.display = response[1].data.display, $scope.task.description = response[1].data.description, $scope.task.helpURL = response[1].data.helpURL;
var params = paramService.initParams(response, $scope.task.reload);
params.reload = $scope.task.reload, $scope.hasAdvanced = params.hasAdvanced, $scope.params = params.params, $scope.mapParams = params.mapParams, $scope.hasMap = params.hasMap, _applyExtentToMapParams(), usSpinnerService.stop("tasks-spinner")
}, function() {
$scope.setError("Error occurred loading task"), usSpinnerService.stop("tasks-spinner")
})
};
_init(), $scope.setError = function(val) {
$scope.errorMessage = val, $scope.hasError = !0
}, $scope.selectTask = function(task) {
task.name !== $scope.task.name && task.available === !0 && (task.isNew = !0, $scope.task = $.extend({}, task), _init())
}, $scope.execTask = function() {
$scope.$emit("taskStatusEvent", "alert-running");
var params = _prepare();
_validate(params).then(function() {
var request = {
task: $scope.task.name,
params: params,
isModal: $scope.task.isModal
};
$scope.executeTask(request).then(function() {
$scope.task.isSelected = !1
})
}, function(error) {
_errorHandler(error, params)
})
}, $scope.executeTask = function(request) {
usSpinnerService.spin("tasks-spinner"), _.isUndefined(request) && (request = {
task: $scope.task.name,
params: paramService.getAllParams()
});
var params = paramService.getStorable();
localStorageService.add(request.task, params), $scope.isRunning = !0, $scope.hasError = !1;
var inputItems = _.find(request.params, {
type: "VoyagerResults"
});
return delete inputItems.ids, inputItems.query = _getQuery(cartService.getQuery(), cartService.getItemIds()), taskService.execute(request).then(function(response) {
request.isModal ? ($scope.$dismiss(), $stateParams.id = response.data.id, $stateParams.isModalTask = !0, taskModalService.showStatusModal()) : $state.go("status", {
id: response.data.id
})
}, function(error) {
_errorHandler(error, params)
})
}, $scope.cancel = function() {
$scope.$dismiss()
}, $scope.showInvalidTaskItems = function() {
return taskModalService.showInvalidTaskItems($scope.invalidTaskItems)
}, $scope.getInvalidTaskItems = function() {
taskService.validateTaskItems($scope.task.constraints, !0).then(function(data) {
$scope.invalidTaskItems = data.docs, $scope.showInvalidTaskItems($scope.invalidTaskItems).result.then(function() {
$scope.task.warning = !1
})
})
}
}), angular.module("taskRunner").controller("TasksCtrl", function($scope, taskService, usSpinnerService, authService, $state) {
"use strict";
function _loadTasks() {
taskService.findAllTasks($scope.canReload).then(function(response) {
$scope.taskList = response, usSpinnerService.stop("tasks-spinner"), $scope.refreshing = !1;
var unavailableTasks = [],
taskCount = 0;
angular.forEach($scope.taskList, function(tasks) {
tasks.warnings = 0, tasks.errors = 0, unavailableTasks = unavailableTasks.concat(_.filter(tasks, function(task) {
return taskService.validateTaskItems(task.constraints).then(function(severity) {
1 === severity ? tasks.warnings += 1 : 2 === severity && (tasks.errors += 1), task.severity = severity
}), task.available === !1
})), taskCount += tasks.length
}), $scope.hasUnavailable = unavailableTasks.length > 0, $scope.allUnavailable = unavailableTasks.length === taskCount, $scope.allUnavailable && ($scope.toggleTasksText = "Show Available")
})
}
$scope.toggleTasksText = "Show All", $scope.hasUnavailable = !1, $scope.hasInvalidItems = !1, $scope.constraintFormats = [], $scope.refreshTasks = function() {
$scope.refreshing = !0, usSpinnerService.spin("tasks-spinner"), taskService.refresh().then(function() {
_loadTasks()
})
}, $scope.selectTask = function(task) {
$scope.constraintFormats = taskService.getTaskConstraintFormats(task.constraints), taskService.validateTaskItems(task.constraints).then(function(severity) {
0 === severity ? (task.error = !1, task.warning = !1, $state.go("task", {
task: task,
type: task.name
})) : 1 === severity ? (task.error = !1, task.warning = !0, $scope.hasInvalidItems = !0, $state.go("task", {
task: task,
type: task.name
})) : 2 === severity && taskService.showTaskValidationError($scope.constraintFormats)
})
}, authService.getPrivileges().then(function() {
$scope.canReload = authService.hasPermission("manage"), _loadTasks()
})
}), angular.module("taskRunner").controller("StatusCtrl", function($scope, taskService, $stateParams, $timeout, config, $location, paramService, $window, usSpinnerService, $analytics, $uibModal, sugar) {
"use strict";
function _removeSolrBbox(query) {
var solrBbox;
if (_.isArray(query.fq)) {
var index = sugar.getIndex(query.fq, "bbox");
index !== -1 && (solrBbox = query.fq[index], query.fq.splice(index, 1))
} else angular.isDefined(query.fq) && query.fq.indexOf("bbox") !== -1 && (solrBbox = query.fq, delete query.fq);
return solrBbox
}
function _applyBbox(query) {
var solrBbox = _removeSolrBbox(query);
query.bbox || angular.isDefined(solrBbox) && (query.bboxt = "i", solrBbox.indexOf("IsWithin") !== -1 && (query.bboxt = "w"), query.bbox = solrBbox.substring(solrBbox.indexOf("(") + 1, solrBbox.indexOf(")")))
}
function _confirmStatus() {
taskService.checkStatus($scope.id).then(function(statusResponse) {
$scope.messages = statusResponse.data.errors, $scope.files = taskService.getFiles(statusResponse), $scope.logFiles = taskService.getLogFiles(statusResponse), taskService.getReport(statusResponse).then(function(report) {
$scope.report = report
}), $scope.warnings = statusResponse.data.warnings, !angular.isUndefined($scope.warnings) && $scope.warnings.length > 0 && ($scope.hasWarning = !0)
}, _self.statusError)
}
function _showFailureInfo(data) {
done("alert-danger"), "FAILED" === data.state ? (angular.isUndefined(data.status) ? $scope.errorMessage = $scope.type + " Task " + data.taskId + " " + data.state : $scope.errorMessage = data.status.text + " for " + $scope.type + " Task " + data.taskId, $scope.hasError = !0, $scope.statusMessage = "ERROR", $scope.statusDetail = "Your task could not be completed. View task log for details. " + info, $scope.statusIcon = _getIcon(data.state), $scope.statusColor = "alert-error", $scope.statusStyle = "background-color: #f2dede;") : ($scope.statusMessage = "Cancelled", $scope.statusDetail = "Your task was cancelled.", $scope.statusIcon = _getIcon("CANCELED")), _confirmStatus(), $analytics.eventTrack("process", {
category: $scope.type,
label: data.state
})
}
function _showActivityInfo(data) {
"RUNNING" === data.state && ($scope.statusIcon = _getIcon(data.state)), $scope.statusMessage = _.str.classify(data.state), _.isUndefined(data.status) || ($scope.progressMessage = data.status.text, $scope.hasProgressMessage = !0), _.isUndefined(data.progress) || ($scope.progress = data.progress), $scope.messageType = "alert-info"
}
function _showSuccessInfo(data, statusResponse) {
$scope.files = taskService.getFiles(statusResponse), $scope.logFiles = taskService.getLogFiles(statusResponse), taskService.getReport(statusResponse).then(function(report) {
$scope.report = report
}), $scope.statusMessage = "Completed", "WARNING" === data.state ? ($scope.statusMessage += " With Warnings", $scope.statusDetail = "Completed with Warnings. See task log for details.", $scope.statusIcon = _getIcon(data.state), $scope.statusColor = "alert-warning", $scope.messageType = "alert-warning") : ($scope.statusDetail = "Your task was successful.", $scope.statusIcon = _getIcon("SUCCESS"), $scope.statusColor = "alert-success", $scope.messageType = "alert-success"), $scope.files.length > 0 && ($scope.statusDetail = "You can now download your data by clicking the link below. " + $scope.statusDetail), $scope.statusDetail += info, $timeout(function() {
_confirmStatus()
}, 1e3), done($scope.messageType), $analytics.eventTrack("process", {
category: $scope.type,
label: data.state
})
}
function _getIcon(status) {
switch (status) {
case "PENDING":
return {
icon: "icon-queue_status_waiting",
color: "black"
};
case "RUNNING":
return {
icon: "fa fa-cog fa-spin",
color: "#337ab7"
};
case "FAILED":
return {
icon: "icon-queue_status_error",
color: "red"
};
case "CANCELED":
return {
icon: "icon-queue_status_cancled",
color: "black"
};
case "WARNING":
return {
icon: "icon-queue_status_complete",
color: "orange"
};
default:
return {
icon: "icon-queue_status_complete",
color: "green"
}
}
}
function _reset(isRunning) {
$scope.params = [], $scope.inputItems = [], $scope.files = [], $scope.statusDetail = "", $scope.progressMessage = "", $scope.isRunning = isRunning, $scope.hasProgressMessage = !1, $scope.hasProgressMessage = "", $scope.statusMessage = "is Initializing", $scope.progress = [], $scope.hasError = !1, $scope.hasWarning = !1, $scope.statusIcon = "", $scope.showFile = !1, $scope.messages = [], $scope.logFiles = [], $scope.warnings = [], isRunning && ($scope.statusIcon = _getIcon("RUNNING"))
}
$scope.messageType = "alert-info", $scope.state = "RUNNING", $scope.id = $stateParams.id, $scope.allowNotify = !1, $scope.email = "", $scope.emailButtonText = "Notify Me When Done", $scope.isRunning = !0, $scope.hasItems = !1, $scope.isSuccess = !1, $scope.downloadUrl = "", $scope.messages = [], $scope.isDetailsOpen = !0, $scope.statusMessage = "", $scope.isDetailsCollapsed = !0, $scope.showLog = !0, $scope.logFiles = [], $scope.showFile = !1, $scope.$emit("taskStatusEvent", "alert-running");
var timer, info = "",
isModalTask = $stateParams.isModalTask,
_self = this,
attempts = 0,
canNotify = !0,
done = function(messageType) {
attempts = 0, $scope.messageType = messageType, $scope.allowNotify = !1, $scope.isRunning = !1, $scope.hasProgressMessage = !1, $scope.progress = [], $scope.$emit("taskStatusEvent", messageType)
};
this.statusError = function(data) {
done("alert-danger"), $scope.messages.push({
message: data.error,
trace: data.error
}), $scope.state = "FAILED", $scope.statusIcon = _getIcon($scope.state)
};
var updateStatusCallback = function(id) {
$scope.statusReady = !0, usSpinnerService.stop("status-spinner"), _.isUndefined(id) && (id = $scope.id), $scope.id === id && taskService.checkProgress(id).then(_self.updateStatus)
};
this.startCheckStatus = function(response) {
$scope.copyUrl = taskService.getCopyUrl($scope.id), taskService.lookupTaskDisplay(response.data.task).then(function(res) {
if ($scope.type = res.data.display, !_.isUndefined(response.data.params)) {
var readOnlyParams = paramService.initReadOnly(response, res.data),
searchParams = $location.search();
$scope.params = readOnlyParams.params, $scope.inputItems = readOnlyParams.inputItems;
var query = readOnlyParams.inputItems[0].query;
if (query) sugar.removeDoubleQuotes(query), _applyBbox(query), $scope.searchItemURL = "search?disp=" + searchParams.disp + "&" + sugar.toNavigoQueryString(query);
else {
var ids = readOnlyParams.inputItems[0].ids,
idParams = ids.join("&fq=id:");
$scope.searchItemURL = "search?disp=" + searchParams.disp + "&fq=id:" + idParams
}
$scope.hasMap = readOnlyParams.hasMap, $scope.taskItems = readOnlyParams.inputItems[0].response.docs, $scope.itemCount = readOnlyParams.inputItems[0].response.numFound
}
updateStatusCallback(response.data.id)
})
}, this.updateStatus = function(response) {
var data = response.data;
$scope.hasItems = !0, $scope.state = _.str.classify(data.state), "FAILED" === data.state || "CANCELED" === data.state ? _showFailureInfo(data) : "RUNNING" === data.state || "PENDING" === data.state ? (_showActivityInfo(data), attempts++, $scope.allowNotify === !1 && config.enableEmail === !0 && canNotify === !0 && ($scope.allowNotify = !0), timer = $timeout(function() {
updateStatusCallback(data.taskId)
}, 1e3)) : ($scope.isSuccess = !0, taskService.checkStatus($scope.id).then(function(statusResponse) {
$scope.warnings = statusResponse.data.warnings, !angular.isUndefined($scope.warnings) && $scope.warnings.length > 0 && ($scope.hasWarnings = !0), _showSuccessInfo(data, statusResponse)
}, _self.statusError))
}, $location.path().indexOf("status") > -1 && ($scope.id = $stateParams.id, taskService.checkStatus($scope.id).then(_self.startCheckStatus, _self.statusError), $scope.isStandalone = !0), isModalTask && (taskService.checkStatus($scope.id).then(_self.startCheckStatus, _self.statusError), $scope.isStandalone = !0), $scope.hasMessage = function() {
return $scope.messages && $scope.messages.length > 0
}, $scope.emailClick = function() {
"Cancel Notify" === $scope.emailButtonText ? (taskService.cancelNotify($scope.id, $scope.email), $scope.emailButtonText = "Notify Me When Done") : (taskService.notify($scope.id, $scope.email), $scope.emailButtonText = "Cancel Notify"), $(".hover_flyout, .opened").removeClass("opened")
}, $scope.cancelClick = function() {
usSpinnerService.spin("status-spinner"), timer && $timeout.cancel(timer), _reset(!1), $scope.statusMessage = "Cancelled", taskService.cancel($scope.id).then(function() {
usSpinnerService.stop("status-spinner")
}, function() {
usSpinnerService.stop("status-spinner")
})
}, $scope.$on("$destroy", function() {
timer && $timeout.cancel(timer)
}), $scope.cancel = function() {
$scope.$dismiss()
}, $scope.getData = function(file) {
$uibModal.open({
templateUrl: "src/taskrunner/task-log.html",
controller: "TaskLogCtrl",
size: "lg",
resolve: {
file: function() {
return file
},
task: function() {
return {
id: $scope.id,
type: $scope.type
}
}
}
})
}, $scope.showDetails = function() {
$uibModal.open({
templateUrl: "src/taskrunner/task-details.html",
controller: "TaskDetailsCtrl",
size: "lg",
resolve: {
inputItems: function() {
return $scope.inputItems
},
params: function() {
return $scope.params
},
task: function() {
return {
id: $scope.id,
type: $scope.type
}
}
}
})
}, $scope.showUrl = function() {
$scope.showCopyUrl = !0, $timeout(function() {
document.getElementById("copy-url").select()
}, 0)
}, $scope.showReport = function() {
var size = "sm";
($scope.report.Skipped || $scope.report.Errors) && (size = "lg"), $uibModal.open({
templateUrl: "src/taskrunner/task-report.html",
controller: "TaskReportCtrl",
size: size,
resolve: {
data: function() {
return {
report: $scope.report,
size: size
}
}
}
})
}
}), angular.module("taskRunner").controller("TaskLogCtrl", function($scope, $uibModalInstance, taskService, usSpinnerService, file, task) {
"use strict";
$scope.task = task, usSpinnerService.spin("spinner"), taskService.getFileData(file, !0).then(function(response) {
usSpinnerService.stop("spinner"), $scope.logFileData = response.data
}), $scope.download = function() {
window.location.href = file.downloadUrl
}, $scope.cancel = function() {
$uibModalInstance.close()
}
}), angular.module("taskRunner").controller("TaskDetailsCtrl", function($scope, $uibModalInstance, inputItems, params, task) {
"use strict";
$scope.task = task, $scope.inputItems = inputItems, $scope.params = params, $scope.cancel = function() {
$uibModalInstance.close()
}
}), angular.module("taskRunner").controller("TaskReportCtrl", function($scope, $uibModalInstance, data) {
"use strict";
$scope.data = data.report, $scope.hasDetails = "lg" === data.size, $scope.cancel = function() {
$uibModalInstance.close()
}
}), angular.module("taskRunner").factory("taskModalService", function($uibModal) {
"use strict";
var modalInstance = null;
return {
showTaskValidationError: function(errorMessage, constraintFormats) {
$uibModal.open({
templateUrl: "src/taskrunner/task-error-dialog.html",
controller: "TaskErrorCtrl",
size: "lg",
resolve: {
errorMessage: function() {
return errorMessage
},
constraintFormats: function() {
return constraintFormats
}
}
})
},
showInvalidTaskItems: function(invalidTaskItems) {
return modalInstance = $uibModal.open({
templateUrl: "src/taskrunner/invalid-items-dialog.html",
controller: "InvalidItemsCtrl",
size: "lg",
resolve: {
invalidTaskItems: function() {
return invalidTaskItems
}
}
})
},
showStatusModal: function() {
return modalInstance = $uibModal.open({
templateUrl: "src/taskrunner/status_modal.html",
controller: "StatusCtrl",
size: "lg"
})
},
close: function() {
modalInstance.close()
}
}
}), angular.module("taskRunner").controller("TaskErrorCtrl", function($scope, $uibModalInstance, errorMessage, constraintFormats) {
"use strict";
$scope.errorMessage = errorMessage, $scope.constraintFormats = constraintFormats, $scope.cancel = function() {
$uibModalInstance.dismiss("close")
}
}), angular.module("taskRunner").directive("vsCartItems", function(cartItemsQuery, cartService, taskService, taskModalService, $location) {
return {
templateUrl: "src/taskrunner/cart-items.html",
scope: {
cartItems: "=",
invalid: "=",
displayCategory: "=",
task: "="
},
controller: function($scope) {
$scope.disp = $location.search().disp || "default";
var _removeValue = function(array, id) {
return _.reject(array, function(item) {
return item.id === id
})
};
$scope.removeItem = function(id) {
cartService.remove(id), $scope.cartItems = _removeValue($scope.cartItems, id)
}, $scope.removeInvalidItems = function(invalidItems) {
$.each(invalidItems, function(index, item) {
cartService.remove(item.id), $scope.cartItems = _removeValue($scope.cartItems, item.id)
}), taskModalService.close()
}, $scope.removeItemByFormat = function(item) {
if (angular.isDefined(item)) cartService.removeByFormat(item.key), cartService.fetch().then(function(data) {
cartService.setQueryCount(data.count),
$scope.cartItemCount = data.count, $scope.cartItems = data.docs, $scope.loading = !1
});
else {
var items = cartService.getItemIds(),
query = taskService.getTaskQueryCriteria($scope.task.constraints, !1, items);
cartItemsQuery.fetchItems(query, items).then(function(data) {
cartService.addQuery(query, items), cartService.setQueryCount(data.count), taskModalService.close()
})
}
}
}
}
}), angular.module("taskRunner").controller("InvalidItemsCtrl", function($scope, $uibModalInstance, invalidTaskItems) {
"use strict";
$scope.invalidTaskItems = invalidTaskItems, $scope.cancel = function() {
$uibModalInstance.dismiss("close")
}
}), angular.module("taskRunner").factory("jobService", function($http, config, $q) {
return {
fetchJobs: function() {
var jobsPromise = $http.jsonp(config.root + "solr/jobs/select?q=*:*&sort=queue_time%20desc&wt=json&rows=100&json.wrf=JSON_CALLBACK&rand=" + Math.random()),
displayPromise = $http.jsonp(config.root + "solr/tasks/select?q=*:*&fl=name,display&wt=json&rows=1000&json.wrf=JSON_CALLBACK");
return $q.all([jobsPromise, displayPromise])
},
execute: function(job) {
return $http.post(config.root + "api/rest/process/job/" + job.id + "/run.json")
},
getCopyUrl: function(id) {
return config.root + "api/rest/process/job/" + id + "/run.json"
}
}
}), angular.module("taskRunner").controller("JobsCtrl", function($scope, jobService, $stateParams, config, $window, taskService, sugar, usSpinnerService, urlUtil, $location) {
function getIcon(status) {
switch (status) {
case "PENDING":
return {
icon: "icon-queue_status_waiting",
color: "black"
};
case "RUNNING":
return {
icon: "fa fa-cog fa-spin",
color: "#337ab7"
};
case "FAILED":
return {
icon: "icon-queue_status_error",
color: "red"
};
case "CANCELED":
return {
icon: "icon-queue_status_cancled",
color: "black"
};
case "WARNING":
return {
icon: "icon-queue_status_complete",
color: "orange"
};
case "SUCCESS":
return {
icon: "icon-queue_status_complete",
color: "green"
};
default:
return {
icon: "icon-queue_status_radioactive",
color: "slategray"
}
}
}
function _getItems(list) {
return _.find(list, function(item) {
return "VoyagerResults" === item.type
})
}
function _getFiles(output) {
var files = sugar.toArray(output);
return _.filter(files, function(file) {
return file.indexOf("_") === -1
})
}
$scope.display = $location.search().disp || "default", $scope.goBack = function() {
var params = sugar.retroParams($stateParams);
$window.location.href = config.root + config.explorePath + "/" + params
}, jobService.fetchJobs().then(function(response) {
var jobs = response[0].data.response.docs,
jobsDisplay = _.indexBy(response[1].data.response.docs, "name");
$.each(jobs, function(index, job) {
job.statusIcon = getIcon(job.state), angular.isUndefined(job.output_name) || $.each(job.output_name, function(index, value) {
value.indexOf("_") === -1 && (job.hasDownload = !0)
});
var jobDisplay = jobsDisplay[job.task];
angular.isUndefined(jobDisplay) ? job.displayName = _(job.task).chain().humanize().titleize().value() : job.displayName = jobDisplay.display
}), $scope.jobs = jobs, usSpinnerService.stop("job-spinner")
}), $scope.viewItems = function(job) {
var data = JSON.parse(job.json),
resultsParam = _getItems(data.params),
params = $location.search();
sugar.removeDoubleQuotes(resultsParam.query), $window.location = "search?disp=" + params.disp + "&" + sugar.toQueryString(resultsParam.query)
}, $scope.download = function(job) {
var files = _getFiles(job.output_name);
if (1 === files.length) {
var file = files[0],
downloadUrl = taskService.getFileUrl(job.id, file);
$window.location.href = downloadUrl
} else $window.location.href = "status?id=" + job.id
}, $scope.isDone = function(job) {
return "PENDING" !== job && "RUNNING" !== job
}, $scope.run = function(job) {
usSpinnerService.spin("job-spinner"), jobService.execute(job).then(function(response) {
var newJobId = response.data.id;
$window.location.href = "status?id=" + newJobId
}, function() {
usSpinnerService.stop("job-spinner")
})
}
}), angular.module("taskRunner").controller("ModalBrowseCtrl", function($scope, $uibModalInstance, type, path) {
"use strict";
$scope.browserType = type, $scope.path = path, $scope.ok = function(path) {
$uibModalInstance.close(path)
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}
}), angular.module("taskRunner").controller("ModalSearchCtrl", function($scope, $uibModalInstance, queryCriteria) {
"use strict";
$scope.queryCriteria = queryCriteria, $scope.isModal = !0, $scope.ok = function(path) {
$uibModalInstance.close(path)
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}
}), angular.module("voyager.map", ["voyager.util"]), angular.module("voyager.map").factory("mapUtil", function(leafletData, config, $timeout) {
"use strict";
function _getWeight(type) {
var weight = 3;
return void 0 !== type && (weight = "within" === type.toLowerCase() ? config.searchMap.bboxWithinWidth : config.searchMap.bboxIntersectsWidth), weight
}
function _getBounds(bbox) {
bbox = bbox.replace(/,/g, " ");
var bboxCoords = bbox.split(" "),
recStart = {
lat: bboxCoords[3],
lng: bboxCoords[0]
},
recEnd = {
lat: bboxCoords[1],
lng: bboxCoords[2]
};
return [recStart, recEnd]
}
function _getStyle(type, weight) {
var color = config.searchMap.footprintColor,
_weight = config.searchMap.footprintWidth;
return angular.isDefined(type) && (color = "within" === type.toLowerCase() ? config.searchMap.bboxWithinColor : config.searchMap.bboxIntersectsColor, _weight = _getWeight(type)), angular.isDefined(weight) && (_weight = weight), {
color: color,
weight: _weight
}
}
return {
getWGS84CRS: function() {
var _wgs84Proj = L.extend({}, L.Projection.LonLat, {
bounds: L.bounds([-180, -90], [180, 90])
}),
_wgs84 = L.extend({}, L.CRS, {
projection: _wgs84Proj,
transformation: new L.Transformation(1 / 180, 1, -1 / 180, .5),
getSize: function(zoom) {
var b = this.projection.bounds,
s = this.scale(zoom),
min = this.transformation.transform(b.min, s),
max = this.transformation.transform(b.max, s);
return L.point(Math.abs(max.x - min.x), Math.abs(max.y - min.y))
}
});
return _wgs84
},
getRectangle: function(bbox, type, weight) {
var bounds = _getBounds(bbox),
style = _getStyle(type, weight);
return L.rectangle(bounds, {
color: style.color,
weight: style.weight,
fill: !1
})
},
getPolygon: function(geo, type, weight) {
var style = _getStyle(type, weight);
return L.polygon(geo.coordinates[0], {
color: style.color,
weight: style.weight,
fill: !1
})
},
getGeoJson: function(geo, type, weight) {
_.isString(geo) && (geo = JSON.parse(geo));
var style = _getStyle(type, weight),
isPoint = "Point" === geo.type || "MultiPoint" === geo.type;
return L.geoJson(geo, {
style: {
color: style.color,
weight: isPoint ? 0 : style.weight,
opacity: .65,
fill: isPoint,
fillOpacity: .65
},
pointToLayer: function(f, ll) {
return L.circleMarker(ll, {
radius: 6,
fillColor: style.color
})
}
})
},
drawBBox: function(map, bbox, fit, type) {
var weight = _getWeight(type),
box = this.getRectangle(bbox, type, weight);
return map.addLayer(box), fit && map.fitBounds(_getBounds(bbox)), box
},
drawPolygon: function(map, geo, fit, type) {
var weight = _getWeight(type),
polygon = this.getPolygon(geo, type, weight);
return map.addLayer(polygon), fit && map.fitBounds(polygon.getBounds()), polygon
},
drawGeoJson: function(map, geo, fit, type, checkArea) {
var weight = _getWeight(type),
geoJson = this.getGeoJson(geo, type, weight),
bounds = geoJson.getBounds(),
area = 1e5;
if (checkArea) {
var lyr = L.GeoJSON.geometryToLayer(geo),
latlngs = lyr.getLatLngs();
if (area = L.GeometryUtil.geodesicArea(latlngs), area < 15e3 && 0 !== area && "Point" !== geo.type) {
geo.type = "Point";
var center = bounds.getCenter();
geo.coordinates = [center.lng, center.lat], geoJson = this.getGeoJson(geo, type, 3)
}
}
return map.addLayer(geoJson), fit && $timeout(function() {
map.currentBounds = bounds, map.fitBounds(bounds), area < 15e3 && 0 !== area && map.setZoom(3)
}), geoJson
},
fitToBBox: function(map, bbox, checkArea) {
var bounds = _getBounds(bbox);
if (map.fitBounds(bounds), checkArea) {
var area = L.GeometryUtil.geodesicArea(bounds);
area < 15e3 && map.setZoom(3)
}
},
isWkt: function(args) {
var wkt = new Wkt.Wkt;
try {
wkt.read(args)
} catch (e1) {
try {
wkt.read(args.replace("\n", "").replace("\r", "").replace("\t", ""))
} catch (e2) {
return !1
}
}
return !0
},
getWkt: function(args) {
var wkt = new Wkt.Wkt;
try {
wkt.read(args)
} catch (e1) {
try {
wkt.read(args.replace("\n", "").replace("\r", "").replace("\t", ""))
} catch (e2) {
if ("WKTError" === e2.name) return void alert("Wicket could not understand the WKT string you entered. Check that you have parentheses balanced, and try removing tabs and newline characters.")
}
}
return wkt.toObject({})
},
moveMapTo: function(wktObj, map) {
if (void 0 !== wktObj.getBounds && "function" == typeof wktObj.getBounds) {
var height = $(map.getContainer()).height();
height > 0 ? map.fitBounds(wktObj.getBounds()) : map.moveToLater = wktObj.getBounds()
} else void 0 !== wktObj.getLatLng && "function" == typeof wktObj.getLatLng && map.panTo(wktObj.getLatLng())
},
setExtent: function(map, param) {
var bounds = map.getBounds();
param.extent = bounds.toBBoxString().replace(/,/g, " ");
var center = bounds.getCenter();
param.center = center.lat + " " + center.lng, param.zoom = map.getZoom()
},
startDraw: function(e, mapId) {
leafletData.getMap(mapId).then(function(map) {
var options = {
shapeOptions: {
strokeOpacity: .8,
fillOpacity: 0
},
showArea: !1
};
if ("clip-rectangle" === e.target.id) new L.Draw.Rectangle(map, options).enable();
else {
var polygon = new L.Draw.Polygon(map, options);
polygon.enable()
}
})
},
getBounds: function(bbox) {
return _getBounds(bbox)
},
isBbox: function(value) {
var isBbox = !1;
if (_.isString(value) && !_.isEmpty(value)) {
var coords = value.split(" "),
nonNumeric = _.find(coords, function(val) {
return isNaN(val)
});
angular.isUndefined(nonNumeric) && (isBbox = !0)
}
return isBbox
},
convertToWkt: function(latlngs) {
var wkt = new Wkt.Wkt;
return wkt.fromObject(latlngs), wkt.write()
},
formatWktForDisplay: function(wkt) {
if (!this.isWkt(wkt)) return wkt;
var wktArray = wkt.split(" "),
firstPartWkt = wktArray[0].split("."),
lastPartWkt = wktArray.pop().split("."),
shortWkt = firstPartWkt[0];
if (firstPartWkt[1] && (shortWkt += "." + firstPartWkt[1].substring(0, firstPartWkt[1].length > 1 ? 2 : 1)), shortWkt += " ... " + lastPartWkt[0], lastPartWkt[1]) {
var endLastPartArray = lastPartWkt[1].split(")");
endLastPartArray[0].length > 2 && (endLastPartArray[0] = endLastPartArray[0].substring(0, 2)), shortWkt += "." + endLastPartArray.join(")")
}
return shortWkt
},
currentColor: function(type) {
return "Within" === type ? config.searchMap.bboxWithinColor : config.searchMap.bboxIntersectsColor
},
currentWeight: function(type) {
return _getWeight(type)
}
}
}), angular.module("voyager.map").factory("mapControls", function($compile, leafletData, mapUtil, configService) {
"use strict";
function _getControls(template, $scope) {
var controls = L.control();
return controls.setPosition("topleft"), controls.onAdd = function() {
return $compile($(template))($scope)[0]
}, controls
}
function _toggleState(map, $scope, zoomLevel) {
void 0 === zoomLevel && (zoomLevel = map.getZoom()), zoomLevel === map.getMaxZoom() ? $scope.zoomInClass = "leaflet-disabled" : $scope.zoomInClass = "", zoomLevel === map.getMinZoom() ? $scope.zoomOutClass = "leaflet-disabled" : $scope.zoomOutClass = ""
}
var _bbox, _bounds, container = '<div class="leaflet-bar leaflet-draw-toolbar">',
rectangle = '<a class="leaflet-draw-draw-rectangle" id="clip-rectangle" target="_self" ng-click="startDraw($event)" title="Clip Rectangle" style="cursor: pointer;"></a>',
polygon = '<a class="leaflet-draw-draw-polygon" id="clip-polygon" target="_self" ng-click="startDraw($event)" title="Clip Polygon" style="cursor: pointer;"></a>',
endContainer = "</div>",
zoomContainer = '<div class="leaflet-control-zoom leaflet-bar leaflet-control">',
zoomIn = '<a class="leaflet-control-zoom-in {{zoomInClass}}" href="#" ng-click="zoomIn($event)" ng-dblClick="preventDoubleClick($event)" title="Zoom in" style="cursor: pointer;">+</a>',
pan = '<a class="voyager-pan" ng-click="cancelDraw($event)" title="Pan"><span class="icon-map_pan"><span class="path1"></span><span class="path2"></span></span></a>',
zoomOut = '<a class="leaflet-control-zoom-out {{zoomOutClass}}" href="#" ng-click="zoomOut($event)" ng-dblClick="preventDoubleClick($event)" title="Zoom out" style="cursor: pointer;">-</a>',
defaultExtent = '<a class="voyager-default-extent" id="default-extent" ng-click="defaultExtent($event)" title="Default Extent" style="cursor: pointer;"><span class="icon-map_home"></span></a>',
_extent = configService.getDefaultMapView();
return {
setBbox: function(val) {
_bbox = val
},
setBounds: function(bounds) {
_bounds = bounds
},
init: function($scope, mapId) {
$scope.zoomOutClass = "", $scope.zoomInClass = "", _bbox = null, _bounds = null, $scope.zoomIn = function(e) {
e.preventDefault(), leafletData.getMap(mapId).then(function(map) {
var zoomLevel = map.getZoom();
zoomLevel < map.getMaxZoom() && (map.zoomIn(), _toggleState(map, $scope, zoomLevel + 1))
}), $(".leaflet-draw-actions").hide()
}, $scope.zoomOut = function(e) {
e.preventDefault(), leafletData.getMap(mapId).then(function(map) {
var zoomLevel = map.getZoom();
zoomLevel > map.getMinZoom() && (map.zoomOut(), _toggleState(map, $scope, zoomLevel - 1))
}), $(".leaflet-draw-actions").hide()
}, $scope.defaultExtent = function(e) {
leafletData.getMap(mapId).then(function(map) {
_bbox ? mapUtil.fitToBBox(map, _bbox) : _bounds ? map.fitBounds(_bounds) : map.setView([_extent.lat, _extent.lng], _extent.zoom)
})
}, $scope.startDraw = function(e) {
mapUtil.startDraw(e, mapId)
}, $scope.preventDoubleClick = function(e) {
return e.preventDefault(), e.stopPropagation(), !1
}, $scope.cancelDraw = function(e) {
e.preventDefault(), $scope.$emit("cancelledDraw")
}
},
getClipControls: function(withPolygon, $scope) {
var template = container + rectangle;
return withPolygon && (template += polygon), template += endContainer, _getControls(template, $scope)
},
getZoomControls: function($scope) {
var template = zoomContainer + zoomIn + zoomOut + defaultExtent;
return $scope.showPan && (template += pan), _getControls(template, $scope)
},
toggleState: function(map, $scope) {
_toggleState(map, $scope)
}
}
}), angular.module("voyager.map").factory("mapCustomControls", function(config, $http) {
"use strict";
function _bufferTemplate() {
var markup = '<div class="buffer-option" style="min-width: 145px">';
return markup += '<form name="bufferOption">', markup += '<div class="buffer-content"><div class="buffer-label semi">Buffer distance</div>', markup += '<div style="white-space: nowrap;">', markup += '<input type="text" ng-model="buffer.distance" style="float: left"/>', markup += dropdown, markup += "</div>", markup += '<div class="buffer-footer">', markup += '<input type="submit" value="Done" class="btn btn-primary" ng-click="addBuffer()" style="width: 70px; padding-left: 15px"/>', markup += '<a href="#" ng-click="bufferCancel($event)" class="link_secondary">Cancel</a>', markup += "</div>", markup += "</form>", markup += "</div>"
}
function _drawingToolTemplate() {
var template = '<div class="leaflet-draw-section"><div class="leaflet-bar">';
return template += '<a class="voyager-draw-rect" ng-class="{\'selected\': _drawing}" ng-mouseover="toggleDrawingOption($event)" ng-mouseleave="toggleDrawingTools(false)"><i class="icon-map_draw_{{toolType}}"></i></a>', template += "</div>", template += '<div class="leaflet-bar drawing-option-cont" ng-if="showDrawingTools" ng-mouseover="toggleDrawingTools(true)" ng-mouseleave="toggleDrawingTools(false)">', template += '<ul id="drawingTools">', template += '<li><a ng-click="selectDrawingTool($event, \'rectangle\')" title="Rectangle"><i class="icon-map_draw_rectangle"></i></a></li>', template += '<li><a ng-click="selectDrawingTool($event, \'polygon\')" title="Polygon"><i class="icon-map_draw_polygon"></i></a></li>', template += '<li><a ng-click="selectDrawingTool($event, \'polyline\')" title="Line"><i class="icon-map_draw_polyline"></i></a></li>', template += '<li><a ng-click="selectDrawingTool($event, \'point\')" title="Marker"><i class="icon-map_draw_point"></i></a></li>', template += "</ul>", template += "</div></div>"
}
var dropdown = '<div class="hover_flyout" style="display: inline">';
return dropdown += '<span style="font-weight: bold; font-size: 15px; padding-right: 5px">{{buffer.measure}}</span>', dropdown += '<a href="javascript:;" class="fa fa-chevron-down underline flyout_trigger"></a>', dropdown += '<div class="flyout user_flyout">', dropdown += '<div class="arrow"></div>', dropdown += '<div class="flyout_inner">', dropdown += "<ul>", dropdown += '<li ng-repeat="type in ::bufferMeasures" role="menuitem"><a href="javascript:;" ng-click="buffer.measure = type.id">{{::type.text}}</a></li>', dropdown += "</ul></div></div></div>", {
getBufferTemplate: function() {
return _bufferTemplate()
},
getDrawingToolTemplate: function() {
return _drawingToolTemplate()
},
convertBuffer: function(buffer, geoJSON) {
return $http.post(config.root + "api/rest/spatial/buffer?diff=false&distance=" + buffer.distance + "&units=" + buffer.measure, geoJSON)
}
}
}), angular.module("voyager.map").directive("vsViewMap", function(config, mapUtil, baseMapService, searchService, $timeout) {
"use strict";
function _setParam($scope, map) {
$scope.param && mapUtil.setExtent(map, $scope.param)
}
var zoomLayer;
$.extend({}, config.mapDefault);
return {
compile: function(element) {
element.append('<leaflet id="view-map" style="height: 100%" defaults="defaults" layers="layers" controls="controls"></leaflet>')
},
controller: function($scope, leafletData, mapControls) {
mapControls.init($scope, "view-map"), $scope.defaults = $.extend({
zoomControl: !1
}, baseMapService.getDefaultConfig()), $scope.layers = baseMapService.getLayers(), $scope.controls = {
custom: [mapControls.getZoomControls($scope)]
}, leafletData.getMap("view-map").then(function(map) {
_setParam($scope, map), map.on("draw:drawstop", function(e) {
map.fitBounds(zoomLayer.getBounds())
}), map.on("draw:created", function(e) {
zoomLayer = e.layer
}), map.on("moveend", function(e) {
_setParam($scope, e.target), mapControls.toggleState(map, $scope)
})
}), $scope.$on("$destroy", function() {
leafletData.unresolveMap("view-map")
})
}
}
}), angular.module("voyager.map").directive("vsReadOnlyMap", function(mapUtil, baseMapService, $timeout, searchService) {
"use strict";
function _isGeometry($scope) {
return $scope.param.type && "Geometry" === $scope.param.type
}
function _applyWkt($scope, map) {
var wktObj = mapUtil.getWkt($scope.param.wkt);
_isGeometry($scope) && wktObj.addTo(map), $timeout(function() {
mapUtil.moveMapTo(wktObj, map)
}, 200)
}
function _applyBbox($scope, bbox, map) {
_isGeometry($scope) ? (mapUtil.drawBBox(map, bbox, !1), $timeout(function() {
mapUtil.fitToBBox(map, bbox)
}, 200)) : mapUtil.fitToBBox(map, bbox)
}
return {
compile: function(element) {
element.append('<leaflet id="read-only-map" style="height: 100%" defaults="defaults" layers="layers"></leaflet>')
},
controller: function($scope, leafletData) {
var config = $.extend({}, baseMapService.getDefaultConfig());
$scope.defaults = config, $scope.layers = baseMapService.getLayers(), $scope.param.wkt ? leafletData.getMap("read-only-map").then(function(map) {
_applyWkt($scope, map)
}) : $scope.param.extent && leafletData.getMap("read-only-map").then(function(map) {
_applyBbox($scope, $scope.param.extent, map)
}), $scope.$on("$destroy", function() {
leafletData.unresolveMap("read-only-map")
}), $timeout(function() {
leafletData.getMap("read-only-map").then(function(map) {
map.invalidateSize()
})
}, 200)
}
}
}), angular.module("voyager.map").directive("vsClipMap", function(config, mapUtil, baseMapService, searchService, $timeout) {
"use strict";
function _applyWkt($scope, map) {
var wktObj = mapUtil.getWkt($scope.param.wkt),
layer = wktObj.addTo(map);
return $timeout(function() {
mapUtil.moveMapTo(wktObj, map)
}, 200), layer
}
function _updateScope(layer, $scope, digest) {
var wkt = new Wkt.Wkt(layer);
$scope.$parent.wkt = wkt.write(), $scope.$parent.hasError = !1, digest && $scope.$parent.$digest(), $scope.param && ($scope.param.wkt = $scope.$parent.wkt)
}
var layer;
$.extend({}, config.mapDefault);
return {
compile: function(element) {
element.append('<leaflet id="clip-map" defaults="defaults" layers="layers" controls="controls"></leaflet>')
},
controller: function($scope, leafletData, mapControls) {
mapControls.init($scope, "clip-map"), $scope.defaults = $.extend({
zoomControl: !1
}, baseMapService.getDefaultConfig()), $scope.layers = baseMapService.getLayers();
var withPolygon = $scope.param && $scope.param.extentParam !== !0;
$scope.controls = {
custom: [mapControls.getZoomControls($scope), mapControls.getClipControls(withPolygon, $scope)]
}, leafletData.getMap("clip-map").then(function(map) {
map.on("draw:drawstart", function(e) {
layer && (map.removeLayer(layer), layer = null)
}), map.on("draw:drawstop", function(e) {
map.addLayer(layer), _updateScope(layer, $scope, !0)
}), map.on("draw:created", function(e) {
layer = e.layer
}), map.on("moveend", function(e) {
mapControls.toggleState(map, $scope)
}), $scope.param && $scope.param.resultsExtent && (layer = mapUtil.getRectangle($scope.param.resultsExtent), layer.options.fill = !1, layer.options.fillColor = "#f06eaa", layer.addTo(map), _updateScope(layer, $scope, !1))
}), $scope.param && $scope.param.reload === !0 && $scope.param.wkt && leafletData.getMap("clip-map").then(function(map) {
layer = _applyWkt($scope, map), _updateScope(layer, $scope)
}), $scope.$on("$destroy", function() {
leafletData.unresolveMap("clip-map")
})
}
}
}), angular.module("voyager.map").factory("mapService", function(config, converter, $q, $timeout) {
"use strict";
function _createDynamicLayer(map, mapInfo, spatialReference) {
var options = {
url: mapInfo.root
};
mapInfo.isLayer && (options.layers = [mapInfo.layer]);
var layer = L.esri.dynamicMapLayer(options);
return layer.addTo(map), 102100 !== spatialReference.wkid && 102113 !== spatialReference.wkid && (layer.options.bboxSR = 102100, layer.options.imageSR = 102100, layer._update()), layer
}
function _createTiledLayer(map, mapInfo, spatialReference) {
var options = {
url: mapInfo.root
};
mapInfo.isLayer && (options.layers = [mapInfo.layer]);
var layer = L.esri.tiledMapLayer(options);
return layer.addTo(map), layer
}
function _createImageLayer(map, mapInfo, spatialReference) {
var layer = new L.esri.imageMapLayer({
url: mapInfo.path
});
return map.addLayer(layer), layer
}
function _getSpatialReference(data) {
var spatialReference = data.spatialReference;
return angular.isUndefined(spatialReference) && (spatialReference = data.extent.spatialReference), spatialReference
}
function _getExtent(data) {
var extent = data.initialExtent;
return angular.isUndefined(extent) && (extent = data.extent), extent
}
function _moveToExtent(data, map, layer) {
var extent = _getExtent(data),
spatialReference = _getSpatialReference(data);
converter.toWebMercator(extent, spatialReference).then(function(bounds) {
layer.bounds = bounds, map.fitBounds(bounds), map.currentBounds = bounds
})
}
function _getWmsExtent(data) {
var extent = data.targetBoundingBox,
crs = extent.CRS;
return angular.isUndefined(crs) && (crs = extent.SRS), "1.1.1" === extent.version ? {
ymin: parseFloat(extent.minx),
xmin: parseFloat(extent.miny),
ymax: parseFloat(extent.maxx),
xmax: parseFloat(extent.maxy),
crs: crs.replace("EPSG:", "")
} : {
xmin: parseFloat(extent.minx),
ymin: parseFloat(extent.miny),
xmax: parseFloat(extent.maxx),
ymax: parseFloat(extent.maxy),
crs: crs.replace("EPSG:", "")
}
}
function _moveToWmsExtent(data, map, layer) {
if (angular.isDefined(data.geoBbox)) {
var geoBox = data.geoBbox,
bounds = [
[geoBox.southBoundLatitude, geoBox.westBoundLongitude],
[geoBox.northBoundLatitude, geoBox.eastBoundLongitude]
];
layer.bounds = bounds, map.fitBounds(bounds), map.currentBounds = bounds
} else {
var extent = _getWmsExtent(data),
spatialReference = {
wkid: parseInt(extent.crs)
};
converter.toLatLng(extent, spatialReference).then(function(bounds) {
layer.bounds = bounds, map.fitBounds(bounds), map.currentBounds = bounds
})
}
}
function _validate(data) {
var validation = {
isValid: !0
};
return angular.isDefined(data.error) && (validation.isValid = !1, validation.error = data.error), validation
}
function _getError(e, name) {
var details = e.statusText;
return "abort" === details && (details = "Timed out getting info for: " + name), {
message: "Unable to add to map",
details: [details]
}
}
function _getMetadata(mapInfo, isFeature) {
var deferred = $q.defer(),
p = $.getJSON(mapInfo.path + "?f=json&callback=?", function(data) {
var validation = _validate(data);
if (validation.isValid)
if (!mapInfo.isLayer || isFeature) deferred.resolve(data);
else {
var rootInfo = {
path: mapInfo.root,
isLayer: !1,
name: mapInfo.name
};
_getMetadata(rootInfo, !1).then(function(rootData) {
data.singleFusedMapCache = rootData.singleFusedMapCache, deferred.resolve(data)
})
}
else deferred.reject(validation)
}).error(function(e) {
deferred.reject({
isValid: !1,
error: _getError(e, mapInfo.name)
})
});
return $timeout(function() {
p.abort()
}, 5e3), deferred.promise
}
function _getWmsMetadata(mapInfo) {
var deferred = $q.defer(),
url = encodeURIComponent(mapInfo.path),
p = $.getJSON(config.proxy + ":callback=?", url, function(data) {
var validation = _validate(data);
if (validation.isValid) {
var root = "WMS_Capabilities";
if (angular.isUndefined(data[root]) && (root = "WMT_MS_Capabilities"), mapInfo.isLayer) {
var param, layerName, pathTokens = mapInfo.path.split("&");
$.each(pathTokens, function(index, value) {
param = value.split("="), "layer.name" === param[0] && (layerName = param[1])
});
var layers = data[root].Capability.Layer.Layer,
targetLayer = _.find(layers, {
Name: layerName
});
targetLayer.targetBoundingBox = targetLayer.BoundingBox, data.geoBbox = data[root].Capability.Layer.EX_GeographicBoundingBox, data.version = data[root].version, "1.1.1" === data.version && (data.targetBoundingBox = data[root].Capability.Layer.LatLonBoundingBox, data.targetBoundingBox.CRS = "EPSG:4326", data.targetBoundingBox.version = "1.1.1"), targetLayer.name = targetLayer.Name, deferred.resolve(targetLayer)
} else {
data.targetBoundingBox = data[root].Capability.Layer.BoundingBox, data.geoBbox = data[root].Capability.Layer.EX_GeographicBoundingBox, data.version = data[root].version, "1.1.1" === data.version && (data.targetBoundingBox = data[root].Capability.Layer.LatLonBoundingBox, data.targetBoundingBox.CRS = "EPSG:4326", data.targetBoundingBox.version = "1.1.1");
var layerNames = _.pluck(data[root].Capability.Layer.Layer, "Name");
data.name = layerNames.join(), deferred.resolve(data)
}
} else deferred.reject(validation)
}).error(function(e) {
deferred.reject({
isValid: !1,
error: _getError(e, mapInfo.name)
})
});
return $timeout(function() {
p.abort()
}, 5e3), deferred.promise
}
function _addMapServerLayer(map, mapInfo) {
var deferred = $q.defer();
return _getMetadata(mapInfo, !1).then(function(data) {
var layer, spatialReference = _getSpatialReference(data);
layer = mapInfo.format.indexOf("application/x-arcgis-image-server") > -1 ? _createImageLayer(map, mapInfo, spatialReference) : data.singleFusedMapCache === !0 && 102100 === spatialReference.wkid ? _createTiledLayer(map, mapInfo, spatialReference) : _createDynamicLayer(map, mapInfo, spatialReference), _moveToExtent(data, map, layer), deferred.resolve(layer)
}, function(error) {
deferred.reject(error)
}), deferred.promise
}
function _addFeatureServiceLayer(map, mapInfo) {
var deferred = $q.defer();
return _getMetadata(mapInfo, !1).then(function(data) {
var layer = null;
mapInfo.isLayer ? layer = new L.esri.FeatureLayer({
url: mapInfo.path
}).addTo(map) : $.each(data.layers, function(index, value) {
var url = mapInfo.path + "/" + value.id;
layer = new L.esri.FeatureLayer({
url: url
}).addTo(map)
}), layer.on("load", function() {
loaded || (loaded = !0, layer.query().bounds(function(error, latlngbounds) {
layer.bounds = latlngbounds, map.fitBounds(latlngbounds), map.currentBounds = latlngbounds
}))
}), deferred.resolve(layer)
}, function(error) {
deferred.reject(error)
}), deferred.promise
}
function _addWMSLayer(map, mapInfo) {
var deferred = $q.defer(),
urlInfo = mapInfo.path.split("?");
return _getWmsMetadata(mapInfo, !1).then(function(data) {
var layer = L.tileLayer.wms(urlInfo[0], {
layers: data.name,
format: "image/png",
transparent: !0
});
layer.on("load", function() {
loaded || (loaded = !0)
}), layer.addTo(map), _moveToWmsExtent(data, map, layer), deferred.resolve(layer)
}), deferred.promise
}
var loaded = !0,
mappable = {
"application/x-arcgis-image-server": !0,
"application/x-arcgis-feature-server": !0,
"application/x-arcgis-feature-server-layer": !0,
"application/x-arcgis-map-server": !0,
"application/x-arcgis-map-server-layer": !0,
"application/vnd.ogc.wms_xml": !0,
"application/vnd.ogc.wms_layer_xml": !0
};
return {
addToMap: function(mapInfo, map) {
return loaded = !1, mapInfo.format.indexOf("application/x-arcgis-map-server") > -1 || mapInfo.format.indexOf("application/x-arcgis-image-server") > -1 ? _addMapServerLayer(map, mapInfo) : mapInfo.format.indexOf("application/x-arcgis-feature-server") > -1 ? _addFeatureServiceLayer(map, mapInfo) : mapInfo.format.indexOf("application/vnd.ogc.wms") > -1 ? _addWMSLayer(map, mapInfo) : $q.reject({
isValid: !1,
error: "Not Supported"
})
},
isMappable: function(format) {
return mappable[format]
}
}
}), angular.module("voyager.map").factory("wmsLayerQuery", function(config, $http) {
function _getQueryString(id) {
return config.root + "solr/v0/select?links.to=" + id + ":_root&fl=wms_layer_name&wt=json&json.wrf=JSON_CALLBACK"
}
return {
execute: function(id) {
return $http.jsonp(_getQueryString(id)).then(function(data) {
return _.pluck(data.data.response.docs, "wms_layer_name")
}, function(error) {
return console.log(error), error
})
}
}
}), angular.module("voyager.map").factory("simpleMapService", function(mapUtil, $q) {
function _getOptions(mapInfo) {
var options = {};
return options.url = mapInfo.root, mapInfo.isLayer && (options.layers = [mapInfo.layer]), options
}
function _createDynamicLayer(map, mapInfo, spatialReference) {
var layer = L.esri.dynamicMapLayer(_getOptions(mapInfo));
return layer.addTo(map), layer
}
function _createTiledLayer(map, mapInfo) {
var layer = L.esri.tiledMapLayer(_getOptions(mapInfo));
return layer.addTo(map), layer
}
function _createImageLayer(map, mapInfo, spatialReference) {
var layer = new L.esri.imageMapLayer({
url: mapInfo.path
});
return map.addLayer(layer), layer
}
function _moveToExtent(map, layer, mapInfo) {
var bounds = mapUtil.getBounds(mapInfo.bbox);
layer.bounds = bounds, map.fitBounds(bounds), map.currentBounds = bounds
}
function _addMapServerLayer(map, mapInfo) {
var layer;
return layer = mapInfo.format.indexOf("application/x-arcgis-image-server") > -1 ? _createImageLayer(map, mapInfo) : mapInfo.ags_fused_cache === !0 ? _createTiledLayer(map, mapInfo) : _createDynamicLayer(map, mapInfo), _moveToExtent(map, layer, mapInfo), layer
}
var loaded = !0;
return {
addToMap: function(mapInfo, map) {
loaded = !1;
var layer = _addMapServerLayer(map, mapInfo);
return $q.when(layer)
}
}
}), angular.module("voyager.map").factory("simpleFeatureServer", function(config, converter, $q) {
"use strict";
function _addFeatureServiceLayer(map, mapInfo) {
var layer = null,
layerCount = 1;
return angular.isDefined(mapInfo.linkcount__children) && (layerCount = mapInfo.linkcount__children), mapInfo.isLayer ? layer = new L.esri.Services.featureLayerService({
url: mapInfo.path
}).addTo(map) : $.each(new Array(layerCount), function(index, value) {
var url = mapInfo.path + "/" + index;
layer = new L.esri.FeatureLayer({
url: url
}).addTo(map)
}), layer.on("load", function() {
_loaded || (_loaded = !0, layer.query().bounds(function(error, latlngbounds) {
layer.bounds = latlngbounds, map.fitBounds(latlngbounds), map.currentBounds = latlngbounds
}))
}), layer
}
var _loaded = !0;
return {
addToMap: function(mapInfo, map) {
_loaded = !1;
var layer = _addFeatureServiceLayer(map, mapInfo);
return $q.when(layer)
}
}
}), angular.module("voyager.map").factory("simpleWmsService", function(config, converter, $q, mapUtil, wmsLayerQuery) {
function _moveToExtent(map, layer, mapInfo) {
var bounds = mapUtil.getBounds(mapInfo.bbox);
layer.bounds = bounds, map.fitBounds(bounds), map.currentBounds = bounds
}
function _addLayer(map, mapInfo) {
var urlInfo = mapInfo.path.split("?"),
layers = mapInfo.wms_layer_name;
mapInfo.layerNames && (layers = mapInfo.layerNames);
var layer = L.tileLayer.wms(urlInfo[0], {
layers: layers,
format: "image/png",
transparent: !0
});
return layer.on("load", function() {
loaded || (loaded = !0)
}), layer.addTo(map), _moveToExtent(map, layer, mapInfo), layer
}
var loaded = !0;
return {
addToMap: function(mapInfo, map) {
if (loaded = !1, mapInfo.contains_name) return wmsLayerQuery.execute(mapInfo.id).then(function(layerNames) {
return layerNames = layerNames.slice(0, 10), mapInfo.layerNames = layerNames.join(), _addLayer(map, mapInfo)
});
var layer = _addLayer(map, mapInfo);
return $q.when(layer)
}
}
}), angular.module("voyager.map").factory("mapServiceFactory", function(config, converter, $q, simpleMapService, mapService, simpleFeatureServer, simpleWmsService) {
function _getRootPath(mapInfo) {
var path = mapInfo.path,
index = path.lastIndexOf("/"),
root = path.substring(0, index + 1),
layer = path.substring(index + 1, path.length);
mapInfo.root = root, mapInfo.layer = layer
}
var mappable = {
"application/x-arcgis-image-server": !0,
"application/x-arcgis-feature-server": !0,
"application/x-arcgis-feature-server-layer": !0,
"application/x-arcgis-map-server": !0,
"application/x-arcgis-map-server-layer": !0,
"application/vnd.ogc.wms_xml": !0,
"application/vnd.ogc.wms_layer_xml": !0
};
return {
getMapService: function(mapInfo) {
return angular.isUndefined(mapInfo.path) && (mapInfo.path = mapInfo.fullpath), mapInfo.path = mapInfo.path.replace(/\+/g, "%20"), mapInfo.root = mapInfo.path, mapInfo.format.indexOf("layer") > -1 && (mapInfo.isLayer = !0, _getRootPath(mapInfo)), mapInfo.format.indexOf("application/x-arcgis-map-server") > -1 || mapInfo.format.indexOf("application/x-arcgis-image-server") > -1 ? angular.isDefined(mapInfo.bbox) ? simpleMapService : mapService : mapInfo.format.indexOf("application/x-arcgis-feature-server") > -1 ? angular.isDefined(mapInfo.linkcount__children) ? simpleFeatureServer : mapService : mapInfo.format.indexOf("application/vnd.ogc.wms") > -1 ? angular.isDefined(mapInfo.bbox) ? simpleWmsService : mapService : {
isValid: !1,
error: "Not Supported"
}
},
isMappable: function(format) {
return mappable[format]
}
}
}), angular.module("voyager.map").factory("baseMapService", function(config, converter, mapUtil, $http, $q) {
"use strict";
function _fetchBaselayers() {
var service = config.root + "api/rest/display/maps";
return $http.get(service).then(function(response) {
return response.data
})
}
function _getBaselayers() {
return angular.isDefined(_baselayers) ? $q.when(_baselayers) : _fetchBaselayers().then(function(data) {
if (_baselayers = _processBaselayerData(data), Object.keys(_baselayers).length <= 0) {
var layerData = [{
name: _layers.baselayers.base.name,
url: _layers.baselayers.base.url,
layers: _layers.baselayers.base.layerOptions.layers,
selected: !0
}];
_baselayers = _processBaselayers(_baselayers, layerData, _layers.baselayers.base.type)
}
return _baselayers
})
}
function _processBaselayerData(layerData) {
var baselayers = {};
return layerData.ags && (baselayers = _processBaselayers(baselayers, layerData.ags, "ags")), layerData.bing && (baselayers = _processBaselayers(baselayers, layerData.bing, "bing")), layerData.google && (baselayers = _processBaselayers(baselayers, layerData.google, "google")), layerData.mapbox && (baselayers = _processBaselayers(baselayers, layerData.mapbox, "mapbox")), layerData.wms && (baselayers = _processBaselayers(baselayers, layerData.wms, "wms")), baselayers
}
function _processBaselayers(baselayers, layers, type) {
return baselayers = baselayers || {}, $.each(layers, function(index, layer) {
var layerType = type,
layerUrl = layer.url;
config.map.config.proxy && (layerUrl = config.root + "proxy?" + layerUrl);
var layerOptions = {
continuousWorld: !1,
showOnSelector: !0
},
layerDefault = layer.selected || !1,
layerCached = !1;
if (layerUrl) {
switch (type) {
case "ags":
layer.cached === !0 ? (layerUrl += "tile/{z}/{y}/{x}/", layerType = "xyz", layerCached = !0) : layerType = "agsDynamic", layerOptions.layers = layer.layers;
break;
case "google":
layerCached = !0;
break;
case "bing":
layerCached = !0;
break;
case "mapbox":
layerUrl = layerUrl.replace(/\$/g, ""), layerCached = !0;
break;
case "wms":
layerOptions.layers = layer.layers, layerOptions.format = "image/png", layerOptions.transparent = !0, layerCached = !0
}
var layerInfo = {
name: layer.name,
type: layerType,
url: layerUrl,
cached: layerCached,
default: layerDefault,
options: layerOptions
};
layerDefault && (_defaultBaselayer = {
name: layerInfo.name,
type: layerInfo.type,
url: layerInfo.url,
cached: layerCached,
layerOptions: layerInfo.options
}, _defaultBaselayer.layerOptions.showOnSelector = !1), baselayers[layerInfo.name] = layerInfo
}
}), baselayers
}
var _baselayers, _defaultBaselayer, _baselayerStorageName = "selected-base-layer",
_defaultConfig = {
attributionControl: !1,
scrollWheelZoom: !0,
zoomControl: !1,
minZoom: 1
},
_layers = {
baselayers: {
base: {
name: "arcgis",
type: "xyz",
url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}/",
layerParams: {},
layerOptions: {
showOnSelector: !1
}
}
}
},
baseMap = _.getPath(config, "map.config.url");
return angular.isDefined(baseMap) && (config.map.config.proxy && (baseMap = config.root + "proxy?" + baseMap), "WMSLayerDefinition" === config.map.type ? (delete _defaultConfig.tileLayer, _defaultConfig.crs = "EPSG4326", _layers = {
baselayers: {
base: {
name: config.map.config.name,
type: "wms",
url: baseMap,
layerOptions: {
layers: config.map.config.layers,
showOnSelector: !1
},
layerParams: {}
}
}
}) : "MapboxLayerDefinition" === config.map.type ? _layers.baselayers.base.url = baseMap.replace(/\$/g, "") : config.map.config.cached === !0 ? (_layers.baselayers.base.url = baseMap + "tile/{z}/{y}/{x}/", config.map.config.simpleWGS84 && (_defaultConfig.crs = mapUtil.getWGS84CRS())) : (delete _defaultConfig.tileLayer, _layers = {
baselayers: {
base: {
name: config.map.config.name,
type: "agsDynamic",
url: baseMap,
layerOptions: {
layers: config.map.config.layers,
showOnSelector: !1
}
}
}
})), {
BASELAYER_STORAGE_NAME: _baselayerStorageName,
getDefaultConfig: function() {
return _defaultConfig
},
getLayers: function(origin) {
if ("home" === origin) {
var homeLayer = _.clone(_layers, !0);
return config.homepage.wrapMap === !1 && (homeLayer.baselayers.base.layerParams.noWrap = !0), homeLayer
}
return _layers
},
getBaselayers: function() {
return _getBaselayers()
},
getDefaultBaselayer: function() {
return _defaultBaselayer
},
getCRSForLayerType: function(type) {
return "wms" === type ? L.CRS.EPSG4326 : L.CRS.EPSG3857
}
}
}), angular.module("fileBrowser", []), angular.module("fileBrowser").factory("fileBrowserService", function($http, config) {
"use strict";
return {
browse: function(uri) {
return $http.get(config.root + "api/rest/system/browse.json?uri=" + uri)
}
}
}), angular.module("fileBrowser").controller("FileBrowserCtrl", function($scope, fileBrowserService, usSpinnerService, $timeout, translateService, config, $stateParams) {
"use strict";
function _decorate(list) {
return $.each(list, function(index, value) {
value.isFile = !1, value.iconUrl = config.root + "vres/mime/icon/application/vnd.voyager.folder", angular.isUndefined(value.parentUri) ? (value.icon = "fa fa-hdd-o", value.type = "Drive") : value.folder === !0 ? (value.icon = "fa fa-folder gridFolder", value.type = "Folder") : (value.type = translateService.getType(value.format), value.iconUrl = config.root + "vres/mime/icon/" + value.format, value.isFile = !0), angular.isDefined(value.parts) && value.parts.length > 0 && (value.hasParts = !0, value.partsCount = value.parts.length, value.partsDisplay = value.parts.join("<br/>"))
}), list
}
function _getPathArray(response) {
var pathLinks = [];
return response.data.uri.indexOf("\\") > -1 ? (pathLinks = response.data.uri.split("\\"), "" === pathLinks[1] && (pathLinks = pathLinks.splice(0, 1))) : response.data.uri.indexOf("/") > -1 && (pathLinks = response.data.uri.split("/"), "" === pathLinks[1] && (pathLinks = pathLinks.splice(0, 1)), pathSep = "/"), pathLinks
}
function _browse(path, selected) {
var encoded = encodeURIComponent(path);
usSpinnerService.spin("browser-spinner"), fileBrowserService.browse(encoded).then(function(response) {
$scope.gridData = _decorate(response.data.children), $scope.pathLinks = _getPathArray(response), $scope.editPath = !1, $scope.path = path, $("#voyagerSearch").trigger("selectedPath", path), usSpinnerService.stop("browser-spinner")
}, function(error) {
usSpinnerService.stop("browser-spinner"), $scope.error = "Could not open " + decodeURIComponent(path), "" === path || selected || _browse("")
})
}
function _selectRow(rowItem, event) {
rowItem.selected && rowItem.entity.folder === !0 && _browse(rowItem.entity.uri, !0), "folder" !== $scope.browserType && ($scope.path = rowItem.entity.uri, $("#voyagerSearch").trigger("selectedPath", $scope.path))
}
function _getUri(path, index) {
var uri;
return "" !== path ? ($scope.pathLinks.splice(index + 1, $scope.pathLinks.length - (index + 1)), uri = $scope.pathLinks.length > 1 ? $scope.pathLinks.join(pathSep) : $scope.pathLinks[0] + pathSep) : uri = "", uri
}
var pathSep = "\\";
angular.isUndefined($scope.browserType) && ($scope.browserType = "folder"), $scope.isInline = $stateParams.inline, angular.isUndefined($scope.path) && ($scope.path = "");
var pathClicked = !1,
componentsTemplate = '<div class="ngCellText"> <a tooltip-html-unsafe="{{row.getProperty(\'partsDisplay\')}}" tooltip-append-to-body="true" tooltip-placement="left" class="badge" ng-show="{{row.getProperty(\'hasParts\')}}">{{row.getProperty(\'partsCount\')}}</a> {{row.getProperty(col.field)}}</div>',
nameTemplate = '<div class="ngCellText"><img src="{{row.getProperty(\'iconUrl\')}}"/> {{row.getProperty(col.field)}}</div>';
$scope.gridOptions = {
enableHighlighting: !0,
multiSelect: !1,
data: "gridData",
enableColumnResize: !0,
afterSelectionChange: _selectRow,
columnDefs: [{
field: "name",
displayName: "Name",
cellTemplate: nameTemplate
}, {
field: "type",
displayName: "Type"
}, {
field: "fileSize",
displayName: "File Size",
cellTemplate: componentsTemplate
}]
}, $timeout(function() {
$(window).resize()
}, 0), $scope.$on("ngGridEventData", function() {}), _browse($scope.path), $scope.browse = function() {
_browse($scope.path)
}, $scope.pathClick = function(path, index) {
pathClicked = !0, $scope.editPath = !1, $scope.path = _getUri(path, index), _browse($scope.path)
}, $scope.pathContainerClick = function(path) {
pathClicked || ($scope.editPath = !0, $timeout(function() {
angular.element("#pathInput").focus()
}, 0)), pathClicked = !1
}, $scope.movedAway = function() {
$scope.editPath = !1
}, $scope.setPath = function() {
$("#voyagerSearch").trigger("selectedPath", $scope.path), $scope.ok($scope.path)
}, $scope.closeBrowser = function() {
$("#voyagerSearch").trigger("cancelBrowse"), $scope.cancel()
}
}), angular.module("voyager.config", ["voyager.common.savedsearch"]), angular.module("voyager.config").factory("configService", function(config, translateService, complexFilterService, $http, $q, catalogService, $location, solrUtil) {
function _getPageFramework() {
return _pageFramework
}
function _getDefaultView() {
return _defaultView.toLowerCase()
}
function _getCardView() {
return _cardView
}
function _setConfigFields(displayFields) {
$.each(displayFields, function(index, value) {
_displayFields[value.name] = translateService.getFieldName(value.name), _displayFieldsOrder[value.name] = index, _displayFieldsStyle[value.name] = value.style, _solrParams += "," + value.name, value.editable && (_editable[value.name] = value.name)
})
}
function _setSummaryFields(summaryFields) {
$.each(summaryFields, function(index, value) {
_summaryFields[value.name] = translateService.getFieldName(value.name), _summaryFieldsOrder[value.name] = index, _summaryFieldsStyle[value.name] = value.style, _summaryFieldsShowLabels[value.name] = value.showLabel, _summaryFieldsMaxLines[value.name] = value.maxLines, _summarySolrParams += "," + value.name
})
}
function _setTableFields(table) {
_tableFields = [], $.each(table, function(index, value) {
var name = value.name;
value.name = solrUtil.stripAugmented(value.name), _tableFieldsStyle[value.name] = value.style;
var tableField = {
field: value.name,
display: translateService.getFieldName(value.name),
width: value.width,
sortable: name === value.name
};
_tableFields.push(tableField), angular.isDefined(value.width) && (_tableColumnWidthMap[value.field] = {
value: parseFloat(value.width)
})
})
}
function _setCardViewFields(cardViewFields) {
_cardViewFields = [], $.each(cardViewFields, function(index, value) {
var cardViewField = {
field: value.name,
display: translateService.getFieldName(value.name)
};
cardViewField.maxLines = value.maxLines || 3, cardViewField.showLabel = value.showLabel, _cardViewFields.push(cardViewField)
})
}
function _setCardViewNames(cardViewNames) {
_cardViewNames = [], $.each(cardViewNames, function(index, value) {
var cardViewName = {
field: value,
display: translateService.getFieldName(value)
};
_cardViewNames.push(cardViewName)
})
}
function _updateConfig(configData) {
_shards = null, _systemFilterMap = _.indexBy(configData.filters, "field"), _isQueryAllCatalogs = configData.queryAllCatalogs, _setConfigFields(configData.details.detailsTableFields), _globalEditable = configData.details.detailsTableFieldsAreEditable, _homepage = configData.homepage, _pageFramework = configData.pageElements, _defaultView = configData.defaultView, _cardView = configData.cardView, _gridView = configData.gridView, configData.cardView ? _setSummaryFields(configData.cardView.fields || []) : (_summaryFields = {}, _summarySolrParams = "", _summaryFieldsOrder = {}, _summaryFieldsStyle = {}), angular.isDefined(configData.listView) && _setTableFields(configData.listView.fields || []), angular.isDefined(configData.cardView) && (angular.isDefined(configData.cardView.fields) && _setCardViewFields(configData.cardView.fields), angular.isDefined(configData.cardView.names) && _setCardViewNames(configData.cardView.names))
}
function _setFilterDataTypes() {
var filterString = _.keys(_systemFilterMap).join(" ");
return $http.jsonp(config.root + "solr/fields/select?fq=name:(" + filterString + ")&fl=name,multivalued,disp:disp_en,stype&wt=json&json.wrf=JSON_CALLBACK&rows=1000").then(function(filterData) {
_.each(filterData.data.response.docs, function(doc) {
var filter = _systemFilterMap[doc.name];
filter.stype = doc.stype, filter.multivalued = doc.multivalued, filter.disp = doc.disp
})
})
}
function _load(configId) {
return $http.get(config.root + "api/rest/display/config/" + configId + ".json").then(function(res) {
return _configId = configId, config.settings = res, _updateConfig(config.settings.data), _setFilterDataTypes().then(function() {
return config.settings.data
})
})
}
function _setDefaultConfig() {
return null !== _configId ? (_configId = null, _load(config.configid).then(function() {
return $location.search("disp", config.configid), {
configId: config.configid
}
})) : config.settings ? (_updateConfig(config.settings.data), $q.when({
configId: config.configid
})) : _load(config.configid).then(function() {
return $location.search("disp", config.configid), {
configId: config.configid
}
}, function(error) {
return $q.reject(error)
})
}
function _setFilterConfig(configId) {
var deferred = $q.defer();
return configId === _configId ? deferred.resolve({
configId: configId
}) : angular.isDefined(configId) ? _load(configId).then(function() {
deferred.resolve({
configId: configId
})
}, function() {
_setDefaultConfig().then(function(config) {
deferred.resolve(config)
})
}) : _setDefaultConfig().then(function(config) {
deferred.resolve(config)
}), deferred.promise
}
function _createCatalogFacet(catalog, urlShards) {
var selected = _.indexOf(urlShards, catalog.id) !== -1 || _isQueryAllCatalogs;
return {
display: catalog.name,
style: "CHECK",
isSelected: selected,
field: "shard",
hasCount: !1,
id: catalog.id,
raw: catalog.url
}
}
function _createCatalogFilter(catalogFilter, facetTypes) {
catalogFilter || (catalogFilter = {
field: "shards",
value: "Catalog",
values: []
}, facetTypes.unshift(catalogFilter)), catalogFilter.value = "Catalog";
var urlShards = $location.search().shards;
angular.isDefined(urlShards) && (urlShards = urlShards.split(",")), _catalogsPromise = catalogService.fetch().then(function(catalogs) {
var selectedCount = 0;
if (_.each(catalogs, function(catalog) {
var facet = _createCatalogFacet(catalog, urlShards);
catalogFilter.values.push(facet), facet.isSelected && selectedCount++
}), 1 === selectedCount) {
var filter = _.find(catalogFilter.values, {
isSelected: !0
});
filter.disabled = !0
}
_isQueryAllCatalogs && _.each(catalogFilter.values, function(facet) {
facet.disabled = !0
})
})
}
var _catalogsPromise, _pageFramework, _defaultView, _cardView, _gridView, _globalEditable, _isQueryAllCatalogs, _configId = null,
_systemFilters = null,
_systemFilterMap = {},
_displayFields = {},
_summaryFields = {},
_solrParams = "",
_summarySolrParams = "",
_tableFields = [],
_tableFieldsStyle = [],
_cardViewFields = [],
_cardViewNames = [],
_displayFieldsOrder = {},
_displayFieldsStyle = {},
_displayFieldsShowLabels = {},
_displayFieldsMaxLines = {},
_summaryFieldsOrder = {},
_summaryFieldsStyle = {},
_summaryFieldsShowLabels = {},
_summaryFieldsMaxLines = {},
_tableColumnWidthMap = {},
_shards = null,
_homepage = {},
_editable = {},
_defaultMapView = {
lng: 0,
lat: 0,
zoom: 3
};
try {
_updateConfig(config.settings.data)
} catch (err) {}
return {
getPageFramework: _getPageFramework,
getDefaultView: _getDefaultView,
getCardView: _getCardView,
getGridView: function() {
return _gridView
},
getDisplayFilters: function() {
var catalogFilter, discoveryStatusFilter, facetTypes = config.settings.data.filters,
hasShard = !1;
return $.each(facetTypes, function(index, value) {
value.value = "", value.values = [], "HIERARCHY" === value.style && (value.value = translateService.getFieldName(value.field)), "shards" === value.field && (hasShard = !0, catalogFilter = value), "discoveryStatus" === value.field && (discoveryStatusFilter = value)
}), translateService.translateFilterNames(facetTypes), config.settings.data.showFederatedSearch && _createCatalogFilter(catalogFilter, facetTypes), config.settings.data.showDiscoveryStatus && complexFilterService.createDiscoveryStatusFilter(discoveryStatusFilter, facetTypes), facetTypes
},
getDisplay: function() {
return config.settings.data
},
getAllowsTextWrappingOnTableView: function() {
return config.settings.data.listView.allowTextWrapping
},
getShowThumbnailOnTableView: function() {
return config.settings.data.listView.showThumbnail
},
getShowFlagOnTableView: function() {
return config.settings.data.listView.showFlag
},
lookupFilter: function(filter) {
return _systemFilterMap[filter]
},
lookupFilterStyle: function(filterName) {
var filterConfig = this.lookupFilter(filterName);
return angular.isDefined(filterConfig) ? "date" === filterConfig.stype ? "DATE" : filterConfig.style : ""
},
getSystemFilters: function() {
return _systemFilters
},
getFilters: function() {
return null === config.settings.data.filters && (config.settings.data.filters = []), config.settings.data.filters
},
setConfigId: function(configId) {
_configId = configId
},
getConfigId: function() {
return null !== _configId ? _configId : angular.isDefined(config.defaultId) ? config.defaultId : config.configid
},
setFilterConfig: function(configId) {
return _setFilterConfig(configId)
},
getConfigDetails: function(id) {
return $http.get(config.root + "api/rest/display/config/" + id + ".json")
},
getSolrFields: function() {
return "" !== _summarySolrParams ? _summarySolrParams : _solrParams
},
getDisplayFields: function(doc) {
var fields, order, style, labels, lines, prettyFields = [];
return fields = _displayFields, order = _displayFieldsOrder, style = _displayFieldsStyle, labels = _displayFieldsShowLabels, lines = _displayFieldsMaxLines, _.isEmpty(_summaryFields) || (fields = _summaryFields, order = _summaryFieldsOrder, style = _summaryFieldsStyle, labels = _summaryFieldsShowLabels, lines = _summaryFieldsMaxLines), $.each(doc, function(name, value) {
fields[name] && (_.isArray(value) && (value = value.join(", ")), prettyFields.push({
name: fields[name],
value: value,
order: order[name],
style: style[name],
raw: name,
showLabel: labels[name],
maxLines: lines[name]
}))
}), _.sortBy(prettyFields, "order")
},
getCardViewFields: function() {
return _cardViewFields
},
getCardViewNames: function() {
return _cardViewNames
},
getTableFields: function() {
return _tableFields.forEach(function(field) {
field.style = _tableFieldsStyle[field.field]
}), _tableFields
},
getTableFieldNames: function() {
return _.map(_tableFields, "field")
},
updateColumnWidth: function(field, value) {
_tableColumnWidthMap[field] = {
changed: !0,
value: value
}
},
getColumnWidth: function(field) {
var col = _tableColumnWidthMap[field];
return angular.isDefined(col) ? col.value : col
},
resetColumns: function() {
$.each(_tableFields, function(index, field) {
angular.isDefined(field.width) && (_tableColumnWidthMap[field.field] = {
value: parseFloat(field.width)
})
})
},
hasChanges: function() {
return !_.isEmpty(_tableColumnWidthMap)
},
getUpdatedSettings: function() {
var colInfo;
return $.each(config.settings.data.listView.fields, function(index, column) {
colInfo = _tableColumnWidthMap[column.field || column.name], angular.isDefined(colInfo) && (column.width = colInfo.value)
}), config.settings.data
},
getSort: function() {
var sort = {};
return sort.direction = angular.isDefined(config.defaultSortDirection) ? config.defaultSortDirection : "desc", sort.field = angular.isDefined(config.defaultSort) ? config.defaultSort : "score", sort
},
showMap: function() {
null === config.settings.data.pageElements && (config.settings.data.pageElements = {
showMap: !0
});
var showMap = config.settings.data.pageElements.showMap;
return angular.isUndefined(showMap) && (showMap = !0), showMap
},
getSortable: function() {
var sortable = [];
return angular.isDefined(config.settings.data.sorting) && $.each(config.settings.data.sorting, function(index, field) {
sortable.push({
key: field,
value: translateService.getFieldName(field)
})
}), sortable
},
setShards: function(shards) {
_shards = shards
},
getShards: function() {
return _shards
},
getHomePage: function() {
return _homepage
},
getEditable: function() {
return _editable
},
getDefaultMapView: function() {
return _defaultMapView
},
setDefaultMapView: function(mapView) {
_defaultMapView = mapView
},
parseMapViewString: function(str, delim) {
var coords = str.split(_.isEmpty(delim) ? "," : delim);
coords = _.map(coords, function(val) {
return parseFloat(val)
});
var view = {
lng: 0,
lat: 0,
zoom: 3
};
return coords.length > 1 && (view.lng = coords[0], view.lat = coords[1]), coords.length > 2 && (view.zoom = coords[2]), view
},
getCatalogs: function() {
return _catalogsPromise
},
hideDefaultCredentials: function() {
return $http.post(config.root + "api/rest/appearance/defaultCredentials?show=false")
},
updateConfig: function(data) {
return _updateConfig(data)
},
getIsGlobalEditable: function() {
return _globalEditable
},
fetchCartTasks: function() {
return $http.get(config.root + "api/rest/appearance").then(function(res) {
return res.data.cartTasks
})
}
}
}), angular.module("voyager.config").factory("configLoader", function($http, $q, config, configService, savedSearchQuery, $location, $timeout, translateService, savedSearchService, catalogService, baseMapService) {
function _setConfigRoot(hostname) {
"127.0.0.1" !== hostname && "localhost" !== hostname && (config.root = config.root.replace("localhost", window.location.hostname)), "https:" === window.location.protocol && config.root.indexOf("https:") === -1 && (config.root = config.root.replace("http:", "https:"))
}
function _setProxy(hostname) {
if ("127.0.0.1" !== hostname && "localhost" !== hostname && config.proxy.indexOf("localhost") > -1) {
var port = window.location.port;
"" !== port && (port = ":" + port);
var root = location.pathname;
root = _.str.trim(root, "/"), root = root.split("/"), root.length > 1 && (root.pop(), root = root.join("/")), config.proxy = config.proxy.replace("http://localhost:8888", window.location.protocol + "//" + window.location.hostname + port + "/" + root)
}
}
function _loadDependencies() {
var url, promises = [];
return $.each(config.require, function(index, value) {
url = config.root + value;
var promise = $http.get(url, {
headers: {
"Content-Type": "application/json; charset=utf-8"
},
withCredentials: !0
}).then(function(response) {
config[index] = response
});
promises.push(promise)
}), promises.push(catalogService.fetch()), promises.push(baseMapService.getBaselayers()), $q.all(promises)
}
function _prepare() {
if (_prepared) return _prepared = !0, $q.when({});
angular.isDefined(config.rootOverride) && (config.root = config.rootOverride);
var hostname = window.location.hostname;
return _setConfigRoot(hostname), _setProxy(hostname), _loadDependencies($q, $http)
}
var _configId, _prepared = !1;
return {
load: function(configId) {
return _prepare().then(function() {
translateService.init();
var defaultView = _.getPath(config, "map.config.defaultView");
return angular.isDefined(defaultView) && configService.setDefaultMapView(configService.parseMapViewString(defaultView)), angular.isUndefined(configId) ? savedSearchQuery.fetchDefault().then(function(docs) {
var defaultSearch = docs[0];
return defaultSearch || (defaultSearch = {}), configService.setFilterConfig(defaultSearch.config).then(function(config) {
$timeout(function() {
var params = {};
defaultSearch && (params = savedSearchService.getParams(defaultSearch)), params.disp = config.configId, $location.search(params)
})
})
}) : _configId !== configId ? configService.setFilterConfig(configId).then(function() {
$location.search().disp !== configId && $timeout(function() {
$location.search("disp", configId)
}), _configId = configId
}) : $q.when()
})
},
prepare: function() {
return _prepare()
}
}
}), angular.module("voyager.component", []), angular.module("voyager.component").directive("placeholder", function($timeout) {
"use strict";
return {
restrict: "A",
link: function(scope, element, attr, ctrl) {
if (!$(element).parents("#ecobar_addin").length) {
var test = document.createElement("input");
if ("placeholder" in test) return !0;
if ($timeout(function() {
element.val(element.attr("placeholder")).addClass("placeholder")
}), "password" === element.attr("type").toLowerCase() && element.data("oType", "password").attr("type", "text"), element.bind("focus", function() {
"password" === element.data("oType") && element.attr("type", "password"), element.val() === element.attr("placeholder") && element.val("").removeClass("placeholder")
}).bind("blur", function() {
"" === element.val() && (element.val(element.attr("placeholder")).addClass("placeholder"), "password" === element.data("oType") && element.attr("type", "text"))
}), void 0 !== attr.ngModel && void 0 !== ctrl) {
var value;
scope.$watch(attr.ngModel, function(val) {
value = val || ""
}), ctrl.$formatters.unshift(function(val) {
return val ? val : (element.val(element.attr("placeholder")), value = "", attr.placeholder)
})
}
}
}
}
}), angular.module("voyager.component").directive("vsHighlight", function() {
"use strict";
return {
restrict: "A",
link: function(scope, element) {
function _unhighlight() {
document.selection ? document.selection.empty() : window.getSelection && window.getSelection().removeAllRanges()
}
function _highlight(event) {
var range, id = $(event.currentTarget).attr("id"),
index = parseInt(id.replace("locationPath", "")),
highlightList = $("#locationPathWrap a");
if (index >= highlightList.length)
for (var i = highlightList.length; i <= index; i++) $("#locationPathWrap").append($("#locationPath" + i));
if (document.body.createTextRange) range = document.body.createTextRange(), range.moveToElementText(document.getElementById("locationPathWrap")), range.select();
else if (window.getSelection) {
var selection = window.getSelection();
selection.removeAllRanges(), range = document.createRange(), range.selectNodeContents(document.getElementById("locationPathWrap")), selection.addRange(range)
}
}
var parent = $(element);
parent.on("mouseover", "a", function(event) {
_unhighlight(), _highlight(event)
}).on("mouseout", "a", function(event) {
for (var id = $(event.currentTarget).attr("id"), index = parseInt(id.replace("locationPath", "")), highlightList = $("#locationPathWrap a"), i = highlightList.length; i >= index; i--) $("#locationPathNotHighlight").prepend($("#locationPath" + i));
_unhighlight()
})
}
}
}), angular.module("voyager.component").directive("vsPopover", function($timeout, $window) {
"use strict";
return {
restrict: "A",
link: function(scope, element) {
function _anchorPopover(event, triggerEl, popOverEl) {
var winHeight = $(window).height(),
winWidth = $(window).width() > $(document).width() ? $(window).width() : $(document).width(),
popOverYPos = event.clientY,
popOverXPos = triggerEl.offset().left,
popOverContent = popOverEl.find(".flyout"),
popOverContentHeight = popOverContent.data("height"),
popOverContentWidth = popOverContent.data("width");
popOverContentHeight || (popOverContentHeight = popOverContent.addClass("offscreen").height() + 30, popOverContent.data("height", popOverContentHeight), popOverContentWidth = popOverContent.addClass("offscreen").width(), popOverContent.data("width", popOverContentWidth), popOverContent.removeClass("offscreen")), popOverEl.hasClass("top_only") || (winHeight - popOverYPos < popOverContentHeight ? popOverEl.addClass("bottom") : popOverEl.removeClass("bottom")), popOverXPos + popOverContentWidth > winWidth - 10 ? popOverEl.find(".flyout_inner").css("left", winWidth - popOverXPos - popOverContentWidth - 10 + "px") : popOverEl.find(".flyout_inner").css("left", 0)
}
element.on("click", "a", function(event) {
$timeout.cancel(this.timer);
var trigger = $(event.currentTarget),
el = trigger.parents(".hover_flyout");
trigger.hasClass("flyout_trigger") ? el.hasClass("opened") ? el.removeClass("opened") : (_anchorPopover(event, trigger, el), el.hasClass("max_height") && el.find(".flyout_inner").css("max-height", $window.innerHeight - (el.offset().top - $window.pageYOffset) - 80 + "px"), el.addClass("opened").siblings().removeClass("opened")) : trigger.hasClass("keep_open") ? trigger.hasClass("subcat_trigger") && (trigger.parent().toggleClass("opened"), el.length > 0 && el.find(".flyout_inner").css("max-height", $window.innerHeight - (el.offset().top - $window.pageYOffset) - 80 + "px")) : trigger.parents(".hover_flyout").removeClass("opened")
}).on("mouseleave", ".hover_flyout", function(event) {
var trigger = $(event.currentTarget);
trigger.hasClass("keep_open") || (this.timer = $timeout(function() {
$(event.currentTarget).removeClass("opened")
}, 500))
}).on("mouseenter", ".hover_flyout", function() {
$timeout.cancel(this.timer)
})
}
}
}), angular.module("voyager.component").filter("bytes", function() {
"use strict";
return function(bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return "-";
"undefined" == typeof precision && (precision = 1);
var units = ["bytes", "kB", "MB", "GB", "TB", "PB"],
number = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + " " + units[number]
}
}), angular.module("voyager.component").directive("vsSearchToolToggle", function() {
"use strict";
return {
restrict: "A",
link: function(scope, element, attr) {
var _update = !0;
scope.$watch(attr.ngModel, function() {
_update ? scope.$emit("searchDrawingTypeChanged", scope.selectedDrawingType) : _update = !0
}), scope.$on("updateSearchDrawingType", function(event, args) {
_update = !1, scope.selectedDrawingType = args
})
}
}
}), angular.module("voyager.component").directive("vsSelectedFilter", function($timeout, $window) {
"use strict";
return {
restrict: "A",
link: function(scope, element, attr) {
var windowEl = angular.element($window),
windowWidth = windowEl.width(),
windowHeight = windowEl.height(),
_adjustSelectedFilterContainer = function() {
$timeout(function() {
var searchResultMapContainer = angular.element("#searchResultMapContainer"),
selectedFilterEl = angular.element("#selectedFilters"),
selectedFilterContainer = selectedFilterEl.find(".overtop"),
filterContainerHeight = 0,
listWrapEl = selectedFilterEl.next(".list_wrap");
scope.filters.length && (filterContainerHeight = selectedFilterEl.find(".overtop").outerHeight(), selectedFilterContainer.css("width", selectedFilterEl.parent().outerWidth() + "px")), listWrapEl.css({
"padding-top": filterContainerHeight + "px"
});
var banner = angular.element("#top-banner");
if ("table" === attr.view) {
var top = 118 + filterContainerHeight;
banner.length > 0 && (top += banner.height()), searchResultMapContainer.css("top", top + "px")
} else {
selectedFilterEl.next(".list_wrap").css({
"margin-top": 0
});
var height = "";
banner.length && (height = $window.innerHeight - banner.height() - 64 - 5 + "px"), searchResultMapContainer.css({
top: "",
height: height,
visibility: "visible"
})
}
}, 100)
};
element.ready(function() {
scope.$watch("filters", function() {
_adjustSelectedFilterContainer()
}), scope.$watch("$parent.filterVisible", function() {
_adjustSelectedFilterContainer()
}), scope.$watch("$parent.view", function() {
_adjustSelectedFilterContainer()
}), windowEl.on("resize", function() {
windowWidth === windowEl.width() && windowHeight === windowEl.height() || (windowWidth = windowEl.width(), windowHeight = windowEl.height(), _adjustSelectedFilterContainer())
}), scope.$on("destroy", function() {
windowEl.unbind("resize", _adjustSelectedFilterContainer)
})
})
}
}
}), angular.module("voyager.component").directive("vsDetailScroll", function($window, $document, $timeout) {
"use strict";
return {
restrict: "A",
link: function(scope, element) {
function bannerAdjust() {
$banner = angular.element("#top-banner"), $banner.outerHeight() > 0 && $timeout(function() {
var paddingTop = detailTopStickyContent.css("padding-top");
paddingTop = parseInt(paddingTop.replace("px", "")), detailTopStickyContent.css("padding-top", $banner.outerHeight() + paddingTop), detailSecondaryColumn.css("padding-top", $banner.outerHeight() + paddingTop), scope.resize()
})
}
function _scroll() {
var $nameHeader = angular.element("h1[name=doc-header]"),
$floatingNav = angular.element(".floating-nav"),
floatingNavBottom = $floatingNav.offset().top + $floatingNav.height() + 30,
nameHeaderBottom = $nameHeader.offset().top + $nameHeader.height(),
$floatingHeader = angular.element(".floating-header > h1");
floatingNavBottom < nameHeaderBottom ? $floatingHeader.hide() : $floatingHeader.show(), detailTabContentNav.offset().top < floatingNavBottom && !detailTabContentNavClone && (detailTabContentNavClone = detailTabContentNav.clone().prop("id", detailTabContentNav.prop("id") + "-clone"), detailTabContentNavClone = detailTabContentNavClone.insertBefore(detailTabContentNav), detailTabContentNav.addClass("fixed"));
var $divider = angular.element("hr[name=divider]");
$divider.offset().top > detailTabContentNav.offset().top && detailTabContentNavClone && (detailTabContentNavClone.remove(), detailTabContentNavClone = null, detailTabContentNav.removeClass("fixed"))
}
var windowEl, detailTopStickyContent, detailTabContentNav, detailTabContentNavClone, detailTabContentNavTipPoint, detailTabContentNavHeight, detailSecondaryColumn, itemDetailEl, $banner;
scope.initialize = function() {
element.ready(function() {
$timeout(function() {
detailTopStickyContent = angular.element("#detailTopStickyContent"), detailTabContentNav = angular.element("#detailTabContentNav"), detailSecondaryColumn = angular.element("#detailSecondaryColumn"), bannerAdjust(), detailTabContentNavHeight = detailTabContentNav.outerHeight(), itemDetailEl = angular.element("#itemDetailContent"), windowEl.on("scroll", _scroll), windowEl.on("resize", scope.resize), scope.$on("$destroy", function() {
scope.destroy()
})
}, 350)
})
}, windowEl = angular.element($window), scope.$watch("loading", function() {
scope.loading === !1 && scope.initialize()
}), scope.$watch("showTab", function() {
angular.isDefined(scope.showTab) && $document.scrollTop(detailTabContentNavTipPoint)
}), scope.resize = function() {
$timeout.cancel(scope.resizeTimer), scope.resizeTimer = $timeout(function() {}, 100)
}, scope.destroy = function() {
windowEl.unbind("scroll", _scroll), windowEl.unbind("resize", scope.resize)
}
}
}
}), angular.module("voyager.component").directive("vsTableResults", function($window, $timeout, $document, tableResultsService) {
"use strict";
return {
restrict: "A",
link: function(scope, element, attr) {
scope.windowEl = angular.element($window), scope.windowWidth = scope.windowEl.width(), scope.windowHeight = scope.windowEl.height();
var searchResultMapContainerEl = angular.element("#searchResultMapContainer"),
listWrapEl = angular.element(".list_wrap");
scope.getAvailableHeight = function(size, availableHeight) {
return "small" === size ? scope.minHeight(availableHeight - 600) : "large" === size ? scope.minHeight(availableHeight - 280) : 0
}, scope.minHeight = function(availableHeight) {
return availableHeight < 250 && (availableHeight = 250), availableHeight
}, scope.animate = function(el, animateParams, callback) {
el.stop().css("visibility", "visible").animate(animateParams, 250, "linear", function() {
callback && callback()
})
}, scope.hideElement = function(el) {
el.css("visibility", "hidden")
}, scope.resizeContent = function() {
$timeout(function() {
if (scope.windowWidth < 768) return searchResultMapContainerEl.css({
visibility: "hidden",
height: 0
}), void listWrapEl.css("margin-top", scope.windowWidth < 640 ? "155px" : "110px");
var mapTopPosition = angular.element(".search-map").offset().top,
availableHeight = scope.windowHeight - mapTopPosition;
"small" === attr.size ? (availableHeight = scope.getAvailableHeight("small", availableHeight), scope.animate(searchResultMapContainerEl, {
height: availableHeight
})) : "no" === attr.size ? (availableHeight = 0, scope.animate(searchResultMapContainerEl, 0, function() {
scope.hideElement(searchResultMapContainerEl)
})) : availableHeight = scope.getAvailableHeight("large", availableHeight), scope.animate(searchResultMapContainerEl, {
height: availableHeight
}), scope.animate(listWrapEl, {
marginTop: availableHeight - 20
}), tableResultsService.setFixedWidths()
}, 100)
}, scope.resize = function() {
scope.windowWidth === scope.windowEl.width() && scope.windowHeight === scope.windowEl.height() || (scope.windowWidth = scope.windowEl.width(), scope.windowHeight = scope.windowEl.height(), scope.resizeContent())
}, $document.ready(function() {
scope.resizeContent(), scope.windowEl.on("resize", scope.resize), scope.$watch("tableViewMapSize", scope.resizeContent)
}), scope.$on("$destroy", function() {
scope.windowEl.unbind("resize", scope.resize)
})
}
}
}), angular.module("voyager.component").filter("urlValue", function(sugar) {
"use strict";
var urlValueFilter = function(input) {
return sugar.isUrl(input) ? '<a href="' + input + '" target="_blank">' + input + "</a>" : input
};
return urlValueFilter
}), angular.module("voyager.layout", []), angular.module("voyager.layout").directive("vsLayout", function($location) {
"use strict";
return {
restrict: "A",
link: function(scope) {
function toggleScreen() {
"/search" === $location.path() ? $("body").addClass("full") : $("body").removeClass("full")
}
if (scope.$on("$stateChangeSuccess", toggleScreen), !_.isUndefined(config.ecobar) && config.ecobar) {
var fileref = document.createElement("script");
fileref.setAttribute("type", "text/javascript"), fileref.setAttribute("src", "assets/js/vendor/ecobar/jquery.ecobar.js"), document.getElementsByTagName("head")[0].appendChild(fileref)
}
}
}
}), angular.module("voyager.layout").controller("HeaderCtrl", function(config, $rootScope, $scope, $uibModal, $window, $location, $stateParams, $timeout, sugar, cartService, taskService, authService, systemService, savedSearchService, $state, catalogService, configService) {
function _init() {
_updateUserInfo(), cartService.addObserver(_updateQueueTotal), authService.addObserver(_updateUserInfo), $scope.$on("$stateChangeSuccess", _updateClassicLink), configService.fetchCartTasks().then(function(cartTasks) {
vm.cartTasks = cartTasks
})
}
function _updateClassicLink() {
if (authService.hasPermission("manage")) {
var path = $location.path();
vm.showClassicLink = path.indexOf("/search") > -1 || path.indexOf("/show") > -1 || path.indexOf("/home") > -1
} else vm.showClassicLink = !1
}
function _logout() {
authService.doLogout(), $state.go("login")
}
function _updateQueueTotal() {
vm.queueTotal = cartService.getCount() || "0"
}
function _updateUserInfo() {
vm.isAnonymous = authService.isAnonymous(), vm.state = authService.getState(), vm.user = authService.getUser(), vm.canCart = authService.hasPermission("process"), vm.canManage = authService.hasPermission("manage"), vm.canSaveSearch = authService.hasPermission("save_search"), vm.canRestart = authService.hasPermission("shutdown_restart"), vm.showLogout = authService.showLogout(), vm.canViewAnalytics = authService.hasPermission("view_analytics"), _updateClassicLink(), vm.canCart && _updateQueueTotal()
}
function _showLoginDialog() {
var modalInstance = $uibModal.open({
templateUrl: "common/security/login.html",
size: "md",
controller: "AuthCtrl"
});
modalInstance.result.then(function() {}, function() {}), vm.toggleMobileNav()
}
function _login() {
vm.loggedIn ? authService.doLogout() : authService.checkAccess().then(function(hasAccess) {
hasAccess || _showLoginDialog()
})
}
function _showSavedSearch() {
$uibModal.open({
template: "<saved-content />",
size: "lg",
scope: $scope
}), vm.toggleMobileNav()
}
function _getTaskObject(taskName) {
return taskService.findAllTasks(!1).then(function(taskList) {
var task;
for (var property in taskList)
if (taskList.hasOwnProperty(property)) {
var category = taskList[property];
if (void 0 !== task) {
task.isModal = !0, $stateParams.task = task;
break
}
task = _.find(category, {
name: taskName
})
}
})
}
var vm = this;
vm.queue = {}, vm.login = _login, vm.logout = _logout, vm.showSavedSearch = _showSavedSearch, vm.manageLink = config.root + "manage", vm.myVoyagerLink = config.root + "manage", vm.analyticsLink = config.root + "analytics", vm.showClassicLink = !1, vm.showNav = "/login" !== $location.path(), vm.buildRev = "d8d7fd7", vm.mobileToggleClass = "fa fa-bars", vm.logo = config.root + "pub/header.png", vm.uiText = config.ui.navbar, vm.debug = "true" === $location.search().debug, angular.isDefined($location.search().disp) && (vm.disp = "?disp=" + $location.search().disp), $scope.$on("filterChanged", function() {
angular.isDefined($location.search().disp) && (vm.disp = "?disp=" + $location.search().disp)
}), $rootScope.$on("$stateChangeStart", function(event, toState) {
vm.showNav = "login" !== toState.name
}), vm.gotoPage = function(route) {
route.indexOf("task?") !== -1 ? $window.location.href = route : $window.location.href = route + "?disp=" + ($location.search().disp || "default"), vm.toggleMobileNav()
}, vm.clearQueue = function() {
cartService.clear(), $scope.$emit("removeAllCartEvent", {}), vm.toggleMobileNav()
}, vm.toggleMobileNav = function() {
"" === vm.navClass || void 0 === vm.navClass ? (vm.navClass = "full_width", vm.mobileToggleClass = "icon-x") : (vm.navClass = "", vm.mobileToggleClass = "fa fa-bars")
}, vm.openTaskModal = function(taskName) {
_getTaskObject(taskName).then(function() {
$uibModal.open({
templateUrl: "src/taskrunner/task_modal.html",
controller: "TaskCtrl",
size: "lg",
scope: $scope
})
})
}, _init(), vm.goToClassic = function() {
var params = $location.search(),
baseUrl = config.root + config.explorePath + "/#/";
if ("card" === params.view && delete params.view, angular.isDefined(params.shard)) {
var catalog = catalogService.lookup(params.shard);
angular.isDefined(catalog) && (params.shard = catalog.id)
}
params = sugar.retroParams(params);
var path = $location.path();
path.indexOf("/show") !== -1 ? baseUrl += path.replace("/show", "") : path.indexOf("/home") !== -1 && (params = ""), $window.open(baseUrl + params, "_blank")
}, vm.restart = function() {
$uibModal.open({
templateUrl: "common/modal/confirm-modal.html",
controller: "ConfirmRestartCtrl",
controllerAs: "vm",
size: "md"
})
}, $scope.$on("$destroy", function() {
authService.removeObserver(_updateUserInfo), cartService.removeObserver(_updateQueueTotal)
})
}), angular.module("voyager.layout").controller("ConfirmRestartCtrl", function($scope, $uibModalInstance, systemService) {
function _setStatus_WAITING() {
vm.showMessage = !0, vm.isWaiting = !0, vm.hasCompleted = !1, vm.hasError = !1
}
function _setStatus_COMPLETED() {
vm.showMessage = !0, vm.isWaiting = !1, vm.hasCompleted = !0, vm.hasError = !1
}
function _setStatus_FAILED() {
vm.showMessage = !0, vm.isWaiting = !1, vm.hasCompleted = !1, vm.hasError = !0
}
function _restart() {
systemService.doRestart().then(function() {
systemService.checkForLife(_setRestartSuccessful, 2500, 1e4)
}, function() {
_setRestartFailed()
}).catch(function() {
_setRestartFailed()
})
}
function _setRestartSuccessful() {
_setStatus_COMPLETED(), vm.statusMessage = "Voyager Restart has Completed Successfully", vm.confirmButtonText = "Restart", vm.cancelLinkText = "Dismiss"
}
function _setRestartFailed() {
_setStatus_FAILED(), vm.statusMessage = "Voyager Restart has Failed", vm.confirmButtonText = "Retry", vm.cancelLinkText = "Dismiss"
}
var vm = this;
vm.modalHeader = "Confirm Restart", vm.modalText = ["This will restart Voyager.", "Are you sure you want to continue?"], vm.confirmButtonText = "Confirm", vm.cancelLinkText = "Cancel", vm.statusMessage = "", vm.showMessage = !1, vm.isWaiting = !1, vm.hasCompleted = !1, vm.hasError = !1, vm.confirm = function() {
vm.statusMessage = "Warning: The Server is Restarting", _setStatus_WAITING(), _restart()
}, vm.cancel = function() {
$uibModalInstance.dismiss(vm.cancelLinkText)
}
}), angular.module("voyager.home", ["leaflet-directive", "voyager.common.featured", "voyager.common.savedsearch", "voyager.util", "voyager.config", "voyager.search"]), angular.module("voyager.home").service("featureQuery", function(config, $http, cartService, $q, configService, translateService, featuredService, savedSearchQuery, sugar, authService, resultsDecorator, $location) {
function _getSavedSearchQueryString(savedSearch) {
var config = $location.search().disp;
return angular.isUndefined(config) && (config = savedSearch.config), configService.setFilterConfig(config).then(function() {
var solrParams = querystring.parse(sugar.trim(savedSearch.query, "&"));
delete solrParams.facet, delete solrParams["facet.field"], delete solrParams["facet.mincount"], delete solrParams["extent.bbox"], sugar.decodeParams(solrParams);
var queryString = _getQueryString();
return queryString += "&" + querystring.stringify(solrParams)
})
}
function _getDefaultQueryString() {
var savedSearch;
return savedSearchQuery.fetchDefault().then(function(docs) {
return docs && docs.length > 0 ? (savedSearch = docs[0], _featureQuery = savedSearch, _getSavedSearchQueryString(savedSearch)) : (_featureQuery = void 0, _getQueryString())
})
}
function _getConfiguredQuery() {
var savedSearch, featuredQuery = "";
return config.homepage && config.homepage.featuredContentQuery && (featuredQuery = config.homepage.featuredContentQuery), "" !== featuredQuery ? savedSearchQuery.fetch(featuredQuery).then(function(docs) {
return docs && docs.length > 0 ? (savedSearch = docs[0], _featureQuery = savedSearch, _getSavedSearchQueryString(savedSearch)) : _getDefaultQueryString()
}) : _getDefaultQueryString()
}
function _getQueryString() {
var rows = 12,
queryString = config.root + "solr/v0/select?";
return queryString += "fl=id,title, name:[name],format,abstract,fullpath:[absolute],thumb:[thumbURL], path_to_thumb, subject,download:[downloadURL],format_type,bytes,modified,shard:[shard],bbox,format_category, component_files, tag_flags", queryString += configService.getSolrFields(), queryString += "&rows=" + rows, queryString += "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _execute() {
var deferred = $q.defer(),
queryPromise = _getConfiguredQuery().then(function(queryString) {
return $http.jsonp(queryString)
});
return $q.all([queryPromise]).then(function(res) {
var searchResult = res[0].data.response.docs;
return resultsDecorator.decorate(searchResult, []), deferred.resolve(searchResult)
}), deferred.promise
}
var _featureQuery;
return {
execute: function() {
return _execute()
},
getFeatureQuery: function() {
return _featureQuery
}
}
}), angular.module("voyager.home").service("collectionsQuery", function(config, $http) {
function _getQueryString(count) {
var rows = 1e3,
label = config.homepage.sidebarLinksLabel,
queryString = config.root + "solr/ssearch/select?fq=labels:" + label + "&fl=id,title,query,display:[display],*";
return count && (queryString += ",count:[count]"), queryString += "&rows=" + rows + "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK&block=false", queryString += "&sort=order desc"
}
function _execute(count) {
return $http.jsonp(_getQueryString(count)).then(function(data) {
return data.data.response.docs
}, function(error) {
return error
})
}
return {
execute: function(count) {
return _execute(count)
}
}
}), angular.module("voyager.home").service("homeService", function(config, $http, $q, featureQuery, collectionsQuery) {
function _collectionsAction(count) {
return config.homepage && config.homepage.showSidebarLinks ? collectionsQuery.execute(count) : $q.when(null)
}
return {
fetchCollections: function(count) {
return _collectionsAction(count)
},
fetchFeatured: function() {
return featureQuery.execute()
},
getFeaturedQuery: function() {
return featureQuery.getFeatureQuery()
}
}
}), angular.module("voyager.home").controller("HomeCtrl", function(config, $scope, $window, $location, homeService, authService, leafletData, filterService, searchService, savedSearchService, sugar, configService, savedSearchQuery, $uibModal, cartService, $log) {
function _reload(response) {
"login" === response.action && _init()
}
function _init() {
cartService.fetch(!1).then(function(data) {
cartService.setQueryCount(data.count)
}, function(error) {
$log.error(error)
}), homeService.fetchCollections(!1).then(function(respond) {
$scope.collections = respond, _fetchCounts()
}), homeService.fetchFeatured().then(function(respond) {
$scope.featured = respond
}), $scope.$watch("selectedMapType", function() {
"Map" === $scope.selectedMapType ? ($scope.showMap = !0, $scope.displayFormat = "short_format") : ($scope.showMap = !1, $scope.displayFormat = "detail_format")
}), $scope.$on("updateSearchType", function(e, type) {
$scope.selectedMapType = type
}), $scope.$on("updateSearchDrawingType", function(event, args) {
$scope.selectedDrawingType = args
})
}
function _fetchCounts() {
_.isEmpty($scope.collections) || homeService.fetchCollections(!0).then(function(docs) {
var docMap = sugar.toMap("id", docs);
$scope.collections.forEach(function(item) {
item.count = docMap[item.id].count
})
})
}
function _changeSearchTab(type) {
$scope.showRecent = "recent" === type
}
function _submitSearch() {
filterService.clear();
var params = {};
if (_.isEmpty($scope.search.query) || ($scope.useExpandedQueries && !_.startsWith($scope.search.query, "{!expand}") ? $scope.search.query = "{!expand}" + $scope.search.query : $scope.useExpandedQueries || ($scope.search.query = $scope.search.query.replace("{!expand}", "")), params.q = $scope.search.query), _.isEmpty($scope.search.q) && ($scope.search.q = null), "Place" === $scope.selectedMapType) {
if (!_.isEmpty($scope.search.location)) {
params.place = $scope.search.location;
var placeId = $location.search()["place.id"];
angular.isDefined(placeId) && (params["place.id"] = placeId), params["place.op"] = $scope.selectedDrawingType.toLowerCase()
}
} else void 0 !== $scope.search.place && (params.place = $scope.search.place, params["place.op"] = $scope.selectedDrawingType.toLowerCase());
var disp = $location.search().disp;
return angular.isDefined(disp) && (params.disp = disp), savedSearchQuery.fetchDefaultParams().then(function(solrParams) {
_.isEmpty(params.q) || delete solrParams.q, _.isEmpty(params.place) || (delete solrParams.place, delete solrParams["place.op"], delete solrParams["place.id"]), params = _.extend(params, solrParams), $location.path("search").search(params)
}), !1
}
function _changeSelectedType(type) {
$scope.selectedMapType = type
}
$scope.search = {}, $scope.mapTypes = ["Place", "Map"], $scope.selectedMapType = "Place", $scope.drawingTypes = ["Within", "Intersects"], $scope.selectedDrawingType = "Within", $scope.displayFormat = "detail_format", $scope.showRecent = !0, $scope.changeTab = _changeSearchTab, $scope.submitSearch = _submitSearch, $scope.changeSelectedType = _changeSelectedType, $scope.showPan = !0, $scope.hideMap = !configService.showMap(), $scope.featuredTitle = "Featured", $scope.collectionsTitle = "Collections", $scope.searchInputClass = "col-md-6 col-xs-6", $scope.placeInputClass = "col-md-6 col-xs-6", $scope.QueryExpansionInputClass = "col-md-2 col-xs-2", $scope.showSpatialInput = !0, $scope.useExpandedQueries = config.queryExpansion && config.queryExpansion.checkedByDefault, $scope.queryExpansionEnabled = config.queryExpansion && config.queryExpansion.enabled, $scope.toggleUseExpandedQueries = function() {
$scope.useExpandedQueries = !$scope.useExpandedQueries
}, $scope.showAll = function() {
var search = homeService.getFeaturedQuery();
angular.isDefined(search) ? savedSearchService.applySavedSearch(search, $scope) : _submitSearch()
}, $scope.hideMap && ($scope.containerStyle = "margin-top: -60px; height: 180px"), config.homepage && angular.isDefined(config.homepage.featuredContentTitle) && ($scope.featuredTitle = config.homepage.featuredContentTitle), config.homepage && angular.isDefined(config.homepage.sidebarLinksTitle) && ($scope.collectionsTitle = config.homepage.sidebarLinksTitle), config.homepage && config.homepage.showPlaceQuery === !1 && ($scope.mapTypes = ["Map"], $scope.showMap = !0, $scope.displayFormat = "short_format", $scope.selectedMapType = "Map"), $scope.hideMap && ($scope.mapTypes = ["Place"], $scope.showMap = !1, $scope.selectedMapType = "Place"), config.homepage && config.homepage.showPlaceQuery === !1 && $scope.hideMap && ($scope.searchInputClass = "col-xs-12", $scope.showSpatialInput = !1), $scope.hasPermission = function(permission) {
return authService.hasPermission(permission)
}, authService.addObserver(_reload), _init(), $scope.saveLocation = function() {
$uibModal.open({
template: "<vs-save-location-dialog />",
size: "md",
scope: $scope
})
}, $scope.clearField = function() {
$scope.showMap ? delete $scope.search.displayBBox : $scope.search.location = ""
}, $scope.$on("$destroy", function() {
authService.removeObserver(_reload)
})
}), angular.module("voyager.home").directive("vsSearchform", function($timeout) {
function _adjustMap(element) {
var availableHeight = $(window).height() - $("#header").height(),
timeDuration = .5 * availableHeight;
$(".content-header-padding").length && (availableHeight -= $(".content-header-padding").height()), $("#searchContainer").stop().animate({
height: availableHeight
}, timeDuration, "linear"), element.stop().animate({
top: availableHeight - $("#searchContainer .search_wrap").outerHeight() - 3,
height: $(".search_wrap").outerHeight()
}, timeDuration, "linear")
}
return {
restrict: "A",
link: function(scope, element) {
function _resizeMap() {
$timeout.cancel(timer), "short_format" === scope.displayFormat && (timer = $timeout(function() {
_adjustMap(element)
}, 15))
}
$timeout(function() {
element.find("input[name=query]").trigger("focus").parents("fieldset").addClass("focused").siblings().removeClass("focused")
}, 155), element.on("focus", ".input_field", function(event) {
$(event.currentTarget).parents("fieldset").addClass("focused").siblings().removeClass("focused")
}).on("blur", ".input_field", function(event) {
$(event.currentTarget).parents("fieldset").removeClass("focused")
}), scope.$watch("displayFormat", function() {
"short_format" === scope.displayFormat ? element.find(".location_fieldset").addClass("focused") : element.find(".location_fieldset").removeClass("focused")
});
var initialized = !1;
scope.$watch("displayFormat", function() {
return initialized ? ($(window).scrollTop(0), void("short_format" === scope.displayFormat ? _adjustMap(element) : (element.css("height", "auto").stop().animate({
top: 100,
height: $(".search_wrap").outerHeight() + $("#searchHistory").outerHeight()
}, 300, "linear", function() {
$(this).css("height", "auto")
}), $("#searchContainer").stop().animate({
height: 540
}, 300, "linear")))) : void(initialized = !0)
});
var timer;
$(window).on("resize", _resizeMap), scope.$on("$destroy", function() {
$timeout.cancel(timer), $(window).unbind("resize", _resizeMap)
})
}
}
}), angular.module("voyager.search", ["voyager.filters", "voyager.util", "angularSpinner", "ui.router", "ui.slider", "leaflet-directive", "voyager.map", "dialogs.main", "leaflet-directive", "ui.bootstrap", "cart", "voyager.security", "ngGrid", "angulartics", "voyager.map", "voyager.common.featured", "voyager.heatmap", "vs.tools.displayConfig", "toastr"]),
function() {
"use strict";
function resultsDecorator(configService, sugar, translateService, cartService, authService, $location, config, $filter, catalogService) {
function _setFormatProperties(doc) {
doc.displayFormat = translateService.getType(doc.format), doc.isService = _mappable[doc.format]
}
function _loadDisplayFields(doc) {
var htmlified = "";
return doc.displayFields = configService.getDisplayFields(doc), $.each(doc.displayFields, function(index, field) {
htmlified += _decorateField(field)
}), htmlified
}
function _loadExtraRelationshipFields(doc, fields) {
var htmlified = "";
return $.each(fields, function(index, field) {
var _f = {
raw: field
};
doc[_f.raw] && (_f.name = translateService.getFieldName(_f.raw), _f.value = doc[_f.raw], _f.showLabel = !0, _f.maxLines = 3, sugar.isUrl(_f.value) && (_f.isHref = !0), htmlified += _decorateField(_f))
}), htmlified
}
function _decorateField(field) {
var values, formattedValues, trimmed, facetValue, htmlified = "",
actualValues = {},
formattedValue = field.value,
lowerFieldName = field.name.toLowerCase();
if ("format" === lowerFieldName && (formattedValue = translateService.getType(field.value)), "STRIP_HTML" === field.style && (formattedValue = $("<p>" + field.value + "</p>").text()), "HTML" === field.style && (field.isHtml = !0), ("HREF" === field.style || sugar.isUrl(field.value)) && (field.isHref = !0), "contains_mime" === field.raw ? field.value.indexOf(",") !== -1 ? (formattedValues = [], values = formattedValue.split(","), _.each(values, function(val) {
trimmed = _.trim(val), formattedValue = translateService.getType(trimmed), formattedValues.push(formattedValue), actualValues[formattedValue] = trimmed
}), formattedValue = formattedValues.join()) : formattedValue = translateService.getType(field.value) : "bytes" === field.raw ? formattedValue = $filter("bytes")(field.value) : sugar.isDate(field.value) && (formattedValue = $filter("date")(Date.parse(field.value), "M/d/yyyy, hh:mma")), field.formattedValue = formattedValue, "description" !== lowerFieldName && "abstract" !== lowerFieldName && isNaN(field.value) && "extent" !== lowerFieldName && !field.isHref)
if (formattedValue.indexOf(",") !== -1) {
field.showLabel && (htmlified += "<b>" + field.name + "</b>:"), values = formattedValue.split(",");
var sep = "";
_.each(values, function(val) {
htmlified += sep, facetValue = _.trim(val), angular.isDefined(actualValues[facetValue]) && (facetValue = actualValues[facetValue]), htmlified += '<a href="javascript:;" ng-click="applyFilter(\'' + field.raw + "','" + facetValue + "')\"> " + val + "</a>", sep = ","
}), htmlified += "<br>"
} else htmlified += (field.showLabel ? "<b>" + field.name + "</b>: " : "") + '<a href="javascript:;" ng-click="applyFilter(\'' + field.raw + "','" + field.value + "')\">" + $("<p>" + field.formattedValue + "</p>").text() + "</a><br>";
else htmlified += field.isHref ? (field.showLabel ? "<b>" + field.name + "</b>: " : "") + '<a href="' + field.value + '">' + $("<p>" + field.formattedValue + "</p>").text() + "</a><br>" : (field.showLabel ? "<b>" + field.name + "</b>: " : "") + $("<p>" + field.formattedValue + "</p>").text() + "<br>";
return field.maxLines && (htmlified = '<div class="max-lines" style="max-height: ' + 20 * field.maxLines + 'px;">' + htmlified + "</div>"), htmlified
}
function _getDetailsLink(doc, disp) {
var link = "show?id=" + encodeURIComponent(encodeURIComponent(doc.id)) + "&disp=" + disp;
return angular.isDefined(doc.shard) && "[not a shard request]" !== doc.shard && (link += "&shard=" + doc.shard, doc.isRemote = catalogService.isRemote(doc.shard)), link
}
function _removeLongTextFieldNames(htmlValue) {
return htmlValue = htmlValue.replace("<b>Description</b>:", ""), htmlValue = htmlValue.replace("<b>Abstract</b>:", "")
}
function _decorateRelationships(docs, fields) {
var htmlified;
$.each(docs, function(index, doc) {
htmlified = _loadExtraRelationshipFields(doc, fields), doc.htmlValue = _removeLongTextFieldNames(htmlified)
})
}
function _decorate(docs, recordIds, visitor) {
var htmlified, disp = $location.search().disp || "default";
return $.each(docs, function(index, doc) {
recordIds.push({
id: doc.id,
shard: doc.shard
}), doc.isopen = !1, doc.getActionText = "Download", angular.isDefined(doc.download) && (doc.hasDownload = !0, 0 === doc.download.indexOf("file:") && (doc.canOpen = !0, doc.getActionText = "Open")), angular.isDefined(doc.layerURL) && (doc.isEsriLayer = !0), angular.isDefined(doc.format) && _setFormatProperties(doc), _.isEmpty(doc.format) || (doc.formatValue = translateService.getTypeAbbr(doc.format), doc.formatLink = "search?fq=format:" + doc.format + "&disp=" + disp), angular.isDefined(doc.bytes) && (doc.size = sugar.bytesToSize(doc.bytes)), htmlified = _loadDisplayFields(doc), doc.htmlValue = _removeLongTextFieldNames(htmlified), doc.detailLink = _getDetailsLink(doc, disp), doc.inCart = cartService.isInCart(doc.id), doc.isRemote !== !0 && (doc.canCart = authService.hasPermission("process")), angular.isDefined(doc.thumb) && doc.thumb.indexOf("vres/mime") !== -1 && (doc.defaultThumb = !0), visitor && visitor(doc)
}), recordIds
}
var _mappable = {
"application/x-arcgis-image-server": !0,
"application/x-arcgis-feature-server": !0,
"application/x-arcgis-feature-server-layer": !0,
"application/x-arcgis-map-server": !0,
"application/x-arcgis-map-server-layer": !0,
"application/vnd.ogc.wms_xml": !0,
"application/vnd.ogc.wms_layer_xml": !0
};
return {
decorate: _decorate,
decorateField: _decorateField,
decorateRelationships: _decorateRelationships
}
}
angular.module("voyager.search").factory("resultsDecorator", resultsDecorator)
}(), angular.module("voyager.search").factory("searchService", function($http, translateService, filterService, urlUtil, config, queryBuilder, sugar, $q, configService, solrGrunt, cartService, $analytics, authService, resultsDecorator) {
"use strict";
function _setParams(params) {
if (angular.isUndefined(_sortField) && (_sortField = _defaultSortField), angular.isDefined(params.sort))
if (params.sort.indexOf(" ") !== -1) {
var sortInfo = params.sort.split(" ");
_sortField = sortInfo[0], _sortDirection = sortInfo[1]
} else _sortField = params.sort;
angular.isDefined(params.sortdir) && (_sortDirection = params.sortdir), _searchParams = solrGrunt.getSolrParams(params)
}
function _track(solrPage, data, endTime) {
$analytics.eventTrack("search", {
category: "time",
label: solrPage,
value: endTime,
user: authService.getUser().id
}), $analytics.eventTrack("search", {
category: "size",
label: solrPage,
value: data.response.docs.length,
user: authService.getUser().id
}), $analytics.eventTrack("search-group", {
category: authService.getGroupsJoined(),
label: solrPage,
user: authService.getUser().id
})
}
var _searchParams, _page = 1,
_idsPage = _page,
_itemsPerPage = 48,
_solrService = "",
_lastResult = {},
_recordIds = [],
_sortDirection = angular.isDefined(config.defaultSortDirection) ? config.defaultSortDirection : "desc",
_defaultSortField = angular.isDefined(config.defaultSort) ? config.defaultSort : "score",
_sortField = "score",
_mapView = "0 0 0",
getMapView = function(mapView) {
var val;
return _mapView ? (val = _mapView, _mapView = null, val) : mapView
};
return {
doSearch2: function(params, append) {
_setParams(params);
var service = queryBuilder.doBuild2(_searchParams, _page, _itemsPerPage, _sortDirection, _sortField, !0);
_solrService = service;
var solrPage = service.substring(service.indexOf("solr") - 1);
urlUtil.buildSearchUrl2(_searchParams, _page, getMapView(params.vw), params.view, _sortField);
var startTime = Date.now();
return $http.get(service).success(function(data) {
var endTime = Date.now() - startTime;
_lastResult = data, append || (_recordIds = [], _idsPage = _page), resultsDecorator.decorate(data.response.docs, _recordIds), _track(solrPage, data, endTime)
})
},
setPage: function(value) {
_page = value
},
getPage: function() {
return _page
},
clear: function() {
filterService.clear(), _page = 1
},
getLastQuery: function() {
return _solrService
},
getLastSearch: function() {
return urlUtil.getLastUrl()
},
setSort: function(direction) {
_sortDirection = direction
},
setSortField: function(field) {
_sortField = field
},
getSortField: function() {
return _sortField
},
getPrettySortField: function() {
return translateService.getFieldName(_sortField)
},
getSort: function() {
return _sortDirection
},
setMapView: function(val) {
_mapView = val
},
setItemsPerPage: function(val) {
_itemsPerPage = val
},
getItemsPerPage: function() {
return _itemsPerPage
},
getResults: function() {
return _lastResult
},
hasRecords: function() {
return _recordIds.length > 0
},
getPageIds: function() {
return _recordIds
},
getPreviousId: function(id) {
var index = _.findIndex(_recordIds, {
id: id
});
return 0 !== index ? _recordIds[index - 1] : null
},
getNextId: function(id) {
var deferred = $q.defer(),
index = _.findIndex(_recordIds, {
id: id
}),
nextId = null;
if (index !== _recordIds.length - 1 && (nextId = _recordIds[index + 1], deferred.resolve(nextId)), null === nextId) {
_idsPage += 1;
var service = queryBuilder.doBuild2(_searchParams, _idsPage, _itemsPerPage, _sortDirection, _sortField);
$http.jsonp(service).success(function(data) {
$.each(data.response.docs, function(index, doc) {
0 === index && (nextId = {
id: doc.id,
shard: doc.shard
}), _recordIds.push({
id: doc.id,
shard: doc.shard
})
}), deferred.resolve(nextId)
})
}
return deferred.promise
},
getAllIds: function() {
var service = queryBuilder.buildAllIds(_searchParams);
return $http.jsonp(service)
},
getAllBboxes: function() {
var service = queryBuilder.buildAllBboxes(_searchParams);
return $http.jsonp(service)
},
reset: function() {
_sortDirection = angular.isDefined(config.defaultSortDirection) ? config.defaultSortDirection : "desc", _sortField = _defaultSortField || "score"
},
testEsriGeocodeService: function() {
var d = $q.defer();
return $http.jsonp(queryBuilder.buildEsriGeocodeServiceTestQuery()).success(function(rsp) {
_.isEmpty(rsp.placefinder.results) ? d.resolve(!1) : d.resolve(!0)
}), d.promise
}
}
}),
function() {
function searchScroll(searchService, $timeout, $window) {
function _resetItemsPerPage(view) {
"table" === view ? searchService.setItemsPerPage(50) : searchService.setItemsPerPage(48)
}
var _position = 0,
_actualPage = 0;
return {
setPosition: function(pos) {
_position = pos
},
getPosition: function() {
return _position
},
do: function(view) {
$timeout(function() {
if (_position > 0) {
var windowEl = angular.element($window);
windowEl.scrollTop(_position), searchService.setPage(_actualPage)
}
_resetItemsPerPage(view)
})
},
getPage: function() {
return _actualPage
},
prepare: function(view) {
if (_position > 0) {
_actualPage = searchService.getPage();
var records = 0;
records = "table" === view ? 50 * _actualPage : 48 * _actualPage, searchService.setItemsPerPage(records)
}
},
setItemsPerPage: function() {
_resetItemsPerPage()
}
}
}
angular.module("voyager.search").factory("searchScroll", searchScroll)
}(), angular.module("voyager.search").controller("SearchCtrl", function($scope, cartService, searchService, $location, authService, loading, $window, $document, usSpinnerService, configService, localStorageService, config, $analytics, savedSearchService, recentSearchService, filterService, cartItemsQuery, $timeout, inView, $q, searchScroll, urlUtil, searchViewService, searchModalService, tagService, $log, extractionService) {
function _init() {
inView.reset(), $scope.uiText = config.ui.list, $scope.bigMap = !1, $scope.mapSize = "small-map", $scope.showGrid = !1, $scope.result = {}, $scope.filterVisible = !1, $scope.placefinderLink = config.root + "manage/settings/placefinder", $scope.eof = !1, $scope.pageFramework = configService.getPageFramework(), $scope.pageFramework.showMap || angular.element("body").addClass("no-map"), loading.show("#working"), _params.pg && _params.pg > 1 && (_page = parseInt(_params.pg)), _.isEmpty(_params.disp) || ($scope.disp = _params.disp), _.isEmpty(_params.mapsize) ? $scope.tableViewMapSize = "large" : $scope.tableViewMapSize = _params.mapsize, $scope.count = 0, $scope.maxSize = 5, $scope.totalItems = 1, _.isEmpty(_params.view) ? ($scope.view = configService.getDefaultView(), $location.search("view", $scope.view)) : "table" === _params.view ? ($scope.view = "table", searchService.setItemsPerPage(50)) : $scope.view = _params.view, _initFilters(), $scope.canCart = !hasRemoteShard() && authService.hasPermission("process"), $scope.canAdmin = authService.hasPermission("manage"), $scope.canViewFeed = authService.hasPermission("show_rss"), $scope.canViewAnalytics = authService.hasPermission("view_analytics")
}
function _initFilters() {
$timeout(function() {
_.isEmpty(_params.fq) || filterService.setFilters(_params.fq), $scope.$emit("filterEvent", {}), searchService.clear(), "true" === $location.search().filter && ($scope.filterVisible = !1, $scope.toggleFilter())
})
}
function _reloadResults(response) {
"login" === response.action && _init()
}
function _setSortDirection() {
searchService.getSort() ? $scope.sortDirection = searchService.getSort() : $scope.sortDirection = "asc"
}
function _searchSuccess() {
$scope.currentPage = _page, _setSortDirection(), _initializing = !1, "table" === $scope.view && ($scope.showGrid = !0), loading.done(), $scope.selectedFilters = filterService.getFilters(), _busy = !1
}
function _setSortField() {
if (_.isEmpty(_params.sort)) $scope.sortable.length > 0 && ($scope.displaySortField = $scope.sortable[0].value, $scope.sortField = $scope.sortable[0].key);
else {
0 !== _params.sort.indexOf(" ") ? $scope.sortField = _params.sort.split(" ")[0] : $scope.sortField = _params.sort;
for (var field in $scope.sortable)
if ($scope.sortable[field].key === $scope.sortField) {
$scope.displaySortField = $scope.sortable[field].value;
break
}
}
}
function _syncCartState(docs) {
if (cartService.hasItems()) {
var itemIds = searchService.getPageIds();
return itemIds = itemIds.slice(Math.max(itemIds.length - searchService.getItemsPerPage(), 0)), cartService.fetchQueued(itemIds).then(function(items) {
_setCartState(items, docs), $scope.$broadcast("syncCard", {})
})
}
return $q.when({})
}
function _syncCartCount() {
cartService.fetch(!1).then(function(data) {
cartService.setQueryCount(data.count)
}, function(error) {
$log.error(error)
})
}
function _formatErrorReason(error) {
var reason = "Search failed.";
return error && (error.msg || "").toLowerCase().indexOf("undefined field") > -1 && (reason += " One or more fields do not exist for this saved search."),
reason
}
function _handleSearchError(res) {
searchScroll.setPosition(0), $scope.eof = !1, $scope.totalItems = 0, $scope.results = {}, loading.done(), _busy = !1, _searching = !1, _initializing = !1, $scope.searchError = !0, $scope.searchErrorReason = _formatErrorReason((res.data || {}).error), res.data = {
response: {
docs: []
}
}, $scope.$emit("searchComplete", res.data), _setPageClass()
}
function checkFederations(res) {
var shards = res.data["shards.info"];
if (shards)
for (var shard in shards)
if (!_.isEmpty(shards[shard].error)) {
$scope.resultError = !0, $scope.resultStackTrace = shards, _setPageClass();
break
}
}
function checkEsriGeocoder(res) {
var placefinder = res.data.response.placefinder;
$scope.esriGeocodeServiceError = placefinder && placefinder.errors && placefinder.errors.esri
}
function _doSearch() {
!$scope.pageFramework.showHeaderInfo && $location.path().indexOf("/search") > -1 ? angular.element("body").addClass("no-header") : angular.element("body").removeClass("no-header"), _searching = !0, $scope.sortable = configService.getSortable(), _setSortField(), document.body.scrollTop = document.documentElement.scrollTop = 0, loading.show("#working"), _params = $location.search(), searchScroll.prepare(_params.view), searchService.setPage(1), searchService.doSearch2(_params).then(function(res) {
loading.done(), $scope.$emit("searchComplete", res.data), $scope.results = res.data.response.docs, $scope.totalItems = res.data.response.numFound, $scope.eof = $scope.totalItems > 0 && $scope.results.length >= $scope.totalItems, _syncCartState($scope.results), _syncCartCount(), _searchSuccess(), _searching = !1, $scope.searchError = !1, checkFederations(res), checkEsriGeocoder(res), $location.search("block", null), searchScroll.getPosition() > 0 && (_page = searchScroll.getPage(), searchScroll.do(_params.view)), $scope.resetTable = !1, $scope.gridView = configService.getGridView()
}, function(res) {
_handleSearchError(res)
}), 1 === _page && _.isEmpty(_params.id) && _.isEmpty(_params.recent) && recentSearchService.addItem(_params)
}
function _setCartState(items, docs) {
var itemMap = _.indexBy(items, "id");
$.each(docs, function(index, item) {
itemMap[item.id] && (item.inCart = !0)
})
}
function hasRemoteShard() {
var shards = $location.search().shards;
if (angular.isDefined(shards)) {
if (shards.indexOf(",") !== -1) return !0;
if ("local" !== shards.toLowerCase()) return !0
}
return !1
}
function _setPageClass() {
var _pageClass = searchViewService.getPageClass($scope.filterVisible, $scope.view, $scope.pageFramework.showMap, $scope.searchError, $scope.resultError);
$scope.mapWrapperClass = _pageClass.mapWrapperClass, $scope.mapContentClass = _pageClass.mapContentClass, $scope.headerClass = _pageClass.headerClass, $scope.listViewClass = _pageClass.listViewClass
}
function _bannerAdjust(view) {
if (_bannerAdjusted || "table" !== view) {
var mapContent = angular.element(".map_content");
mapContent.css("top", ""), _bannerAdjusted = !1
} else _bannerAdjusted = !0, $timeout(function() {
var banner = angular.element("#top-banner");
if (banner.length > 0) {
var bannerHeight = banner.height(),
mapContent = angular.element(".map_content");
mapContent.offset({
top: mapContent.offset().top + bannerHeight
})
}
})
}
function _setView(view, doSearch) {
var currentView = $scope.view;
$scope.view = angular.isUndefined(view) ? "card" : view, _page = 1, $location.search("view", $scope.view), _bannerAdjust(view), "table" === view ? searchService.setItemsPerPage(50) : (searchService.setItemsPerPage(48), doSearch === !0 && _doSearch(_page)), urlUtil.updateParam("view", currentView, $scope.view), _setPageClass()
}
function _loadNextChunk($scope) {
_page += 1, _busy = !0, searchScroll.setItemsPerPage(), searchService.setPage(_page), _params = $location.search(), searchService.doSearch2(_params, !0).then(function(res) {
var docs = res.data.response.docs;
checkFederations(res), _syncCartState(docs).then(function() {
docs.length > 0 ? $.merge($scope.results, docs) : $scope.eof = !0, res.data.response.docs = $scope.results, res.data.scrolled = !0, $scope.$emit("searchComplete", res.data), _busy = !1, usSpinnerService.stop("scroll-spinner")
})
}, function(res) {
_handleSearchError(res)
})
}
function _windowScroll() {
if (inView.clear(), inView.notify(), $location.path().indexOf("/search") !== -1) {
var windowEl = angular.element($window);
windowEl.scrollTop() + windowEl.height() >= $document.height() - 200 && _busy === !1 && !$scope.eof && (usSpinnerService.spin("scroll-spinner"), _loadNextChunk($scope)), searchScroll.setPosition(windowEl.scrollTop()), inView.check(), inView.notify(), $scope.$apply()
}
}
var _busy = !0,
_initializing = !0,
_page = 1,
_params = $location.search(),
_searching = !1,
_bannerAdjusted = !1;
$scope.showPan = !0, _init(), authService.addObserver(_reloadResults), $scope.$on("doSearch", function(e, options) {
(!_initializing || options && options.force) && (searchScroll.setPosition(0), _params = $location.search(), angular.isDefined(_params.sort) && (searchService.setSortField(_params.sort), angular.isDefined(_params.sortdir) ? searchService.setSort(_params.sortdir) : searchService.setSort("desc")), _page = 1, _doSearch())
}), $scope.$on("filterChanged", function(event, args) {
if (searchViewService.setViewChanged(!1), $scope.resetTable = !1, !(args && args.refresh === !1 || _initializing)) {
searchScroll.setPosition(0), _page = 1, _params = $location.search();
var view = _params.view,
switched = $scope.switchView(view);
switched && "table" !== view ? $timeout(function() {
_doSearch()
}) : switched || $timeout(function() {
_doSearch()
});
var showMap = configService.showMap();
showMap !== $scope.pageFramework.showMap && ($scope.showMap = showMap, _setPageClass())
}
}), $scope.$on("updateBBox", function() {
$location.search("id", null), $location.search("recent", null), $location.search("pg", null), $scope.$emit("filterEvent", {})
}), $scope.$on("updateSearchSaveStatus", function(events, args) {
$location.search("id", args.id)
}), $scope.$watch("sortField", function() {
_initializing || ($location.search("sort", $scope.sortField), searchService.setSortField($scope.sortField), _page = 1, _searching || (searchScroll.setPosition(0), _doSearch()))
}), $scope.hasResults = function() {
return $scope.totalItems && $scope.totalItems > 0
}, $scope.hasPermission = function(permission) {
return authService.hasPermission(permission)
}, $scope.hasOnePermission = function() {
return $scope.canEditPermission() || $scope.flagPermission() || $scope.canCart || $scope.canViewFeed
}, $scope.canEditPermission = function() {
return !hasRemoteShard() && $scope.hasPermission("edit_fields")
}, $scope.flagPermission = function() {
return !hasRemoteShard() && $scope.hasPermission("flag")
}, $scope.exportPermission = function() {
return $scope.hasPermission("export")
}, $scope.addToCart = function(item) {
cartService.addItem(item), $analytics.eventTrack("addToList", {
category: "results",
label: "table",
id: item.id,
user: authService.getUser().id
})
}, $scope.addAllToCart = function() {
$scope.isCartOpen = !1;
var query = cartItemsQuery.getQueryCriteria($location.search());
query.count = $scope.totalItems, cartService.replace(query), $scope.$emit("addAllToCartEvent", {})
}, $scope.flagAllResults = function() {
var modal = searchModalService.flagModal("src/bulk-update/flag-all.html", "FlagAllCtrl", $scope.totalItems);
modal.result.then(function() {
_doSearch()
})
}, $scope.removeAllFlags = function() {
var modal = searchModalService.flagModal("src/bulk-update/remove-flag-all.html", "RemoveAllFlagsCtrl", $scope.totalItems);
modal.result.then(function() {
_doSearch()
})
}, $scope.editAllPresentation = function() {
var modal = searchModalService.editAllPresentation($scope.totalItems);
modal.result.then(function() {
_doSearch()
})
}, $scope.exportResultsList = function() {
searchModalService.exportResultsList($scope)
}, $scope.openFeed = function(type) {
var params = filterService.getFilterParams().replace("&", "?"),
path = "rss" === type ? "feed/voyager.rss" : "feed/atom.xml";
$window.open(config.root + path + params, "_blank")
}, $scope.hideResultErrorMessage = function($event) {
$event.preventDefault(), $scope.resultError = !1, _setPageClass()
}, $scope.showResultErrorTrace = function() {
searchModalService.showResultErrorTrace($scope.resultStackTrace)
}, $scope.removeFromCart = function(id) {
cartService.remove(id), $analytics.eventTrack("removeFromList", {
category: "results",
label: "table",
id: id,
user: authService.getUser().id
})
}, $scope.inCart = function(doc) {
return cartService.isInCart(doc.id)
}, $scope.toggleSave = function() {
savedSearchService.showSaveSearchDialog(_params)
}, $scope.toggleFilter = function() {
$scope.filterVisible = !$scope.filterVisible, $scope.filterVisible ? (urlUtil.updateParam("filter", "true", "true"), $location.search("filter", "true")) : ($location.search("filter", null), urlUtil.removeParam("filter", "true")), _setPageClass()
}, $scope.getLastQuery = function() {
var solrQuery = searchService.getLastQuery();
return solrQuery
}, $scope.getAnalyticsUrl = function() {
var q = $location.search().q,
fq = $location.search().fq,
place = $location.search().place,
placeOp = $location.search()["place.op"],
url = config.root + "analytics/chart/create";
return angular.isDefined(q) && (url += ";q=" + encodeURIComponent(q)), angular.isDefined(fq) && (_.isArray(fq) || (fq = [fq]), url += ";fq=" + encodeURIComponent(encodeURIComponent(fq.join()))), angular.isDefined(place) && (url += ";place=" + encodeURIComponent(place) + ";place.op=" + placeOp), url
}, $scope.hideSearchError = function($event) {
$event.preventDefault(), $scope.searchError = !1, _setPageClass()
}, $scope.changeSortDirection = function(direction) {
if (searchService.getSort() !== direction && !_initializing) {
searchScroll.setPosition(0);
var currentSort = $location.search().sort;
if (angular.isDefined(currentSort) && currentSort.indexOf(" ") !== -1) {
var sortInfo = currentSort.split(" ");
sortInfo[1] = direction, $location.search("sort", sortInfo.join(" "))
} else $location.search("sortdir", direction);
searchService.setSort(direction), _page = 1, _doSearch()
}
}, $scope.changeSort = function(field) {
searchScroll.setPosition(0), $scope.displaySortField = field.value, $scope.sortField = field.key
}, $scope.checkDownload = function($event, doc) {
doc.hasDownload || $event.preventDefault()
}, $scope.switchView = function(view) {
return $scope.view !== view && (searchScroll.setPosition(0), _setView(view), !0)
}, $scope.addToMap = function(doc) {
doc.isopen = !1, doc.isService && ($scope.mapInfo = doc, $scope.$broadcast("addToMap", doc))
}, $scope.showOnMap = function(doc) {
if (doc.isopen = !1, doc.isService) {
$scope.mapInfo = doc;
var webMapSettings = {
webMap: config.mapApp,
urls: [doc.fullpath],
back: $location.absUrl()
};
localStorageService.add("web-map-settings", webMapSettings), $window.location.href = "map.html"
}
}, $scope.toggleMap = function() {
var newSetting = searchViewService.changeMapSize($scope.mapSize);
$scope.bigMap = newSetting.bigMap, $scope.mapClass = newSetting.mapClass, $scope.mapSize = newSetting.mapSize
}, $scope.$on("changeView", function(event, args) {
if (!_initializing) {
_params = $location.search(), searchService.setSortField(_params.sort), searchService.setSort(_params.sortdir), searchScroll.setPosition(0);
var doSearch = args && args.search === !0;
_setView(_params.view, doSearch)
}
}), $scope.$watch("view", function() {
_params = $location.search(), _setView(_params.view, _initializing)
}), $scope.switchMap = function(size) {
$scope.tableViewMapSize !== size && ($scope.tableViewMapSize = size, $location.search("mapsize", size))
}, $scope.$on("mapSizeChanged", function(event, size) {
$scope.switchMap(size)
}), $scope.clearSearch = function() {
filterService.clear(), searchService.reset(), $location.search(""), _page = 1, _doSearch()
}, $scope.$on("clearSearch", function() {
$scope.resetTable = !0, searchService.reset()
}), angular.element($window).bind("scroll", _windowScroll), $scope.$on("$destroy", function() {
angular.element($window).unbind("scroll", _windowScroll), inView.reset(), authService.removeObserver(_reloadResults)
}), $scope.hoverIn = function(doc) {
doc.hoverShow = !0
}, $scope.hoverOut = function(doc) {
doc.hoverShow = !1
}, $scope.applyTag = function(tag) {
tagService.applyTag(tag, $scope, filterService)
}, $scope.updateQueue = function(type) {
extractionService.updateQueue(type)
}
}), angular.module("voyager.search").controller("SearchMapCtrl", function($scope, filterService, $location, localStorageService, searchService, $stateParams, mapUtil, usSpinnerService, $compile, $timeout, dialogs, config, leafletData, $analytics, mapServiceFactory, baseMapService, inView, heatmapService, configService, searchViewService) {
"use strict";
function _setCurrentView(local) {
var point = $scope.map.getCenter(),
vw = point.lng + " " + point.lat + " " + $scope.map.getZoom();
return angular.isUndefined(local) && searchService.setMapView(vw), searchViewService.setUserView({
lat: point.lat,
lng: point.lng,
zoom: $scope.map.getZoom()
}), vw
}
function _compileLayersControl() {
var elem = $(".leaflet-control-layers-overlays");
$compile(elem.contents())($scope);
var mapSizeClass = "table" === $scope.view ? "leaflet-bottom-search" : "";
$(".leaflet-control-layers .leaflet-control-layers-toggle").addClass("icon-map_layers").parents(".leaflet-right").removeClass("leaflet-top").addClass("leaflet-bottom " + mapSizeClass)
}
function _addClickToggleLayersControl(map) {
var LayersControl = L.Control.Layers.extend({
_expand: function() {},
_collapse: function() {}
});
layersControl = new LayersControl(null, null, {
collapsed: !0
}).addTo(map), $timeout(function() {
$(".leaflet-control-layers-toggle").click(function(e) {
$(".leaflet-control-layers").toggleClass("leaflet-control-layers-expanded"), e.preventDefault()
}), $(".leaflet-control-layers-list").click(function(e) {
var tagClicked = e.target.tagName;
"INPUT" !== tagClicked && "SPAN" !== tagClicked && (e.preventDefault(), $(".leaflet-control-layers").removeClass("leaflet-control-layers-expanded"))
}), $(".leaflet-control-layers-list").mouseleave(function(e) {
e.preventDefault(), $(".leaflet-control-layers").removeClass("leaflet-control-layers-expanded")
})
})
}
function _refreshMap(baselayerType) {
var center = $scope.map.getCenter();
$scope.map.options.crs = baseMapService.getCRSForLayerType(baselayerType), $scope.map.setView(center), $scope.map._resetView($scope.map.getCenter(), $scope.map.getZoom(), !0)
}
function _addToLayerControl(layer, map, mapInfo, permanent) {
addedLayer = !0, layers[mapInfo.mapKey] = layer, null === layersControl && _addClickToggleLayersControl(map);
var template = '<a class="btn btn-xs" style="cursor: pointer;" ng-click="removeLayer(\'' + mapInfo.mapKey + "')\">X</a>";
permanent && (template = ""), _.isEmpty(mapInfo.extra) || (template += " " + mapInfo.extra), layersControl.addOverlay(layer, mapInfo.mapKey + template), $timeout(function() {
_compileLayersControl()
})
}
function _removeSearchBoundary() {
layersControl && (delete layers.Place, layersControl.removeLayer(_searchBoundaryLayer)), $scope.map.removeLayer(_searchBoundaryLayer), _searchBoundaryLayer = null, _.isEmpty(layers) && layersControl ? ($scope.map.removeControl(layersControl), layersControl = null, delete $scope.map.currentBounds) : layersControl && _compileLayersControl(), $scope.map.currentBounds = null
}
function _getDefaultExtent(params) {
var extent = $.extend({}, configService.getDefaultMapView());
return params.vw && (extent = configService.parseMapViewString(params.vw, " ")), extent
}
function _addGeoJson(docs) {
_geoGroup && ($scope.map.removeLayer(_geoGroup), _geoGroup = null);
var boxes = [];
_.each(docs, function(doc) {
angular.isDefined(doc.geo) && boxes.push(mapUtil.getGeoJson(doc.geo))
}), boxes.length > 0 && (_geoGroup = L.featureGroup(boxes), _geoGroup.vgCount = boxes.length, $scope.map.addLayer(_geoGroup))
}
function _moveToDefaultExtent() {
var defaultExtent = _getDefaultExtent($stateParams);
$scope.map.setView([defaultExtent.lat, defaultExtent.lng], defaultExtent.zoom)
}
function _showError(error) {
var message = null;
angular.isDefined(error.details) && (message = error.details[0]), dialogs.error(error.message, message)
}
var _points, _searchBoundary, _searchBoundaryLayer, _resultsBoundary, _heatmapLayer, _geoGroup, _geoHighlightLayer, _docs, _baselayers, loaded = !1,
layersControl = null,
layers = {},
addedLayer = !1,
_cancelledDraw = !1;
$scope.hasMapError = config.hasMapError, $scope.$on("drawingTypeChanged", function(event, args) {
$scope.selectedDrawingType = args
}), $scope.selectedDrawingType = "intersects" === $location.search()["place.op"] ? "Intersects" : "Within", leafletData.getMap("search-map").then(function(map) {
$scope.map = map, map.on("moveend", function() {
_setCurrentView(!0)
})
}), $scope.removeLayer = function(layerName) {
if (null !== layersControl && angular.isDefined(layers[layerName])) {
var layer = layers[layerName];
delete layers[layerName], layersControl.removeLayer(layer), $scope.map.removeLayer(layer), "Place" === layerName && ($location.search("place", null), $location.search("place.op", null), $location.search("place.id", null), $scope.$emit("removeFilterEvent", {
isBbox: !0
})), _.isEmpty(layers) ? ($scope.map.removeControl(layersControl), layersControl = null, delete $scope.map.currentBounds) : _compileLayersControl()
}
}, $scope.$on("clearBbox", function() {
_searchBoundaryLayer && _removeSearchBoundary()
}), $scope.$on("addToMap", function() {
angular.isDefined(layers[$scope.mapInfo.name]) || (usSpinnerService.spin("map-spinner"), $scope.addToMap())
}), inView.setViewObserver(_addGeoJson), $scope.$on("searchResults", function(event, results) {
if (results.scrolled !== !0) {
if (results.placefinder && results.placefinder.match) {
_searchBoundaryLayer && _removeSearchBoundary();
var place = results.placefinder.match;
_searchBoundary = place.extent.join(" "), _searchBoundaryLayer = mapUtil.drawGeoJson($scope.map, place.geo, !0, results.placefinder.search.op, !1), _addToLayerControl(_searchBoundaryLayer, $scope.map, {
mapKey: "Place"
})
} else _searchBoundaryLayer ? (_removeSearchBoundary(), angular.isDefined(results["extent.bbox"]) ? (_resultsBoundary = results["extent.bbox"], mapUtil.fitToBBox($scope.map, _resultsBoundary)) : _moveToDefaultExtent()) : searchViewService.viewChanged() || (angular.isDefined(results["extent.bbox"]) ? (_resultsBoundary = results["extent.bbox"], mapUtil.fitToBBox($scope.map, _resultsBoundary)) : (_searchBoundary = null, _resultsBoundary = null, _moveToDefaultExtent()));
_docs = results.response.docs, _addGeoJson(results.response.docs)
}
}), $scope.addToMap = function() {
addedLayer = !0, $scope.map.invalidateSize(!1);
var mapService = mapServiceFactory.getMapService($scope.mapInfo);
mapService.addToMap($scope.mapInfo, $scope.map).then(function(layer) {
$scope.mapInfo.mapKey = $scope.mapInfo.name.replace(/'/g, ""), layer.isValid !== !1 ? (loaded = !1, layer.on("loading", function() {
loaded === !1 && usSpinnerService.spin("map-spinner")
}), _addToLayerControl(layer, $scope.map, $scope.mapInfo), usSpinnerService.stop("map-spinner"), layer.on("load", function() {
loaded = !0, usSpinnerService.stop("map-spinner")
}), $analytics.eventTrack("addToMap", {
category: "results",
label: $scope.mapInfo.format,
id: $scope.mapInfo.id
})) : (usSpinnerService.stop("map-spinner"), $analytics.eventTrack("addToMap", {
category: "error",
label: $scope.mapInfo.format,
id: $scope.mapInfo.id
}), _showError(layer.error))
}, function(error) {
usSpinnerService.stop("map-spinner"), $analytics.eventTrack("addToMap", {
category: "error",
label: $scope.mapInfo.format,
id: $scope.mapInfo.id
}), _showError(error.error)
})
}, $scope.$watch("map", function(old) {
angular.isUndefined(old) || ($scope.map.on("overlayadd", function(e) {
_compileLayersControl(), e.target.fitBounds(e.layer.bounds)
}), $scope.map.on("layeradd", function() {
addedLayer && (addedLayer = !1, _compileLayersControl())
}), $scope.map.on("draw:drawstart", function() {
_cancelledDraw = !1
}), $scope.map.on("draw:drawstop", function() {
$timeout(function() {
if (!_cancelledDraw) {
_searchBoundaryLayer && _removeSearchBoundary(), $location.search("place", $scope._bbox);
var placeType = $scope.selectedDrawingType.toLowerCase();
$location.search("place.op", placeType);
var vw = _setCurrentView();
$location.search("vw", vw), $scope.$emit("bboxChangeEvent", {
bbox: $scope._bbox,
bboxt: placeType,
vw: vw,
place: $scope._bbox,
"place.op": placeType
})
}
})
}), $scope.map.on("baselayerchange", function(e) {
localStorageService.set(baseMapService.BASELAYER_STORAGE_NAME, e.name), _baselayers && _refreshMap(_baselayers[e.name].type)
}), $scope.$on("cancelledDraw", function() {
_cancelledDraw = !0
}), $scope.map.on("draw:created", function(e) {
_cancelledDraw = !1, "point" === $scope.toolType ? (_points = e.layer.getLatLng(), _searchBoundary = e.layer.getLatLng()) : (_points = e.layer.getLatLngs(), _searchBoundary = e.layer.getBounds().toBBoxString())
}), $scope.$on("resultHover", function(evt, data) {
if (_geoHighlightLayer || (_geoHighlightLayer = L.geoJson(null, {
style: {
color: "#e6e600",
weight: 6,
fill: !0
},
pointToLayer: function(f, ll) {
return L.circleMarker(ll, {
radius: 6,
color: "#e6e600",
fillOpacity: .65
})
}
}).addTo($scope.map)), data.doc && data.doc.geo) try {
_geoHighlightLayer.addData(data.doc.geo)
} catch (err) {
console.log("WARNING: failed adding geojson layer to search map")
} else _geoHighlightLayer.clearLayers()
}), $scope.heatmapOpts = {
opacity: 100 * config.searchMap.heatmapOpacity
}, $scope.$watch("heatmapOpts.opacity", function(newVal) {
angular.isDefined(newVal) && angular.isDefined(_heatmapLayer) && (heatmapService.opacity(newVal / 100), _heatmapLayer.render())
}), $scope.heatmapOpacityClick = function(e) {
e.preventDefault(), e.stopPropagation()
}, heatmapService.fetch("-180,-90,180,90", 1).then(function(hm) {
_.isEmpty(hm.counts_ints2D) || (_heatmapLayer = heatmapService.init($scope.map), _addToLayerControl(_heatmapLayer, $scope.map, {
mapKey: "Heatmap",
extra: '<slider floor="0" ceiling="100" step="1" ng-model="heatmapOpts.opacity" class="heatmap-opacity-control" ng-click="heatmapOpacityClick($event)"></slider>'
}, !0))
}), baseMapService.getBaselayers().then(function(baselayers) {
if (_baselayers = baselayers, null === layersControl && _addClickToggleLayersControl($scope.map), baselayers) {
var defaultBaselayer, defaultBaselayer_Type, selectedBaselayer, selectedBaselayer_Type, selectedBaselayer_Name = localStorageService.get(baseMapService.BASELAYER_STORAGE_NAME);
$.each(baselayers, function(index, layerInfo) {
var layer;
switch (layerInfo.options.crs = baseMapService.getCRSForLayerType(layerInfo.type), layerInfo.type) {
case "wms":
layer = new L.TileLayer.WMS(layerInfo.url, layerInfo.options);
break;
default:
layerInfo.cached ? layer = new L.TileLayer(layerInfo.url) : (layerInfo.options.url = layerInfo.url, layer = L.esri.dynamicMapLayer(layerInfo.options))
}
layersControl.addBaseLayer(layer, layerInfo.name), layerInfo.name === selectedBaselayer_Name && (selectedBaselayer = layer, selectedBaselayer_Type = layerInfo.type), layerInfo.default && (defaultBaselayer = layer, defaultBaselayer_Type = layerInfo.type)
}), selectedBaselayer ? (selectedBaselayer.addTo($scope.map), _refreshMap(selectedBaselayer_Type)) : defaultBaselayer && (defaultBaselayer.addTo($scope.map), _refreshMap(defaultBaselayer_Type))
}
$timeout(function() {
_compileLayersControl()
})
}))
}), $scope.$on("filterChanged", function() {
var params = _.pick($location.search(), function(val, key) {
return "q" === key || "fq" === key || 0 === key.indexOf("place")
});
heatmapService.filter(params)
}), $scope.$on("renderHeatmapStarting", function() {
$(".leaflet-control-layers-list").unbind("mouseleave")
}), $scope.$on("renderHeatmapEnding", function() {
$timeout(function() {
$(".leaflet-control-layers-list").mouseleave(function(e) {
e.preventDefault(), $(".leaflet-control-layers").removeClass("leaflet-control-layers-expanded")
})
}, 300)
})
}), angular.module("voyager.search").directive("vsSearchMap", function($compile, config, mapUtil, baseMapService, $timeout, mapControls, configService, $window, $http, sugar, $rootScope, mapCustomControls, searchViewService) {
"use strict";
function getMapSizeTemplate() {
var mapSizeTemplate = '<div ng-show="view == \'table\'" class="leaflet-control-map-size-toggle leaflet-bar leaflet-control">';
return mapSizeTemplate += '<div class="map-size-drop-down">', mapSizeTemplate += '<div class="icon-arrow flyout-trigger" ng-click="toggleMapSizeDropDown()"><span class="icon-search_map"></span></div>', mapSizeTemplate += '<div class="flyout"><div class="arrow"></div><div class="flyout_inner">', mapSizeTemplate += '<ul><li><a href="javascript:;" ng-click="switchMap(\'large\')">Large map</a></li>', mapSizeTemplate += '<li><a href="javascript:;" ng-click="switchMap(\'small\')">Small map</a></li>', mapSizeTemplate += '<li><a href="javascript:;" ng-click="switchMap(\'no\')">No map</a></li>', mapSizeTemplate += "</ul></div></div></div></div>"
}
function getExtent(params) {
var extent = $.extend({}, configService.getDefaultMapView());
return params.vw && (extent = configService.parseMapViewString(params.vw, " ")), extent
}
function toggleMapMode($element, $scope, leafletData) {
"detail_format" === $scope.displayFormat ? leafletData.getMap("search-map").then(function(map) {
map.dragging.disable(), map.doubleClickZoom.disable(), map.scrollWheelZoom.disable(), void 0 !== map.drawRectangle && map.drawRectangle.disable(), $element.addClass("dragging_disabled")
}) : (leafletData.getMap("search-map").then(function(map) {
map.dragging.enable(), map.doubleClickZoom.enable(), map.scrollWheelZoom.disable(), $element.removeClass("dragging_disabled"), $scope.resizeMap(!0)
}), $("#searchByMap").addClass("selected").siblings().removeClass("selected"))
}
return {
compile: function(element, attr) {
return element.append('<leaflet class="search-map" style="height: 100%" center="clientDefault" defaults="defaults" controls="controls" layers="layers" id="search-map" watch-markers="no"></leaflet>'),
function(scope) {
angular.isDefined(attr.zoom) && (scope.clientDefault.zoom = parseInt(attr.zoom))
}
},
controller: function($scope, $element, $attrs, leafletData, $stateParams) {
function _cancelDraw() {
$scope.$emit("cancelledDraw"), $scope._drawing = !1, _cancelledDraw = !0, _drawedShape && _drawedShape.disable()
}
function currentColor() {
return mapUtil.currentColor($scope.selectedDrawingType)
}
function _createShape(color) {
leafletData.getMap("search-map").then(function(map) {
map.vsSearchType = $scope.selectedDrawingType;
var weight = mapUtil.currentWeight($scope.selectedDrawingType);
$timeout(function() {
_drawedShape && _drawedShape.disable(), _drawedShape = "polyline" === $scope.toolType ? new L.Draw.Polyline(map, {
shapeOptions: _shapeOptions(color, weight),
repeatMode: !0,
showArea: !1
}) : "polygon" === $scope.toolType ? new L.Draw.Polygon(map, {
shapeOptions: _shapeOptions(color, weight),
repeatMode: !0,
showArea: !0
}) : "point" === $scope.toolType ? new L.Draw.Marker(map, {
icon: markerIcon,
repeatMode: !1
}) : new L.Draw.Rectangle(map, {
shapeOptions: _shapeOptions(color, weight),
repeatMode: !0,
showArea: !1
}), _drawedShape.enable()
})
})
}
function _shapeOptions(color, weight) {
return {
color: color,
weight: weight,
fillColor: color,
strokeOpacity: .8,
fillOpacity: 0
}
}
function _option(type) {
var color = currentColor(),
weight = mapUtil.currentWeight(type);
return {
color: color,
weight: weight,
"stroke-color": color,
"stoke-opacity": .8,
fill: !1
}
}
function _convertBuffer(geoJSON) {
mapCustomControls.convertBuffer($scope.buffer, geoJSON.geometry).then(function(response) {
geoJSON.geometry = response.data, _bufferBoundaryLayer && _map.removeLayer(_bufferBoundaryLayer), _bufferBoundaryLayer = L.geoJson(geoJSON, {
style: {
color: currentColor(),
weight: 0,
fill: !0,
opacity: .8
}
}).addTo(_map), $scope.search.place = mapUtil.convertToWkt(geoJSON.geometry), $scope.search.displayBBox = mapUtil.formatWktForDisplay($scope.search.place), "false" === $attrs.cancel && $rootScope.$broadcast("bboxChangeEvent", {
place: $scope.search.place
})
})
}
function _mapEvents(map) {
map.on("draw:drawstop", function() {
if (_.isEmpty(map.vsSearchType) || void 0 === _searchBoundary || _remove) return void(_remove = !1);
var latLngs, placeType = map.vsSearchType,
pointInx = 0;
angular.isUndefined($scope.search) && ($scope.search = {}), $scope.search["place.op"] = placeType, angular.isDefined(_searchBoundaryLayer) && _removeLayers(), "rectangle" === $scope.toolType ? (latLngs = _searchBoundary.layer.getLatLngs(), _searchBoundaryLayer = L.rectangle(_searchBoundary.layer.getBounds(), _option(placeType)), pointInx = 2, $scope._bbox = _searchBoundary.layer.getBounds().toBBoxString().replace(/,/g, " "), $scope.search.displayBBox = sugar.formatBBox($scope._bbox)) : "polyline" === $scope.toolType ? (latLngs = _searchBoundary.layer.getLatLngs(), _searchBoundaryLayer = L.polyline(latLngs, _option(placeType)), pointInx = 1) : "polygon" === $scope.toolType ? (latLngs = _searchBoundary.layer.getLatLngs(), _searchBoundaryLayer = L.polygon(latLngs, _option(placeType))) : "point" === $scope.toolType && (latLngs = _searchBoundary.layer.getLatLng(), _searchBoundaryLayer = L.marker(latLngs, {
icon: markerIcon
})), "rectangle" !== $scope.toolType && ($scope._bbox = mapUtil.convertToWkt(_searchBoundaryLayer), $scope.search.displayBBox = mapUtil.formatWktForDisplay($scope._bbox)), _searchBoundaryLayer.addTo(map), $scope.search.place = $scope._bbox, _addLayerMarkers(map, pointInx), $scope._drawing = !1
}), map.on("layeradd", function() {
config.map.config.cached || $(".leaflet-image-layer").css("z-index", "-1")
})
}
function _addLayerMarkers(map, pointInx) {
"point" !== $scope.toolType ? (_addEditBufferMarker(map, _searchBoundaryLayer.getLatLngs()[pointInx]), _addClearBoundaryMarker(map, _searchBoundaryLayer.getLatLngs()[pointInx])) : (_addEditBufferMarker(map, _searchBoundaryLayer.getLatLng()), _addClearBoundaryMarker(map, _searchBoundaryLayer.getLatLng()))
}
function _addEditBufferMarker(map, pointPosition) {
if (angular.isDefined(_editMarker) && null !== _editMarker) _editMarker.setLatLng(pointPosition);
else {
var anchor = [0, 0];
"rectangle" === $scope.toolType ? anchor = [-2, 2] : "point" === $scope.toolType && (anchor = [0, 25]);
var editIcon = L.icon({
iconUrl: "assets/img/icon_edit.png",
iconSize: [20, 20],
iconAnchor: anchor,
popupAnchor: [-95, 160]
});
_editMarker = L.marker(pointPosition, {
icon: editIcon,
zIndexOffset: 5e3
}).addTo(map).bindPopup(addBufferOption()), _editMarker.on("click", function() {
_editMarker.openPopup()
})
}
}
function _addClearBoundaryMarker(map, pointPosition) {
if (angular.isDefined(_closeMarker) && null !== _closeMarker) _closeMarker.setLatLng(pointPosition);
else {
if ("false" === $attrs.cancel) return;
var anchor = [-20, 0];
"rectangle" === $scope.toolType ? anchor = [-22, 2] : "point" === $scope.toolType && (anchor = [-20, 25]);
var closeIcon = L.icon({
iconUrl: "assets/img/icon_x.png",
iconSize: [20, 20],
iconAnchor: anchor
});
_closeMarker = L.marker(pointPosition, {
icon: closeIcon,
zIndexOffset: 5e3
}).addTo(map), _closeMarker.on("mousedown", function() {
_removeLayers(), _removeMarkers(), _remove = !0
})
}
}
function _removeLayers() {
angular.isDefined(_searchBoundaryLayer) && (_map.removeLayer(_searchBoundaryLayer), $scope.search.displayBBox = null, $scope.search.place = null, angular.isDefined(_bufferBoundaryLayer) && _map.removeLayer(_bufferBoundaryLayer))
}
function _removeMarkers() {
angular.isDefined(_editMarker) && null !== _editMarker && (_map.removeLayer(_editMarker), _editMarker = null), angular.isDefined(_closeMarker && null !== _closeMarker) && (_map.removeLayer(_closeMarker), _closeMarker = null)
}
function addBufferOption() {
return $compile($(mapCustomControls.getBufferTemplate()))($scope)[0]
}
var _drawedShape, _searchBoundaryLayer, _searchBoundary, _remove, _closeMarker, _editMarker, _bufferBoundaryLayer, _timer, _cancelledDraw = !1,
windowEl = angular.element($window);
$scope._drawing = !1, $scope.toolType = "rectangle", $scope.clientDefault = getExtent($stateParams, config), $scope.defaults = baseMapService.getDefaultConfig(), "false" !== $attrs.basemapvisible ? $scope.layers = baseMapService.getLayers($attrs.origin) : $scope.layers = {}, $scope.controls = {
custom: []
}, mapControls.init($scope, "search-map");
var _unbindResize = function() {
windowEl.unbind("resize", $scope.resizeMap)
};
$scope.$on("removeFilter", function() {
_cancelDraw(), _removeLayers(), _removeMarkers()
}), $scope.$on("clearBboxEvent", function() {
_removeLayers(), _removeMarkers()
});
var zoomIn = $scope.zoomIn;
$scope.zoomIn = function(e) {
_cancelDraw(), zoomIn(e), _unbindResize()
};
var zoomOut = $scope.zoomOut;
$scope.zoomOut = function(e) {
_cancelDraw(), zoomOut(e), _unbindResize()
};
var defaultExtent = $scope.defaultExtent;
$scope.defaultExtent = function(e) {
_cancelDraw(), defaultExtent(e)
}, $scope.toggleDisplayFormat = function(type, event) {
event.preventDefault(), event.stopPropagation(), $scope.selectedMapType !== type && ($scope.selectedMapType = type, $(event.currentTarget).addClass("selected").siblings().removeClass("selected"), $scope.$emit("searchTypeChanged", type), "Map" !== type ? _cancelDraw() : $scope.selectDrawingTool(event, $scope.toolType))
};
var searchControls = L.control();
$scope.addDrawingTool = function() {
searchControls.setPosition("topleft"), searchControls.onAdd = function() {
return $compile($(mapCustomControls.getDrawingToolTemplate()))($scope)[0]
}
}, $scope.addDrawingTool();
var clickTime;
$scope.toggleDrawingOption = function($event) {
return clickTime = new Date, $event.preventDefault(), $event.stopPropagation(), $scope.releaseDrawingOption($event), !1
}, $scope.releaseDrawingOption = function($event) {
var newTime = new Date;
return $event.preventDefault(), $event.stopPropagation(), angular.isDefined(clickTime) || clickTime.getSeconds() !== newTime.getSeconds() ? (_cancelDraw(), $scope.showDrawingTools = !0) : $scope.selectDrawingTool($event, $scope.toolType), !1
}, $scope.toggleDrawingTools = function(show) {
_timer && $timeout.cancel(_timer), show === !1 ? _timer = $timeout(function() {
$scope.showDrawingTools = !1
}, 1e3) : $scope.showDrawingTools = !0
}, $scope.selectDrawingTool = function($event, toolType) {
$event.preventDefault(), $scope.toolType = toolType, $scope.showDrawingTools = !1, $scope._drawing && _cancelDraw(),
$scope._drawing = !0, _createShape(currentColor())
};
var _map, markerIcon = L.icon({
iconUrl: "assets/img/marker-icon.png",
iconSize: [14, 14]
});
leafletData.getMap("search-map").then(function(map) {
_map = map, map.on("draw:created", function(e) {
_searchBoundary = e
}), _mapEvents(map)
}), $scope.bufferMeasures = [{
id: "mi",
text: "Miles"
}, {
id: "km",
text: "Kilometers"
}, {
id: "m",
text: "Meters"
}, {
id: "ft",
text: "Feet"
}, {
id: "deg",
text: "Lat/Lng Degree"
}, {
id: "nmi",
text: "Nautical Miles"
}], $scope.buffer = {
measure: "mi"
}, addBufferOption(), $scope.addBuffer = function() {
isNaN($scope.buffer.distance) || (angular.element(".leaflet-popup-close-button")[0].click(), _convertBuffer(_searchBoundaryLayer.toGeoJSON()))
}, $scope.bufferCancel = function($event) {
$event.preventDefault(), $scope.buffer = {
measure: "mi"
}, angular.element(".leaflet-popup-close-button")[0].click()
};
var mapTypeToggleControls = L.control();
if (mapTypeToggleControls.setPosition("topleft"), mapTypeToggleControls.onAdd = function() {
var template = '<div class="leaflet-map-toggle-section"><div class="leaflet-bar">';
return template += '<a ng-click="toggleDisplayFormat(\'Place\', $event)" id="searchByPlace" class="selected" title="Search by place"><span class="icon-place_search"></span></a>', template += '<a ng-click="toggleDisplayFormat(\'Map\', $event)" id="searchByMap" title="Search by map"><span class="icon-search_map"></span></a>', template += "</div>", template += "</div>", $compile($(template))($scope)[0]
}, "false" !== $attrs.resize) {
$scope.sizeIcon = "glyphicon-resize-full";
var sizeControl = L.control();
sizeControl.setPosition("bottomright"), sizeControl.onAdd = function() {
var template = '<div class="leaflet-bar leaflet-draw-toolbar">';
return template += '<a class="voyager-default-extent" target="_self" ng-click="resize()" title="Resize" style="cursor: pointer"><span class="glyphicon {{sizeIcon}}"></span></a>', template += "</div>", $compile($(template))($scope)[0]
}, $scope.controls.custom.push(sizeControl)
}
$scope.addMapSizeToggleControl = function() {
var mapSizeControl = L.control();
mapSizeControl.setPosition("bottomright"), mapSizeControl.onAdd = function() {
return $compile(getMapSizeTemplate())($scope)[0]
}, $scope.controls.custom.push(mapSizeControl)
}, $attrs.control && $scope.addMapSizeToggleControl(), $scope.displayFormat && $scope.controls.custom.push(mapTypeToggleControls), $scope.controls.custom.push(mapControls.getZoomControls($scope)), $scope.controls.custom.push(searchControls), $element.on("click", function(e) {
angular.isDefined($scope.displayFormat) && $element.hasClass("dragging_disabled") && ($scope.toggleDisplayFormat("Map", e), $scope.$apply())
}), $element.on("keydown", function(e) {
27 === e.keyCode && _cancelDraw()
}), $scope.$watch("displayFormat", function() {
angular.isDefined($scope.displayFormat) && toggleMapMode($element, $scope, leafletData)
}), $scope.$watch("view", function(view) {
_cancelDraw(), leafletData.getMap("search-map").then(function(map) {
"map" === view ? map.options.minZoom = 2 : map.options.minZoom = 1, $timeout(function() {
map.invalidateSize(), angular.isUndefined(map.currentBounds) && angular.isUndefined(searchViewService.getUserView()) && "home" !== $attrs.origin && $scope.resizeMap(), "table" === view ? $(".leaflet-control-layers-toggle").parent().parent().addClass("leaflet-bottom-search") : $(".leaflet-control-layers-toggle").parent().parent().removeClass("leaflet-bottom-search")
}, 200)
})
}), $scope.switchMap = function(size) {
$scope.$emit("mapSizeChanged", size)
}, $scope.toggleMapSizeDropDown = function() {
var dropDownEl = angular.element(".map-size-drop-down");
dropDownEl.hasClass("opened") ? dropDownEl.removeClass("hover_flyout bottom opened") : dropDownEl.addClass("hover_flyout bottom opened")
}, $scope.preventDoubleClick = function(event) {
event.stopPropagation()
}, $scope.cancelDraw = function(event) {
_cancelDraw(), event.preventDefault(), $(".voyager-pan").addClass("selected").parents(".leaflet-control").siblings().find("a").not("#searchByMap").removeClass("selected")
}, $scope.resize = function() {
var zoom = 10;
"glyphicon-resize-full" === $scope.sizeIcon ? ($scope.sizeIcon = "glyphicon-resize-small", zoom = 2) : $scope.sizeIcon = "glyphicon-resize-full", $scope.toggleMap(), leafletData.getMap("search-map").then(function(map) {
$timeout(function() {
map.invalidateSize(), angular.isDefined(map.currentBounds) || map.setZoom(zoom)
}, 200)
})
}, $scope.resizeMap = function(isFull) {
leafletData.getMap("search-map").then(function(map) {
if (map.currentBounds) map.invalidateSize();
else {
var ratio;
$timeout(function() {
ratio = isFull ? (windowEl.innerHeight() - 85) / 256 : $element.outerHeight() / 256;
Math.ceil(ratio - Math.floor(ratio)) + 1;
isFull && $timeout(function() {
map.invalidateSize()
}, 200)
}, 200)
}
})
}, $scope.$on("$destory", function() {
_unbindResize()
})
}
}
}), angular.module("voyager.search").directive("cleanExpand", [function() {
"use strict";
return {
require: "ngModel",
link: function(scope, element, attr, ngModel) {
ngModel.$formatters.push(function(value) {
return value ? value.replace("{!expand}", "") : null
})
}
}
}]).controller("SearchInputCtrl", function($scope, config, $location, searchService, $timeout, filterService, mapUtil, sugar, $uibModal) {
"use strict";
function _init() {
if ("/search" !== $location.path()) return void($scope.showSearch = !1);
$scope.showSearch = !0;
var initParams = $location.search();
if (_.isEmpty(initParams.q) ? $scope.search.q = "" : ($scope.search.q = initParams.q, $scope.useExpandedQueries = $scope.search.q.indexOf("{!expand}") > -1, $scope.$emit("expandedQueryToggle", $scope.useExpandedQueries)), _.isEmpty(initParams.place)) _.isEmpty(initParams.bbox) ? $scope.search.place = "" : _updatePlaceToBbox(initParams);
else {
$scope.search.place = initParams.place, mapUtil.isBbox(initParams.place) && ($scope.search.place = sugar.formatBBox(initParams.place));
var placeType = initParams["place.op"];
angular.isDefined(placeType) ? ($scope.search["place.op"] = placeType.toLowerCase(), $scope.selectedDrawingType = _.classify(placeType)) : angular.isDefined($scope.selectedDrawingType) && ($scope.search["place.op"] = $scope.selectedDrawingType.toLowerCase()), $location.search("place.op", $scope.search["place.op"]), _setBBoxNull()
}
}
function _updatePlaceToBbox(params) {
null === params.place || _.isEmpty(params.place) || ($scope.search.place = null, $location.search("place", params.place), $location.search("place.id", null), $timeout(function() {
mapUtil.isBbox(params.place) ? $scope.search.place = sugar.formatBBox(params.place) : $scope.search.place = params.place, $scope.search["place.op"] = params["place.op"], _.isNull(params.vw) || ($scope.search.vw = params.vw)
}, 1))
}
function _setBBoxNull() {
$scope.search.vw = null
}
function _submitSearch() {
if (placeChanged && ($location.search("place.id", null), $scope.$emit("clearBboxEvent", {})), $scope.search["place.op"] = $scope.selectedDrawingType.toLowerCase(), angular.isDefined($scope.selectedDrawingType) && $location.search("place.op", $scope.selectedDrawingType.toLowerCase()), _.isEmpty($scope.search.place) ? ($scope.search.place = null, $location.search("place.id", null), _setBBoxNull()) : placeChanged && mapUtil.isBbox($scope.search.place) && _setBBoxNull(), _.isEmpty($scope.search.q) && delete $scope.search.q, _.isEmpty($scope.search.q) || ($scope.useExpandedQueries && !_.startsWith($scope.search.q, "{!expand}") ? $scope.search.q = "{!expand}" + $scope.search.q : $scope.useExpandedQueries || ($scope.search.q = $scope.search.q.replace("{!expand}", ""))), !_.isEmpty($scope.search.q) || !_.isEmpty($scope.search.place)) {
var params = $location.search();
delete params.id, delete params.recent, delete params.expanded, params.block = "false", _.extend(params, $scope.search), _.extend(params, {
fq: filterService.getFilterAsLocationParams()
}), $location.search(params), $location.search("expand.exclude", $scope.search["expand.exclude"]), $scope.$emit("filterEvent", {})
}
placeChanged = !1
}
function _locationChange() {
placeChanged = !0
}
function _clearPlace(args) {
delete args.place, delete args["place.id"], delete args["place.iop"], delete args.block
}
function _clearField(field, isPlace) {
var eventArgs = {},
args = $location.search();
isPlace ? (eventArgs.isBbox = mapUtil.isBbox($scope.search.place), eventArgs.isBbox || (eventArgs.isWkt = mapUtil.isWkt($scope.search.place)), $scope.search.place = "", _clearPlace(args), _locationChange()) : (delete args[field], $scope.search[field] = ""), $location.search(args), $scope.$emit("removeFilterEvent", eventArgs)
}
function _clearAllField(event, args) {
var params = $location.search();
_clearPlace(params), $location.search(params), $scope.search = {}, filterService.clear(), args && args.filter === !0 && $scope.$emit("filterEvent", {})
}
var placeChanged = !1;
$scope.search = {}, $scope.submitSearch = _submitSearch, $scope.clearField = _clearField, $scope.locationChange = _locationChange, $scope.showLocation = config.homepage && config.homepage.showPlaceQuery !== !1, $scope.drawingTypes = ["Within", "Intersects"], $scope.selectedDrawingType = "intersects" === $location.search()["place.op"] ? "Intersects" : "Within", $scope.defaultSelected = !1, $scope.expandedSelected = !0, $scope.useExpandedQueries = config.queryExpansion && config.queryExpansion.checkedByDefault, $scope.queryExpansionEnabled = config.queryExpansion && config.queryExpansion.enabled, $scope.placeOpChange = function(type) {
$scope.selectedDrawingType !== type && ($scope.selectedDrawingType = type), $scope.$emit("selectedDrawingTypeChanged", type)
}, $scope.saveLocation = function() {
$uibModal.open({
template: "<vs-save-location-dialog />",
size: "md",
scope: $scope
})
}, $scope.toggleUseExpandedQueries = function() {
$scope.useExpandedQueries = !$scope.useExpandedQueries, $scope.$emit("expandedQueryToggle", $scope.useExpandedQueries)
}, _init(), $scope.$on("$stateChangeSuccess", _init), $scope.$on("updateBBox", function(event, args) {
_updatePlaceToBbox(args)
}), $scope.$on("clearSearch", _clearAllField), $scope.$on("filterChanged", function(args) {
args && args.refresh === !1 || _init()
})
}), angular.module("voyager.search").factory("searchViewService", function() {
var _view, _mapView, _viewChanged = !1;
return {
getPageClass: function(filterVisible, view, showMap, searchError, resultError) {
var viewChanged = !angular.isUndefined(_view) && _view !== view;
viewChanged && (_viewChanged = !0), _view = view;
var isMapFilterVisible = filterVisible && "map" === view,
page = {};
return page.listViewClass = "", showMap ? "card" === view || "list" === view || "grid" === view ? (page.mapContentClass = "col-lg-8 col-md-8 col-sm-8 col-xs-6 col-lg-push-4 col-md-push-4 col-sm-push-4 col-xs-push-6 no_float", page.headerClass = "col-lg-8 col-md-8 col-sm-12 col-xs-12", page.filterVisible ? page.mapWrapperClass = "map_fixed col-lg-4 col-md-4 col-sm-4 col-xs-6 filter_opened" : page.mapWrapperClass = "map_fixed col-lg-4 col-md-4 col-sm-4 col-xs-6") : "table" === view ? (page.mapContentClass = "col-lg-12 col-md-12 col-sm-12 col-xs-12 no_float", page.headerClass = "col-lg-12 col-md-12 col-sm-12 col-xs-12", filterVisible ? page.mapWrapperClass = "map_fixed tab_center filter_opened" : page.mapWrapperClass = "map_fixed tab_center col-lg-12 col-md-12 col-sm-12 col-xs-12") : isMapFilterVisible ? (page.mapWrapperClass = "map_fixed col-lg-6 col-md-6 col-sm-5 col-xs-5 filter_opened", page.mapContentClass = "map_view_content col-lg-6 col-md-6 col-sm-7 col-xs-7 col-lg-push-6 col-md-push-6 col-sm-push-5 col-xs-push-5", page.headerClass = "col-lg-6 col-md-6 col-sm-12 col-xs-12") : (page.mapWrapperClass = "map_fixed col-lg-8 col-md-8 col-sm-6 col-xs-6", page.mapContentClass = "map_view_content col-lg-4 col-md-4 col-sm-6 col-xs-6 col-lg-push-8 col-md-push-8 col-sm-push-6 col-xs-push-6", page.headerClass = "col-lg-4 col-md-4 col-sm-12 col-xs-12", page.listViewClass = "alt_list_view") : (page.mapWrapperClass = "tab_center", page.mapContentClass = "col-lg-12 col-md-12 no_float", page.headerClass = "col-lg-12 col-md-12 col-sm-12 col-xs-12 no_float"), (searchError || resultError) && (page.mapContentClass += " extra_height"), page
},
changeMapSize: function(mapSize) {
return "small-map" === mapSize ? {
bigMap: !0,
mapClass: "col-sm-12",
mapSize: "big-map"
} : {
bigMap: !1,
mapClass: "col-md-4 col-sm-5 col-lg-3 col-xs-5",
mapSize: "small-map"
}
},
viewChanged: function() {
return _viewChanged
},
setViewChanged: function(viewChanged) {
_viewChanged = viewChanged, viewChanged === !1 && (_mapView = void 0)
},
setUserView: function(mapView) {
_mapView = mapView
},
getUserView: function() {
return _mapView
}
}
}), angular.module("voyager.search").factory("searchModalService", function($uibModal) {
"use strict";
return {
exportResultsList: function(scope) {
$uibModal.open({
template: "<div><vs-export-results /></div>",
size: "md",
scope: scope
})
},
showResultErrorTrace: function(resultStackTrace) {
$uibModal.open({
templateUrl: "src/results/result-error.html",
controller: "ResultErrorCtrl",
size: "lg",
resolve: {
resultStackTrace: function() {
return resultStackTrace
}
}
})
},
flagModal: function(templateUrl, controller, totalItems) {
return $uibModal.open({
templateUrl: templateUrl,
controller: controller,
resolve: {
resultData: function() {
return {
totalItemCount: totalItems
}
}
}
})
},
editAllPresentation: function(totalItems) {
return $uibModal.open({
templateUrl: "src/bulk-update/edit-all.html",
controller: "EditAllCtrl",
size: "lg",
resolve: {
resultTotalCount: function() {
return totalItems
}
}
})
}
}
}), angular.module("voyager.search").factory("extractionService", function(config, $http, $location, converter, vsModalService, toastr) {
function _getArgs() {
var params = _.clone($location.search()),
args = {
q: params.q || "*:*",
fq: []
};
return angular.isDefined(params.fq) && (_.isArray(params.fq) ? args.fq = params.fq : args.fq.push(params.fq)), angular.isDefined(params.place) && args.fq.push(converter.toPlaceFilter(params)), args
}
var service = config.root + "api/rest/discovery/extraction";
return {
updateQueue: function(type) {
var message, args = _getArgs();
return "add" === type ? $http.post(service, {}, {
params: args
}).then(function() {
toastr.success("The current query set has been added to the Extraction Queue for re-indexing.")
}) : void("replace" === type ? (message = "The records in this query will replace items in the indexing queue. Are you sure you want to proceed?", vsModalService.showModal("Extraction Queue Replace", message, "Yes", "No").then(function(proceed) {
if (proceed) return $http.put(service, {}, {
params: args
}).then(function() {
var statusLink = config.root + "manage/#/discovery/status/";
message = "The Extraction Queue has been updated and these records are being re-indexed. </br></br>", message += 'Please visit the <a class="status-link" target="_blank" href="' + statusLink + '">Status</a> page in the Management controls to monitor indexing.', toastr.success(message, {
timeOut: 6e3,
extendedTimeOut: 1e3
})
})
})) : "remove" === type && (message = "The records in this query will be removed from the Extraction Queue for reindexing. Are you sure you want to proceed?", vsModalService.showModal("Extraction Queue Replace", message, "Yes", "No").then(function(proceed) {
if (proceed) return $http.delete(service, {
params: args
}).then(function() {
message = "The records were removed from the Extraction Queue.", toastr.success(message)
})
})))
}
}
}), angular.module("voyager.search").factory("exportService", function($http, config, sugar, filterService, configService, solrGrunt) {
"use strict";
function _setParams(params) {
if (angular.isUndefined(_sortField) && (_sortField = _defaultSortField), angular.isDefined(params.sort))
if (params.sort.indexOf(" ") !== -1) {
var sortInfo = params.sort.split(" ");
_sortField = sortInfo[0], _sortDirection = sortInfo[1]
} else _sortField = params.sort;
angular.isDefined(params.sortdir) && (_sortDirection = params.sortdir), _searchParams = solrGrunt.getSolrParams(params)
}
function buildQueryForCSV(solrParams, itemsPerPage, sortDirection, sortField) {
delete solrParams.fq;
var queryString = config.root + selectPath;
queryString += "?" + sugar.toQueryString(solrParams), queryString += "&start=0", queryString += "&fl=id";
var tableFieldNames = configService.getTableFieldNames();
return tableFieldNames.length && (queryString += "," + tableFieldNames.join(","), queryString += ",absolute_path:[absolute]"), queryString += "&rows=" + itemsPerPage, queryString += "&extent.bbox=true&block=false", queryString += filterService.getFilterParams(), angular.isDefined(configService.getConfigId()) && angular.isUndefined(solrParams["voyager.config.id"]) && (queryString += "&voyager.config.id=" + configService.getConfigId()), angular.isDefined(sortField) && (angular.isUndefined(sortDirection) && (sortDirection = angular.isDefined(config.defaultSortDirection) ? config.defaultSortDirection : "desc"), queryString += "&sort=" + sortField + " " + sortDirection), queryString += "&rand=" + Math.random(), queryString += "&wt=csv"
}
var _searchParams, _sortDirection, selectPath = "solr/v0/select",
_defaultSortField = angular.isDefined(config.defaultSort) ? config.defaultSort : "score",
_sortField = "score";
return {
getCSV: function(params, rowCount) {
_setParams(params);
var service = buildQueryForCSV(_searchParams, rowCount, _sortDirection, _sortField);
return $http.get(service).then(function(response) {
return response
}, function(exception) {
return exception
})
}
}
}), angular.module("voyager.search").directive("vsExportResults", function(usSpinnerService, searchService, $location, exportService) {
return {
restrict: "E",
replace: !0,
templateUrl: "src/export-results/export-results.html",
link: function(scope) {
scope.error = !1, scope.hasError = function() {
return scope.error !== !1
}, scope.save = function() {
if (_.isEmpty(scope.CSVFileName)) scope.success = !1, scope.error = "Please enter a file name";
else {
scope.error = !1, usSpinnerService.spin("task-spinner");
var _params = $location.search();
delete _params.recent, scope.getCSVFile(_params, scope.totalItems)
}
}, scope.cancel = function() {
scope.$dismiss()
}, scope.getFileName = function() {
var fileNameParts = scope.CSVFileName.split("."),
fileExt = "";
return "csv" !== fileNameParts.pop().toLowerCase() && (fileExt = ".csv"), scope.CSVFileName + fileExt
}, scope.createAnchorTag = function(data, filename) {
var anchor = angular.element("<a/>");
return navigator.msSaveBlob ? anchor[0].addEventListener("click", function() {
var blob = new Blob([data], {
type: "text/csv;charset=utf-8;"
});
navigator.msSaveBlob(blob, filename)
}, !1) : anchor.attr({
href: "data:attachment/csv;charset=utf-8," + encodeURI(data),
target: "_blank",
download: filename
}), anchor
}, scope.successHandler = function(response, filename) {
if (usSpinnerService.stop("task-spinner"), 200 === response.status && angular.isUndefined(response.error)) {
scope.success = !0;
var anchor = scope.createAnchorTag(response.data, filename)[0];
"function" == typeof anchor.click && anchor.click(), scope.cancel()
} else scope.error = response.error || "Please try again later"
}, scope.errorHandler = function(response) {
usSpinnerService.stop("task-spinner"), scope.error = response.error || "Please try again later"
}, scope.getCSVFile = function(params, rowCount) {
exportService.getCSV(params, rowCount).then(function(response) {
scope.successHandler(response, scope.getFileName())
}, function(response) {
scope.errorHandler(response)
})
}
}
}
}), angular.module("voyager.search").factory("suggestQuery", function($http, config) {
return {
execute: function(name) {
var query = config.root + "solr/v0/select?place=" + name + "&place.suggest=true&block=false&rows=0&wt=json&json.wrf=JSON_CALLBACK&rand=" + Math.random();
return $http.jsonp(query).then(function(res) {
return res.data.placefinder.results
})
}
}
}), angular.module("voyager.search").directive("vsSuggest", function($timeout, suggestQuery, $compile, $q, $location, urlUtil, mapUtil) {
function _check(value) {
return value.length > 3 ? suggestQuery.execute(value) : $q.when([])
}
function _link(scope, element, attrs) {
function _getSuggestions() {
scope.hasRecommendations = !1, _check(element.val()).then(function(suggestions) {
suggestions = _.filter(suggestions, function(s) {
return null !== s.name
}), _.find(suggestions, {
name: element.val()
}) ? scope.hasSuggestions = !1 : (scope.suggestions = suggestions, scope.hasSuggestions = suggestions.length > 0)
})
}
function _handleDownArrow(index) {
index < scope.suggestions.length - 1 && (index > -1 && (scope.suggestions[index].highlighted = !1), scope.suggestions[index + 1].highlighted = !0)
}
function _handleUpArrow(index) {
index > 0 && (scope.suggestions[index].highlighted = !1, scope.suggestions[index - 1].highlighted = !0)
}
var t = '<div ng-show="hasSuggestions" vs-suggest-list class="suggest-container hdpi" style="width:100%"></div>';
element.after($compile(t)(scope));
var _typeTimer, handleKeydown = function(e) {
if (scope.selectedPlace = !1, _placeSearch = !1, scope.hasRecommendations = !1, $timeout.cancel(_typeTimer), 13 === e.which) {
if (scope.suggestions) {
var selectedIndex = _.findIndex(scope.suggestions, function(item) {
return item.highlighted
});
selectedIndex > -1 && scope.select(scope.suggestions[selectedIndex])
}
return scope.suggestions = [], scope.hasSuggestions = !1, scope.selectedPlace = !0, void(_placeSearch = !0)
}
if (40 === e.which || 38 === e.which) {
var arrowFn = 40 === e.which ? _handleDownArrow : _handleUpArrow;
if (scope.suggestions && scope.suggestions.length > 0) {
var index = _.findIndex(scope.suggestions, function(item) {
return item.highlighted
});
return arrowFn(index), void scope.$digest()
}
}
_typeTimer = $timeout(function() {
_getSuggestions()
}, 300)
};
element.on("keydown", handleKeydown);
var handleBlur = function() {
$timeout(function() {
scope.suggestions = [], scope.hasSuggestions = !1, _focused = !1
})
};
element.on("blur", handleBlur);
var handleFocus = function() {
var val = element.val();
_focused || scope.selectedPlace || mapUtil.isBbox(val) || _getSuggestions()
};
element.on("focus", handleFocus), scope.select = function(item) {
scope.selectedPlace = !0, _placeSearch = !0, scope.hasRecommendations = !1, scope.hasSuggestions = !1, element.val(item.name), scope.search && angular.isDefined(scope.search.location) && (scope.search.location = item.name), $location.search("place", item.name), $location.search("place.id", item.id), "off" !== attrs.autosearch && scope.$emit("filterEvent", {})
}, scope.$on("$destroy", function() {
element.off("focus", handleFocus), element.off("blur", handleBlur), element.off("keydown", handleKeydown)
})
}
var _focused = !1,
_placeSearch = !1;
return {
compile: function() {
return _link
},
controller: function($scope, $document) {
var docClickHandler = function() {
$scope.selectedPlace = !0, $scope.hasRecommendations = !1, $scope.hasSuggestions = !1, $scope.$apply(), $document.off("click", docClickHandler)
};
$scope.$on("searchResults", function(event, data) {
var isChosen = $location.search()["place.id"];
if (!angular.isDefined(isChosen)) {
var place = $location.search().place;
if (_placeSearch = angular.isDefined(place) && "" !== place, _placeSearch && data.placefinder && !mapUtil.isBbox(place)) {
if (!_.find(data.placefinder.results, {
name: place
})) {
$scope.hasRecommendations = !0, $scope.suggestions = data.placefinder.results, $scope.hasSuggestions = $scope.suggestions && $scope.suggestions.length > 0;
var matchName = data.placefinder.match.name;
matchName === place && ($scope.hasSuggestions = !1), _.isEmpty(matchName) && (matchName = data.placefinder.search.text), $scope.location = matchName, $location.search("place", $scope.location), urlUtil.updateParam("place", place, $scope.location), $location.search("place.id", data.placefinder.match.id), urlUtil.addParam("place.id", data.placefinder.match.id), $scope.$emit("filterEvent", {
refresh: !1
})
}
} else $scope.hasRecommendations = !1;
$scope.hasRecommendations ? $document.on("click", docClickHandler) : $document.off("click", docClickHandler)
}
}), $scope.$on("$destroy", function() {
$document.off("click", docClickHandler)
})
}
}
}), angular.module("voyager.search").directive("vsSuggestList", function() {
return {
templateUrl: "src/suggest/suggest.html"
}
}), angular.module("voyager.results", ["ngTable", "voyager.tagging"]),
function() {
"use strict";
function actionManager($window, $analytics, $uibModal, authService, sugar, config, $location) {
function _isVisible(action, scope) {
var visible = action.visible;
return visible === !0 || visible === !1 ? visible : visible.indexOf("doc.") > -1 ? scope.$eval(visible) : scope.doc[action.visible]
}
function _toggleDisplay(action, scope) {
scope.doc[action.toggle] === !0 ? (action.display = action.off, action.icon = action.offIcon, scope.isTable && (action.display = action.offList), action.buttonType = "btn-default") : (action.display = action.text, action.icon = action.onIcon, action.buttonType = "btn-primary")
}
function _setAction(action, scope) {
action.visible = _isVisible(action, scope), "add" === action.action ? (action.do = function() {
scope.doc.isopen = !1, scope.toggleCart(scope.doc), _toggleDisplay(action, scope)
}, _toggleDisplay(action, scope)) : "preview" === action.action ? action.do = function() {
$analytics.eventTrack("mapped", {
category: "results",
label: scope.doc.format,
id: scope.doc.id,
user: authService.getUser().id
}), scope.doc.isopen = !1, scope.addToMap(scope.doc), $window.scrollTo(0, 0)
} : "download" === action.action ? action.do = function() {
scope.doc.isopen = !1, $analytics.eventTrack("download", {
category: "results",
label: scope.doc.format,
id: scope.doc.id,
user: authService.getUser().id
}), sugar.canOpen(scope.doc) ? $window.open(scope.doc.download) : authService.getUserInfo().then(function(user) {
$window.location.href = scope.doc.download + sugar.paramDelimiter(scope.doc.download) + "_vgp=" + user.exchangeToken
})
} : "open" === action.action ? action.do = function() {
scope.doc.isopen = !1, $analytics.eventTrack("openWith", {
category: "results",
label: action.url,
id: scope.doc.id,
user: authService.getUser().id
});
var param = "";
action.url.indexOf("?") === -1 && (param = "?url="), action.param && (param = "?" + action.param + "="), $window.open(action.url + param + encodeURIComponent(scope.doc.fullpath))
} : "openArcMap" === action.action ? action.do = function() {
scope.doc.isopen = !1, $analytics.eventTrack("openArcMap", {
category: "results",
label: scope.doc.id,
id: scope.doc.id,
user: authService.getUser().id
}), $window.location.href = scope.doc.layerURL
} : "tag" === action.action && (action.do = function() {
scope.doc.isopen = !1, $analytics.eventTrack("tag", {
category: "results",
label: action.url,
id: scope.doc.id,
user: authService.getUser().id
}), $uibModal.open({
templateUrl: "common/tagging/tagging.html",
size: "md",
controller: "TagDialog",
resolve: {
doc: function() {
return scope.doc
}
}
})
})
}
function _initActions(scope, view) {
var actionMap = {},
defaultAction = null,
displayActions = [],
actions = sugar.copy(config.docActions);
return $.each(actions, function(index, action) {
action.buttonType = "btn-primary", _setAction(action, scope), actionMap[action.action] = action, "preview" === action.action && "/home" === $location.path() && (action.visible = !1), action.display = angular.isDefined(action.display) ? action.display : action.text, action.enabled = !!angular.isUndefined(action.enabled) || action.enabled, action.visible = !!action.enabled && action.visible, action.visible && (null === defaultAction && "table" !== view ? defaultAction = action : displayActions.push(action), "download" === action.action && angular.isDefined(scope.doc.download) && sugar.canOpen(scope.doc) && (action.text = action.alt))
}), displayActions.length > 0 && angular.isDefined(displayActions[0].sort) && (displayActions = _.sortBy(displayActions, "sort")), {
display: displayActions,
defaultAction: defaultAction,
types: actionMap
}
}
return {
setAction: _setAction,
toggleDisplay: _toggleDisplay,
initActions: _initActions
}
}
angular.module("voyager.results").factory("actionManager", actionManager)
}(), angular.module("voyager.results").directive("vgBindHtml", function($compile) {
return function(scope, element, attrs) {
scope.$watch(function(scope) {
return scope.$eval(attrs.vgBindHtml)
}, function(value) {
element.html(value), $compile(element.contents())(scope)
})
}
}).directive("vsCard", function(authService, cartService, config, $window, $analytics, actionManager, sugar, inView, $document, $location, tagService) {
return {
templateUrl: "src/results/card.html",
link: function($scope, $element) {
function _isInView() {
var clientHeight, imageRect, visible = $element.is(":visible"),
isIn = !1;
visible && (clientHeight = $document[0].documentElement.clientHeight, imageRect = $element[0].getBoundingClientRect(), isIn = imageRect.top >= 0 && imageRect.bottom <= clientHeight || imageRect.bottom >= 0 && imageRect.bottom <= clientHeight || imageRect.top >= 0 && imageRect.top <= clientHeight), isIn ? inView.add($scope.doc) : inView.remove($scope.doc)
}
angular.isDefined($scope.doc.geo) && inView.addCheckObserver(_isInView)
},
controller: function($scope, filterService, translateService, $timeout, $location, configService, $filter) {
$scope.imagePrefix = config.root + "meta/", $scope.link = sugar.copy(config.docLink), $scope.cardView = configService.getCardView(), actionManager.setAction($scope.link, $scope), $scope.fields = configService.getCardViewFields(), $scope.names = configService.getCardViewNames(), "preview" === $scope.link.action && "/home" === $location.path() && ($scope.link.visible = !1), $scope.toggleCart = function(doc) {
doc.inCart ? (cartService.remove(doc.id), $scope.cartAction = "Add", $scope.btnType = "btn-primary", doc.inCart = !1, $analytics.eventTrack("removeFromList", {
category: "results",
label: "card",
id: doc.id,
user: authService.getUser().id
})) : (cartService.addItem(doc), $scope.cartAction = "Remove", $scope.btnType = "btn-default", doc.inCart = !0, $analytics.eventTrack("addToList", {
category: "results",
label: "card",
id: doc.id,
user: authService.getUser().id
}))
}, $scope.canCart = function() {
return authService.hasPermission("process")
}, $scope.applyTag = function(tag) {
tagService.applyTag(tag, $scope, filterService)
}, $scope.hover = function(active) {
$scope.$emit("resultHoverEvent", {
doc: active ? $scope.doc : null
})
};
var actions = actionManager.initActions($scope);
$scope.actions = actions.display, $scope.default = actions.defaultAction, $scope.$on("addAllToCart", function() {
$scope.cartAction = "Remove", $scope.btnType = "btn-default", $scope.doc.inCart = !0, actionManager.toggleDisplay(actions.types.add, $scope)
}), $scope.$on("removeAllCart", function() {
$scope.cartAction = "Add", $scope.btnType = "btn-primary", $scope.doc.inCart = !1, actionManager.toggleDisplay(actions.types.add, $scope)
}), $scope.$on("syncCard", function() {
$scope.doc.inCart ? ($scope.cartAction = "Remove", $scope.btnType = "btn-default") : ($scope.cartAction = "Add", $scope.btnType = "btn-primary"), actionManager.toggleDisplay(actions.types.add, $scope)
}), $scope.applyFilter = function(filter, value) {
if ("/search" === $location.path()) {
var facet = {
field: value,
filter: filter,
humanized: translateService.getFieldName(filter) + ":" + value,
name: value,
pretty: translateService.getType(value)
};
filterService.addFilter(facet), $location.search("fq", filterService.getFilterAsLocationParams()), $timeout(function() {
$scope.$emit("filterEvent", {})
})
} else {
var searchPage = config.root + "navigo/search?fq=" + filter + ":" + encodeURIComponent(value) + "&disp=" + $location.search().disp;
$window.location.href = searchPage
}
}, $scope.getNameToUse = function(doc, names) {
var selectedName = null;
return $.each(names, function(idx, name) {
selectedName || _.isEmpty(doc[name.field]) || (selectedName = name)
}), selectedName ? selectedName.field : null
}, $scope.formatField = function(doc, facet) {
var formatted = "",
value = doc[facet.field];
return angular.isDefined(value) && (formatted = "format" === facet.field ? translateService.getTypeAbbr(value) : "modified" === facet.field ? $filter("date")(Date.parse(value), "M/d/yyyy, hh:mma") : "bytes" === facet.field ? value > 0 ? $filter("bytes")(value) : "0 bytes" : sugar.isDate(value) ? $filter("date")(Date.parse(value), "M/d/yyyy, hh:mma") : value), formatted
}
}
}
}), angular.module("voyager.results").directive("vsCardRecent", function() {
return {
strict: "A",
templateUrl: "src/results/card-recent.html"
}
}), angular.module("voyager.results").directive("vsTableRow", function(inView, $document, sugar, actionManager, config, $location, tagService) {
return {
link: function($scope, $element) {
function _isInView() {
var clientHeight, imageRect, visible = $element.is(":visible"),
isIn = !1;
visible && (clientHeight = $document[0].documentElement.clientHeight, imageRect = $element.children()[0].getBoundingClientRect(), isIn = imageRect.top >= 0 && imageRect.bottom <= clientHeight || imageRect.bottom >= 0 && imageRect.bottom <= clientHeight || imageRect.top >= 0 && imageRect.top <= clientHeight), isIn ? inView.add($scope.doc) : inView.remove($scope.doc)
}
angular.isDefined($scope.doc.geo) && inView.addCheckObserver(_isInView)
},
controller: function($scope, filterService, translateService, $timeout, $location, $analytics, authService, cartService) {
$scope.link = sugar.copy(config.docLink), actionManager.setAction($scope.link, $scope), $scope.toggleCart = function(doc) {
var action = _.find($scope.actions, {
action: "add"
});
doc.inCart ? (cartService.remove(doc.id), $scope.cartAction = "Add", $scope.btnType = "btn-primary", doc.inCart = !1, $analytics.eventTrack("removeFromList", {
category: "results",
label: "card",
id: doc.id,
user: authService.getUser().id
}), action.display = action.text) : (cartService.addItem(doc), $scope.cartAction = "Remove", $scope.btnType = "btn-default", doc.inCart = !0, $analytics.eventTrack("addToList", {
category: "results",
label: "card",
id: doc.id,
user: authService.getUser().id
}), action.onList = action.display, action.display = action.offList)
}, $scope.applyTag = function(tag) {
tagService.applyTag(tag, $scope, filterService)
}, $scope.hover = function(active) {
$scope.$emit("resultHoverEvent", {
doc: active ? $scope.doc : null
})
};
var actions = actionManager.initActions($scope, "table");
$scope.actions = actions.display, $scope.default = actions.defaultAction, $scope.$on("addAllToCart", function() {
$scope.cartAction = "Remove", $scope.btnType = "btn-default", $scope.doc.inCart = !0,
actionManager.toggleDisplay(actions.types.add, $scope)
}), $scope.$on("removeAllCart", function() {
$scope.cartAction = "Add", $scope.btnType = "btn-primary", $scope.doc.inCart = !1, actionManager.toggleDisplay(actions.types.add, $scope)
}), $scope.$on("syncCard", function() {
$scope.doc.inCart ? ($scope.cartAction = "Remove", $scope.btnType = "btn-default") : ($scope.cartAction = "Add", $scope.btnType = "btn-primary"), $scope.isTable = !0, actionManager.toggleDisplay(actions.types.add, $scope)
})
}
}
}), angular.module("voyager.results").factory("tableResultsService", function($window) {
return {
setFixedWidths: function() {
var windowWidth = angular.element($window).width(),
imgCol = $("th.semi.img"),
imageWidth = 100 / windowWidth * 100;
imgCol.css("width", imageWidth + "%");
var toolsCol = $("#resultsTable").find("th").last(),
toolsWidth = 85 / windowWidth * 100;
toolsCol.css("width", toolsWidth + "%")
},
forceWidths: function() {
var $header, width, toWidth, $tableHeaders = angular.element(".ng-table").find("th");
_.each($tableHeaders, function(header) {
$header = angular.element(header), width = $header.css("width"), toWidth = $header.data("width"), angular.isDefined(toWidth) && width !== toWidth && $header.css("width", toWidth)
})
}
}
}), angular.module("voyager.results").controller("TableCtrl", function($scope, ngTableParams, $timeout, $location, configService, translateService, $filter, filterService, config, sugar, tableResultsService) {
"use strict";
function _setDefaultColumnWidths() {
var defaultWidth = 88 / vm.tableFields.length,
width = 0,
totalWidth = 0;
$.each(vm.tableFields, function(index, field) {
angular.isUndefined(field.width) ? field.width = "" + defaultWidth + "%" : field.width.indexOf("%") === -1 && (field.width = field.width + "%"), width = field.width.replace("%", ""), width = Number(parseFloat(width).toFixed(2)), totalWidth += width
})
}
function _getSort(sortParam) {
var name;
for (name in sortParam)
if (sortParam.hasOwnProperty(name)) return {
sort: name,
direction: sortParam[name]
}
}
var deferred, vm = this,
loaded = !1,
reloading = !1,
lastSort = {};
vm.getTableWidth = function() {
var table = angular.element(document.getElementById("resultsTable"))[0];
return table.clientWidth
};
var addAction = _.find(config.docActions, {
action: "add"
});
$scope.addActionText = "Add to Queue", addAction && ($scope.addActionText = addAction.text);
var Store = function() {
return {
set: function(field, value) {
var fieldName = field.split("-")[1];
configService.updateColumnWidth(fieldName, value)
},
get: function(field) {
var fieldName = field.split("-")[1];
return configService.getColumnWidth(fieldName)
}
}
}();
window.store = Store, vm.tableFields = configService.getTableFields(), vm.textWrappingNotAllowed = !configService.getAllowsTextWrappingOnTableView(), _setDefaultColumnWidths(), $scope.hideThumbnails = !configService.getShowThumbnailOnTableView(), $scope.hideFlags = !configService.getShowFlagOnTableView(), $scope.toggleThumbnails = function() {
$scope.hideThumbnails = !$scope.hideThumbnails
}, $scope.applyFlag = function(flag) {
filterService.clear();
var params = $location.search();
return delete params.q, delete params.place, delete params.recent, params.fq = "tag_flags" + flag, $location.search(params), filterService.setFilters({
fq: "tag_flags:" + flag
}), $scope.$emit("filterEvent"), !1
}, $scope.$on("searchResults", function(event, data) {
vm.tableLoading = !1, vm.tableFields = configService.getTableFields(), _setDefaultColumnWidths();
var docs = data.response.docs;
loaded ? (reloading = !0, $scope.tableParams.reload(), deferred.resolve(docs), reloading = !1) : (loaded = !0, deferred.resolve(docs)), $timeout(function() {
tableResultsService.setFixedWidths(), tableResultsService.forceWidths()
}), $timeout(function() {
$(window).trigger("resize")
}, 200)
}), $scope.$on("changeView", function() {
var view = $location.search().view;
"table" === view && ($scope.$emit("doSearch", {}), vm.tableLoading = !0)
}), $scope.$on("$destroy", function() {
configService.resetColumns()
});
var tableParams = {
count: 10,
filter: {},
sorting: {}
};
$scope.tableParams = new ngTableParams(tableParams, {
counts: [],
total: 0,
getData: function($defer, params) {
deferred = $defer;
var isSort = !angular.equals(lastSort, params.sorting());
if (!isSort || loaded && !reloading) {
if (isSort) {
lastSort = params.sorting();
var sort = _getSort(params.sorting());
$location.search("sort", sort.sort), $location.search("sortdir", sort.direction), $scope.$emit("doSearch", sort)
} else loaded || ($scope.$emit("doSearch", {
force: !0
}), vm.tableLoading = !0);
if (!isSort) {
var sortField = $location.search().sort,
sortDir = $location.search().sortdir;
if (angular.isDefined(sortField)) {
var sortParam = {};
sortParam[sortField] = sortDir, params.sorting(sortParam)
}
}
}
}
}), $scope.formatField = function(doc, facet) {
var formatted = "",
value = doc[facet.field];
return angular.isDefined(value) && (formatted = "format" === facet.field ? translateService.getTypeAbbr(value) : "modified" === facet.field ? $filter("date")(Date.parse(value), "M/d/yyyy, hh:mma") : "bytes" === facet.field ? value > 0 ? $filter("bytes")(value) : "0 bytes" : sugar.isDate(value) ? $filter("date")(Date.parse(value), "M/d/yyyy, hh:mma") : value), formatted
}, vm.hover = function(doc) {
$scope.$emit("resultHoverEvent", {
doc: doc
})
}, $scope.setDefer = function(defer) {
deferred = defer
}
}), angular.module("voyager.results").factory("inView", function() {
function _check() {
_.each(_checkObservers, function(observer) {
observer()
})
}
var _inView = {},
_checkObservers = [],
_viewObserver = function() {};
return {
add: function(doc) {
_inView[doc.id] = doc
},
remove: function(doc) {
delete _inView[doc.id]
},
addCheckObserver: function(observer) {
_checkObservers.push(observer)
},
reset: function() {
_inView = {}, _checkObservers = []
},
clear: function() {
_inView = {}
},
check: function() {
_check()
},
getAll: _inView,
setViewObserver: function(observer) {
_viewObserver = observer
},
notify: function() {
_viewObserver(_inView)
}
}
}), angular.module("voyager.results").controller("ResultErrorCtrl", function($scope, $uibModalInstance, resultStackTrace) {
"use strict";
$scope.resultStackTrace = JSON.stringify(resultStackTrace), $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}
}), angular.module("voyager.details", ["leaflet-directive", "cart", "voyager.search", "voyager.util", "voyager.security", "dialogs.main", "voyager.map", "ui.router", "angularSpinner"]),
function() {
"use strict";
function detailsActions($window, $analytics, config, sugar, authService) {
function _isVisible(action, doc, $scope) {
var visible = action.visible;
return action.enabled = !!angular.isUndefined(action.enabled) || action.enabled, visible = !!action.enabled && visible, visible === !0 || visible === !1 ? visible : (visible = visible.indexOf("doc.") > -1 ? $scope.$eval(visible) && "preview" !== action.action && "tag" !== action.action : doc[action.visible] && "preview" !== action.action && "tag" !== action.action, !!action.enabled && visible)
}
function _setAction(action, doc, $scope) {
action.visible = _isVisible(action, doc, $scope), doc.isopen = !1, "download" === action.action ? (angular.isDefined(doc.download) && sugar.canOpen(doc) && (action.text = action.alt), action.do = function() {
$analytics.eventTrack("download", {
category: "results",
label: doc.format,
id: doc.id,
user: authService.getUser().id
}), sugar.canOpen(doc) ? $window.open(doc.download) : authService.getUserInfo().then(function(user) {
$window.location.href = doc.download + sugar.paramDelimiter(doc.download) + "_vgp=" + user.exchangeToken
})
}) : "open" === action.action ? action.do = function() {
$analytics.eventTrack("openWith", {
category: "results",
label: action.url,
id: doc.id,
user: authService.getUser().id
});
var param = "";
action.url.indexOf("?") === -1 && (param = "?url="), action.param && (param = "?" + action.param + "="), $window.open(action.url + param + encodeURIComponent(doc.fullpath))
} : "openArcMap" === action.action && (action.do = function() {
$analytics.eventTrack("openArcMap", {
category: "results",
label: doc.id,
id: doc.id,
user: authService.getUser().id
}), $window.location.href = doc.layerURL
})
}
function _getActions(doc, $scope) {
var actions = _.cloneDeep(config.docActions);
return _.each(actions, function(action) {
_setAction(action, doc, $scope), action.display = angular.isDefined(action.display) ? action.display : action.text
}), actions
}
return {
setAction: _setAction,
getActions: _getActions
}
}
angular.module("voyager.details").factory("detailsActions", detailsActions)
}(), angular.module("voyager.details").factory("detailService", function($http, config, $q, resultsDecorator, solrUtil, catalogService, authService) {
"use strict";
function _buildTreeRequest(id, shard) {
var service = config.root + "solr/v0/select?fq=id:" + id,
fields = "&fl=tree, format, id",
shards = "";
return _.isEmpty(shard) || (shards = "&shards.info=true&shards.tolerant=true&shards=" + shard), service + fields + shards + _type + "&r=" + Math.random()
}
function _buildRelationshipRequest(id, shard, type, direction, displayFields) {
var service = config.root + "api/rest/index/links/" + id + "?dir=" + direction + "&rel=" + type,
fields = "&fl=id,name:[name],fullpath:[absolute],content:[contentURL],thumb:[thumbURL],preview:[previewURL],download:[downloadURL],bbox, format, hasMetadata, root, tree, tag_tags, links, hasMissingData, shard:[shard]";
_.isArray(displayFields) ? fields += "," + displayFields.join(",") : "string" == typeof displayFields && (fields += "," + displayFields);
var shards = "";
return _.isEmpty(shard) || (shards = "&shards=" + shard), service + fields + shards + "&r=" + Math.random()
}
function _fetchTranslation() {
return _.isEmpty(_translation) ? $http.get(config.root + "api/rest/i18n/links?block=false").then(function(res) {
return _translation = res.data
}) : $q.when(_translation)
}
function _fetchTypes(direction) {
return _fetchTranslation().then(function(types) {
return types[direction]
})
}
function _fetchRelationship(id, shard, type, direction, fields) {
var deferred = $q.defer(),
request = _buildRelationshipRequest(id, shard, type, direction, fields);
return $http.get(request).then(function(res) {
var docs = res.data.docs;
angular.isDefined(docs) && docs.length > 0 ? deferred.resolve(res.data) : deferred.reject(id + " not found")
}), deferred.promise
}
function _fetchLink(relationship, id, shard, type, direction, fields) {
return _fetchRelationship(id, shard, type, direction, fields).then(function(response) {
var docs = response.docs;
return resultsDecorator.decorate(docs, []), resultsDecorator.decorateRelationships(docs, fields), relationship.numFound += response.numFound, $.merge(relationship.values, docs), relationship
}, function() {
return relationship
})
}
function _getRelationship(relationships, name, type) {
var relationship = relationships[type];
return relationship || (relationship = {
name: name,
type: type,
values: [],
numFound: 0
}, relationships[type] = relationship), relationship
}
function _getTokenParam(shard) {
return angular.isDefined(shard) ? authService.getUserInfo().then(function(user) {
return "&_vgp=" + user.exchangeToken
}) : $q.when("")
}
function _getFields(shard) {
var root = config.root,
catalog = "local";
if (angular.isDefined(shard)) {
var remoteCatalog = catalogService.lookup(shard);
angular.isDefined(remoteCatalog) && (root = remoteCatalog.url, catalog = shard)
}
return _.isEmpty(_fields[catalog]) ? _getTokenParam(shard).then(function(tokenParam) {
var request = root + "solr/fields/select?fl=name,multivalued,disp:disp_en,stype,displayable,filterable" + _type + "&rows=100000&r=" + Math.random() + tokenParam;
return $http.jsonp(request).then(function(res) {
return _fields[catalog] = _.indexBy(res.data.response.docs, function(key) {
return solrUtil.stripAugmented(key.name)
}), _fields[catalog]
})
}) : $q.when(_fields[catalog])
}
function _fetchRelationships(direction, id, shard, fields) {
var relationships = {},
promises = [],
deferred = $q.defer();
return _fetchTypes(direction).then(function(types) {
_.each(types, function(name, type) {
var relationship = _getRelationship(relationships, name, type),
promise = _fetchLink(relationship, id, shard, type, direction, fields);
promises.push(promise)
}), $q.all(promises).then(function() {
deferred.resolve(relationships)
})
}), deferred.promise
}
var _type = "&wt=json&json.wrf=JSON_CALLBACK&block=false",
_translation = {},
_recentViews = [],
_fields = {},
buildRequest = function(id, displayFields, shard, disp) {
var service = config.root + "solr/v0/select?fq=id:" + id,
fields = "&fl=id,name:[name],fullpath:[absolute],absolute_path:[absolute],content:[contentURL],thumb:[thumbURL],preview:[previewURL],download:[downloadURL],bbox,format,hasMetadata,root,tree,tag_tags,links,geo:[geo],hasMissingData,schema,layerURL:[lyrURL]";
fields += displayFields;
var shards = "";
return _.isEmpty(shard) || (shards = "&shards.info=true&shards.tolerant=true&shards=" + shard), service + fields + shards + _type + "&rand=" + Math.random() + "&disp=" + disp
};
return {
lookup: function(id, fields, shard, disp) {
var promises = [];
promises.push(_getFields(shard));
var request = buildRequest(id, fields, shard, disp);
return promises.push($http.jsonp(request)), $q.all(promises).then(function(result) {
return result[1]
})
},
fetchTree: function(id, shard) {
var deferred = $q.defer(),
request = _buildTreeRequest(id, shard);
return $http.jsonp(request).then(function(res) {
var docs = res.data.response.docs;
angular.isDefined(docs) && docs.length > 0 ? deferred.resolve(docs[0]) : deferred.reject(id + " not found")
}), deferred.promise
},
fetchToRelationships: function(id, fields, shard) {
var direction = "to";
return _fetchRelationships(direction, id, shard, fields)
},
fetchFromRelationships: function(doc, fields, shard) {
var direction = "from";
return _fetchRelationships(direction, doc.id, shard, fields)
},
addRecent: function(doc) {
var exists = _.findIndex(_recentViews, {
id: doc.id
}) !== -1;
exists || _recentViews.push(doc), _recentViews.length > 5 && _recentViews.splice(0, 1)
},
getRecent: function() {
return _recentViews.slice()
},
getFields: function(shard) {
var catalog = "local";
if (angular.isDefined(shard)) {
var remoteCatalog = catalogService.lookup(shard);
angular.isDefined(remoteCatalog) && (catalog = shard)
}
return _fields[catalog]
},
fetchMetadataStyles: function(id) {
return $http.get(config.root + "api/rest/appearance/metadata/styles/" + id).then(function(res) {
return res.data
})
}
}
}), angular.module("voyager.details").directive("vsDetailsMap", function($compile, config, mapUtil, baseMapService, mapControls, $timeout) {
"use strict";
var geoLayer;
return {
compile: function(element) {
element.append('<leaflet style="height: 100%" defaults="defaults" controls="controls" layers="layers" id="details-map"></leaflet>')
},
link: function() {
geoLayer = null
},
controller: function($scope, leafletData) {
if ($scope.doc.isMappable);
else if ($scope.doc.geo) {
var geo = $scope.doc.geo;
leafletData.getMap("details-map").then(function(map) {
$timeout(function() {
map.invalidateSize(!1);
var geoType = angular.isDefined(geo.type) ? geo.type.toLowerCase() : "",
checkArea = geoType.indexOf("point") === -1;
geoLayer = mapUtil.drawGeoJson(map, geo, !0, void 0, checkArea)
}), map.on("layeradd", function() {
config.map.config.cached || $(".leaflet-image-layer").css("z-index", "-1")
})
})
}
$scope.defaults = baseMapService.getDefaultConfig(), $scope.layers = baseMapService.getLayers();
var spinControl = L.control();
spinControl.setPosition("topright"), spinControl.onAdd = function() {
var template = '<div class="leaflet-bar leaflet-draw-toolbar">';
return template += "<span us-spinner=\"{top:'-25px',left:'-5px',radius:4, width:3, length: 5}\" spinner-key=\"map-spinner\"></span>", template += "</div>", $compile($(template))($scope)[0]
}, $scope.controls = {
custom: [spinControl]
}, mapControls.init($scope, "details-map"), geoLayer && mapControls.setBounds(geoLayer.getBounds()), $scope.controls.custom.push(mapControls.getZoomControls($scope).setPosition("bottomleft"))
}
}
}), angular.module("voyager.details").factory("detailConfig", function(config, $q, configService, translateService, configLoader, sugar, solrUtil) {
function _setInclusions() {
$.each(displayFields, function(index, value) {
value.name = solrUtil.stripAugmented(value.name), inclusions[value.name] = value.name, _styles[value.name] = value.style, _showLabels[value.name] = value.showLabel, _maxLines[value.name] = value.maxLines, displayParams += ", " + value.name, _displayFieldsOrder[value.name] = index, _editable[value.name] = value.editable
})
}
function _setSummaryInclusions() {
$.each(_summaryFields, function(index, value) {
value.name = solrUtil.stripAugmented(value.name), _summaryInclusions[value.name] = value.name, _summaryStyles[value.name] = value.style, _summaryMaxLines[value.name] = value.maxLines, _summaryShowLabels[value.name] = value.showLabel, _summaryParams += ", " + value.name, _summaryFieldsOrder[value.name] = index
})
}
function _getPageFramework() {
return _pageFramework
}
function _getSummaryFlags() {
return _summaryFlags
}
function _getDefaultMetadataStylesheet() {
return _defaultMetadataStylesheet
}
function _load(configId, allFields) {
var deferred = $q.defer();
return configLoader.prepare().then(function() {
translateService.init(), configService.setFilterConfig(configId).then(function() {
configService.getConfigDetails(configId).then(function(response) {
var display = response.data.details;
_pageFramework = display.pageElements, _summaryFlags = display.summaryFields, _defaultMetadataStylesheet = display.defaultMetadataStylesheet, display.path === !1 && (_showPath = !1), display.ref === !1 && (_showFormat = !1), displayFields = display.detailsTableFields, _showAllFields = "ALL" === display.detailsTableConfig || "true" === allFields, _globalEditable = config.editAll, display.summaryFields && (_summaryFields = display.summaryFields.fields, _setSummaryInclusions()), _setInclusions(), deferred.resolve()
})
})
}), deferred.promise
}
function _exclude(name) {
var index = _.findIndex(excludePrefix, function(prefix) {
return 0 === name.indexOf(prefix) || name === prefix
});
return index !== -1
}
function _getFields(doc, fields, typeInclusions, typeStyles, typeShowAllFields) {
var prettyFields = [],
emptyFields = _.clone(typeInclusions),
isArray = !1,
formattedValue = "";
return $.each(doc, function(name, value) {
if ((typeInclusions[name] || typeShowAllFields === !0) && angular.isDefined(fields[name]) && fields[name].displayable === !0 && (delete emptyFields[name], !_exclude(name))) {
formattedValue = value, isArray = !1;
var formattedValues = {};
_.isArray(value) && (formattedValue = value.join(", "), isArray = !0, formattedValues = _.indexBy(value)), "format" === name ? formattedValue = translateService.getType(value) : "contains_mime" === name ? _.isArray(value) ? (formattedValues = {}, _.each(value, function(val) {
formattedValues[val] = translateService.getType(val)
})) : formattedValue = translateService.getType(value) : "location" === name ? formattedValue = translateService.getLocation(value) : "bytes" === name && (formattedValue = sugar.bytesToSize(value)), "STRIP_HTML" === typeStyles[name] && (formattedValue = $("<p>" + value + "</p>").text());
var isHref = !1;
"STRING" !== typeStyles[name] && "STRIP_HTML" !== typeStyles[name] && (isHref = _.isArray(value) && "HREF" !== typeStyles[name] ? _.any(value, function(v) {
return sugar.isUrl(v)
}) : "HREF" === typeStyles[name] || sugar.isUrl(value));
var isHtml = "HTML" === typeStyles[name];
fields[name].filterable || isHtml || isHref ? isHref && (typeStyles[name] = "HREF") : typeStyles[name] = "STRING", prettyFields.push({
name: translateService.getFieldName(name),
stype: fields[name].stype,
isArray: isArray,
value: value,
formattedValue: formattedValue,
formattedValues: formattedValues,
order: _displayFieldsOrder[name],
editable: _editable[name] || _globalEditable,
maxLines: _maxLines[name],
showLabel: _showLabels[name],
key: name,
style: typeStyles[name],
isHtml: isHtml,
isHref: isHref
})
}
prettyFields.length > 0 && ("abstract" !== name || _.isEmpty(doc.abstract) ? "description" !== name || _.isEmpty(doc.description) || (doc.displayDescription = _.last(prettyFields)) : doc.displayDescription = _.last(prettyFields))
}), $.each(emptyFields, function(name) {
(_editable[name] === !0 || _globalEditable) && prettyFields.push({
name: translateService.getFieldName(name),
value: "",
formattedValue: "",
order: _displayFieldsOrder[name],
editable: !0,
key: name
})
}), _.sortBy(prettyFields, "order")
}
function _getDisplayFields(doc, fields) {
return _getFields(doc, fields, inclusions, _styles, _showAllFields)
}
function _getSummaryFields(doc, fields) {
return _getFields(doc, fields, _summaryInclusions, _summaryStyles, !1)
}
var displayFields;
config.settings && (displayFields = config.settings.data.details.detailsTableFields);
var _summaryFields = [],
_summaryFlags = {},
_summaryInclusions = {},
_summaryParams = "",
_summaryFieldsOrder = {},
inclusions = {},
_displayFieldsOrder = {},
displayParams = "",
_showAllFields = !1,
_editable = {},
_styles = {},
_showLabels = {},
_maxLines = {},
_summaryStyles = {},
_summaryMaxLines = {},
_summaryShowLabels = {},
_pageFramework = {},
_showPath = !0,
_showFormat = !0,
_defaultMetadataStylesheet = "",
_globalEditable = !1,
excludePrefix = config.excludeDetails;
return {
load: _load,
showPath: function() {
return _showPath
},
showFormat: function() {
return _showFormat
},
getFields: _getDisplayFields,
getSummaryFields: _getSummaryFields,
getPageFramework: _getPageFramework,
getDefaultMetadataStylesheet: _getDefaultMetadataStylesheet,
getSummaryFlags: _getSummaryFlags
}
}), angular.module("voyager.details").controller("DetailsCtrl", function($scope, $stateParams, cartService, translateService, authService, config, detailService, mapServiceFactory, leafletData, usSpinnerService, dialogs, $sce, $q, configService, $timeout, tagService, searchService, $location, $window, urlUtil, resultsDecorator, loading, detailConfig, $analytics, $uibModal, filterService, detailsActions, $log, converter) {
function _getExtraRelationshipFields() {
return config.extraRelationshipFields || []
}
function _setPermissions() {
$scope.canEdit = authService.hasPermission("edit_fields") && $scope.isRemote !== !0, $scope.canTag = authService.hasPermission("tag"), $scope.canAdmin = authService.hasPermission("manage"), $scope.canFlag = authService.hasPermission("flag"), $scope.canViewTags = authService.hasPermission("view_tags"), $scope.canViewMetadata = authService.hasPermission("show_metadata")
}
function _adjustForBanner() {
$timeout(function() {
var $banner = angular.element("#top-banner");
if ($banner.outerHeight() > 0) {
var $floatingNav = angular.element(".floating-nav");
$floatingNav.length > 0 ? $floatingNav.offset({
top: $floatingNav.offset().top + $banner.outerHeight()
}) : _adjustForBanner()
}
}, 250)
}
function _hasShard(shard) {
return angular.isDefined(shard) && "[not a shard request]" !== shard
}
function _activate() {
_hasShard($stateParams.shard) && ($scope.shard = $stateParams.shard, $scope.shardParam = "&shard=" + $stateParams.shard, $scope.shardsParam = "&shards=" + $stateParams.shard), !$scope.pageFramework.showHeaderInfo && $location.path().indexOf("/search") > -1 ? angular.element("body").addClass("no-header") : angular.element("body").removeClass("no-header"), _doLookup($stateParams.id), $analytics.eventTrack("view", {
category: "details",
label: $stateParams.id,
id: $stateParams.id
}), detailService.fetchMetadataStyles($stateParams.id).then(function(styleSheets) {
$scope.styleSheets = styleSheets
}), _setPermissions(), tagService.fetchTags().then(function(tags) {
$.merge(_tags, tags)
}), $scope.onUpdateTags = function(tags) {
var index = $scope.displayFields.findIndex(function(item) {
return "tag_tags" === item.key
});
if (index !== -1) {
var field = $scope.displayFields[index];
field.value = tags, field.formattedValue = tags.join();
var formattedValues = {};
_.each(tags, function(val) {
formattedValues[val] = val
}), field.formattedValues = formattedValues
}
}, authService.addObserver(_setPermissions)
}
function createFolderLinks(doc, url) {
$scope.doc_path = {
url: "search?disp=" + $scope.disp + "&fq=location:" + doc.location,
path: doc.fullpath.substring(0, doc.fullpath.indexOf(doc.folder.replace(/\//g, "\\")))
};
var tempFolders = doc.folder.split("/");
_.each(tempFolders, function(item) {
"" !== url && (url += "/"), url += encodeURI(item), $scope.sub_paths.push({
path: item + "\\",
url: "search?disp=" + $scope.disp + "&fq=path:" + url + "&fq=location:" + doc.location
})
});
var filename = doc.fullpath.split("\\").pop();
$scope.sub_paths.push({
path: filename,
url: "search?disp=" + $scope.disp + "&fq=path:" + (url + "/" + filename) + "&fq=location:" + doc.location
})
}
function createDatasetLinks(doc) {
var tempFolders = doc.fullpath.split("Dataset");
if (tempFolders && ($scope.doc_path = {
url: "search?disp=" + $scope.disp + "&fq=location:" + doc.location,
path: tempFolders[0] + "Dataset"
}, tempFolders[1])) {
var path = tempFolders[1].replace(/^[\/\\]/, "").replace(/\s[|]\s/g, "\\").replace(/\\/g, "%255C");
$scope.sub_paths.push({
path: tempFolders[1],
url: "search?disp=" + $scope.disp + "&fq=location:" + doc.location + "&fq=path:" + path
})
}
}
function createPathLinks(doc) {
if ($scope.isURL = 0 === doc.fullpath.indexOf("http:") || 0 === doc.fullpath.indexOf("https:"), !$scope.isURL) {
var url = "";
$scope.sub_paths = [], doc.folder ? createFolderLinks(doc, url) : createDatasetLinks(doc)
}
}
function _doSyncFields(id) {
detailService.lookup(id, ",*", $stateParams.shard, $stateParams.disp).then(function(data) {
var doc = data.data.response.docs[0];
$scope.displayFields = detailConfig.getFields(doc, detailService.getFields($stateParams.shard)), $scope.summaryFields = detailConfig.getSummaryFields(doc, detailService.getFields($stateParams.shard))
})
}
function _doLookup(id) {
detailService.lookup(id, ",*", $stateParams.shard, $stateParams.disp).then(function(data) {
var doc = data.data.response.docs[0];
resultsDecorator.decorate([doc], []);
var shardInfo = data.data["shards.info"];
shardInfo && doc.isRemote && _.each(shardInfo, function(shard) {
doc.remoteDetails = shard.shardAddress, doc.remoteDetails = doc.remoteDetails.substring(0, doc.remoteDetails.indexOf("/solr")), doc.remoteDetails += "/show?id=" + doc.id + "&disp=default"
}), $scope.doc = doc, $scope.image = doc.thumb, $scope.preview = doc.preview, angular.isUndefined(doc.preview) && ($scope.preview = $scope.image), $scope.download = doc.download, angular.isDefined(doc.format) && ($scope.format = translateService.getType(doc.format), $scope.doc.displayFormat = $scope.format), $scope.displayFields = detailConfig.getFields(doc, detailService.getFields($stateParams.shard)), $scope.summaryFields = detailConfig.getSummaryFields(doc, detailService.getFields($stateParams.shard)), $scope.pageFramework = detailConfig.getPageFramework(), $scope.summaryFlags = detailConfig.getSummaryFlags(), $scope.description = doc.displayDescription, doc.fullpath ? createPathLinks(doc) : $scope.isURL = !1, doc.bbox && ($scope.hasBbox = !0), doc.hasSchema = angular.isDefined(doc.schema), doc.hasSchema && ($scope.schema = JSON.parse(doc.schema), $scope.schemaLink = "search?disp=" + $scope.disp + "&fq=schema_hash:" + $scope.schema.hash), $scope.doc.isMappable = mapServiceFactory.isMappable(doc.format), $scope.doc.isService = $scope.doc.isMappable, $scope.showMap = $scope.hasBbox || $scope.doc.isMappable, $scope.getAction = "Download", $scope.recent = detailService.getRecent(), resultsDecorator.decorate($scope.recent, []), detailService.addRecent($scope.doc), doc.hasMetadata && $scope.canViewMetadata && _setStyle(), angular.isDefined(doc.tag_tags) && ($scope.select2Options.tags = doc.tag_tags, $scope.labels = doc.tag_tags), $scope.getRelationships(), _setSelectedTab(), loading.done(), $timeout(function() {
$scope.loading = !1, $scope.doc.isMappable && $scope.addToMap()
}, 100), angular.isDefined($scope.doc.thumb) && $scope.doc.thumb.indexOf("vres/mime") !== -1 && (doc.defaultThumb = !0), $scope.doc.canCart = authService.hasPermission("process"), $scope.actions = detailsActions.getActions($scope.doc, $scope);
var addAction = _.find($scope.actions, {
action: "add"
});
$scope.canCart = $scope.doc.canCart && !$scope.isRemote && addAction.visible, addAction.visible = !1, cartService.fetchQueued([{
id: doc.id
}]).then(function(items) {
doc.inCart = items.length > 0
}), _adjustForBanner(), doc.isVideo = "video/mp4" === doc.format
})
}
function _setStyle() {
$scope.theme = {}, $scope.theme.selected = detailConfig.getDefaultMetadataStylesheet() || config.metadataStyle, $scope.$watch("theme.selected", function() {
$scope.metadataUrl = $scope.doc.content, $scope.metadataUrl && ($scope.metadataUrl.indexOf("/", $scope.metadataUrl.length - 1) === -1 && ($scope.metadataUrl += "/"), $scope.metadataUrl += "meta.xml?style=" + $scope.theme.selected, _hasShard($scope.doc.shard) && ($scope.metadataUrl += "&shard=" + $scope.doc.shard))
})
}
function _showError(error) {
var message = null;
angular.isDefined(error.details) && (message = error.details[0]), dialogs.error(error.message, message)
}
function _flagMissing(nodes) {
for (var format, node, i = 0; i < nodes.length; i++) node = nodes[i], format = node.mime, node.hasMissingData = angular.isDefined(format) && format.indexOf("missing") !== -1, node.children && _flagMissing(node.children)
}
function _applyRelationships(relationships, type) {
$.isEmptyObject(relationships) ? $log.log("no result") : _.each(relationships, function(obj) {
if (obj.values && obj.values.length > 0) return $scope[type] = relationships, $scope.hasRelationships = !0, _removeDuplicateRelationshipChildren(), _setSelectedTab(), !1
})
}
function _removeDuplicateRelationshipChildren() {
$scope.relationships && $scope.relationships._root && $scope.fromRelationships && $scope.fromRelationships._children && $scope.relationships._root.numFound === $scope.fromRelationships._children.numFound && _.isEqual($scope.relationships._root.values, $scope.fromRelationships._children.values) && delete $scope.fromRelationships._children
}
function _setSelectedTab() {
$scope.showTab || ($scope.displayFields.length ? $scope.showTab = "summary" : $scope.doc.hasMetadata && $scope.canViewMetadata ? $scope.showTab = "metadata" : $scope.hasRelationships && ($scope.showTab = "relationship"))
}
function _getId() {
return decodeURIComponent($location.search().id)
}
function _move(direction, doc) {
var flag = "no" + direction;
if (null !== doc) {
$scope[flag] = !1;
var encodedId = encodeURIComponent(encodeURIComponent(doc.id)),
params = {
id: encodedId,
disp: configService.getConfigId()
};
return _hasShard(doc.shard) && (params.shard = doc.shard), $location.search(params), !0
}
return $scope[flag] = !0, !1
}
function _searchTag(tagField, value) {
return $location.path("search"), $location.search("fq", tagField + ":" + value), filterService.setFilters({
fq: tagField + ":" + value
}), $scope.$emit("filterEvent"), !1
}
var _layer;
loading.show("#working"), $scope.imagePrefix = config.root + "vres/mime/icon/", $scope.showTab = "", $scope.demo = config.demo, $scope.rate = {}, $scope.rate.current_rating = 0, $scope.rate.total_user = 0, $scope.rate.user_rated = !1, $scope.labels = [], $scope.loading = !0, $scope.disp = $stateParams.disp || "default", $scope.hasRelationships = !1, $scope.pageFramework = {}, $scope.uiText = config.ui.details, $scope.showPath = detailConfig.showPath(), $scope.showFormat = detailConfig.showFormat();
var _tags = [];
$scope.select2Options = {
multiple: !0,
simple_tags: !0
}, _.isEmpty(config.homepage.tagValues) ? $scope.select2Options.tags = _tags : $scope.select2Options.data = converter.toIdTextArray(config.homepage.tagValues), _activate(), $scope.openOnRemote = function() {
$window.open($scope.doc.remoteDetails, "_blank")
}, $scope.addToCart = function() {
$scope.doc.inCart = !0, cartService.addItem($scope.doc)
}, $scope.removeFromCart = function() {
$scope.doc.inCart = !1, cartService.remove($scope.doc.id)
}, $scope.inCart = function(id) {
return cartService.isInCart(id)
}, $scope.showEditTag = !1, $scope.toggleEditTag = function() {
$scope.showEditTag = !$scope.showEditTag
}, $scope.addToMap = function() {
return !$scope.addedToMap && void $timeout(function() {
leafletData.getMap("details-map").then(function(map) {
var mapInfo = _.clone($scope.doc),
mapService = mapServiceFactory.getMapService(mapInfo);
mapService.addToMap(mapInfo, map).then(function(layer) {
layer.isValid !== !1 ? (layer.on("loading", function() {
usSpinnerService.spin("map-spinner")
}), usSpinnerService.stop("map-spinner"), layer.on("load", function() {
$scope.addedToMap = !0, _layer = layer, usSpinnerService.stop("map-spinner")
})) : (usSpinnerService.stop("map-spinner"), _showError(layer.error))
}, function(error) {
usSpinnerService.stop("map-spinner"), _showError(error.error)
}), map.invalidateSize(!1)
})
})
}, $scope.removeFromMap = function() {
leafletData.getMap("details-map").then(function(map) {
map.removeLayer(_layer), $scope.addedToMap = !1, _layer = null
})
}, $scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src)
}, $scope.metadataSelect = function() {
window.scrollTo(0, document.body.scrollHeight)
}, $scope.getRelationships = function() {
var root = $scope.doc.id;
angular.isDefined($scope.doc.root) && (root = $scope.doc.root), detailService.fetchTree(root, $stateParams.shard).then(function(response) {
if (angular.isDefined(response.tree)) {
var tree = JSON.parse(response.tree);
tree.children && _flagMissing(tree.children), $scope.tree = [{
mime: response.format,
name: tree.name,
id: tree.id,
children: tree.children
}], $scope.hasRelationships = !0, _setSelectedTab()
}
}), detailService.fetchToRelationships($scope.doc.id, _getExtraRelationshipFields(), $stateParams.shard).then(function(relationships) {
_applyRelationships(relationships, "relationships")
}), detailService.fetchFromRelationships($scope.doc, _getExtraRelationshipFields(), $stateParams.shard).then(function(relationships) {
_applyRelationships(relationships, "fromRelationships")
})
}, $scope.fetchPreview = function(node) {
$scope.previewVisible = !0, node.promise = $timeout(function() {
detailService.fetchTreePreview(node.id, $stateParams.shard).then(function(preview) {
$scope.previewNodeData = preview.data.response.docs[0]
})
}, 150)
}, $scope.cancelPreview = function(node) {
$scope.previewVisible = !1, $timeout.cancel(node.promise)
}, $scope.changeTab = function(tab) {
$scope.showTab !== tab && ($scope.showTab = tab, "relationship" === tab && void 0 === $scope.tree && $scope.getRelationships())
}, $scope.edit = function(field) {
field.editing = !0, field.originalValue = field.value, field.originalFormatted = field.formattedValue,
"tag_tags" === field.key && "" === field.value && (field.value = [])
}, $scope.append = function(field) {
field.appending = !0
}, $scope.cancel = function(field) {
field.editing = !1, field.appending = !1, field.value = field.originalValue, field.formattedValue = field.originalFormatted
}, $scope.isArray = function(data) {
return _.isArray(data)
}, $scope.doSave = function(field) {
if (field.isArray && !_.isArray(field.value)) {
var values = field.value.split(","),
edits = [];
_.each(values, function(val) {
edits.push(val.trim())
}), field.value = edits
}
tagService.replace($scope.doc.id, field.key, field.value).then(function() {
field.editing = !1;
var canViewTags = $scope.canViewTags;
"tag_tags" === field.key && ($scope.labels = field.value, field.formattedValue = field.value.join(), canViewTags && ($scope.canViewTags = !1)), $timeout(function() {
canViewTags && ($scope.canViewTags = !0), _doSyncFields($scope.doc.id)
}, 200)
})
}, $scope.lastSearch = urlUtil.getLastUrl(), $scope.hasRecords = searchService.hasRecords(), $scope.getPrevious = function() {
var id = searchService.getPreviousId(_getId());
_move("Previous", id) && ($scope.noNext = !1)
}, $scope.getNext = function() {
usSpinnerService.spin("nav-spinner"), searchService.getNextId(_getId()).then(function(id) {
_move("Next", id) && ($scope.noPrevious = !1), usSpinnerService.stop("nav-spinner")
})
}, $scope.showFlagModal = function() {
var modal = $uibModal.open({
templateUrl: "src/bulk-update/flag-all.html",
controller: "FlagAllCtrl",
resolve: {
resultData: function() {
return {
totalItemCount: 1,
docId: $scope.doc.id
}
}
}
});
modal.result.then(function() {
_doLookup($stateParams.id)
})
}, $scope.removeFlag = function() {
tagService.deleteByField($scope.doc.id, "tag_flags").then(function(res) {
res.documents > 0 && delete $scope.doc.tag_flags
})
}, $scope.searchFlag = function(tag) {
return _searchTag("tag_flags", tag)
}, $scope.searchTag = function(tag) {
return _searchTag("tag_tags", tag)
}, $scope.$on("$destroy", function() {
authService.removeObserver(_setPermissions)
})
}), angular.module("voyager.details").directive("vgTags", function($timeout, tagService, $window, searchService) {
"use strict";
function _decorateTags() {
var $container = $("#s2id_labels"),
$tags = $container.children(".select2-choices").children(".select2-search-choice").children("div"),
hasTags = !1;
return $.each($tags, function(name, value) {
$(value).hover(function(e) {
$(e.currentTarget).css({
"text-decoration": "underline",
cursor: "pointer"
})
}, function(e) {
$(e.currentTarget).css({
"text-decoration": "none",
cursor: "auto"
})
}), hasTags = !0
}), hasTags
}
function _searchByTag() {
$("#labels").off("choice-selected"), $("#labels").on("choice-selected", function(e, v) {
var tag = $(v).text().trim();
searchService.getLastSearch().indexOf("?") === -1 ? $window.location.href = searchService.getLastSearch() + "?fq=tag_tags:" + tag : $window.location.href = searchService.getLastSearch() + "&fq=tag_tags:" + tag
})
}
return {
restrict: "A",
require: "ngModel",
link: function(scope, el, attrs) {
var autosave = "true" === attrs.autosave;
return scope.$watch(attrs.ngModel, function(newValues, last) {
$timeout(function() {
_decorateTags() && _searchByTag()
}, 0), _.isEqual(newValues, last) || scope.loading || !autosave || (tagService.saveLabels(scope.doc.id, newValues), scope.onUpdateTags && scope.onUpdateTags(newValues))
})
}
}
}), angular.module("voyager.details").directive("vsPreview", function(detailService, $timeout, translateService, loading, detailConfig) {
return {
restrict: "A",
link: function($scope, element) {
function _lookup(id, shard, el) {
_positionPreview(el), $scope.previewLoading = !0, loading.show("#previewLoading"), $scope.node = {}, detailService.lookup(id, "", shard).then(function(data) {
return $scope.node = data.data.response.docs[0], void 0 === $scope.node ? void $("#preview").css({
display: "none"
}) : ($scope.previewNodeData = detailConfig.getFields(data.data.response.docs[0], detailService.getFields(shard)), angular.isDefined(data.data.response.docs[0].format) && ($scope.node.displayFormat = translateService.getType(data.data.response.docs[0].format)), $scope.previewLoading = !1, void loading.done())
})
}
function _positionPreview(el) {
var cp = el.offset(),
parentOffset = el.parents(".relationship").offset();
$("#preview").css({
display: "block",
left: parseInt(cp.left - parentOffset.left + el.parents("div").width() - 20) + "px",
top: parseInt(cp.top - parentOffset.top - 22) + "px"
})
}
element.on("mouseenter", ".label a", function(event) {
$scope.node = {};
var el = $(event.currentTarget);
this.timeoutPromise = $timeout(function() {
_lookup(el.data("id"), el.data("shard"), el)
}, 100)
}).on("mouseleave", ".label a", function() {
angular.isDefined(this.timeoutPromise) && $timeout.cancel(this.timeoutPromise), $("#preview").css({
display: "none"
})
})
}
}
}), angular.module("voyager.search").controller("SavedSearchCtrl", function($scope, $location, filterService, savedSearchService, authService, $analytics, recentSearchService) {
function _loadSavedSearches() {
savedSearchService.getSavedSearches().then(function(savedSearches) {
var sortedSavedSearches = savedSearchService.sortSavedSearches(savedSearches);
vm.savedSearches = sortedSavedSearches.global, vm.personalSavedSearches = sortedSavedSearches.personal
}), $scope.isAnonymous = authService.isAnonymous()
}
var vm = this;
_loadSavedSearches(), authService.addObserver(_loadSavedSearches), savedSearchService.addObserver(_loadSavedSearches), recentSearchService.addObserver(_loadSavedSearches), vm.applySavedSearch = function(saved) {
savedSearchService.applySavedSearch(saved, $scope)
}, vm.deleteSearch = function(id) {
savedSearchService.deleteSearch(id).then(function() {
_loadSavedSearches(), $analytics.eventTrack("saved-search", {
category: "delete"
})
})
}, vm.dragControlListeners = {
enabled: !0,
accept: function() {
return vm.dragControlListeners.enabled
},
orderChanged: function(eventObj) {
var list = vm.personalSavedSearches,
index = eventObj.dest.index,
beforeId = null,
afterId = null;
0 !== index && (beforeId = list[index - 1].id), index + 1 !== list.length && (afterId = list[index + 1].id), vm.dragControlListeners.enabled = !1, savedSearchService.order(list[index].id, beforeId, afterId).then(function() {
vm.dragControlListeners.enabled = !0
})
}
}, $scope.$on("$destroy", function() {
authService.removeObserver(_loadSavedSearches), savedSearchService.removeObserver(_loadSavedSearches), recentSearchService.removeObserver(_loadSavedSearches)
}), vm.criteriaMatch = function(term) {
return function(item) {
return !!angular.isUndefined(term) || item.title.toLowerCase().indexOf(term.toLowerCase()) > -1
}
}
}), angular.module("voyager.search").factory("savedSearchService", function(sugar, $http, configService, $q, authService, $uibModal, recentSearchService, $location, filterService, $analytics, converter, displayConfigResource, solrGrunt, $timeout, catalogService) {
"use strict";
function _applyBbox(solrParams, voyagerParams) {
if (_.isArray(solrParams.fq)) {
var index = sugar.getIndex(solrParams.fq, "bbox");
solrParams.fq.splice(index, 1)
} else delete solrParams.fq;
solrParams.place = voyagerParams.bbox, solrParams["place.op"] = "WITHIN" === voyagerParams["bbox.mode"] ? "within" : "intersects"
}
function _getView(voyagerParams, defaultView) {
defaultView = defaultView ? defaultView.toLowerCase() : "card";
var view = {
type: defaultView
};
return angular.isDefined(voyagerParams.view) && (voyagerParams.view = voyagerParams.view.toLowerCase(), "table" !== voyagerParams.view && "map" !== voyagerParams.view || (view.type = voyagerParams.view)), view
}
function _decode(params) {
$.each(params, function(index, param) {
"string" == typeof param ? params[index] = decodeURIComponent(param) : $.each(param, function(index, value) {
param[index] = decodeURIComponent(value)
})
})
}
function _doSave(request) {
if (configService.hasChanges()) {
var settings = configService.getUpdatedSettings();
request.display_override = {
listView: {
fields: settings.listView.fields
}
}
}
return request.path += "/disp=" + request.config, sugar.postJson(request, "display", "ssearch")
}
function _getQueryString(name) {
var rows = 150,
queryString = config.root + "solr/ssearch/select?&fl=*,display:[display]&";
return queryString += "rows=" + rows + "&rand=" + Math.random(), angular.isDefined(name) && (name = name.replace(/ /g, "\\%20"), queryString += "&fq=title:" + name), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _fetch(name) {
var time = 100;
return void 0 !== name && (time = 0), $timeout.cancel(delay), delay = $timeout(function() {
$http.jsonp(_getQueryString(name)).then(function(data) {
deferred.resolve(data.data.response.docs), deferred = $q.defer()
}, function(error) {
console.log(error), deferred.error(error), deferred = $q.defer()
})
}, time), deferred.promise
}
function _mergeOrFilters(params) {
var filters = params.fq;
if (_.isArray(filters) && filters.length > 1) {
var orIndex = _.findIndex(filters, function(filter) {
return filter.indexOf("(") !== -1
});
if (orIndex !== -1) {
var orParam = filters[orIndex],
facetValues = orParam.split(":"),
facet = facetValues[0],
values = facetValues[1];
values = values.replace(/\(|\)/g, ""), values = values.split(" ");
for (var nameValue, fq = [], i = 0; i < filters.length; i++) nameValue = filters[i].split(":"), nameValue[0] === facet && i !== orIndex ? values.push(nameValue[1]) : i !== orIndex && fq.push(filters[i]);
fq.push(facet + ":" + values.join(" ")), params.fq = fq
}
}
}
var delay, observers = [],
deferred = $q.defer();
return {
getSavedSearches: function() {
return _fetch()
},
fetch: function(savedSearch) {
return _fetch(savedSearch.title)
},
getParams: function(saved) {
saved.query = saved.query.replace(/\+/g, "%2B");
var solrParams = querystring.parse(sugar.trim(saved.query, "&"));
delete solrParams.facet, delete solrParams["facet.field"], delete solrParams["facet.mincount"], delete solrParams["extent.bbox"], delete solrParams["f.format_category.facet.mincount"], delete solrParams["shards.info"], delete solrParams["shards.tolerant"], _decode(solrParams);
var voyagerParams;
voyagerParams = void 0 === saved.path ? querystring.parse(sugar.trim(saved.query.replace(/\//g, "&"), "&")) : querystring.parse(sugar.trim(saved.path.replace(/\//g, "&"), "&")), angular.isDefined(voyagerParams.catalog) && angular.isUndefined(solrParams.shards) && (solrParams.shards = _.isArray(voyagerParams.catalog) ? voyagerParams.catalog.join(",") : voyagerParams.catalog), angular.isDefined(solrParams.shards) && (solrParams.shards = catalogService.removeInvalid(solrParams.shards)), angular.isDefined(voyagerParams.bbox) && _applyBbox(solrParams, voyagerParams), angular.isDefined(voyagerParams.disp) && (solrParams.disp = voyagerParams.disp);
var view = _getView(voyagerParams, saved.display ? saved.display.defaultView : void 0);
if (solrParams.view = view.type, angular.isDefined(solrParams.sort)) {
var sort = solrParams.sort.split(" ");
solrParams.sort = sort[0].replace("_sort", ""), solrParams.sortdir = sort[1]
}
return solrParams
},
addObserver: function(obs) {
var index = _.findIndex(observers, function(item) {
return obs === item
});
index === -1 && observers.push(obs)
},
removeObserver: function(observer) {
observers = _.without(observers, function(item) {
return item === observer
})
},
saveSearch: function(savedSearch, params) {
return savedSearch.config = configService.getConfigId(), _mergeOrFilters(params), savedSearch.path = converter.toClassicParams(params, !0), _doSave(savedSearch)
},
deleteSearch: function(id) {
return $http.delete(config.root + "api/rest/display/ssearch/" + id).then(function() {
observers.forEach(function(entry) {
entry(id)
})
})
},
showSaveSearchDialog: function(item) {
var modalInstance = $uibModal.open({
templateUrl: "src/saved-search/save-search-dialog.html",
size: "md",
controller: "SaveSearchDialog",
resolve: {
searchItem: function() {
return item
}
}
});
modalInstance.result.then(function() {}, function() {})
},
showSearchModal: function(tab) {
var modalInstance = $uibModal.open({
templateUrl: "src/saved-search/saved-search-modal.html",
size: "lg",
controller: "SavedSearchModalCtrl",
resolve: {
tab: function() {
return tab
}
}
});
modalInstance.result.then(function() {}, function() {})
},
applySavedSearch: function(saved, $scope) {
var currentView = $location.search().view,
solrParams = this.getParams(saved);
$scope.$emit("clearSearchEvent"), $location.search(solrParams), "/search" !== $location.path() && $location.path("/search"), configService.updateConfig(saved.display), filterService.applyFromUrl($location.search()).then(function() {
var params = {};
"table" === solrParams.view && "table" === currentView && (params.refresh = !1), $timeout(function() {
$scope.$emit("filterEvent", params)
})
}), $analytics.eventTrack("saved-search", {
category: "run"
}), this.addToRecent(saved)
},
addToRecent: function(searchItem) {
var item = {};
item.id = searchItem.id, item.title = searchItem.title, item.query = this.getParams(searchItem), item.query = sugar.toQueryStringEncoded(item.query), item.saved = !0, recentSearchService.addItem(item)
},
order: function(id, beforeId, afterId) {
var data = "";
return null !== beforeId && (data += "before=" + beforeId), "" !== data && (data += "&"), null !== afterId && (data += "after=" + afterId), sugar.postForm("api/rest/display/ssearch/" + id + "/order", data)
},
sortSavedSearches: function(savedSearches) {
var global = [],
personal = [],
userHasSaveSearch = authService.hasPermission("save_search"),
authUser = authService.getUser();
$.each(savedSearches, function(index, saved) {
authUser && userHasSaveSearch && saved.owner === authUser.name ? personal.push(saved) : global.push(saved)
});
var sortedSavedSearches = {
global: global,
personal: personal
};
return sortedSavedSearches
}
}
}), angular.module("voyager.search").controller("SaveSearchDialog", function($scope, $uibModalInstance, savedSearchService, $location, authService, $analytics, recentSearchService, searchItem, displayConfigResource, $q) {
function _loadGroups() {
$scope.canAdmin ? ($.merge(_shareGroups, _coreRoles), authService.fetchGroups().then(function(groups) {
$.merge(_shareGroups, groups)
})) : $scope.canShare && authService.getUserInfo().then(function(user) {
var groups = [];
_(user.groups).forEach(function(n) {
groups.push({
id: n,
text: n
})
}), $.merge(_shareGroups, groups)
})
}
function _getPrivileges() {
authService.getPrivileges().then(function() {
$scope.canAdmin = authService.hasPermission("manage"), $scope.canSave = authService.hasPermission("save_search"), $scope.canShare = authService.hasPermission("share_saved_search"), _loadGroups()
})
}
function _activate() {
_getPrivileges()
}
function _saveSearch(savedSearch) {
return savedSearchService.saveSearch(savedSearch, searchItem).then(function(response) {
$uibModalInstance.close(), $analytics.eventTrack("saved-search", {
category: "save"
}), recentSearchService.updateSearchID(searchItem, response.data), $scope.$emit("saveSearchSuccess", response.data)
}, function(error) {
console.log(error.data)
})
}
$scope.savedSearch = {
query: searchItem.query
};
var _shareGroups = [],
_coreRoles = [{
id: "_EVERYONE",
text: "EVERYONE"
}, {
id: "_LOGGEDIN",
text: "LOGGEDIN"
}, {
id: "_ANONYMOUS",
text: "ANONYMOUS"
}],
_existingSearch = {};
$scope.sharedOptions = {
multiple: !0,
tags: _shareGroups
}, _activate(), $scope.ok = function() {
if (!_.isEmpty($scope.savedSearch.title)) {
$scope.savedSearch.makeDefault && ($scope.savedSearch.order = (new Date).getTime());
var savedSearchCopy = _.cloneDeep($scope.savedSearch);
savedSearchCopy.share = _.pluck(savedSearchCopy.share, "id");
var promises = [savedSearchService.fetch(savedSearchCopy), displayConfigResource.getDisplayConfig($location.search().disp)];
$q.all(promises).then(function(response) {
var docs = response[0],
dispConfig = response[1].data;
return 0 === docs.length || _.contains($scope.error, "Overwrite") ? (delete $scope.error, savedSearchCopy.labels = _existingSearch.labels, docs.length > 0 && (savedSearchCopy.id = docs[0].id), searchItem.view === dispConfig.defaultView.toLowerCase() && delete searchItem.view, _saveSearch(savedSearchCopy)) : void(docs[0].owner === authService.getUser().id || authService.hasPermission("manage") ? (_existingSearch = docs[0], $scope.error = "Saved Search exists. Overwrite?") : $scope.error = "Saved Search exists. You don't have permission to overwrite. Please rename your search.")
})
}
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}, $scope.hasPermission = function(permission) {
return authService.hasPermission(permission)
}, $scope.handleEnter = function(ev) {
delete $scope.error, 13 === ev.which && $scope.ok()
}
}), angular.module("voyager.search").directive("savedContent", function(authService) {
return {
restrict: "E",
templateUrl: "src/saved-content/saved-content-modal.html",
link: function(scope) {
function _syncState() {
scope.isAnonymous = authService.isAnonymous(), scope.canSave = authService.hasPermission("save_search")
}
scope.showSearch = !0, scope.showTab = scope.tab || "suggested", scope.showCategory = function($event, category) {
return $event.preventDefault(), "search" === category ? scope.showSearch || (scope.showSearch = !0, scope.showTab = scope.canSave ? "saved" : "suggested") : (scope.showSearch = !1, scope.showTab = scope.canSave ? "saved" : "suggested"), !1
}, scope.changeTab = function(tab) {
scope.showTab !== tab && (scope.showTab = tab)
}, scope.cancel = function() {
scope.$dismiss()
}, scope.$on("filterChanged", function() {
scope.cancel()
}), scope.isAnonymous = authService.isAnonymous(), scope.canSave = authService.hasPermission("save_search"), authService.addObserver(_syncState), scope.$on("$destroy", function() {
authService.removeObserver(_syncState)
})
}
}
}), angular.module("voyager.search").factory("savedLocationService", function(sugar, $http, configService, $q, authService, $location, $analytics, filterService, converter) {
"use strict";
function _doSave(request) {
if (configService.hasChanges()) {
var deferred = $q.defer();
return sugar.postJson(configService.getUpdatedSettings(), "display", "config").then(function(response) {
request.config = response.data.id, request.query += "/disp=" + request.config, request.path = request.query, sugar.postJson(request, "display", "slocation").then(function(savedResponse) {
deferred.resolve()
}, function(error) {
deferred.reject(error)
})
}, function(error) {
deferred.reject(error)
}), deferred.promise
}
return request.query += "/disp=" + request.config, request.path = request.query, sugar.postJson(request, "display", "slocation")
}
function _getQueryString() {
var rows = 150,
queryString = config.root + "solr/slocation/select?";
return queryString += "rows=" + rows + "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _execute(url) {
return $http.jsonp(url).then(function(data) {
return data.data ? data.data.response.docs : []
}, function(error) {
return console.log(error), error
})
}
function _getSearchResult(term) {
var rows = 150,
queryString = config.root + "solr/slocation/select?";
return queryString += "fq=name:" + term, queryString += "&fl=name", queryString += "&rows=" + rows + "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
var observers = [];
return {
getSavedLocations: function() {
return _execute(_getQueryString())
},
searchByTerm: function(term) {
return _execute(_getSearchResult(term))
},
getParams: function(saved) {
return querystring.parse(sugar.trim(saved.value.replace(/\//g, "&"), "&"))
},
addObserver: function(obs) {
var index = _.findIndex(observers, function(item) {
return obs === item
});
index === -1 && observers.push(obs)
},
removeObserver: function(obs) {
observers = _.without(observers, function(item) {
return obs === item
})
},
saveLocation: function(SavedLocation, params) {
return SavedLocation.config = configService.getConfigId(), SavedLocation.value = converter.toClassicParams(params), _doSave(SavedLocation)
},
applySavedLocation: function(saved, $scope) {
var solrParams = this.getParams(saved);
$scope.$emit("clearSearchEvent"), $location.path("search").search(solrParams), filterService.applyFromUrl($location.search()).then(function() {
$scope.$emit("filterEvent", {})
})
},
deleteLocation: function(id) {
return $http.delete(config.root + "api/rest/display/slocation/" + id).then(function() {
observers.forEach(function(entry) {
entry(id)
})
})
},
order: function(id, beforeId, afterId) {
var data = "";
return null !== beforeId && (data += "before=" + beforeId), "" !== data && (data += "&"), null !== afterId && (data += "after=" + afterId), sugar.postForm("api/rest/display/slocation/" + id + "/order", data)
}
}
}), angular.module("voyager.search").directive("vsSaveLocationDialog", function(authService, $location, savedLocationService) {
return {
restrict: "E",
templateUrl: "src/saved-location/save-location-dialog.html",
link: function(scope) {
function _loadGroups() {
scope.canAdmin && ($.merge(_shareGroups, _coreRoles), authService.fetchGroups().then(function(groups) {
$.merge(_shareGroups, groups)
}))
}
function _getPrivileges() {
authService.getPrivileges().then(function() {
scope.canAdmin = authService.hasPermission("manage"), _loadGroups()
})
}
function _activate() {
_getPrivileges()
}
scope.savedLocation = {}, scope.error = !1;
var _shareGroups = [],
_coreRoles = [{
id: "_EVERYONE",
text: "EVERYONE"
}, {
id: "_LOGGEDIN",
text: "LOGGEDIN"
}, {
id: "_ANONYMOUS",
text: "ANONYMOUS"
}];
scope.sharedOptions = {
multiple: !0,
simple_tags: !0,
data: function() {
return {
results: _shareGroups
}
}
}, scope.hasError = function() {
return scope.error !== !1
}, _activate(), scope.ok = function() {
if (!_.isEmpty(scope.savedLocation.name)) {
var params = {};
if ("Place" === scope.selectedMapType) {
if (!_.isEmpty(scope.search.location)) {
params.place = scope.search.location;
var placeId = $location.search()["place.id"];
angular.isDefined(placeId) && (params["place.id"] = placeId), params["place.op"] = scope.selectedDrawingType.toLowerCase()
}
} else void 0 !== scope.search.place && (params.place = scope.search.place, params["place.op"] = scope.selectedDrawingType.toLowerCase());
savedLocationService.saveLocation(scope.savedLocation, params).then(function(response) {
angular.isDefined(response.data.error) ? scope.error = response.data.error : (scope.$dismiss(), scope.error = !1)
}, function() {
scope.error = "please try again later"
})
}
}, scope.cancel = function() {
scope.$dismiss()
}
}
}
}), angular.module("voyager.search").controller("SavedLocationsCtrl", function($scope, $location, savedLocationService, authService) {
function _loadSavedLocations() {
savedLocationService.getSavedLocations().then(function(savedLocations) {
var permissions, global = [],
personal = [],
all = "_EVERYONE";
$.each(savedLocations, function(index, saved) {
if (permissions = _.indexBy(saved.share), angular.isDefined(permissions[all]) ? global.push(saved) : personal.push(saved), 6 === global.length && 6 === personal.length) return !1
}), vm.savedLocations = global, vm.personalSavedLocations = personal
})
}
var vm = this;
_loadSavedLocations(), authService.addObserver(_loadSavedLocations), savedLocationService.addObserver(_loadSavedLocations), vm.applySavedLocation = function(saved) {
savedLocationService.applySavedLocation(saved, $scope)
}, vm.deleteLocation = function(id) {
savedLocationService.deleteLocation(id)
}, vm.search = function() {
return _.isEmpty(vm.savedTerm) ? void _loadSavedLocations() : void savedLocationService.searchByTerm(vm.savedTerm).then(function(savedLocations) {
var permissions, personal = [],
all = "_EVERYONE";
$.each(savedLocations, function(index, saved) {
permissions = _.indexBy(saved.share), angular.isDefined(permissions[all]) || personal.push(saved)
}), vm.personalSavedLocations = personal
})
}, vm.dragLocationControlListeners = {
enabled: !0,
accept: function() {
return vm.dragLocationControlListeners.enabled
},
orderChanged: function(eventObj) {
var list = vm.personalSavedLocations,
index = eventObj.dest.index,
beforeId = null,
afterId = null;
0 !== index && (beforeId = list[index - 1].id), index + 1 !== list.length && (afterId = list[index + 1].id), vm.dragLocationControlListeners.enabled = !1, savedLocationService.order(list[index].id, beforeId, afterId).then(function() {
vm.dragLocationControlListeners.enabled = !0
})
}
}, $scope.$on("$destroy", function() {
authService.removeObserver(_loadSavedLocations), savedLocationService.removeObserver(_loadSavedLocations)
})
}), angular.module("voyager.search").factory("recentSearchService", function(localStorageService, $location, filterService, mapUtil, sugar) {
"use strict";
var RECENT_ITEM_NAME = "recent-items",
observers = [],
_notify = function(itemMap) {
observers.forEach(function(entry) {
entry(itemMap)
})
},
_getItems = function() {
var items = localStorageService.get(RECENT_ITEM_NAME);
return items ? items : []
},
_formatQuery = function(item) {
var query = [];
for (var i in item) "saved" !== i && i.indexOf("$") === -1 && i.indexOf("display") === -1 && query.push(i + "=" + item[i]);
return query.join("&")
};
return {
addItem: function(item) {
var itemMap = _getItems(),
duplicate = !1;
if (!(_.isEmpty(item.q) && _.isEmpty(item.query) && _.isEmpty(item.place) && _.isEmpty(item.bbox))) {
if (itemMap.length)
for (var i = 0, t = itemMap.length; i < t; i++)
if (void 0 === item.q) {
if (angular.isDefined(item.place) && itemMap[i].place === item.place || angular.isDefined(item.bbox) && itemMap[i].bbox === item.bbox) {
duplicate = !0, itemMap[i] = item;
break
}
} else if (item.q === itemMap[i].q) {
if (angular.isDefined(item.place) && itemMap[i].place === item.place || angular.isDefined(item.bbox) && itemMap[i].bbox === item.bbox) {
duplicate = !0, itemMap[i] = item;
break
}
if (!angular.isDefined(item.place) && !angular.isDefined(item.bbox)) {
duplicate = !0, itemMap[i] = item;
break
}
} else if (itemMap[i].query && (itemMap[i].query.indexOf(item.q) !== -1 || itemMap[i].query.indexOf(encodeURIComponent(item.q)) !== -1) && item.q && item.q.indexOf("!func") !== -1) {
duplicate = !0;
break
}
duplicate || (itemMap.length > 5 && itemMap.pop(), itemMap.splice(0, 0, item)), localStorageService.add(RECENT_ITEM_NAME, itemMap), _notify(itemMap)
}
},
getItems: function() {
return _getItems()
},
deleteSearch: function(inx) {
var itemMap = _getItems();
itemMap.splice(inx, 1), localStorageService.add(RECENT_ITEM_NAME, itemMap), _notify(itemMap)
},
addObserver: function(observer) {
observers.push(observer)
},
removeObserver: function(observer) {
observers = _.without(observers, function(item) {
return item === observer
})
},
changeSaveStatus: function(id) {
for (var itemMap = _getItems(), i = 0, t = itemMap.length; i < t; i++)
if (itemMap[i].id === id) {
itemMap[i].saved = !itemMap[i].saved;
break
}
localStorageService.add(RECENT_ITEM_NAME, itemMap), _notify(itemMap)
},
updateSearchID: function(searchItem, data) {
for (var isFound, itemMap = _getItems(), i = 0, totalItemMapLength = itemMap.length; i < totalItemMapLength; i++) {
isFound = !0;
for (var attr in searchItem) attr.indexOf("$") !== -1 || attr.indexOf("display") !== -1 || "fq" === attr || searchItem[attr] === itemMap[i][attr] || (isFound = !1);
if (isFound) break
}
isFound && (itemMap[i].id = data.id, itemMap[i].title = data.title, itemMap[i].saved = !0, localStorageService.add(RECENT_ITEM_NAME, itemMap), _notify(itemMap))
},
syncWithSavedSearches: function(savedSearches) {
for (var savedSearchInx, found, itemMap = _getItems(), i = 0, totalItemMapLength = itemMap.length, savedSearchLength = savedSearches.length; i < totalItemMapLength; i++) {
for (found = !1, savedSearchInx = 0; savedSearchInx < savedSearchLength; savedSearchInx++)
if (itemMap[i].id === savedSearches[savedSearchInx].id) {
found = !0;
break
}
itemMap[i].saved = !!found
}
localStorageService.add(RECENT_ITEM_NAME, itemMap)
},
getItemsWithFormatBBox: function() {
for (var itemMap = _getItems(), i = 0, totalItemMapLength = itemMap.length; i < totalItemMapLength; i++) mapUtil.isBbox(itemMap[i].place) ? itemMap[i].displayBBox = sugar.formatBBox(itemMap[i].place) : _.isEmpty(itemMap[i].place) || (itemMap[i].displayBBox = mapUtil.formatWktForDisplay(itemMap[i].place)), itemMap[i].displayPlaceOP = itemMap[i]["place.op"];
return itemMap
},
applyRecentSearch: function(item, $scope) {
var query = "";
query = _.isEmpty(item.query) ? _formatQuery(item) : item.query, $scope.$emit("clearSearchEvent"), $location.path("search").search(query).search("recent", "true"), filterService.applyFromUrl($location.search()).then(function() {
$scope.$emit("filterEvent", {})
})
}
}
}), angular.module("voyager.search").controller("RecentSearchCtrl", function($scope, recentSearchService, savedSearchService, $timeout, authService) {
"use strict";
function _init() {
savedSearchService.getSavedSearches().then(function(respond) {
recentSearchService.syncWithSavedSearches(respond), _getRecentSearch()
}), recentSearchService.addObserver(_getRecentSearch), savedSearchService.addObserver(_changeSearchStatus)
}
function _getRecentSearch() {
$timeout(function() {
$scope.recentSearches = recentSearchService.getItemsWithFormatBBox()
}, 10)
}
function _toggleSaveStatus(item) {
item.saved ? savedSearchService.deleteSearch(item.id) : savedSearchService.showSaveSearchDialog(item)
}
function _changeSearchStatus(id) {
recentSearchService.changeSaveStatus(id), _getRecentSearch()
}
function _deleteSearchByIndex(id) {
recentSearchService.deleteSearch(id)
}
function _openSearchModal() {
savedSearchService.showSearchModal("recent")
}
function _applyRecentSearch(searchItem) {
recentSearchService.applyRecentSearch(searchItem, $scope), "function" == typeof $scope.cancel && $scope.cancel()
}
$scope.toggleSave = _toggleSaveStatus, $scope.deleteSearch = _deleteSearchByIndex, $scope.openSearchModal = _openSearchModal, $scope.applyRecentSearch = _applyRecentSearch, $scope.hasPermission = function(permission) {
return authService.hasPermission(permission)
}, _init(), $scope.$on("$destroy", function() {
recentSearchService.removeObserver(_getRecentSearch), savedSearchService.removeObserver(_changeSearchStatus)
})
}), angular.module("voyager.search").controller("BaseUpdateCtrl", function($scope, $uibModalInstance, tagService, resultTotalCount, $timeout, usSpinnerService, config) {
var _loading = !1;
$scope.hasError = function() {
return angular.isDefined($scope.error)
}, $scope.resultTotalCount = resultTotalCount, $scope.overLimit = resultTotalCount > config.bulkLimit, $scope.overLimit && ($scope.error = "This operation is limited to " + config.bulkLimit + " records. Please refine your search."), $scope.validate = function() {
return !0
}, $scope.save = function() {
$scope.validate() && (delete $scope.error, _loading = !0, usSpinnerService.spin("task-spinner"), $scope.doSaveAll())
}, $scope.handleEnter = function(ev) {
13 !== ev.which || _loading || $scope.save()
}, $scope.handleResponse = function(response) {
_loading = !1, usSpinnerService.stop("task-spinner"), angular.isUndefined(response.error) ? ($scope.successMessage = response.documents + " items were updated.", $timeout(function() {
$scope.done()
}, 2e3)) : $scope.error = "Sorry, please try again later"
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel"), $scope.successMessage = !1
}, $scope.done = function() {
$uibModalInstance.close()
}
}), angular.module("voyager.search").controller("FlagAllCtrl", function($scope, $uibModalInstance, tagService, resultData, $controller) {
function _init() {
tagService.fetchFlags().then(function(tags) {
$.merge(_tags, tags)
})
}
$controller("BaseUpdateCtrl", {
$scope: $scope,
resultTotalCount: resultData.totalItemCount,
$uibModalInstance: $uibModalInstance
});
var _tags = [];
$scope.select2Options = {
tags: _tags
}, _init(), $scope.validate = function() {
return !_.isEmpty($scope.flag) || ($scope.error = "Enter a flag.", !1)
}, $scope.doSaveAll = function() {
tagService.saveBulkField($scope.flag, "tag_flags", resultData.docId).then($scope.handleResponse)
}
}), angular.module("voyager.search").controller("EditAllCtrl", function($scope, $uibModalInstance, tagService, configService, resultTotalCount, $controller, config, converter) {
function _init() {
tagService.fetchTags().then(function(tags) {
$.merge(_tags, tags)
}), _getFieldList()
}
function _getFieldList() {
$scope.fieldList = configService.getEditable()
}
$controller("BaseUpdateCtrl", {
$scope: $scope,
resultTotalCount: resultTotalCount,
$uibModalInstance: $uibModalInstance
});
var _tags = [];
$scope.select2Options = {
multiple: !0,
simple_tags: !0
}, _.isEmpty(config.homepage.editValues) ? $scope.select2Options.tags = _tags : $scope.select2Options.data = converter.toIdTextArray(config.homepage.editValues), _init(), $scope.validate = function() {
return !_.isEmpty($scope.fieldText) && !_.isEmpty($scope.selectedField) || ($scope.error = "Please select a field and enter a value.", !1)
}, $scope.doSaveAll = function() {
tagService.saveBulkField($scope.fieldText, $scope.selectedField).then($scope.handleResponse)
}
}), angular.module("voyager.search").controller("RemoveAllFlagsCtrl", function($scope, $uibModalInstance, tagService, resultData, $timeout, usSpinnerService, config, $controller) {
$controller("BaseUpdateCtrl", {
$scope: $scope,
resultTotalCount: resultData.totalItemCount,
$uibModalInstance: $uibModalInstance
}), $scope.doSaveAll = function() {
tagService.removeBulkField("tag_flags").then($scope.handleResponse)
}
}), angular.module("voyager.filters", ["voyager.util", "ui-rangeSlider", "voyager.config", "blockUI"]).config(function(blockUIConfig) {
blockUIConfig.delay = 300, blockUIConfig.requestFilter = function(config) {
return config.url.indexOf("block=false") === -1 && ((!config.params || config.params.block !== !1) && (config.url.indexOf("api/rest") === -1 && void 0))
}
}), angular.module("voyager.filters").factory("catalogService", function(config, $http, $location, $q) {
function _fetch() {
return _fetched ? $q.when(_cachedCatalogs) : $http.get(config.root + "api/rest/index/config/federation.json").then(function(res) {
var catalogs = res.data.servers;
return catalogs.forEach(function(catalog) {
angular.isDefined(catalog.url) && (_catalogLookup[catalog.url.replace("http://", "").replace("https://", "")] = catalog)
}), _cachedCatalogs = res.data.servers, _fetched = !0, res.data.servers
})
}
function _loadRemoteLocations() {
return "/search" === $location.path() && (angular.isDefined($location.search().shards) || config.settings.data.queryAllCatalogs) ? _fetch().then(function(catalogs) {
var catalogPromises = [];
return _.each(catalogs, function(catalog) {
if (angular.isDefined(catalog.url)) {
var url = catalog.url + config.require.locations,
catalogPromise = $http.get(url, {
withCredentials: !1
}).then(function(response) {
_.extend(config.locations.data.VALUE.location, response.data.VALUE.location);
});
catalogPromises.push(catalogPromise)
}
}), $q.all(catalogPromises).then(function(res) {
return res
}, function(error) {
return error
})
}) : $q.when({})
}
function _lookup(shard) {
var catalog = shard.replace("http://", "").replace("https://", "").toLowerCase(),
pos = catalog.indexOf("solr");
return pos > -1 && (catalog = catalog.substring(0, pos)), _catalogLookup[catalog]
}
function _isRemote(shard) {
return angular.isDefined(_lookup(shard))
}
function _removeInvalid(shards) {
var arr = shards.split(","),
valid = arr.filter(function(shard) {
return _.findIndex(_cachedCatalogs, {
id: shard
}) !== -1
});
return valid.join(",")
}
var _catalogLookup = {},
_cachedCatalogs = [],
_fetched = !1;
return {
fetch: _fetch,
loadRemoteLocations: _loadRemoteLocations,
isRemote: _isRemote,
removeInvalid: _removeInvalid,
lookup: _lookup
}
}), angular.module("voyager.filters").factory("statsService", function(config, $http, configService, translateService, $q, solrGrunt, sugar) {
function _getStatsParams() {
var configFilters = configService.getFilters(),
facetParams = "";
return $.each(configFilters, function(index, filter) {
"STATS" === filter.style && (facetParams += "&stats.field=" + filter.field)
}), facetParams
}
function _hasStatsParam() {
var configFilters = configService.getFilters(),
hasStats = !1;
return $.each(configFilters, function(index, filter) {
if ("STATS" === filter.style) return hasStats = !0, !1
}), hasStats
}
function _getQueryString(params, filterParams, bboxParams) {
var solrParams = solrGrunt.getSolrParams(params);
delete solrParams.fq, solrParams.q = solrGrunt.getInput(solrParams.q);
var queryString = config.root + "solr/v0/select?rows=0&stats=true" + _getStatsParams();
return queryString += "&" + sugar.toQueryString(solrParams), queryString += filterParams, queryString += bboxParams, angular.isDefined(configService.getConfigId()) && (queryString += "&voyager.config.id=" + configService.getConfigId()), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _setStats(params, filterParams, bboxParams) {
var deferred = $q.defer();
return _hasStatsParam() ? $http.jsonp(_getQueryString(params, filterParams, bboxParams)).success(function(data) {
_stats = data.stats.stats_fields, deferred.resolve(_stats)
}) : deferred.resolve(null), deferred.promise
}
function _parseInt(val) {
var ret = 0;
return angular.isDefined(val) && (ret = parseInt(val)), ret
}
var _stats = {},
_statsFields = {};
return {
updateStats: function(params, filterParams, bboxParams, filters) {
_setStats(params, filterParams, bboxParams).then(function(stats) {
null !== stats && $.each(filters, function(index, filter) {
"STATS" === filter.style && $.each(filter.values, function(i, facet) {
facet.stddev = _parseInt(stats[filter.field].stddev), facet.sum = _parseInt(stats[filter.field].sum), facet.mean = _parseInt(stats[filter.field].mean)
})
})
})
},
setStatsFields: function(statsFields) {
_statsFields = statsFields
}
}
}), angular.module("voyager.filters").factory("treeService", function(config, $http, configService, $q, solrGrunt, sugar, facetService, catalogService) {
function _isHierarchy(filter) {
return "HIERARCHY" === filter.style || "hierarchy" === filter.stype
}
function _getTreeParams() {
var configFilters = configService.getFilters(),
facetParams = "";
return $.each(configFilters, function(index, filter) {
_isHierarchy(filter) && (facetParams += "&facet.field=" + filter.field + "&f." + filter.field + ".facet.mincount=1&f." + filter.field + ".facet.prefix=%s/", _trees[filter.field] = {})
}), facetParams
}
function _hasTreeParam() {
var configFilters = configService.getFilters(),
hasTree = !1;
return $.each(configFilters, function(index, filter) {
if (_isHierarchy(filter)) return hasTree = !0, !1
}), hasTree
}
function _getQueryString(params, filterParams, bboxParams) {
var solrParams = solrGrunt.getSolrParams(params);
angular.isDefined(solrParams.shards) && (solrParams.shards = catalogService.removeInvalid(solrParams.shards)), delete solrParams.fq, solrParams.q = solrGrunt.getInput(solrParams.q);
var queryString = config.root + "solr/v0/select?rows=0&block=false&facet=true" + _getTreeParams();
return queryString += "&" + sugar.toQueryString(solrParams), queryString += filterParams, queryString += bboxParams, angular.isDefined(configService.getConfigId()) && (queryString += "&voyager.config.id=" + configService.getConfigId()), queryString += "&wt=json&json.wrf=JSON_CALLBACK", queryString += "&rand=" + Math.random()
}
function _getSelectedLevel(params) {
var paths, level = 0;
if (params.fq && (paths = _.filter(sugar.toArray(params.fq), function(f) {
return f.indexOf("path_path") > -1
}), paths.length > 0)) {
var path = paths[0];
path = path.replace(/\\/g, ""), level = path.split("/").length
}
return level
}
function _queryLevels(queryString, level) {
var deferred = $q.defer(),
promises = [],
level1 = "1",
level2 = "2";
level > 0 && (level1 = level.toString(), level2 = (level + 1).toString());
var queryLevel = queryString.replace(/%s/g, level1),
queryLevel2 = queryString.replace(/%s/g, level2),
queries = [queryLevel, queryLevel2];
return $.each(queries, function(index, query) {
promises.push($http.jsonp(query))
}), $q.all(promises).then(function(response) {
$.each(_trees, function(name) {
var raw = response[0].data.facet_counts.facet_fields[name],
tree = facetService.buildFacets(raw, {
field: name,
style: "HIERARCHY"
}, {});
raw = response[1].data.facet_counts.facet_fields[name];
var next = facetService.buildFacets(raw, {
field: name,
style: "HIERARCHY"
}, {});
$.merge(tree, next), _trees[name] = tree
}), deferred.resolve(_trees)
}, function() {
console.log("failed"), deferred.reject()
}), deferred.promise
}
function _queryNodeLevels(queryString, name, level, path) {
var deferred = $q.defer(),
promises = [],
level1 = level.toString() + "/" + path,
level2 = (level + 1).toString() + "/" + path,
queryLevel = queryString.replace(/%s/g, level1),
queryLevel2 = queryString.replace(/%s/g, level2),
queries = [queryLevel, queryLevel2];
return $.each(queries, function(index, query) {
promises.push($http.jsonp(query))
}), $q.all(promises).then(function(response) {
var raw = response[0].data.facet_counts.facet_fields[name],
tree = facetService.buildFacets(raw, {
field: name,
style: "HIERARCHY"
}, {});
raw = response[1].data.facet_counts.facet_fields[name];
var next = facetService.buildFacets(raw, {
field: name,
style: "HIERARCHY"
}, {});
$.merge(tree, next), deferred.resolve(tree)
}, function() {
console.log("failed"), deferred.reject()
}), deferred.promise
}
function _setTree(params, filterParams, bboxParams) {
_trees = {};
var deferred = $q.defer();
if (_hasTreeParam()) {
var level = _getSelectedLevel(params),
queryString = _getQueryString(params, filterParams, bboxParams);
_queryLevels(queryString, level).then(function() {
deferred.resolve()
})
} else deferred.resolve(null);
return deferred.promise
}
function _addChild(folder, nodes, collapsed, field) {
var child = nodes[folder.path];
angular.isUndefined(child) && (child = {
level: folder.level,
root: folder.node[0],
path: folder.path,
children: [],
childMap: {},
mime: "application/vnd.voyager.folder",
id: folder.path,
collapsed: !0,
field: field
}, nodes[child.path] = child), angular.isUndefined(nodes[folder.parentPath].childMap[child.path]) && (nodes[folder.parentPath].children.push(child), nodes[folder.parentPath].childMap[child.path] = child), nodes[folder.parentPath].collapsed === !0 && (nodes[folder.parentPath].collapsed = collapsed)
}
function _getFolder(row, index) {
var folder = {};
return folder.level = row[0], folder.node = row.slice(1, index + 1), folder.name = folder.node[folder.node.length - 1], folder.path = folder.node.join("/"), folder.parent = row.slice(1, index), folder.parentPath = folder.parent.join("/"), folder
}
function _getPathInfo(path) {
var pathInfo = {};
return pathInfo.value = path.value.replace(/\\/g, "/"), pathInfo.name = path.name.replace(/\\/g, "/"), pathInfo.folders = pathInfo.name.split("/"), pathInfo.level = pathInfo.folders.length - 1, pathInfo.display = pathInfo.value.substring(pathInfo.value.lastIndexOf("/") + 1, pathInfo.value.length), pathInfo.path = pathInfo.name.substring(pathInfo.name.indexOf("/") + 1, pathInfo.name.length), pathInfo.count = path.count, pathInfo
}
function _getNode(pathInfo, selected, field) {
var node = {
level: pathInfo.level,
root: pathInfo.folders[1],
path: pathInfo.path,
children: [],
display: pathInfo.display,
childMap: {},
mime: "application/vnd.voyager.folder",
id: pathInfo.path,
collapsed: !0,
field: field
};
return angular.isDefined(selected[node.path]) && (node.selected = !0), node
}
function _getParentNode(folder, field, pathInfo) {
var parentNode = {
level: folder.parent.length,
root: folder.parent[0],
path: folder.parentPath,
children: [],
childMap: {},
mime: "application/vnd.voyager.folder",
id: folder.parentPath,
collapsed: !0,
field: field
},
name = parentNode.path;
return name.indexOf("/") !== -1 && (name = name.split("/"), name = name[name.length - 1]), parentNode.display = name + " (" + pathInfo.count + ")", parentNode
}
function _buildStructure(pathList, selected, field) {
var pathInfo, nodes = {};
return $.each(pathList, function(index, path) {
pathInfo = _getPathInfo(path);
var node = _getNode(pathInfo, selected, field);
nodes[pathInfo.path] = node;
for (var i = pathInfo.folders.length - 1; i > 1; i--) {
var folder = _getFolder(pathInfo.folders, i);
if (angular.isDefined(nodes[folder.parentPath])) _addChild(folder, nodes, !node.selected, field);
else {
var parentNode = _getParentNode(folder, field, pathInfo);
nodes[parentNode.path] = parentNode, angular.isDefined(selected[parentNode.path]) && (parentNode.selected = !0), parentNode.children.push(nodes[folder.path]), parentNode.childMap[folder.path] = nodes[folder.path]
}
}
}), nodes
}
function _getSelected(filters) {
var selected = {};
return filters = sugar.toArray(filters), angular.isDefined(filters) && $.each(filters, function(key, value) {
if (value.indexOf("path_path") !== -1) {
var path = value.split(":")[1].replace(/\\/g, "");
selected[path] = path
}
}), selected
}
function _getNodesToExpand(name) {
var path = name.split("/"),
key = null,
expanded = [];
return $.each(path, function(index, node) {
key = null === key ? node : key + "/" + node, expanded.push(key)
}), expanded
}
var _tree = {},
_fields = {},
_trees = {};
return {
updateTree: function(params, filterParams, bboxParams, filters) {
var self = this;
_setTree(params, filterParams, bboxParams).then(function() {
_.isEmpty(_trees) || $.each(filters, function(index, filter) {
if (_isHierarchy(filter)) {
var structure = _buildStructure(_trees[filter.field], _getSelected(params.fq), filter.field),
expanded = [];
$.each(structure, function(name, node) {
node.selected && !node.loaded && (expanded = expanded.concat(_getNodesToExpand(name)), self.loadNode(params, filterParams, bboxParams, filters, node))
}), $.each(expanded, function(index, node) {
structure[node].collapsed = !1
});
var tree = _.where(structure, {
level: 1
});
void 0 === filter.style && (filter.style = "HIERARCHY"), filter.values = [{
tree: tree,
filter: filter.field,
style: filter.style
}]
}
})
})
},
loadNode: function(params, filterParams, bboxParams, filters, node) {
node.loaded = !0;
var queryString = _getQueryString(params, filterParams, bboxParams);
_queryNodeLevels(queryString, node.field, node.level + 1, node.path).then(function(data) {
var structure = _buildStructure(data, _getSelected(params.fq), node.field),
children = _.where(structure, {
level: node.level + 1
});
node.children = children
})
},
setTreeFields: function(fields) {
_fields = fields
},
getTree: function(filter) {
return _tree[filter]
}
}
}), angular.module("voyager.filters").factory("complexFilterService", function() {
function _createComplexFilter(filterField, filterValue, filterValues) {
var complexFilter = {
field: filterField,
value: filterValue,
values: [],
style: _complexFilterStyle
};
return _updateComplexFilter(complexFilter, filterValue, filterValues)
}
function _updateComplexFilter(filter, filterValue, filterValues) {
return filterValue && (filter.value = filterValue), filterValues && (filter.values = filterValues), filter
}
function _calculateIsSelected(facet, selectedFilters) {
var isSelected = !0;
return $.each(facet.name, function(index, facetName) {
var facetFilter = facet.filter[index];
isSelected = isSelected && !!selectedFilters[facetName] && selectedFilters[facetName].filter === facetFilter
}), isSelected
}
var _complexFilterStyle = "COMPLEX",
_discoveryStatusFilter_Field = "discoveryStatus",
_discoveryStatusFilter_Value = "Discovery Status",
_discoveryStatusFilter_Values = [{
name: ["(SCAN SCAN_FULL)", "false"],
value: "First Pass: Scan Complete",
filter: ["_index_reason", "__to_extract"],
humanized: "1st Pass: Scan Complete",
count: 0,
hasCount: !1,
display: "1st Pass: Scan Complete",
style: "COMPLEX"
}, {
name: ["true"],
value: "Second Pass: Read Pending",
filter: ["__to_extract"],
humanized: "nd Pass: Read Pending",
count: 0,
hasCount: !1,
display: "2nd Pass: Read Pending",
style: "COMPLEX"
}, {
name: ["CHECKOUT", "false"],
value: "Second Pass: Read Complete",
filter: ["_index_reason", "__to_extract"],
humanized: "2nd Pass: Read Complete",
count: 0,
hasCount: !1,
display: "2nd Pass: Read Complete",
style: "COMPLEX"
}];
return {
calculateIsSelected: function(facet, selectedFilters) {
return _calculateIsSelected(facet, selectedFilters)
},
createDiscoveryStatusFilter: function(discoveryStatusFilter, facetTypes) {
discoveryStatusFilter ? _updateComplexFilter(discoveryStatusFilter, _discoveryStatusFilter_Value, _discoveryStatusFilter_Values) : (discoveryStatusFilter = _createComplexFilter(_discoveryStatusFilter_Field, _discoveryStatusFilter_Value, _discoveryStatusFilter_Values), facetTypes.unshift(discoveryStatusFilter))
}
}
}), angular.module("voyager.filters").directive("vsFilter", function($compile) {
function _link(scope, element) {
var template = "";
template = "date" === scope.facet.stype ? date : "CHECK" === scope.facet.style ? checkbox : "RANGE" === scope.facet.style ? scope.facet.units ? unitslider : nounitslider : "STATS" === scope.facet.style ? nounitslider + stats : "HIERARCHY" === scope.facet.style ? tree : button, element.html(template).show(), $compile(element.contents())(scope)
}
function _controller($scope, config) {
$scope.imagePrefix = config.root + "vres/mime/icon/"
}
var button = '<a href="javascript:;" ng-click="filterResults(facet)" class="underline" ng-class="facet.isSelected ? \'active\':\'\'">';
button += '<span class="text">{{facet.display}}<span class="facet_count" ng-hide="facet.hasCount == false"> ({{facet.count}} filter items)</span></span> <span ng-show="facet.isSelected" class="icon-x"></span>', button += "</a>";
var checkbox = '<div class="checkbox">';
checkbox += '<label><input type="checkbox" ng-click="filterResults(facet)" ng-disabled="facet.disabled" ng-checked="facet.isSelected">{{facet.display}} ', checkbox += '<span class="facet_count" ng-hide="facet.hasCount == false">({{facet.count}})</span>', checkbox += "</label>", checkbox += '<span title="Not Available" class="facet_error icon-error" ng-show="facet.hasError == true">&nbsp;</span>', checkbox += '<span class="fa fa-star-o pull-right checkbox-only" ng-hide="facet.hasCount == false" ng-click="filterOnly(facet)" title="Only This"></span>', checkbox += "</div>";
var slider = '<div class="ui_slider_wrap">';
slider += '<div range-slider id="slider" min="facet.min" max="facet.max" model-min="facet.model[0]" model-max="facet.model[1]" step="1"></div></div>', slider += '<div class="slider_range"><span class="min pull-left" ng-bind="facet.min"></span>', slider += '<span class="min pull-right" ng-bind="facet.max | number"></span></div>', slider += '<button class="btn btn-xs btn-primary" ng-click="addRangeFilter(facet)">Apply filter</button></form>', slider += "</div>";
var nounitslider = '<div class="slider_wrap"><form class="form-inline" role="form"><div class="form-group">';
nounitslider += '<input class="form-control input-xs semi" type="text" ng-model="facet.model[0]" ng-init="facet.model[0] = (facet.model[0] == undefined) ? facet.min : facet.model[0]">', nounitslider += '<span class="dash"></span>', nounitslider += '<input class="form-control input-xs semi" type="text" ng-model="facet.model[1]" ng-init="facet.model[1] = (facet.model[1] == undefined) ? facet.max : facet.model[1]"></div>', nounitslider += slider;
var unitslider = '<div class="slider_wrap"><form class="form-inline" role="form"><div class="form-group">';
unitslider += '<input class="form-control input-xs semi" type="text" style="width:84px; padding:6px;" ng-model="facet.model[0]" ng-init="facet.model[0] = (facet.model[0] == undefined) ? facet.min : facet.model[0]">', unitslider += '<span class="dash thin-dash"></span>', unitslider += '<div class="input-group">', unitslider += '<input class="form-control input-xs semi" type="text" ng-model="facet.model[1]" ng-init="facet.model[1] = (facet.model[1] == undefined) ? facet.max : facet.model[1]">', unitslider += '<span class="input-group-addon" style="width:0px; padding-left:0px; padding-right:0px; border:none;"></span>', unitslider += '<select class="form-control" ng-model="facet.selectedUnit" ng-change="facet.convert(facet)" ng-options="unit for unit in facet.units"></select>', unitslider += "</div>", unitslider += slider;
var stats = '<div class="row stats_wrap"><ul><li><div class="pull-left col-xs-4">Total</div>{{facet.sum | number}}</li><li><div class="pull-left col-xs-4">Average</div>{{facet.mean | number}}</li><li><div class="pull-left col-xs-4">Deviation</div>{{facet.stddev | number}}</li></ul></div>',
tree = '<div><ul class="folder_tree" frang-tree>';
tree += '<li frang-tree-repeat="node in facet.tree">', tree += "<div ng-class=\"node.children && node.children.length > 0 ? 'folderNode' : 'leaf'\"><span class=\"icon\"", tree += 'ng-class="{collapsed: node.collapsed, expanded: !node.collapsed}"', tree += 'ng-show="node.children && node.children.length > 0"', tree += 'ng-click="loadNode(node)"></span>', tree += "<i class=\"fa\" ng-class=\"{'fa-folder': node.collapsed, 'fa-folder-open': !node.collapsed}\"></i>", tree += '<span class="label" ng-class="{folder: node.children && node.children.length > 0}">', tree += '<a href="javascript:;" ng-click="addFolderFilter(node)" ng-class="{selected:node.id === doc.id}">{{node.display}}</a>', tree += "</span>", tree += "</div>", tree += '<ul class="noindent" ng-if="!node.collapsed && node.children && node.children.length > 0"', tree += 'frang-tree-insert-children="node.children"></ul>', tree += "</li>", tree += "</ul></div>";
var date = '<div class="slider_wrap"><form class="form-inline" role="form"><div class="form-group">';
return date += '<label class="semi">Date</label><br />', date += '<input type="text" placeholder="yyyy-mm-dd" class="form-control input-xs semi min_date_picker_input {{facet.minError}}" uib-datepicker-popup="yyyy-MM-dd" is-open="facet.isMinOpened" ng-click="openMinDatePicker($event, facet)" datepicker-options="{formatYear: \'yy\', startingDay: 1, showWeeks: false, showButtonBar: false}" ng-model="facet.dateModel[0]" close-text="Close" ng-required="true" />', date += '<span class="dash"></span>', date += '<input type="text" placeholder="yyyy-mm-dd" class="form-control input-xs semi max_date_picker_input {{facet.maxError}}" uib-datepicker-popup="yyyy-MM-dd" is-open="facet.isMaxOpened" ng-focus="openMaxDatePicker($event, facet)" datepicker-options="{formatYear: \'yy\', startingDay: 1, showWeeks: false, showButtonBar: false}" ng-model="facet.dateModel[1]" close-text="Close" ng-required="true" />', date += '</div><button class="btn btn-xs btn-primary" ng-click="addCalendarFilter(facet)">Apply filter</button></form>', date += "</div>", {
restrict: "A",
replace: !0,
link: _link,
controller: _controller
}
}), angular.module("voyager.filters").directive("vsFilters", function($document, $window) {
return {
restrict: "A",
link: function(scope, element) {
function onDestroy() {
angular.element($window).unbind("scroll", _windowScroll)
}
var lastScroll = 0,
uptick = 0,
_windowScroll = function() {
if (!element.is(":hidden")) {
var scrollTop = $document.scrollTop(),
winHeight = $window.innerHeight,
filterHeight = element.outerHeight();
if ($(".result_container .list").outerHeight() < filterHeight && $(".result_container .list").css("min-height", filterHeight + "px"), scrollTop < 10) return void element.css("margin-top", 0);
if (filterHeight > winHeight) {
var actualHeight, marginTop;
actualHeight = scrollTop + winHeight + parseInt(element.css("padding-bottom")), marginTop = filterHeight > actualHeight ? -scrollTop : winHeight - filterHeight, lastScroll > scrollTop && marginTop < 0 ? uptick += 50 : uptick = 0, marginTop += uptick, marginTop < 50 && (marginTop > 0 && (marginTop = 0), element.css("margin-top", marginTop + "px"))
}
lastScroll = scrollTop, scope.$apply()
}
};
angular.element($window).bind("scroll", _windowScroll), scope.$on("$destroy", onDestroy);
var padding, $banner = $("#top-banner");
$(".content-header-padding").length ? (padding = 210, $banner.length && (padding += $banner.height()), element.css("padding-top", padding + "px")) : $banner.length && (padding = element.css("padding-top"), padding = padding.replace("px", ""), padding = parseInt(padding), padding += $banner.height(), element.css("padding-top", padding + "px"))
}
}
}), angular.module("voyager.filters").controller("FacetsCtrl", function($scope, $uibModalInstance, selectedFilter, updateFilters, facetService, $location, translateService, usSpinnerService) {
$scope.selectedFilter = translateService.getFieldName(selectedFilter.field), $scope.updateFilters = updateFilters, $scope.predicate = "-count", facetService.doLookup(selectedFilter, $location.search(), function(facets) {
if (facets.length > 0 && "CHECK" === facets[0].style)
for (var idx = 0; idx < facets.length; idx++)
for (var i = 0; i < selectedFilter.values.length; i++)
if (facets[idx].name === selectedFilter.values[i].name) {
facets[idx].isSelected = selectedFilter.values[i].isSelected;
break
}
$scope.facets = facets, usSpinnerService.stop("facets-spinner")
}), $scope.filterResults = function(facet, evt) {
"CHECK" !== facet.style ? $uibModalInstance.close(facet) : (facet.checked = evt.currentTarget.checked, $scope.updateFilters(facet))
}, $scope.cancel = function() {
$uibModalInstance.dismiss("cancel")
}
}), angular.module("voyager.filters").factory("calendarFilter", function() {
function _styleDate(num) {
return num < 10 ? "0" + num : num
}
function _validateDate(date, facet, formattedDate) {
return "" === date ? (facet.minError = "error", !0) : isNaN(formattedDate.getTime()) ? (facet.minError = "error", !0) : (facet.minError = "", !1)
}
return {
decorate: function(facet) {
var calendar = facet.dateModel,
minDate = new Date(calendar[0]),
maxDate = new Date(calendar[1]),
seeError = _validateDate(calendar[0], facet, minDate);
if (seeError ? _validateDate(calendar[1], facet, maxDate) : seeError = _validateDate(calendar[1], facet, maxDate), !seeError) {
var formatMinDate = minDate.getFullYear() + "-" + _styleDate(minDate.getMonth() + 1) + "-" + _styleDate(minDate.getDate()),
formatMaxDate = maxDate.getFullYear() + "-" + _styleDate(maxDate.getMonth() + 1) + "-" + _styleDate(maxDate.getDate());
if (!(formatMinDate > formatMaxDate)) return facet.humanize = facet.display + ": [" + formatMinDate + "T07:00:00Z TO " + formatMaxDate + "T07:00:00Z]", facet.model[0] = formatMinDate + "T07:00:00Z", facet.model[1] = formatMaxDate + "T07:00:00Z", facet;
facet.maxError = "error", facet.minError = "error"
}
return !1
}
}
}), angular.module("voyager.filters").controller("FiltersCtrl", function($scope, filterService, $location, $uibModal, $timeout, statsService, treeService, configService, filterQuery, translateService, filterStyle, calendarFilter, $document, catalogService) {
function _appendIfMissing(filter, selectedFacet) {
if (angular.isDefined(filter)) {
var facetsMap = _.indexBy(filter.values, "name");
if (0 === selectedFacet.name.indexOf("(")) {
var facets = selectedFacet.name.replace(" )", ")").replace(")", "").replace("(", "").split(" ");
facets.forEach(function(facet) {
var facetObj = angular.copy(selectedFacet);
facetObj.name = facet, facetObj.pretty = facet, facetObj.humanized = facet, _appendIfMissing(filter, facetObj)
})
} else angular.isUndefined(facetsMap[selectedFacet.name]) && filter.values.push({
name: selectedFacet.name,
display: selectedFacet.humanized,
style: selectedFacet.style,
filter: selectedFacet.filter,
isSelected: !0,
count: selectedFacet.count
})
}
}
function _showMissingSelectedFacets() {
var i, selectedFacet, filter, selectedFilters = filterService.getFilters().slice(0),
filtersMap = _.indexBy($scope.filters, "field");
for (i = 0; i < selectedFilters.length; i++) selectedFacet = selectedFilters[i], "CHECK" === selectedFacet.style && (filter = filtersMap[selectedFacet.filter], _appendIfMissing(filter, selectedFacet))
}
function _addFilter(facet) {
filterService.removeExisting(facet), filterService.addFilter(facet), $location.search("fq", filterService.getFilterAsLocationParams()), _notifyFilter = !0, _fetchFilter()
}
function _clearBounds() {
$location.search("bbox", null), $location.search("bboxt", null), $scope.$emit("clearBboxEvent", {})
}
function _clearSearchInput() {
$location.search("q", null), $scope.$emit("clearSearchEvent", {})
}
function _scrollIntoView(filter) {
$timeout(function() {
var clientHeight = $document[0].documentElement.clientHeight,
element = $("#" + filter.field);
element[0].getBoundingClientRect().bottom > clientHeight && $("body").animate({
scrollTop: element.offset().top
}, "slow")
}, 250)
}
function _fetchFilter() {
_busy || (_busy = !0, filterService.applyFromUrl($location.search()).then(function() {
_busy = !1, _notifyFilter && $scope.$emit("filterEvent", {
from: "filtersController"
}), catalogService.loadRemoteLocations().then(function() {
filterQuery.execute($location.search(), filterService.getFilterParams(), "", filterService.getSelectedFilters()).then(function(res) {
$scope.filters = filterStyle.apply(res.filters), _.isEmpty(res.badShards) || configService.getCatalogs().then(function() {
var shardUrl, catalogFilter = _.find($scope.filters, {
field: "shards"
});
_.each(catalogFilter.values, function(catalogFacet) {
angular.isDefined(catalogFacet.raw) && (shardUrl = catalogFacet.raw, shardUrl = shardUrl.substring(shardUrl.indexOf("://") + 3), shardUrl += "solr/v0", catalogFacet.hasError = angular.isDefined(res.badShards[shardUrl]))
})
}), _showMissingSelectedFacets(), statsService.updateStats($location.search(), filterService.getFilterParams(), "", $scope.filters), treeService.updateTree($location.search(), filterService.getFilterParams(), "", $scope.filters)
})
})
}))
}
var _busy = !1,
_notifyFilter = !1;
$scope.maxFacets = 10, $scope.$on("doSearch", function() {
_notifyFilter = !1, _fetchFilter()
}), $scope.$on("filterChanged", function(event, args) {
!args || "filtersController" !== args.from && args.refresh !== !1 ? (_notifyFilter = !1, _fetchFilter()) : _notifyFilter = !1
}), $scope.$on("searchResults", function(event, data) {
angular.isDefined(data.stats) && filterService.setStatsFields(data.stats.stats_fields)
}), $scope.openMinDatePicker = function($event, facet) {
$event.preventDefault(), $event.stopPropagation(), facet.isMinOpened = !0, facet.isMaxOpened = !1
}, $scope.openMaxDatePicker = function($event, facet) {
$event.preventDefault(), $event.stopPropagation(), facet.isMaxOpened = !0, facet.isMinOpened = !1
}, $scope.filterResults = function(facet) {
var shards = [],
forceSelectedParameter = !1;
if (angular.isDefined(facet.checked) && (facet.isSelected = !facet.checked, delete facet.checked, forceSelectedParameter = !0), facet.isSelected) "shard" === facet.field ? $scope.removeFilter(facet) : (filterService.removeFilter(facet), facet.isSelected = !1), forceSelectedParameter && (facet.isSelected = !1);
else if ("shard" === facet.field) {
var urlShards = $location.search().shards;
"" !== urlShards && angular.isDefined(urlShards) && (shards = urlShards.split(",")), shards.push(facet.id), $location.search("shards", shards.join())
} else filterService.addFilter(facet), forceSelectedParameter && (facet.isSelected = !0);
$location.search("fq", filterService.getFilterAsLocationParams()), _notifyFilter = !0, _fetchFilter()
}, $scope.filterOnly = function(facet) {
filterService.removeThisFilter(facet), _addFilter(facet)
}, $scope.addRangeFilter = function(facet) {
var range = facet.model;
facet.units && (range[0] = facet.convertValue(range[0], facet.selectedUnit, facet.units[0], facet), range[1] = facet.convertValue(range[1], facet.selectedUnit, facet.units[0], facet)), facet.humanized = facet.display + ": [" + range[0] + " TO " + range[1] + "]", _addFilter(facet)
}, $scope.addCalendarFilter = function(facet) {
var calendarFacet = calendarFilter.decorate(facet);
calendarFacet && _addFilter(facet)
}, $scope.addFolderFilter = function(node) {
var facet = {
field: "path_path",
filter: "path_path",
humanized: "Path: " + node.path,
name: node.path
};
_addFilter(facet)
}, $scope.loadNode = function(node) {
node.collapsed = !node.collapsed, node.loaded || treeService.loadNode($location.search(), filterService.getFilterParams(), "", $scope.filters, node)
}, $scope.removeFilter = function(facet) {
if (facet.isInput) _clearSearchInput();
else if (facet.isBbox) _clearBounds();
else if ("shard" === facet.field) {
var shards = $location.search().shards.split(","),
urlShards = [];
facet.selected = !1, _.each(shards, function(shard) {
facet.id === shard || urlShards.push(shard)
}), $location.search("shards", urlShards.join())
} else filterService.removeFilter(facet), $location.search("fq", filterService.getFilterAsLocationParams());
_notifyFilter = !0, _fetchFilter()
}, $scope.$on("removeFilter", function(e, facet) {
$scope.removeFilter(facet)
}), $scope.hasFacets = function(filter) {
return filter.values.length > 0
}, $scope.hasMoreFacets = function(filter) {
return filter.values.length > $scope.maxFacets
}, $scope.toggleDisplayState = function(filter) {
$timeout(function() {
"in" !== filter.displayState ? filter.displayState = "in" : filter.displayState = "", filterService.setFilterState(filter, filter.displayState), "in" === filter.displayState && _scrollIntoView(filter)
}, 0)
}, $scope.showAllFacets = function(filter) {
var modalInstance = $uibModal.open({
templateUrl: "src/filters/facets.html",
controller: "FacetsCtrl",
resolve: {
selectedFilter: function() {
return filter
},
updateFilters: function() {
return $scope.filterResults
}
}
});
modalInstance.result.then(function(facet) {
$scope.filterResults(facet)
}, function() {})
}, $scope.getFieldName = function(key) {
return translateService.getFieldName(key) || key
}
}), angular.module("voyager.filters").controller("SelectedFiltersCtrl", function($scope, filterService, $location, mapUtil, sugar, translateService) {
function _applyOrFacets() {
$scope.filters.forEach(function(filter) {
if (filter.isOr = 0 === filter.name.indexOf("("), filter.isOr) {
filter.parts = [];
var parts = filter.name.replace("(", "").replace(")", "").replace("{!expand}", "").trim().split(" ");
parts.forEach(function(part) {
var facet = {
name: part,
filter: filter.filter,
pretty: part
};
filter.parts.push(facet), "location" === filter.filter && (facet.pretty = translateService.getLocation(part))
})
}
})
}
function _setSelectedFilters() {
var params = $location.search();
if ($scope.filters = filterService.getFilters().slice(0), _applyOrFacets(), params.q && "*:*" !== params.q && $scope.filters.push({
isInput: !0,
name: "search",
humanized: "Search:" + params.q,
pretty: params.q.replace("{!expand}", "")
}), params.place) {
var humanized, formattedPlace = params.place,
isBbox = !1,
isWkt = !1;
mapUtil.isBbox(params.place) ? (formattedPlace = sugar.formatBBox(params.place), isBbox = !0) : (formattedPlace = mapUtil.formatWktForDisplay(params.place), isWkt = !0), humanized = ("within" === params["place.op"] ? "Within" : "Intersects") + ": " + formattedPlace, $scope.filters.push({
isInput: !0,
name: "place",
humanized: humanized,
isBbox: isBbox,
isWkt: isWkt,
pretty: formattedPlace
})
}
params["links.to"] && $scope.filters.push({
isInput: !1,
name: "linksTo",
humanized: "Links.To:" + params["links.to"],
pretty: params["links.to"]
}), params["links.from"] && $scope.filters.push({
isInput: !1,
name: "linksFrom",
humanized: "Links.From:" + params["links.from"],
pretty: params["links.from"]
})
}
function clearPlace(params) {
return delete params.place, delete params["place.op"], delete params["place.id"], params
}
$scope.removeExpanded = function(term) {
var exp_exclude = $location.search()["expand.exclude"];
"undefined" == typeof exp_exclude && (exp_exclude = ""), exp_exclude += " " + term, $location.search("expand.exclude", exp_exclude.trim()), $scope.$emit("removeFilterEvent", {})
}, $scope.removeFilter = function(facet) {
if ("search" === facet.name) $location.search("q", null), $scope.$emit("removeFilterEvent", {});
else if ("place" === facet.name) {
var filterHumanized = facet.humanized.split(": ");
filterHumanized.splice(0, 1);
var args = {
isBbox: facet.isBbox,
isWkt: facet.isWkt
};
$location.search(clearPlace($location.search())), $scope.$emit("removeFilterEvent", args)
} else if ("linksTo" === facet.name || "linksFrom" === facet.name) {
var params = $location.search();
delete params["links.to"], delete params["links.from"], $location.search(params), $scope.$emit("removeFilterEvent", facet)
} else filterService.removeFilter(facet), $location.search("fq", filterService.getFilterAsLocationParams()), $scope.$emit("removeFilterEvent", facet);
_setSelectedFilters()
}, $scope.clearAllFilter = function() {
var params = $location.search();
delete params.q, delete params.fq, $location.search(clearPlace(params)), filterService.clear(), $scope.$emit("removeFilterEvent", {}), _setSelectedFilters()
}, $scope.resetExpanded = function() {
delete $location.search()["expand.exclude"], delete $scope.expanded, $scope.$emit("removeFilterEvent", {})
}, $scope.$on("filterChanged", function() {
_setSelectedFilters()
}), $scope.$on("searchResults", function(event, data) {
data && data.expansion && data.expansion.terms && _.isArray(data.expansion.terms) && data.expansion.terms.length > 0 ? $scope.expanded = data.expansion.terms : delete $scope.expanded
}), $scope.$on("clearSearch", function() {
_setSelectedFilters()
}), $location.search().fq ? filterService.setFilters($location.search().fq) : (angular.isDefined($location.search()["links.to"]) || angular.isDefined($location.search()["links.from"])) && filterService.clear(), _setSelectedFilters()
}), angular.module("voyager.filters").factory("rangeService", function(config, $http, $timeout, configService, translateService, $q) {
function _getRangeParams() {
var configFilters = configService.getFilters(),
facetParams = "";
return $.each(configFilters, function(index, filter) {
"RANGE" !== filter.style && "STATS" !== filter.style || (facetParams += "&stats.field=" + filter.field)
}), facetParams
}
function _hasRangeParam() {
var configFilters = configService.getFilters(),
hasRange = !1;
return $.each(configFilters, function(index, filter) {
if ("RANGE" === filter.style || "STATS" === filter.style) return hasRange = !0, !1
}), hasRange
}
function _getRangeLimitsQuery() {
var queryString = config.root + "solr/v0/select?rows=0&stats=true" + _getRangeParams();
return angular.isDefined(configService.getConfigId()) && (queryString += "&voyager.config.id=" + configService.getConfigId()), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function _setRangeLimits() {
var deferred = $q.defer();
return _hasRangeParam() ? $http.jsonp(_getRangeLimitsQuery()).success(function(data) {
_rangeLimits = data.stats.stats_fields, deferred.resolve()
}) : deferred.resolve(), deferred.promise
}
function _parseInt(val) {
var ret = 0;
return angular.isDefined(val) && (ret = parseInt(val)), ret
}
var _rangeLimits = {},
_statsFields = {},
_rangeUnitMap = {
fileSize: {
options: ["B", "KB", "MB", "GB", "TB"],
convertValue: function(value, unitFrom, unitTo, facet) {
var unitFrom_Index = facet.units.indexOf(unitFrom),
unitTo_Index = facet.units.indexOf(unitTo),
converted = value;
return converted = unitFrom_Index > unitTo_Index ? value * Math.pow(1e3, unitFrom_Index - unitTo_Index) : value / Math.pow(1e3, unitTo_Index - unitFrom_Index)
}
}
};
return {
fetchAllRangeLimits: function() {
return _setRangeLimits()
},
setStatsFields: function(statsFields) {
_statsFields = statsFields
},
getRangeLimits: function(filter) {
return _rangeLimits[filter]
},
buildRangeFilter: function(filter, selectedFilter) {
var range = {
min: _rangeLimits[filter.field].min,
max: _rangeLimits[filter.field].max,
style: filter.style,
name: filter.field,
filter: filter.field,
display: filter.value
};
return selectedFilter ? range.model = selectedFilter.model : range.model = [range.min, range.max], range.stddev = _parseInt(_rangeLimits[filter.field].stddev), range.sum = _parseInt(_rangeLimits[filter.field].sum), range.mean = _parseInt(_rangeLimits[filter.field].mean), filter.unit && "none" !== filter.unit && (range.units = _rangeUnitMap[filter.unit].options, range.selectedUnit = range.units[0], range.storedUnit = range.selectedUnit, range.convertValue = _rangeUnitMap[filter.unit].convertValue, range.convert = function(rangeFacet) {
rangeFacet.min = rangeFacet.convertValue(rangeFacet.min, rangeFacet.storedUnit, rangeFacet.selectedUnit, rangeFacet), rangeFacet.max = rangeFacet.convertValue(rangeFacet.max, rangeFacet.storedUnit, rangeFacet.selectedUnit, rangeFacet), rangeFacet.storedUnit = rangeFacet.selectedUnit
}), range
},
buildCalendarFilter: function(filter, selectedFilter) {
var calendar = {
style: filter.style,
name: filter.field,
filter: filter.field,
display: filter.value,
stype: filter.stype,
multivalued: filter.multivalued
};
return selectedFilter ? (calendar.model = decodeURIComponent(selectedFilter.name).replace(/[\[\]]/g, "").split(" TO "), calendar.dateModel = [new Date(calendar.model[0]), new Date(calendar.model[1])]) : (calendar.model = [], calendar.dateModel = []), calendar
},
decorateSelected: function(selectedFilter, filterKeyValue) {
var range = filterKeyValue.value.replace("TO", ",");
selectedFilter.name = filterKeyValue.name, selectedFilter.model = JSON.parse(range), selectedFilter.humanized = translateService.getFieldName(filterKeyValue.name) + ": " + filterKeyValue.value
}
}
}), angular.module("voyager.filters").factory("facetService", function($http, config, translateService, $injector) {
function _checkSelectedOr(selectedFilters, facet) {
for (var selectedKeys = Object.keys(selectedFilters), i = 0; i < selectedKeys.length; i++) {
var selected = selectedFilters[selectedKeys[i]];
if (0 === selected.name.indexOf("(") && (_checkSelectedOrFacet(selected, facet), facet.isSelected)) break
}
}
function _checkSelectedOrFacet(selected, facet) {
var facets = selected.name.replace("(", "").replace(" )", "").replace(")", "");
facets = facets.split(" ");
for (var i = 0; i < facets.length; i++)
if (facets[i] === facet.name) {
facet.isSelected = !0;
break
}
}
function lookup(filter, params, callback) {
QueryBuilder || (QueryBuilder = $injector.get("queryBuilder"));
var service = QueryBuilder.buildAllFacets(params, filter.field);
$http.jsonp(service).success(function(data) {
var rawFacets = data.facet_counts.facet_fields[filter.field];
callback(_buildFacets(rawFacets, filter))
})
}
var QueryBuilder, isEven = function(someNumber) {
return someNumber % 2 === 0
},
_buildFacet = function(facetName, value, filter, selectedFilters) {
var filterName = angular.isString(filter) ? filter : filter.field,
builtValue = facetName + " (" + value + ")",
facet = {
name: facetName,
value: builtValue,
filter: filterName,
style: filter.style
};
if (config.rawFields[filterName] ? facet.humanized = facet.name : "location" === facet.filter ? facet.humanized = translateService.getLocation(facet.name) : facet.humanized = translateService.getType(facet.name), facet.count = value, facet.display = facet.humanized, selectedFilters) {
var selectedFilter = selectedFilters[facet.name];
selectedFilter ? facet.isSelected = !0 : _checkSelectedOr(selectedFilters, facet)
}
return facet
},
_buildFacets = function(rawFacets, filter, selectedFilters) {
var facets = [];
return $.each(rawFacets, function(index, value) {
if (!isEven(index)) {
var facetName = rawFacets[index - 1],
facet = _buildFacet(facetName, value, filter, selectedFilters);
facets.push(facet)
}
}), facets
};
return {
doLookup: function(filter, params, callback) {
lookup(filter, params, callback)
},
buildFacet: function(facetName, value, filterName, selectedFilters) {
return _buildFacet(facetName, value, filterName, selectedFilters)
},
buildFacets: function(rawFacets, filter, selectedFilters) {
return _buildFacets(rawFacets, filter, selectedFilters)
},
buildAllFacets: function(filters, selectedFilters) {
var nameValues = {};
return $.each(filters, function(filterName, values) {
var prettyFacetValues = _buildFacets(values, filterName, selectedFilters);
nameValues[filterName] = prettyFacetValues
}), nameValues
}
}
}), angular.module("voyager.filters").factory("filterQuery", function(config, facetService, configService, sugar, $http, queryBuilder, catalogService, converter) {
function _convertPlaceFilter(params) {
var placeFilter = "";
return angular.isDefined(params.place) && (placeFilter = "&fq=" + converter.toPlaceFilter(params)), placeFilter
}
function _getQueryString(params, filters, bounds) {
var placeFilter = _convertPlaceFilter(params);
delete params.fq, delete params.sort, angular.isDefined(params.shards) && (params.shards = catalogService.removeInvalid(params.shards)), angular.isDefined(params.disp) && angular.isUndefined(params["voyager.config.id"]) ? params["voyager.config.id"] = params.disp : angular.isUndefined(params.disp) && angular.isDefined(configService.getConfigId()) && (params["voyager.config.id"] = configService.getConfigId());
var queryString = config.root + "solr/v0/select";
queryString += "?" + sugar.toQueryString(params);
var facetLimit = 11;
return queryString += "&rows=0", queryString += "&facet=true&facet.mincount=1&facet.limit=" + facetLimit + queryBuilder.buildFacetParams(), queryString += filters, queryString += bounds, queryString += placeFilter, queryString += "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK"
}
function checkFederations(res) {
var shards = res.data["shards.info"],
badShards = {};
if (shards)
for (var shard in shards) _.isEmpty(shards[shard].error) || (badShards[shard] = shards[shard].shardAddress);
return badShards
}
return {
execute: function(params, filters, bounds, selectedFilters) {
var paramCopy = _.clone(params);
return $http.jsonp(_getQueryString(paramCopy, filters, bounds)).then(function(res) {
var resultData = res.data.facet_counts.facet_fields,
badShards = checkFederations(res),
filterFacets = facetService.buildAllFacets(resultData, selectedFilters);
return {
filters: filterFacets,
badShards: badShards
}
})
}
}
}), angular.module("voyager.filters").factory("filterService", function(translateService, facetService, $q, configService, rangeService, converter, $filter, sugar) {
function _setFilters(filterList) {
filters = filterList, $.each(filters, function(index, value) {
filterMap[value.name] = value
})
}
function _clear() {
filters.length = 0, filterMap = {}
}
function _getKeyValue(filter) {
var pos = filter.indexOf(":"),
keyValue = {};
return keyValue.name = filter.substring(0, pos), keyValue.value = filter.substring(pos + 1), keyValue.value = keyValue.value.replace(/\\/g, ""), keyValue
}
function _buildSelectedFilter(filterKeyValue) {
var style, filterName = filterKeyValue.name;
filterName.indexOf("{!tag=") !== -1 ? (filterKeyValue.name = filterName.substring(filterName.indexOf("}") + 1), style = "CHECK") : style = configService.lookupFilterStyle(filterKeyValue.name);
var pretty = "location" === filterKeyValue.name ? translateService.getLocation(filterKeyValue.value) : translateService.getType(decodeURI(filterKeyValue.value)),
humanized = translateService.getFieldName(filterKeyValue.name) + ":" + pretty,
decodeValue = decodeURIComponent(filterKeyValue.value),
timeValues = decodeValue.replace(/[\[\]]/g, "").split(" TO ");
if ("RANGE" !== style && sugar.isValidDate(timeValues[0])) {
style = "DATE";
var dateFilterValue = Date.parse(timeValues[0]);
pretty = $filter("date")(dateFilterValue, "M/d/yyyy"), timeValues[1] && (dateFilterValue = Date.parse(timeValues[1]), pretty += " TO " + $filter("date")(dateFilterValue, "M/d/yyyy")), humanized = translateService.getFieldName(filterKeyValue.name) + ":" + decodeValue
}
var selectedFilter = {
filter: filterKeyValue.name,
name: filterKeyValue.value,
humanized: humanized,
isSelected: !0,
style: style,
displayState: "in",
pretty: pretty
};
return "RANGE" === style && rangeService.decorateSelected(selectedFilter, filterKeyValue), selectedFilter
}
function _getFilterList(urlFilters) {
var filterList = [];
return $.each(urlFilters, function(index, filter) {
var filterKeyValue = _getKeyValue(filter),
selectedFilter = _buildSelectedFilter(filterKeyValue);
filterList.push(selectedFilter), angular.isUndefined(filterState[filterKeyValue.name]) && (filterState[filterKeyValue.name] = "in")
}), filterList
}
function _syncFilters(urlFilters, resetState) {
if (resetState && (filterState = {}), "string" == typeof urlFilters && (urlFilters = [urlFilters]), urlFilters) {
var filterList = _getFilterList(urlFilters);
_setFilters(filterList)
} else _clear()
}
function _replaceName(target, source) {
var name = target.replace("(" + source + " ", "(").replace(" " + source + ")", ")").replace(" " + source + " ", " ").replace(" )", ")");
return name.indexOf(" ") === -1 && (name = name.replace("(", "").replace(")", "")), name
}
var searchBounds, filters = [],
filterMap = {},
filterState = {},
_systemFilters = null,
_statsFields = {};
return {
getSystemFilters: function() {
return _systemFilters
},
buildFacets: function(filters) {
return facetService.buildAllFacets(filters, filterMap)
},
getFilterAsLocationParams: function() {
var name, filterList = [];
return $.each(filters, function(index, facet) {
name = facet.name, "RANGE" === facet.style || "STATS" === facet.style ? (name = "date" === facet.stype ? "[" + encodeURIComponent(facet.model[0] + " TO " + facet.model[1]) + "]" : "[" + facet.model[0] + " TO " + facet.model[1] + "]", filterList.push(facet.filter + ":" + name)) : "COMPLEX" === facet.style ? filterList.push(facet.filter + ":" + facet.name) : (name = converter.solrReady(name), filterList.push(facet.filter + ":" + name))
}), filterList
},
getFilterParams: function() {
return converter.toSolrParams(filters)
},
getSolrList: function() {
return converter.toSolrQueryList(filters)
},
getFilters: function() {
return filters
},
setFilters: function(fq) {
_syncFilters(fq)
},
getSelectedFilters: function() {
return filterMap
},
addFilter: function(facet) {
"COMPLEX" === facet.style ? $.each(facet.name, function(index) {
if (!filterMap[facet.name[index]]) {
var simpleFacet = $.extend({}, facet);
simpleFacet.name = facet.name[index], simpleFacet.filter = facet.filter[index], filters.push(simpleFacet), filterMap[simpleFacet.name] = simpleFacet
}
}) : filterMap[facet.name] || (filters.push(facet), filterMap[facet.name] = facet)
},
removeFilter: function(facet) {
var isCalendar = "DATE" === facet.style || !angular.isUndefined(facet.stype) && "date" === facet.stype,
isRange = "RANGE" === facet.style,
isComplex = "COMPLEX" === facet.style;
filters = _.reject(filters, function(el) {
return isCalendar || isRange ? el.filter === facet.filter : isComplex ? facet.name.indexOf(el.name) >= 0 && facet.filter[facet.name.indexOf(el.name)] === el.filter : el.name === facet.name
}), filters.forEach(function(filter) {
0 === filter.name.indexOf("(") && filter.name.indexOf(facet.name) !== -1 && (delete filterMap[filter.name], filter.name = _replaceName(filter.name, facet.name), filter.pretty = _replaceName(filter.pretty, facet.name), filter.humanized = _replaceName(filter.humanized, facet.name), filterMap[filter.name] = filter)
}), filters = filters.filter(function(filter) {
return "()" !== filter.name && filter.humanized.indexOf("()") === -1
}), isCalendar || isRange ? delete filterMap[facet.filter] : isComplex ? $.each(facet.name, function(index, facetName) {
delete filterMap[facetName]
}) : delete filterMap[facet.name]
},
clear: function() {
_clear()
},
applyFromUrl: function(params) {
var deferred = $q.defer();
return configService.setFilterConfig(params.disp).then(function(config) {
rangeService.fetchAllRangeLimits().then(function() {
_syncFilters(params.fq, config.configId !== params.disp), deferred.resolve({})
})
}), deferred.promise
},
clearBbox: function() {
searchBounds = null
},
setStatsFields: function(statsFields) {
_statsFields = statsFields
},
getFilterState: function(filter) {
return filterState[filter.field]
},
setFilterState: function(filter, state) {
filterState[filter.field] = state
},
removeExisting: function(facet) {
var self = this;
$.each(filters, function(index, selectedFilter) {
if (selectedFilter.filter === facet.filter) return self.removeFilter(facet), !1
})
},
removeThisFilter: function(facet) {
filters = _.reject(filters, function(filter) {
return filter.filter === facet.filter && (delete filterMap[filter.name], filter.isSelected = !1, !0)
})
}
}
}), angular.module("voyager.filters").factory("filterStyle", function(config, facetService, configService, rangeService, filterService, complexFilterService) {
function _decorateFacets(facetValues, filter) {
$.each(facetValues, function(i, facet) {
facet.style = filter.style, "RANGE" === filter.style ? facet.numeric = parseInt(facet.name) : "COMPLEX" === facet.style && (facet.isSelected = complexFilterService.calculateIsSelected(facet, filterService.getSelectedFilters()))
})
}
function _decorateFilters(systemFilters, facets) {
var selectedFilters = filterService.getFilters();
$.each(systemFilters, function(index, filter) {
var selectedFilter, facetValues = facets[filter.field] || filter.values;
facetValues && facetValues.length > 0 && (facetValues.multivalued = filter.multivalued, facetValues.stype = filter.stype, _decorateFacets(facetValues, filter), "RANGE" !== filter.style && "STATS" !== filter.style && "HIERARCHY" !== filter.style ? filter.values = facetValues : "HIERARCHY" !== filter.style && (selectedFilter = _.find(selectedFilters, {
filter: filter.field
}), "date" === filter.stype ? filter.values = [rangeService.buildCalendarFilter(filter, selectedFilter)] : filter.values = [rangeService.buildRangeFilter(filter, selectedFilter)])), filter.displayState = filterService.getFilterState(filter)
})
}
return {
apply: function(filters) {
var displayFilters = configService.getDisplayFilters();
return _decorateFilters(displayFilters, filters), displayFilters
}
}
}), angular.module("cart", ["taskRunner", "voyager.util", "LocalStorageModule", "voyager.filters"]), angular.module("cart").config(["localStorageServiceProvider", function(localStorageServiceProvider) {
"use strict";
localStorageServiceProvider.setPrefix("vs")
}]).factory("cartService", function(localStorageService, queryBuilder, $http, $q, translateService, cartItemsQuery) {
"use strict";
function _setItems(items) {
var itemMap = {};
$.each(items, function(index, value) {
itemMap[value.id] = value.id
}), localStorageService.add(CART_STORAGE_NAME, itemMap), _notify(itemMap)
}
function _syncItems() {
return cartItemsQuery.fetchItemsOnly(_getItems()).then(function(items) {
_setItems(items)
})
}
function _appendFilter(filter, query) {
var solrFilters = query.solrFilters;
angular.isUndefined(solrFilters) && (query.solrFilters = []), query.solrFilters.push(filter)
}
var observers = [],
CART_STORAGE_NAME = "cart-items",
_notify = function(itemMap, action) {
var length = _.size(itemMap),
query = localStorageService.get("cart-query");
query && (length += query.count), observers.forEach(function(entry) {
entry(length, itemMap, action)
})
},
_getItems = function() {
var items = localStorageService.get(CART_STORAGE_NAME);
return items ? items : {}
},
_notifyCount = function(count) {
var items = _getItems();
observers.forEach(function(entry) {
entry(count, items)
})
};
return {
addItem: function(item) {
var query = localStorageService.get("cart-query"),
removedFilter = !1;
if (query) {
if (angular.isDefined(query.solrFilters)) {
var length = query.solrFilters.length;
query.solrFilters = query.solrFilters.filter(function(item) {
return item !== "-id:" + item.id
}), removedFilter = query.solrFilters.length !== length
}
query.count = query.count + 1, this.addQuery(query)
}
if (!removedFilter) {
var itemMap = _getItems();
itemMap[item.id] = item.id, localStorageService.add(CART_STORAGE_NAME, itemMap)
}
_notify(_getItems())
},
addItems: function(items) {
var itemMap = _getItems();
$.each(items, function(index, item) {
itemMap[item.id] = item.id
}), localStorageService.add(CART_STORAGE_NAME, itemMap), _notify(itemMap);
var query = localStorageService.get("cart-query");
query && (query.count += items.length, this.addQuery(query))
},
getItems: function() {
return _getItems()
},
setItems: function(items) {
_setItems(items)
},
getCount: function() {
var count = 0,
query = this.getQuery();
return query && (count += query.count, query.actualCount) ? count : count += _.size(_getItems())
},
addObserver: function(observer) {
observers.push(observer)
},
removeObserver: function(observer) {
observers = _.without(observers, function(item) {
return item === observer
})
},
remove: function(id) {
var itemMap = _getItems(),
query = localStorageService.get("cart-query");
angular.isDefined(itemMap[id]) && (delete itemMap[id], localStorageService.add(CART_STORAGE_NAME, itemMap), _notify(itemMap)), query && (_appendFilter("-id:" + id, query), query.count = query.count - 1, this.addQuery(query))
},
isInCart: function(id) {
return angular.isDefined(_getItems()[id])
},
getItemIds: function() {
return $.map(_getItems(), function(item) {
return item
})
},
fetch: function(block) {
var query = this.getQuery(),
itemIds = this.getItemIds();
return query || itemIds.length > 0 ? cartItemsQuery.execute(query, itemIds, block) : $q.when({
count: 0,
docs: []
})
},
fetchQueued: function(items) {
var query = this.getQuery(),
itemIds = this.getItemIds();
return query || itemIds.length > 0 ? cartItemsQuery.fetchQueued(query, itemIds, items) : $q.when([])
},
clear: function() {
localStorageService.remove(CART_STORAGE_NAME), localStorageService.remove("cart-query"), _notify({}, "clear")
},
getItemsArray: function() {
var itemsArray = [];
return $.map(_getItems(), function(item) {
itemsArray.push(item)
}), itemsArray
},
removeByFormat: function(format) {
var query = localStorageService.get("cart-query");
query && (format = format.replace("+", "%2B"), _appendFilter("-format:" + format, query), query.actualCount = !1, this.addQuery(query))
},
addQuery: function(query, items) {
angular.isUndefined(items) && (items = _getItems());
var length = _.keys(items).length;
length > 0 && query.actualCount !== !0 && (query.count += length), query.actualCount = !0, localStorageService.add("cart-query", query), _notifyCount(query.count)
},
replace: function(query) {
localStorageService.remove(CART_STORAGE_NAME), this.addQuery(query)
},
getQuery: function() {
return localStorageService.get("cart-query")
},
setQueryCount: function(count) {
var query = localStorageService.get("cart-query");
query ? (query.count = count, query.actualCount = !0, this.addQuery(query)) : count !== this.getCount() && _syncItems(), _notifyCount(count)
},
hasItems: function() {
var query = localStorageService.get("cart-query"),
items = localStorageService.get(CART_STORAGE_NAME);
return query || items
}
}
}), angular.module("cart").factory("cartItemsQuery", function(config, filterService, configService, sugar, $http, translateService, $log, converter) {
function _cleanFilters(filters) {
var pos, cleanFilters = _.clone(filters);
return _.each(cleanFilters, function(filter, index) {
pos = filter.indexOf("{!tag"), pos !== -1 && (pos = filter.indexOf("}"), cleanFilters[index] = filter.substring(pos + 1)), cleanFilters[index] = cleanFilters[index].replace("+", "%2B")
}), cleanFilters.join(" AND ")
}
function _applyItems(queryCriteria, items) {
var filters, itemsStr = "",
sep = "",
hasItems = !1,
q = "",
oper = "";
items && items.length > 0 && (itemsStr = "id:(" + items.join(" ") + ")", sep = " OR ", hasItems = !0), angular.isDefined(queryCriteria.params.q) && _.isEmpty(queryCriteria.solrFilters) ? (q = queryCriteria.params.q, angular.isDefined(queryCriteria.params.place) && (q = "(" + q + " AND " + converter.toPlaceFilter(queryCriteria.params) + ")"), queryCriteria.params.q = itemsStr + sep + q) : hasItems && (_.isEmpty(queryCriteria.solrFilters) ? (angular.isDefined(queryCriteria.params.place) && (q = "(" + converter.toPlaceFilter(queryCriteria.params) + ")", oper = " OR "), angular.isDefined(queryCriteria.constraintFilters) && queryCriteria.constraintFilters.length > 0 ? queryCriteria.params.q = itemsStr + oper + q + " AND " + _cleanFilters(queryCriteria.constraintFilters) : queryCriteria.params.q = itemsStr + oper + q) : (filters = _cleanFilters(queryCriteria.solrFilters), angular.isDefined(queryCriteria.params.q) && (q = queryCriteria.params.q, oper = " AND "), angular.isDefined(queryCriteria.params.place) && (q += oper + converter.toPlaceFilter(queryCriteria.params), oper = " AND "), _.has(queryCriteria, "constraints") ? filters.length > 0 ? (angular.isDefined(queryCriteria.invalidItems) && queryCriteria.invalidItems === !0 && (filters = filters.replace(" AND ", "&fq=")), queryCriteria.params.q = itemsStr + " OR " + q + oper + filters + "&fq=" + queryCriteria.constraintFilters.join("&fq=")) : queryCriteria.params.q = itemsStr + " AND " + q + oper + _cleanFilters(queryCriteria.constraintFilters) : queryCriteria.params.q = itemsStr + sep + "(" + q + oper + filters + ")"))
}
function _convertPlaceIf(queryCriteria) {
if (angular.isDefined(queryCriteria.params.place)) {
var fq = [];
angular.isDefined(queryCriteria.solrFilters) && (fq = queryCriteria.solrFilters), fq.push(converter.toPlaceFilter(queryCriteria.params)), queryCriteria.solrFilters = fq
}
}
function _setParams(queryCriteria, items) {
var queryString = "";
return queryCriteria || (queryCriteria = {
params: {},
hasQuery: !1
}), _.isEmpty(items) ? _convertPlaceIf(queryCriteria) : _applyItems(queryCriteria, items), queryString += "?" + sugar.toQueryString(queryCriteria.params)
}
function _addRow(results, add, item) {
return add ? results.push({
key: item,
displayFormat: translateService.getType(item)
}) : results[results.length - 1].count = item, !add
}
function _buildRows(items) {
var isKey = !0,
results = [],
count = 0;
return $.each(items, function(index, item) {
isKey = _addRow(results, isKey, item), isKey && (count += item)
}), {
results: results,
count: count
}
}
function _buildQuery(settings, queryCriteria, items, block) {
var queryString = config.root + "solr/v0/select";
if (queryString += _setParams(queryCriteria, items), queryString += settings, queryCriteria && (angular.isUndefined(items) || 0 === items.length)) {
if (!_.isEmpty(queryCriteria.solrFilters)) {
for (var i = 0; i < queryCriteria.solrFilters.length; i++) queryCriteria.solrFilters[i] = sugar.safeUrlEncode(queryCriteria.solrFilters[i]);
queryString += "&fq=" + queryCriteria.solrFilters.join("&fq=")
}
angular.isDefined(queryCriteria.bounds) && (queryString += queryCriteria.bounds)
}
return angular.isDefined(block) && (queryString += "&block=" + block), queryString += "&wt=json&json.wrf=JSON_CALLBACK&r=" + Math.random(), $log.debug("Cart queryString: " + queryString), queryString
}
function _getSummaryQueryString(queryCriteria, items, block) {
var settings = "&fl=id,name:[name],format&extent.bbox=true";
return settings += "&facet=true&facet.field=format&facet.mincount=1&rows=0", _buildQuery(settings, queryCriteria, items, block)
}
function _getQueryString(queryCriteria, items, block) {
var settings = "&fl=id,title,name:[name],format,thumb:[thumbURL]";
return settings += "&rows=100&extent.bbox=true", _buildQuery(settings, queryCriteria, items, block)
}
function _getQueuedQueryString(queryCriteria, items, queued) {
if (queryCriteria || (queryCriteria = {
params: {},
hasQuery: !1
}), queued && queued.length > 0) {
var ids = _.pluck(queued, "id");
queryCriteria.params.fq ? queryCriteria.params.fq.push("id:(" + ids.join(" ") + ")") : queryCriteria.params.fq = "id:(" + ids.join(" ") + ")"
}
var settings = "&fl=id&rows=100&extent.bbox=true&block=false";
return _buildQuery(settings, queryCriteria, items, !1)
}
function _getQueryCriteria(solrParams) {
var params = _.clone(solrParams),
solrFilters = filterService.getSolrList();
return delete params.fq, delete params.sort, delete params.view, delete params.vw, delete params.disp, "*:*" === params.q && delete params.q, {
params: params,
bounds: "",
solrFilters: solrFilters
}
}
function _decorate(items) {
$.each(items, function(index, item) {
angular.isDefined(item.format) ? item.displayFormat = translateService.getType(item.format) : item.displayFormat = "Unknown", angular.isDefined(item.thumb) && item.thumb.indexOf("vres/mime") !== -1 && (item.defaultThumb = !0)
})
}
function _fetchItems(queryCriteria, items, block) {
return $http.jsonp(_getQueryString(queryCriteria, items, block)).then(function(res) {
var docs = res.data.response.docs;
return _decorate(docs), {
docs: docs,
bbox: res.data["extent.bbox"],
count: res.data.response.numFound
}
})
}
function _fetchQueued(queryCriteria, items, queued) {
return $http.jsonp(_getQueuedQueryString(queryCriteria, items, queued)).then(function(res) {
return res.data.response.docs
})
}
function _fetchSummary(queryCriteria, items, block) {
return $http.jsonp(_getSummaryQueryString(queryCriteria, items, block)).then(function(res) {
var rows = _buildRows(res.data.facet_counts.facet_fields.format);
return {
docs: rows.results,
bbox: res.data["extent.bbox"],
count: res.data.response.numFound
}
})
}
function _fetchItemsOnly(query) {
return $http.jsonp(query).then(function(res) {
return res.data.response.docs
})
}
return {
getQueryCriteria: function(params) {
return _getQueryCriteria(params)
},
execute: function(queryCriteria, items, block) {
var count = 1;
return queryCriteria && (count = queryCriteria.count, delete queryCriteria.params.sort), count <= 100 ? _fetchItems(_.clone(queryCriteria), items, block) : _fetchSummary(_.clone(queryCriteria), items, block)
},
fetchItems: function(queryCriteria, items) {
return _fetchItems(queryCriteria, items)
},
fetchQueued: function(queryCriteria, items, queued) {
return _fetchQueued(_.clone(queryCriteria), items, queued)
},
fetchItemsOnly: function(items) {
var queryString = config.root + "solr/v0/select";
if (items) {
var ids = _.keys(items);
queryString += "?fq=id:(" + ids.join(" ") + ")"
}
return queryString += "&fl=id", queryString += "&rows=100", queryString += "&rand=" + Math.random(), queryString += "&wt=json&json.wrf=JSON_CALLBACK", _fetchItemsOnly(queryString)
}
}
}), angular.module("cart").controller("CartNavCtrl", function(config, $scope, $location, searchService, cartService, authService, usSpinnerService, $uibModal, taskService, $timeout, $state) {
"use strict";
function _init() {
$scope.taskStatusIcon = "fa fa-cog fa-spin", $scope.lastSearch = searchService.getLastSearch();
var path = $location.path().split("/");
$scope.page = path[1], "history" === $scope.page ? $scope.showTaskList = !1 : ($scope.showTaskList = cartService.getCount() > 0, _loadTasks(), $scope.cartItemCount = cartService.getCount(), cartService.addObserver(function() {
$scope.cartItemCount = cartService.getCount(), $scope.showTaskList = $scope.cartItemCount > 0
}), _setPermissions(), authService.addObserver(_setPermissions)), $scope.uiText = config.ui.list
}
function _setPermissions() {
$scope.canReload = authService.hasPermission("manage")
}
function _getTask() {
var task = $location.search().task;
return angular.isUndefined(task) && $location.path().indexOf("status") <= -1 && $location.path().indexOf("tasks") <= -1 && $location.path().indexOf("task") <= -1 && $location.path().indexOf("tasks") <= -1 ? config.defaultTask : task
}
function _loadTasks() {
taskService.findAllTasks($scope.canReload).then(function(response) {
$scope.taskList = response, $scope.refreshing = !1;
var task = _getTask();
_.isEmpty(task) || $timeout(function() {
var defaultTask;
_.isArray($scope.taskList) ? defaultTask = _.find($scope.taskList, {
name: task
}) : _.each($scope.taskList, function(category) {
defaultTask || (defaultTask = _.find(category, {
name: task
}))
}), defaultTask && defaultTask.available === !0 && $scope.selectTask(defaultTask)
}), usSpinnerService.stop("tasks-spinner")
})
}
$scope.refreshTasks = function() {
$scope.refreshing || ($scope.refreshing = !0, usSpinnerService.spin("tasks-spinner"), taskService.refresh().then(function() {
_loadTasks()
}))
}, $scope.selectTask = function(task) {
if (task.isSelected = !task.isSelected, task.available === !0) {
task.isNew = !0;
var constraintFormats = taskService.getTaskConstraintFormats(task.constraints);
taskService.validateTaskItems(task.constraints).then(function(severity) {
0 === severity ? (task.error = !1, task.warning = !1, $state.go("task", {
task: task
})) : 1 === severity ? (task.error = !1, task.warning = !0, $scope.hasInvalidItems = !0, $state.go("task", {
task: task
})) : 2 === severity && taskService.showTaskValidationError(constraintFormats)
})
}
}, $scope.$on("taskStatusChanged", function(event, args) {
$scope.loadDefaultTask = !1, "alert-running" === args ? $scope.taskStatusIcon = "fa fa-cog fa-spin" : "alert-success" === args ? $scope.taskStatusIcon = "glyphicon glyphicon-ok" : "alert-warning" === args ? $scope.taskStatusIcon = "icon-warning" : $scope.taskStatusIcon = "icon-error"
}), _init()
}), angular.module("cart").controller("CartCtrl", function($scope, cartService, searchService, $location, config, $log) {
function _updateCartCount(length, items, action) {
"clear" === action && ($scope.cartItems = [], $scope.cartItemCount = 0)
}
$scope.hasError = !1, $scope.loading = !0, $scope.cartName = config.ui.list.name.toLowerCase(), $scope.disp = $location.search().disp || "default", $scope.uiText = config.ui.list;
var _removeValue = function(array, id) {
return _.reject(array, function(item) {
return item.id === id
})
};
cartService.addObserver(_updateCartCount);
var init = function() {
$scope.displayCategory = cartService.getCount() > 100, cartService.fetch().then(function(data) {
cartService.setQueryCount(data.count), $scope.cartItemCount = data.count, $scope.cartItems = data.docs, $scope.loading = !1
}, function(error) {
$log.error(error)
})
};
init(), $scope.removeItem = function(id) {
cartService.remove(id), $scope.cartItems = _removeValue($scope.cartItems, id), $scope.cartItemCount = cartService.getCount()
}, $scope.removeItemByFormat = function(item) {
cartService.removeByFormat(item.key), init()
}, $scope.hasItems = function() {
return cartService.getCount() > 0
}, $scope.clearQueue = function() {
cartService.clear()
}, $scope.$on("$destroy", function() {
cartService.removeObserver(_updateCartCount)
})
}), angular.module("tree.directive", []).directive("frangTree", function($parse, $animate) {
return {
restrict: "EA",
controller: function($scope, $element) {
this.insertChildren = null, this.init = function(insertChildren) {
this.insertChildren = insertChildren
}
}
}
}).directive("frangTreeRepeat", function($parse, $animate) {
function hashKey(obj) {
var key, objType = typeof obj;
return "object" == objType && null !== obj ? "function" == typeof(key = obj.$$hashKey) ? key = obj.$$hashKey() : void 0 === key && (key = obj.$$hashKey = nextUid()) : key = obj, objType + ":" + key
}
function isArrayLike(obj) {
if (null == obj || isWindow(obj)) return !1;
var length = obj.length;
return !(1 !== obj.nodeType || !length) || (isString(obj) || isArray(obj) || 0 === length || "number" == typeof length && length > 0 && length - 1 in obj)
}
function isWindow(obj) {
return obj && obj.document && obj.location && obj.alert && obj.setInterval
}
function isString(value) {
return "string" == typeof value
}
function isArray(value) {
return "[object Array]" == toString.apply(value)
}
function nextUid() {
for (var digit, index = uid.length; index;) {
if (index--, digit = uid[index].charCodeAt(0), 57 == digit) return uid[index] = "A", uid.join("");
if (90 != digit) return uid[index] = String.fromCharCode(digit + 1), uid.join("");
uid[index] = "0"
}
return uid.unshift("0"), uid.join("")
}
function assertNotHasOwnProperty(name, context) {
if ("hasOwnProperty" === name) throw ngMinErr("badname", "hasOwnProperty is not a valid {0} name", context)
}
function minErr(module) {
return function() {
var message, i, code = arguments[0],
prefix = "[" + (module ? module + ":" : "") + code + "] ",
template = arguments[1],
templateArgs = arguments,
stringify = function(obj) {
return isFunction(obj) ? obj.toString().replace(/ \{[\s\S]*$/, "") : isUndefined(obj) ? "undefined" : isString(obj) ? obj : JSON.stringify(obj)
};
for (message = prefix + template.replace(/\{\d+\}/g, function(match) {
var arg, index = +match.slice(1, -1);
return index + 2 < templateArgs.length ? (arg = templateArgs[index + 2], isFunction(arg) ? arg.toString().replace(/ ?\{[\s\S]*$/, "") : isUndefined(arg) ? "undefined" : isString(arg) ? arg : toJson(arg)) : match
}), message = message + "\nhttp://errors.angularjs.org/" + version.full + "/" + (module ? module + "/" : "") + code, i = 2; i < arguments.length; i++) message = message + (2 == i ? "?" : "&") + "p" + (i - 2) + "=" + encodeURIComponent(stringify(arguments[i]));
return new Error(message)
}
}
function getBlockElements(block) {
if (block.startNode === block.endNode) return jqLite(block.startNode);
var element = block.startNode,
elements = [element];
do {
if (element = element.nextSibling, !element) break;
elements.push(element)
} while (element !== block.endNode);
return jqLite(elements)
}
function addRepeatWatch($scope, $element, _lastBlockMap, valueIdentifier, keyIdentifier, rhs, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, linker, expression) {
var lastBlockMap = _lastBlockMap;
$scope.$watchCollection(rhs, function(collection) {
var index, length, nextNode, arrayLength, childScope, key, value, trackById, trackByIdFn, collectionKeys, block, elementsToRemove, previousNode = $element[0],
nextBlockMap = {},
nextBlockOrder = [];
if (isArrayLike(collection)) collectionKeys = collection, trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
else {
trackByIdFn = trackByIdExpFn || trackByIdObjFn, collectionKeys = [];
for (key in collection) collection.hasOwnProperty(key) && "$" != key.charAt(0) && collectionKeys.push(key);
collectionKeys.sort()
}
for (arrayLength = collectionKeys.length, length = nextBlockOrder.length = collectionKeys.length, index = 0; index < length; index++)
if (key = collection === collectionKeys ? index : collectionKeys[index], value = collection[key], trackById = trackByIdFn(key, value, index), assertNotHasOwnProperty(trackById, "`track by` id"), lastBlockMap.hasOwnProperty(trackById)) block = lastBlockMap[trackById], delete lastBlockMap[trackById], nextBlockMap[trackById] = block, nextBlockOrder[index] = block;
else {
if (nextBlockMap.hasOwnProperty(trackById)) throw forEach(nextBlockOrder, function(block) {
block && block.startNode && (lastBlockMap[block.id] = block)
}), ngRepeatMinErr("dupes", "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}", expression, trackById);
nextBlockOrder[index] = {
id: trackById
}, nextBlockMap[trackById] = !1
}
for (key in lastBlockMap) lastBlockMap.hasOwnProperty(key) && (block = lastBlockMap[key], elementsToRemove = getBlockElements(block), $animate.leave(elementsToRemove), forEach(elementsToRemove, function(element) {
element[NG_REMOVED] = !0
}), block.scope.$destroy());
for (index = 0, length = collectionKeys.length; index < length; index++) {
if (key = collection === collectionKeys ? index : collectionKeys[index], value = collection[key], block = nextBlockOrder[index], nextBlockOrder[index - 1] && (previousNode = nextBlockOrder[index - 1].endNode), block.startNode) {
childScope = block.scope, nextNode = previousNode;
do nextNode = nextNode.nextSibling; while (nextNode && nextNode[NG_REMOVED]);
block.startNode == nextNode || $animate.move(getBlockElements(block), null, jqLite(previousNode)), previousNode = block.endNode
} else childScope = $scope.$new();
childScope[valueIdentifier] = value, keyIdentifier && (childScope[keyIdentifier] = key), childScope.$index = index, childScope.$first = 0 === index, childScope.$last = index === arrayLength - 1, childScope.$middle = !(childScope.$first || childScope.$last), childScope.$odd = !(childScope.$even = index % 2 == 0), block.startNode || linker(childScope, function(clone) {
clone[clone.length++] = document.createComment(" end ngRepeat: " + expression + " "), $animate.enter(clone, null, jqLite(previousNode)), previousNode = clone, block.scope = childScope, block.startNode = previousNode && previousNode.endNode ? previousNode.endNode : clone[0], block.endNode = clone[clone.length - 1], nextBlockMap[block.id] = block
})
}
lastBlockMap = nextBlockMap
})
}
var uid = ["0", "0", "0"],
jqLite = angular.element,
forEach = angular.forEach,
NG_REMOVED = "$$NG_REMOVED",
ngRepeatMinErr = minErr("ngRepeat"),
ngMinErr = minErr("ng"),
toString = Object.prototype.toString,
isFunction = angular.isFunction,
isUndefined = angular.isUndefined,
toJson = angular.toJson;
return {
restrict: "A",
transclude: "element",
priority: 1e3,
terminal: !0,
require: "^frangTree",
compile: function(element, attr, linker) {
return function($scope, $element, $attr, ctrl) {
var trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, lhs, rhs, valueIdentifier, keyIdentifier, expression = $attr.frangTreeRepeat,
match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
hashFnLocals = {
$id: hashKey
};
if (!match) throw ngRepeatMinErr("iexp", "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", expression);
if (lhs = match[1], rhs = match[2], trackByExp = match[4], trackByExp ? (trackByExpGetter = $parse(trackByExp), trackByIdExpFn = function(key, value, index) {
return keyIdentifier && (hashFnLocals[keyIdentifier] = key), hashFnLocals[valueIdentifier] = value, hashFnLocals.$index = index, trackByExpGetter($scope, hashFnLocals)
}) : (trackByIdArrayFn = function(key, value) {
return hashKey(value)
}, trackByIdObjFn = function(key) {
return key
}), match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/), !match) throw ngRepeatMinErr("iidexp", "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.", lhs);
valueIdentifier = match[3] || match[1], keyIdentifier = match[2];
addRepeatWatch($scope, $element, {}, valueIdentifier, keyIdentifier, rhs, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, linker, expression), ctrl.init(function($scope, $element, collection) {
addRepeatWatch($scope, $element, {}, valueIdentifier, keyIdentifier, collection, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, linker, expression)
})
}
}
}
}).directive("frangTreeInsertChildren", function() {
return {
restrict: "EA",
require: "^frangTree",
link: function(scope, element, attrs, ctrl) {
var comment = document.createComment("treeRepeat");
element.append(comment), ctrl.insertChildren(scope, angular.element(comment), attrs.frangTreeInsertChildren)
}
}
}).directive("frangTreeDrag", function($parse) {
return {
restrict: "A",
require: "^frangTree",
link: function(scope, element, attrs, ctrl) {
var el = element[0],
parsedDrag = $parse(attrs.frangTreeDrag);
el.draggable = !0, el.addEventListener("dragstart", function(e) {
return e.stopPropagation && e.stopPropagation(), e.dataTransfer.effectAllowed = "move", e.dataTransfer.setData("Text", "nothing"), element.addClass("tree-drag"), ctrl.dragData = parsedDrag(scope), !1
}, !1), el.addEventListener("dragend", function(e) {
return e.stopPropagation && e.stopPropagation(), element.removeClass("tree-drag"), ctrl.dragData = null, !1
}, !1)
}
}
}).directive("frangTreeDrop", function($parse) {
return {
restrict: "A",
require: "^frangTree",
link: function(scope, element, attrs, ctrl) {
var el = element[0],
parsedDrop = $parse(attrs.frangTreeDrop),
parsedAllowDrop = $parse(attrs.frangTreeAllowDrop || "true");
el.addEventListener("dragover", function(e) {
return parsedAllowDrop(scope, {
dragData: ctrl.dragData
}) && (e.stopPropagation && e.stopPropagation(), e.dataTransfer.dropEffect = "move", element.addClass("tree-drag-over"), e.preventDefault && e.preventDefault()), !1
}, !1), el.addEventListener("dragenter", function(e) {
return parsedAllowDrop(scope, {
dragData: ctrl.dragData
}) && (e.stopPropagation && e.stopPropagation(), element.addClass("tree-drag-over"), e.preventDefault && e.preventDefault()), !1
}, !1), el.addEventListener("dragleave", function(e) {
return parsedAllowDrop(scope, {
dragData: ctrl.dragData
}) && (e.stopPropagation && e.stopPropagation(), element.removeClass("tree-drag-over")), !1
}, !1), el.addEventListener("drop", function(e) {
return parsedAllowDrop(scope, {
dragData: ctrl.dragData
}) && (e.stopPropagation && e.stopPropagation(), element.removeClass("tree-drag-over"), scope.$apply(function() {
parsedDrop(scope, {
dragData: ctrl.dragData
})
}), ctrl.dragData = null, e.preventDefault && e.preventDefault()), !1
}, !1)
}
}
}), angular.module("ngTableResizableColumns", []).directive("ngTableResizableColumns", function() {
function ResizableColumns($table, loading) {
var __bind = function(fn, me) {
return function() {
return fn.apply(me, arguments)
}
};
this.loading = loading, this.pointerdown = __bind(this.pointerdown, this);
this.options = {
store: window.store,
rigidSizing: !1,
resizeFromBody: !0
}, this.$table = $table, this.setHeaders(), this.restoreColumnWidths(), this.syncHandleWidths()
}
var parseWidth = function(node) {
return parseFloat(node.style.width.replace("%", ""))
},
setWidth = function(node, table, width) {
return table && (table.find(".results-column")[node.cellIndex].style.width = "" + width.toFixed(2) + "%"), node.style.width = "" + width.toFixed(2) + "%"
},
pointerX = function(e) {
return 0 === e.type.indexOf("touch") ? (e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]).pageX : e.pageX
};
return ResizableColumns.prototype.getColumnId = function($el) {
return this.$table.data("resizable-columns-id") + "-" + $el.attr("data-resizable-column-id")
}, ResizableColumns.prototype.setHeaders = function() {
return this.$tableHeaders = this.$table.find("thead tr:first th:visible"), this.assignPercentageWidths(), this.createHandles()
}, ResizableColumns.prototype.destroy = function() {
return this.$handleContainer.remove(), this.$table.removeData("resizableColumns"), $(window).off(".rc")
}, ResizableColumns.prototype.assignPercentageWidths = function() {
var _this = this,
variableWidthHeaders = [],
totalWidth = 0;
return this.$tableHeaders.each(function(i, el) {
var $el;
$el = $(el), $el[0].attributes.getNamedItem("data-noresize") || variableWidthHeaders.push($el);
var elWidth = $el.outerWidth() / _this.$table.width() * 100;
if (totalWidth += Math.round(100 * elWidth) / 100, !_this.loading) {
if (i === _this.$tableHeaders.length - 1 && 100 != totalWidth && variableWidthHeaders.length > 0) {
var currentWidth = Number(parseWidth(variableWidthHeaders[0][0]));
setWidth(variableWidthHeaders[0][0], _this.$table, currentWidth + (100 - totalWidth))
}
return setWidth($el[0], _this.$table, elWidth)
}
})
}, ResizableColumns.prototype.createHandles = function() {
var _ref, _this = this;
return null != (_ref = this.$handleContainer) && _ref.remove(), this.$table.before(this.$handleContainer = $("<div class='rc-handle-container' />")), this.$tableHeaders.each(function(i, el) {
var $handle;
if (0 !== _this.$tableHeaders.eq(i + 1).length && null == _this.$tableHeaders.eq(i).attr("data-noresize") && null == _this.$tableHeaders.eq(i + 1).attr("data-noresize")) return $handle = $("<div class='rc-handle' />"), $handle.data("th", $(el)), $handle.appendTo(_this.$handleContainer)
}), this.$handleContainer.on("mousedown touchstart", ".rc-handle", this.pointerdown)
}, ResizableColumns.prototype.syncHandleWidths = function() {
var _this = this;
this.setHeaders();
var theColumns = this.$table.find(".results-column");
return this.$tableHeaders.each(function(i, el) {
var myCol = theColumns[i];
myCol.style.width = el.style.width
}), this.$handleContainer.width(this.$table.width()).find(".rc-handle").each(function(_, el) {
var $el;
return $el = $(el), $el.css({
left: $el.data("th").outerWidth() + ($el.data("th").offset().left - _this.$handleContainer.offset().left),
height: _this.options.resizeFromBody ? _this.$table.height() : _this.$table.find("thead").height()
})
})
}, ResizableColumns.prototype.saveColumnWidths = function() {
var _this = this;
return this.$tableHeaders.each(function(_, el) {
var $el;
if ($el = $(el), null == $el.attr("data-noresize") && null != _this.options.store) return _this.options.store.set(_this.getColumnId($el), parseWidth($el[0]))
})
}, ResizableColumns.prototype.restoreColumnWidths = function() {
var _this = this;
return this.$tableHeaders.each(function(_, el) {
var $el, width;
if ($el = $(el), null != _this.options.store && (width = _this.options.store.get(_this.getColumnId($el)))) return setWidth($el[0], _this.$table, width)
})
}, ResizableColumns.prototype.totalColumnWidths = function() {
var total;
return total = 0, this.$tableHeaders.each(function(_, el) {
return total += parseFloat($(el)[0].style.width.replace("%", ""))
}), total
}, ResizableColumns.prototype.pointerdown = function(e) {
var $currentGrip, $leftColumn, $rightColumn, startPosition, widths, _this = this;
return e.preventDefault(), startPosition = pointerX(e), $currentGrip = $(e.currentTarget), $leftColumn = $currentGrip.data("th"), $rightColumn = this.$tableHeaders.eq(this.$tableHeaders.index($leftColumn) + 1), widths = {
left: parseWidth($leftColumn[0]),
right: parseWidth($rightColumn[0])
}, this.$table.addClass("rc-table-resizing"), $(document).on("mousemove.rc touchmove.rc", function(e) {
var difference;
return difference = (pointerX(e) - startPosition) / _this.$table.width() * 100, setWidth($rightColumn[0], _this.$table, widths.right - difference), setWidth($leftColumn[0], _this.$table, widths.left + difference)
}), $(document).one("mouseup touchend", function() {
return $(document).off("mousemove.rc touchmove.rc"), _this.$table.removeClass("rc-table-resizing"), _this.syncHandleWidths(), _this.saveColumnWidths()
})
}, {
restrict: "C",
priority: 999,
require: "ngTable",
link: function(scope, element, args, ngTable) {
var data;
scope.$watch("$data", function() {
data.destroy(), data = new ResizableColumns(element)
}), scope.$watch(function() {
return element[0].clientWidth
}, function() {
data.syncHandleWidths()
}), data = new ResizableColumns(element, !0)
}
}
}), angular.module("voyager.search").component("vsBotSearch", {
templateUrl: "src/bot/bot-search.html",
controller: function(searchService, $location, $scope) {
function _doSearch() {
var _params = $location.search();
searchService.doSearch2(_params).then(function(res) {
vm.list = res.data.response.docs, vm.hasMore = 50 === vm.list.length
})
}
var vm = this;
vm.hasMore = !0, $scope.$on("$locationChangeSuccess", function() {
if ("/bot" === $location.path()) {
var page = $location.search().page;
angular.isDefined(page) && parseInt(page) !== vm.page && (vm.page = parseInt(page), searchService.setPage(vm.page), _doSearch())
}
}), vm.$onInit = function() {
vm.page = 1, angular.isDefined($location.search().page) && (vm.page = parseInt($location.search().page)), searchService.setItemsPerPage(50), searchService.setPage(vm.page), _doSearch()
}
}
});
var VoyagerHome;
! function(VoyagerHome) {
var QuickLinks = function() {
function QuickLinks() {
this.templateUrl = "src/home/quick-links.html", this.bindings = {
title: "@",
list: "<"
}, this.controller = Controller
}
return QuickLinks
}();
VoyagerHome.QuickLinks = QuickLinks;
var Controller = function() {
function Controller(savedSearchService, $scope, $timeout, sugar) {
this.savedSearchService = savedSearchService, this.$scope = $scope, this.$timeout = $timeout, this.sugar = sugar, this.categories = []
}
return Controller.prototype.$onChanges = function(changesObj) {
if (changesObj.list && changesObj.list.currentValue) {
var categoryMap = this.sugar.toMapList("categories", changesObj.list.currentValue),
categoryList = this.sugar.mapToList(categoryMap);
if (categoryList.length > 0) {
var others = changesObj.list.currentValue.filter(function(item) {
return void 0 === item.categories
});
others.length > 0 && categoryList.push({
key: "Others",
list: others
}), this.categories = _.sortBy(categoryList, "title"), this.categories[0].displayState = "in"
}
}
}, Controller.prototype.applyCollection = function(saved) {
this.savedSearchService.applySavedSearch(saved, this.$scope)
}, Controller.prototype.toggleDisplayState = function(category) {
this.$timeout(function() {
category.displayState = "in" === category.displayState ? "" : "in"
}, 0)
}, Controller
}()
}(VoyagerHome || (VoyagerHome = {}));
var VoyagerHome;
! function(VoyagerHome) {
function init() {
angular.module("voyager.home").component("vsQuickLinks", new VoyagerHome.QuickLinks)
}
VoyagerHome.init = init
}(VoyagerHome || (VoyagerHome = {})), VoyagerHome.init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment