3 Handlebars.registerHelper('mkws-json', function(obj) {
4 return mkws.$.toJSON(obj);
8 // This is intended to handle paragraphs from Wikipedia, hence the
9 // rather hacky code to remove numbered references.
11 Handlebars.registerHelper('mkws-paragraphs', function(obj, nPara, nSent) {
14 // For some reason, Handlebars provides the value
15 // {"hash":{},"data":{}} for parameters that are not provided. So we
16 // have to be prepared for actual numbers, explicitly undefined
17 // values and this dumb magic value.
18 if (obj && (nPara === undefined || nPara.hasOwnProperty('hash') || nPara == 0 || nPara > obj.length)) {
21 if (nSent === undefined || nSent.hasOwnProperty('hash') || nSent == 0) {
25 for (var i = 0; i < nPara; i++) {
26 // Remove numbered references such as "[1,3,4]" from text
27 var text = obj[i].replace(/\[[0-9,]+\]/g, '');
28 // Next line from http://stackoverflow.com/questions/18914629/split-string-into-sentences-in-javascript
29 var sentences = text.replace(/([.?!])\s*(?=[A-Z])/g, "$1|").split("|");
30 if (sentences.length > nSent)
31 sentences.length = nSent;
33 acc.push('<p>', sentences.join(' '), '</p>');
34 nSent -= sentences.length;
43 Handlebars.registerHelper('mkws-translate', function(s) {
48 // We need {{mkws-attr '@name'}} because Handlebars can't parse {{@name}}
49 Handlebars.registerHelper('mkws-attr', function(attrName) {
50 return this[attrName];
55 * Use as follows: {{#mkws-if-any NAME1 having="NAME2"}}
56 * Applicable when NAME1 is the name of an array
57 * The guarded code runs only if at least one element of the NAME1
58 * array has a subelement called NAME2.
60 Handlebars.registerHelper('mkws-if-any', function(items, options) {
61 var having = options.hash.having;
62 for (var i in items) {
64 if (!having || item[having]) {
65 return options.fn(this);
72 Handlebars.registerHelper('mkws-first', function(items, options) {
73 var having = options.hash.having;
74 for (var i in items) {
76 if (!having || item[having]) {
77 return options.fn(item);
84 Handlebars.registerHelper('mkws-commaList', function(items, options) {
87 for (var i in items) {
88 if (i > 0) out += ", ";
89 out += options.fn(items[i])
96 Handlebars.registerHelper('mkws-index1', function(obj) {
97 return obj.data.index + 1;
100 Handlebars.registerHelper('mkws-repeat', function(count, options) {
102 for (var i = 0; i < count; i++) {
103 out += options.fn(this);
107 /*! MKWS, the MasterKey Widget Set.
108 * Copyright (C) 2013-2014 Index Data
109 * See the file LICENSE for details
112 "use strict"; // HTML5: disable for log_level >= 2
115 // Set up global mkws object. Contains truly global state such as SP
116 // authentication, and a hash of team objects, indexed by team-name.
118 // We set it as a property of window to make the global explicit as
119 // some things complain about an implicit global.
121 $: $, // Our own local copy of the jQuery object
122 authenticated: false,
123 authenticating: false,
125 log_level: 1, // Will be overridden from mkws.config, but
126 // initial value allows jQuery popup to use logging.
128 widgetType2function: {},
129 defaultTemplates: {},
133 "Authors": "Autoren",
134 "Subjects": "Schlagwörter",
135 "Sources": "Daten und Quellen",
136 "source": "datenquelle",
137 "Facets": "Termlisten",
139 "Prev": "Zurück",
141 "Sort by": "Sortieren nach",
142 "and show": "und zeige",
143 "per page": "pro Seite",
144 "Displaying": "Zeige",
152 "Subject": "Schlagwort",
153 "subject": "schlagwort",
155 "Records": "Datensätze",
156 "Targets": "Datenbanken",
162 "Authors": "Forfattere",
166 "Facets": "Termlists",
167 "Next": "Næste",
169 "Search": "Søg",
170 "Sort by": "Sorter efter",
171 "and show": "og vis",
172 "per page": "per side",
173 "Displaying": "Viser",
178 "Author": "Forfatter",
179 "author": "forfatter",
181 "Subject": "Emneord",
182 "subject": "emneord",
183 "Location": "Lokation",
192 // We may be using a separate copy
193 if (typeof(mkws_jQuery) !== "undefined") {
194 mkws.$ = mkws_jQuery;
199 mkws.log = function(string) {
203 if (typeof console === "undefined" || typeof console.log === "undefined") { /* ARGH!!! old IE */
207 // you need to disable use strict at the top of the file!!!
208 if (mkws.log_level >= 3) {
209 // Works in Chrome; not sure about elsewhere
211 } else if (mkws.log_level >= 2) {
212 console.log(">>> called from function " + arguments.callee.caller.name + ' <<<');
218 // Translation function.
219 mkws.M = function(word) {
220 var lang = mkws.config.lang;
222 if (!lang || !mkws.locale_lang[lang])
225 return mkws.locale_lang[lang][word] || word;
229 // This function is taken from a StackOverflow answer
230 // http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript/901144#901144
231 mkws.getParameterByName = function(name, url) {
232 if (!url) url = location.search;
233 name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
234 var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
235 results = regex.exec(url);
236 return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
240 mkws.registerWidgetType = function(name, fn) {
241 if(mkws._old2new.hasOwnProperty(name)) {
242 mkws.log("Warning: registerWidgetType old widget name: " + name + " => " + mkws._old2new[name]);
243 name = mkws._old2new[name];
246 mkws.widgetType2function[name] = fn;
247 mkws.log("registered widget-type '" + name + "'");
250 mkws.promotionFunction = function(name) {
251 return mkws.widgetType2function[name];
255 mkws.setMkwsConfig = function(overrides) {
256 // Set global log_level flag early so that mkws.log() works
257 var tmp = overrides.log_level;
258 if (typeof(tmp) !== 'undefined') mkws.log_level = tmp;
260 var config_default = {
261 use_service_proxy: true,
262 pazpar2_url: undefined,
263 pp2_hostname: "sp-mkws.indexdata.com",
264 pp2_path: "service-proxy/",
265 service_proxy_auth: undefined,
266 sp_auth_path: undefined,
267 sp_auth_query: "command=auth&action=perconfig",
268 sp_auth_credentials: undefined,
270 sort_options: [["relevance"], ["title:1", "title"], ["date:0", "newest"], ["date:1", "oldest"]],
271 perpage_options: [10, 20, 30, 50],
272 sort_default: "relevance",
274 show_lang: true, /* show/hide language menu */
275 show_sort: true, /* show/hide sort menu */
276 show_perpage: true, /* show/hide perpage menu */
277 show_switch: true, /* show/hide switch menu */
278 lang_options: [], /* display languages links for given languages, [] for all */
279 facets: ["xtargets", "subject", "author"], /* display facets, in this order, [] for none */
280 responsive_design_width: undefined, /* a page with less pixel width considered as narrow */
281 log_level: 1, /* log level for development: 0..2 */
282 template_vars: {}, /* values that may be exposed to templates */
287 mkws.config = mkws.objectInheritingFrom(config_default);
288 for (var k in overrides) {
289 mkws.config[k] = overrides[k];
294 // This code is from Douglas Crockford's article "Prototypal Inheritance in JavaScript"
295 // http://javascript.crockford.com/prototypal.html
296 // mkws.objectInheritingFrom behaves the same as Object.create,
297 // but since the latter is not available in IE8 we can't use it.
299 mkws.objectInheritingFrom = function(o) {
306 // The following functions are dispatchers for team methods that
307 // are called from the UI using a team-name rather than implicit
309 mkws.switchView = function(tname, view) {
310 mkws.teams[tname].switchView(view);
313 mkws.showDetails = function(tname, prefixRecId) {
314 mkws.teams[tname].showDetails(prefixRecId);
317 mkws.limitTarget = function(tname, id, name) {
318 mkws.teams[tname].limitTarget(id, name);
321 mkws.limitQuery = function(tname, field, value) {
322 mkws.teams[tname].limitQuery(field, value);
325 mkws.limitCategory = function(tname, id) {
326 mkws.teams[tname].limitCategory(id);
329 mkws.delimitTarget = function(tname, id) {
330 mkws.teams[tname].delimitTarget(id);
333 mkws.delimitQuery = function(tname, field, value) {
334 mkws.teams[tname].delimitQuery(field, value);
337 mkws.showPage = function(tname, pageNum) {
338 mkws.teams[tname].showPage(pageNum);
341 mkws.pagerPrev = function(tname) {
342 mkws.teams[tname].pagerPrev();
345 mkws.pagerNext = function(tname) {
346 mkws.teams[tname].pagerNext();
350 mkws.pazpar2_url = function() {
351 if (mkws.config.pazpar2_url) {
352 mkws.log("using pre-baked pazpar2_url '" + mkws.config.pazpar2_url + "'");
353 return mkws.config.pazpar2_url;
355 var s = document.location.protocol + "//" + mkws.config.pp2_hostname + "/" + mkws.config.pp2_path;
356 mkws.log("generated pazpar2_url '" + s + "'");
362 // We put a session token in window.name, as it's the only place to
363 // keep data that is preserved across reloads and within-site
364 // navigation. pz2.js picks this up and uses it as part of the
365 // cookie-name, to ensure we get a new session when we need one.
367 // We want to use different sessions for different windows/tabs (so
368 // they don't receive each other's messages), different hosts and
369 // different paths on a host (since in general these will
370 // authenticate as different libraries). So the window name needs to
371 // include the hostname and the path from the URL, plus the token.
375 token = window.name.replace(/.*\//, '');
376 mkws.log("Reusing existing window token '" + token + "'");
378 // Incredible that the standard JavaScript runtime doesn't define a
379 // unique windowId. Instead, we have to make one up. And since there's
380 // no global area shared between windows, the best we can do for
381 // ensuring uniqueness is generating a random ID and crossing our
384 // Ten chars from 26 alpha-numerics = 36^10 = 3.65e15 combinations.
385 // At one per second, it will take 116 million years to duplicate a token
386 token = Math.random().toString(36).slice(2, 12);
387 mkws.log("Generated new window token '" + token + "'");
390 window.name = window.location.hostname + window.location.pathname + '/' + token;
391 mkws.log("Using window.name '" + window.name + "'");
394 // wrapper to provide local copy of the jQuery object.
397 var _old2new = { // Maps old-style widget names to new-style
398 'Authname': 'auth-name',
399 'ConsoleBuilder': 'console-builder',
400 'Coverart': 'cover-art',
401 'GoogleImage': 'google-image',
403 'MOTDContainer': 'motd-container',
404 'Perpage': 'per-page',
405 'SearchForm': 'search-form',
406 'ReferenceUniverse': 'reference-universe',
407 'Termlists': 'facets'
409 // Annoyingly, there is no built-in way to invert a hash
411 for (var key in _old2new) {
412 if(_old2new.hasOwnProperty(key)) {
413 _new2old[_old2new[key]] = key;
417 mkws._old2new = _old2new;
419 function handleNodeWithTeam(node, callback) {
420 // First branch for DOM objects; second branch for jQuery objects
421 var classes = node.className || node.attr('class');
423 // For some reason, if we try to proceed when classes is
424 // undefined, we don't get an error message, but this
425 // function and its callers, up several stack level,
426 // silently return. What a crock.
427 log("handleNodeWithTeam() called on node with no classes");
430 var list = classes.split(/\s+/)
433 for (var i = 0; i < list.length; i++) {
435 if (cname.match(/^mkws-team-/)) {
436 // New-style teamnames of the form mkws-team-xyz
437 teamName = cname.replace(/^mkws-team-/, '');
438 } else if (cname.match(/^mkwsTeam_/)) {
439 // Old-style teamnames of the form mkwsTeam_xyz
440 teamName = cname.replace(/^mkwsTeam_/, '');
441 } else if (cname.match(/^mkws-/)) {
442 // New-style names of the from mkws-foo-bar
443 type = cname.replace(/^mkws-/, '');
444 } else if (cname.match(/^mkws/)) {
445 // Old-style names of the form mkwsFooBar
446 var tmp = cname.replace(/^mkws/, '');
447 type = _old2new[tmp] || tmp.toLowerCase();
451 // Widgets without a team are on team "AUTO"
454 // Autosearch widgets don't join team AUTO if there is already an
455 // autosearch on the team or the team has otherwise gotten a query
456 if (node.getAttribute("autosearch")) {
457 if (mkws.autoHasAuto ||
458 mkws.teams["AUTO"] && mkws.teams["AUTO"].config["query"]) {
459 log("AUTO team already has a query, using unique team");
462 mkws.autoHasAuto = true;
466 // Widgets on team "UNIQUE" get a random team
467 if (teamName === "UNIQUE") {
468 teamName = Math.floor(Math.random() * 100000000).toString();
471 callback.call(node, teamName, type);
475 function resizePage() {
476 var threshhold = mkws.config.responsive_design_width;
477 var width = $(window).width();
478 var from, to, method;
480 if ((mkws.width === undefined || mkws.width > threshhold) &&
481 width <= threshhold) {
482 from = "wide"; to = "narrow"; method = "hide";
483 } else if ((mkws.width === undefined || mkws.width <= threshhold) &&
484 width > threshhold) {
485 from = "narrow"; to = "wide"; method = "show";
490 log("changing from " + from + " to " + to + ": " + width);
491 for (var tname in mkws.teams) {
492 var team = mkws.teams[tname];
493 team.visitWidgets(function(t, w) {
494 var w1 = team.widget(t + "-container-" + from);
495 var w2 = team.widget(t + "-container-" + to);
501 w.node.appendTo(w2.node);
504 team.queue("resize-" + to).publish();
511 * Run service-proxy authentication in background (after page load).
512 * The username/password is configured in the apache config file
515 function authenticateSession(auth_url, auth_domain, pp2_url) {
516 mkws.authenticating = true;
517 log("service proxy authentication on URL: " + auth_url);
520 auth_domain = pp2_url.replace(/^(https?:)?\/\/(.*?)\/.*/, '$2');
521 log("guessed auth_domain '" + auth_domain + "' from pp2_url '" + pp2_url + "'");
524 var request = new pzHttpRequest(auth_url, function(err) {
525 alert("HTTP call for authentication failed: " + err)
529 request.get(null, function(data) {
530 mkws.authenticating = false;
531 if (!$.isXMLDoc(data)) {
532 alert("Service Proxy authentication response is not a valid XML document");
535 var status = $(data).find("status");
536 if (status.text() != "OK") {
537 var message = $(data).find("message");
538 alert("Service Proxy authentication response: " + status.text() + " (" + message.text() + ")");
542 log("service proxy authentication successful");
543 mkws.authenticated = true;
544 var authName = $(data).find("displayName").text();
545 // You'd think there would be a better way to do this:
546 var realm = $(data).find("realm:not(realmAttributes realm)").text();
547 for (var teamName in mkws.teams) {
548 mkws.teams[teamName].queue("authenticated").publish(authName, realm);
556 function runAutoSearches() {
557 log("running auto searches");
559 for (var teamName in mkws.teams) {
560 mkws.teams[teamName].queue("ready").publish();
565 function selectorForAllWidgets() {
566 if (mkws.config && mkws.config.scan_all_nodes) {
567 // This is the old version, which works by telling jQuery to
568 // find every node that has a class beginning with "mkws". In
569 // theory it should be slower than the class-based selector; but
570 // instrumentation suprisingly shows this is consistently
571 // faster. It also has the advantage that any widgets of
572 // non-registered types are logged as warnings rather than
574 return '[class^="mkws"],[class*=" mkws"]';
576 // This is the new version, which works by looking up the
577 // specific classes of all registered widget types and their
578 // resize containers. Because all it requires jQuery to do is
579 // some hash lookups in pre-built tables, it should be very
580 // fast; but it silently ignores widgets of unregistered types.
582 for (var type in mkws.widgetType2function) {
584 s += '.mkws-' + type;
585 s += ',.mkws-' + type + "-container-wide";
586 s += ',.mkws-' + type + "-container-narrow";
587 // Annoyingly, we also need to recognise old-style names
588 var oldtype = _new2old[type] || type.charAt(0).toUpperCase() + type.slice(1);
589 s += ',.mkws' + oldtype;
590 s += ',.mkws' + oldtype + "-Container-wide";
591 s += ',.mkws' + oldtype + "-Container-narrow";
598 function makeWidgetsWithin(level, node) {
599 if (node) var widgetNodes = node.find(selectorForAllWidgets());
600 else widgetNodes = $(selectorForAllWidgets());
601 // Return false if we parse no widgets
602 if (widgetNodes.length < 1) return false;
603 widgetNodes.each(function() {
604 handleNodeWithTeam(this, function(tname, type) {
605 var myTeam = mkws.teams[tname];
607 myTeam = mkws.teams[tname] = mkws.makeTeam($, tname);
610 var oldHTML = this.innerHTML;
611 var myWidget = mkws.makeWidget($, myTeam, type, this);
612 myTeam.addWidget(myWidget);
613 var newHTML = this.innerHTML;
614 if (newHTML !== oldHTML) {
615 myTeam.log("widget " + type + " HTML changed: reparsing");
616 makeWidgetsWithin(level+1, $(this));
624 // The second "rootsel" parameter is passed to jQuery and is a DOM node
625 // or a selector string you would like to constrain the search for widgets to.
627 // This function has no side effects if run again on an operating session,
628 // even if the element/selector passed causes existing widgets to be reparsed:
630 // (TODO: that last bit isn't true and we currently have to avoid reinitialising
631 // widgets, MKWS-261)
633 // * configuration is not regenerated
634 // * authentication is not performed again
635 // * autosearches are not re-run
636 mkws.init = function(message, rootsel) {
637 var greet = "MKWS initialised";
638 if (rootsel) greet += " (limited to " + rootsel + ")"
639 if (message) greet += " :: " + message;
642 // MKWS is not active until init() has been run against an object with widget nodes.
643 // We only set initial configuration when MKWS is first activated.
644 if (!mkws.isActive) {
645 var widgetSelector = selectorForAllWidgets();
646 if ($(widgetSelector).length < 1) {
647 mkws.log("no widgets found");
651 // Initial configuration
652 mkws.autoHasAuto = false;
654 if (typeof mkws_config === 'undefined') {
655 log("setting empty config");
658 log("using config: " + $.toJSON(mkws_config));
659 saved_config = mkws_config;
661 mkws.setMkwsConfig(saved_config);
663 for (var key in mkws.config) {
664 if (mkws.config.hasOwnProperty(key)) {
665 if (key.match(/^language_/)) {
666 var lang = key.replace(/^language_/, "");
667 // Copy custom languages into list
668 mkws.locale_lang[lang] = mkws.config[key];
669 log("added locally configured language '" + lang + "'");
674 var lang = mkws.getParameterByName("lang") || mkws.config.lang;
675 if (!lang || !mkws.locale_lang[lang]) {
676 mkws.config.lang = ""
678 mkws.config.lang = lang;
681 log("using language: " + (mkws.config.lang ? mkws.config.lang : "none"));
683 // protocol independent link for pazpar2: "//mkws/sp" -> "https://mkws/sp"
684 if (mkws.pazpar2_url().match(/^\/\//)) {
685 mkws.config.pazpar2_url = document.location.protocol + mkws.config.pazpar2_url;
686 log("adjusted protocol independent link to " + mkws.pazpar2_url());
689 if (mkws.config.responsive_design_width) {
690 // Responsive web design - change layout on the fly based on
691 // current screen width. Required for mobile devices.
692 $(window).resize(resizePage);
693 // initial check after page load
694 $(document).ready(resizePage);
699 // If we've made no widgets, return without starting an SP session
700 // or marking MKWS active.
701 if (makeWidgetsWithin(1, rootsel ? $(rootsel) : undefined) === false) {
706 log("walking MKWS nodes took " + (now-then) + " ms");
707 for (var tName in mkws.teams) {
708 var myTeam = mkws.teams[tName]
710 myTeam.log("made PZ2 object");
712 myTeam.visitWidgets(function(t, w) {
713 log(" has widget of type '" + t + "': " + w);
718 function sp_auth_url(config) {
719 if (config.service_proxy_auth) {
720 mkws.log("using pre-baked sp_auth_url '" + config.service_proxy_auth + "'");
721 return config.service_proxy_auth;
724 s += config.sp_auth_hostname ? config.sp_auth_hostname : config.pp2_hostname;
726 s += config.sp_auth_path ? config.sp_auth_path : config.pp2_path;
727 var q = config.sp_auth_query;
731 var c = config.sp_auth_credentials;
733 s += ('&username=' + c.substr(0, c.indexOf('/')) +
734 '&password=' + c.substr(c.indexOf('/')+1));
736 mkws.log("generated sp_auth_url '" + s + "'");
741 if (mkws.config.use_service_proxy && !mkws.authenticated && !mkws.authenticating) {
742 authenticateSession(sp_auth_url(mkws.config),
743 mkws.config.service_proxy_auth_domain,
745 } else if (!mkws.authenticating) {
746 // raw pp2 or we have a session already open
750 mkws.isActive = true;
754 $(document).ready(function() {
755 if (!window.mkws_noready && !mkws.authenticating && !mkws.active) {
761 // Factory function for team objects. As much as possible, this uses
762 // only member variables (prefixed "m_") and inner functions with
765 // Some functions are visible as member-functions to be called from
766 // outside code -- specifically, from generated HTML. These functions
767 // are that.switchView(), showDetails(), limitTarget(), limitQuery(),
768 // limitCategory(), delimitTarget(), delimitQuery(), showPage(),
769 // pagerPrev(), pagerNext().
771 // Before the team can be used for searching and related operations,
772 // its pz2 object must be created by calling team.makePz2().
774 mkws.makeTeam = function($, teamName) {
776 var m_teamName = teamName;
777 var m_submitted = false;
778 var m_query; // initially undefined
779 var m_sortOrder; // will be set below
780 var m_perpage; // will be set below
781 var m_filterSet = filterSet(that);
782 var m_totalRecordCount = 0;
783 var m_currentPage = 1;
784 var m_currentRecordId = '';
785 var m_currentRecordData = null;
787 // Timestamps for logging
791 var m_paz; // will be initialised below
792 var m_templateText = {}; // widgets can register templates to be compiled
793 var m_template = {}; // compiled templates, from any source
794 var m_widgets = {}; // Maps widget-type to array of widget objects
795 var m_gotRecords = false;
797 var config = mkws.objectInheritingFrom(mkws.config);
798 that.config = config;
800 that.toString = function() { return '[Team ' + teamName + ']'; };
802 // Accessor methods for individual widgets: readers
803 that.name = function() { return m_teamName; };
804 that.submitted = function() { return m_submitted; };
805 that.sortOrder = function() { return m_sortOrder; };
806 that.perpage = function() { return m_perpage; };
807 that.query = function() { return m_query; };
808 that.totalRecordCount = function() { return m_totalRecordCount; };
809 that.currentPage = function() { return m_currentPage; };
810 that.currentRecordId = function() { return m_currentRecordId; };
811 that.currentRecordData = function() { return m_currentRecordData; };
812 that.filters = function() { return m_filterSet; };
813 that.gotRecords = function() { return m_gotRecords; };
815 // Accessor methods for individual widgets: writers
816 that.set_sortOrder = function(val) { m_sortOrder = val };
817 that.set_perpage = function(val) { m_perpage = val };
820 // The following PubSub code is modified from the jQuery manual:
821 // http://api.jquery.com/jQuery.Callbacks/
824 // team.queue("eventName").subscribe(function(param1, param2 ...) { ... });
825 // team.queue("eventName").publish(arg1, arg2, ...);
830 var callbacks = $.Callbacks();
832 publish: callbacks.fire,
833 subscribe: callbacks.add,
834 unsubscribe: callbacks.remove
844 var timestamp = (((now - m_logTime.start)/1000).toFixed(3) + " (+" +
845 ((now - m_logTime.last)/1000).toFixed(3) + ") ");
846 m_logTime.last = now;
847 mkws.log(m_teamName + ": " + timestamp + s);
848 that.queue("log").publish(m_teamName, timestamp, s);
853 log("making new widget team");
855 m_sortOrder = config.sort_default;
856 m_perpage = config.perpage_default;
858 // pz2.js event handlers:
865 function onBytarget(data) {
867 queue("targets").publish(data);
870 function onStat(data) {
871 queue("stat").publish(data);
872 var hitcount = parseInt(data.hits[0], 10);
873 if (!m_gotRecords && hitcount > 0) {
875 queue("firstrecords").publish(hitcount);
877 if (parseInt(data.activeclients[0], 10) === 0) {
879 queue("complete").publish(hitcount);
883 function onTerm(data) {
885 queue("facets").publish(data);
888 function onShow(data, teamName) {
890 m_totalRecordCount = data.merged;
891 log("found " + m_totalRecordCount + " records");
892 queue("pager").publish(data);
893 queue("records").publish(data);
896 function onRecord(data, args, teamName) {
898 // FIXME: record is async!!
899 clearTimeout(m_paz.recordTimer);
900 queue("record").publish(data);
901 var detRecordDiv = findnode(recordDetailsId(data.recid[0]));
902 if (detRecordDiv.length) {
903 // in case on_show was faster to redraw element
906 m_currentRecordData = data;
907 var recordDiv = findnode('.' + recordElementId(m_currentRecordData.recid[0]));
908 var html = renderDetails(m_currentRecordData);
909 $(recordDiv).append(html);
913 // create a parameters array and pass it to the pz2's constructor
914 // then register the form submit event with the pz2.search function
915 // autoInit is set to true on default
916 that.makePz2 = function() {
917 log("m_queues=" + $.toJSON(m_queues));
919 "windowid": teamName,
920 "pazpar2path": mkws.pazpar2_url(),
921 "usesessions" : config.use_service_proxy ? false : true,
922 "showtime": 500, //each timer (show, stat, term, bytarget) can be specified this way
923 "termlist": config.facets.join(',')
926 params.oninit = onInit;
927 if (m_queues.targets) {
928 params.onbytarget = onBytarget;
929 log("setting bytarget callback");
932 params.onstat = onStat;
933 log("setting stat callback");
935 if (m_queues.facets && config.facets.length) {
936 params.onterm = onTerm;
937 log("setting term callback");
939 if (m_queues.records) {
940 log("setting show callback");
941 params.onshow = onShow;
942 // Record callback is subscribed from records callback
943 log("setting record callback");
944 params.onrecord = onRecord;
947 m_paz = new pz2(params);
948 log("created main pz2 object");
952 // Used by the Records widget and onRecord()
953 function recordElementId(s) {
954 return 'mkws-rec_' + s.replace(/[^a-z0-9]/ig, '_');
956 that.recordElementId = recordElementId;
958 // Used by onRecord(), showDetails() and renderDetails()
959 function recordDetailsId(s) {
960 return 'mkws-det_' + s.replace(/[^a-z0-9]/ig, '_');
964 that.targetFiltered = function(id) {
965 return m_filterSet.targetFiltered(id);
969 that.limitTarget = function(id, name) {
970 log("limitTarget(id=" + id + ", name=" + name + ")");
971 m_filterSet.add(targetFilter(id, name));
972 if (m_query) triggerSearch();
977 that.limitQuery = function(field, value) {
978 log("limitQuery(field=" + field + ", value=" + value + ")");
979 m_filterSet.add(fieldFilter(field, value));
980 if (m_query) triggerSearch();
985 that.limitCategory = function(id) {
986 log("limitCategory(id=" + id + ")");
987 // Only one category filter at a time
988 m_filterSet.removeMatching(function(f) { return f.type === 'category' });
989 if (id !== '') m_filterSet.add(categoryFilter(id));
990 if (m_query) triggerSearch();
995 that.delimitTarget = function(id) {
996 log("delimitTarget(id=" + id + ")");
997 m_filterSet.removeMatching(function(f) { return f.type === 'target' });
998 if (m_query) triggerSearch();
1003 that.delimitQuery = function(field, value) {
1004 log("delimitQuery(field=" + field + ", value=" + value + ")");
1005 m_filterSet.removeMatching(function(f) { return f.type == 'field' &&
1006 field == f.field && value == f.value });
1007 if (m_query) triggerSearch();
1012 that.showPage = function(pageNum) {
1013 m_currentPage = pageNum;
1014 m_paz.showPage(m_currentPage - 1);
1018 that.pagerNext = function() {
1019 if (m_totalRecordCount - m_perpage*m_currentPage > 0) {
1026 that.pagerPrev = function() {
1027 if (m_paz.showPrev() != false)
1032 that.reShow = function() {
1034 m_paz.show(0, m_perpage, m_sortOrder);
1038 function resetPage() {
1040 m_totalRecordCount = 0;
1041 m_gotRecords = false;
1043 that.resetPage = resetPage;
1046 function newSearch(query, sortOrder, maxrecs, perpage, limit, targets, torusquery) {
1047 log("newSearch: " + query);
1049 if (config.use_service_proxy && !mkws.authenticated) {
1050 alert("searching before authentication");
1054 m_filterSet.removeMatching(function(f) { return f.type !== 'category' });
1055 triggerSearch(query, sortOrder, maxrecs, perpage, limit, targets, torusquery);
1056 switchView('records'); // In case it's configured to start off as hidden
1059 that.newSearch = newSearch;
1062 function triggerSearch(query, sortOrder, maxrecs, perpage, limit, targets, torusquery) {
1064 queue("navi").publish();
1066 // Continue to use previous query/sort-order unless new ones are specified
1067 if (query) m_query = query;
1068 if (sortOrder) m_sortOrder = sortOrder;
1069 if (perpage) m_perpage = perpage;
1070 if (targets) m_filterSet.add(targetFilter(targets, targets));
1072 var pp2filter = m_filterSet.pp2filter();
1073 var pp2limit = m_filterSet.pp2limit(limit);
1074 var pp2catLimit = m_filterSet.pp2catLimit();
1076 pp2filter = pp2filter ? pp2filter + "," + pp2catLimit : pp2catLimit;
1080 if (pp2limit) params.limit = pp2limit;
1081 if (maxrecs) params.maxrecs = maxrecs;
1083 if (!mkws.config.use_service_proxy)
1084 alert("can't narrow search by torusquery when not authenticated");
1085 params.torusquery = torusquery;
1088 log("triggerSearch(" + m_query + "): filters = " + m_filterSet.toJSON() + ", " +
1089 "pp2filter = " + pp2filter + ", params = " + $.toJSON(params));
1091 m_paz.search(m_query, m_perpage, m_sortOrder, pp2filter, undefined, params);
1094 // fetch record details to be retrieved from the record queue
1095 that.fetchDetails = function(recId) {
1096 log("fetchDetails() requesting record '" + recId + "'");
1097 m_paz.record(recId);
1101 // switching view between targets and records
1102 function switchView(view) {
1103 var targets = widgetNode('targets');
1104 var results = widgetNode('results') || widgetNode('records');
1105 var blanket = widgetNode('blanket');
1106 var motd = widgetNode('motd');
1110 if (targets) $(targets).show();
1111 if (results) $(results).hide();
1112 if (blanket) $(blanket).hide();
1113 if (motd) $(motd).hide();
1116 if (targets) $(targets).hide();
1117 if (results) $(results).show();
1118 if (blanket) $(blanket).show();
1119 if (motd) $(motd).hide();
1122 alert("Unknown view '" + view + "'");
1125 that.switchView = switchView;
1128 // detailed record drawing
1129 that.showDetails = function(recId) {
1130 var oldRecordId = m_currentRecordId;
1131 m_currentRecordId = recId;
1133 // remove current detailed view if any
1134 findnode('#' + recordDetailsId(oldRecordId)).remove();
1136 // if the same clicked, just hide
1137 if (recId == oldRecordId) {
1138 m_currentRecordId = '';
1139 m_currentRecordData = null;
1142 // request the record
1143 log("showDetails() requesting record '" + recId + "'");
1144 m_paz.record(recId);
1148 // Finds the node of the specified class within the current team
1149 function findnode(selector, teamName) {
1150 teamName = teamName || m_teamName;
1152 if (teamName === 'AUTO') {
1153 selector = (selector + '.mkws-team-' + teamName + ',' +
1154 selector + ':not([class^="mkws-team"],[class*=" mkws-team"])');
1156 selector = selector + '.mkws-team-' + teamName;
1159 var node = $(selector);
1160 //log('findnode(' + selector + ') found ' + node.length + ' nodes');
1165 function widgetNode(type) {
1166 var w = that.widget(type);
1167 return w ? w.node : undefined;
1170 function renderDetails(data, marker) {
1171 var template = loadTemplate("details");
1172 var details = template(data);
1173 return '<div class="mkws-details mkwsDetails mkwsTeam_' + m_teamName + '" ' +
1174 'id="' + recordDetailsId(data.recid[0]) + '">' + details + '</div>';
1176 that.renderDetails = renderDetails;
1179 that.registerTemplate = function(name, text) {
1180 if(mkws._old2new.hasOwnProperty(name)) {
1181 mkws.log("Warning: registerTemplate old widget name: " + name + " => " + mkws._old2new[name]);
1182 name = mkws._old2new[name];
1184 m_templateText[name] = text;
1188 function loadTemplate(name, fallbackString) {
1189 if(mkws._old2new.hasOwnProperty(name)) {
1190 mkws.log("Warning loadTemplate: old widget name: " + name + " => " + mkws._old2new[name]);
1191 name = mkws._old2new[name];
1194 var template = m_template[name];
1195 if (template === undefined && Handlebars.compile) {
1197 var node = $(".mkws-template-" + name + " .mkws-team-" + that.name());
1198 if (node && node.length < 1) {
1199 node = $(".mkws-template-" + name);
1201 if (node) source = node.html();
1202 if (!source) source = m_templateText[name];
1204 template = Handlebars.compile(source);
1205 log("compiled template '" + name + "'");
1208 //if (template === undefined) template = mkws_templatesbyteam[m_teamName][name];
1209 if (template === undefined && Handlebars.templates) {
1210 template = Handlebars.templates["mkws-template-" + name];
1212 if (template === undefined && mkws.defaultTemplates) {
1213 template = mkws.defaultTemplates[name];
1216 m_template[name] = template;
1220 log("No MKWS template for " + name);
1224 that.loadTemplate = loadTemplate;
1227 that.addWidget = function(w) {
1228 if (m_widgets[w.type] === undefined) {
1229 m_widgets[w.type] = [ w ];
1231 m_widgets[w.type].push(w);
1235 that.widget = function(type) {
1236 var list = m_widgets[type];
1240 if (list.length > 1) {
1241 alert("widget('" + type + "') finds " + list.length + " widgets: using first");
1246 that.visitWidgets = function(callback) {
1247 for (var type in m_widgets) {
1248 var list = m_widgets[type];
1249 for (var i = 0; i < list.length; i++) {
1250 var res = callback(type, list[i]);
1251 if (res !== undefined) {
1262 // Factory function for sets of filters.
1263 function filterSet(team) {
1269 that.toJSON = function() {
1270 return mkws.$.toJSON(m_list);
1273 that.add = function(filter) {
1274 m_list.push(filter);
1277 that.visitTargets = function(callback) {
1278 for (var i in m_list) {
1279 var filter = m_list[i];
1280 if (filter.type === 'target') {
1281 callback(filter.id, filter.name);
1286 that.visitFields = function(callback) {
1287 for (var i in m_list) {
1288 var filter = m_list[i];
1289 if (filter.type === 'field') {
1290 callback(filter.field, filter.value);
1295 that.visitCategories = function(callback) {
1296 for (var i in m_list) {
1297 var filter = m_list[i];
1298 if (filter.type === 'category') {
1299 callback(filter.id);
1304 that.removeMatching = function(matchFn) {
1306 for (var i in m_list) {
1307 var filter = m_list[i];
1308 if (matchFn(filter)) {
1309 m_team.log("removeMatching: removing filter " + mkws.$.toJSON(filter));
1311 m_team.log("removeMatching: keeping filter " + mkws.$.toJSON(filter));
1312 newList.push(filter);
1318 that.targetFiltered = function(id) {
1319 for (var i = 0; i < m_list.length; i++) {
1320 if (m_list[i].type === 'target' ||
1321 m_list[i].id === 'pz:id=' + id) {
1328 that.pp2filter = function() {
1331 that.visitTargets(function(id, name) {
1332 if (res) res += ",";
1333 if (id.match(/^[a-z:]+[=~]/)) {
1334 m_team.log("filter '" + id + "' already begins with SETTING OP");
1344 that.pp2limit = function(initial) {
1345 var res = initial || "";
1347 that.visitFields(function(field, value) {
1348 if (res) res += ",";
1349 res += field + "=" + value.replace(/[\\|,]/g, '\\$&');
1354 that.pp2catLimit = function() {
1357 that.visitCategories(function(id) {
1358 if (res) res += ",";
1359 res += "category~" + id.replace(/[\\|,]/g, '\\$&');
1368 // Factory functions for filters. These can be of several types.
1369 function targetFilter(id, name) {
1377 function fieldFilter(field, value) {
1385 function categoryFilter(id) {
1391 // Factory function for widget objects.
1392 mkws.makeWidget = function($, team, type, node) {
1393 // Static register of attributes that do not contribute to config
1395 id:1, 'class':1, style:1, name:1, action:1, type:1, size:1,
1396 value:1, width:1, valign:1
1403 config: mkws.objectInheritingFrom(team.config)
1411 that.toString = function() {
1412 return '[Widget ' + team.name() + ':' + type + ']';
1415 that.value = function() {
1419 // Returns the HTML of a subwidget of the specified type. It gets
1420 // the same attributes at the parent widget that invokes this
1421 // function, except where overrides are passed in. If defaults are
1422 // also provided, then these are used when the parent widget
1423 // provides no values.
1424 that.subwidget = function(type, overrides, defaults) {
1425 var attrs = { _team: team.name() };
1427 // Copy locally-set properties from the parent widget
1428 for (var name in this.config) {
1429 if (this.config.hasOwnProperty(name)) {
1430 attrs[name] = this.config[name];
1431 log(this + " copied property " + name + "='" + attrs[name] + "' to " + type + " subwidget");
1435 for (var name in overrides) {
1436 log(this + " overrode property " + name + "='" + overrides[name] + "' (was '" + attrs[name] + "') for " + type + " subwidget");
1437 attrs[name] = overrides[name];
1441 for (var name in defaults) {
1443 attrs[name] = defaults[name];
1444 log(this + " fell back to default property " + name + "='" + attrs[name] + "' for " + type + " subwidget");
1450 s.push('<div class="mkws', type, ' mkws-team-', attrs._team, '"');
1451 for (var name in attrs) {
1452 if (name !== '_team')
1453 s.push(' ', name, '="', attrs[name], '"');
1459 function expandValue(val) {
1460 if (val.match(/^!param!/)) {
1461 var param = val.replace(/^!param!/, '');
1462 val = mkws.getParameterByName(param);
1463 log("obtained val '" + val + "' from param '" + param + "'");
1465 alert("This page has a MasterKey widget that needs a val specified by the '" + param + "' parameter");
1467 } else if (val.match(/^!path!/)) {
1468 var index = val.replace(/^!path!/, '');
1469 var path = window.location.pathname.split('/');
1470 val = path[path.length - index];
1471 log("obtained val '" + val + "' from path-component '" + index + "'");
1473 alert("This page has a MasterKey widget that needs a val specified by the path-component " + index);
1475 } else if (val.match(/^!var!/)) {
1476 var name = val.replace(/^!var!/, '');
1477 val = window[name]; // It's ridiculous that this works
1478 log("obtained val '" + val + "' from variable '" + name + "'");
1480 alert("This page has a MasterKey widget that needs a val specified by the '" + name + "' variable");
1486 // Utility function for use by all widgets that can invoke autosearch.
1487 that.autosearch = function() {
1489 var query = this.config.autosearch;
1491 var old = this.team.config.query;
1493 // Stash this for subsequent inspection
1494 this.team.config.query = query;
1495 } else if (old === query) {
1496 this.log("duplicate autosearch: '" + query + "': ignoring");
1499 this.log("conflicting autosearch: '" + query + "' vs '" + old + "': ignoring");
1503 this.team.queue("ready").subscribe(function() {
1504 // Postpone testing for the configuration items: these are not
1505 // yet set for Record subclass widgets that fill them in in the
1506 // subclass, as widget.autosearch is called in the superclass,
1507 // before the subclass fiddles with the configuration.
1508 var sortOrder = that.config.sort;
1509 var maxrecs = that.config.maxrecs;
1510 var perpage = that.config.perpage;
1511 var limit = that.config.limit;
1512 var targets = that.config.targets;
1513 var targetfilter = that.config.targetfilter;
1514 var target = that.config.target;
1515 if (target) targetfilter = 'udb=="' + target + '"';
1517 var s = "running auto search: '" + query + "'";
1518 if (sortOrder) s += " sorted by '" + sortOrder + "'";
1519 if (maxrecs) s += " restricted to " + maxrecs + " records";
1520 if (perpage) s += " with " + perpage + " per page";
1521 if (limit) s += " limited by '" + limit + "'";
1522 if (targets) s += " in targets '" + targets + "'";
1523 if (targetfilter) s += " constrained by targetfilter '" + targetfilter + "'";
1526 that.team.newSearch(query, sortOrder, maxrecs, perpage, limit, targets, targetfilter);
1531 // Utility function for all widgets that want to hide in narrow windows
1532 that.hideWhenNarrow = function() {
1534 this.team.queue("resize-narrow").subscribe(function(n) {
1537 this.team.queue("resize-wide").subscribe(function(n) {
1543 for (var i = 0; i < node.attributes.length; i++) {
1544 var a = node.attributes[i];
1545 var val = expandValue(a.value);
1546 if (a.name === 'data-mkws-config') {
1547 // Treat as a JSON fragment configuring just this widget
1548 log(node + ": parsing config fragment '" + val + "'");
1551 data = $.parseJSON(val);
1552 for (var key in data) {
1553 log(node + ": adding config element " + key + "='" + data[key] + "'");
1554 that.config[key] = data[key];
1557 alert("Can't parse " + node + " data-mkws-config as JSON: " + val);
1559 } else if (a.name.match (/^data-mkws-/)) {
1560 var name = a.name.replace(/^data-mkws-/, '')
1561 that.config[name] = val;
1562 log(that + ": set data-mkws attribute " + name + "='" + val + "'");
1563 } else if (!ignoreAttrs[a.name]) {
1564 that.config[a.name] = val;
1565 log(that + ": set regular attribute " + a.name + "='" + val + "'");
1569 var fn = mkws.promotionFunction(type);
1572 log("made " + type + " widget(node=" + node + ")");
1573 } else if (type.match(/-Container-(narrow|wide)$/)) {
1574 // Not really a widget: no need to log its lack of promotion
1576 log("made UNPROMOTED widget(type=" + type + ", node=" + node + ")");
1581 (function($) { // jQuery wrapper
1583 // Functions follow for promoting the regular widget object into
1584 // widgets of specific types. These could be moved into their own
1588 mkws.registerWidgetType('targets', function() {
1589 if (!this.config.show_switch) return;
1592 this.node.html('No information available yet.');
1593 this.node.css("display", "none");
1595 this.team.queue("targets").subscribe(function(data) {
1596 // There is a bug in pz2.js wherein it makes each data object an array but
1597 // simply assigns properties to it.
1598 // TODO: remove this when PAZ-946 is addressed.
1600 for (var i = 0; i < data.length; i++) {
1602 cur.id = data[i].id;
1603 cur.hits = data[i].hits;
1604 cur.diagnostic = data[i].diagnostic;
1605 cur.message = data[i].message;
1606 cur.records = data[i].records;
1607 cur.state = data[i].state;
1608 cleandata.push(cur);
1611 var template = that.team.loadTemplate(that.config.template || "targets");
1612 that.node.html(template({data: cleandata}));
1617 mkws.registerWidgetType('stat', function() {
1619 this.team.queue("stat").subscribe(function(data) {
1620 var template = that.team.loadTemplate(that.config.template || "stat");
1621 that.node.html(template(data));
1626 mkws.registerWidgetType('pager', function() {
1630 this.team.queue("pager").subscribe(function(data) {
1631 var teamName = that.team.name();
1633 output.first = data.start + 1;
1634 output.last = data.start + data.num;
1635 output.count = data.merged;
1636 output.found = data.total;
1638 //client indexes pages from 1 but pz2 from 0
1640 var pages = Math.ceil(that.team.totalRecordCount() / that.team.perpage());
1641 var currentPage = that.team.currentPage();
1643 var firstClkbl = (currentPage - onsides > 0)
1644 ? currentPage - onsides
1646 var lastClkbl = firstClkbl + 2*onsides < pages
1647 ? firstClkbl + 2*onsides
1650 if (firstClkbl > 1) output.morePrev = true;
1651 if (lastClkbl < pages) output.moreNext = true;
1653 if (currentPage > 1) output.prevClick = "mkws.pagerPrev(\'" + teamName + "\');";
1656 for(var i = firstClkbl; i <= lastClkbl; i++) {
1659 if (i !== currentPage) {
1660 o.click = "mkws.showPage(\'" + teamName + "\', " + i + ");";
1662 output.pages.push(o);
1665 if (pages - currentPage > 0) output.nextClick = "mkws.pagerNext(\'" + teamName + "\')";
1667 var template = that.team.loadTemplate(that.config.template || "pager");
1668 that.node.html(template(output));
1672 mkws.registerWidgetType('details', function() {
1674 var recid = that.node.attr("data-mkws-recid");
1675 if (this.team.gotRecords()) {
1676 that.team.fetchDetails(recid);
1678 this.team.queue("firstrecords").subscribe(function() {
1679 that.team.fetchDetails(recid);
1682 this.team.queue("record").subscribe(function(data) {
1683 if ($.inArray(recid, data.recid) > -1) {
1684 var template = that.team.loadTemplate(that.config.template || "details");
1685 that.node.html(template(data));
1690 mkws.registerWidgetType('records', function() {
1692 var team = this.team;
1694 this.team.queue("records").subscribe(function(data) {
1695 for (var i = 0; i < data.hits.length; i++) {
1696 var hit = data.hits[i];
1697 hit.detailLinkId = team.recordElementId(hit.recid[0]);
1698 hit.detailClick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;";
1699 hit.containerClass = "mkws-summary mkwsSummary mkws-team-" + team.name();
1700 hit.containerClass += " " + hit.detailLinkId;
1701 // ### At some point, we may be able to move the
1702 // m_currentRecordId and m_currentRecordData members
1703 // from the team object into this widget.
1704 if (hit.recid == team.currentRecordId()) {
1705 if (team.currentRecordData()) {
1706 hit.renderedDetails = team.renderDetails(team.currentRecordData());
1710 var template = team.loadTemplate(that.config.template || "records");
1711 var summaryPartial = team.loadTemplate(that.config['summary-template'] || "summary");
1712 var tdata = $.extend({}, {"hits": data.hits}, that.config.template_vars);
1713 that.node.html(template(tdata, {"partials":{"summary":summaryPartial}}));
1720 mkws.registerWidgetType('navi', function() {
1722 var teamName = this.team.name();
1724 this.team.queue("navi").subscribe(function() {
1725 var filters = that.team.filters();
1726 var output = {filters:[]};
1728 filters.visitTargets(function(id, name) {
1730 cur.facet = 'source';
1732 cur.click = "mkws.delimitTarget('" + teamName + "', '" + id + "'); return false;";
1733 output.filters.push(cur);
1736 filters.visitFields(function(field, value) {
1740 cur.click = "mkws.delimitQuery('" + teamName + "', '" + field + "', '" + value + "'" + ");return false;";
1741 output.filters.push(cur);
1744 var template = that.team.loadTemplate(that.config.template || "navi");
1745 that.node.html(template(output));
1750 // It seems this and the Perpage widget doen't need to subscribe to
1751 // anything, since they produce events rather than consuming them.
1753 mkws.registerWidgetType('sort', function() {
1756 this.node.change(function() {
1757 that.team.set_sortOrder(that.node.val());
1758 if (that.team.submitted()) {
1766 mkws.registerWidgetType('per-page', function() {
1769 this.node.change(function() {
1770 that.team.set_perpage(that.node.val());
1771 if (that.team.submitted()) {
1779 mkws.registerWidgetType('done', function() {
1781 this.team.queue("complete").subscribe(function(n) {
1782 var template = that.team.loadTemplate(that.config.template || "done");
1783 that.node.html(template({count: n}));
1788 mkws.registerWidgetType('switch', function() {
1789 if (!this.config.show_switch) return;
1790 var tname = this.team.name();
1792 output.recordClick = "mkws.switchView(\'" + tname + "\', \'records\')";
1793 output.targetClick = "mkws.switchView(\'" + tname + "\', \'targets\')";
1794 var template = this.team.loadTemplate(this.config.template || "switch");
1795 this.node.html(template(output));
1796 this.hideWhenNarrow();
1800 mkws.registerWidgetType('search', function() {
1802 output.team = this.team.name();
1803 var template = this.team.loadTemplate(this.config.template || "search");
1804 this.node.html(template(output));
1808 mkws.registerWidgetType('search-form', function() {
1809 var team = this.team;
1810 this.node.submit(function() {
1811 var val = team.widget('query').value();
1812 team.newSearch(val);
1818 mkws.registerWidgetType('results', function() {
1819 var template = this.team.loadTemplate(this.config.template || "results");
1820 this.node.html(template({team: this.team.name()}));
1825 mkws.registerWidgetType('ranking', function() {
1827 output.perPage = [];
1829 output.team = this.team.name();
1830 output.showSort = this.config.show_sort;
1831 output.showPerPage = this.config.show_perpage;
1833 var order = this.team.sortOrder();
1834 this.log("making sort, sortOrder = '" + order + "'");
1835 for (var i = 0; i < this.config.sort_options.length; i++) {
1837 var opt = this.config.sort_options[i];
1839 cur.label = opt.length == 1 ? opt[0] : opt[1];
1840 if (order == cur.key || order == cur.label) cur.selected = true;
1841 output.sort.push(cur);
1844 var perpage = this.team.perpage();
1845 this.log("making perpage, perpage = " + perpage);
1846 for(var i = 0; i < this.config.perpage_options.length; i++) {
1848 cur.perPage = this.config.perpage_options[i];
1849 if (cur.perPage == perpage) cur.selected = true;
1850 output.perPage.push(cur);
1853 var template = this.team.loadTemplate(this.config.template || "ranking");
1854 this.node.html(template(output));
1858 mkws.registerWidgetType('lang', function() {
1859 // dynamic URL or static page? /path/foo?query=test
1860 /* create locale language menu */
1861 if (!this.config.show_lang) return;
1863 var lang_default = "en";
1864 var lang = this.config.lang || lang_default;
1867 /* display a list of configured languages, or all */
1868 var lang_options = this.config.lang_options;
1869 var toBeIncluded = {};
1870 for (var i = 0; i < lang_options.length; i++) {
1871 toBeIncluded[lang_options[i]] = true;
1874 for (var k in mkws.locale_lang) {
1875 if (toBeIncluded[k] || lang_options.length == 0) {
1877 if (lang === k) cur.selected = true;
1879 cur.url = lang_url(k);
1885 if (lang_options.length == 0 || toBeIncluded[lang_default]) {
1887 if (lang === lang_default) cur.selected = true;
1888 cur.code = lang_default;
1889 cur.url = lang_url(lang_default);
1893 this.log("language menu: " + list.join(", "));
1895 var template = this.team.loadTemplate(this.config.template || "lang");
1896 this.node.html(template({languages: list}));
1897 this.hideWhenNarrow();
1899 // set or re-set "lang" URL parameter
1900 function lang_url(lang) {
1901 var query = location.search;
1902 // no query parameters? done
1904 return "?lang=" + lang;
1907 // parameter does not exist
1908 if (!query.match(/[\?&]lang=/)) {
1909 return query + "&lang=" + lang;
1912 // replace existing parameter
1913 query = query.replace(/\?lang=([^&#;]*)/, "?lang=" + lang);
1914 query = query.replace(/\&lang=([^&#;]*)/, "&lang=" + lang);
1920 mkws.registerWidgetType('motd', function() {
1921 var container = this.team.widget('motd-container');
1923 // Move the MOTD from the provided element down into the container
1924 this.node.appendTo(container.node);
1929 // This widget has no functionality of its own, but its configuration
1930 // is copied up into its team, allowing it to affect other widgets in
1933 mkws.registerWidgetType('config', function() {
1934 var c = this.config;
1935 for (var name in c) {
1936 if (c.hasOwnProperty(name)) {
1937 this.team.config[name] = c[name];
1938 this.log(this + " copied property " + name + "='" + c[name] + "' up to team");
1944 mkws.registerWidgetType('progress', function() {
1947 this.team.queue("stat").subscribe(function(data) {
1948 var template = that.team.loadTemplate(that.config.template || "progress");
1949 that.node.html(template({
1950 done: data.clients - data.activeclients,
1951 waiting: data.activeclients
1958 // Some elements have mkws* classes that makes them appear as widgets
1959 // -- for example, because we want to style them using CSS -- but have
1960 // no actual functionality. We register these to prevent ignorable
1961 // warnings when they occur.
1963 mkws.registerWidgetType('query', function() {});
1964 mkws.registerWidgetType('motd-container', function() {});
1965 mkws.registerWidgetType('button', function() {});
1968 })(mkws.$); // jQuery wrapper
1969 mkws.registerWidgetType('facets', function() {
1970 // Initially hide the facets; display when we get results
1972 var team = this.team;
1973 team.queue("facets").subscribe(function(data) {
1974 that.node.addClass("active");
1977 var template = team.loadTemplate(this.config.template || "facets");
1978 this.node.html(template({
1980 facets: this.config.facets
1986 mkws.registerWidgetType('facet', function() {
1988 xtargets: [ "Sources", 16, false ],
1989 subject: [ "Subjects", 10, true ],
1990 author: [ "Authors", 10, true ]
1993 var team = this.team;
1994 var name = that.config.facet;
1995 var ref = facetConfig[name] || [ "Unknown", 10, true ];
1996 var caption = this.config['facet_caption_' + name] || ref[0];
1997 var max = parseInt(this.config['facet_max_' + name] || ref[1]);
1998 var pzIndex = ref[2] ? name : null;
2000 that.toString = function() {
2001 return '[Widget ' + team.name() + ':' + that.type + '(' + name + ')]';
2004 team.queue("facets").subscribe(function(data) {
2007 var teamName = team.name();
2008 for (var i = 0; i < data.length && i < max; i++) {
2012 // Special case: target selection
2013 linkdata += ('target_id='+data[i].id+' ');
2014 if (!team.targetFiltered(data[i].id)) {
2015 action = 'mkws.limitTarget(\'' + teamName + '\', this.getAttribute(\'target_id\'),this.firstChild.nodeValue)';
2018 action = 'mkws.limitQuery(\'' + teamName + '\', \'' + pzIndex + '\', this.firstChild.nodeValue)';
2020 linkdata += 'onclick="' + action + ';return false;"';
2024 count: data[i].freq,
2028 // configured template > facet specific template > default facet template
2030 if (that.config.template) {
2031 template = team.loadTemplate(that.config.template);
2033 template = team.loadTemplate("facet-" + name);
2035 that.log("Using facet-" + name + " template.")
2037 that.log("No " + name + " specific template, using default.")
2038 template = team.loadTemplate("facet");
2041 that.node.html(template({
2044 query: that.config.query,
2050 mkws.registerWidgetType('auth-name', function() {
2053 this.team.queue("authenticated").subscribe(function(authName) {
2054 that.node.html(authName);
2057 mkws.registerWidgetType('categories', function() {
2060 if (!mkws.authenticated) {
2061 alert("can't use categories widget when not authenticated");
2065 this.team.queue("authenticated").subscribe(function(authName, realm) {
2066 var req = new pzHttpRequest(mkws.pazpar2_url() + "?command=categories", function(err) {
2067 alert("HTTP call for categories failed: " + err)
2070 req.get(null, function(data) {
2071 if (!$.isXMLDoc(data)) {
2072 alert("categories response document is not XML");
2075 that.log("got categories: " + data);
2078 text.push("Select category: ");
2079 text.push("<select name='mkws-category mkwsCategory' " +
2080 "onchange='mkws.limitCategory(\"" + that.team.name() + "\", this.value)'>");
2081 text.push("<option value=''>[All]</option>");
2082 $(data).find('category').each(function() {
2083 var name = $(this).find('categoryName').text();
2084 var id = $(this).find('categoryId').text();
2085 text.push("<option value='", id, "'>", name, "</option>");
2087 text.push("</select>");
2088 that.node.html(text.join(''));
2092 mkws.registerWidgetType('log', function() {
2095 this.team.queue("log").subscribe(function(teamName, timestamp, message) {
2096 that.node.append(teamName + ": " + timestamp + message + "<br/>");
2099 // A widget for a record-list of a single record
2100 mkws.registerWidgetType('record', function() {
2101 if (!this.config.maxrecs) this.config.maxrecs = 1;
2103 var team = this.team;
2104 team.queue("records").subscribe(function(data) {
2105 var template = team.loadTemplate(that.config.template || "details");
2106 var targs = mkws.$.extend({}, data.hits[0], that.config.template_vars);
2107 that.node.html(template(targs));
2112 mkws.registerWidgetType('images', function() {
2113 mkws.promotionFunction('records').call(this);
2114 if (!this.config.template) this.config.template = 'images';
2117 mkws.registerWidgetType('google-image', function() {
2118 mkws.promotionFunction('images').call(this);
2119 if (!this.config.target) this.config.target = 'Google_Images';
2122 mkws.registerWidgetType('lolcat', function() {
2123 mkws.promotionFunction('google-image').call(this);
2124 if (!this.config.autosearch) this.config.autosearch = 'kitteh';
2127 mkws.registerWidgetType('cover-art', function() {
2128 mkws.promotionFunction('images').call(this);
2129 if (!this.config.target) this.config.target = 'AmazonBooks';
2131 mkws.registerWidgetType('reference', function() {
2132 mkws.promotionFunction('record').call(this);
2133 if (!this.config.target) this.config.target = 'wikimedia_wikipedia_single_result';
2134 if (!this.config.template) this.config.template = 'reference';
2135 this.config.template_vars.paragraphs = this.config.paragraphs || 0;
2136 this.config.template_vars.sentences = this.config.sentences || 0;
2138 mkws.registerWidgetType('builder', function() {
2140 var team = this.team;
2142 var button = mkws.$('<button/>', {
2144 text: this.config.text || "Build!"
2146 this.node.append(button);
2147 button.click(function() {
2148 var query = team.widget('query').value();
2149 var sort = team.widget('sort').value();
2150 var perpage = team.widget('per-page').value();
2152 var html = ('<div class="mkws-records mkwsRecords" ' +
2153 'autosearch="' + query + '" ' +
2154 'sort="' + sort + '" ' +
2155 'perpage="' + perpage + '"></div>');
2156 var fn = that.callback || alert;
2161 mkws.registerWidgetType('console-builder', function() {
2162 mkws.promotionFunction('builder').call(this);
2163 this.callback = function(s) {
2164 console.log("generated widget: " + s);
2168 var template = Handlebars.template, templates = mkws.defaultTemplates = mkws.defaultTemplates || {};
2169 templates['details'] = template({"1":function(depth0,helpers,partials,data) {
2170 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2172 + escapeExpression(((helper = (helper = helpers['md-title-remainder'] || (depth0 != null ? depth0['md-title-remainder'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-remainder","hash":{},"data":data}) : helper)))
2174 },"3":function(depth0,helpers,partials,data) {
2175 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2177 + escapeExpression(((helper = (helper = helpers['md-title-responsibility'] || (depth0 != null ? depth0['md-title-responsibility'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-responsibility","hash":{},"data":data}) : helper)))
2179 },"5":function(depth0,helpers,partials,data) {
2180 var helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function";
2181 return " <tr>\n <th>"
2182 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Date", {"name":"mkws-translate","hash":{},"data":data})))
2184 + escapeExpression(((helper = (helper = helpers['md-date'] || (depth0 != null ? depth0['md-date'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-date","hash":{},"data":data}) : helper)))
2185 + "</td>\n </tr>\n";
2186 },"7":function(depth0,helpers,partials,data) {
2187 var helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function";
2188 return " <tr>\n <th>"
2189 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Author", {"name":"mkws-translate","hash":{},"data":data})))
2191 + escapeExpression(((helper = (helper = helpers['md-author'] || (depth0 != null ? depth0['md-author'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-author","hash":{},"data":data}) : helper)))
2192 + "</td>\n </tr>\n";
2193 },"9":function(depth0,helpers,partials,data) {
2194 var stack1, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <tr>\n <th>"
2195 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Links", {"name":"mkws-translate","hash":{},"data":data})))
2197 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0['md-electronic-url'] : depth0), {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
2198 if (stack1 != null) { buffer += stack1; }
2199 return buffer + " </td>\n </tr>\n";
2200 },"10":function(depth0,helpers,partials,data) {
2201 var helper, lambda=this.lambda, escapeExpression=this.escapeExpression, functionType="function", helperMissing=helpers.helperMissing;
2202 return " <a href=\""
2203 + escapeExpression(lambda(depth0, depth0))
2205 + escapeExpression(((helper = (helper = helpers['mkws-index1'] || (depth0 != null ? depth0['mkws-index1'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"mkws-index1","hash":{},"data":data}) : helper)))
2207 },"12":function(depth0,helpers,partials,data) {
2208 var stack1, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <tr>\n <th>"
2209 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Subject", {"name":"mkws-translate","hash":{},"data":data})))
2211 stack1 = ((helpers['mkws-first'] || (depth0 && depth0['mkws-first']) || helperMissing).call(depth0, (depth0 != null ? depth0.location : depth0), {"name":"mkws-first","hash":{
2212 'having': ("md-subject")
2213 },"fn":this.program(13, data),"inverse":this.noop,"data":data}));
2214 if (stack1 != null) { buffer += stack1; }
2215 return buffer + " </td>\n </tr>\n";
2216 },"13":function(depth0,helpers,partials,data) {
2217 var stack1, buffer = "";
2218 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-subject'] : depth0), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data});
2219 if (stack1 != null) { buffer += stack1; }
2221 },"14":function(depth0,helpers,partials,data) {
2222 var stack1, helperMissing=helpers.helperMissing, buffer = "";
2223 stack1 = ((helpers['mkws-commaList'] || (depth0 && depth0['mkws-commaList']) || helperMissing).call(depth0, (depth0 != null ? depth0['md-subject'] : depth0), {"name":"mkws-commaList","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data}));
2224 if (stack1 != null) { buffer += stack1; }
2225 return buffer + "\n";
2226 },"15":function(depth0,helpers,partials,data) {
2227 var lambda=this.lambda, escapeExpression=this.escapeExpression;
2229 + escapeExpression(lambda(depth0, depth0));
2230 },"17":function(depth0,helpers,partials,data) {
2231 var helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2233 + escapeExpression(((helpers['mkws-attr'] || (depth0 && depth0['mkws-attr']) || helperMissing).call(depth0, "@name", {"name":"mkws-attr","hash":{},"data":data})));
2234 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2235 var stack1, helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", buffer = "<table>\n <tr>\n <th>"
2236 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Title", {"name":"mkws-translate","hash":{},"data":data})))
2238 + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
2240 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-remainder'] : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2241 if (stack1 != null) { buffer += stack1; }
2242 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-responsibility'] : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
2243 if (stack1 != null) { buffer += stack1; }
2244 buffer += " </td>\n </tr>\n";
2245 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-date'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
2246 if (stack1 != null) { buffer += stack1; }
2247 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-author'] : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
2248 if (stack1 != null) { buffer += stack1; }
2249 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-electronic-url'] : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.noop,"data":data});
2250 if (stack1 != null) { buffer += stack1; }
2251 stack1 = ((helpers['mkws-if-any'] || (depth0 && depth0['mkws-if-any']) || helperMissing).call(depth0, (depth0 != null ? depth0.location : depth0), {"name":"mkws-if-any","hash":{
2252 'having': ("md-subject")
2253 },"fn":this.program(12, data),"inverse":this.noop,"data":data}));
2254 if (stack1 != null) { buffer += stack1; }
2255 buffer += " <tr>\n <th>"
2256 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Locations", {"name":"mkws-translate","hash":{},"data":data})))
2258 stack1 = ((helpers['mkws-commaList'] || (depth0 && depth0['mkws-commaList']) || helperMissing).call(depth0, (depth0 != null ? depth0.location : depth0), {"name":"mkws-commaList","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data}));
2259 if (stack1 != null) { buffer += stack1; }
2260 return buffer + "\n </td>\n </tr>\n</table>\n";
2262 templates['done'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2263 var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = "";
2264 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Search complete: found", {"name":"mkws-translate","hash":{},"data":data}));
2265 if (stack1 != null) { buffer += stack1; }
2267 + escapeExpression(((helper = (helper = helpers.count || (depth0 != null ? depth0.count : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"count","hash":{},"data":data}) : helper)))
2269 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "records", {"name":"mkws-translate","hash":{},"data":data}));
2270 if (stack1 != null) { buffer += stack1; }
2271 return buffer + "\n\n";
2273 templates['facet'] = template({"1":function(depth0,helpers,partials,data) {
2274 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <div class=\"mkws-term mkwsTerm\">\n <a href=\"#\" ";
2275 stack1 = ((helper = (helper = helpers.linkdata || (depth0 != null ? depth0.linkdata : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"linkdata","hash":{},"data":data}) : helper));
2276 if (stack1 != null) { buffer += stack1; }
2278 + escapeExpression(((helper = (helper = helpers.term || (depth0 != null ? depth0.term : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"term","hash":{},"data":data}) : helper)))
2280 + escapeExpression(((helper = (helper = helpers.count || (depth0 != null ? depth0.count : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"count","hash":{},"data":data}) : helper)))
2281 + "</span>\n </div>\n";
2282 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2283 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "\n<div class=\"mkws-facet-title mkwsFacetTitle\">"
2284 + escapeExpression(((helper = (helper = helpers.caption || (depth0 != null ? depth0.caption : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"caption","hash":{},"data":data}) : helper)))
2286 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.terms : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2287 if (stack1 != null) { buffer += stack1; }
2290 templates['facets'] = template({"1":function(depth0,helpers,partials,data,depths) {
2291 var lambda=this.lambda, escapeExpression=this.escapeExpression;
2292 return " <div class=\"mkws-facet mkwsFacet mkws-team-"
2293 + escapeExpression(lambda((depths[1] != null ? depths[1].team : depths[1]), depth0))
2294 + "\" data-mkws-facet=\""
2295 + escapeExpression(lambda(depth0, depth0))
2297 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data,depths) {
2298 var stack1, buffer = "";
2299 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.facets : depth0), {"name":"each","hash":{},"fn":this.program(1, data, depths),"inverse":this.noop,"data":data});
2300 if (stack1 != null) { buffer += stack1; }
2302 },"useData":true,"useDepths":true});
2303 templates['images'] = template({"1":function(depth0,helpers,partials,data,depths) {
2304 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <a href=\"#\" id=\""
2305 + escapeExpression(((helper = (helper = helpers.detailLinkId || (depth0 != null ? depth0.detailLinkId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailLinkId","hash":{},"data":data}) : helper)))
2307 + escapeExpression(((helper = (helper = helpers.detailClick || (depth0 != null ? depth0.detailClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailClick","hash":{},"data":data}) : helper)))
2309 stack1 = ((helpers['mkws-first'] || (depth0 && depth0['mkws-first']) || helperMissing).call(depth0, (depth0 != null ? depth0['md-thumburl'] : depth0), {"name":"mkws-first","hash":{},"fn":this.program(2, data, depths),"inverse":this.noop,"data":data}));
2310 if (stack1 != null) { buffer += stack1; }
2311 return buffer + " <br/>\n </a>\n";
2312 },"2":function(depth0,helpers,partials,data,depths) {
2313 var lambda=this.lambda, escapeExpression=this.escapeExpression;
2314 return " <img src=\""
2315 + escapeExpression(lambda(depth0, depth0))
2317 + escapeExpression(lambda((depths[1] != null ? depths[1]['md-title'] : depths[1]), depth0))
2319 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data,depths) {
2320 var stack1, buffer = "";
2321 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.hits : depth0), {"name":"each","hash":{},"fn":this.program(1, data, depths),"inverse":this.noop,"data":data});
2322 if (stack1 != null) { buffer += stack1; }
2324 },"useData":true,"useDepths":true});
2325 templates['lang'] = template({"1":function(depth0,helpers,partials,data) {
2326 var stack1, buffer = "";
2327 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.selected : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data});
2328 if (stack1 != null) { buffer += stack1; }
2329 stack1 = helpers.unless.call(depth0, (data && data.last), {"name":"unless","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data});
2330 if (stack1 != null) { buffer += stack1; }
2332 },"2":function(depth0,helpers,partials,data) {
2333 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2335 + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper)))
2337 },"4":function(depth0,helpers,partials,data) {
2338 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<a href=\"";
2339 stack1 = ((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper));
2340 if (stack1 != null) { buffer += stack1; }
2341 return buffer + "\">"
2342 + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper)))
2344 },"6":function(depth0,helpers,partials,data) {
2346 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2347 var stack1, buffer = "";
2348 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.languages : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2349 if (stack1 != null) { buffer += stack1; }
2350 return buffer + "\n";
2352 templates['navi'] = template({"1":function(depth0,helpers,partials,data) {
2353 var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = " ";
2354 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, (depth0 != null ? depth0.facet : depth0), {"name":"mkws-translate","hash":{},"data":data}));
2355 if (stack1 != null) { buffer += stack1; }
2356 buffer += ": <a class=\"mkws-removable mkwsRemovable\" href=\"#\" onclick=\"";
2357 stack1 = ((helper = (helper = helpers.click || (depth0 != null ? depth0.click : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"click","hash":{},"data":data}) : helper));
2358 if (stack1 != null) { buffer += stack1; }
2360 + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper)))
2362 stack1 = helpers.unless.call(depth0, (data && data.last), {"name":"unless","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
2363 if (stack1 != null) { buffer += stack1; }
2364 return buffer + "\n";
2365 },"2":function(depth0,helpers,partials,data) {
2367 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2368 var stack1, buffer = "";
2369 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.filters : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2370 if (stack1 != null) { buffer += stack1; }
2371 return buffer + "\n";
2373 templates['pager'] = template({"1":function(depth0,helpers,partials,data) {
2374 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <a href=\"#\" class=\"mkws-prev mkwsPrev\" onclick=\""
2375 + escapeExpression(((helper = (helper = helpers.prevClick || (depth0 != null ? depth0.prevClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"prevClick","hash":{},"data":data}) : helper)))
2377 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Prev", {"name":"mkws-translate","hash":{},"data":data}));
2378 if (stack1 != null) { buffer += stack1; }
2379 return buffer + "</a> |\n";
2380 },"3":function(depth0,helpers,partials,data) {
2381 var stack1, helperMissing=helpers.helperMissing, buffer = " <span class=\"mkws-prev mkwsPrev\"><< ";
2382 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Prev", {"name":"mkws-translate","hash":{},"data":data}));
2383 if (stack1 != null) { buffer += stack1; }
2384 return buffer + "</span> |\n";
2385 },"5":function(depth0,helpers,partials,data) {
2387 },"7":function(depth0,helpers,partials,data) {
2388 var stack1, buffer = "";
2389 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.click : depth0), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.program(10, data),"data":data});
2390 if (stack1 != null) { buffer += stack1; }
2392 },"8":function(depth0,helpers,partials,data) {
2393 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2394 return " <a href=\"#\" onclick=\""
2395 + escapeExpression(((helper = (helper = helpers.click || (depth0 != null ? depth0.click : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"click","hash":{},"data":data}) : helper)))
2397 + escapeExpression(((helper = (helper = helpers.number || (depth0 != null ? depth0.number : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"number","hash":{},"data":data}) : helper)))
2399 },"10":function(depth0,helpers,partials,data) {
2400 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2401 return " <span class=\"mkws-current-page mkwsCurrentPage\">"
2402 + escapeExpression(((helper = (helper = helpers.number || (depth0 != null ? depth0.number : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"number","hash":{},"data":data}) : helper)))
2404 },"12":function(depth0,helpers,partials,data) {
2405 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " | <a href=\"#\" class=\"mkws-next mkwsNext\" onclick=\""
2406 + escapeExpression(((helper = (helper = helpers.nextClick || (depth0 != null ? depth0.nextClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nextClick","hash":{},"data":data}) : helper)))
2408 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Next", {"name":"mkws-translate","hash":{},"data":data}));
2409 if (stack1 != null) { buffer += stack1; }
2410 return buffer + " >></a>\n";
2411 },"14":function(depth0,helpers,partials,data) {
2412 var stack1, helperMissing=helpers.helperMissing, buffer = " | <span class=\"mkws-next mkwsNext\">";
2413 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Next", {"name":"mkws-translate","hash":{},"data":data}));
2414 if (stack1 != null) { buffer += stack1; }
2415 return buffer + " >></span>\n";
2416 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2417 var stack1, helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", buffer = "<div style=\"float: right\">\n "
2418 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Displaying", {"name":"mkws-translate","hash":{},"data":data})))
2420 + escapeExpression(((helper = (helper = helpers.first || (depth0 != null ? depth0.first : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"first","hash":{},"data":data}) : helper)))
2422 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "to", {"name":"mkws-translate","hash":{},"data":data})))
2424 + escapeExpression(((helper = (helper = helpers.last || (depth0 != null ? depth0.last : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"last","hash":{},"data":data}) : helper)))
2426 + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "of", {"name":"mkws-translate","hash":{},"data":data})))
2428 + escapeExpression(((helper = (helper = helpers.count || (depth0 != null ? depth0.count : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"count","hash":{},"data":data}) : helper)))
2430 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "found", {"name":"mkws-translate","hash":{},"data":data}));
2431 if (stack1 != null) { buffer += stack1; }
2433 + escapeExpression(((helper = (helper = helpers.found || (depth0 != null ? depth0.found : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"found","hash":{},"data":data}) : helper)))
2434 + ")\n</div>\n\n<div style=\"float: clear\">\n";
2435 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.prevClick : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
2436 if (stack1 != null) { buffer += stack1; }
2438 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.morePrev : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
2439 if (stack1 != null) { buffer += stack1; }
2441 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.pages : depth0), {"name":"each","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
2442 if (stack1 != null) { buffer += stack1; }
2444 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.moreNext : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
2445 if (stack1 != null) { buffer += stack1; }
2447 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.nextClick : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.program(14, data),"data":data});
2448 if (stack1 != null) { buffer += stack1; }
2449 return buffer + "</div>\n";
2451 templates['progress'] = template({"1":function(depth0,helpers,partials,data) {
2453 },"3":function(depth0,helpers,partials,data) {
2454 var stack1, helperMissing=helpers.helperMissing, buffer = "<span class=\"mkws-waiting mkws-waiting mkwsWaiting\">";
2455 stack1 = ((helpers['mkws-repeat'] || (depth0 && depth0['mkws-repeat']) || helperMissing).call(depth0, (depth0 != null ? depth0.waiting : depth0), {"name":"mkws-repeat","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}));
2456 if (stack1 != null) { buffer += stack1; }
2457 return buffer + "</span>";
2458 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2459 var stack1, helperMissing=helpers.helperMissing, buffer = "<span class=\"mkws-done mkws-done mkwsDone\">";
2460 stack1 = ((helpers['mkws-repeat'] || (depth0 && depth0['mkws-repeat']) || helperMissing).call(depth0, (depth0 != null ? depth0.done : depth0), {"name":"mkws-repeat","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}));
2461 if (stack1 != null) { buffer += stack1; }
2462 buffer += "</span>";
2463 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.waiting : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
2464 if (stack1 != null) { buffer += stack1; }
2467 templates['ranking'] = template({"1":function(depth0,helpers,partials,data) {
2468 var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = "";
2469 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Sort by", {"name":"mkws-translate","hash":{},"data":data}));
2470 if (stack1 != null) { buffer += stack1; }
2471 buffer += "\n <select class=\"mkws-sort mkwsSort mkws-team-"
2472 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2474 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.sort : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
2475 if (stack1 != null) { buffer += stack1; }
2476 return buffer + " </select>";
2477 },"2":function(depth0,helpers,partials,data) {
2478 var stack1, buffer = "";
2479 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.selected : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.program(5, data),"data":data});
2480 if (stack1 != null) { buffer += stack1; }
2482 },"3":function(depth0,helpers,partials,data) {
2483 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = " <option value=\"";
2484 stack1 = ((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"key","hash":{},"data":data}) : helper));
2485 if (stack1 != null) { buffer += stack1; }
2486 buffer += "\" selected=\"selected\">";
2487 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, (depth0 != null ? depth0.label : depth0), {"name":"mkws-translate","hash":{},"data":data}));
2488 if (stack1 != null) { buffer += stack1; }
2489 return buffer + "</option>\n";
2490 },"5":function(depth0,helpers,partials,data) {
2491 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <option value=\""
2492 + escapeExpression(((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"key","hash":{},"data":data}) : helper)))
2494 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, (depth0 != null ? depth0.label : depth0), {"name":"mkws-translate","hash":{},"data":data}));
2495 if (stack1 != null) { buffer += stack1; }
2496 return buffer + "</option>\n";
2497 },"7":function(depth0,helpers,partials,data) {
2498 var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = " ";
2499 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "and show", {"name":"mkws-translate","hash":{},"data":data}));
2500 if (stack1 != null) { buffer += stack1; }
2501 buffer += "\n <select class=\"mkws-perpage mkwsPerpage mkws-team-"
2502 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2504 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.perPage : depth0), {"name":"each","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});
2505 if (stack1 != null) { buffer += stack1; }
2506 buffer += " </select>\n ";
2507 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "per page", {"name":"mkws-translate","hash":{},"data":data}));
2508 if (stack1 != null) { buffer += stack1; }
2510 },"8":function(depth0,helpers,partials,data) {
2511 var stack1, buffer = "";
2512 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.selected : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.program(11, data),"data":data});
2513 if (stack1 != null) { buffer += stack1; }
2515 },"9":function(depth0,helpers,partials,data) {
2516 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2517 return " <option value=\""
2518 + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
2519 + "\" selected=\"selected\">"
2520 + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
2522 },"11":function(depth0,helpers,partials,data) {
2523 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2524 return " <option value=\""
2525 + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
2527 + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
2529 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2530 var stack1, buffer = "<form>";
2531 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showSort : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2532 if (stack1 != null) { buffer += stack1; }
2533 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showPerPage : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
2534 if (stack1 != null) { buffer += stack1; }
2535 return buffer + "</form>\n\n";
2537 templates['records'] = template({"1":function(depth0,helpers,partials,data) {
2538 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <div class=\""
2539 + escapeExpression(((helper = (helper = helpers.containerClass || (depth0 != null ? depth0.containerClass : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"containerClass","hash":{},"data":data}) : helper)))
2541 stack1 = this.invokePartial(partials.summary, ' ', 'summary', depth0, undefined, helpers, partials, data);
2542 if (stack1 != null) { buffer += stack1; }
2543 return buffer + " </div>\n";
2544 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2545 var stack1, buffer = "";
2546 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.hits : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2547 if (stack1 != null) { buffer += stack1; }
2549 },"usePartial":true,"useData":true});
2550 templates['reference'] = template({"1":function(depth0,helpers,partials,data) {
2551 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2553 + escapeExpression(((helper = (helper = helpers['md-title-remainder'] || (depth0 != null ? depth0['md-title-remainder'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-remainder","hash":{},"data":data}) : helper)))
2555 },"3":function(depth0,helpers,partials,data) {
2556 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2558 + escapeExpression(((helper = (helper = helpers['md-title-responsibility'] || (depth0 != null ? depth0['md-title-responsibility'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-responsibility","hash":{},"data":data}) : helper)))
2560 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2561 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<img src=\""
2562 + escapeExpression(((helper = (helper = helpers['md-thumburl'] || (depth0 != null ? depth0['md-thumburl'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-thumburl","hash":{},"data":data}) : helper)))
2564 + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
2565 + "\">\n<h1><a href=\""
2566 + escapeExpression(((helper = (helper = helpers['md-electronic-url'] || (depth0 != null ? depth0['md-electronic-url'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-electronic-url","hash":{},"data":data}) : helper)))
2568 + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
2570 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-remainder'] : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2571 if (stack1 != null) { buffer += stack1; }
2572 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-responsibility'] : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
2573 if (stack1 != null) { buffer += stack1; }
2574 stack1 = ((helpers['mkws-paragraphs'] || (depth0 && depth0['mkws-paragraphs']) || helperMissing).call(depth0, (depth0 != null ? depth0['md-description'] : depth0), (depth0 != null ? depth0.paragraphs : depth0), (depth0 != null ? depth0.sentences : depth0), {"name":"mkws-paragraphs","hash":{},"data":data}));
2575 if (stack1 != null) { buffer += stack1; }
2576 return buffer + "\n<p class=\"mkws-credit mkwsCredit\">Wikipedia</p>\n";
2578 templates['results'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2579 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2580 return "<table width=\"100%\" border=\"0\" cellpadding=\"6\" cellspacing=\"0\">\n <tr>\n <td class=\"mkws-facets-container-wide mkws-team-"
2581 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2582 + "\" width=\"250\" valign=\"top\">\n <div class=\"mkws-facets mkwsTermlists mkws-team-"
2583 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2584 + "\"></div>\n </td>\n <td class=\"mkws-motd-container mkwsMOTDContainer mkws-team-"
2585 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2586 + "\" valign=\"top\">\n <div class=\"mkws-ranking mkwsRanking mkws-team-"
2587 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2588 + "\"></div>\n <div class=\"mkws-pager mkwsPager mkws-team-"
2589 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2590 + "\"></div>\n <div class=\"mkws-navi mkwsNavi mkws-team-"
2591 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2592 + "\"></div>\n <div class=\"mkws-records mkwsRecords mkws-team-"
2593 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2594 + "\"></div>\n </td>\n </tr>\n <tr>\n <td colspan=\"2\">\n <div class=\"mkws-facets-container-narrow mkws-team-"
2595 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2596 + "\"></div>\n </td>\n </tr>\n</table>\n\n";
2598 templates['search'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2599 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<form name=\"mkws-search-form\" class=\"mkws-search-form mkws-team-"
2600 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2601 + "\" action=\"\">\n <input class=\"mkws-query mkws-query mkwsQuery mkws-team-"
2602 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2603 + "\" type=\"text\"/>\n <input class=\"mkws-button mkws-button mkwsButton mkws-team-"
2604 + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
2605 + "\" type=\"submit\" value=\"";
2606 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Search", {"name":"mkws-translate","hash":{},"data":data}));
2607 if (stack1 != null) { buffer += stack1; }
2608 return buffer + "\"/>\n</form>\n\n";
2610 templates['stat'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2611 var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = " -- <span class=\"mkws-client-count mkwsClientCount\">";
2612 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Active clients", {"name":"mkws-translate","hash":{},"data":data}));
2613 if (stack1 != null) { buffer += stack1; }
2615 + escapeExpression(((helper = (helper = helpers.activeclients || (depth0 != null ? depth0.activeclients : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"activeclients","hash":{},"data":data}) : helper)))
2617 + escapeExpression(((helper = (helper = helpers.clients || (depth0 != null ? depth0.clients : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"clients","hash":{},"data":data}) : helper)))
2619 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Retrieved records", {"name":"mkws-translate","hash":{},"data":data}));
2620 if (stack1 != null) { buffer += stack1; }
2621 return buffer + " : "
2622 + escapeExpression(((helper = (helper = helpers.records || (depth0 != null ? depth0.records : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"records","hash":{},"data":data}) : helper)))
2624 + escapeExpression(((helper = (helper = helpers.hits || (depth0 != null ? depth0.hits : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"hits","hash":{},"data":data}) : helper)))
2627 templates['summary'] = template({"1":function(depth0,helpers,partials,data) {
2628 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, lambda=this.lambda;
2629 return " <a class=\"mkws-field-thumb\" href=\"#\" onclick=\""
2630 + escapeExpression(((helper = (helper = helpers.detailClick || (depth0 != null ? depth0.detailClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailClick","hash":{},"data":data}) : helper)))
2631 + "\">\n <img src=\""
2632 + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0['md-thumburl'] : depth0)) != null ? stack1['0'] : stack1), depth0))
2634 },"3":function(depth0,helpers,partials,data) {
2635 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2636 return " <span class=\"mkws-field-title-remainder\">"
2637 + escapeExpression(((helper = (helper = helpers['md-title-remainder'] || (depth0 != null ? depth0['md-title-remainder'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-remainder","hash":{},"data":data}) : helper)))
2639 },"5":function(depth0,helpers,partials,data) {
2640 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2641 return " <span class=\"mkws-field-author\">"
2642 + escapeExpression(((helper = (helper = helpers['md-author'] || (depth0 != null ? depth0['md-author'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-author","hash":{},"data":data}) : helper)))
2644 },"7":function(depth0,helpers,partials,data) {
2645 var stack1, buffer = "";
2646 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-responsibility'] : depth0), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});
2647 if (stack1 != null) { buffer += stack1; }
2649 },"8":function(depth0,helpers,partials,data) {
2650 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2651 return " <span class=\"mkws-field-author\">"
2652 + escapeExpression(((helper = (helper = helpers['md-title-responsibility'] || (depth0 != null ? depth0['md-title-responsibility'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-responsibility","hash":{},"data":data}) : helper)))
2654 },"10":function(depth0,helpers,partials,data) {
2655 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2656 return " <div class=\"mkws-field-description\">"
2657 + escapeExpression(((helper = (helper = helpers['md-description'] || (depth0 != null ? depth0['md-description'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-description","hash":{},"data":data}) : helper)))
2659 },"12":function(depth0,helpers,partials,data) {
2660 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2661 return " <span class=\"mkws-field-date\">"
2662 + escapeExpression(((helper = (helper = helpers['md-date'] || (depth0 != null ? depth0['md-date'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-date","hash":{},"data":data}) : helper)))
2664 },"14":function(depth0,helpers,partials,data) {
2665 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = " ";
2666 stack1 = ((helper = (helper = helpers.renderedDetails || (depth0 != null ? depth0.renderedDetails : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"renderedDetails","hash":{},"data":data}) : helper));
2667 if (stack1 != null) { buffer += stack1; }
2668 return buffer + "\n";
2669 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2670 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "";
2671 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-thumburl'] : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2672 if (stack1 != null) { buffer += stack1; }
2673 buffer += "<div class=\"mkws-field-data\">\n <span class=\"mkws-field-title\">\n <a href=\"#\" id=\""
2674 + escapeExpression(((helper = (helper = helpers.detailLinkId || (depth0 != null ? depth0.detailLinkId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailLinkId","hash":{},"data":data}) : helper)))
2676 + escapeExpression(((helper = (helper = helpers.detailClick || (depth0 != null ? depth0.detailClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailClick","hash":{},"data":data}) : helper)))
2678 + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
2679 + "\n </a>\n </span>\n";
2680 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-remainder'] : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
2681 if (stack1 != null) { buffer += stack1; }
2682 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-author'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data});
2683 if (stack1 != null) { buffer += stack1; }
2684 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-description'] : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
2685 if (stack1 != null) { buffer += stack1; }
2686 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-date'] : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data});
2687 if (stack1 != null) { buffer += stack1; }
2688 buffer += "</div>\n";
2689 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.renderedDetails : depth0), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data});
2690 if (stack1 != null) { buffer += stack1; }
2693 templates['switch'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2694 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "<a href=\"#\" onclick=\"";
2695 stack1 = ((helper = (helper = helpers.recordClick || (depth0 != null ? depth0.recordClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"recordClick","hash":{},"data":data}) : helper));
2696 if (stack1 != null) { buffer += stack1; }
2698 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Records", {"name":"mkws-translate","hash":{},"data":data}));
2699 if (stack1 != null) { buffer += stack1; }
2700 buffer += "</a>\n<span>|</span>\n<a href=\"#\" onclick=\"";
2701 stack1 = ((helper = (helper = helpers.targetClick || (depth0 != null ? depth0.targetClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"targetClick","hash":{},"data":data}) : helper));
2702 if (stack1 != null) { buffer += stack1; }
2704 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Targets", {"name":"mkws-translate","hash":{},"data":data}));
2705 if (stack1 != null) { buffer += stack1; }
2706 return buffer + "</a>\n";
2708 templates['targets'] = template({"1":function(depth0,helpers,partials,data) {
2709 var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <tr>\n <td>";
2710 stack1 = ((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper));
2711 if (stack1 != null) { buffer += stack1; }
2712 buffer += "</td>\n <td>"
2713 + escapeExpression(((helper = (helper = helpers.hits || (depth0 != null ? depth0.hits : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"hits","hash":{},"data":data}) : helper)))
2715 stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.message : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
2716 if (stack1 != null) { buffer += stack1; }
2717 return buffer + " </td>\n <td>"
2718 + escapeExpression(((helper = (helper = helpers.records || (depth0 != null ? depth0.records : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"records","hash":{},"data":data}) : helper)))
2720 + escapeExpression(((helper = (helper = helpers.state || (depth0 != null ? depth0.state : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"state","hash":{},"data":data}) : helper)))
2721 + "</td>\n </tr>\n";
2722 },"2":function(depth0,helpers,partials,data) {
2723 var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
2725 + escapeExpression(((helper = (helper = helpers.diagnostic || (depth0 != null ? depth0.diagnostic : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"diagnostic","hash":{},"data":data}) : helper)))
2727 + escapeExpression(((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"message","hash":{},"data":data}) : helper)))
2729 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
2730 var stack1, helperMissing=helpers.helperMissing, buffer = "<table>\n <thead>\n <tr>\n <td>";
2731 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Target ID", {"name":"mkws-translate","hash":{},"data":data}));
2732 if (stack1 != null) { buffer += stack1; }
2733 buffer += "</td>\n <td>";
2734 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Hits", {"name":"mkws-translate","hash":{},"data":data}));
2735 if (stack1 != null) { buffer += stack1; }
2736 buffer += "</td>\n <td>";
2737 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Diags", {"name":"mkws-translate","hash":{},"data":data}));
2738 if (stack1 != null) { buffer += stack1; }
2739 buffer += "</td>\n <td>";
2740 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Records", {"name":"mkws-translate","hash":{},"data":data}));
2741 if (stack1 != null) { buffer += stack1; }
2742 buffer += "</td>\n <td>";
2743 stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "State", {"name":"mkws-translate","hash":{},"data":data}));
2744 if (stack1 != null) { buffer += stack1; }
2745 buffer += "</td>\n </td>\n </tr>\n </thead>\n <tbody>\n";
2746 stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.data : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
2747 if (stack1 != null) { buffer += stack1; }
2748 return buffer + " </tbody>\n</table>\n";
2750 })();/* generic function to open results in a popup window
2755 // $(document).ready(function () {
2756 mkws.registerWidgetType('popup', function() {
2758 var debug = this.log;
2759 debug("init popup window");
2761 var popup_window = $(this.node);
2762 // var popup_window = $(".mkws-popup mkwsPopup"); // $(document).ready()
2763 if (!popup_window) {
2764 debug("no popup found, skip...");
2767 debug("number of popup windows found: " + popup_window.length);
2771 alert("Error: jquery-ui.js is missing, did you include it after jQuery core in the HTML file?");
2775 // more than one widget on a page are possible
2776 popup_window.each(function(i) {
2779 // all atributes are strings, convert them to integers here
2780 var width = parseInt(that.attr("popup_width") || "800");
2781 var height = parseInt(that.attr("popup_height") || "600");
2782 var autoOpen = parseInt(that.attr("popup_autoOpen") || "0");
2783 var modal = parseInt(that.attr("popup_modal") || "0");
2785 debug("Popup parameters: width: " + width + ", height: " + height + ", autoOpen: " + autoOpen);
2787 closeOnEscape: true,
2791 modal: modal ? true : false,
2794 Cancel: function() {
2795 that.dialog("close");
2798 close: function() {}
2801 // open at search query submit: "input.mkws-button mkwsButton"
2802 var id_botton = that.attr("popup_button");
2804 $(id_botton).button().click(function() {
2805 that.dialog("open");