You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2015/05/22 21:41:21 UTC

[03/25] ambari git commit: AMBARI-10064. Storm Ambari view (Sriharsha Chintalapani via srimanth)

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/libs/other/arbor.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/libs/other/arbor.js b/contrib/views/storm/src/main/resources/libs/other/arbor.js
new file mode 100644
index 0000000..7f6cd8c
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/libs/other/arbor.js
@@ -0,0 +1,67 @@
+//
+//  arbor.js - version 0.91
+//  a graph vizualization toolkit
+//
+//  Copyright (c) 2012 Samizdat Drafting Co.
+//  Physics code derived from springy.js, copyright (c) 2010 Dennis Hotson
+//
+//  Permission is hereby granted, free of charge, to any person
+//  obtaining a copy of this software and associated documentation
+//  files (the "Software"), to deal in the Software without
+//  restriction, including without limitation the rights to use,
+//  copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the
+//  Software is furnished to do so, subject to the following
+//  conditions:
+//
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+//  OTHER DEALINGS IN THE SOFTWARE.
+//
+
+(function($){
+
+  /*        etc.js */  var trace=function(msg){if(typeof(window)=="undefined"||!window.console){return}var len=arguments.length;var args=[];for(var i=0;i<len;i++){args.push("arguments["+i+"]")}eval("console.log("+args.join(",")+")")};var dirname=function(a){var b=a.replace(/^\/?(.*?)\/?$/,"$1").split("/");b.pop();return"/"+b.join("/")};var basename=function(b){var c=b.replace(/^\/?(.*?)\/?$/,"$1").split("/");var a=c.pop();if(a==""){return null}else{return a}};var _ordinalize_re=/(\d)(?=(\d\d\d)+(?!\d))/g;var ordinalize=function(a){var b=""+a;if(a<11000){b=(""+a).replace(_ordinalize_re,"$1,")}else{if(a<1000000){b=Math.floor(a/1000)+"k"}else{if(a<1000000000){b=(""+Math.floor(a/1000)).replace(_ordinalize_re,"$1,")+"m"}}}return b};var nano=function(a,b){return a.replace(/\{([\w\-\.]*)}/g,function(f,c){var d=c.split("."),e=b[d.shift()];$.each(d,function(){if(e.hasOwnProperty(this)){e=e[this]}else{e=f}});return e})};var objcopy=function(a){if(a===undefined){return undefined}if(a===null){r
 eturn null}if(a.parentNode){return a}switch(typeof a){case"string":return a.substring(0);break;case"number":return a+0;break;case"boolean":return a===true;break}var b=($.isArray(a))?[]:{};$.each(a,function(d,c){b[d]=objcopy(c)});return b};var objmerge=function(d,b){d=d||{};b=b||{};var c=objcopy(d);for(var a in b){c[a]=b[a]}return c};var objcmp=function(e,c,d){if(!e||!c){return e===c}if(typeof e!=typeof c){return false}if(typeof e!="object"){return e===c}else{if($.isArray(e)){if(!($.isArray(c))){return false}if(e.length!=c.length){return false}}else{var h=[];for(var f in e){if(e.hasOwnProperty(f)){h.push(f)}}var g=[];for(var f in c){if(c.hasOwnProperty(f)){g.push(f)}}if(!d){h.sort();g.sort()}if(h.join(",")!==g.join(",")){return false}}var i=true;$.each(e,function(a){var b=objcmp(e[a],c[a]);i=i&&b;if(!i){return false}});return i}};var objkeys=function(b){var a=[];$.each(b,function(d,c){if(b.hasOwnProperty(d)){a.push(d)}});return a};var objcontains=function(c){if(!c||typeof c!="object"
 ){return false}for(var b=1,a=arguments.length;b<a;b++){if(c.hasOwnProperty(arguments[b])){return true}}return false};var uniq=function(b){var a=b.length;var d={};for(var c=0;c<a;c++){d[b[c]]=true}return objkeys(d)};var arbor_path=function(){var a=$("script").map(function(b){var c=$(this).attr("src");if(!c){return}if(c.match(/arbor[^\/\.]*.js|dev.js/)){return c.match(/.*\//)||"/"}});if(a.length>0){return a[0]}else{return null}};
+  /*     kernel.js */  var Kernel=function(b){var k=window.location.protocol=="file:"&&navigator.userAgent.toLowerCase().indexOf("chrome")>-1;var a=(window.Worker!==undefined&&!k);var i=null;var c=null;var f=[];f.last=new Date();var l=null;var e=null;var d=null;var h=null;var g=false;var j={system:b,tween:null,nodes:{},init:function(){if(typeof(Tween)!="undefined"){c=Tween()}else{if(typeof(arbor.Tween)!="undefined"){c=arbor.Tween()}else{c={busy:function(){return false},tick:function(){return true},to:function(){trace("Please include arbor-tween.js to enable tweens");c.to=function(){};return}}}}j.tween=c;var m=b.parameters();if(a){trace("arbor.js/web-workers",m);l=setInterval(j.screenUpdate,m.timeout);i=new Worker(arbor_path()+"arbor.js");i.onmessage=j.workerMsg;i.onerror=function(n){trace("physics:",n)};i.postMessage({type:"physics",physics:objmerge(m,{timeout:Math.ceil(m.timeout)})})}else{trace("arbor.js/single-threaded",m);i=Physics(m.dt,m.stiffness,m.repulsion,m.friction,j.system
 ._updateGeometry,m.integrator);j.start()}return j},graphChanged:function(m){if(a){i.postMessage({type:"changes",changes:m})}else{i._update(m)}j.start()},particleModified:function(n,m){if(a){i.postMessage({type:"modify",id:n,mods:m})}else{i.modifyNode(n,m)}j.start()},physicsModified:function(m){if(!isNaN(m.timeout)){if(a){clearInterval(l);l=setInterval(j.screenUpdate,m.timeout)}else{clearInterval(d);d=null}}if(a){i.postMessage({type:"sys",param:m})}else{i.modifyPhysics(m)}j.start()},workerMsg:function(n){var m=n.data.type;if(m=="geometry"){j.workerUpdate(n.data)}else{trace("physics:",n.data)}},_lastPositions:null,workerUpdate:function(m){j._lastPositions=m;j._lastBounds=m.bounds},_lastFrametime:new Date().valueOf(),_lastBounds:null,_currentRenderer:null,screenUpdate:function(){var n=new Date().valueOf();var m=false;if(j._lastPositions!==null){j.system._updateGeometry(j._lastPositions);j._lastPositions=null;m=true}if(c&&c.busy()){m=true}if(j.system._updateBounds(j._lastBounds)){m=true
 }if(m){var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}if(c){c.tick()}o.redraw();var p=f.last;f.last=new Date();f.push(f.last-p);if(f.length>50){f.shift()}}}},physicsUpdate:function(){if(c){c.tick()}i.tick();var n=j.system._updateBounds();if(c&&c.busy()){n=true}var o=j.system.renderer;var m=new Date();var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}o.redraw({timestamp:m})}var q=f.last;f.last=m;f.push(f.last-q);if(f.length>50){f.shift()}var p=i.systemEnergy();if((p.mean+p.max)/2<0.05){if(h===null){h=new Date().valueOf()}if(new Date().valueOf()-h>1000){clearInterval(d);d=null}else{}}else{h=null}},fps:function(n){if(n!==undefined){var q=1000/Math.max(1,targetFps);j.physicsModified({timeout:q})}var r=0;for(var p=0,o=f.length;p<o;p++){r+=f[p]}var m=r/Math.max(1,f.length);if(!isNaN(m)){return Math.round(1000/m)}else{return 0}},start:function(m){if(d!==null){return}if(g&&!m){return}g=false;if(a){i.postMessage({type:"start"})}else{h=null;d=s
 etInterval(j.physicsUpdate,j.system.parameters().timeout)}},stop:function(){g=true;if(a){i.postMessage({type:"stop"})}else{if(d!==null){clearInterval(d);d=null}}}};return j.init()};
+  /*      atoms.js */  var Node=function(a){this._id=_nextNodeId++;this.data=a||{};this._mass=(a.mass!==undefined)?a.mass:1;this._fixed=(a.fixed===true)?true:false;this._p=new Point((typeof(a.x)=="number")?a.x:null,(typeof(a.y)=="number")?a.y:null);delete this.data.x;delete this.data.y;delete this.data.mass;delete this.data.fixed};var _nextNodeId=1;var Edge=function(b,c,a){this._id=_nextEdgeId--;this.source=b;this.target=c;this.length=(a.length!==undefined)?a.length:1;this.data=(a!==undefined)?a:{};delete this.data.length};var _nextEdgeId=-1;var Particle=function(a,b){this.p=a;this.m=b;this.v=new Point(0,0);this.f=new Point(0,0)};Particle.prototype.applyForce=function(a){this.f=this.f.add(a.divide(this.m))};var Spring=function(c,b,d,a){this.point1=c;this.point2=b;this.length=d;this.k=a};Spring.prototype.distanceToParticle=function(a){var c=that.point2.p.subtract(that.point1.p).normalize().normal();var b=a.p.subtract(that.point1.p);return Math.abs(b.x*c.x+b.y*c.y)};var Point=function
 (a,b){if(a&&a.hasOwnProperty("y")){b=a.y;a=a.x}this.x=a;this.y=b};Point.random=function(a){a=(a!==undefined)?a:5;return new Point(2*a*(Math.random()-0.5),2*a*(Math.random()-0.5))};Point.prototype={exploded:function(){return(isNaN(this.x)||isNaN(this.y))},add:function(a){return new Point(this.x+a.x,this.y+a.y)},subtract:function(a){return new Point(this.x-a.x,this.y-a.y)},multiply:function(a){return new Point(this.x*a,this.y*a)},divide:function(a){return new Point(this.x/a,this.y/a)},magnitude:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normal:function(){return new Point(-this.y,this.x)},normalize:function(){return this.divide(this.magnitude())}};
+  /*     system.js */  var ParticleSystem=function(e,r,f,g,u,m,s,a){var k=[];var i=null;var l=0;var v=null;var n=0.04;var j=[20,20,20,20];var o=null;var p=null;if(typeof e=="object"){var t=e;f=t.friction;e=t.repulsion;u=t.fps;m=t.dt;r=t.stiffness;g=t.gravity;s=t.precision;a=t.integrator}if(a!="verlet"&&a!="euler"){a="verlet"}f=isNaN(f)?0.5:f;e=isNaN(e)?1000:e;u=isNaN(u)?55:u;r=isNaN(r)?600:r;m=isNaN(m)?0.02:m;s=isNaN(s)?0.6:s;g=(g===true);var q=(u!==undefined)?1000/u:1000/50;var c={integrator:a,repulsion:e,stiffness:r,friction:f,dt:m,gravity:g,precision:s,timeout:q};var b;var d={renderer:null,tween:null,nodes:{},edges:{},adjacency:{},names:{},kernel:null};var h={parameters:function(w){if(w!==undefined){if(!isNaN(w.precision)){w.precision=Math.max(0,Math.min(1,w.precision))}$.each(c,function(y,x){if(w[y]!==undefined){c[y]=w[y]}});d.kernel.physicsModified(w)}return c},fps:function(w){if(w===undefined){return d.kernel.fps()}else{h.parameters({timeout:1000/(w||50)})}},start:function(){d
 .kernel.start()},stop:function(){d.kernel.stop()},addNode:function(z,C){C=C||{};var D=d.names[z];if(D){D.data=C;return D}else{if(z!=undefined){var w=(C.x!=undefined)?C.x:null;var E=(C.y!=undefined)?C.y:null;var B=(C.fixed)?1:0;var A=new Node(C);A.name=z;d.names[z]=A;d.nodes[A._id]=A;k.push({t:"addNode",id:A._id,m:A.mass,x:w,y:E,f:B});h._notify();return A}}},pruneNode:function(x){var w=h.getNode(x);if(typeof(d.nodes[w._id])!=="undefined"){delete d.nodes[w._id];delete d.names[w.name]}$.each(d.edges,function(z,y){if(y.source._id===w._id||y.target._id===w._id){h.pruneEdge(y)}});k.push({t:"dropNode",id:w._id});h._notify()},getNode:function(w){if(w._id!==undefined){return w}else{if(typeof w=="string"||typeof w=="number"){return d.names[w]}}},eachNode:function(w){$.each(d.nodes,function(z,y){if(y._p.x==null||y._p.y==null){return}var x=(v!==null)?h.toScreen(y._p):y._p;w.call(h,y,x)})},addEdge:function(A,B,z){A=h.getNode(A)||h.addNode(A);B=h.getNode(B)||h.addNode(B);z=z||{};var y=new Edge(A,
 B,z);var C=A._id;var D=B._id;d.adjacency[C]=d.adjacency[C]||{};d.adjacency[C][D]=d.adjacency[C][D]||[];var x=(d.adjacency[C][D].length>0);if(x){$.extend(d.adjacency[C][D].data,y.data);return}else{d.edges[y._id]=y;d.adjacency[C][D].push(y);var w=(y.length!==undefined)?y.length:1;k.push({t:"addSpring",id:y._id,fm:C,to:D,l:w});h._notify()}return y},pruneEdge:function(B){k.push({t:"dropSpring",id:B._id});delete d.edges[B._id];for(var w in d.adjacency){for(var C in d.adjacency[w]){var z=d.adjacency[w][C];for(var A=z.length-1;A>=0;A--){if(d.adjacency[w][C][A]._id===B._id){d.adjacency[w][C].splice(A,1)}}}}h._notify()},getEdges:function(x,w){x=h.getNode(x);w=h.getNode(w);if(!x||!w){return[]}if(typeof(d.adjacency[x._id])!=="undefined"&&typeof(d.adjacency[x._id][w._id])!=="undefined"){return d.adjacency[x._id][w._id]}return[]},getEdgesFrom:function(w){w=h.getNode(w);if(!w){return[]}if(typeof(d.adjacency[w._id])!=="undefined"){var x=[];$.each(d.adjacency[w._id],function(z,y){x=x.concat(y)});re
 turn x}return[]},getEdgesTo:function(w){w=h.getNode(w);if(!w){return[]}var x=[];$.each(d.edges,function(z,y){if(y.target==w){x.push(y)}});return x},eachEdge:function(w){$.each(d.edges,function(A,y){var z=d.nodes[y.source._id]._p;var x=d.nodes[y.target._id]._p;if(z.x==null||x.x==null){return}z=(v!==null)?h.toScreen(z):z;x=(v!==null)?h.toScreen(x):x;if(z&&x){w.call(h,y,z,x)}})},prune:function(x){var w={dropped:{nodes:[],edges:[]}};if(x===undefined){$.each(d.nodes,function(z,y){w.dropped.nodes.push(y);h.pruneNode(y)})}else{h.eachNode(function(z){var y=x.call(h,z,{from:h.getEdgesFrom(z),to:h.getEdgesTo(z)});if(y){w.dropped.nodes.push(z);h.pruneNode(z)}})}return w},graft:function(x){var w={added:{nodes:[],edges:[]}};if(x.nodes){$.each(x.nodes,function(z,y){var A=h.getNode(z);if(A){A.data=y}else{w.added.nodes.push(h.addNode(z,y))}d.kernel.start()})}if(x.edges){$.each(x.edges,function(A,y){var z=h.getNode(A);if(!z){w.added.nodes.push(h.addNode(A,{}))}$.each(y,function(E,B){var D=h.getNode(
 E);if(!D){w.added.nodes.push(h.addNode(E,{}))}var C=h.getEdges(A,E);if(C.length>0){C[0].data=B}else{w.added.edges.push(h.addEdge(A,E,B))}})})}return w},merge:function(x){var w={added:{nodes:[],edges:[]},dropped:{nodes:[],edges:[]}};$.each(d.edges,function(B,A){if((x.edges[A.source.name]===undefined||x.edges[A.source.name][A.target.name]===undefined)){h.pruneEdge(A);w.dropped.edges.push(A)}});var z=h.prune(function(B,A){if(x.nodes[B.name]===undefined){w.dropped.nodes.push(B);return true}});var y=h.graft(x);w.added.nodes=w.added.nodes.concat(y.added.nodes);w.added.edges=w.added.edges.concat(y.added.edges);w.dropped.nodes=w.dropped.nodes.concat(z.dropped.nodes);w.dropped.edges=w.dropped.edges.concat(z.dropped.edges);return w},tweenNode:function(z,w,y){var x=h.getNode(z);if(x){d.tween.to(x,w,y)}},tweenEdge:function(x,w,A,z){if(z===undefined){h._tweenEdge(x,w,A)}else{var y=h.getEdges(x,w);$.each(y,function(B,C){h._tweenEdge(C,A,z)})}},_tweenEdge:function(x,w,y){if(x&&x._id!==undefined){d
 .tween.to(x,w,y)}},_updateGeometry:function(z){if(z!=undefined){var w=(z.epoch<l);b=z.energy;var A=z.geometry;if(A!==undefined){for(var y=0,x=A.length/3;y<x;y++){var B=A[3*y];if(w&&d.nodes[B]==undefined){continue}d.nodes[B]._p.x=A[3*y+1];d.nodes[B]._p.y=A[3*y+2]}}}},screen:function(w){if(w==undefined){return{size:(v)?objcopy(v):undefined,padding:j.concat(),step:n}}if(w.size!==undefined){h.screenSize(w.size.width,w.size.height)}if(!isNaN(w.step)){h.screenStep(w.step)}if(w.padding!==undefined){h.screenPadding(w.padding)}},screenSize:function(w,x){v={width:w,height:x};h._updateBounds()},screenPadding:function(z,A,w,x){if($.isArray(z)){trbl=z}else{trbl=[z,A,w,x]}var B=trbl[0];var y=trbl[1];var C=trbl[2];if(y===undefined){trbl=[B,B,B,B]}else{if(C==undefined){trbl=[B,y,B,y]}}j=trbl},screenStep:function(w){n=w},toScreen:function(y){if(!o||!v){return}var x=j||[0,0,0,0];var w=o.bottomright.subtract(o.topleft);var A=x[3]+y.subtract(o.topleft).divide(w.x).x*(v.width-(x[1]+x[3]));var z=x[0]+y.s
 ubtract(o.topleft).divide(w.y).y*(v.height-(x[0]+x[2]));return arbor.Point(A,z)},fromScreen:function(A){if(!o||!v){return}var z=j||[0,0,0,0];var y=o.bottomright.subtract(o.topleft);var x=(A.x-z[3])/(v.width-(z[1]+z[3]))*y.x+o.topleft.x;var w=(A.y-z[0])/(v.height-(z[0]+z[2]))*y.y+o.topleft.y;return arbor.Point(x,w)},_updateBounds:function(x){if(v===null){return}if(x){p=x}else{p=h.bounds()}var A=new Point(p.bottomright.x,p.bottomright.y);var z=new Point(p.topleft.x,p.topleft.y);var C=A.subtract(z);var w=z.add(C.divide(2));var y=4;var E=new Point(Math.max(C.x,y),Math.max(C.y,y));p.topleft=w.subtract(E.divide(2));p.bottomright=w.add(E.divide(2));if(!o){if($.isEmptyObject(d.nodes)){return false}o=p;return true}var D=n;_newBounds={bottomright:o.bottomright.add(p.bottomright.subtract(o.bottomright).multiply(D)),topleft:o.topleft.add(p.topleft.subtract(o.topleft).multiply(D))};var B=new Point(o.topleft.subtract(_newBounds.topleft).magnitude(),o.bottomright.subtract(_newBounds.bottomright).m
 agnitude());if(B.x*v.width>1||B.y*v.height>1){o=_newBounds;return true}else{return false}},energy:function(){return b},bounds:function(){var x=null;var w=null;$.each(d.nodes,function(A,z){if(!x){x=new Point(z._p);w=new Point(z._p);return}var y=z._p;if(y.x===null||y.y===null){return}if(y.x>x.x){x.x=y.x}if(y.y>x.y){x.y=y.y}if(y.x<w.x){w.x=y.x}if(y.y<w.y){w.y=y.y}});if(x&&w){return{bottomright:x,topleft:w}}else{return{topleft:new Point(-1,-1),bottomright:new Point(1,1)}}},nearest:function(y){if(v!==null){y=h.fromScreen(y)}var x={node:null,point:null,distance:null};var w=h;$.each(d.nodes,function(C,z){var A=z._p;if(A.x===null||A.y===null){return}var B=A.subtract(y).magnitude();if(x.distance===null||B<x.distance){x={node:z,point:A,distance:B};if(v!==null){x.screenPoint=h.toScreen(A)}}});if(x.node){if(v!==null){x.distance=h.toScreen(x.node.p).subtract(h.toScreen(y)).magnitude()}return x}else{return null}},_notify:function(){if(i===null){l++}else{clearTimeout(i)}i=setTimeout(h._synchronize
 ,20)},_synchronize:function(){if(k.length>0){d.kernel.graphChanged(k);k=[];i=null}},};d.kernel=Kernel(h);d.tween=d.kernel.tween||null;Node.prototype.__defineGetter__("p",function(){var x=this;var w={};w.__defineGetter__("x",function(){return x._p.x});w.__defineSetter__("x",function(y){d.kernel.particleModified(x._id,{x:y})});w.__defineGetter__("y",function(){return x._p.y});w.__defineSetter__("y",function(y){d.kernel.particleModified(x._id,{y:y})});w.__proto__=Point.prototype;return w});Node.prototype.__defineSetter__("p",function(w){this._p.x=w.x;this._p.y=w.y;d.kernel.particleModified(this._id,{x:w.x,y:w.y})});Node.prototype.__defineGetter__("mass",function(){return this._mass});Node.prototype.__defineSetter__("mass",function(w){this._mass=w;d.kernel.particleModified(this._id,{m:w})});Node.prototype.__defineSetter__("tempMass",function(w){d.kernel.particleModified(this._id,{_m:w})});Node.prototype.__defineGetter__("fixed",function(){return this._fixed});Node.prototype.__defineSett
 er__("fixed",function(w){this._fixed=w;d.kernel.particleModified(this._id,{f:w?1:0})});return h};
+  /* barnes-hut.js */  var BarnesHutTree=function(){var b=[];var a=0;var e=null;var d=0.5;var c={init:function(g,h,f){d=f;a=0;e=c._newBranch();e.origin=g;e.size=h.subtract(g)},insert:function(j){var f=e;var g=[j];while(g.length){var h=g.shift();var m=h._m||h.m;var p=c._whichQuad(h,f);if(f[p]===undefined){f[p]=h;f.mass+=m;if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}}else{if("origin" in f[p]){f.mass+=(m);if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}f=f[p];g.unshift(h)}else{var l=f.size.divide(2);var n=new Point(f.origin);if(p[0]=="s"){n.y+=l.y}if(p[1]=="e"){n.x+=l.x}var o=f[p];f[p]=c._newBranch();f[p].origin=n;f[p].size=l;f.mass=m;f.p=h.p.multiply(m);f=f[p];if(o.p.x===h.p.x&&o.p.y===h.p.y){var k=l.x*0.08;var i=l.y*0.08;o.p.x=Math.min(n.x+l.x,Math.max(n.x,o.p.x-k/2+Math.random()*k));o.p.y=Math.min(n.y+l.y,Math.max(n.y,o.p.y-i/2+Math.random()*i))}g.push(o);g.unshift(h)}}}},applyForces:function(m,g){var f=[e];while(f.length){node=f.shift();if(node===und
 efined){continue}if(m===node){continue}if("f" in node){var k=m.p.subtract(node.p);var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node._m||node.m)).divide(l*l))}else{var j=m.p.subtract(node.p.divide(node.mass)).magnitude();var h=Math.sqrt(node.size.x*node.size.y);if(h/j>d){f.push(node.ne);f.push(node.nw);f.push(node.se);f.push(node.sw)}else{var k=m.p.subtract(node.p.divide(node.mass));var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node.mass)).divide(l*l))}}}},_whichQuad:function(i,f){if(i.p.exploded()){return null}var h=i.p.subtract(f.origin);var g=f.size.divide(2);if(h.y<g.y){if(h.x<g.x){return"nw"}else{return"ne"}}else{if(h.x<g.x){return"sw"}else{return"se"}}},_newBranch:function(){if(b[a]){var f=b[a];f.ne=f.nw=f.se=f.sw=undefined;f.mass=0;delete f.p}else{f={origin:null,size:null,nw:undefined,ne:undefined,sw:undefined,se:undefined,mass:0};b[a]=f}a+
 +;return f}};return c};
+  /*    physics.js */  var Physics=function(a,m,n,e,h,o){var f=BarnesHutTree();var c={particles:{},springs:{}};var l={particles:{}};var p=[];var k=[];var d=0;var b={sum:0,max:0,mean:0};var g={topleft:new Point(-1,-1),bottomright:new Point(1,1)};var j=1000;var i={integrator:["verlet","euler"].indexOf(o)>=0?o:"verlet",stiffness:(m!==undefined)?m:1000,repulsion:(n!==undefined)?n:600,friction:(e!==undefined)?e:0.3,gravity:false,dt:(a!==undefined)?a:0.02,theta:0.4,init:function(){return i},modifyPhysics:function(q){$.each(["stiffness","repulsion","friction","gravity","dt","precision","integrator"],function(s,t){if(q[t]!==undefined){if(t=="precision"){i.theta=1-q[t];return}i[t]=q[t];if(t=="stiffness"){var r=q[t];$.each(c.springs,function(v,u){u.k=r})}}})},addNode:function(v){var u=v.id;var r=v.m;var q=g.bottomright.x-g.topleft.x;var t=g.bottomright.y-g.topleft.y;var s=new Point((v.x!=null)?v.x:g.topleft.x+q*Math.random(),(v.y!=null)?v.y:g.topleft.y+t*Math.random());c.particles[u]=new Part
 icle(s,r);c.particles[u].connections=0;c.particles[u].fixed=(v.f===1);l.particles[u]=c.particles[u];p.push(c.particles[u])},dropNode:function(t){var s=t.id;var r=c.particles[s];var q=$.inArray(r,p);if(q>-1){p.splice(q,1)}delete c.particles[s];delete l.particles[s]},modifyNode:function(s,q){if(s in c.particles){var r=c.particles[s];if("x" in q){r.p.x=q.x}if("y" in q){r.p.y=q.y}if("m" in q){r.m=q.m}if("f" in q){r.fixed=(q.f===1)}if("_m" in q){if(r._m===undefined){r._m=r.m}r.m=q._m}}},addSpring:function(u){var t=u.id;var q=u.l;var s=c.particles[u.fm];var r=c.particles[u.to];if(s!==undefined&&r!==undefined){c.springs[t]=new Spring(s,r,q,i.stiffness);k.push(c.springs[t]);s.connections++;r.connections++;delete l.particles[u.fm];delete l.particles[u.to]}},dropSpring:function(t){var s=t.id;var r=c.springs[s];r.point1.connections--;r.point2.connections--;var q=$.inArray(r,k);if(q>-1){k.splice(q,1)}delete c.springs[s]},_update:function(q){d++;$.each(q,function(r,s){if(s.t in i){i[s.t](s)}});r
 eturn d},tick:function(){i.tendParticles();if(i.integrator=="euler"){i.updateForces();i.updateVelocity(i.dt);i.updatePosition(i.dt)}else{i.updateForces();i.cacheForces();i.updatePosition(i.dt);i.updateForces();i.updateVelocity(i.dt)}i.tock()},tock:function(){var q=[];$.each(c.particles,function(s,r){q.push(s);q.push(r.p.x);q.push(r.p.y)});if(h){h({geometry:q,epoch:d,energy:b,bounds:g})}},tendParticles:function(){$.each(c.particles,function(r,q){if(q._m!==undefined){if(Math.abs(q.m-q._m)<1){q.m=q._m;delete q._m}else{q.m*=0.98}}q.v.x=q.v.y=0})},updateForces:function(){if(i.repulsion>0){if(i.theta>0){i.applyBarnesHutRepulsion()}else{i.applyBruteForceRepulsion()}}if(i.stiffness>0){i.applySprings()}i.applyCenterDrift();if(i.gravity){i.applyCenterGravity()}},cacheForces:function(){$.each(c.particles,function(r,q){q._F=q.f})},applyBruteForceRepulsion:function(){$.each(c.particles,function(r,q){$.each(c.particles,function(t,s){if(q!==s){var v=q.p.subtract(s.p);var w=Math.max(1,v.magnitude()
 );var u=((v.magnitude()>0)?v:Point.random(1)).normalize();q.applyForce(u.multiply(i.repulsion*(s._m||s.m)*0.5).divide(w*w*0.5));s.applyForce(u.multiply(i.repulsion*(q._m||q.m)*0.5).divide(w*w*-0.5))}})})},applyBarnesHutRepulsion:function(){if(!g.topleft||!g.bottomright){return}var r=new Point(g.bottomright);var q=new Point(g.topleft);f.init(q,r,i.theta);$.each(c.particles,function(t,s){f.insert(s)});$.each(c.particles,function(t,s){f.applyForces(s,i.repulsion)})},applySprings:function(){$.each(c.springs,function(u,q){var t=q.point2.p.subtract(q.point1.p);var r=q.length-t.magnitude();var s=((t.magnitude()>0)?t:Point.random(1)).normalize();q.point1.applyForce(s.multiply(q.k*r*-0.5));q.point2.applyForce(s.multiply(q.k*r*0.5))})},applyCenterDrift:function(){var r=0;var s=new Point(0,0);$.each(c.particles,function(u,t){s.add(t.p);r++});if(r==0){return}var q=s.divide(-r);$.each(c.particles,function(u,t){t.applyForce(q)})},applyCenterGravity:function(){$.each(c.particles,function(s,q){var 
 r=q.p.multiply(-1);q.applyForce(r.multiply(i.repulsion/100))})},updateVelocity:function(r){var s=0,q=0,t=0;$.each(c.particles,function(x,u){if(u.fixed){u.v=new Point(0,0);u.f=new Point(0,0);return}if(i.integrator=="euler"){u.v=u.v.add(u.f.multiply(r)).multiply(1-i.friction)}else{u.v=u.v.add(u.f.add(u._F.divide(u._m)).multiply(r*0.5)).multiply(1-i.friction)}u.f.x=u.f.y=0;var v=u.v.magnitude();if(v>j){u.v=u.v.divide(v*v)}var v=u.v.magnitude();var w=v*v;s+=w;q=Math.max(w,q);t++});b={sum:s,max:q,mean:s/t,n:t}},updatePosition:function(q){var s=null;var r=null;$.each(c.particles,function(v,u){if(i.integrator=="euler"){u.p=u.p.add(u.v.multiply(q))}else{var t=u.f.multiply(0.5*q*q).divide(u.m);u.p=u.p.add(u.v.multiply(q)).add(t)}if(!s){s=new Point(u.p.x,u.p.y);r=new Point(u.p.x,u.p.y);return}var w=u.p;if(w.x===null||w.y===null){return}if(w.x>s.x){s.x=w.x}if(w.y>s.y){s.y=w.y}if(w.x<r.x){r.x=w.x}if(w.y<r.y){r.y=w.y}});g={topleft:r||new Point(-1,-1),bottomright:s||new Point(1,1)}},systemEnergy:
 function(q){return b}};return i.init()};var _nearParticle=function(b,c){var c=c||0;var a=b.x;var f=b.y;var e=c*2;return new Point(a-c+Math.random()*e,f-c+Math.random()*e)};
+
+  // if called as a worker thread, set up a run loop for the Physics object and bail out
+  if (typeof(window)=='undefined') return (function(){
+  /* hermetic.js */  $={each:function(d,e){if($.isArray(d)){for(var c=0,b=d.length;c<b;c++){e(c,d[c])}}else{for(var a in d){e(a,d[a])}}},map:function(a,c){var b=[];$.each(a,function(f,e){var d=c(e);if(d!==undefined){b.push(d)}});return b},extend:function(c,b){if(typeof b!="object"){return c}for(var a in b){if(b.hasOwnProperty(a)){c[a]=b[a]}}return c},isArray:function(a){if(!a){return false}return(a.constructor.toString().indexOf("Array")!=-1)},inArray:function(c,a){for(var d=0,b=a.length;d<b;d++){if(a[d]===c){return d}}return -1},isEmptyObject:function(a){if(typeof a!=="object"){return false}var b=true;$.each(a,function(c,d){b=false});return b},};
+  /*     worker.js */  var PhysicsWorker=function(){var b=20;var a=null;var d=null;var c=null;var g=[];var f=new Date().valueOf();var e={init:function(h){e.timeout(h.timeout);a=Physics(h.dt,h.stiffness,h.repulsion,h.friction,e.tock);return e},timeout:function(h){if(h!=b){b=h;if(d!==null){e.stop();e.go()}}},go:function(){if(d!==null){return}c=null;d=setInterval(e.tick,b)},stop:function(){if(d===null){return}clearInterval(d);d=null},tick:function(){a.tick();var h=a.systemEnergy();if((h.mean+h.max)/2<0.05){if(c===null){c=new Date().valueOf()}if(new Date().valueOf()-c>1000){e.stop()}else{}}else{c=null}},tock:function(h){h.type="geometry";postMessage(h)},modifyNode:function(i,h){a.modifyNode(i,h);e.go()},modifyPhysics:function(h){a.modifyPhysics(h)},update:function(h){var i=a._update(h)}};return e};var physics=PhysicsWorker();onmessage=function(a){if(!a.data.type){postMessage("¿kérnèl?");return}if(a.data.type=="physics"){var b=a.data.physics;physics.init(a.data.physics);return}switch(
 a.data.type){case"modify":physics.modifyNode(a.data.id,a.data.mods);break;case"changes":physics.update(a.data.changes);physics.go();break;case"start":physics.go();break;case"stop":physics.stop();break;case"sys":var b=a.data.param||{};if(!isNaN(b.timeout)){physics.timeout(b.timeout)}physics.modifyPhysics(b);physics.go();break}};
+  })()
+
+
+  arbor = (typeof(arbor)!=='undefined') ? arbor : {}
+  $.extend(arbor, {
+    // object constructors (don't use ‘new’, just call them)
+    ParticleSystem:ParticleSystem,
+    Point:function(x, y){ return new Point(x, y) },
+
+    // immutable object with useful methods
+    etc:{
+      trace:trace,              // ƒ(msg) -> safe console logging
+      dirname:dirname,          // ƒ(path) -> leading part of path
+      basename:basename,        // ƒ(path) -> trailing part of path
+      ordinalize:ordinalize,    // ƒ(num) -> abbrev integers (and add commas)
+      objcopy:objcopy,          // ƒ(old) -> clone an object
+      objcmp:objcmp,            // ƒ(a, b, strict_ordering) -> t/f comparison
+      objkeys:objkeys,          // ƒ(obj) -> array of all keys in obj
+      objmerge:objmerge,        // ƒ(dst, src) -> like $.extend but non-destructive
+      uniq:uniq,                // ƒ(arr) -> array of unique items in arr
+      arbor_path:arbor_path,    // ƒ() -> guess the directory of the lib code
+    }
+  })
+
+})(this.jQuery)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/App.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/App.js b/contrib/views/storm/src/main/resources/scripts/App.js
new file mode 100644
index 0000000..1efaff1
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/App.js
@@ -0,0 +1,41 @@
+/**
+* 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.
+*/
+
+define(['marionette', 'utils/LangSupport', 'utils/Utils'], function(Marionette, localization, Utils) {
+  /*
+   * Localization initialization
+   */
+  localization.setDefaultCulture(); // will take default that is en
+  localization.chooseCulture();
+  var App = new Marionette.Application();
+
+  App.addRegions({
+    rHeader: '#header',
+    rContent: '#content',
+    rTopology: '#topology',
+    rCluster: '#cluster'
+  });
+
+  App.baseUrl = Utils.getStormHostDetails();
+
+  App.addInitializer(function() {
+    Backbone.history.start();
+  });
+
+  return App;
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/collection/BaseCollection.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/collection/BaseCollection.js b/contrib/views/storm/src/main/resources/scripts/collection/BaseCollection.js
new file mode 100644
index 0000000..0844fa5
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/collection/BaseCollection.js
@@ -0,0 +1,61 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'utils/Utils'
+  ], function (require, Globals, Utils) {
+  'use strict';
+
+  var BaseCollection = Backbone.Collection.extend(
+    /** @lends BaseCollection.prototype */
+    {
+      initialize: function () {},
+      bindErrorEvents: function () {
+        this.bind("error", Utils.defaultErrorHandler);
+      },
+
+    },
+    /** BaseCollection's Static Attributes */
+    {
+      // Static functions
+      getTableCols: function (cols, collection) {
+        var retCols = _.map(cols, function (v, k, l) {
+          var defaults = collection.constructor.tableCols[k];
+          if (!defaults) {
+            defaults = {};
+          }
+          return _.extend({
+            'name': k
+          }, defaults, v);
+        });
+
+        return retCols;
+      },
+
+      nonCrudOperation: function (url, requestMethod, options) {
+        return Backbone.sync.call(this, null, this, _.extend({
+          url: url,
+          type: requestMethod
+        }, options));
+      }
+
+    });
+
+  return BaseCollection;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/collection/VTopologyList.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/collection/VTopologyList.js b/contrib/views/storm/src/main/resources/scripts/collection/VTopologyList.js
new file mode 100644
index 0000000..600ed3d
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/collection/VTopologyList.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'collection/BaseCollection',
+  'models/VTopology'
+  ], function (require, Globals, BaseCollection, vTopology) {
+  'use strict';
+  var vTopologyList = BaseCollection.extend(
+    //Prototypal attributes
+    {
+
+      url: Globals.baseURL + '/api/v1/topology/summary',
+
+      model: vTopology,
+
+
+      initialize: function () {
+        this.modelName = 'VTopology';
+        this.modelAttrName = 'topologies';
+        this.bindErrorEvents();
+      }
+    }
+  );
+  return vTopologyList;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/globalize/message/en.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/globalize/message/en.js b/contrib/views/storm/src/main/resources/scripts/globalize/message/en.js
new file mode 100644
index 0000000..527a19d
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/globalize/message/en.js
@@ -0,0 +1,180 @@
+/**
+* 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.
+*/
+
+/**
+ * Never Delete any key without seraching it in all View and Template files
+ */
+(function (window, undefined) {
+  var Globalize;
+  require(['globalize'], function (globalize) {
+    Globalize = globalize;
+    Globalize.addCultureInfo("en", {
+      messages: {
+        // Form labels, Table headers etc
+        lbl: {
+          name: 'Name',
+          id: 'ID',
+          owner: 'Owner',
+          topologySummary: 'Topology Summary',
+          total: 'Total',
+          active: 'Active',
+          inactive: 'Inactive',
+          status: 'Status',
+          uptime: 'Uptime',
+          workers: 'Workers',
+          executors: 'Executors',
+          tasks: 'Tasks',
+          schedulerInfo: 'Scheduler Info',
+          jar: 'Jar',
+          nimbusHostname: 'Nimbus Hostname',
+          topologyClass: 'Topology Class',
+          arguments: 'Arguments',
+          selectTimeFrame: 'Select time frame',
+          showSystemBolt: 'Show System Bolt',
+          topologySummary: 'Topology Summary',
+          last10Min: 'Last 10 minutes',
+          last3Hr: 'Last 3 hours',
+          last1Day: 'Last 1 day',
+          allTime: 'All time',
+          emitted: 'Emitted',
+          transferred: 'Transferred',
+          Capacity: 'Capacity (last 10m)',
+          executed: 'Executed',
+          processLatency: 'Process Latency (ms)',
+          completeLatencyMS: 'Complete Latency (ms)',
+          acked: 'Acked',
+          key: 'Key',
+          value: 'Value',
+          host: 'Host',
+          slots: 'Slots',
+          usedSlots: 'Used Slots',
+          port: 'Port',
+          freeSlots: 'Free Slots',
+          totalSlots: 'Total Slots',
+          isLeader: 'Is Leader',
+          version: 'Version',
+          uptimeSeconds: 'Uptime',
+          supervisors: 'Supervisors',
+          viewLogs: 'View Logs',
+          rebalanceTopology: 'Rebalance Topology',
+          waitTime : 'Wait Time',
+          statistics: 'Statistics',
+          spouts: 'Spouts',
+          bolts: 'Bolts',
+          topologyConfig: 'Topology Configuration',
+          outputStats: 'Output Stats',
+          errors: 'Errors',
+          error: 'Error',
+          errorPort: 'Error Port',
+          errorHost: 'Error Host',
+          time: 'Time',
+          failed: 'Failed',
+          stream: 'Stream',
+          completeLatency: 'Complete Latency',
+          executeLatency: 'Execute Latency',
+          capacity: 'Capacity'
+        },
+        btn: {
+          deployNewTopology: 'Deploy New Topology',
+          activate: 'Activate',
+          deactivate: 'Deactivate',
+          rebalance: 'Rebalance',
+          kill: 'Kill',
+          cancel: 'Cancel',
+          save: 'Save',
+          yes: 'Yes',
+          no: 'No'
+        },
+        h: {
+          topologies: 'Topologies',
+          cluster: 'Cluster',
+          clusterSummary: 'Cluster Summary',
+          nimbusSummary: 'Nimbus Summary',
+          supervisorSummary: 'Supervisor Summary',
+          nimbusConfiguration: 'Nimbus Configuration'
+        },
+        msg: {
+          noTopologyFound: 'No topology found',
+          topologySummaryName: 'The name given to the topology by when it was submitted.',
+          topologySummaryId: 'The unique ID given to a Topology each time it is launched.',
+          topologySummaryOwner: 'The user that submitted the Topology, if authentication is enabled.',
+          topologySummaryStatus: 'The status can be one of ACTIVE, INACTIVE, KILLED, or REBALANCING.',
+          topologySummaryUptime: 'The time since the Topology was submitted.',
+          topologySummaryWorkers: 'The number of Workers (processes).',
+          topologySummaryExecutors: 'Executors are threads in a Worker process.',
+          topologySummaryTasks: 'A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.',
+          topologySummaryScheduler: 'This shows information from the scheduler about the latest attempt to schedule the Topology on the cluster.',
+          noClusterFound: 'No cluster found',
+          noNimbusFound: 'No nimbus found',
+          noSupervisorFound: 'No supervisor found',
+          noNimbusConfigFound: 'No nimbus configuration found',
+          noSpoutFound: 'No spout found',
+          noBoltFound: 'No bolt found',
+          noOutputStatsFound: 'No output stats found',
+          noExecutorsFound: 'No executor found',
+          noErrorFound: 'No error found',
+          noTopologyConfigFound: 'No topology configuration found',
+          clusterSummarySupervisors: 'The number of nodes in the cluster currently.',
+          clusterSummarySlots: 'Slots are Workers (processes).',
+          clusterSummaryExecutors: 'Executors are threads in a Worker process.',
+          clusterSummaryTasks: 'A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.',
+          supervisorId: 'A unique identifier given to a Supervisor when it joins the cluster.',
+          supervisorHost: 'The hostname reported by the remote host. (Note that this hostname is not the result of a reverse lookup at the Nimbus node.)',
+          supervisorUptime: 'The length of time a Supervisor has been registered to the cluster.',
+          stormNotRunning: 'Error detected while fetching storm hostname and port number',
+          stormNotConfigured: 'Currently, no service is configured in ambari',
+          spoutId: 'The ID assigned to a the Component by the Topology.',
+          spoutExecutors: 'Executors are threads in a Worker process.',
+          spoutTasks: 'A Task is an instance of a Bolt or Spout. The number of Tasks is almost always equal to the number of Executors.',
+          emitted: 'The number of Tuples emitted.',
+          transferred: 'The number of Tuples emitted that sent to one or more bolts.',
+          completeLatency: 'The average time a Tuple "tree" takes to be completely processed by the Topology. A value of 0 is expected if no acking is done.',
+          acked: 'The number of Tuple "trees" successfully processed. A value of 0 is expected if no acking is done.',
+          failed: 'The number of Tuple "trees" that were explicitly failed or timed out before acking was completed. A value of 0 is expected if no acking is done.',
+          stream: 'The name of the Tuple stream given in the Topolgy, or "default" if none was given.',
+          uniqueExecutorId: 'The unique executor ID.',
+          extensionUptime: 'The length of time an Executor (thread) has been alive.',
+          extensionHost: 'The hostname reported by the remote host. (Note that this hostname is not the result of a reverse lookup at the Nimbus node.)',
+          extensionPort: 'The port number used by the Worker to which an Executor is assigned. Click on the port number to open the logviewer page for this Worker.',
+          boltCapacity: 'If this is around 1.0, the corresponding Bolt is running as fast as it can, so you may want to increase the Bolt\'s parallelism. This is (number executed * average execute latency) / measurement time.',
+          boltExecuteLatency: 'The average time a Tuple spends in the execute method. The execute method may complete without sending an Ack for the tuple.',
+          boltExected: 'The number of incoming Tuples processed.',
+          boltProcessLatency: 'The average time it takes to Ack a Tuple after it is first received.  Bolts that join, aggregate or batch may not Ack a tuple until a number of other Tuples have been received.',
+          boltAcked: 'The number of Tuples acknowledged by this Bolt.',
+        },
+        plcHldr: {
+          search: 'Search'
+        },
+        dialogMsg: {
+          topologyBeingDeployed: 'Please wait, topology is being deployed',
+          invalidFile: 'Selected file to upload is not a .jar file',
+          topologyDeployedSuccessfully: 'New topology deployed successfully',
+          topologyDeployFailed: 'Deploying new topology failed.',
+          activateTopologyMsg: 'Are you sure you want to activate this topology ?',
+          topologyActivateSuccessfully: 'Topology activated successfully',
+          deactivateTopologyMsg: 'Are you sure you want to deactivate this topology ?',
+          killTopologyMsg: 'Are you sure you want to kill this topology ? If yes, please, specify wait time in seconds.',
+          topologyDeactivateSuccessfully: 'Topology deactivated successfully',
+          topologyRebalanceSuccessfully: 'Topology rebalanced successfully',
+          topologyKilledSuccessfully: 'Topology killed successfully',
+        },
+        validationMessages: {}
+      }
+    });
+  });
+}(this));

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/main.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/main.js b/contrib/views/storm/src/main/resources/scripts/main.js
new file mode 100644
index 0000000..deb3085
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/main.js
@@ -0,0 +1,151 @@
+/**
+* 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.
+*/
+
+require.config({
+  /* starting point for application */
+  hbs: {
+    disableI18n: true, // This disables the i18n helper and doesn't require the json i18n files (e.g. en_us.json)
+    helperPathCallback: // Callback to determine the path to look for helpers
+      function(name) { // ('/template/helpers/'+name by default)
+        return "modules/Helpers";
+      },
+    templateExtension: "html", // Set the extension automatically appended to templates
+    compileOptions: {} // options object which is passed to Handlebars compiler
+  },
+
+  /**
+   * Requested as soon as the loader has processed the configuration. It does
+   * not block any other require() calls from starting their requests for
+   * modules, it is just a way to specify some modules to load asynchronously
+   * as part of a config block.
+   * @type {Array} An array of dependencies to load.
+   */
+  deps: ['marionette', 'globalize', 'utils/LangSupport'],
+
+  /**
+   * The number of seconds to wait before giving up on loading a script.
+   * @default 7 seconds
+   * @type {Number}
+   */
+  waitSeconds: 30,
+
+
+  shim: {
+    backbone: {
+      deps: ['underscore', 'jquery'],
+      exports: 'Backbone'
+    },
+    bootstrap: {
+      deps: ['jquery'],
+    },
+    underscore: {
+      exports: '_'
+    },
+    marionette: {
+      deps: ['backbone']
+    },
+    backgrid: {
+      deps: ['backbone']
+    },
+    'backbone.forms': {
+      deps: ['backbone']
+    },
+    'backbone-forms.templates': {
+      deps: ['backbone-forms.list', 'backbone.forms']
+    },
+    'bootstrap.filestyle': {
+      deps: ['jquery', 'bootstrap']
+    },
+    'bootstrap.notify': {
+      deps: ['jquery']
+    },
+    'jquery-ui': {
+      deps: ['jquery'],
+    },
+    'jquery.ui.widget': {
+      deps: ['jquery']
+    },
+    globalize: {
+      exports: 'Globalize'
+    },
+    bootbox: {
+      deps: ['jquery']
+    },
+    arbor: {
+      deps: ['jquery']
+    },
+    'arbor-tween':{
+      deps: ['jquery', 'arbor']
+    },
+    'arbor-graphics':{
+      deps: ['jquery', 'arbor']
+    },
+    hbs: {
+      deps: ['underscore', 'handlebars']
+    }
+  },
+
+  paths: {
+    'jquery': '../libs/bower/jquery/js/jquery',
+    'backbone': '../libs/bower/backbone/js/backbone',
+    'underscore': '../libs/bower/underscore/js/underscore',
+    'marionette': '../libs/bower/backbone.marionette/js/backbone.marionette',
+    'backbone.wreqr': '../libs/bower/backbone.wreqr/js/backbone.wreqr',
+    'backbone.babysitter': '../libs/bower/backbone.babysitter/js/backbone.babysitter',
+    'backbone.forms': '../libs/bower/backbone-forms/js/backbone-forms',
+    'backbone-forms.list': '../libs/bower/backbone-forms/js/list',
+    'bootstrap': '../libs/bower/bootstrap/js/bootstrap',
+    'bootstrap.filestyle': '../libs/bower/bootstrap/js/bootstrap-filestyle.min',
+    'bootstrap.notify': '../libs/bower/bootstrap/js/bootstrap-notify',
+    'backgrid': '../libs/bower/backgrid/js/backgrid',
+    'jquery-ui': '../libs/bower/jquery-ui/js/jquery-ui-1.10.3.custom',
+    'jquery.ui.widget': '../libs/bower/jquery-ui/js/jquery.ui.widget.min',
+    'globalize': '../libs/bower/globalize/js/globalize',
+    'gblMessages' : '../scripts/globalize',
+    'bootbox': '../libs/bower/bootbox/js/bootbox',
+    'arbor': '../libs/other/arbor',
+    'arbor-tween': '../libs/other/arbor-tween',
+    'arbor-graphics': '../libs/other/arbor-graphics',
+    'handlebars': '../libs/bower/require-handlebars-plugin/js/handlebars',
+    'i18nprecompile': '../libs/bower/require-handlebars-plugin/js/i18nprecompile',
+    'json2': '../libs/bower/require-handlebars-plugin/js/json2',
+    'hbs': '../libs/bower/require-handlebars-plugin/js/hbs',
+    'tmpl': '../templates'
+  },
+
+  /**
+   * If set to true, an error will be thrown if a script loads that does not
+   * call define() or have a shim exports string value that can be checked.
+   * To get timely, correct error triggers in IE, force a define/shim export.
+   * @type {Boolean}
+   */
+  enforceDefine: false
+});
+
+require(["App",
+  "router/Router",
+  "utils/Overrides",
+  "arbor",
+  "arbor-tween",
+  "arbor-graphics"
+  ], function(App, Router) {
+    'use strict';
+
+  App.appRouter = new Router();
+  App.start();
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/BaseModel.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/BaseModel.js b/contrib/views/storm/src/main/resources/scripts/models/BaseModel.js
new file mode 100644
index 0000000..fe5b564
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/BaseModel.js
@@ -0,0 +1,71 @@
+/**
+* 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.
+*/
+
+define(['require', 'utils/Utils'], function (require, Utils) {
+  'use strict';
+
+var BaseModel = Backbone.Model.extend(
+	/** @lends BaseModel.prototype */
+	{
+		/**
+		 * BaseModel's initialize function
+		 * @augments Backbone.Model
+		 * @constructs
+		 */
+		initialize : function() {
+
+		},
+		bindErrorEvents :function(){
+			this.bind("error", Utils.defaultErrorHandler);
+		},
+		/**
+		 * toString for a model. Every model should implement this function.
+		 */
+		toString : function() {
+			throw new Error('ERROR: toString() not defined for ' + this.modelName);
+		},
+
+		/**
+		 * Silent'ly set the attributes. ( do not trigger events )
+		 */
+		silent_set: function(attrs) {
+			return this.set(attrs, {
+				silent: true
+			});
+		}
+	},
+	/** BaseModel's Static Attributes */
+	{
+
+		/**
+		 * [nonCrudOperation description]
+		 * @param  {[type]} url           [description]
+		 * @param  {[type]} requestMethod [description]
+		 * @param  {[type]} options       [description]
+		 * @return {[type]}               [description]
+		 */
+		nonCrudOperation : function(url, requestMethod, options){
+			return Backbone.sync.call(this, null, this, _.extend({
+				url: url,
+				type: requestMethod
+			}, options));
+		}
+	});
+
+	return BaseModel;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/Cluster.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/Cluster.js b/contrib/views/storm/src/main/resources/scripts/models/Cluster.js
new file mode 100644
index 0000000..c1e0de0
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/Cluster.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vCluster = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '/api/v1/cluster/summary',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vCluster';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vCluster;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VBolt.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VBolt.js b/contrib/views/storm/src/main/resources/scripts/models/VBolt.js
new file mode 100644
index 0000000..7fd266c
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VBolt.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vBolt = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vBolt';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vBolt;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VError.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VError.js b/contrib/views/storm/src/main/resources/scripts/models/VError.js
new file mode 100644
index 0000000..caaaea2
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VError.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vError = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vError';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vError;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VExecutor.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VExecutor.js b/contrib/views/storm/src/main/resources/scripts/models/VExecutor.js
new file mode 100644
index 0000000..0b10965
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VExecutor.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vExecutor = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vExecutor';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vExecutor;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VModel.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VModel.js b/contrib/views/storm/src/main/resources/scripts/models/VModel.js
new file mode 100644
index 0000000..a46c602
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VModel.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var VModel = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'VModel';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return VModel;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VNimbus.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VNimbus.js b/contrib/views/storm/src/main/resources/scripts/models/VNimbus.js
new file mode 100644
index 0000000..541cb24
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VNimbus.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vNimbus = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '/api/v1/nimbus/summary',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vNimbus';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vNimbus;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VNimbusConfig.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VNimbusConfig.js b/contrib/views/storm/src/main/resources/scripts/models/VNimbusConfig.js
new file mode 100644
index 0000000..5ae850b
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VNimbusConfig.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vNimbusConfig = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '/api/v1/cluster/configuration',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vNimbusConfig';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vNimbusConfig;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VOutputStat.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VOutputStat.js b/contrib/views/storm/src/main/resources/scripts/models/VOutputStat.js
new file mode 100644
index 0000000..617865b
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VOutputStat.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vOutputStat = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vOutputStat';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vOutputStat;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VSpout.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VSpout.js b/contrib/views/storm/src/main/resources/scripts/models/VSpout.js
new file mode 100644
index 0000000..d19c2c4
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VSpout.js
@@ -0,0 +1,44 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vSpout = vBaseModel.extend({
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vSpout';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    },
+    getDetails: function(options) {
+      return this.constructor.nonCrudOperation.call(this, Globals.baseURL + '/api/v1/topology/' + options.topologyId + '/component/' + options.spoutId + '?sys=' + options.systemBoltFlag + '&window=' + options.windowTimeFrame, 'GET', options);
+    }
+  }, {});
+  return vSpout;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VSupervisor.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VSupervisor.js b/contrib/views/storm/src/main/resources/scripts/models/VSupervisor.js
new file mode 100644
index 0000000..496ffb4
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VSupervisor.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vSupervisor = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '/api/v1/supervisor/summary',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vSupervisor';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vSupervisor;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VTopology.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VTopology.js b/contrib/views/storm/src/main/resources/scripts/models/VTopology.js
new file mode 100644
index 0000000..f367167
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VTopology.js
@@ -0,0 +1,56 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var VTopology = vBaseModel.extend({
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'VTopology';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    },
+    getDetails: function(options) {
+      return this.constructor.nonCrudOperation.call(this, Globals.baseURL + '/api/v1/topology/' + options.id + '?sys=' + options.sysBoltFlag + '&window=' + options.windowTimeFrame, 'GET', options);
+    },
+    activateTopology: function(options) {
+      return this.constructor.nonCrudOperation.call(this, Globals.baseURL + '/api/v1/topology/' + options.id + '/activate', 'POST', options);
+    },
+    deactivateTopology: function(options) {
+      return this.constructor.nonCrudOperation.call(this, Globals.baseURL + '/api/v1/topology/' + options.id + '/deactivate', 'POST', options);
+    },
+    rebalanceTopology: function(options) {
+      return this.constructor.nonCrudOperation.call(this, Globals.baseURL + '/api/v1/topology/' + options.id + '/rebalance/' + options.waitTime, 'POST', options);
+    },
+    killTopology: function(options) {
+      return this.constructor.nonCrudOperation.call(this, Globals.baseURL + '/api/v1/topology/' + options.id + '/kill/' + options.waitTime, 'POST', options);
+    }
+  }, {});
+  return VTopology;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/models/VTopologyConfig.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/models/VTopologyConfig.js b/contrib/views/storm/src/main/resources/scripts/models/VTopologyConfig.js
new file mode 100644
index 0000000..6dc3fa7
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/models/VTopologyConfig.js
@@ -0,0 +1,42 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'utils/Globals',
+  'models/BaseModel'
+], function(require, Globals, vBaseModel) {
+  'use strict';
+  var vTopologyConfig = vBaseModel.extend({
+    urlRoot: Globals.baseURL + '',
+
+    defaults: {},
+
+    serverSchema: {},
+
+    idAttribute: 'id',
+
+    initialize: function() {
+      this.modelName = 'vTopologyConfig';
+      this.bindErrorEvents();
+    },
+    toString: function() {
+      return this.get('name');
+    }
+  }, {});
+  return vTopologyConfig;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/modules/Helpers.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/modules/Helpers.js b/contrib/views/storm/src/main/resources/scripts/modules/Helpers.js
new file mode 100644
index 0000000..588585e
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/modules/Helpers.js
@@ -0,0 +1,157 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'handlebars',
+  'utils/LangSupport'
+  ], function(require, Handlebars, localization) {
+  /*
+   * General guidelines while writing helpers:
+   *
+   * - If returning HTML use return new Handlebars.SafeString();
+   * - If the helper needs optional arguments use the "hash arguments"
+   *   Eg. {{{link . "See more..." story.url class="story"}}}
+   *   NOTE: the first argument after the helper name should be . which will be context in the helper function
+   *   Handlebars.registerHelper('link', function (context, text, url, options) {
+   *    var attrs = [];
+   *
+   *    for(var prop in options.hash) {
+   *      attrs.push(prop + '="' + options.hash[prop] + '"');
+   *    }
+   *    return new Handlebars.SafeString("<a " + attrs.join(" ") + ">" + text + "</a>");
+   *   });
+   *
+   *
+   * NOTE: Due to some limitations in the require-handlebars-plugin, we cannot have helper that takes zero arguments,
+   *       for such helpers we have to pass a "." as first argument. [https://github.com/SlexAxton/require-handlebars-plugin/issues/72]
+   */
+
+  var HHelpers = {};
+
+  /**
+   * Convert new line (\n\r) to <br>
+   * from http://phpjs.org/functions/nl2br:480
+   */
+  HHelpers.nl2br = function(text) {
+    text = Handlebars.Utils.escapeExpression(text);
+    var nl2br = (text + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + '<br>' + '$2');
+    return new Handlebars.SafeString(nl2br);
+  };
+  Handlebars.registerHelper('nl2br', HHelpers.nl2br);
+
+  Handlebars.registerHelper('toHumanDate', function(val) {
+    if (!val) return "";
+    return localization.formatDate(val, 'f');
+  });
+
+  /*
+   * Truncate the String till n positions
+   */
+  Handlebars.registerHelper('truncStr', function(str, n, useWordBoundary) {
+    var len = n || 1;
+    var useWordBn = useWordBoundary || false;
+    return str.trunc(len, useWordBn);
+  });
+
+
+  Handlebars.registerHelper('tt', function(str) {
+    return localization.tt(str);
+    return str;
+  });
+
+  Handlebars.registerHelper('if_eq', function(context, options) {
+    if (context == options.hash.compare)
+      return options.fn(this);
+    return options.inverse(this);
+  });
+
+  Handlebars.registerHelper('if_gt', function(context, options) {
+    if (context > options.hash.compare)
+      return options.fn(this);
+    return options.inverse(this);
+  });
+
+  Handlebars.registerHelper('ifCond', function(v1, operator, v2, options) {
+
+    switch (operator) {
+      case '==':
+        return (v1 == v2) ? options.fn(this) : options.inverse(this);
+        break;
+      case '===':
+        return (v1 === v2) ? options.fn(this) : options.inverse(this);
+        break;
+      case '<':
+        return (v1 < v2) ? options.fn(this) : options.inverse(this);
+        break;
+      case '<=':
+        return (v1 <= v2) ? options.fn(this) : options.inverse(this);
+        break;
+      case '>':
+        return (v1 > v2) ? options.fn(this) : options.inverse(this);
+        break;
+      case '>=':
+        return (v1 >= v2) ? options.fn(this) : options.inverse(this);
+        break;
+      default:
+        return options.inverse(this);
+        break;
+    }
+    //return options.inverse(this);
+  });
+
+  //For Example
+  /*{{#compare numberone "eq" numbretwo}}
+    do something
+  {{else}}
+    do something else
+  {{/compare}}
+*/
+  Handlebars.registerHelper("compare", function(v1, op, v2, options) {
+
+    var c = {
+      "eq": function(v1, v2) {
+        return v1 == v2;
+      },
+      "neq": function(v1, v2) {
+        return v1 != v2;
+      },
+
+    };
+
+    if (Object.prototype.hasOwnProperty.call(c, op)) {
+      return c[op].call(this, v1, v2) ? options.fn(this) : options.inverse(this);
+    }
+    return options.inverse(this);
+  });
+  //For Example
+  //{{#eachProperty object}}
+  //{{property}}: {{value}}<br/>
+  //{{/eachProperty }}
+  Handlebars.registerHelper('eachProperty', function(context, options) {
+    var ret = "";
+    for (var prop in context) {
+      ret = ret + options.fn({
+        property: prop,
+        value: context[prop]
+      });
+    }
+    return new Handlebars.SafeString(ret);
+  });
+
+  return HHelpers;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/modules/Vent.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/modules/Vent.js b/contrib/views/storm/src/main/resources/scripts/modules/Vent.js
new file mode 100644
index 0000000..eebd6d7
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/modules/Vent.js
@@ -0,0 +1,22 @@
+/**
+* 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.
+*/
+
+define(['backbone.wreqr'], function (Wreqr) {
+  "use strict";
+  return new Wreqr.EventAggregator();
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/router/Router.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/router/Router.js b/contrib/views/storm/src/main/resources/scripts/router/Router.js
new file mode 100644
index 0000000..0a227cf
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/router/Router.js
@@ -0,0 +1,98 @@
+/**
+* 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.
+*/
+
+define([
+	'jquery',
+	'underscore',
+	'backbone',
+	'utils/Utils',
+	'App'
+], function($, _, Backbone, Utils, App) {
+	var AppRouter = Backbone.Router.extend({
+		routes: {
+			// Define some URL routes
+			"": 'topologySummaryAction',
+			"!/topology": 'topologySummaryAction',
+			"!/topology/:id": 'topologyDetailAction',
+
+			// Default
+			'*actions': 'defaultAction'
+		},
+
+		initialize: function() {
+			this.showRegions();
+			this.bindRegions();
+			this.listenTo(this, "route", this.postRouteExecute, this);
+		},
+
+		showRegions: function () {
+			require(['views/site/Header'], function (HeaderView) {
+				App.rHeader.show(new HeaderView());
+			});
+		},
+
+		bindRegions: function () {
+			require(['modules/Vent'], function(vent){
+				vent.on('Region:showTopologySection', function(){
+					App.rCluster.$el.removeClass('active').hide();
+					App.rTopology.$el.addClass('active').show();
+					if(App.rTopology.$el.children().hasClass('topologyDetailView')){
+						vent.trigger('Breadcrumb:Show');
+					}
+				});
+
+				vent.on('Region:showClusterSection', function(){
+					if(!App.rCluster.hasView()){
+						require(['views/Cluster/ClusterSummary'], function(ClusterSummaryView){
+							App.rCluster.show(new ClusterSummaryView());
+						});
+					}
+					App.rTopology.$el.removeClass('active').hide();
+					App.rCluster.$el.addClass('active').show();
+					vent.trigger('Breadcrumb:Hide');
+				});
+
+			});
+		},
+
+		/**
+		 * Define route handlers here
+		 */
+		topologySummaryAction: function() {
+			require(['views/Topology/TopologySummary'],function(TopologySummaryView){
+        App.rTopology.show(new TopologySummaryView());
+      });
+		},
+
+		topologyDetailAction: function(id) {
+			require(['views/Topology/TopologyDetail'], function(TopologyDetailView){
+				App.rTopology.show(new TopologyDetailView({
+					id: id
+				}));
+			});
+		},
+
+		defaultAction: function(actions) {
+			// We have no matching route, lets just log what the URL was
+			console.log('No route:', actions);
+		}
+	});
+
+	return AppRouter;
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/utils/Globals.js b/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
new file mode 100644
index 0000000..bfbb873
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
@@ -0,0 +1,30 @@
+/**
+* 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.
+*/
+
+define(['require', 'App'], function (require, App) {
+  'use strict';
+
+  var Globals = {};
+
+  Globals.baseURL = App.baseUrl;
+
+  Globals.settings = {};
+  Globals.settings.refreshInterval = 60000;
+
+  return Globals;
+});
\ No newline at end of file