diff --git a/doc/source/development.rst b/doc/source/development.rst new file mode 100644 index 0000000..aa18578 --- /dev/null +++ b/doc/source/development.rst @@ -0,0 +1,98 @@ +=========== +Development +=========== + +.. _build_vm_image: + +Build KloudBuster Image +------------------------ + +The official pre-built image from OpenStack App Catalog should satisfy most of +use cases. This option is just for development purposes, and for whatever +reason the pre-built version does not work for you. + + +Build on MacOSX +^^^^^^^^^^^^^^^ + +You need to install first: + +* `Virtualbox `_ +* `Vagrant `_ + +And build the image with below commands: + +.. code-block:: bash + + $ # Clone the kloudbuster repository if you have not done so + $ git clone https://github.com/openstack/kloudbuster.git + $ # Go to the dib directory + $ cd kloudbuster/kb_dib + $ # Run vagrant and start building the image + $ vagrant up + +After a few minutes (depending on virtualbox overhead), the qcow2 image will +be built and available in the same directory. You can then upload it to +OpenStack using the glance CLI, destroy the vagrant VM ("vagrant destroy") and +dispose of the kloudbuster directory (if no longer needed). + + +Build on Linux +^^^^^^^^^^^^^^ + +A generally faster build method than with MacOSX/Vagrant. Your Linux server +must have python, git and qemu utilities installed. You can skip the package +installation if you've installed KloudBuster using the GitHub/OpenStack +repository based installation. + +Ubuntu/Debian based: + +.. code-block:: bash + + $ sudo apt-get install python-dev git qemu-utils + $ # Source the virtual environment if you have one + $ pip install PyYAML + +Redhat/Fedora/CentOS based: + +.. code-block:: bash + + $ sudo yum install python-devel git qemu-img + $ # Source the virtual environment if you have one + $ pip install PyYAML + +Build the image with below commands: + +.. code-block:: bash + + $ # Clone the kloudbuster repository if you have not done so + $ git clone https://github.com/openstack/kloudbuster.git + $ # Go to the dib directory + $ cd kloudbuster/kb_dib + $ # Run the build image script, which will install DIB and start the build + $ ./build-image.sh + +After a few minutes, the qcow2 image will be built and available in the same +directory. You can then upload it to OpenStack using the glance CLI. + + +Trouble-shooting +^^^^^^^^^^^^^^^^ + +If you get an error message saying that import yaml fails (seems to happen +only on Ubuntu):: + + dib-run-parts Thu Jul 2 09:27:50 PDT 2015 Running /tmp/image.ewtpa5DW/hooks/extra-data.d/99-squash-package-install + + "/tmp/image.ewtpa5DW/hooks/extra-data.d/../bin/package-installs-squash", + line 26, in + import yaml + ImportError: No module named yaml + +You need to comment out the secure_path option in your /etc/sudoers file (use +"sudo visudo" to edit that file):: + + #Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + + +.. include:: ../../kb_web/README.rst diff --git a/doc/source/index.rst b/doc/source/index.rst index 3b7d4a1..720e645 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -14,6 +14,7 @@ Contents: readme installation usage + development contributing Indices and tables diff --git a/doc/source/installation.rst b/doc/source/installation.rst index 6926f6e..25dc3ee 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -142,7 +142,7 @@ Upload VM Image KloudBuster needs one "universal" test VM image (referred to as "KloudBuster image") that contains the necessary test software. The KloudBuster image is then instantiated in potentially large number of VMs by the KloudBuster application using the appropriate role (HTTP server, HTTP traffic generator...). -Pre-built images are available for download from the `OpenStack App Catalog `_ (preferred method). For whatever reason the pre-built version doesn't work for you, the image can be re-built from MacOSX using Vagrant or from any Linux server. See :ref:`below section ` for more details. +Pre-built images are available for download from the `OpenStack App Catalog `_ (preferred method). For whatever reason the pre-built version doesn't work for you, the image can be re-built from MacOSX using Vagrant or from any Linux server. See :ref:`here ` for more details. Manual upload of the KloudBuster VM image @@ -157,84 +157,3 @@ KloudBuster VM images are qcow2 images named "kloudbuster_v.qcow2" (e.g .. code-block:: bash $ glance image-create --file kloudbuster_v3.qcow2 --disk-format qcow2 --container-format bare --is-public True --name kloudbuster_v3 - - -.. _build_vm_image: - -Build VM image --------------- - -The official pre-built image from OpenStack App Catalog should satisfy most of use cases. This option is just for development purposes, and for whatever reason the pre-built version does not work for you. - - -Build on MacOSX -^^^^^^^^^^^^^^^ - -You need to install first: - -* `Virtualbox `_ -* `Vagrant `_ - -And build the image with below commands: - -.. code-block:: bash - - $ # Clone the kloudbuster repository if you have not done so - $ git clone https://github.com/openstack/kloudbuster.git - $ # Go to the dib directory - $ cd kloudbuster/kb_dib - $ # Run vagrant and start building the image - $ vagrant up - -After a few minutes (depending on virtualbox overhead), the qcow2 image will be built and available in the same directory. You can then upload it to OpenStack using the glance CLI, destroy the vagrant VM ("vagrant destroy") and dispose of the kloudbuster directory (if no longer needed). - -Build on Linux -^^^^^^^^^^^^^^ - -A generally faster build method than with MacOSX/Vagrant. Your Linux server must have python, git and qemu utilities installed. You can skip the package installation if you've installed KloudBuster using the GitHub/OpenStack repository based installation. - -Ubuntu/Debian based: - -.. code-block:: bash - - $ sudo apt-get install python-dev git qemu-utils - $ # Source the virtual environment if you have one - $ pip install PyYAML - -Redhat/Fedora/CentOS based: - -.. code-block:: bash - - $ sudo yum install python-devel git qemu-img - $ # Source the virtual environment if you have one - $ pip install PyYAML - -Build the image with below commands: - -.. code-block:: bash - - $ # Clone the kloudbuster repository if you have not done so - $ git clone https://github.com/openstack/kloudbuster.git - $ # Go to the dib directory - $ cd kloudbuster/kb_dib - $ # Run the build image script, which will install DIB and start the build - $ ./build-image.sh - -After a few minutes, the qcow2 image will be built and available in the same directory. You can then upload it to OpenStack using the glance CLI. - -Trouble-shooting -^^^^^^^^^^^^^^^^ - -If you get an error message saying that import yaml fails (seems to happen only on Ubuntu):: - - dib-run-parts Thu Jul 2 09:27:50 PDT 2015 Running /tmp/image.ewtpa5DW/hooks/extra-data.d/99-squash-package-install - - "/tmp/image.ewtpa5DW/hooks/extra-data.d/../bin/package-installs-squash", - line 26, in - import yaml - ImportError: No module named yaml - -You need to comment out the secure_path option in your /etc/sudoers file (use "sudo visudo" to edit that file):: - - #Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - diff --git a/kb_dib/elements/kloudbuster/package-installs.yaml b/kb_dib/elements/kloudbuster/package-installs.yaml index f226e33..12acb3f 100644 --- a/kb_dib/elements/kloudbuster/package-installs.yaml +++ b/kb_dib/elements/kloudbuster/package-installs.yaml @@ -1,9 +1,13 @@ -nginx: -iperf: -nuttcp: -redis-server: -python-pip: -git: build-essential: -libssl-dev: cmake: +git: +iperf: +libssl-dev: +nginx: +nodejs: +nodejs-legacy: +npm: +nuttcp: +python-pip: +python-dev: +redis-server: diff --git a/kb_dib/elements/kloudbuster/post-install.d/01-kb-script b/kb_dib/elements/kloudbuster/post-install.d/01-kb-script index 4a48d27..cef7d64 100755 --- a/kb_dib/elements/kloudbuster/post-install.d/01-kb-script +++ b/kb_dib/elements/kloudbuster/post-install.d/01-kb-script @@ -57,7 +57,6 @@ sed -i "s/^exit\s0/python \/kb_test\/kb_vm_agent.py \&\n\0/g" /etc/rc.local # ====== # Client # ====== - # python redis client pip install redis @@ -75,16 +74,43 @@ cd wrk2 make mv wrk /usr/local/bin/wrk2 +# Move the HdrHistogram library to /usr/lib +mv /usr/local/lib/libhdr_histogram.so /usr/lib/ + + +# ================= +# KloudBuster Proxy +# ================= +cd /kb_test +git clone git://github.com/openstack/kloudbuster.git +cd kloudbuster +pip install -r requirements.txt +cd kb_web +npm install -g grunt-cli bower +npm install +bower install --allow-root --config.interactive=false --force +grunt build +rm -rf ../kb_server/public/ui/* +mv dist/* ../kb_server/public/ui + + +# ======= +# Cleanup +# ======= + # Remove HdrHistogram_c and wrk2 builds rm -rf /tmp/HdrHistogram_c rm -rf /tmp/wrk2 -# Move the HdrHistogram library to /usr/lib -mv /usr/local/lib/libhdr_histogram.so /usr/lib/ +# Remove KloudBuster Web UI builds +rm -rf /kb_test/kloudbuster/kb_web/node_modules +rm -rf /kb_test/kloudbuster/kb_web/bower_components +rm -rf /kb_test/kloudbuster/kb_web/.tmp # Uninstall unneeded packages apt-get -y --purge remove git apt-get -y --purge remove python-pip +apt-get -y --purge remove python-dev apt-get -y --purge remove build-essential apt-get -y --purge remove cmake apt-get -y --purge autoremove diff --git a/kb_dib/elements/kloudbuster/static/kb_test/kb_vm_agent.py b/kb_dib/elements/kloudbuster/static/kb_test/kb_vm_agent.py index 175e787..ba6f9e4 100644 --- a/kb_dib/elements/kloudbuster/static/kb_test/kb_vm_agent.py +++ b/kb_dib/elements/kloudbuster/static/kb_test/kb_vm_agent.py @@ -29,7 +29,7 @@ import redis # # This version must be incremented if the interface changes or if new features # are added to the agent VM -__version__ = '4' +__version__ = '5d1' # TODO(Logging on Agent) @@ -44,6 +44,12 @@ def get_image_name(): def get_image_version(): return __version__ +def exec_command(cmd): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = p.communicate() + + return p.returncode + class KB_Instance(object): # Check whether the HTTP Service is up running @@ -107,7 +113,7 @@ class KB_Instance(object): return cmd -class KB_VM_Agent(object): +class KBA_Client(object): def __init__(self, user_data): host = user_data['redis_server'] @@ -184,7 +190,6 @@ class KB_VM_Agent(object): stderr = p.communicate()[1] return (p.returncode, p_output, stderr) - def work(self): for item in self.pubsub.listen(): if item['type'] != 'message': @@ -251,50 +256,55 @@ class KB_VM_Agent(object): **http_tool_configs) return self.exec_command_report(self.last_cmd) -def exec_command(cmd): - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (stdout, stderr) = p.communicate() - return p.returncode +class KBA_Server(object): -def start_redis_server(): - cmd = ['sudo', 'service', 'redis-server', 'start'] - return exec_command(cmd) + def __init__(self, user_data): + self.user_data = user_data -def config_nginx_server(http_server_configs): - # Generate the HTML file with specified size - html_size = http_server_configs['html_size'] - cmd_str = 'dd if=/dev/zero of=/data/www/index.html bs=%s count=1' % html_size - cmd = cmd_str.split() - return False if exec_command(cmd) else True + def config_nginx_server(self): + # Generate the HTML file with specified size + html_size = self.user_data['http_server_configs']['html_size'] + cmd_str = 'dd if=/dev/zero of=/data/www/index.html bs=%s count=1' % html_size + cmd = cmd_str.split() + return False if exec_command(cmd) else True -def start_nuttcp_server(): - cmd = ['/usr/bin/nuttcp', '-P5002', '-S', '--single-threaded'] - return exec_command(cmd) + def start_nginx_server(self): + cmd = ['sudo', 'service', 'nginx', 'start'] + return exec_command(cmd) + + # def start_nuttcp_server(self): + # cmd = ['/usr/bin/nuttcp', '-P5002', '-S', '--single-threaded'] + # return exec_command(cmd) + +class KBA_Proxy(object): + + def __init__(self): + pass + + def start_redis_server(self): + cmd = ['sudo', 'service', 'redis-server', 'start'] + return exec_command(cmd) -def start_nginx_server(): - cmd = ['sudo', 'service', 'nginx', 'start'] - return exec_command(cmd) if __name__ == "__main__": try: with open('user-data', 'r') as f: - user_data = eval(f.read()) + user_data = dict(eval(f.read())) except Exception as e: - print e.message - sys.exit(1) + # KloudBuster starts without user-data + config_file = 'kloudbuster/kb_server/config.py' + cmd = ['pecan', 'serve', config_file] + sys.exit(exec_command(cmd)) - if 'role' not in user_data: - sys.exit(1) - - if user_data['role'] == 'KB-PROXY': - sys.exit(start_redis_server()) - if user_data['role'] == 'Server': - # rc = start_nuttcp_server() - if config_nginx_server(user_data['http_server_configs']): - sys.exit(start_nginx_server()) - elif user_data['role'] == 'Client': - agent = KB_VM_Agent(user_data) + if user_data.get('role') == 'KB-PROXY': + agent = KBA_Proxy() + sys.exit(agent.start_redis_server()) + if user_data.get('role') == 'Server': + agent = KBA_Server(user_data) + sys.exit(agent.start_nginx_server()) + elif user_data.get('role') == 'Client': + agent = KBA_Client(user_data) agent.setup_channels() agent.hello_thread = threading.Thread(target=agent.send_hello) agent.hello_thread.daemon = True diff --git a/kb_server/public/ui/404.html b/kb_server/public/ui/404.html deleted file mode 100644 index 1dc421a..0000000 --- a/kb_server/public/ui/404.html +++ /dev/null @@ -1,128 +0,0 @@ - Page Not Found :(

Not found :(

Sorry, but the page you were trying to view does not exist.

It looks like this was the result of either:

  • a mistyped address
  • an out-of-date link
\ No newline at end of file diff --git a/kb_server/public/ui/favicon.ico b/kb_server/public/ui/favicon.ico deleted file mode 100644 index 6527905..0000000 Binary files a/kb_server/public/ui/favicon.ico and /dev/null differ diff --git a/kb_server/public/ui/images/back.8e3b7090.jpg b/kb_server/public/ui/images/back.8e3b7090.jpg deleted file mode 100644 index 5ae232e..0000000 Binary files a/kb_server/public/ui/images/back.8e3b7090.jpg and /dev/null differ diff --git a/kb_server/public/ui/images/logo.d2085010.jpg b/kb_server/public/ui/images/logo.d2085010.jpg deleted file mode 100644 index 740332a..0000000 Binary files a/kb_server/public/ui/images/logo.d2085010.jpg and /dev/null differ diff --git a/kb_server/public/ui/index.html b/kb_server/public/ui/index.html deleted file mode 100644 index 0b6df23..0000000 --- a/kb_server/public/ui/index.html +++ /dev/null @@ -1,4 +0,0 @@ - KloudBuster
\ No newline at end of file diff --git a/kb_server/public/ui/robots.txt b/kb_server/public/ui/robots.txt deleted file mode 100644 index 4d521f9..0000000 --- a/kb_server/public/ui/robots.txt +++ /dev/null @@ -1,4 +0,0 @@ -# robotstxt.org - -User-agent: * -Disallow: diff --git a/kb_server/public/ui/scripts/scripts.a17af697.js b/kb_server/public/ui/scripts/scripts.a17af697.js deleted file mode 100644 index ce301d3..0000000 --- a/kb_server/public/ui/scripts/scripts.a17af697.js +++ /dev/null @@ -1,4 +0,0 @@ -var directive,m,mod,old_m,__indexOf=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};old_m=angular.module("n3-charts.linechart",["n3charts.utils"]),m=angular.module("n3-line-chart",["n3charts.utils"]),directive=function(a,b){return old_m.directive(a,b),m.directive(a,b)},directive("linechart",["n3utils","$window","$timeout",function(a,b,c){var d;return d=function(d,e,f,g){var h,i,j,k,l,m,n,o;o=a,h=o.getEventDispatcher(),i=o.uuid(),e[0].style["font-size"]=0,d.redraw=function(){d.update()},k=!1,j={onSeriesVisibilityChange:function(a){var b,c,e;return e=a.series,b=a.index,c=a.newVisibility,d.options.series[b].visible=c,d.$apply()}},d.update=function(){var a,b,c,g,k,l,m,n,p;return n=o.sanitizeOptions(d.options,f.mode),l=angular.extend(j,o.getTooltipHandlers(n)),c=o.getDataPerSeries(d.data,n),g=o.getDimensions(n,e,f),m="thumbnail"===f.mode,o.clean(e[0]),p=o.bootstrap(e[0],i,g),k=function(a){return n.series.filter(function(b){return b.axis===a&&b.visible!==!1}).length>0},a=o.createAxes(p,g,n.axes).andAddThemIf({all:!m,x:!0,y:k("y"),y2:k("y2")}),c.length&&o.setScalesDomain(a,d.data,n.series,p,n),o.createContent(p,i,n,l),c.length&&(b=o.getBestColumnWidth(a,g,c,n),o.drawData(p,g,a,c,b,n,l,h)),n.drawLegend&&o.drawLegend(p,n.series,g,l,h),"scrubber"===n.tooltip.mode?o.createGlass(p,g,l,a,c,n,h,b):"none"!==n.tooltip.mode&&o.addTooltips(p,g,n.axes),o.createFocus(p,g,n),o.setZoom(p,g,a,c,b,n,l,h)},m=function(){return d.oldclick?h.on("click",d.oldclick):d.click?h.on("click",d.click):h.on("click",null),d.oldhover?h.on("hover",d.oldhover):d.hover?h.on("hover",d.hover):h.on("hover",null),d.mouseenter?h.on("mouseenter",d.mouseenter):h.on("mouseenter",null),d.mouseover?h.on("mouseover",d.mouseover):h.on("mouseover",null),d.mouseout?h.on("mouseout",d.mouseout):h.on("mouseout",null),d.oldfocus?h.on("focus",d.oldfocus):d.focus?h.on("focus",d.focus):h.on("focus",null),d.toggle?h.on("toggle",d.toggle):h.on("toggle",null)},l=void 0,n=function(){return null!=l&&c.cancel(l),l=c(d.redraw,1)},b.addEventListener("resize",n),d.$watch("data",d.redraw,!0),d.$watch("options",d.redraw,!0),d.$watchCollection("[click, hover, focus, toggle]",m),d.$watchCollection("[mouseenter, mouseover, mouseout]",m),d.$watchCollection("[oldclick, oldhover, oldfocus]",m),d.$on("$destroy",function(){return b.removeEventListener("resize",n)})},{replace:!0,restrict:"E",scope:{data:"=",options:"=",oldclick:"=click",oldhover:"=hover",oldfocus:"=focus",click:"=onClick",hover:"=onHover",focus:"=onFocus",toggle:"=onToggle",mouseenter:"=onMouseenter",mouseover:"=onMouseover",mouseout:"=onMouseout"},template:"
",link:d}}]),mod=angular.module("n3charts.utils",[]),mod.factory("n3utils",["$window","$log","$rootScope",function(a,b,c){return{addPatterns:function(a,b){var c;return c=a.select("defs").selectAll("pattern").data(b.filter(function(a){return a.striped})).enter().append("pattern").attr({id:function(a){return a.type+"Pattern_"+a.index},patternUnits:"userSpaceOnUse",x:0,y:0,width:60,height:60}).append("g").style({fill:function(a){return a.color},"fill-opacity":.9}),c.append("rect").style("fill-opacity",.9).attr("width",60).attr("height",60),c.append("path").attr("d","M 10 0 l10 0 l -20 20 l 0 -10 z"),c.append("path").attr("d","M40 0 l10 0 l-50 50 l0 -10 z"),c.append("path").attr("d","M60 10 l0 10 l-40 40 l-10 0 z"),c.append("path").attr("d","M60 40 l0 10 l-10 10 l -10 0 z")},drawArea:function(a,b,c,d){var e,f,g,h;return g=c.filter(function(a){return"area"===a.type}),this.addPatterns(a,g),h={y:this.createLeftAreaDrawer(b,d.lineMode,d.tension),y2:this.createRightAreaDrawer(b,d.lineMode,d.tension)},f=a.select(".content").selectAll(".areaGroup").data(g),e=f.enter().append("g").attr("class",function(a){return"areaGroup series_"+a.index}),f.each(function(a){var b;return b=d3.select(this).selectAll("path").data([a]),b.enter().append("path").attr("class","area"),b.style("fill",function(a){return a.striped!==!0?a.color:"url(#areaPattern_"+a.index+")"}).style("opacity",function(a){return a.striped?"1":"0.8"}).attr("d",function(a){return h[a.axis](a.values)})}),this},createLeftAreaDrawer:function(a,b,c){return d3.svg.area().x(function(b){return a.xScale(b.x)}).y0(function(b){return a.yScale(b.y0)}).y1(function(b){return a.yScale(b.y0+b.y)}).interpolate(b).tension(c)},createRightAreaDrawer:function(a,b,c){return d3.svg.area().x(function(b){return a.xScale(b.x)}).y0(function(b){return a.y2Scale(b.y0)}).y1(function(b){return a.y2Scale(b.y0+b.y)}).interpolate(b).tension(c)},getPseudoColumns:function(a,b){var c,d;return a=a.filter(function(a){return"column"===a.type}),d={},c=[],a.forEach(function(a){var e,f,g,h,i;return e=b.series.map(function(a){return a.id}).indexOf(a.id),h=null!=(i=b.series)?i[e].visible:void 0,void 0!==h&&h!==!0||(f=!1,b.stacks.forEach(function(b,e){var g;return null!=a.id&&(g=a.id,__indexOf.call(b.series,g)>=0)?(d[a.id]=e,__indexOf.call(c,e)<0&&c.push(e),f=!0):void 0}),f!==!1)?void 0:(e=d[a.id]=g=c.length,c.push(e))}),{pseudoColumns:d,keys:c}},getMinDelta:function(a,b,c,d){return d3.min(a.map(function(a){return a.values.map(function(a){return c(a[b])}).filter(function(a){return d?a>=d[0]&&a<=d[1]:!0}).reduce(function(a,b,c,d){var e;return e=c>0?Math.max(b-d[c-1],0):Number.MAX_VALUE,a>e?e:a},Number.MAX_VALUE)}))},getBestColumnWidth:function(a,b,c,d){var e,f,g,h,i,j,k;return c&&0!==c.length?0===c.filter(function(a){return"column"===a.type}).length?10:(k=this.getPseudoColumns(c,d),j=k.pseudoColumns,h=k.keys,g=b.width-b.left-b.right,e=c.filter(function(a){return j.hasOwnProperty(a.id)}),f=this.getMinDelta(e,"x",a.xScale,[0,g]),f>g&&(f=.25*g),i=h.length,d.columnsHGap0))return[g];for(m=c.width-c.right-c.left,d=0,j=[],f=k.length-1;f>=0;)j.push(m-d-k[f]),d+=k[f]+i,f--;return j.reverse(),[g,j]},getLegendItemsWidths:function(a,b){var c,d,e,f,g;if(f=this,c=function(a){return f.getTextBBox(a).width},e=a.selectAll(".legendItem."+b),!(e.length>0))return[];for(g=[],d=0;dA;h=++A)f=t[h],u=b.xScale(f.x),x=b.yScale(f.y),("undefined"==typeof n||null===n||n>u)&&(n=u,o=f.x),("undefined"==typeof j||null===j||u>j)&&(j=u,k=f.x),("undefined"==typeof p||null===p||p>x)&&(p=x),("undefined"==typeof l||null===l||x>l)&&(l=x),("undefined"==typeof q||null===q||f.ym)&&(m=f.y);return v=(r[0]-n)/(j-n),y=(r[1]-p)/(l-p),w=Math.round(v*(k-o)+o),z=Math.round((1-y)*(m-q)+q),i={x:w,y:z},"function"==typeof e.onMouseOver?e.onMouseOver(a,{series:c,x:r[0],y:r[1],datum:i},d.axes):void 0},h.on("mousemove",g).on("mouseout",function(b){return"function"==typeof e.onMouseOut?e.onMouseOut(a):void 0})),this},createLeftLineDrawer:function(a,b,c){return d3.svg.line().x(function(b){return a.xScale(b.x)}).y(function(b){return a.yScale(b.y+b.y0)}).interpolate(b).tension(c)},createRightLineDrawer:function(a,b,c){return d3.svg.line().x(function(b){return a.xScale(b.x)}).y(function(b){return a.y2Scale(b.y+b.y0)}).interpolate(b).tension(c)},getPixelCssProp:function(b,c){var d;return d=a.getComputedStyle(b,null).getPropertyValue(c),+d.replace(/px$/,"")},getDefaultMargins:function(){return{top:20,right:50,bottom:60,left:50}},getDefaultThumbnailMargins:function(){return{top:1,right:1,bottom:2,left:0}},getElementDimensions:function(a,b,c){var d,e,f,g,h,i;return e={},g=a,i=this.getPixelCssProp(g,"padding-top"),d=this.getPixelCssProp(g,"padding-bottom"),f=this.getPixelCssProp(g,"padding-left"),h=this.getPixelCssProp(g,"padding-right"),e.width=+(b||g.offsetWidth||900)-f-h,e.height=+(c||g.offsetHeight||500)-i-d,e},getDimensions:function(a,b,c){var d;return d=this.getElementDimensions(b[0].parentElement,c.width,c.height),d=angular.extend(a.margin,d)},clean:function(a){return d3.select(a).on("keydown",null).on("keyup",null).select("svg").remove()},uuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b,c;return b=16*Math.random()|0,c="x"===a?b:3&b|8,c.toString(16)})},bootstrap:function(a,b,c){var d,e,f,g;return d3.select(a).classed("chart",!0),g=c.width,e=c.height,f=d3.select(a).append("svg").attr({width:g,height:e}).append("g").attr("transform","translate("+c.left+","+c.top+")"),d=f.append("defs").attr("class","patterns"),d.append("clipPath").attr("class","content-clip").attr("id","content-clip-"+b).append("rect").attr({x:0,y:0,width:g-c.left-c.right,height:e-c.top-c.bottom}),f},createContent:function(a,b,c){var d;return d=a.append("g").attr("class","content"),c.hideOverflow?d.attr("clip-path","url(#content-clip-"+b+")"):void 0},createZoomResetIcon:function(a,b,c,d,e,f,g,h,i){var j,k,l,m,n,o,p;return o=this,m="M22.646,19.307c0.96-1.583,1.523-3.435,1.524-5.421C24.169,8.093,19.478,3.401,13.688,3.399C7.897,3.401,3.204,8.093,3.204,13.885c0,5.789,4.693,10.481,10.484,10.481c1.987,0,3.839-0.563,5.422-1.523l7.128,7.127l3.535-3.537L22.646,19.307zM13.688,20.369c-3.582-0.008-6.478-2.904-6.484-6.484c0.006-3.582,2.903-6.478,6.484-6.486c3.579,0.008,6.478,2.904,6.484,6.486C20.165,17.465,17.267,20.361,13.688,20.369zM8.854,11.884v4.001l9.665-0.001v-3.999L8.854,11.884z",k=a.select(".focus-container").selectAll(".icon.zoom-reset").data([1]),j=k.enter().append("g").attr("class","icon zoom-reset").on("click",function(){return o.resetZoom(a,b,c,d,e,f,g,h,i),d3.select(this).remove()}).on("mouseenter",function(){return d3.select(this).style("fill","steelblue")}).on("mouseout",function(){return d3.select(this).style("fill","black")}),j.append("path").attr("d",m),l=b.width-b.left-b.right-24,p=2,n=.7,k.style({fill:"black",stroke:"white","stroke-width":1.5}).attr({opacity:1,transform:"translate("+l+", "+p+") scale("+n+")"})},createFocus:function(a,b,c){var d;return d=a.append("g").attr({"class":"focus-container"})},createGlass:function(a,b,c,d,e,f,g,h){var i,j,k;return k=this,i=a.append("g").attr({"class":"glass-container",opacity:0}),j=i.selectAll(".scrubberItem").data(e).enter().append("g").attr("class",function(a,b){return"scrubberItem series_"+b}),j.each(function(a,b){var c,d,e;return e=d3.select(this),c=e.append("g").attr({"class":"rightTT"}),c.append("path").attr({"class":"scrubberPath series_"+b,y:"-7px",fill:a.color}),k.styleTooltip(c.append("text").style("text-anchor","start").attr({"class":function(a,b){return"scrubberText series_"+b},height:"14px",transform:"translate(7, 3)","text-rendering":"geometric-precision"})).text(a.label||a.y),d=e.append("g").attr({"class":"leftTT"}),d.append("path").attr({"class":"scrubberPath series_"+b,y:"-7px",fill:a.color}),k.styleTooltip(d.append("text").style("text-anchor","end").attr({"class":"scrubberText series_"+b,height:"14px",transform:"translate(-13, 3)","text-rendering":"geometric-precision"})).text(a.label||a.y),e.append("circle").attr({"class":"scrubberDot series_"+b,fill:"white",stroke:a.color,"stroke-width":"2px",r:4})}),i.append("rect").attr({"class":"glass",width:b.width-b.left-b.right,height:b.height-b.top-b.bottom}).style("fill","white").style("fill-opacity",1e-6).on("mouseover",function(){return c.onChartHover(a,d3.select(this),d,e,f,g,h)})},drawData:function(a,b,c,d,e,f,g,h){return this.drawArea(a,c,d,f,g).drawColumns(a,c,d,e,f,g,h).drawLines(a,c,d,f,g),f.drawDots?this.drawDots(a,c,d,f,g,h):void 0},getDataPerSeries:function(a,b){var c,d,e,f;return e=b.series,c=b.axes,e&&e.length&&a&&a.length?(f=e.map(function(c,d){var e;return e={index:d,name:c.y,values:[],color:c.color,axis:c.axis||"y",xOffset:0,type:c.type,thickness:c.thickness,drawDots:c.drawDots!==!1},null!=c.dotSize&&(e.dotSize=c.dotSize),c.striped===!0&&(e.striped=!0),null!=c.lineMode&&(e.lineMode=c.lineMode),c.id&&(e.id=c.id),a.filter(function(a){return null!=a[c.y]}).forEach(function(a){var d;return d={x:a[b.axes.x.key],y:a[c.y],y0:0,axis:c.axis||"y"},null!=c.dotSize&&(d.dotSize=c.dotSize),e.values.push(d)}),e}),null==b.stacks||0===b.stacks.length?f:(d=d3.layout.stack().values(function(a){return a.values}),b.stacks.forEach(function(a){var b;if(a.series.length>0)return b=f.filter(function(a,b){return void 0===e[b].visible||e[b].visible}).filter(function(b,c){var d;return null!=b.id&&(d=b.id,__indexOf.call(a.series,d)>=0)}),d(b)}),f)):[]},estimateSideTooltipWidth:function(a,b){var c,d;return d=a.append("text"),d.text(""+b),this.styleTooltip(d),c=this.getTextBBox(d[0][0]),d.remove(),c},getTextBBox:function(a){var b;if(null!==a)try{return a.getBBox()}catch(c){return b=c,{height:0,width:0,y:0,x:0}}return{}},getWidestTickWidth:function(a,b){var c,d,e,f;return d=0,c=this.getTextBBox,e=a.select("."+b+".axis").selectAll(".tick"),null!=(f=e[0])&&f.forEach(function(a){return d=Math.max(d,c(a).width)}),d},getWidestOrdinate:function(a,b,c){var d;return d="",a.forEach(function(a){return b.forEach(function(b){var e,f;return e=a[b.y],null!=b.axis&&(null!=(f=c.axes[b.axis])?f.ticksFormatter:void 0)&&(e=c.axes[b.axis].ticksFormatter(e)),null!=e&&(""+e).length>(""+d).length?d=e:void 0})}),d},getDefaultOptions:function(){return{tooltip:{mode:"scrubber"},lineMode:"linear",tension:.7,margin:this.getDefaultMargins(),axes:{x:{type:"linear",key:"x"},y:{type:"linear"}},series:[],drawLegend:!0,drawDots:!0,stacks:[],columnsHGap:5,hideOverflow:!1}},sanitizeOptions:function(a,b){var c;return null==a&&(a={}),"thumbnail"===b&&(a.drawLegend=!1,a.drawDots=!1,a.tooltip={mode:"none",interpolate:!1}),a.series=this.sanitizeSeriesOptions(a.series),a.stacks=this.sanitizeSeriesStacks(a.stacks,a.series),a.axes=this.sanitizeAxes(a.axes,this.haveSecondYAxis(a.series)),a.tooltip=this.sanitizeTooltip(a.tooltip),a.margin=this.sanitizeMargins(a.margin),a.lineMode||(a.lineMode=this.getDefaultOptions().lineMode),a.tension=/^\d+(\.\d+)?$/.test(a.tension)?a.tension:this.getDefaultOptions().tension,a.drawLegend=a.drawLegend!==!1,a.drawDots=a.drawDots!==!1,angular.isNumber(a.columnsHGap)||(a.columnsHGap=5),a.hideOverflow=a.hideOverflow||!1,c="thumbnail"===b?this.getDefaultThumbnailMargins():this.getDefaultMargins(),a.series=angular.extend(this.getDefaultOptions().series,a.series),a.axes=angular.extend(this.getDefaultOptions().axes,a.axes),a.tooltip=angular.extend(this.getDefaultOptions().tooltip,a.tooltip),a.margin=angular.extend(c,a.margin),a},sanitizeMargins:function(a){var b,c,d,e;b=["top","right","bottom","left"],c={};for(d in a)e=a[d],__indexOf.call(b,d)>=0&&(c[d]=parseFloat(e));return c},sanitizeSeriesStacks:function(a,c){var d;return null==a?[]:(d={},c.forEach(function(a){return d[a.id]=a}),a.forEach(function(a){return a.series.forEach(function(c){var e;if(e=d[c],null!=e){if(e.axis!==a.axis)return b.warn("Series "+c+" is not on the same axis as its stack")}else if(!e)return b.warn("Unknown series found in stack : "+c)})}),a)},sanitizeTooltip:function(a){var b;if(!a)return{mode:"scrubber"};if("none"!==(b=a.mode)&&"axes"!==b&&"scrubber"!==b&&(a.mode="scrubber"),"scrubber"===a.mode?delete a.interpolate:a.interpolate=!!a.interpolate,"scrubber"===a.mode&&a.interpolate)throw new Error("Interpolation is not supported for scrubber tooltip mode.");return a},sanitizeSeriesOptions:function(a){var b,c;return null==a?[]:(b=d3.scale.category10(),c={},a.forEach(function(a,b){if(null!=c[a.id])throw new Error("Twice the same ID ("+a.id+") ? Really ?");return null!=a.id?c[a.id]=a:void 0}),a.forEach(function(a,d){var e,f,g,h,i;if(a.axis="y2"!==(null!=(f=a.axis)?f.toLowerCase():void 0)?"y":"y2",a.color||(a.color=b(d)),a.type="line"===(g=a.type)||"area"===g||"column"===g?a.type:"line","column"===a.type?(delete a.thickness,delete a.lineMode,delete a.drawDots,delete a.dotSize):/^\d+px$/.test(a.thickness)||(a.thickness="1px"),("line"===(h=a.type)||"area"===h)&&("dashed"!==(i=a.lineMode)&&delete a.lineMode,a.drawDots!==!1&&null==a.dotSize&&(a.dotSize=2)),null==a.id){for(e=0;null!=c["series_"+e];)e++;a.id="series_"+e,c[a.id]=a}return a.drawDots===!1?delete a.dotSize:void 0}),a)},sanitizeAxes:function(a,b){var c;return null==a&&(a={}),a.x=this.sanitizeAxisOptions(a.x),(c=a.x).key||(c.key="x"),a.y=this.sanitizeAxisOptions(a.y),b&&(a.y2=this.sanitizeAxisOptions(a.y2)),a},sanitizeExtrema:function(a){var c,d,e,f,g,h;for(g=["min","max"],h=[],e=0,f=g.length;f>e;e++)c=g[e],d=a[c],null!=d?(a[c]=this.sanitizeExtremum(c,a),null==a[c]?h.push(b.warn("Invalid "+c+" value '"+d+"' (parsed as "+a[c]+"), ignoring it.")):h.push(void 0)):h.push(void 0);return h},sanitizeExtremum:function(a,b){var c;return c=this.sanitizeNumber,"date"===b.type&&(c=this.sanitizeDate),c(b[a])},sanitizeDate:function(a){return null==a?void 0:a instanceof Date&&!isNaN(a.valueOf())?a:void 0},sanitizeNumber:function(a){var b;return null==a?void 0:(b=parseFloat(a),isNaN(b)?void 0:b)},sanitizeAxisOptions:function(a){return null==a?{type:"linear"}:(a.type||(a.type="linear"),null!=a.ticksRotate&&(a.ticksRotate=this.sanitizeNumber(a.ticksRotate)),null!=a.zoomable&&(a.zoomable=a.zoomable||!1),null!=a.innerTicks&&(a.innerTicks=a.innerTicks||!1),null!=a.labelFunction&&(a.ticksFormatter=a.labelFunction),null!=a.ticksFormat&&("date"===a.type?a.ticksFormatter=d3.time.format(a.ticksFormat):a.ticksFormatter=d3.format(a.ticksFormat),null==a.tooltipFormatter&&(a.tooltipFormatter=a.ticksFormatter)),null!=a.tooltipFormat&&("date"===a.type?a.tooltipFormatter=d3.time.format(a.tooltipFormat):a.tooltipFormatter=d3.format(a.tooltipFormat)),null!=a.ticksInterval&&(a.ticksInterval=this.sanitizeNumber(a.ticksInterval)),this.sanitizeExtrema(a),a)},createAxes:function(a,b,c){var d,e,f,g,h,i,j,k,l,m;return d=null!=c.y2,g=b.width,e=b.height,g=g-b.left-b.right,e=e-b.top-b.bottom,h=void 0,h="date"===c.x.type?d3.time.scale().rangeRound([0,g]):d3.scale.linear().rangeRound([0,g]),i=this.createAxis(h,"x",c),j=void 0,j="log"===c.y.type?d3.scale.log().clamp(!0).rangeRound([e,0]):d3.scale.linear().rangeRound([e,0]),j.clamp(!0),m=this.createAxis(j,"y",c),k=void 0,k=d&&"log"===c.y2.type?d3.scale.log().clamp(!0).rangeRound([e,0]):d3.scale.linear().rangeRound([e,0]),k.clamp(!0),l=this.createAxis(k,"y2",c),f=function(a){return a.style({font:"10px Courier","shape-rendering":"crispEdges"}),a.selectAll("path").style({fill:"none",stroke:"#000"})},{xScale:h,yScale:j,y2Scale:k,xAxis:i,yAxis:m,y2Axis:l,andAddThemIf:function(b){return b.all&&(b.y&&(a.append("g").attr("class","y grid"),a.append("g").attr("class","y axis").call(m).call(f)),d&&b.y2&&(a.append("g").attr("class","y2 grid").attr("transform","translate("+g+", 0)"),a.append("g").attr("class","y2 axis").attr("transform","translate("+g+", 0)").call(l).call(f)),b.x&&(a.append("g").attr("class","x grid").attr("transform","translate(0,"+e+")"),a.append("g").attr("class","x axis").attr("transform","translate(0,"+e+")").call(i).call(f))),{xScale:h,yScale:j,y2Scale:k,xAxis:i,yAxis:m,y2Axis:l}}}},createAxis:function(a,b,c){var d,e,f;return f={x:"bottom",y:"left",y2:"right"},e=c[b],d=d3.svg.axis().scale(a).orient(f[b]).innerTickSize(4).tickFormat(null!=e?e.ticksFormatter:void 0),null==e?d:(angular.isArray(e.ticks)?d.tickValues(e.ticks):angular.isNumber(e.ticks)?d.ticks(e.ticks):angular.isFunction(e.ticks)&&d.ticks(e.ticks,e.ticksInterval),d)},setDefaultStroke:function(a){return a.attr("stroke","#000").attr("stroke-width",1).style("shape-rendering","crispEdges")},setDefaultGrid:function(a){return a.attr("stroke","#eee").attr("stroke-width",1).style("shape-rendering","crispEdges")},setScalesDomain:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n;return this.setXScale(a.xScale,b,c,e.axes),f=d.selectAll(".x.axis").call(a.xAxis),null!=e.axes.x.innerTicks&&f.selectAll(".tick>line").call(this.setDefaultStroke),null!=e.axes.x.grid&&(h=e.margin.height-e.margin.top-e.margin.bottom,j=a.xAxis.tickSize(-h,0,0),g=d.selectAll(".x.grid").call(j),g.selectAll(".tick>line").call(this.setDefaultGrid)),null!=e.axes.x.ticksRotate&&f.selectAll(".tick>text").attr("dy",null).attr("transform","translate(0,5) rotate("+e.axes.x.ticksRotate+" 0,6)").style("text-anchor",e.axes.x.ticksRotate>=0?"start":"end"),c.filter(function(a){return"y"===a.axis&&a.visible!==!1}).length>0&&(m=this.getVerticalDomain(e,b,c,"y"),a.yScale.domain(m).nice(),f=d.selectAll(".y.axis").call(a.yAxis),null!=e.axes.y.innerTicks&&f.selectAll(".tick>line").call(this.setDefaultStroke),null!=e.axes.y.ticksRotate&&f.selectAll(".tick>text").attr("transform","rotate("+e.axes.y.ticksRotate+" -6,0)").style("text-anchor","end"),null!=e.axes.y.grid&&(i=e.margin.width-e.margin.left-e.margin.right,n=a.yAxis.tickSize(-i,0,0),g=d.selectAll(".y.grid").call(n),g.selectAll(".tick>line").call(this.setDefaultGrid))),c.filter(function(a){return"y2"===a.axis&&a.visible!==!1}).length>0&&(k=this.getVerticalDomain(e,b,c,"y2"),a.y2Scale.domain(k).nice(),f=d.selectAll(".y2.axis").call(a.y2Axis),null!=e.axes.y2.innerTicks&&f.selectAll(".tick>line").call(this.setDefaultStroke),null!=e.axes.y2.ticksRotate&&f.selectAll(".tick>text").attr("transform","rotate("+e.axes.y2.ticksRotate+" 6,0)").style("text-anchor","start"),null!=e.axes.y2.grid)?(i=e.margin.width-e.margin.left-e.margin.right,l=a.y2Axis.tickSize(-i,0,0),g=d.selectAll(".y2.grid").call(l),g.selectAll(".tick>line").call(this.setDefaultGrid)):void 0},getVerticalDomain:function(a,b,c,d){var e,f,g;return(g=a.axes[d])?null!=g.ticks&&angular.isArray(g.ticks)?[g.ticks[0],g.ticks[g.ticks.length-1]]:(f=c.filter(function(a){return a.axis===d&&a.visible!==!1}),e=this.yExtent(c.filter(function(a){return a.axis===d&&a.visible!==!1}),b,a.stacks.filter(function(a){return a.axis===d})),"log"===g.type&&(e[0]=0===e[0]?.001:e[0]),null!=g.min&&(e[0]=g.min),null!=g.max&&(e[1]=g.max),e):[]},yExtent:function(a,b,c){var d,e,f;return f=Number.POSITIVE_INFINITY,e=Number.NEGATIVE_INFINITY,d=[],c.forEach(function(b){return d.push(b.series.map(function(b){return a.filter(function(a){return a.id===b})[0]}))}),a.forEach(function(a,b){var e;return e=!1,c.forEach(function(b){var c;return c=a.id,__indexOf.call(b.series,c)>=0?e=!0:void 0}),e?void 0:d.push([a])}),d.forEach(function(a){return a=a.filter(Boolean),f=Math.min(f,d3.min(b,function(b){return a.reduce(function(a,c){return Math.min(a,b[c.y])},Number.POSITIVE_INFINITY)})),e=Math.max(e,d3.max(b,function(b){return a.reduce(function(a,c){return a+b[c.y]},0)}))}),f===e?f>0?[0,2*f]:[2*f,0]:[f,e]},setXScale:function(a,b,c,d){var e,f;return e=this.xExtent(b,d.x.key,d.x.type),c.filter(function(a){return"column"===a.type}).length&&this.adjustXDomainForColumns(e,b,d.x.key),f=d.x,null!=f.min&&(e[0]=f.min),null!=f.max&&(e[1]=f.max),a.domain(e)},xExtent:function(a,b,c){var d,e,f,g;return g=d3.extent(a,function(a){return a[b]}),e=g[0],f=g[1],e===f?"date"===c?(d=864e5,[new Date(+e-d),new Date(+f+d)]):e>0?[0,2*e]:[2*e,0]:[e,f]},adjustXDomainForColumns:function(a,b,c){var d;return d=this.getAverageStep(b,c),angular.isDate(a[0])?(a[0]=new Date(+a[0]-d),a[1]=new Date(+a[1]+d)):(a[0]=a[0]-d,a[1]=a[1]+d)},getAverageStep:function(a,b){var c,d,e;if(!(a.length>1))return 0;for(e=0,d=a.length-1,c=0;d>c;)e+=a[c+1][b]-a[c][b],c++;return e/d},haveSecondYAxis:function(a){return!a.every(function(a){return"y2"!==a.axis})},showScrubber:function(a,b,c,d,e,f,g){var h;return h=this,b.on("mousemove",function(){return a.selectAll(".glass-container").attr("opacity",1),h.updateScrubber(a,d3.mouse(this),c,d,e,f,g)}),b.on("mouseout",function(){return b.on("mousemove",null),a.selectAll(".glass-container").attr("opacity",0)})},getClosestPoint:function(a,b){var c,d,e,f,g;return g=d3.bisector(function(a){return a.x}).left,f=g(a,b),0===f?a[0]:f>a.length-1?a[a.length-1]:(d=a[f-1],e=a[f],c=b-d.x>e.x-b?e:d)},updateScrubber:function(a,b,c,d,e,f,g){var h,i,j,k,l,m;return l=b[0],m=b[1],h=function(a){return a.transition().duration(50)},j=this,i=[],d.forEach(function(b,d){var g,k,n,o,p,q,r,s,t,u,v,w,x;return k=a.select(".scrubberItem.series_"+d),e.series[d].visible===!1?void k.attr("opacity",0):(k.attr("opacity",1),v=c.xScale.invert(l),x=c.yScale.invert(m),u=j.getClosestPoint(b.values,v),f.focus(u,b.values.indexOf(u),[v,x]),t=u.x+" : "+u.y,e.tooltip.formatter&&(t=e.tooltip.formatter(u.x,u.y,e.series[d])),q=k.select(".rightTT"),p=q.select("text"),p.text(t),o=k.select(".leftTT"),n=o.select("text"),n.text(t),s={right:j.getTextBBox(p[0][0]).width+5,left:j.getTextBBox(n[0][0]).width+5},r="y2"===b.axis?"right":"left",w=c.xScale(u.x),"left"===r?w+j.getTextBBox(n[0][0]).x-10<0&&(r="right"):"right"===r&&w+s.right>j.getTextBBox(a.select(".glass")[0][0]).width&&(r="left"),"left"===r?(h(q).attr("opacity",0),h(o).attr("opacity",1)):(h(q).attr("opacity",1),h(o).attr("opacity",0)),i[d]={index:d,x:w,y:c[u.axis+"Scale"](u.y+u.y0),side:r,sizes:s},g=angular.isFunction(b.color)?b.color(u,b.values.indexOf(u)):b.color,k.selectAll("circle").attr("stroke",g),k.selectAll("path").attr("fill",g))}),i=this.preventOverlapping(i),k=Math.max(15,100/g),d.forEach(function(b,c){var d,f,g,l;if(e.series[c].visible!==!1)return f=i[c],d=a.select(".scrubberItem.series_"+c),g=d.select("."+f.side+"TT"),l="left"===f.side?b.xOffset:-b.xOffset,g.select("text").attr("transform",function(){return"left"===f.side?"translate("+(-3-k-l)+", "+(f.labelOffset+3)+")":"translate("+(4+k+l)+", "+(f.labelOffset+3)+")"}), -g.select("path").attr("d",j.getScrubberPath(f.sizes[f.side]+1,f.labelOffset,f.side,k+l)),h(d).attr({transform:"translate("+(i[c].x+b.xOffset)+", "+i[c].y+")"})})},getScrubberPath:function(a,b,c,d){var e,f,g,h;return e=18,f=d,a=a,g="left"===c?1:-1,h=1,0!==b&&(h=Math.abs(b)/b),b||(b=0),["m0 0","l"+g+" 0","l0 "+(b+h),"l"+-g*(f+1)+" 0","l0 "+(-e/2-h),"l"+-g*a+" 0","l0 "+e,"l"+g*a+" 0","l0 "+(-e/2-h),"l"+g*(f-1)+" 0","l0 "+(-b+h),"l1 0","z"].join("")},preventOverlapping:function(a){var b,c,d,e;return d=18,b={},a.forEach(function(a){var c;return b[c=a.x]||(b[c]={left:[],right:[]}),b[a.x][a.side].push(a)}),c=function(a){var c,e,f,g,h,i,j,k,l;f=[];for(j in b)if(i=b[j],0!==i[a].length){for(g={};i[a].length>0;){h=i[a].pop(),c=!1;for(k in g)e=g[k],+k-d<=(l=h.y)&&+k+d>=l&&(e.push(h),c=!0);c||(g[h.y]=[h])}f.push(g)}return f},e=function(a){var b,c,d,e,f,g,h;f=20;for(b in a){g=a[b];for(h in g)d=g[h],c=d.length,1!==c?(d=d.sort(function(a,b){return a.y-b.y}),e=c%2===0?-(f/2)*(c/2):-(c-1)/2*f,d.forEach(function(a,b){return a.labelOffset=e+f*b})):d[0].labelOffset=0}},e(c("left")),e(c("right")),a},getTooltipHandlers:function(a){return"scrubber"===a.tooltip.mode?{onChartHover:angular.bind(this,this.showScrubber)}:{onMouseOver:angular.bind(this,this.onMouseOver),onMouseOut:angular.bind(this,this.onMouseOut)}},styleTooltip:function(a){return a.attr({"font-family":"monospace","font-size":10,fill:"white","text-rendering":"geometric-precision"})},addTooltips:function(a,b,c){var d,e,f,g,h,i,j,k;return h=b.width,e=b.height,h=h-b.left-b.right,e=e-b.top-b.bottom,g=24,d=18,f=5,i=a.append("g").attr({id:"xTooltip","class":"xTooltip",opacity:0}),i.append("path").attr("transform","translate(0,"+(e+1)+")"),this.styleTooltip(i.append("text").style("text-anchor","middle").attr({width:g,height:d,transform:"translate(0,"+(e+19)+")"})),k=a.append("g").attr({id:"yTooltip","class":"yTooltip",opacity:0}),k.append("path"),this.styleTooltip(k.append("text").attr({width:d,height:g})),null!=c.y2?(j=a.append("g").attr({id:"y2Tooltip","class":"y2Tooltip",opacity:0,transform:"translate("+h+",0)"}),j.append("path"),this.styleTooltip(j.append("text").attr({width:d,height:g}))):void 0},onMouseOver:function(a,b,c){return this.updateXTooltip(a,b,c.x),"y2"===b.series.axis?this.updateY2Tooltip(a,b,c.y2):this.updateYTooltip(a,b,c.y)},onMouseOut:function(a){return this.hideTooltips(a)},updateXTooltip:function(a,b,c){var d,e,f,g,h,i,j,k;return i=b.x,e=b.datum,g=b.series,j=a.select("#xTooltip"),j.transition().attr({opacity:1,transform:"translate("+i+",0)"}),k=c.tooltipFormatter,h=k?k(e.x):e.x,f=j.select("text"),f.text(h),d=angular.isFunction(g.color)?g.color(e,g.values.indexOf(e)):g.color,j.select("path").style("fill",d).attr("d",this.getXTooltipPath(f[0][0]))},getXTooltipPath:function(a){var b,c,d;return d=Math.max(this.getTextBBox(a).width,15),b=18,c=5,"m-"+d/2+" "+c+" l0 "+b+" l"+d+" 0 l0 "+-b+"l"+(-d/2+c)+" 0 l"+-c+" -"+b/4+" l"+-c+" "+b/4+" l"+(-d/2+c)+" 0z"},updateYTooltip:function(a,b,c){var d,e,f,g,h,i,j,k,l;return j=b.y,e=b.datum,g=b.series,k=a.select("#yTooltip"),k.transition().attr({opacity:1,transform:"translate(0, "+j+")"}),l=c.tooltipFormatter,h=l?l(e.y):e.y,f=k.select("text"),f.text(h),i=this.getTextBBox(f[0][0]).width+5,f.attr({transform:"translate("+(-i-2)+",3)",width:i}),d=angular.isFunction(g.color)?g.color(e,g.values.indexOf(e)):g.color,k.select("path").style("fill",d).attr("d",this.getYTooltipPath(i))},updateY2Tooltip:function(a,b,c){var d,e,f,g,h,i,j,k,l;return j=b.y,e=b.datum,g=b.series,k=a.select("#y2Tooltip"),k.transition().attr("opacity",1),l=c.tooltipFormatter,h=l?l(e.y):e.y,f=k.select("text"),f.text(h),i=this.getTextBBox(f[0][0]).width+5,f.attr({transform:"translate(7, "+(parseFloat(j)+3)+")",w:i}),d=angular.isFunction(g.color)?g.color(e,g.values.indexOf(e)):g.color,k.select("path").style("fill",d).attr({d:this.getY2TooltipPath(i),transform:"translate(0, "+j+")"})},getYTooltipPath:function(a){var b,c;return b=18,c=5,"m0 0l"+-c+" "+-c+" l0 "+(-b/2+c)+" l"+-a+" 0 l0 "+b+" l"+a+" 0 l0 "+(-b/2+c)+"l"+-c+" "+c+"z"},getY2TooltipPath:function(a){var b,c;return b=18,c=5,"m0 0l"+c+" "+c+" l0 "+(b/2-c)+" l"+a+" 0 l0 "+-b+" l"+-a+" 0 l0 "+(b/2-c)+" l"+-c+" "+c+"z"},hideTooltips:function(a){return a.select("#xTooltip").transition().attr("opacity",0),a.select("#yTooltip").transition().attr("opacity",0),a.select("#y2Tooltip").transition().attr("opacity",0)}}}]),angular.module("kbWebApp",["ngAnimate","ngCookies","ngResource","ngRoute","ngSanitize","ngTouch","ngTable","ui.bootstrap","angular-loading-bar","n3-line-chart"]).config(["$routeProvider",function(a){a.when("/About",{templateUrl:"views/about.html",controller:"AboutCtrl",controllerAs:"about"}).when("/Config",{templateUrl:"views/config.html",controller:"ConfigCtrl",controllerAs:"config"}).when("/InteractiveMode",{templateUrl:"views/run.html",controller:"RunCtrl",controllerAs:"run"}).when("/MonitoringMode",{templateUrl:"views/interval.html",controller:"IntervalCtrl",controllerAs:"interval"}).when("/Log",{templateUrl:"views/log.html",controller:"LogCtrl",controllerAs:"log"}).when("/Login",{templateUrl:"views/login.html",controller:"LoginCtrl",controllerAs:"login"}).otherwise({redirectTo:"/InteractiveMode"})}]).config(["cfpLoadingBarProvider",function(a){a.latencyThreshold=1}]),angular.module("kbWebApp").controller("AboutCtrl",["$scope","$http","$location","kbHttp","kbCookie","locationChange",function(a,b,c,d,e,f){this.awesomeThings=["HTML5 Boilerplate","AngularJS","Karma"],$(window).on("hashchange",f.change()),d.getMethod("/kloudbuster/version").then(function(b){a.version=b.data},function(a){console.log("get version error:"),console.log(a)})}]).service("locationChange",function(){function a(a){$("#"+a).addClass("active")}function b(){$("#scaletestnav").removeClass("active"),$("#interactivenav").removeClass("active"),$("#monitoringnav").removeClass("active"),$("#confignav").removeClass("active"),$("#lognav").removeClass("active"),$("#loginnav").removeClass("active"),$("#aboutnav").removeClass("active")}var c;this.change=function(){switch(c=$(location).attr("hash"),b(),$("#scaletestname").text("Scale Test"),$("#loginname").text("Log Out"),c){case"#/InteractiveMode":a("scaletestnav"),a("interactivenav"),$("#scaletestname").text("Interactive Mode");break;case"#/MonitoringMode":a("scaletestnav"),a("monitoringnav"),$("#scaletestname").text("Monitoring Mode");break;case"#/Config":a("confignav");break;case"#/Log":a("lognav");break;case"#/Login":a("loginnav"),$("#loginname").text("Log In");break;case"#/About":a("aboutnav")}}}).service("kbHttp",["$http","$q",function(a,b){var c=$(location).attr("protocol")+"//"+$(location).attr("host")+"/api";this.getMethod=function(d){var e=b.defer();return a.get(c+d).then(function(a){e.resolve(a)},function(a){e.reject(a)}),e.promise},this.getMethod2=function(d){var e=b.defer();return a.get(c+d,{ignoreLoadingBar:!0}).then(function(a){e.resolve(a)},function(a){e.reject(a)}),e.promise},this.putMethod=function(d,e){var f=b.defer();return a.defaults.headers.put["Content-Type"]="application/x-www-form-urlencoded;charset=utf-8",a.put(c+d,"arg="+encodeURIComponent(JSON.stringify(e))).then(function(a){f.resolve(a)},function(a){f.reject(a)}),f.promise},this.postMethod=function(d,e){var f=b.defer();return e?(a.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded;charset=utf-8",a.post(c+d,"arg="+encodeURIComponent(JSON.stringify(e))).then(function(a){f.resolve(a)},function(a){f.reject(a)}),f.promise):(a.post(c+d).then(function(a){f.resolve(a)},function(a){f.reject(a)}),f.promise)},this.delMethod=function(d){var e=b.defer();return a["delete"](c+d).then(function(a){e.resolve(a)},function(a){e.reject(a)}),e.promise}}]).service("kbCookie",function(){this.init=function(){a="",b="",c="",d="",f="",g=0,e="",f="",g=0};var a="";this.getSessionID=function(){return a},this.setSessionID=function(b){return a=b};var b="";this.getStatus=function(){return b},this.setStatus=function(a){return b=a};var c="";this.getConfig=function(){return c},this.setConfig=function(a){return c=a};var d="";this.getCredentials=function(){return d},this.setCredentials=function(a){return d=a};var e="";this.getIsOneCloud=function(){return e},this.setIsOneCloud=function(a){return e=a};var f="";this.getTopology=function(){return f},this.setTopology=function(a){return f=a};var g=0;this.getLogOffset=function(){return g},this.setLogOffset=function(a){return g=a}}),angular.module("kbWebApp").controller("ConfigCtrl",["$scope","$http","$location","kbHttp","kbCookie","locationChange",function(a,b,c,d,e,f){function g(){a.selectedA=[],a.selectedB=[],a.selectedC=[],k=[],a.listA=[],a.listB=[],a.listC=[],a.toggle=!1}function h(a,b,c){for(var d=0,e=a.length;e>d;d++)if(a[d][c]===b)return d;return-1}function i(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1}function j(){a.selectedA=[],a.selectedB=[],a.selectedC=[],a.toggle=!1}this.awesomeThings=["HTML5 Boilerplate","AngularJS","Karma"],""===e.getSessionID()&&c.path("/Login"),$(window).on("hashchange",f.change()),a.sessionID=e.getSessionID(),a.status=e.getStatus(),a.dashstatus1="active",a.dashstatus1vis=!0,a.dashstatus2="",a.dashstatus2vis=!1,a.dashstatus3="",a.dashstatus3vis=!1,a.setDashStatus=function(b){1===b?(a.dashstatus2="",a.dashstatus2vis=!1,a.dashstatus3="",a.dashstatus3vis=!1,a.dashstatus1="active",a.dashstatus1vis=!0):2===b?(a.dashstatus1="",a.dashstatus1vis=!1,a.dashstatus3="",a.dashstatus3vis=!1,a.dashstatus2="active",a.dashstatus2vis=!0):3===b&&(a.dashstatus1="",a.dashstatus1vis=!1,a.dashstatus2="",a.dashstatus2vis=!1,a.dashstatus3="active",a.dashstatus3vis=!0)};var k;a.setUserData=function(b){var c,d=1;for(c in b)k.push({id:d++,firstName:b[c]});a.listA=k.slice(0,k.length),a.items=k},g(),a.aToB=function(){for(var b in a.selectedA){var c=h(a.items,a.selectedA[b],"id");a.listB.push(a.items[c]);var d=h(a.listA,a.selectedA[b],"id");a.listA.splice(d,1)}j()},a.aToC=function(){for(var b in a.selectedA){var c=h(a.items,a.selectedA[b],"id");a.listC.push(a.items[c]);var d=h(a.listA,a.selectedA[b],"id");a.listA.splice(d,1)}j()},a.bToA=function(){for(var b in a.selectedB){var c=h(a.items,a.selectedB[b],"id");a.listA.push(a.items[c]);var d=h(a.listB,a.selectedB[b],"id");a.listB.splice(d,1)}j()},a.cToA=function(){for(var b in a.selectedC){var c=h(a.items,a.selectedC[b],"id");a.listA.push(a.items[c]);var d=h(a.listC,a.selectedC[b],"id");a.listC.splice(d,1)}j()},a.toggleA=function(){if(a.selectedA.length>0)j();else for(var b in a.listA)a.selectedB=[],a.selectedC=[],a.selectedA.push(a.listA[b].id)},a.toggleB=function(){if(a.selectedB.length>0)j();else for(var b in a.listB)a.selectedA=[],a.selectedC=[],a.selectedB.push(a.listB[b].id)},a.toggleC=function(){if(a.selectedC.length>0)j();else for(var b in a.listC)a.selectedA=[],a.selectedB=[],a.selectedC.push(a.listC[b].id)},a.selectA=function(b){var c=i(a.selectedA,b);-1===c?a.selectedA.push(b):a.selectedA.splice(c,1)},a.selectB=function(b){var c=i(a.selectedB,b);-1===c?a.selectedB.push(b):a.selectedB.splice(c,1)},a.selectC=function(b){var c=i(a.selectedC,b);-1===c?a.selectedC.push(b):a.selectedC.splice(c,1)},a.checkStatus=function(){a.sessionID?d.getMethod2("/kloudbuster/status/"+a.sessionID).then(function(b){a.status=b.data.status,e.setStatus(a.status),a.configStatus()},function(a){console.log("get status error:"),console.log(a)}):(a.status="NO SESSION ID",e.setStatus(""))},a.checkStatus();var l=!1;a.disableConfig=function(a){$("#"+a).find("input").each(function(){$(this).attr("disabled","disabled")})},a.enableConfig=function(a){$("#"+a).find("input").each(function(){$(this).removeAttr("disabled")})},a.configStatus=function(){"READY"===a.status?l===!0&&(l=!1,a.enableConfig("stagingConfig2"),a.enableConfig("getButton")):l===!1&&(l=!0,a.disableConfig("stagingConfig2"),a.disableConfig("getButton")),e.getIsOneCloud()===!1&&a.disableConfig("topology")},a.getTopology=function(){d.getMethod("/config/hypervisor_list/"+a.sessionID).then(function(b){a.setUserData(b.data.server),console.log("get hypervisor list")},function(a){console.log("get hypervisor list error:"),console.log(a)})},a.getDefaultConfig=function(){d.getMethod("/config/default_config").then(function(b){e.setConfig(b.data),a.config=b.data,console.log("get & save default config")},function(a){console.log("get default config error:"),console.log(a)}),a.getTopology(),e.setTopology(""),a.availability_zone=1,k=[],g()},a.getRunConfig=function(){a.availability_zone=1,d.getMethod("/config/running_config/"+a.sessionID).then(function(b){e.setConfig(b.data),a.config=b.data,(null!=a.config.server.availability_zone&&""!=a.config.server.availability_zone||null!=a.config.client.availability_zone&&""!=a.client.server.availability_zone)&&(a.availability_zone=2),console.log("get & save running config")},function(a){console.log("get running config error:"),console.log(a)}),g(),a.getTopology(),d.getMethod("/config/topology_config/"+a.sessionID).then(function(b){if("null"!=b.data&&(0!=b.data.servers_rack.length||0!=b.data.clients_rack.length)){a.availability_zone=3,a.topology={servers_rack:b.data.servers_rack,clients_rack:b.data.clients_rack},e.setTopology(a.topology),console.log(b.data);for(var c in a.topology.servers_rack){var d=h(a.items,a.topology.servers_rack[c],"firstName");a.listC.push(a.items[d]);var f=h(a.listA,a.topology.servers_rack[c],"firstName");a.listA.splice(f,1)}for(var c in a.topology.clients_rack){var d=h(a.items,a.topology.clients_rack[c],"firstName");a.listB.push(a.items[d]);var f=h(a.listA,a.topology.clients_rack[c],"firstName");a.listA.splice(f,1)}}console.log("get & save topology config")},function(a){console.log("get topology config error:"),console.log(a)})},a.getRunConfig(),a.changeConfig=function(){if("READY"===a.status||""===a.status){if(e.setConfig(a.config),3==a.availability_zone){a.topology={servers_rack:[],clients_rack:[]};for(var b in a.listC)a.topology.servers_rack.push(a.listC[b].firstName);for(var b in a.listB)a.topology.clients_rack.push(a.listB[b].firstName);e.setTopology(a.topology),console.log(a.topology)}else e.setTopology({servers_rack:"",clients_rack:""});a.chaCon={kb_cfg:{},topo_cfg:{}},a.chaCon.kb_cfg=e.getConfig(),a.chaCon.topo_cfg=e.getTopology(),console.log(a.chaCon),d.putMethod("/config/running_config/"+a.sessionID,a.chaCon).then(function(a){console.log("change running config")},function(a){console.log("change running config error:"),console.log(a)})}else console.log("config not allow to change now!")},a.changeTopology=function(){1==a.availability_zone?(a.config.server.availability_zone="",a.config.client.availability_zone="",a.topology={},e.setTopology({servers_rack:"",clients_rack:""}),g(),a.getTopology()):2==a.availability_zone?(a.topology={},e.setTopology({servers_rack:"",clients_rack:""}),g(),a.getTopology()):3==a.availability_zone&&(a.config.server.availability_zone="",a.config.client.availability_zone="")}}]),angular.module("kbWebApp").controller("RunCtrl",["$scope","$timeout","$location","$http","$q","ngTableParams","kbCookie","kbHttp","interactiveMode","color","locationChange",function(a,b,c,d,e,f,g,h,i,j,k){function l(a,b){var c=document.createElement("a"),d=new Blob([b]),e=document.createEvent("HTMLEvents");e.initEvent("click",!1,!1),c.download=a,c.href=URL.createObjectURL(d),c.dispatchEvent(e)}this.awesomeThings=["HTML5 Boilerplate","AngularJS","Karma"],""===g.getSessionID()&&c.path("/Login"),$(window).on("hashchange",k.change()),$("[data-toggle='.container']").click(function(){var a=$(this).data("toggle");$(a).toggleClass("open-sidebar"),$("#littleglyph").toggleClass("glyphicon-triangle-right"),$("#littleglyph").toggleClass("glyphicon-triangle-left")}),$(".swipe-area").swipe({swipeStatus:function(a,b,c,d,e,f){return"move"==b&&"right"==c?($(".container").addClass("open-sidebar"),!1):"move"==b&&"left"==c?($(".container").removeClass("open-sidebar"),!1):void 0}}),a.oneAtATime=!0,a.status1={isFirstOpen:!0,isFirstDisabled:!1},a.status2={isFirstOpen:!0,isFirstDisabled:!1},a.status3={isFirstOpen:!0,isFirstDisabled:!1},a.status1.open=!1,a.status2.open=!0,a.status3.open=!1,a.alerts=[],a.closeAlert=function(b){a.alerts.splice(b,1)},a.sessionID=g.getSessionID(),a.status=g.getStatus(),a.config=g.getConfig(),a.getRunConfig=function(){h.getMethod("/config/running_config/"+a.sessionID).then(function(b){a.config=b.data,g.setConfig(b.data),console.log("get & save config")},function(a){console.log("get running config error:"),console.log(a)})},a.sessionID&&!a.config&&a.getRunConfig(),a.setConfig=function(){var b=e.defer();return"READY"===a.status?(g.setConfig(a.config),a.chaCon={kb_cfg:{}},a.chaCon.kb_cfg=g.getConfig(),console.log(a.chaCon),h.putMethod("/config/running_config/"+a.sessionID,a.chaCon).then(function(a){console.log("change running config"),b.resolve(1)},function(a){console.log("change running config error:"),console.log(a),b.reject(0)})):"STAGED"===a.status?(a.config.client.http_tool_configs.report_interval=0,g.setConfig(a.config),a.chaCon={kb_cfg:{client:{http_tool_configs:{duration:a.config.client.http_tool_configs.duration,rate_limit:a.config.client.http_tool_configs.rate_limit,connections:a.config.client.http_tool_configs.connections,report_interval:0}}}},console.log(a.chaCon),h.putMethod("/config/running_config/"+a.sessionID,a.chaCon).then(function(a){console.log("change running config"),b.resolve(1)},function(a){console.log("change running config error:"),console.log(a),b.reject(0)})):(console.log("config not allow to change now!"),b.reject(0)),b.promise};var m=!1,n=!1;a.disableConfig=function(a){$("#"+a).find("input").each(function(){$(this).attr("disabled","disabled")})},a.enableConfig=function(a){$("#"+a).find("input").each(function(){$(this).removeAttr("disabled")})},a.configStatus=function(){"READY"===a.status?(m===!0&&(m=!1,a.enableConfig("stagingConfig"),a.enableConfig("stagingConfig1")),n===!0&&(n=!1,a.enableConfig("runningConfig"))):"STAGED"===a.status?(m===!1&&(m=!0,a.disableConfig("stagingConfig"),a.disableConfig("stagingConfig1")),n===!0&&(n=!1,a.enableConfig("runningConfig"))):(m===!1&&(m=!0,a.disableConfig("stagingConfig"),a.disableConfig("stagingConfig1")),n===!1&&(n=!0,a.disableConfig("runningConfig")))};var o=0;a.pointNum=function(){var a=".";o=(o+1)%6;for(var b=0;o>b;b++)a+=" .";return a},a.runButton="Run Test",a.runStatus=!0,a.setStatus=!1,a.setUnstage=!0,a.client_vm_count=0,a.server_vm_count=0,a.checkStatus=function(){a.sessionID?h.getMethod2("/kloudbuster/status/"+a.sessionID).then(function(b){a.status=b.data.status,g.setStatus(a.status),a.configStatus(),"READY"===a.status?(a.runButton="Create VMs",a.runStatus=!1,a.setStatus=!1,a.setUnstage=!0,a.client_vm_count=0,a.server_vm_count=0,$(".loading").addClass("pause"),a.info=""):"STAGING"===a.status?(a.runButton="Run Test",a.runStatus=!0,a.setStatus=!0,a.setUnstage=!0,a.client_vm_count=b.data.client_vm_count,a.server_vm_count=b.data.server_vm_count,$(".loading").removeClass("pause"),a.info="KloudBuster is Creating VM(s)"+a.pointNum()):"STAGED"===a.status?(a.runButton="Run Test",a.runStatus=!1,a.setStatus=!1,a.setUnstage=!1,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,a.getReport(),$(".loading").addClass("pause"),a.info=""):"RUNNING"===a.status?(a.runButton="Stop Test",a.runStatus=!1,a.setStatus=!0,a.setUnstage=!0,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,a.config.client.progression.enabled===!0&&a.getReport(),$(".loading").removeClass("pause"),a.info="KloudBuster is Running"+a.pointNum()):"ERROR"===a.status?(a.runButton="Run Test",a.runStatus=!0,a.setStatus=!0,a.setUnstage=!1,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,$(".loading").addClass("pause"),a.info=""):("CLEANING"===a.status||"STOPPING"===a.status)&&(a.runButton="Run Test",a.runStatus=!0,a.setStatus=!0,a.setUnstage=!0,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,$(".loading").removeClass("pause"),a.info="Please Wait"+a.pointNum())},function(a){console.log("get status error:"),console.log(a)}):(a.status="NO SESSION ID",g.setStatus(""))},a.checkStatus(),a.setStage=function(){h.postMethod("/kloudbuster/stage/"+a.sessionID).then(function(b){a.checkStatus()},function(a){console.log("set stage error:"),console.log(a)})},a.runKb=function(){h.postMethod("/kloudbuster/run_test/"+a.sessionID).then(function(b){a.checkStatus()},function(a){console.log("running error:"),console.log(a)})},a.stopKb=function(){h.postMethod("/kloudbuster/stop_test/"+a.sessionID).then(function(b){a.checkStatus()},function(a){console.log("stop error:"),console.log(a)})},a.scaleTest=function(){if("RUNNING"===a.status)a.stopKb();else{var b=a.setConfig();b.then(function(){"READY"===a.status?a.setStage():"STAGED"===a.status&&(a.initChart(),a.runKb())})}},a.CleanUp=function(){a.initChart(),a.sessionID?h.postMethod("/kloudbuster/cleanup/"+a.sessionID).then(function(b){a.checkStatus(),console.log("clean up successfully")},function(a){console.log("clean error:"),console.log(a)}):console.log("no sessionID")},a.tabledata=[],a.cols=[{field:"seq",title:"SEQ",sortable:"seq",show:!0},{field:"connection",title:"Connection",sortable:"connection",show:!0},{field:"server_vms",title:"Server VMs",sortable:"server_vms",show:!0},{field:"requests",title:"Requests",sortable:"requests",show:!0},{field:"sock_err",title:"Error",sortable:"sock_err",show:!0},{field:"rps",title:"RPS measured",sortable:"rps",show:!0},{field:"rate_limit",title:"RPS requested",sortable:"rate_limit",show:!0},{field:"throughput",title:"Throughput",sortable:"throughput",show:!0},{field:"action",title:"Action",sortable:"action",show:!0}],a.tableParams=new f({sorting:{name:"asc"},count:10},{counts:[],data:a.tabledata}),a.options={axes:{x:{key:"x",type:"linear",ticksFormatter:function(a){return 0===a?"50%":10===a?"75%":20===a?"90%":30===a?"99%":40===a?"99.9%":50===a?"99.99%":60===a?"99.999%":void 0}},y:{type:"log",ticksFormat:"d",innerTicks:!0,grid:!0}},tooltip:{mode:"scrubber",formatter:function(a,b,c){return c.label+":"+b}},tension:.8,lineMode:"cardinal",series:[{}]},a.initChart=function(){a.data=[{x:0},{x:10},{x:20},{x:30},{x:40},{x:50},{x:60}],a.options.series=[{}],a.isDely=!1,a.tabledata.length=0,a.tableParams.reload(),a.isDely=!1,p=0,j.reset()};var p=0;a.initChart(),a.refreshChart=function(){a.data=[{x:0},{x:10},{x:20},{x:30},{x:40},{x:50},{x:60}],a.options.series=[{}],a.isDely=!1,a.tabledata.length=0,a.tableParams.reload(),j.reset()},a.getReport=function(){h.getMethod2("/kloudbuster/report/"+a.sessionID+"?final=true").then(function(b){if(console.log("get report totally:"+b.data.length),console.log(b.data),b.data.length>0&&pc;c++){a.result=b.data[c];var d=j.getColor();a.config.client.progression.enabled?(console.log("show report"+a.name),a.pushChartData("Connection-"+a.result.total_connections,a.result,d),a.pushTableData("Connection-"+a.result.total_connections,a.result,d)):(console.log("show report"+a.name),a.pushChartData("Final",a.result,d),a.pushTableData("Final",a.result,d))}}},function(a){console.log("get report error:"),console.log(a)})},a.pushChartData=function(b,c,d){console.log("chart date"+b),a.isDely===!1&&(a.options.series.shift(),a.isDely=!0),a.options.series.push({y:b,label:b,color:d,dotSize:"3",thickness:"2px"});for(var e=0;7>e;e++)a.data[e][b]=c.latency_stats[e][1]/1e3},a.pushTableData=function(b,c,d){console.log("table date:"+b);var e=8*c.http_throughput_kbytes/1e6;a.tabledata.push({seq:b,connection:c.total_connections,server_vms:c.total_server_vms,requests:c.http_total_req,sock_err:c.http_sock_err+c.http_sock_timeout,rps:c.http_rps,rate_limit:c.http_rate_limit,throughput:e.toFixed(2),description:c.description,color:d}),a.tableParams.reload()},a.saveResult=function(a){var b=new Date,c=b.getMonth()+1,d=b.getDate(),e=b.getHours(),f=b.getMinutes(),g=c+d+e+f+a+".json",h=i.getResult();""!=h[a]?l(g,JSON.stringify(h[a])):console.log("no file to save")},setInterval(function(){a.checkStatus()},2e3)}]).service("interactiveMode",function(){var a=[];this.getResult=function(){return a},this.setResult=function(b){return a=b}}).service("color",function(){var a=-1,b=["#F44336","#673AB7","#03A9F4","#4CAF50","#FFEB3B","#BF360C","#795548","#E91E63","#3F51B5","#00BCD4","#CDDC39","#FF9800","#9E9E9E","#9C27B0","#009688"],c=b.length;this.getColor=function(){return a=(a+1)%c,b[a]},this.reset=function(){a=-1}}).directive("convertToNumber",function(){return{require:"ngModel",link:function(a,b,c,d){d.$parsers.push(function(a){return parseFloat(a)}),d.$formatters.push(function(a){return""+a})}}}),angular.module("kbWebApp").controller("LogCtrl",["$scope","$compile","$http","$location","kbHttp","kbCookie","locationChange",function(a,b,c,d,e,f,g){this.awesomeThings=["HTML5 Boilerplate","AngularJS","Karma"],""===f.getSessionID()&&d.path("/Login"),$(window).on("hashchange",g.change()),String.prototype.replaceAll=function(a,b){return this.replace(new RegExp(a,"gm"),b)},a.sessionID=f.getSessionID(),a.status=f.getStatus(),a.logs="",a.logOffset=0,a.delLog=function(){f.setLogOffset(a.logOffset),$("#cc").empty(),a.getLog()},a.getLog=function(){a.sessionID?e.getMethod("/kloudbuster/log/"+a.sessionID+"?offset="+f.getLogOffset()).then(function(b){b.data=b.data.substring(1,b.data.length-1),a.logOffset=f.getLogOffset()+b.data.length-1,a.logs=b.data.split("\\n"),$("#cc").empty();for(var c in a.logs)a.logs[c]=a.logs[c].replace(/ /g," "),$("#cc").append(a.logs[c]+"
")},function(a){console.log("get Log error:"),console.log(a)}):console.log("not connected "+a.status+","+a.sessionID)},a.getLog()}]),angular.module("kbWebApp").controller("IntervalCtrl",["$scope","$http","kbHttp","$q","$location","kbCookie","monitorMode","locationChange",function(a,b,c,d,e,f,g,h){function i(a,b){var c=document.createElement("a"),d=new Blob([b]),e=document.createEvent("HTMLEvents");e.initEvent("click",!1,!1),c.download=a,c.href=URL.createObjectURL(d),c.dispatchEvent(e)}this.awesomeThings=["HTML5 Boilerplate","AngularJS","Karma"],""===f.getSessionID()&&e.path("/Login"),$(window).on("hashchange",h.change()),$("[data-toggle='.container']").click(function(){var a=$(this).data("toggle");$(a).toggleClass("open-sidebar"),$("#littleglyph1").toggleClass("glyphicon-triangle-right"),$("#littleglyph1").toggleClass("glyphicon-triangle-left")}),$(".swipe-area").swipe({swipeStatus:function(a,b,c,d,e,f){return"move"==b&&"right"==c?($(".container").addClass("open-sidebar"),!1):"move"==b&&"left"==c?($(".container").removeClass("open-sidebar"),!1):void 0}}),a.oneAtATime=!0,a.status1={isFirstOpen:!0,isFirstDisabled:!1},a.status2={isFirstOpen:!0,isFirstDisabled:!1},a.status1.open=!1,a.status2.open=!0,a.alerts=[],a.closeAlert=function(b){a.alerts.splice(b,1)},a.sessionID=f.getSessionID(),a.status=f.getStatus(),a.config=f.getConfig(),a.getRunConfig=function(){c.getMethod("/config/running_config/"+a.sessionID).then(function(b){a.config=b.data,f.setConfig(b.data),console.log("get & save config")},function(a){console.log("get running config error:"),console.log(a)})},a.sessionID&&!a.config&&a.getRunConfig(),a.setConfig=function(){var b=d.defer();if("READY"===a.status)a.config.client.progression.enabled=!1,f.setConfig(a.config),a.chaCon={kb_cfg:{}},a.chaCon.kb_cfg=f.getConfig(),c.putMethod("/config/running_config/"+a.sessionID,a.chaCon).then(function(a){console.log("change running config"),b.resolve(1)},function(a){console.log("change running config error:"),console.log(a),b.reject(0)});else if("STAGED"===a.status){if(a.config.client.progression.enabled===!0)return alert("Can't Run Monitor Test Now! You have chosen Progression Test. Click Unstage Button First!"),b.reject(0),b.promise;f.setConfig(a.config),a.chaCon={kb_cfg:{client:{http_tool_configs:{duration:a.config.client.http_tool_configs.duration,rate_limit:a.config.client.http_tool_configs.rate_limit,connections:a.config.client.http_tool_configs.connections,report_interval:a.config.client.http_tool_configs.report_interval}}}},console.log(a.chaCon),c.putMethod("/config/running_config/"+a.sessionID,a.chaCon).then(function(a){console.log("change running config"),b.resolve(1)},function(a){console.log("change running config error:"),console.log(a),b.reject(0)})}else console.log("config not allow to change now!"),b.reject(0);return b.promise};var j=!1,k=!1;a.disableConfig=function(a){$("#"+a).find("input").each(function(){$(this).attr("disabled","disabled")})},a.enableConfig=function(a){$("#"+a).find("input").each(function(){$(this).removeAttr("disabled")})},a.configStatus=function(){"READY"===a.status?(j===!0&&(j=!1,a.enableConfig("stagingConfig")),k===!0&&(k=!1,a.enableConfig("runningConfig"))):"STAGED"===a.status?(j===!1&&(j=!0,a.disableConfig("stagingConfig")),k===!0&&(k=!1,a.enableConfig("runningConfig"))):(j===!1&&(j=!0,a.disableConfig("stagingConfig")),k===!1&&(k=!0,a.disableConfig("runningConfig")))};var l=0;a.pointNum=function(){var a=".";l=(l+1)%6;for(var b=0;l>b;b++)a+=" .";return a},a.runButton="Run Test",a.runStatus=!0,a.setStatus=!1,a.setUnstage=!0,a.client_vm_count=0,a.server_vm_count=0,a.checkStatus=function(){a.sessionID?c.getMethod2("/kloudbuster/status/"+a.sessionID).then(function(b){a.status=b.data.status,a.configStatus(),f.setStatus(a.status),"READY"===a.status?(a.runButton="Create VMs",a.runStatus=!1,a.setStatus=!1,a.setUnstage=!0,a.client_vm_count=0,a.server_vm_count=0,$(".loading").addClass("pause"),a.info=""):"STAGING"===a.status?(a.runButton="Run Test",a.runStatus=!0,a.setStatus=!0,a.setUnstage=!0,a.client_vm_count=b.data.client_vm_count,a.server_vm_count=b.data.server_vm_count,$(".loading").removeClass("pause"),a.info="KloudBuster is Creating VM(s)"+a.pointNum()):"STAGED"===a.status?(a.runButton="Run Test",a.runStatus=!1,a.setStatus=!1,a.setUnstage=!1,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,$(".loading").addClass("pause"),a.info=""):"RUNNING"===a.status?(a.runButton="Stop Test",a.runStatus=!1,a.setStatus=!0,a.setUnstage=!0,a.getSeqReport(),a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,$(".loading").removeClass("pause"),a.info="KloudBuster is Running"+a.pointNum()):"ERROR"===a.status?(a.runButton="Run Test",a.runStatus=!0,a.setStatus=!0,a.setUnstage=!1,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,$(".loading").addClass("pause"),a.info=""):("CLEANING"===a.status||"STOPPING"===a.status)&&(a.runButton="Run Test",a.runStatus=!0,a.setStatus=!0,a.setUnstage=!0,a.client_vm_count=a.config.server.routers_per_tenant*a.config.server.networks_per_router*a.config.server.vms_per_network*a.config.server.number_tenants,a.server_vm_count=a.client_vm_count,$(".loading").removeClass("pause"),a.info="Please Wait"+a.pointNum())},function(a){console.log("get status error:"),console.log(a)}):a.status="NO SESSION ID"},a.checkStatus(),a.setStage=function(){c.postMethod("/kloudbuster/stage/"+a.sessionID).then(function(b){a.checkStatus()},function(a){console.log("set stage error:"),console.log(a)})},a.runKb=function(){c.postMethod("/kloudbuster/run_test/"+a.sessionID).then(function(b){a.checkStatus()},function(a){console.log("running error:"),console.log(a)})},a.stopKb=function(){ -c.postMethod("/kloudbuster/stop_test/"+a.sessionID).then(function(b){a.checkStatus()},function(a){console.log("stop error:"),console.log(a)})},a.scaleTest=function(){if("RUNNING"===a.status)a.stopKb();else{var b=a.setConfig();b.then(function(){"READY"===a.status?a.setStage():"STAGED"===a.status&&(a.config.client.progression.enabled===!0?alert("Can't Run Monitor Test Now! You have chosen Progression Test. Clean Up First!"):(a.initChart(),a.runKb()))})}},a.CleanUp=function(){a.initChart(),a.sessionID?c.postMethod("/kloudbuster/cleanup/"+a.sessionID).then(function(b){a.checkStatus(),console.log("clean up successfully")},function(a){console.log("clean error:"),console.log(a)}):console.log("no sessionID")},a.data=[{x:new Date}],a.isDely=!1;var m=0;a.initChart=function(){a.data=[{x:new Date}],a.isDely=!1,m=0,g.setResult("")},a.options={axes:{x:{type:"date"},y:{type:"log",ticksFormat:"d",innerTicks:!0,grid:!0}},series:[{y:"val_6",label:"99.999%",type:"area",color:"#2e4174",dotSize:"0",thickness:"2px",visible:!1},{y:"val_5",label:"99.99%",type:"area",color:"#084594",dotSize:"0",thickness:"2px",visible:!1},{y:"val_4",label:"99.9%",type:"area",color:"#0074D9",dotSize:"0",thickness:"2px"},{y:"val_3",label:"99%",type:"area",color:"#79afe1",dotSize:"0",thickness:"2px"},{y:"val_2",label:"90%",type:"area",color:"#9ecae1",dotSize:"0",thickness:"2px"},{y:"val_1",label:"75%",type:"area",color:"#c6dbef",dotSize:"0",thickness:"2px",visible:!1},{y:"val_0",label:"50%",type:"area",color:"#eff3ff",dotSize:"0",thickness:"2px"}],tooltip:{mode:"scrubber",formatter:function(a,b,c){return c.label+":"+b}},tension:.9,lineMode:"cardinal"},a.data.forEach(function(a){a.x=new Date(a.x)}),a.getSeqReport=function(){c.getMethod2("/kloudbuster/report/"+a.sessionID).then(function(b){a.result=b.data.report,a.seq=b.data.seq,console.log("get seq report:"+a.seq),a.seq&&a.seq>m&&(m=a.seq,a.data.length>40&&a.data.shift(),a.pushChartData("SEQ_"+a.seq,a.result))},function(a){console.log("get seq report error:"),console.log(a)})},a.pushChartData=function(b,c){a.isDely===!1&&(a.data.shift(),a.isDely=!0),a.data.push({x:new Date,val_0:c.latency_stats[0][1]/1e3,val_1:c.latency_stats[1][1]/1e3,val_2:c.latency_stats[2][1]/1e3,val_3:c.latency_stats[3][1]/1e3,val_4:c.latency_stats[4][1]/1e3,val_5:c.latency_stats[5][1]/1e3,val_6:c.latency_stats[6][1]/1e3}),g.setResult(a.data)},g.getResult()&&(a.data=g.getResult()),a.saveResult=function(){var a=new Date,b=a.getMonth()+1,c=a.getDate(),d=a.getHours(),e=a.getMinutes(),f=b+c+d+e+".json";console.log(f),""!=g.getResult()?i(f,JSON.stringify(g.getResult())):console.log("no file to save")},setInterval(function(){a.checkStatus()},2e3)}]).service("monitorMode",function(){var a="";this.getResult=function(){return a},this.setResult=function(b){return a=b}}),angular.module("kbWebApp").controller("LoginCtrl",["$scope","$http","$location","kbHttp","kbCookie","locationChange",function(a,b,c,d,e,f){function g(a){var b=a.target.files,c=b[0],d=new FileReader;d.onload=function(){i=this.result},d.readAsText(c)}function h(a){var b=a.target.files,c=b[0],d=new FileReader;d.onload=function(){j=this.result},d.readAsText(c)}this.awesomeThings=["HTML5 Boilerplate","AngularJS","Karma"],$(window).on("hashchange",f.change()),a.deleteSession=function(){d.delMethod("/config/running_config/"+a.sessionID).then(function(a){console.log("del sessionID")},function(a){console.log("delete error:"),console.log(a)})},a.CleanUp=function(){d.postMethod("/kloudbuster/cleanup/"+a.sessionID).then(function(a){console.log("clean up successfully")},function(a){console.log("clean error:"),console.log(a)})},""!=e.getSessionID()&&(a.sessionID=e.getSessionID(),"READY"!=e.getStatus()&&a.CleanUp(),a.deleteSession(),e.init()),a.samecloud=!0,a.clouds=function(){a.samecloud===!0?($("#inputPassword2").attr("disabled",!0),$("#file2").attr("disabled",!0)):($("#inputPassword2").attr("disabled",!1),$("#file2").attr("disabled",!1))};var i;document.getElementById("file1").addEventListener("change",g,!1);var j;document.getElementById("file2").addEventListener("change",h,!1),$("#inputPassword1").keydown(function(b){var c=b.which;13==c&&a.setConfig()}),$("#inputPassword2").keydown(function(b){var c=b.which;13==c&&a.setConfig()}),a.setConfig=function(){a.samecloud===!0?(e.setIsOneCloud(!0),a.credentials={"tested-passwd":a.inputPassword1,"tested-rc":i}):(e.setIsOneCloud(!1),a.credentials={"tested-passwd":a.inputPassword1,"tested-rc":i,"testing-passwd":inputPassword2,"testing-rc":j}),a.runCon={credentials:{},kb_cfg:""},console.log(a.credentials),a.runCon.credentials=a.credentials,e.setCredentials(a.credentials),d.postMethod("/config/running_config",a.runCon).then(function(b){e.setSessionID(b.data),a.sessionID=e.getSessionID(),console.log("set config & get sesID:"+a.sessionID),c.path("/")},function(a){console.log("set config error:"),console.log(a)})}}]),angular.module("kbWebApp").run(["$templateCache",function(a){"use strict";a.put("views/about.html",'

KloudBuster

{{version}}

Splendid!

'),a.put("views/config.html",'

VM Creation Concurrency:


VM PLACEMENT


For Server:
For Client:
Server Pool {{user.firstName}}
Available Hypervisors {{user.firstName}}
Client Pool {{user.firstName}}
Html Payload Size:

flavor
vCPUs:

RAM (KB):

Disk (GB):
flavor
vCPUs:

RAM (KB):

Disk (GB):
'),a.put("views/interval.html",'
Latency(ms)

'),a.put("views/log.html",'
LOGS
'),a.put("views/login.html",'

Server Cloud

Password

Client Cloud

Password

'),a.put("views/run.html",'
Latency(ms)
cols to show
       {{row.connection}} {{row.server_vms}} {{row.requests}} {{row.sock_err}} {{row.rps}} {{row.rate_limit}} {{row.throughput}} Gbps
'); -}]); \ No newline at end of file diff --git a/kb_server/public/ui/scripts/vendor.5ac9f2d1.js b/kb_server/public/ui/scripts/vendor.5ac9f2d1.js deleted file mode 100644 index 5a44663..0000000 --- a/kb_server/public/ui/scripts/vendor.5ac9f2d1.js +++ /dev/null @@ -1,20 +0,0 @@ -if(function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b="length"in a&&a.length,c=_.type(a);return"function"===c||_.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(_.isFunction(b))return _.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return _.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(ha.test(b))return _.filter(b,a,c);b=_.filter(b,a)}return _.grep(a,function(a){return U.call(b,a)>=0!==c})}function e(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function f(a){var b=oa[a]={};return _.each(a.match(na)||[],function(a,c){b[c]=!0}),b}function g(){Z.removeEventListener("DOMContentLoaded",g,!1),a.removeEventListener("load",g,!1),_.ready()}function h(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=_.expando+h.uid++}function i(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(ua,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:ta.test(c)?_.parseJSON(c):c}catch(e){}sa.set(a,b,c)}else c=void 0;return c}function j(){return!0}function k(){return!1}function l(){try{return Z.activeElement}catch(a){}}function m(a,b){return _.nodeName(a,"table")&&_.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function n(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function o(a){var b=Ka.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function p(a,b){for(var c=0,d=a.length;d>c;c++)ra.set(a[c],"globalEval",!b||ra.get(b[c],"globalEval"))}function q(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(ra.hasData(a)&&(f=ra.access(a),g=ra.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)_.event.add(b,e,j[e][c])}sa.hasData(a)&&(h=sa.access(a),i=_.extend({},h),sa.set(b,i))}}function r(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&_.nodeName(a,b)?_.merge([a],c):c}function s(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ya.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function t(b,c){var d,e=_(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:_.css(e[0],"display");return e.detach(),f}function u(a){var b=Z,c=Oa[a];return c||(c=t(a,b),"none"!==c&&c||(Na=(Na||_("