You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@chukwa.apache.org by ey...@apache.org on 2015/06/25 22:48:39 UTC

[08/22] chukwa git commit: CHUKWA-756. Added ajax-solr UI for log search. (Eric Yang)

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js b/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js
new file mode 100644
index 0000000..987f865
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js
@@ -0,0 +1,35 @@
+/*
+ RequireJS 2.1.5 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
+ Available via the MIT or new BSD license.
+ see: http://github.com/jrburke/requirejs for details
+*/
+var requirejs,require,define;
+(function(aa){function I(b){return"[object Function]"===L.call(b)}function J(b){return"[object Array]"===L.call(b)}function y(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function M(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function m(b,c){return s(b,c)&&b[c]}function G(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function R(b,c,d,m){c&&G(c,function(c,j){if(d||!s(b,j))m&&"string"!==typeof c?(b[j]||(b[j]={}),R(b[j],
+c,d,m)):b[j]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function ba(b){if(!b)return b;var c=aa;y(b.split("."),function(b){c=c[b]});return c}function B(b,c,d,m){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=m;d&&(c.originalError=d);return c}function ha(b){function c(a,f,b){var e,n,c,g,d,S,i,h=f&&f.split("/");e=h;var j=k.map,l=j&&j["*"];if(a&&"."===a.charAt(0))if(f){e=m(k.pkgs,f)?h=[f]:h.slice(0,h.length-1);f=a=e.concat(a.split("/"));
+for(e=0;f[e];e+=1)if(n=f[e],"."===n)f.splice(e,1),e-=1;else if(".."===n)if(1===e&&(".."===f[2]||".."===f[0]))break;else 0<e&&(f.splice(e-1,2),e-=2);e=m(k.pkgs,f=a[0]);a=a.join("/");e&&a===f+"/"+e.main&&(a=f)}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&j&&(h||l)){f=a.split("/");for(e=f.length;0<e;e-=1){c=f.slice(0,e).join("/");if(h)for(n=h.length;0<n;n-=1)if(b=m(j,h.slice(0,n).join("/")))if(b=m(b,c)){g=b;d=e;break}if(g)break;!S&&(l&&m(l,c))&&(S=m(l,c),i=e)}!g&&S&&(g=S,d=i);g&&(f.splice(0,d,
+g),a=f.join("/"))}return a}function d(a){A&&y(document.getElementsByTagName("script"),function(f){if(f.getAttribute("data-requiremodule")===a&&f.getAttribute("data-requirecontext")===i.contextName)return f.parentNode.removeChild(f),!0})}function z(a){var f=m(k.paths,a);if(f&&J(f)&&1<f.length)return d(a),f.shift(),i.require.undef(a),i.require([a]),!0}function h(a){var f,b=a?a.indexOf("!"):-1;-1<b&&(f=a.substring(0,b),a=a.substring(b+1,a.length));return[f,a]}function j(a,f,b,e){var n,C,g=null,d=f?f.name:
+null,j=a,l=!0,k="";a||(l=!1,a="_@r"+(M+=1));a=h(a);g=a[0];a=a[1];g&&(g=c(g,d,e),C=m(q,g));a&&(g?k=C&&C.normalize?C.normalize(a,function(a){return c(a,d,e)}):c(a,d,e):(k=c(a,d,e),a=h(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!C&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:f,unnormalized:!!b,url:n,originalName:j,isDefine:l,id:(g?g+"!"+k:k)+b}}function r(a){var f=a.id,b=m(p,f);b||(b=p[f]=new i.Module(a));return b}function t(a,f,b){var e=a.id,n=m(p,e);if(s(q,e)&&(!n||n.defineEmitComplete))"defined"===
+f&&b(q[e]);else r(a).on(f,b)}function v(a,f){var b=a.requireModules,e=!1;if(f)f(a);else if(y(b,function(f){if(f=m(p,f))f.error=a,f.events.error&&(e=!0,f.emit("error",a))}),!e)l.onError(a)}function w(){T.length&&(ia.apply(H,[H.length-1,0].concat(T)),T=[])}function x(a){delete p[a];delete V[a]}function F(a,f,b){var e=a.map.id;a.error?a.emit("error",a.error):(f[e]=!0,y(a.depMaps,function(e,c){var g=e.id,d=m(p,g);d&&(!a.depMatched[c]&&!b[g])&&(m(f,g)?(a.defineDep(c,q[g]),a.check()):F(d,f,b))}),b[e]=!0)}
+function D(){var a,f,b,e,n=(b=1E3*k.waitSeconds)&&i.startTime+b<(new Date).getTime(),c=[],g=[],h=!1,j=!0;if(!W){W=!0;G(V,function(b){a=b.map;f=a.id;if(b.enabled&&(a.isDefine||g.push(b),!b.error))if(!b.inited&&n)z(f)?h=e=!0:(c.push(f),d(f));else if(!b.inited&&(b.fetched&&a.isDefine)&&(h=!0,!a.prefix))return j=!1});if(n&&c.length)return b=B("timeout","Load timeout for modules: "+c,null,c),b.contextName=i.contextName,v(b);j&&y(g,function(a){F(a,{},{})});if((!n||e)&&h)if((A||da)&&!X)X=setTimeout(function(){X=
+0;D()},50);W=!1}}function E(a){s(q,a[0])||r(j(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!Y?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||Y)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;for(w();H.length;){a=H.shift();if(null===a[0])return v(B("mismatch","Mismatched anonymous define() module: "+a[a.length-
+1]));E(a)}}var W,Z,i,N,X,k={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},shim:{},config:{}},p={},V={},$={},H=[],q={},U={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=q[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return k.config&&m(k.config,a.map.id)||{}},exports:q[a.map.id]}}};Z=function(a){this.events=
+m($,a.id)||{};this.map=a;this.shim=m(k.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Z.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=
+!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;U[a]||(U[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;
+var e=this.exports,n=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(I(n)){if(this.events.error)try{e=i.execCb(c,n,b,e)}catch(d){a=d}else e=i.execCb(c,n,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=[this.map.id],a.requireType="define",v(this.error=
+a)}else e=n;this.exports=e;if(this.map.isDefine&&!this.ignore&&(q[c]=e,l.onResourceLoad))l.onResourceLoad(i,this.map,this.depMaps);x(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=j(a.prefix);this.depMaps.push(d);t(d,"defined",u(this,function(e){var n,d;d=this.map.name;var g=this.map.parentMap?this.map.parentMap.name:null,h=
+i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,g,!0)})||""),e=j(a.prefix+"!"+d,this.map.parentMap),t(e,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(p,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else n=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),n.error=u(this,
+function(a){this.inited=!0;this.error=a;a.requireModules=[b];G(p,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&x(a.map.id)});v(a)}),n.fromText=u(this,function(e,c){var d=a.name,g=j(d),C=O;c&&(e=c);C&&(O=!1);r(g);s(k.config,b)&&(k.config[d]=k.config[b]);try{l.exec(e)}catch(ca){return v(B("fromtexteval","fromText eval for "+b+" failed: "+ca,ca,[b]))}C&&(O=!0);this.depMaps.push(g);i.completeLoad(d);h([d],n)}),e.load(a.name,h,n,k)}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=
+this;this.enabling=this.enabled=!0;y(this.depMaps,u(this,function(a,b){var c,e;if("string"===typeof a){a=j(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;t(a,"defined",u(this,function(a){this.defineDep(b,a);this.check()}));this.errback&&t(a,"error",this.errback)}c=a.id;e=p[c];!s(N,c)&&(e&&!e.enabled)&&i.enable(a,this)}));G(this.pluginMaps,u(this,function(a){var b=m(p,a.id);b&&!b.enabled&&i.enable(a,
+this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){y(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:k,contextName:b,registry:p,defined:q,urlFetched:U,defQueue:H,Module:Z,makeModuleMap:j,nextTick:l.nextTick,onError:v,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.pkgs,c=k.shim,e={paths:!0,config:!0,map:!0};G(a,function(a,b){e[b]?
+"map"===b?(k.map||(k.map={}),R(k[b],a,!0,!0)):R(k[b],a,!0):k[b]=a});a.shim&&(G(a.shim,function(a,b){J(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);c[b]=a}),k.shim=c);a.packages&&(y(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,location:a.location||a.name,main:(a.main||"main").replace(ja,"").replace(ea,"")}}),k.pkgs=b);G(p,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=j(b))});if(a.deps||a.callback)i.require(a.deps||[],
+a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(aa,arguments));return b||a.exports&&ba(a.exports)}},makeRequire:function(a,f){function d(e,c,h){var g,k;f.enableBuildCallback&&(c&&I(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(I(c))return v(B("requireargs","Invalid require call"),h);if(a&&s(N,e))return N[e](p[a.id]);if(l.get)return l.get(i,e,a,d);g=j(e,a,!1,!0);g=g.id;return!s(q,g)?v(B("notloaded",'Module name "'+g+'" has not been loaded yet for context: '+
+b+(a?"":". Use require([])"))):q[g]}L();i.nextTick(function(){L();k=r(j(null,a));k.skipMap=f.skipMap;k.init(e,c,h,{enabled:!0});D()});return d}f=f||{};R(d,{isBrowser:A,toUrl:function(b){var d,f=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==f&&(!("."===g||".."===g)||1<f))d=b.substring(f,b.length),b=b.substring(0,f);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return s(q,j(b,a,!1,!0).id)},specified:function(b){b=j(b,a,!1,!0).id;return s(q,b)||s(p,b)}});a||(d.undef=function(b){w();var c=
+j(b,a,!0),d=m(p,b);delete q[b];delete U[c.url];delete $[b];d&&(d.events.defined&&($[b]=d.events),x(b))});return d},enable:function(a){m(p,a.id)&&r(a).enable()},completeLoad:function(a){var b,c,e=m(k.shim,a)||{},d=e.exports;for(w();H.length;){c=H.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=m(p,a);if(!b&&!s(q,a)&&c&&!c.inited){if(k.enforceDefine&&(!d||!ba(d)))return z(a)?void 0:v(B("nodefine","No define call for "+a,null,[a]));E([a,e.deps||[],e.exportsFn])}D()},nameToUrl:function(a,
+b,c){var e,d,h,g,j,i;if(l.jsExtRegExp.test(a))g=a+(b||"");else{e=k.paths;d=k.pkgs;g=a.split("/");for(j=g.length;0<j;j-=1)if(i=g.slice(0,j).join("/"),h=m(d,i),i=m(e,i)){J(i)&&(i=i[0]);g.splice(0,j,i);break}else if(h){a=a===h.name?h.location+"/"+h.main:h.location;g.splice(0,j,a);break}g=g.join("/");g+=b||(/\?/.test(g)||c?"":".js");g=("/"===g.charAt(0)||g.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+g}return k.urlArgs?g+((-1===g.indexOf("?")?"?":"&")+k.urlArgs):g},load:function(a,b){l.load(i,a,b)},execCb:function(a,
+b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!z(b.id))return v(B("scripterror","Script error",a,[b.id]))}};i.require=i.makeRequire();return i}var l,w,x,D,t,E,P,K,Q,fa,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/\.js$/,ja=/^\.\//;w=Object.prototype;var L=w.toString,ga=w.hasOwnProperty,ia=
+Array.prototype.splice,A=!!("undefined"!==typeof window&&navigator&&document),da=!A&&"undefined"!==typeof importScripts,ka=A&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,Y="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},T=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(I(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!I(require)&&(r=require,require=void 0);l=requirejs=function(b,c,d,z){var h,
+j="_";!J(b)&&"string"!==typeof b&&(h=b,J(c)?(b=c,c=d,d=z):b=[]);h&&h.context&&(j=h.context);(z=m(F,j))||(z=F[j]=l.s.newContext(j));h&&z.configure(h);return z.require(b,c,d)};l.config=function(b){return l(b)};l.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=l);l.version="2.1.5";l.jsExtRegExp=/^\/|:|\?|\.js$/;l.isBrowser=A;w=l.s={contexts:F,newContext:ha};l({});y(["toUrl","undef","defined","specified"],function(b){l[b]=function(){var c=F._;return c.require[b].apply(c,
+arguments)}});if(A&&(x=w.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))x=w.head=D.parentNode;l.onError=function(b){throw b;};l.load=function(b,c,d){var l=b&&b.config||{},h;if(A)return h=l.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),h.type=l.scriptType||"text/javascript",h.charset="utf-8",h.async=!0,h.setAttribute("data-requirecontext",b.contextName),h.setAttribute("data-requiremodule",c),
+h.attachEvent&&!(h.attachEvent.toString&&0>h.attachEvent.toString().indexOf("[native code"))&&!Y?(O=!0,h.attachEvent("onreadystatechange",b.onScriptLoad)):(h.addEventListener("load",b.onScriptLoad,!1),h.addEventListener("error",b.onScriptError,!1)),h.src=d,K=h,D?x.insertBefore(h,D):x.appendChild(h),K=null,h;if(da)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(B("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};A&&M(document.getElementsByTagName("script"),function(b){x||(x=
+b.parentNode);if(t=b.getAttribute("data-main"))return r.baseUrl||(E=t.split("/"),Q=E.pop(),fa=E.length?E.join("/")+"/":"./",r.baseUrl=fa,t=Q),t=t.replace(ea,""),r.deps=r.deps?r.deps.concat(t):[t],!0});define=function(b,c,d){var l,h;"string"!==typeof b&&(d=c,c=b,b=null);J(c)||(d=c,c=[]);!c.length&&I(d)&&d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c));if(O){if(!(l=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"),
+function(b){if("interactive"===b.readyState)return P=b}),l=P;l&&(b||(b=l.getAttribute("data-requiremodule")),h=F[l.getAttribute("data-requirecontext")])}(h?h.defQueue:T).push([b,c,d])};define.amd={jQuery:!0};l.exec=function(b){return eval(b)};l(r)}})(this);

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html b/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html
new file mode 100644
index 0000000..e71987b
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html
@@ -0,0 +1,35 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Log Viewer</title>
+  <link href="../../css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+  <link href="../../css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
+  <link href="css/logviewer.css" type ="text/css" rel="stylesheet" />
+  <script src="../../js/jquery.js" type="text/javascript"></script>
+  <script src="../../js/bootstrap.min.js" type="text/javascript"></script>
+</head>
+<body>
+  <div id="content"></div>
+  <script src="js/logviewer.js" type="text/javascript"></script>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js
new file mode 100644
index 0000000..e7e9db5
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js
@@ -0,0 +1,57 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractTextWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.AutocompleteWidget = AjaxSolr.AbstractTextWidget.extend({
+  afterRequest: function () {
+    $(this.target).find('input').unbind().removeData('events').val('');
+
+    var self = this;
+
+    var list = [];
+    for (var i = 0; i < this.fields.length; i++) {
+      var field = this.fields[i];
+      for (var facet in this.manager.response.facet_counts.facet_fields[field]) {
+        list.push({
+          field: field,
+          value: facet,
+          label: facet + ' (' + this.manager.response.facet_counts.facet_fields[field][facet] + ') - ' + field
+        });
+      }
+    }
+
+    this.requestSent = false;
+    $(this.target).find('input').autocomplete('destroy').autocomplete({
+      source: list,
+      select: function(event, ui) {
+        if (ui.item) {
+          self.requestSent = true;
+          if (self.manager.store.addByValue('fq', ui.item.field + ':' + AjaxSolr.Parameter.escapeValue(ui.item.value))) {
+            self.doRequest();
+          }
+        }
+      }
+    });
+
+    // This has lower priority so that requestSent is set.
+    $(this.target).find('input').bind('keydown', function(e) {
+      if (self.requestSent === false && e.which == 13) {
+        var value = $(this).val();
+        if (value && self.set(value)) {
+          self.doRequest();
+        }
+      }
+    });
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js
new file mode 100644
index 0000000..6a00865
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js
@@ -0,0 +1,71 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractTextWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.AutocompleteWidget = AjaxSolr.AbstractTextWidget.extend({
+  afterRequest: function () {
+    $(this.target).find('input').unbind().removeData('events').val('');
+
+    var self = this;
+
+    var callback = function (response) {
+      var list = [];
+      for (var i = 0; i < self.fields.length; i++) {
+        var field = self.fields[i];
+        for (var facet in response.facet_counts.facet_fields[field]) {
+          list.push({
+            field: field,
+            value: facet,
+            label: facet + ' (' + response.facet_counts.facet_fields[field][facet] + ') - ' + field
+          });
+        }
+      }
+
+      self.requestSent = false;
+      $(self.target).find('input').autocomplete({
+        minLength: 2,
+        source: list,
+        select: function(event, ui) {
+          if (ui.item) {
+            self.requestSent = true;
+            if (self.manager.store.addByValue('fq', ui.item.field + ':' + AjaxSolr.Parameter.escapeValue(ui.item.value))) {
+              self.doRequest();
+            }
+          }
+        }
+      });
+
+      // This has lower priority so that requestSent is set.
+      $(self.target).find('input').bind('keydown', function(e) {
+        if (self.requestSent === false && e.which == 13) {
+          var value = $(this).val();
+          if (value && self.set(value)) {
+            self.doRequest();
+          }
+        }
+      });
+    } // end callback
+
+    var params = [ 'rows=0&facet=true&facet.limit=-1&facet.mincount=1&json.nl=map' ];
+    for (var i = 0; i < this.fields.length; i++) {
+      params.push('facet.field=' + this.fields[i]);
+    }
+    var values = this.manager.store.values('fq');
+    for (var i = 0; i < values.length; i++) {
+      params.push('fq=' + encodeURIComponent(values[i]));
+    }
+    params.push('q=' + this.manager.store.get('q').val());
+    $.getJSON(this.manager.solrUrl + 'select?' + params.join('&') + '&wt=json&json.wrf=?', {}, callback);
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js
new file mode 100644
index 0000000..26759ff
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js
@@ -0,0 +1,38 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractFacetWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.CalendarWidget = AjaxSolr.AbstractFacetWidget.extend({
+  afterRequest: function () {
+    var self = this;
+    $(this.target).datepicker('destroy').datepicker({
+      dateFormat: 'yy-mm-dd',
+      defaultDate: new Date(1987, 2, 1),
+      maxDate: $.datepicker.parseDate('yy-mm-dd', this.manager.store.get('facet.date.end').val().split('T')[0]),
+      minDate: $.datepicker.parseDate('yy-mm-dd', this.manager.store.get('facet.date.start').val().split('T')[0]),
+      nextText: '&gt;',
+      prevText: '&lt;',
+      beforeShowDay: function (date) {
+        var value = $.datepicker.formatDate('yy-mm-dd', date) + 'T00:00:00Z';
+        var count = self.manager.response.facet_counts.facet_dates[self.field][value];
+        return [ parseInt(count) > 0, '', count + ' documents found!' ];
+      },
+      onSelect: function (dateText, inst) {
+        if (self.add('[' + dateText + 'T00:00:00Z TO ' + dateText + 'T23:59:59Z]')) {
+          self.doRequest();
+        }
+      }
+    });
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js
new file mode 100644
index 0000000..28ff16e
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js
@@ -0,0 +1,50 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractFacetWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.CountryCodeWidget = AjaxSolr.AbstractFacetWidget.extend({
+  afterRequest: function () {
+    var self = this;
+
+    $(this.target).empty();
+
+    var maxCount = 0;
+    var options = { '': '--select--' };
+    for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) {
+      if (facet.length == 2) { // only display country codes
+        var count = this.manager.response.facet_counts.facet_fields[this.field][facet];
+        if (count > maxCount) {
+          maxCount = count;
+        }
+        options[facet] = facet + ' (' + count + ')';
+      }
+    }
+    $(this.target).append(this.template('country', options));
+
+    $(this.target).find('#country').change(function () {
+      var value = $(this).val();
+      if (value && self.add(value)) {
+        self.doRequest();
+      }
+    });
+  },
+
+  template: function (name, container) {
+    var options = [];
+    for (var value in container) {
+      options.push('<option value="' + value +'">' + container[value] + '</option>');
+    }
+    return '<select id="' + name + '" name="' + name + '">' + options.join('\n') + '</select>';
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js
new file mode 100644
index 0000000..dfe5eca
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js
@@ -0,0 +1,79 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractFacetWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.CountryCodeWidget = AjaxSolr.AbstractFacetWidget.extend({
+  afterRequest: function () {
+    var self = this;
+
+    $(this.target).empty();
+
+    var maps = {
+      world: 'view the World',
+      africa: 'view Africa',
+      asia: 'view Asia',
+      europe: 'view Europe',
+      middle_east: 'view the Middle East',
+      south_america: 'view South America',
+      usa: 'view North America'
+    };
+    $(this.target).append(this.template('region', maps));
+
+    $(this.target).find('#region').change(function () {
+      $(self.target).find('img').hide();
+      $('#' + self.id + $(this).val()).show();
+    });
+
+    var maxCount = 0;
+    var options = { '': '--select--' };
+    for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) {
+      if (facet.length == 2) { // only display country codes
+        var count = this.manager.response.facet_counts.facet_fields[this.field][facet];
+        if (count > maxCount) {
+          maxCount = count;
+        }
+        options[facet] = facet + ' (' + count + ')';
+      }
+    }
+    $(this.target).append(this.template('country', options));
+
+    $(this.target).find('#country').change(function () {
+      var value = $(this).val();
+      if (value && self.add(value)) {
+        self.doRequest();
+      }
+    });
+
+    var chd = [];
+    var chld = '';
+    for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) {
+      if (facet.length == 2) { // only display country codes
+        chd.push(parseInt(this.manager.response.facet_counts.facet_fields[this.field][facet] / maxCount * 100) + '.0');
+        chld += facet;
+      }
+    }
+    for (var value in maps) {
+      var src = 'http://chart.apis.google.com/chart?chco=f5f5f5,edf0d4,6c9642,365e24,13390a&chd=t:' + chd.join(',') + '&chf=bg,s,eaf7fe&chtm=' + value + '&chld=' + chld + '&chs=350x180&cht=t';
+      $('<img>').attr('id', this.id + value).showIf(value == 'world').attr('src', src).appendTo(this.target);
+    }
+  },
+
+  template: function (name, container) {
+    var options = [];
+    for (var value in container) {
+      options.push('<option value="' + value +'">' + container[value] + '</option>');
+    }
+    return '<select id="' + name + '" name="' + name + '">' + options.join('\n') + '</select>';
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js
new file mode 100644
index 0000000..21b22f4
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js
@@ -0,0 +1,74 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.CurrentSearchWidget = AjaxSolr.AbstractWidget.extend({
+  start: 0,
+
+  afterRequest: function () {
+    var self = this;
+    var links = [];
+
+    var q = this.manager.store.get('q').val();
+    if (q != '*:*') {
+      links.push($('<a href="#"></a>').text('(x) ' + q).click(function () {
+        self.manager.store.get('q').val('*:*');
+        self.doRequest();
+        return false;
+      }));
+    }
+
+    var fq = this.manager.store.values('fq');
+    for (var i = 0, l = fq.length; i < l; i++) {
+      if (fq[i].match(/[\[\{]\S+ TO \S+[\]\}]/)) {
+        var field = fq[i].match(/^\w+:/)[0];
+        var value = fq[i].substr(field.length + 1, 10);
+        links.push($('<a href="#"></a>').text('(x) ' + field + value).click(self.removeFacet(fq[i])));
+      }
+      else {
+        links.push($('<a href="#"></a>').text('(x) ' + fq[i]).click(self.removeFacet(fq[i])));
+      }
+    }
+
+    if (links.length > 1) {
+      links.unshift($('<a href="#"></a>').text('remove all').click(function () {
+        self.manager.store.get('q').val('*:*');
+        self.manager.store.remove('fq');
+        self.doRequest();
+        return false;
+      }));
+    }
+
+    if (links.length) {
+      var $target = $(this.target);
+      $target.empty();
+      for (var i = 0, l = links.length; i < l; i++) {
+        $target.append($('<li></li>').append(links[i]));
+      }
+    }
+    else {
+      $(this.target).html('<li>Viewing all documents!</li>');
+    }
+  },
+
+  removeFacet: function (facet) {
+    var self = this;
+    return function () {
+      if (self.manager.store.removeByValue('fq', facet)) {
+        self.doRequest();
+      }
+      return false;
+    };
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js
new file mode 100644
index 0000000..3378553
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js
@@ -0,0 +1,67 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.CurrentSearchWidget = AjaxSolr.AbstractWidget.extend({
+  start: 0,
+
+  afterRequest: function () {
+    var self = this;
+    var links = [];
+
+    var q = this.manager.store.get('q').val();
+    if (q != '*:*') {
+      links.push($('<a href="#"></a>').text('(x) ' + q).click(function () {
+        self.manager.store.get('q').val('*:*');
+        self.doRequest();
+        return false;
+      }));
+    }
+
+    var fq = this.manager.store.values('fq');
+    for (var i = 0, l = fq.length; i < l; i++) {
+      links.push($('<a href="#"></a>').text('(x) ' + fq[i]).click(self.removeFacet(fq[i])));
+    }
+
+    if (links.length > 1) {
+      links.unshift($('<a href="#"></a>').text('remove all').click(function () {
+        self.manager.store.get('q').val('*:*');
+        self.manager.store.remove('fq');
+        self.doRequest();
+        return false;
+      }));
+    }
+
+    if (links.length) {
+      var $target = $(this.target);
+      $target.empty();
+      for (var i = 0, l = links.length; i < l; i++) {
+        $target.append($('<li></li>').append(links[i]));
+      }
+    }
+    else {
+      $(this.target).html('<li>Viewing all documents!</li>');
+    }
+  },
+
+  removeFacet: function (facet) {
+    var self = this;
+    return function () {
+      if (self.manager.store.removeByValue('fq', facet)) {
+        self.doRequest();
+      }
+      return false;
+    };
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js
new file mode 100644
index 0000000..e343c0a
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js
@@ -0,0 +1,41 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({
+  afterRequest: function () {
+    $(this.target).empty();
+    for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) {
+      var doc = this.manager.response.response.docs[i];
+      $(this.target).append(this.template(doc));
+    }
+  },
+
+  template: function (doc) {
+    var snippet = '';
+    if (doc.data.length > 300) {
+      snippet += doc.source + ' ' + doc.data.substring(0, 300);
+      snippet += '<span style="display:none;">' + doc.data.substring(300);
+      snippet += '</span> <a href="#" class="more">more</a>';
+    }
+    else {
+      snippet += doc.source + ' ' + doc.data;
+    }
+
+    var output = '<div><h2>' + doc.type + '</h2>';
+    output += '<p id="links_' + doc.id + '" class="links"></p>';
+    output += '<p>' + snippet + '</p></div>';
+    return output;
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js
new file mode 100644
index 0000000..7ec6061
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js
@@ -0,0 +1,106 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({
+  start: 0,
+
+  beforeRequest: function () {
+    $(this.target).html($('<img>').attr('src', 'images/ajax-loader.gif'));
+  },
+
+  facetLinks: function (facet_field, facet_values) {
+    var links = [];
+    if (facet_values) {
+      for (var i = 0, l = facet_values.length; i < l; i++) {
+        if (facet_values[i] !== undefined) {
+          links = links.concat([
+            facet_field + ':',
+            $('<a href="#"></a>')
+            .text(facet_values[i])
+            .click(this.facetHandler(facet_field, facet_values[i]))
+          ]);
+        }
+        else {
+          links.push('no items found in current selection');
+        }
+      }
+    }
+    return links;
+  },
+
+  facetHandler: function (facet_field, facet_value) {
+    var self = this;
+    return function () {
+      self.manager.store.remove('fq');
+      self.manager.store.addByValue('fq', facet_field + ':' + AjaxSolr.Parameter.escapeValue(facet_value));
+      self.doRequest(0);
+      return false;
+    };
+  },
+
+  afterRequest: function () {
+    $(this.target).empty();
+    for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) {
+      var doc = this.manager.response.response.docs[i];
+      $(this.target).append(this.template(doc));
+
+      var items = [];
+      items = items.concat(this.facetLinks('topics', doc.type));
+      items = items.concat(this.facetLinks('sources', doc.source));
+      //items = items.concat(this.facetLinks('users', doc.users));
+
+      var $links = $('#links_' + doc.id);
+      $links.empty();
+      for (var j = 0, m = items.length; j < m; j++) {
+        $links.append($('<li></li>').append(items[j]));
+      }
+    }
+  },
+
+  template: function (doc) {
+    var snippet = '';
+    if (doc.data.length > 300) {
+      snippet += doc.source + ' ' + doc.data.substring(0, 300);
+      snippet += '<span style="display:none;">' + doc.data.substring(300);
+      snippet += '</span> <a href="#" class="more">more</a>';
+    }
+    else {
+      snippet += doc.source + ' ' + doc.data;
+    }
+
+    var output = '<div><h2>' + doc.type + '</h2>';
+    output += '<p id="links_' + doc.id + '" class="links"></p>';
+    output += '<p>' + snippet + '</p></div>';
+    return output;
+  },
+
+  init: function () {
+    $(document).on('click', 'a.more', function () {
+      var $this = $(this),
+          span = $this.parent().find('span');
+
+      if (span.is(':visible')) {
+        span.hide();
+        $this.text('more');
+      }
+      else {
+        span.show();
+        $this.text('less');
+      }
+
+      return false;
+    });
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js
new file mode 100644
index 0000000..fc87e83
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js
@@ -0,0 +1,107 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({
+  start: 0,
+
+  beforeRequest: function () {
+    $(this.target).html($('<img>').attr('src', 'images/ajax-loader.gif'));
+  },
+
+  facetLinks: function (facet_field, facet_values) {
+    var links = [];
+    if (facet_values) {
+      for (var i = 0, l = facet_values.length; i < l; i++) {
+        if (facet_values[i] !== undefined) {
+          links.push(
+            $('<a href="#"></a>')
+            .text(facet_values[i])
+            .click(this.facetHandler(facet_field, facet_values[i]))
+          );
+        }
+        else {
+          links.push('no items found in current selection');
+        }
+      }
+    }
+    return links;
+  },
+
+  facetHandler: function (facet_field, facet_value) {
+    var self = this;
+    return function () {
+      self.manager.store.remove('fq');
+      self.manager.store.addByValue('fq', facet_field + ':' + AjaxSolr.Parameter.escapeValue(facet_value));
+      self.doRequest(0);
+      return false;
+    };
+  },
+
+  afterRequest: function () {
+    $(this.target).empty();
+    for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) {
+      var doc = this.manager.response.response.docs[i];
+      $(this.target).append(this.template(doc));
+
+      var items = [];
+      items = items.concat(this.facetLinks('topics', doc.type));
+      items = items.concat(this.facetLinks('sources', doc.source));
+      //items = items.concat(this.facetLinks('users', doc.users));
+
+      var $links = $('#links_' + doc.id);
+      $links.empty();
+      for (var j = 0, m = items.length; j < m; j++) {
+        $links.append($('<li></li>').append(items[j]));
+      }
+    }
+  },
+
+  template: function (doc) {
+    var snippet = '';
+    if (doc.data.length > 300) {
+      snippet += doc.source + ' ' + doc.data.substring(0, 300);
+      snippet += '<span style="display:none;">' + doc.data.substring(300);
+      snippet += '</span> <a href="#" class="more">more</a>';
+    }
+    else {
+      snippet += doc.source + ' ' + doc.data;
+    }
+
+    var output = '<div><h2>' + doc.type + '</h2>';
+    output += '<p id="links_' + doc.id + '" class="links"></p>';
+    output += '<a href="log-viewer.html?type='+ doc.type +
+              '&source=' + doc.source + '&date='+ doc.date +'">Link</a>';
+    output += '<p>' + snippet + '</p></div>';
+    return output;
+  },
+
+  init: function () {
+    $(document).on('click', 'a.more', function () {
+      var $this = $(this),
+          span = $this.parent().find('span');
+
+      if (span.is(':visible')) {
+        span.hide();
+        $this.text('more');
+      }
+      else {
+        span.show();
+        $this.text('less');
+      }
+
+      return false;
+    });
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js
new file mode 100644
index 0000000..7d86914
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js
@@ -0,0 +1,47 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractFacetWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.TagcloudWidget = AjaxSolr.AbstractFacetWidget.extend({
+  afterRequest: function () {
+    if (this.manager.response.facet_counts.facet_fields[this.field] === undefined) {
+      $(this.target).html('no items found in current selection');
+      return;
+    }
+
+    var maxCount = 0;
+    var objectedItems = [];
+    for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) {
+      var count = parseInt(this.manager.response.facet_counts.facet_fields[this.field][facet]);
+      if (count > maxCount) {
+        maxCount = count;
+      }
+      objectedItems.push({ facet: facet, count: count });
+    }
+    objectedItems.sort(function (a, b) {
+      return a.facet < b.facet ? -1 : 1;
+    });
+
+    $(this.target).empty();
+    for (var i = 0, l = objectedItems.length; i < l; i++) {
+      var facet = objectedItems[i].facet;
+      $(this.target).append(
+        $('<a href="#" class="tagcloud_item"></a>')
+        .text(facet)
+        .addClass('tagcloud_size_' + parseInt(objectedItems[i].count / maxCount * 10))
+        .click(this.clickHandler(facet))
+      );
+    }
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js
new file mode 100644
index 0000000..c701fbf
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js
@@ -0,0 +1,32 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractTextWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+(function ($) {
+
+AjaxSolr.TextWidget = AjaxSolr.AbstractTextWidget.extend({
+  init: function () {
+    var self = this;
+    $(this.target).find('input').bind('keydown', function(e) {
+      if (e.which == 13) {
+        var value = $(this).val();
+        if (value && self.set(value)) {
+          self.doRequest();
+        }
+      }
+    });
+  },
+
+  afterRequest: function () {
+    $(this.target).find('input').val('');
+  }
+});
+
+})(jQuery);
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js
new file mode 100644
index 0000000..9e5ca33
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js
@@ -0,0 +1,293 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget', 'core/Parameter'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * Baseclass for all facet widgets.
+ *
+ * @class AbstractFacetWidget
+ * @augments AjaxSolr.AbstractWidget
+ */
+AjaxSolr.AbstractFacetWidget = AjaxSolr.AbstractWidget.extend(
+  /** @lends AjaxSolr.AbstractFacetWidget.prototype */
+  {
+  /**
+   * @param {Object} attributes
+   * @param {String} attributes.field The field to facet on.
+   * @param {Number} [attributes.start] This widget will by default set the
+   *   offset parameter to 0 on each request.
+   * @param {Boolean} [attributes.multivalue] Set to <tt>false</tt> to force a
+   *   single "fq" parameter for this widget. Defaults to <tt>true</tt>.
+   */
+  constructor: function (attributes) {
+    AjaxSolr.AbstractFacetWidget.__super__.constructor.apply(this, arguments);
+    AjaxSolr.extend(this, {
+      start: 0,
+      field: null,
+      multivalue: true
+    }, attributes);
+  },
+
+  init: function () {
+    this.initStore();
+  },
+
+  /**
+   * Add facet parameters to the parameter store.
+   */
+  initStore: function () {
+    /* http://wiki.apache.org/solr/SimpleFacetParameters */
+    var parameters = [
+      'facet.prefix',
+      'facet.sort',
+      'facet.limit',
+      'facet.offset',
+      'facet.mincount',
+      'facet.missing',
+      'facet.method',
+      'facet.enum.cache.minDf'
+    ];
+
+    this.manager.store.addByValue('facet', true);
+
+    // Set facet.field, facet.date or facet.range to truthy values to add
+    // related per-field parameters to the parameter store.
+    if (this['facet.field'] !== undefined) {
+      this.manager.store.addByValue('facet.field', this.field);
+    }
+    else if (this['facet.date'] !== undefined) {
+      this.manager.store.addByValue('facet.date', this.field);
+      parameters = parameters.concat([
+        'facet.date.start',
+        'facet.date.end',
+        'facet.date.gap',
+        'facet.date.hardend',
+        'facet.date.other',
+        'facet.date.include'
+      ]);
+    }
+    else if (this['facet.range'] !== undefined) {
+      this.manager.store.addByValue('facet.range', this.field);
+      parameters = parameters.concat([
+        'facet.range.start',
+        'facet.range.end',
+        'facet.range.gap',
+        'facet.range.hardend',
+        'facet.range.other',
+        'facet.range.include'
+      ]);
+    }
+
+    for (var i = 0, l = parameters.length; i < l; i++) {
+      if (this[parameters[i]] !== undefined) {
+        this.manager.store.addByValue('f.' + this.field + '.' + parameters[i], this[parameters[i]]);
+      }
+    }
+  },
+
+  /**
+   * @returns {Boolean} Whether any filter queries have been set using this
+   *   widget's facet field.
+   */
+  isEmpty: function () {
+    return !this.manager.store.find('fq', new RegExp('^-?' + this.field + ':'));
+  },
+
+  /**
+   * Sets the filter query.
+   *
+   * @returns {Boolean} Whether the selection changed.
+   */
+  set: function (value) {
+    return this.changeSelection(function () {
+      var a = this.manager.store.removeByValue('fq', new RegExp('^-?' + this.field + ':')),
+          b = this.manager.store.addByValue('fq', this.fq(value));
+      return a || b;
+    });
+  },
+
+  /**
+   * Adds a filter query.
+   *
+   * @returns {Boolean} Whether a filter query was added.
+   */
+  add: function (value) {
+    return this.changeSelection(function () {
+      return this.manager.store.addByValue('fq', this.fq(value));
+    });
+  },
+
+  /**
+   * Removes a filter query.
+   *
+   * @returns {Boolean} Whether a filter query was removed.
+   */
+  remove: function (value) {
+    return this.changeSelection(function () {
+      return this.manager.store.removeByValue('fq', this.fq(value));
+    });
+  },
+
+  /**
+   * Removes all filter queries using the widget's facet field.
+   *
+   * @returns {Boolean} Whether a filter query was removed.
+   */
+  clear: function () {
+    return this.changeSelection(function () {
+      return this.manager.store.removeByValue('fq', new RegExp('^-?' + this.field + ':'));
+    });
+  },
+
+  /**
+   * Helper for selection functions.
+   *
+   * @param {Function} Selection function to call.
+   * @returns {Boolean} Whether the selection changed.
+   */
+  changeSelection: function (func) {
+    changed = func.apply(this);
+    if (changed) {
+      this.afterChangeSelection();
+    }
+    return changed;
+  },
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>This method is executed after the filter queries change.</p>
+   */
+  afterChangeSelection: function () {},
+
+  /**
+   * One of "facet.field", "facet.date" or "facet.range" must be set on the
+   * widget in order to determine where the facet counts are stored.
+   *
+   * @returns {Array} An array of objects with the properties <tt>facet</tt> and
+   * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>.
+   */
+  getFacetCounts: function () {
+    var property;
+    if (this['facet.field'] !== undefined) {
+      property = 'facet_fields';
+    }
+    else if (this['facet.date'] !== undefined) {
+      property = 'facet_dates';
+    }
+    else if (this['facet.range'] !== undefined) {
+      property = 'facet_ranges';
+    }
+    if (property !== undefined) {
+      switch (this.manager.store.get('json.nl').val()) {
+        case 'map':
+          return this.getFacetCountsMap(property);
+        case 'arrarr':
+          return this.getFacetCountsArrarr(property);
+        default:
+          return this.getFacetCountsFlat(property);
+      }
+    }
+    throw 'Cannot get facet counts unless one of the following properties is set to "true" on widget "' + this.id + '": "facet.field", "facet.date", or "facet.range".';
+  },
+
+  /**
+   * Used if the facet counts are represented as a JSON object.
+   *
+   * @param {String} property "facet_fields", "facet_dates", or "facet_ranges".
+   * @returns {Array} An array of objects with the properties <tt>facet</tt> and
+   * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>.
+   */
+  getFacetCountsMap: function (property) {
+    var counts = [];
+    for (var facet in this.manager.response.facet_counts[property][this.field]) {
+      counts.push({
+        facet: facet,
+        count: parseInt(this.manager.response.facet_counts[property][this.field][facet])
+      });
+    }
+    return counts;
+  },
+
+  /**
+   * Used if the facet counts are represented as an array of two-element arrays.
+   *
+   * @param {String} property "facet_fields", "facet_dates", or "facet_ranges".
+   * @returns {Array} An array of objects with the properties <tt>facet</tt> and
+   * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>.
+   */
+  getFacetCountsArrarr: function (property) {
+    var counts = [];
+    for (var i = 0, l = this.manager.response.facet_counts[property][this.field].length; i < l; i++) {
+      counts.push({
+        facet: this.manager.response.facet_counts[property][this.field][i][0],
+        count: parseInt(this.manager.response.facet_counts[property][this.field][i][1])
+      });
+    }
+    return counts;
+  },
+
+  /**
+   * Used if the facet counts are represented as a flat array.
+   *
+   * @param {String} property "facet_fields", "facet_dates", or "facet_ranges".
+   * @returns {Array} An array of objects with the properties <tt>facet</tt> and
+   * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>.
+   */
+  getFacetCountsFlat: function (property) {
+    var counts = [];
+    for (var i = 0, l = this.manager.response.facet_counts[property][this.field].length; i < l; i += 2) {
+      counts.push({
+        facet: this.manager.response.facet_counts[property][this.field][i],
+        count: parseInt(this.manager.response.facet_counts[property][this.field][i+1])
+      });
+    }
+    return counts;
+  },
+
+  /**
+   * @param {String} value The value.
+   * @returns {Function} Sends a request to Solr if it successfully adds a
+   *   filter query with the given value.
+   */
+  clickHandler: function (value) {
+    var self = this, meth = this.multivalue ? 'add' : 'set';
+    return function () {
+      if (self[meth].call(self, value)) {
+        self.doRequest();
+      }
+      return false;
+    }
+  },
+
+  /**
+   * @param {String} value The value.
+   * @returns {Function} Sends a request to Solr if it successfully removes a
+   *   filter query with the given value.
+   */
+  unclickHandler: function (value) {
+    var self = this;
+    return function () {
+      if (self.remove(value)) {
+        self.doRequest();
+      }
+      return false;
+    }
+  },
+
+  /**
+   * @param {String} value The facet value.
+   * @param {Boolean} exclude Whether to exclude this fq parameter value.
+   * @returns {String} An fq parameter value.
+   */
+  fq: function (value, exclude) {
+    return (exclude ? '-' : '') + this.field + ':' + AjaxSolr.Parameter.escapeValue(value);
+  }
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractManager.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/AbstractManager.js b/src/main/web/hicc/ajax-solr/core/AbstractManager.js
new file mode 100644
index 0000000..72e0972
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/AbstractManager.js
@@ -0,0 +1,159 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/Core'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * The Manager acts as the controller in a Model-View-Controller framework. All
+ * public calls should be performed on the manager object.
+ *
+ * @param properties A map of fields to set. Refer to the list of public fields.
+ * @class AbstractManager
+ */
+AjaxSolr.AbstractManager = AjaxSolr.Class.extend(
+  /** @lends AjaxSolr.AbstractManager.prototype */
+  {
+  /**
+   * @param {Object} [attributes]
+   * @param {String} [attributes.solrUrl] The fully-qualified URL of the Solr
+   *   application. You must include the trailing slash. Do not include the path
+   *   to any Solr servlet. Defaults to "http://localhost:8983/solr/"
+   * @param {String} [attributes.proxyUrl] If we want to proxy queries through a
+   *   script, rather than send queries to Solr directly, set this field to the
+   *   fully-qualified URL of the script.
+   * @param {String} [attributes.servlet] The default Solr servlet. You may
+   *   prepend the servlet with a core if using multiple cores. Defaults to
+   *   "servlet".
+   */
+  constructor: function (attributes) {
+    AjaxSolr.extend(this, {
+      solrUrl: 'http://localhost:8983/solr/',
+      proxyUrl: null,
+      servlet: 'select',
+      // The most recent response from Solr.
+      response: {},
+      // A collection of all registered widgets.
+      widgets: {},
+      // The parameter store for the manager and its widgets.
+      store: null,
+      // Whether <tt>init()</tt> has been called yet.
+      initialized: false
+    }, attributes);
+  },
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>This method should be called after the store and the widgets have been
+   * added. It should initialize the widgets and the store, and do any other
+   * one-time initializations, e.g., perform the first request to Solr.</p>
+   *
+   * <p>If no store has been set, it sets the store to the basic <tt>
+   * AjaxSolr.ParameterStore</tt>.</p>
+   */
+  init: function () {
+    this.initialized = true;
+    if (this.store === null) {
+      this.setStore(new AjaxSolr.ParameterStore());
+    }
+    this.store.load(false);
+    for (var widgetId in this.widgets) {
+      this.widgets[widgetId].init();
+    }
+    this.store.init();
+  },
+
+  /**
+   * Set the manager's parameter store.
+   *
+   * @param {AjaxSolr.ParameterStore} store
+   */
+  setStore: function (store) {
+    store.manager = this;
+    this.store = store;
+  },
+
+  /**
+   * Adds a widget to the manager.
+   *
+   * @param {AjaxSolr.AbstractWidget} widget
+   */
+  addWidget: function (widget) {
+    widget.manager = this;
+    this.widgets[widget.id] = widget;
+  },
+
+  /**
+   * Stores the Solr parameters to be sent to Solr and sends a request to Solr.
+   *
+   * @param {Boolean} [start] The Solr start offset parameter.
+   * @param {String} [servlet] The Solr servlet to send the request to.
+   */
+  doRequest: function (start, servlet) {
+    if (this.initialized === false) {
+      this.init();
+    }
+    // Allow non-pagination widgets to reset the offset parameter.
+    if (start !== undefined) {
+      this.store.get('start').val(start);
+    }
+    if (servlet === undefined) {
+      servlet = this.servlet;
+    }
+
+    this.store.save();
+
+    for (var widgetId in this.widgets) {
+      this.widgets[widgetId].beforeRequest();
+    }
+
+    this.executeRequest(servlet);
+  },
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>Sends the request to Solr, i.e. to <code>this.solrUrl</code> or <code>
+   * this.proxyUrl</code>, and receives Solr's response. It should pass Solr's
+   * response to <code>handleResponse()</code> for handling.</p>
+   *
+   * <p>See <tt>managers/Manager.jquery.js</tt> for a jQuery implementation.</p>
+   *
+   * @param {String} servlet The Solr servlet to send the request to.
+   * @param {String} string The query string of the request. If not set, it
+   *   should default to <code>this.store.string()</code>
+   * @throws If not defined in child implementation.
+   */
+  executeRequest: function (servlet, string) {
+    throw 'Abstract method executeRequest must be overridden in a subclass.';
+  },
+
+  /**
+   * This method is executed after the Solr response data arrives. Allows each
+   * widget to handle Solr's response separately.
+   *
+   * @param {Object} data The Solr response.
+   */
+  handleResponse: function (data) {
+    this.response = data;
+
+    for (var widgetId in this.widgets) {
+      this.widgets[widgetId].afterRequest();
+    }
+  },
+
+  /**
+   * This method is executed if Solr encounters an error.
+   *
+   * @param {String} message An error message.
+   */
+  handleError: function (message) {
+    window.console && console.log && console.log(message);
+  }
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js
new file mode 100644
index 0000000..bb9b316
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js
@@ -0,0 +1,67 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * Offers an interface to the local parameters used by the Spatial Solr plugin.
+ *
+ * @see http://www.jteam.nl/news/spatialsolr
+ *
+ * @class AbstractSpatialWidget
+ * @augments AjaxSolr.AbstractWidget
+ */
+AjaxSolr.AbstractSpatialWidget = AjaxSolr.AbstractWidget.extend(
+  /** @lends AjaxSolr.AbstractSpatialWidget.prototype */
+  {
+  /**
+   * Sets the Spatial Solr local parameters.
+   *
+   * @param {Object} params The local parameters to set.
+   * @param {Number} params.lat Latitude of the center of the search area.
+   * @param {Number} params.lng Longitude of the center of the search area.
+   * @param {Number} params.radius Radius of the search area.
+   * @param {String} [params.unit] Unit the distances should be calculated in:
+   *   "km" or "miles".
+   * @param {String} [params.calc] <tt>GeoDistanceCalculator</tt> that will be
+   *   used to calculate the distances. "arc" for
+   *   <tt>ArchGeoDistanceCalculator</tt> and "plane" for
+   *   <tt>PlaneGeoDistanceCalculator</tt>.
+   * @param {Number} [params.threadCount] Number of threads that will be used
+   *   by the <tt>ThreadedDistanceFilter</tt>.
+   */
+  set: function (params) {
+    this.manager.store.get('q').local('type', 'spatial');
+    this.manager.store.get('q').local('lat', params.lat);
+    this.manager.store.get('q').local('long', params.lng);
+    this.manager.store.get('q').local('radius', params.radius);
+    if (params.unit !== undefined) {
+      this.manager.store.get('q').local('unit', params.unit);
+    }
+    if (params.calc !== undefined) {
+      this.manager.store.get('q').local('calc', params.calc);
+    }
+    if (params.threadCount !== undefined) {
+      this.manager.store.get('q').local('threadCount', params.threadCount);
+    }
+  },
+
+  /**
+   * Removes the Spatial Solr local parameters.
+   */
+  clear: function () {
+    this.manager.store.get('q').remove('type');
+    this.manager.store.get('q').remove('lat');
+    this.manager.store.get('q').remove('long');
+    this.manager.store.get('q').remove('radius');
+    this.manager.store.get('q').remove('unit');
+    this.manager.store.get('q').remove('calc');
+    this.manager.store.get('q').remove('threadCount');
+  }
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js
new file mode 100644
index 0000000..76571c4
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js
@@ -0,0 +1,87 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * Interacts with Solr's SpellCheckComponent.
+ *
+ * @see http://wiki.apache.org/solr/SpellCheckComponent
+ *
+ * @class AbstractSpellcheckWidget
+ * @augments AjaxSolr.AbstractWidget
+ */
+AjaxSolr.AbstractSpellcheckWidget = AjaxSolr.AbstractWidget.extend(
+  /** @lends AjaxSolr.AbstractSpellcheckWidget.prototype */
+  {
+  constructor: function (attributes) {
+    AjaxSolr.AbstractSpellcheckWidget.__super__.constructor.apply(this, arguments);
+    AjaxSolr.extend(this, {
+      // The suggestions.
+      suggestions: {}
+    }, attributes);
+  },
+
+  /**
+   * Uses the top suggestion for each word to return a suggested query.
+   *
+   * @returns {String} A suggested query.
+   */
+  suggestion: function () {
+    var suggestion = this.manager.response.responseHeader.params['spellcheck.q'];
+    for (var word in this.suggestions) {
+      suggestion = suggestion.replace(new RegExp(word, 'g'), this.suggestions[word][0]);
+    }
+    return suggestion;
+  },
+
+  beforeRequest: function () {
+    if (this.manager.store.get('spellcheck').val() && this.manager.store.get('q').val()) {
+      this.manager.store.get('spellcheck.q').val(this.manager.store.get('q').val());
+    }
+    else {
+      this.manager.store.remove('spellcheck.q');
+    }
+  },
+
+  afterRequest: function () {
+    this.suggestions = {};
+
+    if (this.manager.response.spellcheck && this.manager.response.spellcheck.suggestions) {
+      var suggestions = this.manager.response.spellcheck.suggestions,
+          empty = true;
+
+      for (var word in suggestions) {
+        if (word == 'collation' || word == 'correctlySpelled') continue;
+
+        this.suggestions[word] = [];
+        for (var i = 0, l = suggestions[word].suggestion.length; i < l; i++) {
+          if (this.manager.response.responseHeader.params['spellcheck.extendedResults']) {
+            this.suggestions[word].push(suggestions[word].suggestion[i].word);
+          }
+          else {
+            this.suggestions[word].push(suggestions[word].suggestion[i]);
+          }
+        }
+        empty = false;
+      }
+
+      if (!empty) {
+        this.handleSuggestions(this.manager.response);
+      }
+    }
+  },
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>Allow the child to handle the suggestions without parsing the response.</p>
+   */
+  handleSuggestions: function () {}
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js
new file mode 100644
index 0000000..1be3da8
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js
@@ -0,0 +1,111 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/AbstractWidget'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * Baseclass for all free-text widgets.
+ *
+ * @class AbstractTextWidget
+ * @augments AjaxSolr.AbstractWidget
+ */
+AjaxSolr.AbstractTextWidget = AjaxSolr.AbstractWidget.extend(
+  /** @lends AjaxSolr.AbstractTextWidget.prototype */
+  {
+  /**
+   * @param {Object} [attributes]
+   * @param {Number} [attributes.start] This widget will by default set the
+   *   offset parameter to 0 on each request.
+   */
+  constructor: function (attributes) {
+    AjaxSolr.AbstractTextWidget.__super__.constructor.apply(this, arguments);
+    AjaxSolr.extend(this, {
+      start: 0
+    }, attributes);
+  },
+
+  /**
+   * Sets the main Solr query to the given string.
+   *
+   * @param {String} q The new Solr query.
+   * @returns {Boolean} Whether the selection changed.
+   */
+  set: function (q) {
+    return this.changeSelection(function () {
+      this.manager.store.get('q').val(q);
+    });
+  },
+
+  /**
+   * Sets the main Solr query to the empty string.
+   *
+   * @returns {Boolean} Whether the selection changed.
+   */
+  clear: function () {
+    return this.changeSelection(function () {
+      this.manager.store.remove('q');
+    });
+  },
+
+  /**
+   * Helper for selection functions.
+   *
+   * @param {Function} Selection function to call.
+   * @returns {Boolean} Whether the selection changed.
+   */
+  changeSelection: function (func) {
+    var before = this.manager.store.get('q').val();
+    func.apply(this);
+    var after = this.manager.store.get('q').val();
+    if (after !== before) {
+      this.afterChangeSelection(after);
+    }
+    return after !== before;
+  },
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>This method is executed after the main Solr query changes.</p>
+   *
+   * @param {String} value The current main Solr query.
+   */
+  afterChangeSelection: function (value) {},
+
+  /**
+   * Returns a function to unset the main Solr query.
+   *
+   * @returns {Function}
+   */
+  unclickHandler: function () {
+    var self = this;
+    return function () {
+      if (self.clear()) {
+        self.doRequest();
+      }
+      return false;
+    }
+  },
+
+  /**
+   * Returns a function to set the main Solr query.
+   *
+   * @param {String} value The new Solr query.
+   * @returns {Function}
+   */
+  clickHandler: function (q) {
+    var self = this;
+    return function () {
+      if (self.set(q)) {
+        self.doRequest();
+      }
+      return false;
+    }
+  }
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractWidget.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/AbstractWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractWidget.js
new file mode 100644
index 0000000..203a4c7
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/AbstractWidget.js
@@ -0,0 +1,78 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/Core'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * Baseclass for all widgets.
+ *
+ * Provides abstract hooks for child classes.
+ *
+ * @param properties A map of fields to set. May be new or public fields.
+ * @class AbstractWidget
+ */
+AjaxSolr.AbstractWidget = AjaxSolr.Class.extend(
+  /** @lends AjaxSolr.AbstractWidget.prototype */
+  {
+  /**
+   * @param {Object} attributes
+   * @param {String} attributes.id A unique identifier of this widget.
+   * @param {String} [attributes.target] The CSS selector for this widget's
+   *   target HTML element, e.g. a specific <tt>div</tt> or <tt>ul</tt>. A
+   *   Widget is usually implemented to perform all its UI changes relative to
+   *   its target HTML element.
+   * @param {Number} [attributes.start] The offset parameter. Set this field to
+   *   make the widget reset the offset parameter to the given value on each
+   *   request.
+   * @param {String} [attributes.servlet] The Solr servlet for this widget. You
+   *   may prepend the servlet with a core if using multiple cores. If none is
+   *   set, it will default to the manager's servlet.
+   */
+  constructor: function (attributes) {
+    AjaxSolr.extend(this, {
+      id: null,
+      target: null,
+      start: undefined,
+      servlet: undefined,
+      // A reference to the widget's manager.
+      manager: null
+    }, attributes);
+  },
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>This method should do any necessary one-time initializations.</p>
+   */
+  init: function () {},
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>This method is executed before the Solr request is sent.</p>
+   */
+  beforeRequest: function () {},
+
+  /**
+   * An abstract hook for child implementations.
+   *
+   * <p>This method is executed after the Solr response is received.</p>
+   */
+  afterRequest: function () {},
+
+  /**
+   * A proxy to the manager's doRequest method.
+   *
+   * @param {Boolean} [start] The Solr start offset parameter.
+   * @param {String} [servlet] The Solr servlet to send the request to.
+   */
+  doRequest: function (start, servlet) {
+    this.manager.doRequest(start || this.start, servlet || this.servlet);
+  }
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/Core.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/Core.js b/src/main/web/hicc/ajax-solr/core/Core.js
new file mode 100644
index 0000000..af170c3
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/Core.js
@@ -0,0 +1,163 @@
+/**
+ * @namespace A unique namespace for the AJAX Solr library.
+ */
+AjaxSolr = function () {};
+
+/**
+ * @namespace Baseclass for all classes
+ * @see https://github.com/documentcloud/backbone/blob/51eed189bf4d25877be4acdf51e0a4c6039583c5/backbone.js#L243
+ */
+AjaxSolr.Class = function(attributes) {
+  AjaxSolr.extend(this, attributes);
+};
+
+/**
+ * A class 'extends' itself into a subclass.
+ *
+ * @static
+ * @param protoProps The properties of the subclass.
+ * @returns A function that represents the subclass.
+ * @see https://github.com/documentcloud/backbone/blob/51eed189bf4d25877be4acdf51e0a4c6039583c5/backbone.js#L1516
+ */
+AjaxSolr.Class.extend = function (protoProps, staticProps) {
+  var parent = this;
+  var child;
+
+  // The constructor function for the new subclass is either defined by you
+  // (the "constructor" property in your `extend` definition), or defaulted
+  // by us to simply call the parent's constructor.
+  if (protoProps && Object.prototype.hasOwnProperty.call(protoProps, 'constructor')) {
+    child = protoProps.constructor;
+  } else {
+    child = function(){ return parent.apply(this, arguments); };
+  }
+
+  // Add static properties to the constructor function, if supplied.
+  AjaxSolr.extend(child, parent, staticProps);
+
+  // Set the prototype chain to inherit from `parent`, without calling
+  // `parent`'s constructor function.
+  var Surrogate = function(){ this.constructor = child; };
+  Surrogate.prototype = parent.prototype;
+  child.prototype = new Surrogate;
+
+  // Add prototype properties (instance properties) to the subclass,
+  // if supplied.
+  if (protoProps) AjaxSolr.extend(child.prototype, protoProps);
+
+  // Set a convenience property in case the parent's prototype is needed
+  // later.
+  child.__super__ = parent.prototype;
+
+  return child;
+};
+
+/**
+ * @static
+ * @see https://github.com/documentcloud/underscore/blob/7342e289aa9d91c5aacfb3662ea56e7a6d081200/underscore.js#L789
+*/
+AjaxSolr.extend = function (child) {
+  // From _.extend
+  var obj = Array.prototype.slice.call(arguments, 1);
+
+  // From _.extend
+  var iterator = function(source) {
+    if (source) {
+      for (var prop in source) {
+        child[prop] = source[prop];
+      }
+    }
+  };
+
+  // From _.each
+  if (obj == null) return;
+  if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
+    obj.forEach(iterator);
+  } else if (obj.length === +obj.length) {
+    for (var i = 0, l = obj.length; i < l; i++) {
+      iterator.call(undefined, obj[i], i, obj);
+    }
+  } else {
+    for (var key in obj) {
+      if (Object.prototype.hasOwnProperty.call(obj, key)) {
+        iterator.call(undefined, obj[key], key, obj);
+      }
+    }
+  }
+
+  return child;
+};
+
+/**
+ * @static
+ * @param value A value.
+ * @param array An array.
+ * @returns {Boolean} Whether value exists in the array.
+ */
+AjaxSolr.inArray = function (value, array) {
+  if (array) {
+    for (var i = 0, l = array.length; i < l; i++) {
+      if (AjaxSolr.equals(array[i], value)) {
+        return i;
+      }
+    }
+  }
+  return -1;
+};
+
+/**
+ * @static
+ * @param foo A value.
+ * @param bar A value.
+ * @returns {Boolean} Whether the two given values are equal.
+ */
+AjaxSolr.equals = function (foo, bar) {
+  if (AjaxSolr.isArray(foo) && AjaxSolr.isArray(bar)) {
+    if (foo.length !== bar.length) {
+      return false;
+    }
+    for (var i = 0, l = foo.length; i < l; i++) {
+      if (foo[i] !== bar[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+  else if (AjaxSolr.isRegExp(foo) && AjaxSolr.isString(bar)) {
+    return bar.match(foo);
+  }
+  else if (AjaxSolr.isRegExp(bar) && AjaxSolr.isString(foo)) {
+    return foo.match(bar);
+  }
+  else {
+    return foo === bar;
+  }
+};
+
+/**
+ * Can't use toString.call(obj) === "[object Array]", as it may return
+ * "[xpconnect wrapped native prototype]", which is undesirable.
+ *
+ * @static
+ * @see http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+ * @see http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js
+ */
+AjaxSolr.isArray = function (obj) {
+  return obj != null && typeof obj == 'object' && 'splice' in obj && 'join' in obj;
+};
+
+/**
+ * @param obj Any object.
+ * @returns {Boolean} Whether the object is a RegExp object.
+ */
+AjaxSolr.isRegExp = function (obj) {
+  return obj != null && (typeof obj == 'object' || typeof obj == 'function') && 'ignoreCase' in obj;
+};
+
+/**
+ * @param obj Any object.
+ * @returns {Boolean} Whether the object is a String object.
+ */
+AjaxSolr.isString = function (obj) {
+  return obj != null && typeof obj == 'string';
+};

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/Parameter.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/Parameter.js b/src/main/web/hicc/ajax-solr/core/Parameter.js
new file mode 100644
index 0000000..95e638e
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/Parameter.js
@@ -0,0 +1,175 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/Core'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * Represents a Solr parameter.
+ *
+ * @param properties A map of fields to set. Refer to the list of public fields.
+ * @class Parameter
+ */
+AjaxSolr.Parameter = AjaxSolr.Class.extend(
+  /** @lends AjaxSolr.Parameter.prototype */
+  {
+  /**
+   * @param {Object} attributes
+   * @param {String} attributes.name The parameter's name.
+   * @param {String} [attributes.value] The parameter's value.
+   * @param {Object} [attributes.local] The parameter's local parameters.
+   */
+  constructor: function (attributes) {
+    AjaxSolr.extend(this, {
+      name: null,
+      value: null,
+      locals: {}
+    }, attributes);
+  },
+
+  /**
+   * Returns the value. If called with an argument, sets the value.
+   *
+   * @param {String|Number|String[]|Number[]} [value] The value to set.
+   * @returns The value.
+   */
+  val: function (value) {
+    if (value === undefined) {
+      return this.value;
+    }
+    else {
+      this.value = value;
+    }
+  },
+
+  /**
+   * Returns the value of a local parameter. If called with a second argument,
+   * sets the value of a local parameter.
+   *
+   * @param {String} name The name of the local parameter.
+   * @param {String|Number|String[]|Number[]} [value] The value to set.
+   * @returns The value.
+   */
+  local: function (name, value) {
+    if (value === undefined) {
+      return this.locals[name];
+    }
+    else {
+      this.locals[name] = value;
+    }
+  },
+
+  /**
+   * Deletes a local parameter.
+   *
+   * @param {String} name The name of the local parameter.
+   */
+  remove: function (name) {
+    delete this.locals[name];
+  },
+
+  /**
+   * Returns the Solr parameter as a query string key-value pair.
+   *
+   * <p>IE6 calls the default toString() if you write <tt>store.toString()
+   * </tt>. So, we need to choose another name for toString().</p>
+   */
+  string: function () {
+    var pairs = [];
+
+    for (var name in this.locals) {
+      if (this.locals[name]) {
+        pairs.push(name + '=' + encodeURIComponent(this.locals[name]));
+      }
+    }
+
+    var prefix = pairs.length ? '{!' + pairs.join('%20') + '}' : '';
+
+    if (this.value) {
+      return this.name + '=' + prefix + this.valueString(this.value);
+    }
+    // For dismax request handlers, if the q parameter has local params, the
+    // q parameter must be set to a non-empty value. In case the q parameter
+    // has local params but is empty, use the q.alt parameter, which accepts
+    // wildcards.
+    else if (this.name == 'q' && prefix) {
+      return 'q.alt=' + prefix + encodeURIComponent('*:*');
+    }
+    else {
+      return '';
+    }
+  },
+
+  /**
+   * Parses a string formed by calling string().
+   *
+   * @param {String} str The string to parse.
+   */
+  parseString: function (str) {
+    var param = str.match(/^([^=]+)=(?:\{!([^\}]*)\})?(.*)$/);
+    if (param) {
+      var matches;
+
+      while (matches = /([^\s=]+)=(\S*)/g.exec(decodeURIComponent(param[2]))) {
+        this.locals[matches[1]] = decodeURIComponent(matches[2]);
+        param[2] = param[2].replace(matches[0], ''); // Safari's exec seems not to do this on its own
+      }
+
+      if (param[1] == 'q.alt') {
+        this.name = 'q';
+        // if q.alt is present, assume it is because q was empty, as above
+      }
+      else {
+        this.name = param[1];
+        this.value = this.parseValueString(param[3]);
+      }
+    }
+  },
+
+  /**
+   * Returns the value as a URL-encoded string.
+   *
+   * @private
+   * @param {String|Number|String[]|Number[]} value The value.
+   * @returns {String} The URL-encoded string.
+   */
+  valueString: function (value) {
+    value = AjaxSolr.isArray(value) ? value.join(',') : value;
+    return encodeURIComponent(value);
+  },
+
+  /**
+   * Parses a URL-encoded string to return the value.
+   *
+   * @private
+   * @param {String} str The URL-encoded string.
+   * @returns {Array} The value.
+   */
+  parseValueString: function (str) {
+    str = decodeURIComponent(str);
+    return str.indexOf(',') == -1 ? str : str.split(',');
+  }
+});
+
+/**
+ * Escapes a value, to be used in, for example, an fq parameter. Surrounds
+ * strings containing spaces or colons in double quotes.
+ *
+ * @public
+ * @param {String|Number} value The value.
+ * @returns {String} The escaped value.
+ */
+AjaxSolr.Parameter.escapeValue = function (value) {
+  // If the field value has a space, colon, quotation mark or forward slash
+  // in it, wrap it in quotes, unless it is a range query or it is already
+  // wrapped in quotes.
+  if (value.match(/[ :\/"]/) && !value.match(/[\[\{]\S+ TO \S+[\]\}]/) && !value.match(/^["\(].*["\)]$/)) {
+    return '"' + value.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
+  }
+  return value;
+}
+
+}));

http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js b/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js
new file mode 100644
index 0000000..54a2806
--- /dev/null
+++ b/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js
@@ -0,0 +1,116 @@
+(function (callback) {
+  if (typeof define === 'function' && define.amd) {
+    define(['core/ParameterStore'], callback);
+  }
+  else {
+    callback();
+  }
+}(function () {
+
+/**
+ * A parameter store that stores the values of exposed parameters in the URL
+ * hash to maintain the application's state.
+ *
+ * <p>The ParameterHashStore observes the hash for changes and loads Solr
+ * parameters from the hash if it observes a change or if the hash is empty.
+ * The onhashchange event is used if the browser supports it.</p>
+ *
+ * <p>Configure the manager with:</p>
+ *
+ * @class ParameterHashStore
+ * @augments AjaxSolr.ParameterStore
+ * @see https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange
+ */
+AjaxSolr.ParameterHashStore = AjaxSolr.ParameterStore.extend(
+  /** @lends AjaxSolr.ParameterHashStore.prototype */
+  {
+  /**
+   * @param {Object} [attributes]
+   * @param {Number} [attributes.interval] The interval in milliseconds to use
+   *   in <tt>setInterval()</tt>. Do not set the interval too low as you may set
+   *   up a race condition. Defaults to 250.
+   */
+  constructor: function (attributes) {
+    AjaxSolr.ParameterHashStore.__super__.constructor.apply(this, arguments);
+    AjaxSolr.extend(this, {
+      interval: 250,
+      // Reference to the setInterval() function.
+      intervalId: null,
+      // A local copy of the URL hash, so we can detect changes to it.
+      hash: ''
+    }, attributes);
+  },
+
+  /**
+   * If loading and saving the hash take longer than <tt>interval</tt>, we'll
+   * hit a race condition. However, this should never happen.
+   */
+  init: function () {
+    if (this.exposed.length) {
+      // Check if the browser supports the onhashchange event. IE 8 and 9 in compatibility mode
+      // incorrectly report support for onhashchange.
+      if ('onhashchange' in window && (!document.documentMode || document.documentMode > 7)) {
+        if (window.addEventListener) {
+          window.addEventListener('hashchange', this.intervalFunction(this), false);
+        }
+        else if (window.attachEvent) {
+          window.attachEvent('onhashchange', this.intervalFunction(this));
+        }
+        else {
+          window.onhashchange = this.intervalFunction(this);
+        }
+      }
+      else {
+        this.intervalId = window.setInterval(this.intervalFunction(this), this.interval);
+      }
+    }
+  },
+
+  /**
+   * Stores the values of the exposed parameters in both the local hash and the
+   * URL hash. No other code should be made to change these two values.
+   */
+  save: function () {
+    this.hash = this.exposedString();
+    if (this.storedString()) {
+      // Make a new history entry.
+      window.location.hash = this.hash;
+    }
+    else {
+      // Replace the old history entry.
+      window.location.replace(window.location.href.replace('#', '') + '#' + this.hash);
+    }
+  },
+
+  /**
+   * @see ParameterStore#storedString()
+   */
+  storedString: function () {
+    // Some browsers automatically unescape characters in the hash, others
+    // don't. Fortunately, all leave window.location.href alone. So, use that.
+    var index = window.location.href.indexOf('#');
+    if (index == -1) {
+      return '';
+    }
+    else {
+      return window.location.href.substr(index + 1);
+    }
+  },
+
+  /**
+   * Checks the hash for changes, and loads Solr parameters from the hash and
+   * sends a request to Solr if it observes a change or if the hash is empty
+   */
+  intervalFunction: function (self) {
+    return function () {
+      // Support the back/forward buttons. If the hash changes, do a request.
+      var hash = self.storedString();
+      if (self.hash != hash && decodeURIComponent(self.hash) != decodeURIComponent(hash)) {
+        self.load();
+        self.manager.doRequest();
+      }
+    }
+  }
+});
+
+}));