').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
9 | //# sourceMappingURL=bootstrap-toggle.min.js.map
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/c3/c3.min.css:
--------------------------------------------------------------------------------
1 | .c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc rect{stroke:#fff;stroke-width:1}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:grey;font-size:2em}.c3-line{stroke-width:1px}.c3-circle{fill:currentColor}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:1;fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-region text{fill-opacity:1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #ccc}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#fff}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip .value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:#fff}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max{fill:#777}.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000}.c3-chart-arc.c3-target g path{opacity:1}.c3-chart-arc.c3-target.c3-focused g path{opacity:1}.c3-drag-zoom.enabled{pointer-events:all!important;visibility:visible}.c3-drag-zoom.disabled{pointer-events:none!important;visibility:hidden}.c3-drag-zoom .extent{fill-opacity:.1}
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/d3-tip.min.js:
--------------------------------------------------------------------------------
1 | !function(t,e){if("function"==typeof define&&define.amd)define(["d3"],e);else if("object"==typeof module&&module.exports){var n=require("d3");module.exports=e(n)}else t.d3.tip=e(t.d3)}(this,function(t){return function(){function e(t){b=d(t),C=b.createSVGPoint(),document.body.appendChild(T)}function n(){return"n"}function r(){return[0,0]}function o(){return" "}function l(){var t=h();return{top:t.n.y-T.offsetHeight,left:t.n.x-T.offsetWidth/2}}function i(){var t=h();return{top:t.s.y,left:t.s.x-T.offsetWidth/2}}function f(){var t=h();return{top:t.e.y-T.offsetHeight/2,left:t.e.x}}function u(){var t=h();return{top:t.w.y-T.offsetHeight/2,left:t.w.x-T.offsetWidth}}function s(){var t=h();return{top:t.nw.y-T.offsetHeight,left:t.nw.x-T.offsetWidth}}function a(){var t=h();return{top:t.ne.y-T.offsetHeight,left:t.ne.x}}function c(){var t=h();return{top:t.sw.y,left:t.sw.x-T.offsetWidth}}function p(){var t=h();return{top:t.se.y,left:t.e.x}}function y(){var e=t.select(document.createElement("div"));return e.style("position","absolute").style("top",0).style("opacity",0).style("pointer-events","none").style("box-sizing","border-box"),e.node()}function d(t){return t=t.node(),"svg"===t.tagName.toLowerCase()?t:t.ownerSVGElement}function m(){return null===T&&(T=y(),document.body.appendChild(T)),t.select(T)}function h(){for(var e=E||t.event.target;"undefined"==typeof e.getScreenCTM&&"undefined"===e.parentNode;)e=e.parentNode;var n={},r=e.getScreenCTM(),o=e.getBBox(),l=o.width,i=o.height,f=o.x,u=o.y;return C.x=f,C.y=u,n.nw=C.matrixTransform(r),C.x+=l,n.ne=C.matrixTransform(r),C.y+=i,n.se=C.matrixTransform(r),C.x-=l,n.sw=C.matrixTransform(r),C.y-=i/2,n.w=C.matrixTransform(r),C.x+=l,n.e=C.matrixTransform(r),C.x-=l/2,C.y-=i/2,n.n=C.matrixTransform(r),C.y+=i,n.s=C.matrixTransform(r),n}function x(t){return"function"==typeof t?t:function(){return t}}var v=n,g=r,w=o,T=y(),b=null,C=null,E=null;e.show=function(){var t=Array.prototype.slice.call(arguments);t[t.length-1]instanceof SVGElement&&(E=t.pop());var n,r=w.apply(this,t),o=g.apply(this,t),l=v.apply(this,t),i=m(),f=S.length,u=document.documentElement.scrollTop||document.body.scrollTop,s=document.documentElement.scrollLeft||document.body.scrollLeft;for(i.html(r).style("opacity",1).style("pointer-events","all");f--;)i.classed(S[f],!1);return n=H.get(l).apply(this),i.classed(l,!0).style("top",n.top+o[0]+u+"px").style("left",n.left+o[1]+s+"px"),e},e.hide=function(){var t=m();return t.style("opacity",0).style("pointer-events","none"),e},e.attr=function(n,r){if(arguments.length<2&&"string"==typeof n)return m().attr(n);var o=Array.prototype.slice.call(arguments);return t.selection.prototype.attr.apply(m(),o),e},e.style=function(n,r){if(arguments.length<2&&"string"==typeof n)return m().style(n);var o=Array.prototype.slice.call(arguments);return t.selection.prototype.style.apply(m(),o),e},e.direction=function(t){return arguments.length?(v=null==t?t:x(t),e):v},e.offset=function(t){return arguments.length?(g=null==t?t:x(t),e):g},e.html=function(t){return arguments.length?(w=null==t?t:x(t),e):w},e.destroy=function(){return T&&(m().remove(),T=null),e};var H=t.map({n:l,s:i,e:f,w:u,nw:s,ne:a,sw:c,se:p}),S=H.keys();return e}});
2 | //# sourceMappingURL=d3-tip.min.js.map
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/d3/d3-tip.min.js:
--------------------------------------------------------------------------------
1 | !function(t,e){if("function"==typeof define&&define.amd)define(["d3"],e);else if("object"==typeof module&&module.exports){var n=require("d3");module.exports=e(n)}else t.d3.tip=e(t.d3)}(this,function(t){return function(){function e(t){b=d(t),C=b.createSVGPoint(),document.body.appendChild(T)}function n(){return"n"}function r(){return[0,0]}function o(){return" "}function l(){var t=h();return{top:t.n.y-T.offsetHeight,left:t.n.x-T.offsetWidth/2}}function i(){var t=h();return{top:t.s.y,left:t.s.x-T.offsetWidth/2}}function f(){var t=h();return{top:t.e.y-T.offsetHeight/2,left:t.e.x}}function u(){var t=h();return{top:t.w.y-T.offsetHeight/2,left:t.w.x-T.offsetWidth}}function s(){var t=h();return{top:t.nw.y-T.offsetHeight,left:t.nw.x-T.offsetWidth}}function a(){var t=h();return{top:t.ne.y-T.offsetHeight,left:t.ne.x}}function c(){var t=h();return{top:t.sw.y,left:t.sw.x-T.offsetWidth}}function p(){var t=h();return{top:t.se.y,left:t.e.x}}function y(){var e=t.select(document.createElement("div"));return e.style("position","absolute").style("top",0).style("opacity",0).style("pointer-events","none").style("box-sizing","border-box"),e.node()}function d(t){return t=t.node(),"svg"===t.tagName.toLowerCase()?t:t.ownerSVGElement}function m(){return null===T&&(T=y(),document.body.appendChild(T)),t.select(T)}function h(){for(var e=E||t.event.target;"undefined"==typeof e.getScreenCTM&&"undefined"===e.parentNode;)e=e.parentNode;var n={},r=e.getScreenCTM(),o=e.getBBox(),l=o.width,i=o.height,f=o.x,u=o.y;return C.x=f,C.y=u,n.nw=C.matrixTransform(r),C.x+=l,n.ne=C.matrixTransform(r),C.y+=i,n.se=C.matrixTransform(r),C.x-=l,n.sw=C.matrixTransform(r),C.y-=i/2,n.w=C.matrixTransform(r),C.x+=l,n.e=C.matrixTransform(r),C.x-=l/2,C.y-=i/2,n.n=C.matrixTransform(r),C.y+=i,n.s=C.matrixTransform(r),n}function x(t){return"function"==typeof t?t:function(){return t}}var v=n,g=r,w=o,T=y(),b=null,C=null,E=null;e.show=function(){var t=Array.prototype.slice.call(arguments);t[t.length-1]instanceof SVGElement&&(E=t.pop());var n,r=w.apply(this,t),o=g.apply(this,t),l=v.apply(this,t),i=m(),f=S.length,u=document.documentElement.scrollTop||document.body.scrollTop,s=document.documentElement.scrollLeft||document.body.scrollLeft;for(i.html(r).style("opacity",1).style("pointer-events","all");f--;)i.classed(S[f],!1);return n=H.get(l).apply(this),i.classed(l,!0).style("top",n.top+o[0]+u+"px").style("left",n.left+o[1]+s+"px"),e},e.hide=function(){var t=m();return t.style("opacity",0).style("pointer-events","none"),e},e.attr=function(n,r){if(arguments.length<2&&"string"==typeof n)return m().attr(n);var o=Array.prototype.slice.call(arguments);return t.selection.prototype.attr.apply(m(),o),e},e.style=function(n,r){if(arguments.length<2&&"string"==typeof n)return m().style(n);var o=Array.prototype.slice.call(arguments);return t.selection.prototype.style.apply(m(),o),e},e.direction=function(t){return arguments.length?(v=null==t?t:x(t),e):v},e.offset=function(t){return arguments.length?(g=null==t?t:x(t),e):g},e.html=function(t){return arguments.length?(w=null==t?t:x(t),e):w},e.destroy=function(){return T&&(m().remove(),T=null),e};var H=t.map({n:l,s:i,e:f,w:u,nw:s,ne:a,sw:c,se:p}),S=H.keys();return e}});
2 | //# sourceMappingURL=d3-tip.min.js.map
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/d3/d3.flameGraph.min.css:
--------------------------------------------------------------------------------
1 | .d3-flame-graph rect{stroke:#EEE;fill-opacity:.8}.d3-flame-graph rect:hover{stroke:#474747;stroke-width:.5;cursor:pointer}.d3-flame-graph-label{pointer-events:none;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:12px;font-family:Verdana;margin-left:4px;margin-right:4px;line-height:1.5;padding:0;font-weight:400;color:#000;text-align:left}.d3-flame-graph .fade{opacity:.6!important}.d3-flame-graph .title{font-size:20px;font-family:Verdana}.d3-flame-graph-tip{line-height:1;font-family:Verdana;font-size:12px;padding:12px;background:rgba(0,0,0,.8);color:#fff;border-radius:2px;pointer-events:none}.d3-flame-graph-tip:after{box-sizing:border-box;display:inline;font-size:10px;width:100%;line-height:1;color:rgba(0,0,0,.8);position:absolute;pointer-events:none}.d3-flame-graph-tip.n:after{content:"\25BC";margin:-1px 0 0;top:100%;left:0;text-align:center}.d3-flame-graph-tip.e:after{content:"\25C0";margin:-4px 0 0;top:50%;left:-8px}.d3-flame-graph-tip.s:after{content:"\25B2";margin:0 0 1px;top:-8px;left:0;text-align:center}.d3-flame-graph-tip.w:after{content:"\25B6";margin:-4px 0 0 -1px;top:50%;left:100%}
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/d3/d3.flameGraph.min.js:
--------------------------------------------------------------------------------
1 | !function(){"use strict";function n(){function t(t){return t.data.n||t.data.name}function n(t){return t.c||t.children}function e(t){return t.v||t.value}function r(t){S&&(S.innerHTML=t)}function i(t){var n=0,e=1,r=0;if(t){for(var i=0;i
6);i++)n+=e*(t.charCodeAt(i)%10),r+=9*e,e*=.7;r>0&&(n/=r)}return n}function a(t){var n=0;if(t){var e=t.split("`");e.length>1&&(t=e[e.length-1]),n=i(t=t.split("(")[0])}return"rgb("+(200+Math.round(55*n))+","+(0+Math.round(230*(1-n)))+","+(0+Math.round(55*(1-n)))+")"}function o(t){t.data.hide=!0,n(t)&&n(t).forEach(o)}function u(t){t.data.fade=!1,t.data.hide=!1,n(t)&&n(t).forEach(u)}function f(t){var n=[];if(t.parent){var e=t.parent.children.indexOf(t);(n=t.parent.children.slice(0)).splice(e,1)}return n}function c(t){f(t).forEach(function(t){o(t)}),t.parent&&c(t.parent)}function l(t){t.parent&&(t.parent.data.fade=!0,l(t.parent))}function d(t){D.hide(t),c(t),u(t),l(t),v(),"function"==typeof z&&z(t)}function h(e,r){function i(e){var r=t(e);n(e)&&n(e).forEach(function(t){i(t)}),r.match(a)?(e.highlight=!0,o.push(e)):e.highlight=!1}var a=new RegExp(r),o=[];return i(e),o}function s(t){t.highlight=!1,n(t)&&n(t).forEach(function(t){s(t)})}function p(n,e){return"function"==typeof L?L(n,e):L?d3.ascending(t(n),t(e)):void 0}function g(t){var n=t.descendants();if(H>0){var e=b/(t.x1-t.x0);n=n.filter(function(t){return(t.x1-t.x0)*e>H})}return n}function v(){O.each(function(i){function a(t){return(t.x1-t.x0)*f}var o=d3.scaleLinear().range([0,b]),u=d3.scaleLinear().range([0,M]);L&&i.sort(p),i.sum(function(t){if(t.fade||t.hide)return 0;var r=e(t);if(n(t))for(var i=n(t),a=0;a>>0;if("function"!=typeof t)throw new TypeError("predicate must be a function");for(var r=arguments[1],i=0;i>>0,i=new Array(r),a=0,o=-1;if(void 0===e)for(;++o!==r;)if(o in this)if(n(t[o],o,t))i[a++]=t[o];else for(;++o!==r;)o in this&&n.call(e,t[o],o,t)&&(i[a++]=t[o]);return i.length=a,i}),"undefined"!=typeof module&&"undefined"!=typeof exports&&"undefined"==typeof d3&&(d3=require("d3")),"undefined"!=typeof module&&"undefined"!=typeof exports&&void 0===d3.tip&&(d3.tip=require("d3-tip")),"undefined"!=typeof module&&"undefined"!=typeof exports?module.exports=n:d3.flameGraph=n}();
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/dataTables.jqueryui.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | DataTables jQuery UI integration
3 | ©2011-2014 SpryMedia Ltd - datatables.net/license
4 | */
5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,c){a||(a=window);c&&c.fn.dataTable||(c=require("datatables.net")(a,c).$);return b(c,a,a.document)}:b(jQuery,window,document)})(function(b,a,c,d){a=b.fn.dataTable;b.extend(!0,a.defaults,{dom:'<"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-tl ui-corner-tr"lfr>t<"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-bl ui-corner-br"ip>'});
6 | b.extend(a.ext.classes,{sWrapper:"dataTables_wrapper dt-jqueryui",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollFoot:"dataTables_scrollFoot ui-state-default",sHeaderTH:"ui-state-default",sFooterTH:"ui-state-default"});return a});
7 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | .fa-icon-rotate(@degrees, @rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
16 | -webkit-transform: rotate(@degrees);
17 | -ms-transform: rotate(@degrees);
18 | transform: rotate(@degrees);
19 | }
20 |
21 | .fa-icon-flip(@horiz, @vert, @rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
23 | -webkit-transform: scale(@horiz, @vert);
24 | -ms-transform: scale(@horiz, @vert);
25 | transform: scale(@horiz, @vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | .sr-only() {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | .sr-only-focusable() {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | -webkit-transform: rotate($degrees);
17 | -ms-transform: rotate($degrees);
18 | transform: rotate($degrees);
19 | }
20 |
21 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
23 | -webkit-transform: scale($horiz, $vert);
24 | -ms-transform: scale($horiz, $vert);
25 | transform: scale($horiz, $vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | @mixin sr-only {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | @mixin sr-only-focusable {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/font-awesome-4.7.0/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-migrate-3.4.0.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery Migrate v3.4.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
2 | "undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e,window)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),window):t(jQuery,window)}(function(s,n){"use strict";function e(e){return 0<=function(e,t){for(var r=/^(\d+)\.(\d+)\.(\d+)/,n=r.exec(e)||[],o=r.exec(t)||[],a=1;a<=3;a++){if(+n[a]>+o[a])return 1;if(+n[a]<+o[a])return-1}return 0}(s.fn.jquery,e)}s.migrateVersion="3.4.0";var t=Object.create(null),o=(s.migrateDisablePatches=function(){for(var e=0;e\x20\t\r\n\f]*)[^>]*)\/>/gi),_=(s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.migrateEnablePatches("self-closed-tags")},d(s,"htmlPrefilter",function(e){var t,r;return(r=(t=e).replace(O,"<$1>$2>"))!==t&&C(t)!==C(r)&&i("self-closed-tags","HTML tags must be properly nested and closed: "+t),e.replace(O,"<$1>$2>")},"self-closed-tags"),s.migrateDisablePatches("self-closed-tags"),s.fn.offset);return d(s.fn,"offset",function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?_.apply(this,arguments):(i("offset-valid-elem","jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},"offset-valid-elem"),s.ajax&&(H=s.param,d(s,"param",function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(i("param-ajax-traditional","jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),H.call(this,e,t)},"param-ajax-traditional")),u(s.fn,"andSelf",s.fn.addBack,"andSelf","jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),s.Deferred&&(E=s.Deferred,M=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],d(s,"Deferred",function(e){var a=E(),i=a.promise();function t(){var o=arguments;return s.Deferred(function(n){s.each(M,function(e,t){var r="function"==typeof o[e]&&o[e];a[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===i?n.promise():this,r?[e]:arguments)})}),o=null}).promise()}return u(a,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),u(i,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),e&&e.call(a,a),a},"deferred-pipe"),s.Deferred.exceptionHook=E.exceptionHook),s});
3 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright jQuery Foundation and other contributors, https://jquery.org/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/jquery/jquery-ui
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | Copyright and related rights for sample code are waived via CC0. Sample
34 | code is defined as all source code contained within the demos directory.
35 |
36 | CC0: http://creativecommons.org/publicdomain/zero/1.0/
37 |
38 | ====
39 |
40 | All files located in the node_modules and external directories are
41 | externally maintained libraries used by this software which have their
42 | own licenses; we recommend you read them, as their terms may differ from
43 | the terms above.
44 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_444444_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_444444_256x240.png
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_555555_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_555555_256x240.png
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_777620_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_777620_256x240.png
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_777777_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_777777_256x240.png
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_cc0000_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_cc0000_256x240.png
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery-ui-1.13.2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-ui",
3 | "title": "jQuery UI",
4 | "description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
5 | "version": "1.13.2",
6 | "homepage": "http://jqueryui.com",
7 | "author": {
8 | "name": "jQuery Foundation and other contributors",
9 | "url": "https://github.com/jquery/jquery-ui/blob/1.13.2/AUTHORS.txt"
10 | },
11 | "main": "ui/widget.js",
12 | "maintainers": [
13 | {
14 | "name": "Jörn Zaefferer",
15 | "email": "joern.zaefferer@gmail.com",
16 | "url": "http://bassistance.de"
17 | },
18 | {
19 | "name": "Mike Sherov",
20 | "email": "mike.sherov@gmail.com",
21 | "url": "http://mike.sherov.com"
22 | },
23 | {
24 | "name": "TJ VanToll",
25 | "email": "tj.vantoll@gmail.com",
26 | "url": "http://tjvantoll.com"
27 | },
28 | {
29 | "name": "Felix Nagel",
30 | "email": "info@felixnagel.com",
31 | "url": "http://www.felixnagel.com"
32 | },
33 | {
34 | "name": "Alex Schmitz",
35 | "email": "arschmitz@gmail.com",
36 | "url": "https://github.com/arschmitz"
37 | }
38 | ],
39 | "repository": {
40 | "type": "git",
41 | "url": "git://github.com/jquery/jquery-ui.git"
42 | },
43 | "bugs": {
44 | "url": "https://github.com/jquery/jquery-ui/issues"
45 | },
46 | "license": "MIT",
47 | "scripts": {
48 | "test": "grunt"
49 | },
50 | "dependencies": {
51 | "jquery": ">=1.8.0 <4.0.0"
52 | },
53 | "devDependencies": {
54 | "commitplease": "3.2.0",
55 | "eslint-config-jquery": "3.0.0",
56 | "glob": "7.2.0",
57 | "grunt": "1.5.3",
58 | "grunt-bowercopy": "1.2.5",
59 | "grunt-cli": "1.4.3",
60 | "grunt-compare-size": "0.4.2",
61 | "grunt-contrib-concat": "1.0.1",
62 | "grunt-contrib-csslint": "2.0.0",
63 | "grunt-contrib-qunit": "5.1.1",
64 | "grunt-contrib-requirejs": "1.0.0",
65 | "grunt-contrib-uglify": "5.0.1",
66 | "grunt-eslint": "23.0.0",
67 | "grunt-git-authors": "3.2.0",
68 | "grunt-html": "14.5.0",
69 | "load-grunt-tasks": "5.1.0",
70 | "rimraf": "3.0.2",
71 | "testswarm": "1.1.2"
72 | },
73 | "keywords": []
74 | }
75 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/static/plugins/jquery.contextMenu.min.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";/*!
2 | * jQuery contextMenu - Plugin for simple contextMenu handling
3 | *
4 | * Version: v2.9.2
5 | *
6 | * Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF)
7 | * Web: http://swisnl.github.io/jQuery-contextMenu/
8 | *
9 | * Copyright (c) 2011-2020 SWIS BV and contributors
10 | *
11 | * Licensed under
12 | * MIT License http://www.opensource.org/licenses/mit-license
13 | *
14 | * Date: 2020-05-13T13:55:37.023Z
15 | */@-webkit-keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@-o-keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);-o-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);-o-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);-o-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);-o-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@font-face{font-family:context-menu-icons;font-style:normal;font-weight:400;src:url(font/context-menu-icons.eot?33lxn);src:url(font/context-menu-icons.eot?33lxn#iefix) format("embedded-opentype"),url(font/context-menu-icons.woff2?33lxn) format("woff2"),url(font/context-menu-icons.woff?33lxn) format("woff"),url(font/context-menu-icons.ttf?33lxn) format("truetype")}.context-menu-icon-add:before{content:"\EA01"}.context-menu-icon-copy:before{content:"\EA02"}.context-menu-icon-cut:before{content:"\EA03"}.context-menu-icon-delete:before{content:"\EA04"}.context-menu-icon-edit:before{content:"\EA05"}.context-menu-icon-loading:before{content:"\EA06"}.context-menu-icon-paste:before{content:"\EA07"}.context-menu-icon-quit:before{content:"\EA08"}.context-menu-icon::before{position:absolute;top:50%;left:0;width:2em;font-family:context-menu-icons;font-size:1em;font-style:normal;font-weight:400;line-height:1;color:#2980b9;text-align:center;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.context-menu-icon.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon-loading:before{-webkit-animation:cm-spin 2s infinite;-o-animation:cm-spin 2s infinite;animation:cm-spin 2s infinite}.context-menu-icon.context-menu-icon--fa{display:list-item;font-family:inherit;line-height:inherit}.context-menu-icon.context-menu-icon--fa::before{position:absolute;top:50%;left:0;width:2em;font-family:FontAwesome;font-size:1em;font-style:normal;font-weight:400;line-height:1;color:#2980b9;text-align:center;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.context-menu-icon.context-menu-icon--fa.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon--fa5{display:list-item;font-family:inherit;line-height:inherit}.context-menu-icon.context-menu-icon--fa5 i,.context-menu-icon.context-menu-icon--fa5 svg{position:absolute;top:.3em;left:.5em;color:#2980b9}.context-menu-icon.context-menu-icon--fa5.context-menu-hover>i,.context-menu-icon.context-menu-icon--fa5.context-menu-hover>svg{color:#fff}.context-menu-icon.context-menu-icon--fa5.context-menu-disabled i,.context-menu-icon.context-menu-icon--fa5.context-menu-disabled svg{color:#bbb}.context-menu-list{position:absolute;display:inline-block;min-width:13em;max-width:26em;padding:.25em 0;margin:.3em;font-family:inherit;font-size:inherit;list-style-type:none;background:#fff;border:1px solid #bebebe;border-radius:.2em;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.5);box-shadow:0 2px 5px rgba(0,0,0,.5)}.context-menu-item{position:relative;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;padding:.2em 2em;color:#2f2f2f;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff}.context-menu-separator{padding:0;margin:.35em 0;border-bottom:1px solid #e6e6e6}.context-menu-item>label>input,.context-menu-item>label>textarea{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.context-menu-item.context-menu-hover{color:#fff;cursor:pointer;background-color:#2980b9}.context-menu-item.context-menu-disabled{color:#bbb;cursor:default;background-color:#fff}.context-menu-input.context-menu-hover{color:#2f2f2f;cursor:default}.context-menu-submenu:after{position:absolute;top:50%;right:.5em;z-index:1;width:0;height:0;content:'';border-color:transparent transparent transparent #2f2f2f;border-style:solid;border-width:.25em 0 .25em .25em;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%)}.context-menu-item.context-menu-input{padding:.3em .6em}.context-menu-input>label>*{vertical-align:top}.context-menu-input>label>input[type=checkbox],.context-menu-input>label>input[type=radio]{position:relative;top:.12em;margin-right:.4em}.context-menu-input>label{margin:0}.context-menu-input>label,.context-menu-input>label>input[type=text],.context-menu-input>label>select,.context-menu-input>label>textarea{display:block;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.context-menu-input>label>textarea{height:7em}.context-menu-item>.context-menu-list{top:.3em;right:-.3em;display:none}.context-menu-item.context-menu-visible>.context-menu-list{display:block}.context-menu-accesskey{text-decoration:underline}
16 | /*# sourceMappingURL=jquery.contextMenu.min.css.map */
17 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/flame.ftl:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |

13 |

15 |

17 |
21 |
24 |
26 |
27 |
Threshold:
29 |
30 |
31 |
32 |
43 |
44 |
92 |
93 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/index.ftl:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 | Title
15 |
16 | <#-- https://momentjs.com-->
17 |
18 |
19 | <#-- https://code.jquery.com/jquery-3.6.1.min.js-->
20 |
21 |
22 | <#-- https://blog.jqueryui.com/2022/07/jquery-ui-1-13-2-released-->
23 |
24 |
25 |
26 | <#-- https://github.com/xdan/datetimepicker-->
27 |
28 |
29 |
30 | <#-- https://github.com/twbs/bootstrap/releases/download/v4.2.1/bootstrap-4.2.1-dist.zip-->
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
72 | <#include "input.ftl">
73 | <#include "filter-panel.ftl">
74 | <#include "tabs.ftl">
75 |
76 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/input.ftl:
--------------------------------------------------------------------------------
1 |
9 |
10 |
19 |
20 |
21 |
22 |
Data source selector
23 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/river.ftl:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
283 |
284 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/tab-filter-toolbar.ftl:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/tabs.ftl:
--------------------------------------------------------------------------------
1 |
26 |
27 | <#include "tabs-js.ftl">
28 |
29 |
30 | <#include "tab-filter-toolbar.ftl">
31 |
39 |
42 |
43 | <#include "cct.ftl">
44 |
45 |
46 | <#include "sample.ftl">
47 |
48 |
49 | <#include "flame.ftl">
50 |
51 |
52 | <#include "river.ftl">
53 |
54 |
55 | <#include "surface.ftl">
56 |
57 |
58 | <#include "tsview.ftl">
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/perfgenie/src/main/resources/templates/test.ftl:
--------------------------------------------------------------------------------
1 |
2 |
60 |
61 |
--------------------------------------------------------------------------------
/perfgenie/src/test/java/PerfGenieServiceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Salesforce.com, Inc.
3 | * All rights reserved.
4 | * SPDX-License-Identifier: BSD-3-Clause
5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6 | */
7 |
8 | import com.fasterxml.jackson.databind.JsonNode;
9 | import com.fasterxml.jackson.databind.ObjectMapper;
10 | import com.google.common.io.Resources;
11 | import org.testng.annotations.BeforeSuite;
12 | import org.testng.annotations.Test;
13 | import com.salesforce.cantor.Cantor;
14 | import com.salesforce.cantor.h2.CantorOnH2;
15 | import server.PerfGenieService;
16 | import perfgenie.utils.CustomJfrParser;
17 | import perfgenie.utils.EventHandler;
18 | import perfgenie.utils.EventStore;
19 | import perfgenie.utils.Utils;
20 |
21 | import java.io.ByteArrayInputStream;
22 | import java.io.IOException;
23 | import java.util.HashMap;
24 | import java.util.Map;
25 | import java.util.UUID;
26 |
27 |
28 | import static org.testng.Assert.assertTrue;
29 | //import static utils.EventStore.NAMESPACE_JFR_JSON_CACHE;
30 |
31 | public class PerfGenieServiceTest extends PerfGenieService {
32 | private static CustomJfrParser parser = new CustomJfrParser(1);
33 | private static EventStore eventStore;
34 |
35 | static {
36 | try {
37 | eventStore = new EventStore(getCantorInstance());
38 | } catch (IOException e) {
39 | e.printStackTrace();
40 | }
41 | }
42 |
43 | private static final Cantor cantor = getCantorInstance();
44 | public PerfGenieServiceTest serviceTest;
45 | String guid = Utils.generateGuid();
46 |
47 | PerfGenieServiceTest() throws IOException{
48 | super(eventStore, parser);
49 | }
50 |
51 | @BeforeSuite
52 | void setup() throws IOException{
53 | serviceTest = new PerfGenieServiceTest();
54 | }
55 |
56 | @Test
57 | void addEventTest() throws IOException{
58 | EventHandler handler = new EventHandler();
59 | parser.parseStream(handler,new ByteArrayInputStream(Resources.toByteArray(Resources.getResource("test.jfr"))));
60 |
61 | final Map dimMap = new HashMap<>();
62 | final Map queryMap = new HashMap<>();
63 |
64 | long timestamp = System.currentTimeMillis();
65 | queryMap.put("guid", guid);
66 | queryMap.put("tenant", "test");
67 | queryMap.put("host", "localhost");
68 | queryMap.put("file-name", "testfile");
69 | queryMap.put("type", "jfrprofile");
70 | queryMap.put("name", "testname");
71 | boolean ret = serviceTest.addEvent(Utils.toJson(handler.getProfileTree("jdk.ExecutionSample")), timestamp, dimMap, queryMap);
72 |
73 | queryMap.put("type", "jfrevent");
74 | queryMap.put("name", "customEvent");
75 | boolean ret1 = serviceTest.addEvent(Utils.toJson(handler.getLogContext()), timestamp, dimMap, queryMap);
76 |
77 | assertTrue(ret==true, "true expected");
78 | assertTrue(ret1==true, "true expected");
79 | }
80 |
81 | @Test (dependsOnMethods = {"addEventTest"})
82 | void getMetaTest() throws IOException{
83 | final Map dimMap = new HashMap<>();
84 | final Map queryMap = new HashMap<>();
85 | queryMap.put("guid", guid);
86 | queryMap.put("name", "testname");
87 | long end = System.currentTimeMillis();
88 | long start = end-60000;
89 | String json = serviceTest.getMeta(start,end,queryMap,dimMap);
90 | ObjectMapper mapper = new ObjectMapper();
91 | JsonNode n = mapper.readTree(json);
92 | assertTrue(n.size()==1, "1 expected");
93 | }
94 |
95 | @Test (dependsOnMethods = {"addEventTest"})
96 | void getProfileTest() throws IOException{
97 | final Map dimMap = new HashMap<>();
98 | final Map queryMap = new HashMap<>();
99 | queryMap.put("guid", guid);
100 | queryMap.put("tenant", "test");
101 | queryMap.put("host", "localhost");
102 | queryMap.put("file-name", "testfile");
103 | queryMap.put("type", "jfrprofile");
104 | queryMap.put("name", "testname");
105 | long end = System.currentTimeMillis();
106 | long start = end-60000;
107 | String json = serviceTest.getProfile("tenant", start,end,queryMap,dimMap);
108 | ObjectMapper mapper = new ObjectMapper();
109 | JsonNode n = mapper.readTree(json);
110 | assertTrue(n.size()==4, "4 expected");
111 | }
112 |
113 | @Test (dependsOnMethods = {"addEventTest"})
114 | void getProfilesTest() throws IOException{
115 | final Map dimMap = new HashMap<>();
116 | final Map queryMap = new HashMap<>();
117 | queryMap.put("guid", guid);
118 | queryMap.put("tenant", "test");
119 | queryMap.put("host", "localhost");
120 | queryMap.put("file-name", "testfile");
121 | queryMap.put("type", "jfrprofile");
122 | queryMap.put("name", "testname");
123 | long end = System.currentTimeMillis();
124 | long start = end-60000;
125 | String json = serviceTest.getProfiles("tenant", start,end,queryMap,dimMap);
126 | ObjectMapper mapper = new ObjectMapper();
127 | JsonNode n = mapper.readTree(json);
128 | assertTrue(n.size()==4, "4 expected");
129 | }
130 |
131 | @Test (dependsOnMethods = {"addEventTest"})
132 | void getCustomEventsTest() throws IOException{
133 | final Map dimMap = new HashMap<>();
134 | final Map queryMap = new HashMap<>();
135 | queryMap.put("guid", guid);
136 | queryMap.put("tenant", "test");
137 | queryMap.put("host", "localhost");
138 | queryMap.put("file-name", "testfile");
139 | queryMap.put("type", "jfrevent");
140 | queryMap.put("name", "customEvent");
141 | long end = System.currentTimeMillis();
142 | long start = end-60000;
143 | String json = serviceTest.getCustomEvents("tenant", start,end,queryMap,dimMap);
144 | ObjectMapper mapper = new ObjectMapper();
145 | JsonNode n = mapper.readTree(json);
146 | assertTrue(n.size()==3, "3 expected");
147 | }
148 |
149 | public static Cantor getCantorInstance() {
150 | try {
151 | return new CantorOnH2("/tmp/mat-report-job-test/" + UUID.randomUUID().toString());
152 | } catch (Exception e) {
153 | return null;
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/perfgenie/src/test/resources/test.jfr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/perfgenie/src/test/resources/test.jfr
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.4.13
9 |
10 |
11 | pom
12 |
13 | com.perfgenie
14 | perfgenie-parent
15 | 0.0.1-SNAPSHOT
16 |
17 |
18 | 1.8
19 | 2.5.1
20 | 2.4
21 | 0.14.1
22 | 2.7
23 | 0.8.0
24 | ${project.basedir}/../target/jacoco.exec
25 | 1.8
26 | 1.8
27 | false
28 |
29 |
30 |
31 |
32 | org.openjdk.jmc
33 | common
34 | 8.2.1
35 |
36 |
37 | org.openjdk.jmc
38 | flightrecorder
39 | 8.2.1
40 |
41 |
42 | org.openjdk.jmc
43 | flightrecorder.rules
44 | 8.2.1
45 |
46 |
47 | org.openjdk.jmc
48 | flightrecorder.rules.jdk
49 | 8.2.1
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.apache.maven.plugins
58 | maven-source-plugin
59 |
60 |
61 |
62 | org.apache.maven.plugins
63 | maven-compiler-plugin
64 | ${mvn.plugins.compiler.version}
65 |
66 | ${source.version}
67 | ${target.version}
68 |
69 | **/*.java
70 | **/*.proto
71 | **/*.conf
72 |
73 |
74 |
75 |
76 |
77 | org.apache.maven.plugins
78 | maven-resources-plugin
79 | ${mvn.plugins.resources.version}
80 |
81 |
82 |
83 | copy-resources
84 | validate
85 |
86 | copy-resources
87 |
88 |
89 | ${basedir}/target/generated-sources/protobuf
90 |
91 |
92 | src/main/resources/protos
93 | true
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | simulator
105 | utils
106 | perfgenie
107 | agent
108 |
109 |
110 |
--------------------------------------------------------------------------------
/simulator/README.md:
--------------------------------------------------------------------------------
1 | # Java Transaction Simulator
2 |
3 |
4 |
5 | Java Transaction Simulator is a load generation tool that provides a way to simulate Transactions using threads. This simulator can generate High CPU, High Memory, and High DiskIO transactions with a user-chosen probability. This simulator is designed to generate datasets to compare the merits of various visualization tools available for exploring Java Flight Recorder (JFR) profiles to diagnose performance issues.
6 |
7 | ### Usage
8 |
9 | #### Clone & build the repository
10 |
11 | ```sh
12 | $ git clone https://github.com/salesforce-misc/perfGenie.git
13 | $ export JAVA_HOME=
14 | $ mvn clean install
15 | ```
16 | #### Run
17 |
18 | ```sh
19 | usage: java -jar simulator/target/simulator-0.0.1-SNAPSHOT.jar [-b ]
20 | [-c ] [-d ] [-i ] [-m ] [-t ]
21 | -b,--txCount Transactions per simulator (Default: 1000)
22 |
23 | -c,--highCpuProb High CPU event probability (Default: 0.05)
24 |
25 | -d,--maxDepth Max depth of transaction trace (Default: 10)
26 |
27 | -i,--highIoProb High IO events probability (Default: 0.01)
28 |
29 | -m,--highMemoryProb High Memory event probability (Default: 0.01)
30 |
31 | -t,--threads Simulator instance count (Default: 10)
32 |
33 | Note: Probability values range form (0-1)
34 | ```
35 |
36 | ### Dataset Generation
37 |
38 | The simulator generates the following different types of data. Each of these types have their own merits which highlight's different types of performance characteristics of a Java Application.
39 |
40 | #### JFR Profiles
41 | A detailed introduction to [Java Flight Recorder (JFR)](https://docs.oracle.com/javacomponents/jmc-5-5/jfr-runtime-guide/about.htm#JFRRT107) is provided in the official documentations. The steps provided below will help with collecting a JFR recoding for this simulator application using [Java Mission Control (JMC)](https://www.oracle.com/java/technologies/jdk-mission-control.html) tool.
42 | 1. Download and install the JMC tool for your platform from [JMC Download Website](https://www.oracle.com/java/technologies/javase/products-jmc8-downloads.html)
43 | 2. Run the simulator with your preferred options
44 | 3. Open the JMC tool start a JFR recording by choosing the simulator application from the JVM browser table as shown in the below image
45 |
46 | 4. Follow onscreen instructions to complete the JFR recording in JMC tool.
47 |
48 | #### JFR Custom Events
49 | By default, below simple custom JFR events are emitted by the Simulator.
50 | - CPUEvent - This event records the CPU load generated by the simulator every minute
51 | - TxCPUEvent - This event records the transaction level CPU consumption
52 |
53 | This simulator tool can be extended further to include additional events/fields as required. A simple example would be adding a tenant field into the custom events to simulate a multi tenant application behaviour.
54 |
55 | #### JStack Data
56 |
57 | The simulator is configured to collect [JStack](https://docs.oracle.com/javase/7/docs/technotes/tools/share/jstack.html) samples during its run every minute to provide a snapshot of the threads/transactions running in the simulator. These are collect along with the CPU load to give an approximate estimate of what stack traces are contributing the CPU usage.
58 |
--------------------------------------------------------------------------------
/simulator/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | com.perfgenie
9 | perfgenie-parent
10 | 0.0.1-SNAPSHOT
11 |
12 |
13 | simulator
14 | 0.0.1-SNAPSHOT
15 |
16 |
17 |
18 | commons-cli
19 | commons-cli
20 | 1.3.1
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/simulator/src/main/java/CPUEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Salesforce.com, Inc.
3 | * All rights reserved.
4 | * SPDX-License-Identifier: BSD-3-Clause
5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6 | */
7 |
8 | import jdk.jfr.Event;
9 | import jdk.jfr.Label;
10 |
11 | class CPUEvent extends Event {
12 | @Label("tenant")
13 | String tenant;
14 |
15 | @Label("cpuPerc")
16 | double cpuPerc;
17 | }
18 |
--------------------------------------------------------------------------------
/simulator/src/main/java/Simulator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Salesforce.com, Inc.
3 | * All rights reserved.
4 | * SPDX-License-Identifier: BSD-3-Clause
5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6 | */
7 |
8 | import com.sun.management.OperatingSystemMXBean;
9 | import org.apache.commons.cli.*;
10 |
11 | import javax.tools.*;
12 | import java.io.*;
13 | import java.lang.management.ManagementFactory;
14 | import java.lang.reflect.Method;
15 | import java.net.InetAddress;
16 | import java.net.URL;
17 | import java.net.URLClassLoader;
18 | import java.net.UnknownHostException;
19 | import java.util.*;
20 | import java.util.stream.Collectors;
21 |
22 | public class Simulator extends Thread {
23 | public static OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
24 | static int maxDepth, txCount;
25 | static Float highCpuProb, highMemoryProb, highIOProb;
26 | static Map codeBlocks;
27 | static String hostname;
28 |
29 | Simulator() {
30 | try {
31 | hostname = InetAddress.getLocalHost().getHostName();
32 | } catch (UnknownHostException e) {
33 | e.printStackTrace();
34 | }
35 | codeBlocks = new HashMap<>();
36 | codeBlocks.put("methodTemplate", "\n public static void %s(int depth) throws InterruptedException {\n" +
37 | " if(depth>=maxDepth){\n" +
38 | " switch(rand.nextInt(3)) {\n" +
39 | " case 0:\n" +
40 | " cpu();\n" +
41 | " return;\n" +
42 | " case 1:\n" +
43 | " io();\n" +
44 | " return;\n" +
45 | " case 2:\n" +
46 | " memory();\n" +
47 | " return;\n" +
48 | " }\n" +
49 | " }\n" +
50 | " switch(rand.nextInt(maxDepth)) {\n" +
51 | "%s" +
52 | " }\n" +
53 | " }\n");
54 | codeBlocks.put("caseMethodCall", "%s(depth+rand.nextInt(3));\n");
55 | codeBlocks.put("caseTemplate", " case %s:\n" +
56 | " %s" +
57 | " break;\n");
58 | }
59 |
60 | private static String getSource() {
61 | final StringBuilder methods = new StringBuilder();
62 | final ClassLoader classloader = Thread.currentThread().getContextClassLoader();
63 | final String classTemplate = new BufferedReader(new InputStreamReader(Objects.requireNonNull(classloader.getResourceAsStream("class.template"))))
64 | .lines().collect(Collectors.joining("\n"));
65 | for(int i=0; i threads = new HashMap<>();
122 |
123 | txCount = Integer.parseInt(cmd.getOptionValue("txCount", "1000"));
124 | maxDepth = Integer.parseInt(cmd.getOptionValue("maxDepth", "10"));
125 | highCpuProb = Float.parseFloat(cmd.getOptionValue("highCpuProb", "0.5"));
126 | highMemoryProb = Float.parseFloat(cmd.getOptionValue("highMemoryProb", "0.01"));
127 | highIOProb = Float.parseFloat(cmd.getOptionValue("highIOProb", "0.01"));
128 |
129 | System.out.println("Available processors: "+ osBean.getAvailableProcessors());
130 | long pid = Long.parseLong(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
131 |
132 | for(int i = 0; i < threadCount; ++i) {
133 | threads.put(i, new Simulator());
134 | threads.get(i).start();
135 | }
136 |
137 | while(true) {
138 | Thread.sleep(60000L);
139 | final CPUEvent cpuEvent = new CPUEvent();
140 | cpuEvent.begin();
141 | cpuEvent.tenant = hostname;
142 | cpuEvent.cpuPerc = osBean.getProcessCpuLoad()*100;
143 | final File outFile = new File(String.format("%s_%s.jstack", pid, System.currentTimeMillis()));
144 | final ProcessBuilder builder = new ProcessBuilder("jstack", "-l" , String.valueOf(pid));
145 | builder.redirectOutput(outFile);
146 | builder.redirectError(outFile);
147 | builder.start();
148 | cpuEvent.commit();
149 | System.out.println("CPU Usage: " + osBean.getProcessCpuLoad());
150 | }
151 | }
152 |
153 | private static void generateAndExecSourceFile() throws Exception {
154 | File sourceFile = File.createTempFile("Class", ".java");
155 | sourceFile.deleteOnExit();
156 | writeMethods(sourceFile);
157 | compileAndExecSource(sourceFile);
158 | }
159 |
160 | private static void compileAndExecSource(final File sourceFile) throws Exception {
161 | final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
162 | final StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
163 | final File parentDirectory = sourceFile.getParentFile();
164 | fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singletonList(parentDirectory));
165 | final File txCpuClass = new File("simulator/src/main/java/TxCPUEvent.java");
166 |
167 | final Iterable extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile, txCpuClass));
168 | compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
169 | fileManager.close();
170 |
171 | final URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{parentDirectory.toURI().toURL()});
172 | final Class> genClass = classLoader.loadClass(sourceFile.getName().split("\\.")[0]);
173 | final Method mainMethod = genClass.getDeclaredMethod("main", String[].class);
174 | final Object[] args = new Object[1];
175 | System.out.println(Thread.currentThread().getName() + " executing the simulator");
176 | mainMethod.invoke(genClass.newInstance(), args);
177 | }
178 |
179 | private static void writeMethods(final File sourceFile) throws Exception {
180 | final FileWriter writer = new FileWriter(sourceFile);
181 | writer.write("");
182 | writer.write(getSource().replace("CLASS_NAME", sourceFile.getName().split("\\.")[0]));
183 | writer.close();
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/simulator/src/main/java/TxCPUEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Salesforce.com, Inc.
3 | * All rights reserved.
4 | * SPDX-License-Identifier: BSD-3-Clause
5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6 | */
7 |
8 | import jdk.jfr.Event;
9 | import jdk.jfr.Label;
10 |
11 | public class TxCPUEvent extends Event {
12 | @Label("cpu")
13 | public double cpu;
14 | }
15 |
--------------------------------------------------------------------------------
/simulator/src/main/resources/class.template:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Salesforce.com, Inc.
3 | * All rights reserved.
4 | * SPDX-License-Identifier: BSD-3-Clause
5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6 | */
7 |
8 | import java.io.File;
9 | import java.lang.management.ManagementFactory;
10 | import java.lang.management.ThreadMXBean;
11 | import java.nio.charset.StandardCharsets;
12 | import java.nio.file.Files;
13 | import java.nio.file.StandardOpenOption;
14 | import java.util.Random;
15 | import java.util.Map;
16 | import java.util.HashMap;
17 |
18 | public class CLASS_NAME {
19 | final static Random rand = new Random();
20 | final static ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
21 | final static int maxDepth=%s, txCount=%s;
22 |
23 | public static void memory() {
24 | int memAllocSize;
25 | if(rand.nextInt(100)<=%s) {
26 | memAllocSize=8192;
27 | } else {
28 | memAllocSize=1024;
29 | }
30 | for(int i=0; i < memAllocSize; i++) {
31 | byte[] bytes = new byte[1048576]; // 1MB
32 | bytes[0] = 'c';
33 | }
34 | }
35 |
36 | public static void cpu() {
37 | long loopTime;
38 | if(rand.nextInt(100)<=%s) {
39 | loopTime=5_000L;
40 | } else {
41 | loopTime=500L;
42 | }
43 | long startTime = System.currentTimeMillis();
44 | Map counts = new HashMap<>();
45 | int i=0;
46 | String rand = "";
47 | while ((System.currentTimeMillis() - startTime) < loopTime) {
48 | counts.put(i, i);
49 | rand += i;
50 | }
51 | }
52 |
53 | public static void io() {
54 | try {
55 | File tmp = File.createTempFile("data", null);
56 | tmp.deleteOnExit();
57 | byte[] genStr = null;
58 | int tempFileSize;
59 | if(rand.nextInt(100)<=%s) {
60 | tempFileSize=64;
61 | } else {
62 | tempFileSize=8;
63 | }
64 | for(int i=0; i (c<=57 || c>=65) && (c<=90 || c>=97))
67 | .limit(1048576) // 1MB
68 | .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
69 | .toString().getBytes(StandardCharsets.UTF_8);
70 | Files.write(tmp.toPath(), genStr, StandardOpenOption.CREATE);
71 | }
72 | } catch (Exception ignored) {
73 | }
74 | }
75 | %s
76 | public static void main(String[] args) throws InterruptedException {
77 | for(int i=0; i
2 |
5 |
6 | perfgenie-parent
7 | com.perfgenie
8 | 0.0.1-SNAPSHOT
9 |
10 | 4.0.0
11 | perfgenie.utils
12 | jar
13 | perfgenie.utils
14 |
15 |
16 | 11
17 | 11
18 |
19 |
20 |
21 |
22 | org.openjdk.jmc
23 | common
24 | 8.2.1
25 |
26 |
27 | org.openjdk.jmc
28 | flightrecorder
29 | 8.2.1
30 |
31 |
32 | org.openjdk.jmc
33 | flightrecorder.rules
34 | 8.2.1
35 |
36 |
37 | org.openjdk.jmc
38 | flightrecorder.rules.jdk
39 | 8.2.1
40 |
41 |
42 | com.salesforce.cantor
43 | cantor-h2
44 | 0.5.0
45 |
46 |
47 | com.salesforce.cantor
48 | cantor-grpc-client
49 | 0.5.0
50 |
51 |
52 | com.salesforce.cantor
53 | cantor-mysql
54 | 0.5.0
55 |
56 |
57 | com.fasterxml.jackson.core
58 | jackson-core
59 | 2.12.6
60 |
61 |
62 | com.fasterxml.jackson.core
63 | jackson-databind
64 | 2.12.6.1
65 |
66 |
67 | org.testng
68 | testng
69 | 6.14.3
70 | test
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/utils/src/main/java/perfgenie/utils/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Salesforce.com, Inc.
3 | * All rights reserved.
4 | * SPDX-License-Identifier: BSD-3-Clause
5 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6 | */
7 |
8 | package perfgenie.utils;
9 |
10 | import com.fasterxml.jackson.core.JsonProcessingException;
11 | import com.fasterxml.jackson.databind.ObjectMapper;
12 | import com.google.common.io.ByteStreams;
13 |
14 | import java.io.ByteArrayInputStream;
15 | import java.io.ByteArrayOutputStream;
16 | import java.io.IOException;
17 | import java.util.UUID;
18 | import java.util.zip.GZIPInputStream;
19 | import java.util.zip.GZIPOutputStream;
20 |
21 | public class Utils {
22 | // special handling for lambdas
23 | private static String lambdaFrameIndicator = "Lambda$";
24 | private static char lambdaBeginningCharacter = lambdaFrameIndicator.charAt(0);
25 | // special handling for sfdc generated frames
26 | private static String sfdcGeneratedFrameIndicator = "EnhancerBySpringCGLIB$$";
27 | private static char sfdcGeneratedBeginningCharacter = sfdcGeneratedFrameIndicator.charAt(0);
28 | private static final ObjectMapper objectMapper = new ObjectMapper();
29 |
30 | public static boolean trimAfterNthMatchingCharacter(final String str, final StringBuilder builder, final int count, char trimAfter){
31 | int length = str.length();
32 | int c=0;
33 | for (int i = 0; i < length; i++) {
34 | final char character = str.charAt(i);
35 | if(character == trimAfter){
36 | c++;
37 | }
38 | if(c >= count){
39 | return true;
40 | }
41 | builder.append(character);
42 | }
43 | return false;
44 | }
45 | public static boolean normalizeFrame(final String frame, final StringBuilder builder, final int startIndex) {
46 | boolean previousCharacterDollarSign = false;
47 | boolean previousCharacterNormalized = false;
48 | boolean isNormalized = false;
49 | for (int i = startIndex; i < frame.length(); i++) {
50 | final char character = frame.charAt(i);
51 | // open parentheses indicates we're done, throw away parentheses/filename
52 | if (character == '(') {
53 | return isNormalized;
54 | }
55 | // dollar sign indicates potential start of lambda
56 | if (character == '$') {
57 | // always append dollar signs (don't normalize them)
58 | builder.append(character);
59 | // if the frame is a lambda, normalize the rest and we're done
60 | if (frameIsLambda(frame, i, previousCharacterDollarSign)) {
61 | normalizeLambdaFrame(frame, i, builder);
62 | isNormalized=true;
63 | return isNormalized;
64 | }
65 | // can't tell if frame is lambda yet, indicate we've seen a dollar sign and continue to next character
66 | previousCharacterDollarSign = true;
67 | continue;
68 | } else {
69 | previousCharacterDollarSign = false;
70 | }
71 |
72 | final boolean shouldNormalize = shouldNormalizeCharacter(character);
73 | if (!shouldNormalize) {
74 | builder.append(character);
75 | previousCharacterNormalized = false;
76 | } else if (!previousCharacterNormalized) {
77 | builder.append('?');
78 | isNormalized=true;
79 | previousCharacterNormalized = true;
80 | }
81 | }
82 | return isNormalized;
83 | }
84 |
85 |
86 | private static void normalizeLambdaFrame(final String frame, final int index, final StringBuilder normalized) {
87 | final char nextCharacter = frame.charAt(index + 1);
88 | if (nextCharacter == lambdaBeginningCharacter) {
89 | // append the indicator and a replacement for the guid
90 | normalized.append(lambdaFrameIndicator).append("?");
91 | // normalize the rest of the method
92 | normalizeFrame(frame, normalized, getNextPeriodIndex(frame, index + lambdaFrameIndicator.length()));
93 | } else if (nextCharacter == sfdcGeneratedBeginningCharacter) {
94 | // append the indicator and a replacement for the guid
95 | normalized.append(sfdcGeneratedFrameIndicator).append("?");
96 | // skip over the guid until we reach the '.' indicating the start of the method name
97 | // normalize the rest of the method
98 | normalizeFrame(frame, normalized, getNextPeriodIndex(frame, index + sfdcGeneratedFrameIndicator.length()));
99 | } else {
100 | // neither lambda nor sfdc generated code, just normalize the rest
101 | normalizeFrame(frame, normalized, index);
102 | }
103 | }
104 |
105 | private static boolean shouldNormalizeCharacter(final char c) {
106 | // valid characters are [a-zA-Z.$<>] -> normalize everything else
107 | // (we don't check for c == '$' here because we've done it above in lambda checks)
108 | return !(Character.isLetter(c) || (c == '.' || c == '<' || c == '>'));
109 | }
110 |
111 | private static boolean frameIsLambda(final String frame, final int index, final boolean previousCharacterDollarSign) {
112 | return previousCharacterDollarSign && frame.length() > index + 1;
113 | }
114 |
115 | private static int getNextPeriodIndex(final String frame, final int start) {
116 | int skipTo = start;
117 | while (skipTo < frame.length() && frame.charAt(skipTo) != '.') {
118 | skipTo++;
119 | }
120 | return skipTo;
121 | }
122 |
123 | public static byte[] compress(final byte[] bytes) throws IOException {
124 | if (bytes == null || bytes.length == 0) {
125 | return new byte[0];
126 | }
127 |
128 | try (final ByteArrayOutputStream bos = new ByteArrayOutputStream(bytes.length);
129 | final GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
130 | gzip.write(bytes);
131 | gzip.finish();
132 | return bos.toByteArray();
133 | }
134 | }
135 |
136 | public static byte[] decompress(final byte[] compressedBytes) throws IOException {
137 | if (compressedBytes == null || compressedBytes.length == 0) {
138 | return new byte[0];
139 | }
140 |
141 | final byte[] unzippedPayload;
142 | try (final ByteArrayInputStream byteStream = new ByteArrayInputStream(compressedBytes);
143 | final GZIPInputStream gzis = new GZIPInputStream(byteStream)) {
144 | unzippedPayload = ByteStreams.toByteArray(gzis);
145 | }
146 |
147 | return unzippedPayload;
148 | }
149 |
150 | public static String toJson(final Object object) {
151 | try {
152 | return objectMapper.writeValueAsString(object);
153 | } catch (final JsonProcessingException e) {
154 | return "{\"error\": \"" +
155 | e.getMessage() +
156 | "\"}";
157 | }
158 | }
159 |
160 | public static Object readValue(final String json, final Class cls) throws IOException{
161 | try {
162 | return objectMapper.readValue(json, cls);
163 | } catch (final JsonProcessingException e) {
164 | return "{\"error\": \"" +
165 | e.getMessage() +
166 | "\"}";
167 | }
168 | }
169 |
170 | public static String generateGuid() {
171 | return UUID.randomUUID().toString();
172 | }
173 |
174 | }
175 |
--------------------------------------------------------------------------------
/utils/src/test/java/DownloadUploadTest.java:
--------------------------------------------------------------------------------
1 | import com.google.common.io.Resources;
2 | import com.salesforce.cantor.Cantor;
3 | import com.salesforce.cantor.h2.CantorOnH2;
4 | import org.testng.annotations.AfterSuite;
5 | import org.testng.annotations.BeforeSuite;
6 | import org.testng.annotations.Test;
7 | import perfgenie.utils.EventStore;
8 |
9 | import java.io.IOException;
10 | import java.nio.charset.StandardCharsets;
11 | import java.util.HashMap;
12 | import java.util.UUID;
13 |
14 | import static org.testng.AssertJUnit.assertEquals;
15 |
16 | public class DownloadUploadTest {
17 | private final long timestamp = System.currentTimeMillis();
18 |
19 | private static EventStore eventStore;
20 |
21 | static {
22 | try {
23 | eventStore = new EventStore(getCantorInstance());
24 | } catch (IOException e) {
25 | e.printStackTrace();
26 | }
27 | }
28 |
29 | @BeforeSuite
30 | public void setup() throws IOException {
31 | }
32 |
33 | @Test
34 | public void test() throws IOException {
35 | final String original = Resources.toString(Resources.getResource("test.jfr"), StandardCharsets.UTF_8);
36 | eventStore.addEvent(timestamp, new HashMap<>(), new HashMap<>(), original);
37 |
38 | final String downloaded = eventStore.getEvent(timestamp, timestamp, new HashMap<>(), new HashMap<>(), original.length());
39 | assertEquals(original, downloaded);
40 | }
41 |
42 | @AfterSuite
43 | public void cleanup() throws IOException {
44 | }
45 |
46 | public static Cantor getCantorInstance() {
47 | try {
48 | return new CantorOnH2("/tmp/mat-report-job-test/" + UUID.randomUUID().toString());
49 | } catch (Exception e) {
50 | return null;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/utils/src/test/resources/test.jfr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salesforce-misc/perfGenie/30ed82d2f5e8bcdc8989fa4b37f152d7a516f21d/utils/src/test/resources/test.jfr
--------------------------------------------------------------------------------