<commit_before>/**
 * Requirements
 * @ignore
 */
const path = require('path');
require('./configuration.js');

/**
 * Public API
 * @ignore
 */
module.exports =
{
    BaseShared: require('./BaseShared.js').spec,
    fixture:
    {
        files: path.join(__dirname, '/__fixtures__/files'),
        project: require('./__fixtures__/project/index.js')
    },
    export:
    {
        ConfigurationShared: require('./export/ConfigurationShared.js').spec,
        ParserShared: require('./export/ParserShared.js').spec,
        NodeRendererShared: require('./export/renderer/NodeRendererShared.js').spec,
        RendererShared: require('./export/RendererShared.js').spec
    },
    linter:
    {
        LinterShared: require('./linter/LinterShared.js').spec,
        FileLinterShared: require('./linter/FileLinterShared.js').spec
    },
    model:
    {
        loader:
        {
            LoaderPluginShared: require('./model/loader/LoaderPluginShared.js').spec
        }
    },
    nunjucks:
    {
        FilterShared: require('./nunjucks/filter/FilterShared.js').spec
    },
    parser:
    {
        ParserShared: require('./parser/ParserShared.js').spec,
        FileParserShared: require('./parser/FileParserShared.js').spec
    },
    server:
    {
        RouteShared: require('./server/route/RouteShared.js').spec
    },
    task:
    {
        TaskShared: require('./task/TaskShared.js').spec,
        TransformingTaskShared: require('./task/TransformingTaskShared.js').spec
    }
};
<commit_msg>test: exposes CommandShared<commit_after>/**
 * Requirements
 * @ignore
 */
const path = require('path');
require('./configuration.js');

/**
 * Public API
 * @ignore
 */
module.exports =
{
    BaseShared: require('./BaseShared.js').spec,
    fixture:
    {
        files: path.join(__dirname, '/__fixtures__/files'),
        project: require('./__fixtures__/project/index.js')
    },
    command:
    {
        CommandShared: require('./command/CommandShared.js').spec
    },
    export:
    {
        ConfigurationShared: require('./export/ConfigurationShared.js').spec,
        ParserShared: require('./export/ParserShared.js').spec,
        NodeRendererShared: require('./export/renderer/NodeRendererShared.js').spec,
        RendererShared: require('./export/RendererShared.js').spec
    },
    linter:
    {
        LinterShared: require('./linter/LinterShared.js').spec,
        FileLinterShared: require('./linter/FileLinterShared.js').spec
    },
    model:
    {
        loader:
        {
            LoaderPluginShared: require('./model/loader/LoaderPluginShared.js').spec
        }
    },
    nunjucks:
    {
        FilterShared: require('./nunjucks/filter/FilterShared.js').spec
    },
    parser:
    {
        ParserShared: require('./parser/ParserShared.js').spec,
        FileParserShared: require('./parser/FileParserShared.js').spec
    },
    server:
    {
        RouteShared: require('./server/route/RouteShared.js').spec
    },
    task:
    {
        TaskShared: require('./task/TaskShared.js').spec,
        TransformingTaskShared: require('./task/TransformingTaskShared.js').spec
    }
};
<|endoftext|>


<commit_before>/*!
 * numeral.js
 * version : 1.5.3
 * author : Adam Draper
 * license : MIT
 * http://adamwdraper.github.com/Numeral-js/
 */
(function(){function a(a){this._value=a}function b(a,b,c,d){var e,f,g=Math.pow(10,b);return f=(c(a*g)/g).toFixed(b),d&&(e=new RegExp("0{1,"+d+"}$"),f=f.replace(e,"")),f}function c(a,b,c){var d;return d=b.indexOf("$")>-1?e(a,b,c):b.indexOf("%")>-1?f(a,b,c):b.indexOf(":")>-1?g(a,b):i(a._value,b,c)}function d(a,b){var c,d,e,f,g,i=b,j=["KB","MB","GB","TB","PB","EB","ZB","YB"],k=!1;if(b.indexOf(":")>-1)a._value=h(b);else if(b===q)a._value=0;else{for("."!==o[p].delimiters.decimal&&(b=b.replace(/\./g,"").replace(o[p].delimiters.decimal,".")),c=new RegExp("[^a-zA-Z]"+o[p].abbreviations.thousand+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),d=new RegExp("[^a-zA-Z]"+o[p].abbreviations.million+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),e=new RegExp("[^a-zA-Z]"+o[p].abbreviations.billion+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),f=new RegExp("[^a-zA-Z]"+o[p].abbreviations.trillion+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),g=0;g<=j.length&&!(k=b.indexOf(j[g])>-1?Math.pow(1024,g+1):!1);g++);a._value=(k?k:1)*(i.match(c)?Math.pow(10,3):1)*(i.match(d)?Math.pow(10,6):1)*(i.match(e)?Math.pow(10,9):1)*(i.match(f)?Math.pow(10,12):1)*(b.indexOf("%")>-1?.01:1)*((b.split("-").length+Math.min(b.split("(").length-1,b.split(")").length-1))%2?1:-1)*Number(b.replace(/[^0-9\.]+/g,"")),a._value=k?Math.ceil(a._value):a._value}return a._value}function e(a,b,c){var d,e,f=b.indexOf("$"),g=b.indexOf("("),h=b.indexOf("-"),j="";return b.indexOf(" $")>-1?(j=" ",b=b.replace(" $","")):b.indexOf("$ ")>-1?(j=" ",b=b.replace("$ ","")):b=b.replace("$",""),e=i(a._value,b,c),1>=f?e.indexOf("(")>-1||e.indexOf("-")>-1?(e=e.split(""),d=1,(g>f||h>f)&&(d=0),e.splice(d,0,o[p].currency.symbol+j),e=e.join("")):e=o[p].currency.symbol+j+e:e.indexOf(")")>-1?(e=e.split(""),e.splice(-1,0,j+o[p].currency.symbol),e=e.join("")):e=e+j+o[p].currency.symbol,e}function f(a,b,c){var d,e="",f=100*a._value;return b.indexOf(" %")>-1?(e=" ",b=b.replace(" %","")):b=b.replace("%",""),d=i(f,b,c),d.indexOf(")")>-1?(d=d.split(""),d.splice(-1,0,e+"%"),d=d.join("")):d=d+e+"%",d}function g(a){var b=Math.floor(a._value/60/60),c=Math.floor((a._value-60*b*60)/60),d=Math.round(a._value-60*b*60-60*c);return b+":"+(10>c?"0"+c:c)+":"+(10>d?"0"+d:d)}function h(a){var b=a.split(":"),c=0;return 3===b.length?(c+=60*Number(b[0])*60,c+=60*Number(b[1]),c+=Number(b[2])):2===b.length&&(c+=60*Number(b[0]),c+=Number(b[1])),Number(c)}function i(a,c,d){var e,f,g,h,i,j,k=!1,l=!1,m=!1,n="",r=!1,s=!1,t=!1,u=!1,v=!1,w="",x="",y=Math.abs(a),z=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],A="",B=!1;if(0===a&&null!==q)return q;if(c.indexOf("(")>-1?(k=!0,c=c.slice(1,-1)):c.indexOf("+")>-1&&(l=!0,c=c.replace(/\+/g,"")),c.indexOf("a")>-1&&(r=c.indexOf("aK")>=0,s=c.indexOf("aM")>=0,t=c.indexOf("aB")>=0,u=c.indexOf("aT")>=0,v=r||s||t||u,c.indexOf(" a")>-1?(n=" ",c=c.replace(" a","")):c=c.replace("a",""),y>=Math.pow(10,12)&&!v||u?(n+=o[p].abbreviations.trillion,a/=Math.pow(10,12)):y<Math.pow(10,12)&&y>=Math.pow(10,9)&&!v||t?(n+=o[p].abbreviations.billion,a/=Math.pow(10,9)):y<Math.pow(10,9)&&y>=Math.pow(10,6)&&!v||s?(n+=o[p].abbreviations.million,a/=Math.pow(10,6)):(y<Math.pow(10,6)&&y>=Math.pow(10,3)&&!v||r)&&(n+=o[p].abbreviations.thousand,a/=Math.pow(10,3))),c.indexOf("b")>-1)for(c.indexOf(" b")>-1?(w=" ",c=c.replace(" b","")):c=c.replace("b",""),g=0;g<=z.length;g++)if(e=Math.pow(1024,g),f=Math.pow(1024,g+1),a>=e&&f>a){w+=z[g],e>0&&(a/=e);break}return c.indexOf("o")>-1&&(c.indexOf(" o")>-1?(x=" ",c=c.replace(" o","")):c=c.replace("o",""),x+=o[p].ordinal(a)),c.indexOf("[.]")>-1&&(m=!0,c=c.replace("[.]",".")),h=a.toString().split(".")[0],i=c.split(".")[1],j=c.indexOf(","),i?(i.indexOf("[")>-1?(i=i.replace("]",""),i=i.split("["),A=b(a,i[0].length+i[1].length,d,i[1].length)):A=b(a,i.length,d),h=A.split(".")[0],A=A.split(".")[1].length?o[p].delimiters.decimal+A.split(".")[1]:"",m&&0===Number(A.slice(1))&&(A="")):h=b(a,null,d),h.indexOf("-")>-1&&(h=h.slice(1),B=!0),j>-1&&(h=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+o[p].delimiters.thousands)),0===c.indexOf(".")&&(h=""),(k&&B?"(":"")+(!k&&B?"-":"")+(!B&&l?"+":"")+h+A+(x?x:"")+(n?n:"")+(w?w:"")+(k&&B?")":"")}function j(a,b){o[a]=b}function k(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)}function l(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var c=k(a),d=k(b);return c>d?c:d},-1/0)}var m,n="1.5.3",o={},p="en",q=null,r="0,0",s="undefined"!=typeof module&&module.exports;m=function(b){return m.isNumeral(b)?b=b.value():0===b||"undefined"==typeof b?b=0:Number(b)||(b=m.fn.unformat(b)),new a(Number(b))},m.version=n,m.isNumeral=function(b){return b instanceof a},m.language=function(a,b){if(!a)return p;if(a&&!b){if(!o[a])throw new Error("Unknown language : "+a);p=a}return(b||!o[a])&&j(a,b),m},m.languageData=function(a){if(!a)return o[p];if(!o[a])throw new Error("Unknown language : "+a);return o[a]},m.language("en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"}}),m.zeroFormat=function(a){q="string"==typeof a?a:null},m.defaultFormat=function(a){r="string"==typeof a?a:"0.0"},"function"!=typeof Array.prototype.reduce&&(Array.prototype.reduce=function(a,b){"use strict";if(null===this||"undefined"==typeof this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof a)throw new TypeError(a+" is not a function");var c,d,e=this.length>>>0,f=!1;for(1<arguments.length&&(d=b,f=!0),c=0;e>c;++c)this.hasOwnProperty(c)&&(f?d=a(d,this[c],c,this):(d=this[c],f=!0));if(!f)throw new TypeError("Reduce of empty array with no initial value");return d}),m.fn=a.prototype={clone:function(){return m(this)},format:function(a,b){return c(this,a?a:r,void 0!==b?b:Math.round)},unformat:function(a){return"[object Number]"===Object.prototype.toString.call(a)?a:d(this,a?a:r)},value:function(){return this._value},valueOf:function(){return this._value},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b){return a+c*b}var c=l.call(null,this._value,a);return this._value=[this._value,a].reduce(b,0)/c,this},subtract:function(a){function b(a,b){return a-c*b}var c=l.call(null,this._value,a);return this._value=[a].reduce(b,this._value*c)/c,this},multiply:function(a){function b(a,b){var c=l(a,b);return a*c*b*c/(c*c)}return this._value=[this._value,a].reduce(b,1),this},divide:function(a){function b(a,b){var c=l(a,b);return a*c/(b*c)}return this._value=[this._value,a].reduce(b),this},difference:function(a){return Math.abs(m(this._value).subtract(a).value())}},s&&(module.exports=m),"undefined"==typeof ender&&(this.numeral=m),"function"==typeof define&&define.amd&&define([],function(){return m})}).call(this);<commit_msg>Fix issue #1<commit_after>/*!
 * numeral.js
 * version : 1.5.3
 * author : Adam Draper
 * license : MIT
 * http://adamwdraper.github.com/Numeral-js/
 */
(function(){function a(a){this._value=a}function b(a,b,c,d){var e,f,g=Math.pow(10,b);return f=(c(a*g)/g).toFixed(b),d&&(e=new RegExp("0{1,"+d+"}$"),f=f.replace(e,"")),f}function c(a,b,c){var d;return d=b.indexOf("$")>-1?e(a,b,c):b.indexOf("%")>-1?f(a,b,c):b.indexOf(":")>-1?g(a,b):i(a._value,b,c)}function d(a,b){var c,d,e,f,g,i=b,j=["KB","MB","GB","TB","PB","EB","ZB","YB"],k=!1;if(b.indexOf(":")>-1)a._value=h(b);else if(b===q)a._value=0;else{for("."!==o[p].delimiters.decimal&&(b=b.replace(/\./g,"").replace(o[p].delimiters.decimal,".")),c=new RegExp("[^a-zA-Z]"+o[p].abbreviations.thousand+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),d=new RegExp("[^a-zA-Z]"+o[p].abbreviations.million+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),e=new RegExp("[^a-zA-Z]"+o[p].abbreviations.billion+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),f=new RegExp("[^a-zA-Z]"+o[p].abbreviations.trillion+"(?:\\)|(\\"+o[p].currency.symbol+")?(?:\\))?)?$"),g=0;g<=j.length&&!(k=b.indexOf(j[g])>-1?Math.pow(1024,g+1):!1);g++);a._value=(k?k:1)*(i.match(c)?Math.pow(10,3):1)*(i.match(d)?Math.pow(10,6):1)*(i.match(e)?Math.pow(10,9):1)*(i.match(f)?Math.pow(10,12):1)*(b.indexOf("%")>-1?.01:1)*((b.split("-").length+Math.min(b.split("(").length-1,b.split(")").length-1))%2?1:-1)*Number(b.replace(/[^0-9\.]+/g,"")),a._value=k?Math.ceil(a._value):a._value}return a._value}function e(a,b,c){var d,e,f=b,g=f.indexOf("$"),h=f.indexOf("("),j=f.indexOf("-"),k="",l="";if(-1===f.indexOf("$")){switch(o[p].currency.position){case"postfix":g=2;break;case"infix":l=o[p].currency.symbol,o[p].currency.spaceSeparated&&(l=" "+l+" ");break;default:g=0}o[p].currency.spaceSeparated&&(k=" ")}else f.indexOf(" $")>-1?(k=" ",f=f.replace(" $","")):f.indexOf("$ ")>-1?(k=" ",f=f.replace("$ ","")):f=f.replace("$","");if(e=i(a._value,f,c,l),-1===b.indexOf("$"))switch(o[p].currency.position){case"postfix":e.indexOf(")")>-1?(e=e.split(""),e.splice(-1,0,k+o[p].currency.symbol),e=e.join("")):e=e+k+o[p].currency.symbol;break;case"infix":break;default:e.indexOf("(")>-1||e.indexOf("-")>-1?(e=e.split(""),d=1,(h>g||j>g)&&(d=0),e.splice(d,0,o[p].currency.symbol+k),e=e.join("")):e=o[p].currency.symbol+k+e}else 1>=g?e.indexOf("(")>-1||e.indexOf("-")>-1?(e=e.split(""),d=1,(h>g||j>g)&&(d=0),e.splice(d,0,o[p].currency.symbol+k),e=e.join("")):e=o[p].currency.symbol+k+e:e.indexOf(")")>-1?(e=e.split(""),e.splice(-1,0,k+o[p].currency.symbol),e=e.join("")):e=e+k+o[p].currency.symbol;return e}function f(a,b,c){var d,e="",f=100*a._value;return b.indexOf(" %")>-1?(e=" ",b=b.replace(" %","")):b=b.replace("%",""),d=i(f,b,c),d.indexOf(")")>-1?(d=d.split(""),d.splice(-1,0,e+"%"),d=d.join("")):d=d+e+"%",d}function g(a){var b=Math.floor(a._value/60/60),c=Math.floor((a._value-60*b*60)/60),d=Math.round(a._value-60*b*60-60*c);return b+":"+(10>c?"0"+c:c)+":"+(10>d?"0"+d:d)}function h(a){var b=a.split(":"),c=0;return 3===b.length?(c+=60*Number(b[0])*60,c+=60*Number(b[1]),c+=Number(b[2])):2===b.length&&(c+=60*Number(b[0]),c+=Number(b[1])),Number(c)}function i(a,c,d,e){var f,g,h,i,j,k,l=!1,m=!1,n=!1,r="",s=!1,t=!1,u=!1,v=!1,w=!1,x="",y="",z=Math.abs(a),A=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],B="",C=!1,D=!1;if(0===a&&null!==q)return q;if(-1!==c.indexOf("-")&&(C=!0),c.indexOf("(")>-1?(l=!0,c=c.slice(1,-1)):c.indexOf("+")>-1&&(m=!0,c=c.replace(/\+/g,"")),c.indexOf("a")>-1&&(s=c.indexOf("aK")>=0,t=c.indexOf("aM")>=0,u=c.indexOf("aB")>=0,v=c.indexOf("aT")>=0,w=s||t||u||v,c.indexOf(" a")>-1?(r=" ",c=c.replace(" a","")):c=c.replace("a",""),z>=Math.pow(10,12)&&!w||v?(r+=o[p].abbreviations.trillion,a/=Math.pow(10,12)):z<Math.pow(10,12)&&z>=Math.pow(10,9)&&!w||u?(r+=o[p].abbreviations.billion,a/=Math.pow(10,9)):z<Math.pow(10,9)&&z>=Math.pow(10,6)&&!w||t?(r+=o[p].abbreviations.million,a/=Math.pow(10,6)):(z<Math.pow(10,6)&&z>=Math.pow(10,3)&&!w||s)&&(r+=o[p].abbreviations.thousand,a/=Math.pow(10,3))),c.indexOf("b")>-1)for(c.indexOf(" b")>-1?(x=" ",c=c.replace(" b","")):c=c.replace("b",""),h=0;h<=A.length;h++)if(f=Math.pow(1024,h),g=Math.pow(1024,h+1),a>=f&&g>a){x+=A[h],f>0&&(a/=f);break}if(c.indexOf("o")>-1&&(c.indexOf(" o")>-1?(y=" ",c=c.replace(" o","")):c=c.replace("o",""),y+=o[p].ordinal(a)),c.indexOf("[.]")>-1&&(n=!0,c=c.replace("[.]",".")),i=a.toString().split(".")[0],j=c.split(".")[1],k=c.indexOf(","),j){if(j.indexOf("[")>-1?(j=j.replace("]",""),j=j.split("["),B=b(a,j[0].length+j[1].length,d,j[1].length)):B=b(a,j.length,d),i=B.split(".")[0],B.split(".")[1].length){var E=e?r+e:o[p].delimiters.decimal;B=E+B.split(".")[1]}else B="";n&&0===Number(B.slice(1))&&(B="")}else i=b(a,null,d);return i.indexOf("-")>-1&&(i=i.slice(1),D=!0),k>-1&&(i=i.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+o[p].delimiters.thousands)),0===c.indexOf(".")&&(i=""),(l&&D?"(":"")+(C&&D||!l&&D?"-":"")+(!D&&m?"+":"")+i+B+(y?y:"")+(r&&!e?r:"")+(x?x:"")+(l&&D?")":"")}function j(a,b){o[a]=b}function k(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)}function l(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var c=k(a),d=k(b);return c>d?c:d},-1/0)}var m,n="1.5.3",o={},p="en",q=null,r="0,0",s="0$",t="undefined"!=typeof module&&module.exports;m=function(b){return m.isNumeral(b)?b=b.value():0===b||"undefined"==typeof b?b=0:Number(b)||(b=m.fn.unformat(b)),new a(Number(b))},m.version=n,m.isNumeral=function(b){return b instanceof a},m.language=function(a,b){if(!a)return p;if(a&&!b){if(!o[a])throw new Error("Unknown language : "+a);p=a;var c=o[a].defaults;c&&c.format&&m.defaultFormat(c.format),c&&c.currencyFormat&&m.defaultCurrencyFormat(c.currencyFormat)}return(b||!o[a])&&j(a,b),m},m.languageData=function(a){if(!a)return o[p];if(!o[a])throw new Error("Unknown language : "+a);return o[a]},m.language("en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"},defaults:{currencyFormat:"$0[.]00"}}),m.zeroFormat=function(a){q="string"==typeof a?a:null},m.defaultFormat=function(a){r="string"==typeof a?a:"0.0"},m.defaultCurrencyFormat=function(a){s="string"==typeof a?a:"0$"},"function"!=typeof Array.prototype.reduce&&(Array.prototype.reduce=function(a,b){"use strict";if(null===this||"undefined"==typeof this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof a)throw new TypeError(a+" is not a function");var c,d,e=this.length>>>0,f=!1;for(1<arguments.length&&(d=b,f=!0),c=0;e>c;++c)this.hasOwnProperty(c)&&(f?d=a(d,this[c],c,this):(d=this[c],f=!0));if(!f)throw new TypeError("Reduce of empty array with no initial value");return d}),m.fn=a.prototype={clone:function(){return m(this)},format:function(a,b){return c(this,a?a:r,void 0!==b?b:Math.round)},formatCurrency:function(a,b){return e(this,a?a:s,void 0!==b?b:Math.round)},unformat:function(a){return"[object Number]"===Object.prototype.toString.call(a)?a:d(this,a?a:r)},value:function(){return this._value},valueOf:function(){return this._value},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b){return a+c*b}var c=l.call(null,this._value,a);return this._value=[this._value,a].reduce(b,0)/c,this},subtract:function(a){function b(a,b){return a-c*b}var c=l.call(null,this._value,a);return this._value=[a].reduce(b,this._value*c)/c,this},multiply:function(a){function b(a,b){var c=l(a,b);return a*c*b*c/(c*c)}return this._value=[this._value,a].reduce(b,1),this},divide:function(a){function b(a,b){var c=l(a,b);return a*c/(b*c)}return this._value=[this._value,a].reduce(b),this},difference:function(a){return Math.abs(m(this._value).subtract(a).value())}},t&&(module.exports=m),"undefined"==typeof ender&&(this.numeral=m),"function"==typeof define&&define.amd&&define([],function(){return m})}).call(this);<|endoftext|>


<commit_before>'use strict';

var Promise = require('bluebird');
var requestPromise = require('request-promise');

var stalePullRequest = require('../../bin/stalePullRequest');
var RepositorySettings = require('../../lib/RepositorySettings');

describe('stalePullRequest', function () {
    var repositories;
    beforeEach(function () {
        repositories = {
            'AnalyticalGraphics/cesium': new RepositorySettings({
                gitHubToken: 'token1'
            }),
            'AnalyticalGraphics/cesium-concierge': new RepositorySettings({
                gitHubToken: 'token2'
            })
        };
    });

    it('calls stalePullRequest._processRepository once for each repository', function (done) {
        spyOn(stalePullRequest, '_processRepository').and.returnValue(Promise.resolve());
        stalePullRequest(repositories)
            .then(function () {
                var keys = Object.keys(repositories);
                expect(stalePullRequest._processRepository).toHaveBeenCalledTimes(2);
                expect(stalePullRequest._processRepository.calls.argsFor(0)).toEqual([keys[0], repositories[keys[0]]]);
                expect(stalePullRequest._processRepository.calls.argsFor(1)).toEqual([keys[1], repositories[keys[1]]]);
                done();
            })
            .catch(done.fail);
    });

    it('calls stalePullRequest._processPullRequest once for each returned pull request', function (done) {
        var mockPullRequest = {};
        var mockPullRequest2 = {};
        var firstResponse = {
            headers : {
                link : '<https://url?page=2>; rel="next",<https://url?page=2>; rel="last"'
            },
            body: [mockPullRequest]
        };
        var secondResponse = {
            headers : {
                link : '<https://url?page=1>; rel="first",<https://url?page=2>; rel="prev"'
            },
            body: [mockPullRequest2]
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.url === 'https://api.github.com/repos/AnalyticalGraphics/cesium/pulls?state=open&base=master') {
                return Promise.resolve(firstResponse);
            }
            else if (options.url === 'https://url?page=2') {
                return Promise.resolve(secondResponse);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });

        spyOn(stalePullRequest, '_processPullRequest').and.returnValue(Promise.resolve());

        stalePullRequest._processRepository('AnalyticalGraphics/cesium', repositories['AnalyticalGraphics/cesium'])
            .then(function () {
                expect(stalePullRequest._processPullRequest).toHaveBeenCalledTimes(2);
                expect(stalePullRequest._processPullRequest.calls.argsFor(0)).toEqual([mockPullRequest, repositories['AnalyticalGraphics/cesium']]);
                expect(stalePullRequest._processPullRequest.calls.argsFor(1)).toEqual([mockPullRequest2, repositories['AnalyticalGraphics/cesium']]);
                done();
            })
            .catch(done.fail);
    });

    it('stalePullRequest._processPullRequest does not post non-stale pull request', function (done) {
        var repositorySettings = new RepositorySettings();
        var commentsUrl = 'https://url';
        var pullRequest = {
            comments_url: commentsUrl
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.resolveWithFullResponse === true) {
                return Promise.resolve({headers: {link: '<https://url?page=2>; rel="next",<https://url?page=3>; rel="last"'}});
            }
            else if (options.url === commentsUrl + '?page=3') {
                var timestamp = new Date(Date.now());
                return Promise.resolve([{
                    updated_at: timestamp
                }]);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });
        spyOn(requestPromise, 'post');
        spyOn(stalePullRequest, 'foundStopComment').and.callFake(function () {
            return false;
        });

        stalePullRequest._processPullRequest(pullRequest, repositorySettings)
            .then(function () {
                expect(requestPromise.post).not.toHaveBeenCalled();
                done();
            })
            .catch(done.fail);
    });

    it('stalePullRequest._processPullRequest posts expected message for stale pull request', function (done) {
        var repositorySettings = new RepositorySettings();
        var commentsUrl = 'https://url';
        var pullRequest = {
            comments_url: commentsUrl
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.resolveWithFullResponse === true) {
                return Promise.resolve({headers: {link: '<https://url?page=2>; rel="next",<https://url?page=3>; rel="last"'}});
            }
            else if (options.url === commentsUrl + '?page=3') {
                var timestamp = new Date(Date.now());
                timestamp.setDate(timestamp.getDate() - repositorySettings.maxDaysSinceUpdate);
                return Promise.resolve([{
                    updated_at: timestamp,
                    user: {login: 'boomerjones'}
                }]);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });
        spyOn(requestPromise, 'post');
        spyOn(stalePullRequest, 'foundStopComment').and.callFake(function () {
            return false;
        });

        stalePullRequest._processPullRequest(pullRequest, repositorySettings)
            .then(function () {
                expect(requestPromise.post).toHaveBeenCalledWith({
                    url: commentsUrl + '?page=3',
                    headers: repositorySettings.headers,
                    body: {
                        body: repositorySettings.stalePullRequestTemplate({
                            maxDaysSinceUpdate: repositorySettings.maxDaysSinceUpdate
                        })
                    },
                    json: true
                });
                done();
            })
            .catch(done.fail);
    });

    it('stalePullRequest._processPullRequest does not post when asked to stop', function (done) {
        var repositorySettings = new RepositorySettings();
        var commentsUrl = 'https://url';
        var pullRequest = {
            comments_url: commentsUrl
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.resolveWithFullResponse === true) {
                return Promise.resolve({headers: {link: '<https://url?page=2>; rel="next",<https://url?page=3>; rel="last"'}});
            }
            else if (options.url === commentsUrl + '?page=3') {
                var timestamp = new Date(Date.now());
                timestamp.setDate(timestamp.getDate() - repositorySettings.maxDaysSinceUpdate);
                return Promise.resolve([{
                    updated_at: timestamp,
                    user: {login: 'boomerjones'}
                }]);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });
        spyOn(requestPromise, 'post');
        spyOn(stalePullRequest, 'foundStopComment').and.callFake(function () {
            return true;
        });

        stalePullRequest._processPullRequest(pullRequest, repositorySettings)
            .then(function () {
                expect(requestPromise.post).not.toHaveBeenCalled();
                done();
            })
            .catch(done.fail);
    });
});
<commit_msg>Fixed stale spec<commit_after>'use strict';

var Promise = require('bluebird');
var requestPromise = require('request-promise');

var stalePullRequest = require('../../bin/stalePullRequest');
var RepositorySettings = require('../../lib/RepositorySettings');

describe('stalePullRequest', function () {
    var repositories;
    beforeEach(function () {
        repositories = {
            'AnalyticalGraphics/cesium': new RepositorySettings({
                gitHubToken: 'token1'
            }),
            'AnalyticalGraphics/cesium-concierge': new RepositorySettings({
                gitHubToken: 'token2'
            })
        };
    });

    it('calls stalePullRequest._processRepository once for each repository', function (done) {
        spyOn(stalePullRequest, '_processRepository').and.returnValue(Promise.resolve());
        stalePullRequest(repositories)
            .then(function () {
                var keys = Object.keys(repositories);
                expect(stalePullRequest._processRepository).toHaveBeenCalledTimes(2);
                expect(stalePullRequest._processRepository.calls.argsFor(0)).toEqual([keys[0], repositories[keys[0]]]);
                expect(stalePullRequest._processRepository.calls.argsFor(1)).toEqual([keys[1], repositories[keys[1]]]);
                done();
            })
            .catch(done.fail);
    });

    it('calls stalePullRequest._processPullRequest once for each returned pull request', function (done) {
        var mockPullRequest = {};
        var mockPullRequest2 = {};
        var firstResponse = {
            headers : {
                link : '<https://url?page=2>; rel="next",<https://url?page=2>; rel="last"'
            },
            body: [mockPullRequest]
        };
        var secondResponse = {
            headers : {
                link : '<https://url?page=1>; rel="first",<https://url?page=2>; rel="prev"'
            },
            body: [mockPullRequest2]
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.url === 'https://api.github.com/repos/AnalyticalGraphics/cesium/pulls?state=open&base=master') {
                return Promise.resolve(firstResponse);
            }
            else if (options.url === 'https://url?page=2') {
                return Promise.resolve(secondResponse);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });

        spyOn(stalePullRequest, '_processPullRequest').and.returnValue(Promise.resolve());

        stalePullRequest._processRepository('AnalyticalGraphics/cesium', repositories['AnalyticalGraphics/cesium'])
            .then(function () {
                expect(stalePullRequest._processPullRequest).toHaveBeenCalledTimes(2);
                expect(stalePullRequest._processPullRequest.calls.argsFor(0)).toEqual([mockPullRequest, repositories['AnalyticalGraphics/cesium']]);
                expect(stalePullRequest._processPullRequest.calls.argsFor(1)).toEqual([mockPullRequest2, repositories['AnalyticalGraphics/cesium']]);
                done();
            })
            .catch(done.fail);
    });

    it('stalePullRequest._processPullRequest does not post non-stale pull request', function (done) {
        var repositorySettings = new RepositorySettings();
        var commentsUrl = 'https://url';
        var pullRequest = {
            comments_url: commentsUrl
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.resolveWithFullResponse === true) {
                return Promise.resolve({headers: {link: '<https://url?page=2>; rel="next",<https://url?page=3>; rel="last"'}});
            }
            else if (options.url === commentsUrl + '?page=3') {
                var timestamp = new Date(Date.now());
                return Promise.resolve([{
                    updated_at: timestamp
                }]);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });
        spyOn(requestPromise, 'post');
        spyOn(stalePullRequest, 'foundStopComment').and.callFake(function () {
            return false;
        });

        stalePullRequest._processPullRequest(pullRequest, repositorySettings)
            .then(function () {
                expect(requestPromise.post).not.toHaveBeenCalled();
                done();
            })
            .catch(done.fail);
    });

    it('stalePullRequest._processPullRequest posts expected message for stale pull request', function (done) {
        var repositorySettings = new RepositorySettings();
        var commentsUrl = 'https://url';
        var pullRequest = {
            comments_url: commentsUrl,
            user: {login: 'boomerjones'}
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.resolveWithFullResponse === true) {
                return Promise.resolve({headers: {link: '<https://url?page=2>; rel="next",<https://url?page=3>; rel="last"'}});
            }
            else if (options.url === commentsUrl + '?page=3') {
                var timestamp = new Date(Date.now());
                timestamp.setDate(timestamp.getDate() - repositorySettings.maxDaysSinceUpdate);
                return Promise.resolve([{
                    updated_at: timestamp,
                    user: {login: 'boomerjones'}
                }]);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });
        spyOn(requestPromise, 'post');
        spyOn(stalePullRequest, 'foundStopComment').and.callFake(function () {
            return false;
        });

        stalePullRequest._processPullRequest(pullRequest, repositorySettings)
            .then(function () {
                expect(requestPromise.post).toHaveBeenCalledWith({
                    url: commentsUrl + '?page=3',
                    headers: repositorySettings.headers,
                    body: {
                        body: repositorySettings.stalePullRequestTemplate({
                            maxDaysSinceUpdate: repositorySettings.maxDaysSinceUpdate,
                            userName: pullRequest.user.login
                        })
                    },
                    json: true
                });
                done();
            })
            .catch(done.fail);
    });

    it('stalePullRequest._processPullRequest does not post when asked to stop', function (done) {
        var repositorySettings = new RepositorySettings();
        var commentsUrl = 'https://url';
        var pullRequest = {
            comments_url: commentsUrl
        };

        spyOn(requestPromise, 'get').and.callFake(function (options) {
            if (options.resolveWithFullResponse === true) {
                return Promise.resolve({headers: {link: '<https://url?page=2>; rel="next",<https://url?page=3>; rel="last"'}});
            }
            else if (options.url === commentsUrl + '?page=3') {
                var timestamp = new Date(Date.now());
                timestamp.setDate(timestamp.getDate() - repositorySettings.maxDaysSinceUpdate);
                return Promise.resolve([{
                    updated_at: timestamp,
                    user: {login: 'boomerjones'}
                }]);
            }
            return Promise.reject(new Error('Unexpected Url'));
        });
        spyOn(requestPromise, 'post');
        spyOn(stalePullRequest, 'foundStopComment').and.callFake(function () {
            return true;
        });

        stalePullRequest._processPullRequest(pullRequest, repositorySettings)
            .then(function () {
                expect(requestPromise.post).not.toHaveBeenCalled();
                done();
            })
            .catch(done.fail);
    });
});
<|endoftext|>


<commit_before>'use strict';

var Fs = require('fs');
var Request = require('request');
var List = require('immutable').List;
var Promise = require('promise');
var Url = require('url');
var Mkdirp = require('mkdirp');

/**
 * @exports lib/document-downloader
 */

var DocumentDownloader = {};

DocumentDownloader.fetch = function (url) {
  return new Promise(function (resolve, reject) {
    Request.get(url, {
      timeout: 30000,
      encoding: null // If not specified, utf8 by default
    }, function (error, response, body) {
      if (error) {
        reject(new Error(
          'Fetching ' + url + ' triggered a network error: ' + error.message
        ));
      }
      else if (response.statusCode !== 200) {
        reject(new Error(
          'Fetching ' + url +
          ' triggered and HTTP error: code ' + response.statusCode
        ));
      }
      else resolve(body);
    });
  });
};

DocumentDownloader.fetchAll = function (urls) {
  return Promise.all(urls.toArray().map(this.fetch)).then(List);
};

DocumentDownloader.install = function (dest, content) {
  var path = require('path').dirname(dest);

  Mkdirp.sync(path);
  return Promise.denodeify(Fs.writeFile)(dest, content);
};

DocumentDownloader.installAll = function (destsContents) {
  // `e` is a tuple of [dest, content]
  return Promise.all(destsContents.toArray().map(function (e) {
    return DocumentDownloader.install(e[0], e[1]);
  }));
};

/**
 * Checks if a given filename is allowed to be published by the system.
 *
 * @param {string} filename - The filename to check against
 * @returns {boolean} `true` if the filename is allowed, `false` otherwise
 */
DocumentDownloader.isAllowed = function isAllowed(filename) {
  if (filename.toLowerCase().indexOf('.htaccess') !== -1) return false;
  else if (filename.toLowerCase().indexOf('.php') !== -1) return false;
  else if (filename.indexOf('CVS') !== -1) return false;
  else if (filename.indexOf('../') !== -1) return false;
  else return true;
};

DocumentDownloader.fetchAndInstall = function (url, dest) {
  var _ = DocumentDownloader; // Class name shortener
  var mkdir = Promise.denodeify(Fs.mkdir);

  return new Promise(function (resolve) {
    Fs.exists(dest, function (exists) { resolve(exists); });
  }).then(function (pathExists) {
    if (!pathExists) return mkdir(dest);
  }).then(function () {
    return _.fetch(url).then(function (content) {
      var fileType = require('file-type');
      var type = fileType(content);

      if (type.mime === 'application/x-tar') {
        return new Promise(function (resolve, reject) {
          var tar = require('tar-stream');
          var extract = tar.extract();
          var hasOverview = false;

          extract.on('entry', function (header, stream, callback) {
            stream.on('data', function (data) {
              if (_.isAllowed(header.name)) {
                if (header.name === 'Overview.html') {
                  hasOverview = true;
                }
                _.install(dest + '/' + header.name, data);
              }
            });
            stream.on('end', function () {
              callback();
            });
          });
          extract.on('finish', function () {
            return (hasOverview) ? resolve() :
              reject(
                new Error('The tarball doesn\'t have an Overview.html file.')
              );
          });
          extract.end(content);
        });
      }
      else {
        var contentUtf8 = content.toString('utf8');

        if (contentUtf8.trim().charAt(0) !== '<') {
          var filenames = _.getFilenames(contentUtf8).filter(_.isAllowed);

          var dests = filenames
            .set(0, 'Overview.html')
            .map(function (filename) { return dest + '/' + filename; });

          var urls = filenames.map(function (filename) {
            // If an entry in the manifest had a space in it,
            // we assume it needs to be built from the spec-generator.
            // See https://github.com/w3c/spec-generator
            var specGeneratorComp = filename.split(' ');
            var absUrl = Url.resolve(url, specGeneratorComp[0]);

            if (specGeneratorComp.length === 2) {
              return global.SPEC_GENERATOR +
                '?type=' + encodeURIComponent(specGeneratorComp[1]) +
                '&url=' + encodeURIComponent(absUrl);
            }
            return absUrl;
          });

          return _.fetchAll(urls).then(function (contents) {
            return _.installAll(dests.zip(contents));
          });
        }
        else return _.install(dest + '/Overview.html', content);
      }
    });
  });
};

DocumentDownloader.getFilenames = function getFilenames(manifest) {
  return manifest.split('\n').reduce(function (acc, line) {
    var filename = line.split('#')[0].trim();

    if (filename !== '') return acc.push(filename);
    else return acc;
  }, new List());
};

module.exports = DocumentDownloader;
<commit_msg>check if file type has been determined<commit_after>'use strict';

var Fs = require('fs');
var Request = require('request');
var List = require('immutable').List;
var Promise = require('promise');
var Url = require('url');
var Mkdirp = require('mkdirp');

/**
 * @exports lib/document-downloader
 */

var DocumentDownloader = {};

DocumentDownloader.fetch = function (url) {
  return new Promise(function (resolve, reject) {
    Request.get(url, {
      timeout: 30000,
      encoding: null // If not specified, utf8 by default
    }, function (error, response, body) {
      if (error) {
        reject(new Error(
          'Fetching ' + url + ' triggered a network error: ' + error.message
        ));
      }
      else if (response.statusCode !== 200) {
        reject(new Error(
          'Fetching ' + url +
          ' triggered and HTTP error: code ' + response.statusCode
        ));
      }
      else resolve(body);
    });
  });
};

DocumentDownloader.fetchAll = function (urls) {
  return Promise.all(urls.toArray().map(this.fetch)).then(List);
};

DocumentDownloader.install = function (dest, content) {
  var path = require('path').dirname(dest);

  Mkdirp.sync(path);
  return Promise.denodeify(Fs.writeFile)(dest, content);
};

DocumentDownloader.installAll = function (destsContents) {
  // `e` is a tuple of [dest, content]
  return Promise.all(destsContents.toArray().map(function (e) {
    return DocumentDownloader.install(e[0], e[1]);
  }));
};

/**
 * Checks if a given filename is allowed to be published by the system.
 *
 * @param {string} filename - The filename to check against
 * @returns {boolean} `true` if the filename is allowed, `false` otherwise
 */
DocumentDownloader.isAllowed = function isAllowed(filename) {
  if (filename.toLowerCase().indexOf('.htaccess') !== -1) return false;
  else if (filename.toLowerCase().indexOf('.php') !== -1) return false;
  else if (filename.indexOf('CVS') !== -1) return false;
  else if (filename.indexOf('../') !== -1) return false;
  else return true;
};

DocumentDownloader.fetchAndInstall = function (url, dest) {
  var _ = DocumentDownloader; // Class name shortener
  var mkdir = Promise.denodeify(Fs.mkdir);

  return new Promise(function (resolve) {
    Fs.exists(dest, function (exists) { resolve(exists); });
  }).then(function (pathExists) {
    if (!pathExists) return mkdir(dest);
  }).then(function () {
    return _.fetch(url).then(function (content) {
      var fileType = require('file-type');
      var type = fileType(content);

      if (type && type.mime === 'application/x-tar') {
        return new Promise(function (resolve, reject) {
          var tar = require('tar-stream');
          var extract = tar.extract();
          var hasOverview = false;

          extract.on('entry', function (header, stream, callback) {
            stream.on('data', function (data) {
              if (_.isAllowed(header.name)) {
                if (header.name === 'Overview.html') {
                  hasOverview = true;
                }
                _.install(dest + '/' + header.name, data);
              }
            });
            stream.on('end', function () {
              callback();
            });
          });
          extract.on('finish', function () {
            return (hasOverview) ? resolve() :
              reject(
                new Error('The tarball doesn\'t have an Overview.html file.')
              );
          });
          extract.end(content);
        });
      }
      else {
        var contentUtf8 = content.toString('utf8');

        if (contentUtf8.trim().charAt(0) !== '<') {
          var filenames = _.getFilenames(contentUtf8).filter(_.isAllowed);

          var dests = filenames
            .set(0, 'Overview.html')
            .map(function (filename) { return dest + '/' + filename; });

          var urls = filenames.map(function (filename) {
            // If an entry in the manifest had a space in it,
            // we assume it needs to be built from the spec-generator.
            // See https://github.com/w3c/spec-generator
            var specGeneratorComp = filename.split(' ');
            var absUrl = Url.resolve(url, specGeneratorComp[0]);

            if (specGeneratorComp.length === 2) {
              return global.SPEC_GENERATOR +
                '?type=' + encodeURIComponent(specGeneratorComp[1]) +
                '&url=' + encodeURIComponent(absUrl);
            }
            return absUrl;
          });

          return _.fetchAll(urls).then(function (contents) {
            return _.installAll(dests.zip(contents));
          });
        }
        else return _.install(dest + '/Overview.html', content);
      }
    });
  });
};

DocumentDownloader.getFilenames = function getFilenames(manifest) {
  return manifest.split('\n').reduce(function (acc, line) {
    var filename = line.split('#')[0].trim();

    if (filename !== '') return acc.push(filename);
    else return acc;
  }, new List());
};

module.exports = DocumentDownloader;
<|endoftext|>


<commit_before>'use strict'

function TypingInterface() {
    this.__init__()
}

function Message(text, created_time) {
    this.__init__(text, created_time)
}

Message.prototype = {
    __init__: function(text, created_time) {
        this.text = text
        this.created_time = created_time
    }
}

TypingInterface.prototype = {

    __init__: function() {
        this.gui_typing       = new DomElement('gui_typing')
        this.gui_typing_input = new DomElement('gui_typing_input_field')
        this.gui_logs         = new DomElement('gui_console_logs')

        this.input_text = new InputTextProcessor('')

        this.visible = false

        this.all_rows = []
        var i = 0
        while (i < 70) {
            this.all_rows.push(new DomElement('row_' + i.toString()))
            i += 1
        }

        this.messages = []

        // Calculate the initial sizing.
        this.window_was_resized()
    },

    is_visible: function() {
        return this.visible
    },

    toggle_visibility: function() {
        this.visible = !this.visible
        if (this.visible) {
            this.show()
        } else {
            this.hide()
        }
    },

    show: function() {
        this.gui_typing.show()
        this.gui_logs.show()
        this.visible = true
    },

    hide: function() {
        this.gui_typing.hide()
        this.gui_logs.hide()
        this.visible = false
        this.input_text.clear_text()
    },

    key_down_event: function(event) {
        this.input_text.parse_key_event(event)
        this.gui_typing_input.set_text(this.input_text.get_text())
    },

    window_was_resized: function() {
        this.current_height = this.gui_logs.element.clientHeight

        var row_size = 12 + 3 // There is a margin of 3 and pixel size of 12.
        var number_of_rows_that_fit = this.current_height / row_size
        this.last_row = Math.floor(number_of_rows_that_fit)
    },

    update: function() {
        var i = this.last_row
        var m = 0
        while (i > -1) {
            if (this.messages[m].length > 0) {
                this.all_rows[i].set_text(this.messages[m])
            }
            i -= 1
        }
    },

    add_message: function(message_text) {
        l('Adding this message : ' + message_text)
        this.messages.push(message_text)
    },

    add_user_text: function() {
        this.add_message(this.input_text.get_text())
    }
}<commit_msg>javascript updating 27<commit_after>'use strict'

function TypingInterface() {
    this.__init__()
}

function Message(text, created_time) {
    this.__init__(text, created_time)
}

Message.prototype = {
    __init__: function(text, created_time) {
        this.text = text
        this.created_time = created_time
    }
}

TypingInterface.prototype = {

    __init__: function() {
        this.gui_typing       = new DomElement('gui_typing')
        this.gui_typing_input = new DomElement('gui_typing_input_field')
        this.gui_logs         = new DomElement('gui_console_logs')

        this.input_text = new InputTextProcessor('')

        this.visible = false

        this.all_rows = []
        var i = 0
        while (i < 70) {
            this.all_rows.push(new DomElement('row_' + i.toString()))
            i += 1
        }

        this.messages = []

        // Calculate the initial sizing.
        this.window_was_resized()
    },

    is_visible: function() {
        return this.visible
    },

    toggle_visibility: function() {
        this.visible = !this.visible
        if (this.visible) {
            this.show()
        } else {
            this.hide()
        }
    },

    show: function() {
        this.gui_typing.show()
        this.gui_logs.show()
        this.visible = true
    },

    hide: function() {
        this.gui_typing.hide()
        this.gui_logs.hide()
        this.visible = false
        this.input_text.clear_text()
    },

    key_down_event: function(event) {
        this.input_text.parse_key_event(event)
        this.gui_typing_input.set_text(this.input_text.get_text())
    },

    window_was_resized: function() {
        this.current_height = this.gui_logs.element.clientHeight

        var row_size = 12 + 3 // There is a margin of 3 and pixel size of 12.
        var number_of_rows_that_fit = this.current_height / row_size
        this.last_row = Math.floor(number_of_rows_that_fit)
    },

    update: function() {
        var i = this.last_row
        var m = 0
        while (i > -1) {
            if (this.messages[m].length > 0) {
                this.all_rows[i].set_text(this.messages[m])
                m += 1
            }
            i -= 1
        }
    },

    add_message: function(message_text) {
        l('Adding this message : ' + message_text)
        this.messages.push(message_text)
    },

    add_user_text: function() {
        this.add_message(this.input_text.get_text())
    }
}<|endoftext|>


<commit_before>// Copyright 2015, EMC, Inc.

'use strict';

module.exports = ansibleJobFactory;
var di = require('di');

di.annotate(ansibleJobFactory, new di.Provide('Job.Ansible.Playbook'));
di.annotate(ansibleJobFactory, new di.Inject(
    'Job.Base',
    'Util',
    'Logger',
    'JobUtils.Ansible.Playbook',
    'Assert',
    'Services.Waterline'
    )
);

function ansibleJobFactory(
        BaseJob,
        util,
        Logger,
        AnsibleTool,
        assert,
        waterline
) {
    var logger = Logger.initialize(ansibleJobFactory);

     function AnsibleJob(options, context, taskId) {
        AnsibleJob.super_.call(this, logger, options, context, taskId);
        this.ansibleCmd = undefined;
        this.nodeId = this.context.target;
        this.routingKey = context.graphId;
        this.extraVars = options.vars ? JSON.stringify(options.vars) : null;
        logger.debug("ansible job", {
                options: options,
                extraVars: this.extraVars || 'none'
            });
        assert.uuid(this.routingKey);
    }
    util.inherits(AnsibleJob, BaseJob);

    /**
     * @memberOf AnsibleJob
     */
    AnsibleJob.prototype._run = function run() {
        var self = this;

        waterline.nodes.findByIdentifier(self.nodeId)
        .then(function (node) {
            assert.ok(node, "Node should exist to be a target of ansible playbooks");

            self.ansibleCmd = new AnsibleTool();
            return [node,
                    self.ansibleCmd.runPlaybook(node,
                                                self.options.playbook,
                                                self.extraVars )
                   ];
        })
        .spread(function(node, result) {
            var data = {
                host: node,
                result: result
            };
            return self._publishAnsibleResult(self.routingKey, data);
        })
        .then(function() {
            self.ansibleCmd = undefined;
            self._done();
        })
        .catch(function(err) {
            self.ansibleCmd = undefined;
            self._done(err);
        });
    };

    /**
     * @memberOf AnsibleJob
     */
     AnsibleJob.prototype._cleanup = function cleanup() {
        if(this.ansibleCmd) {
            this.ansibleCmd.kill();
        }
    };

    return AnsibleJob;
}
<commit_msg>Pass nodeid to ansible inventory script instead of the node object<commit_after>// Copyright 2015, EMC, Inc.

'use strict';

module.exports = ansibleJobFactory;
var di = require('di');

di.annotate(ansibleJobFactory, new di.Provide('Job.Ansible.Playbook'));
di.annotate(ansibleJobFactory, new di.Inject(
    'Job.Base',
    'Util',
    'Logger',
    'JobUtils.Ansible.Playbook',
    'Assert',
    'Services.Waterline'
    )
);

function ansibleJobFactory(
        BaseJob,
        util,
        Logger,
        AnsibleTool,
        assert,
        waterline
) {
    var logger = Logger.initialize(ansibleJobFactory);

     function AnsibleJob(options, context, taskId) {
        AnsibleJob.super_.call(this, logger, options, context, taskId);
        this.ansibleCmd = undefined;
        this.nodeId = this.context.target;
        this.routingKey = context.graphId;
        this.extraVars = options.vars ? JSON.stringify(options.vars) : null;
        logger.debug("ansible job", {
                options: options,
                extraVars: this.extraVars || 'none'
            });
        assert.uuid(this.routingKey);
    }
    util.inherits(AnsibleJob, BaseJob);

    /**
     * @memberOf AnsibleJob
     */
    AnsibleJob.prototype._run = function run() {
        var self = this;

        waterline.nodes.findByIdentifier(self.nodeId)
        .then(function (node) {
            assert.ok(node, "Node should exist to be a target of ansible playbooks");

            self.ansibleCmd = new AnsibleTool();
            return [node,
                    self.ansibleCmd.runPlaybook(node.id,
                                                self.options.playbook,
                                                self.extraVars )
                   ];
        })
        .spread(function(node, result) {
            var data = {
                host: node,
                result: result
            };
            return self._publishAnsibleResult(self.routingKey, data);
        })
        .then(function() {
            self.ansibleCmd = undefined;
            self._done();
        })
        .catch(function(err) {
            self.ansibleCmd = undefined;
            self._done(err);
        });
    };

    /**
     * @memberOf AnsibleJob
     */
     AnsibleJob.prototype._cleanup = function cleanup() {
        if(this.ansibleCmd) {
            this.ansibleCmd.kill();
        }
    };

    return AnsibleJob;
}
<|endoftext|>


<commit_before><commit_msg>Update nested-set.js<commit_after><|endoftext|>


<commit_before>angular.module('MyModule')
    .controller('phasercollisioncontroller', function ($scope, $window, $timeout, UtilityService) {
        'use strict';
        $scope.windowWidth = function () {
            return $window.innerWidth;
        };

        $scope.$on('$locationChangeStart', function (event, next, current) {
            game.destroy();
            angular.element(document.querySelectorAll('canvas')).remove();
        });

        var game = new $window.Phaser.Game(800, 600, $window.Phaser.AUTO, '', { preload: preload, create: create, update: update });
        var updatedText;
        var fpsText;
        var updatedCount = 0;
        var time;
        var circles;
        //var radius = 25;

        function preload() {
            game.load.image('agent', 'assets/circle.png');
        }

        function create() {
            game.physics.startSystem(Phaser.Physics.P2JS);
            game.physics.p2.restitution = 0.0;

            var circleCollisionGroup = game.physics.p2.createCollisionGroup();
            game.physics.p2.updateBoundsCollisionGroup();

            circles = game.add.group();
            circles.enableBody = true;
            circles.physicsBodyType = Phaser.Physics.P2JS;

//            var spriteMaterial = game.physics.p2.createMaterial('spriteMaterial');

//            var worldMaterial = game.physics.p2.createMaterial('worldMaterial');
            //  4 trues = the 4 faces of the world in left, right, top, bottom order
            //game.physics.p2.setWorldMaterial(worldMaterial, true, true, true, true);

            //  Here is the contact material. It's a combination of 2 materials, so whenever shapes with
            //  those 2 materials collide it uses the following settings.
            //  A single material can be used by as many different sprites as you like.
//            var contactMaterial = game.physics.p2.createContactMaterial(spriteMaterial, worldMaterial);
//            contactMaterial.friction = 0.0;     // Friction to use in the contact of these two materials.
//            contactMaterial.restitution = 1000.0;  // Restitution (i.e. how bouncy it is!) to use in the contact of these two materials.
//            contactMaterial.stiffness = 1e7;    // Stiffness of the resulting ContactEquation that this ContactMaterial generate.
//            contactMaterial.relaxation = 3;     // Relaxation of the resulting ContactEquation that this ContactMaterial generate.
//            contactMaterial.frictionStiffness = 1e7;    // Stiffness of the resulting FrictionEquation that this ContactMaterial generate.
//            contactMaterial.frictionRelaxation = 3;     // Relaxation of the resulting FrictionEquation that this ContactMaterial generate.
//            contactMaterial.surfaceVelocity = 0;        // Will add surface velocity to this material. If bodyA rests on top if bodyB, and the surface velocity is positive, bodyA will slide to the right.

            for (var i = 0; i < 200; i++)
            {
                var radius = UtilityService.randomInt(12,20);
                var circle = circles.create(game.world.randomX, game.world.randomY, 'agent');
                if (i < 2) {
                    circle.width = 150;
                    circle.height = 150;
                    circle.body.setCircle(74,0,0,0);
                    circle.body.mass = 5000;

                    //circle.body.setMaterial(spriteMaterial);
                    //circle.body.setZeroDamping();
                    circle.body.setCollisionGroup(circleCollisionGroup);
                    circle.body.collides(circleCollisionGroup);
                    circle.body.angle = UtilityService.randomInt(0,359);
                    circle.body.moveForward(UtilityService.randomInt(500,750));
                } else {
                    circle.width = radius * 2;
                    circle.height = circle.width;
                    circle.body.setCircle(radius,0,0,0);

                    //circle.body.setMaterial(spriteMaterial);
                    circle.body.setCollisionGroup(circleCollisionGroup);
                    circle.body.collides(circleCollisionGroup);
                    circle.body.angle = UtilityService.randomInt(0,359);
                    //circle.body.moveForward(UtilityService.randomInt(500,1000));
                    circle.body.mass = radius;
                }
            }

            //circle.body.moveForward(1000);

        }

        function update() {
//            updatedText.text = 'updated: ' + updatedCount++;
//            fpsText.text = 'fps: ' + game.time.fps;

            for (var i = 0; i < 2; i++)
            {
                var circle = circles.children[i];
                if (circle.body.velocity.x > -2.0 && circle.body.velocity.x < 2.0 && circle.body.velocity.y > -2.0 && circle.body.velocity.y < 2.0) {
                    circle.body.angle = UtilityService.randomInt(0,359);
                    circle.body.moveForward(UtilityService.randomInt(200,500));
                }
            }
        }

        function init() {
            $scope.pageName = "Phaser.js Collisions";
            var v1 = {};
            var radius = {};
            var startPos = {};
            var i = 0;
        }

        init();
    });<commit_msg>Performance tweaks.<commit_after>angular.module('MyModule')
    .controller('phasercollisioncontroller', function ($scope, $window, $timeout, UtilityService) {
        'use strict';
        $scope.windowWidth = function () {
            return $window.innerWidth;
        };

        $scope.$on('$locationChangeStart', function (event, next, current) {
            game.destroy();
            angular.element(document.querySelectorAll('canvas')).remove();
        });

        var game = new $window.Phaser.Game(800, 600, $window.Phaser.AUTO, '', { preload: preload, create: create, update: update });
        var updatedText;
        var fpsText;
        var updatedCount = 0;
        var time;
        var circles;
        //var radius = 25;

        function preload() {
            game.load.image('agent', 'assets/circle.png');
        }

        function create() {
            game.physics.startSystem(Phaser.Physics.P2JS);
            game.physics.p2.restitution = 0.0;

            var circleCollisionGroup = game.physics.p2.createCollisionGroup();
            game.physics.p2.updateBoundsCollisionGroup();

            circles = game.add.group();
            circles.enableBody = true;
            circles.physicsBodyType = Phaser.Physics.P2JS;

//            var spriteMaterial = game.physics.p2.createMaterial('spriteMaterial');

//            var worldMaterial = game.physics.p2.createMaterial('worldMaterial');
            //  4 trues = the 4 faces of the world in left, right, top, bottom order
            //game.physics.p2.setWorldMaterial(worldMaterial, true, true, true, true);

            //  Here is the contact material. It's a combination of 2 materials, so whenever shapes with
            //  those 2 materials collide it uses the following settings.
            //  A single material can be used by as many different sprites as you like.
//            var contactMaterial = game.physics.p2.createContactMaterial(spriteMaterial, worldMaterial);
//            contactMaterial.friction = 0.0;     // Friction to use in the contact of these two materials.
//            contactMaterial.restitution = 1000.0;  // Restitution (i.e. how bouncy it is!) to use in the contact of these two materials.
//            contactMaterial.stiffness = 1e7;    // Stiffness of the resulting ContactEquation that this ContactMaterial generate.
//            contactMaterial.relaxation = 3;     // Relaxation of the resulting ContactEquation that this ContactMaterial generate.
//            contactMaterial.frictionStiffness = 1e7;    // Stiffness of the resulting FrictionEquation that this ContactMaterial generate.
//            contactMaterial.frictionRelaxation = 3;     // Relaxation of the resulting FrictionEquation that this ContactMaterial generate.
//            contactMaterial.surfaceVelocity = 0;        // Will add surface velocity to this material. If bodyA rests on top if bodyB, and the surface velocity is positive, bodyA will slide to the right.

            for (var i = 0; i < 100; i++)
            {
                var radius = UtilityService.randomInt(12,20);
                var circle = circles.create(game.world.randomX, game.world.randomY, 'agent');
                if (i < 2) {
                    circle.width = 120;
                    circle.height = 120;
                    circle.body.setCircle(60,0,0,0);
                    circle.body.mass = 5000;

                    //circle.body.setMaterial(spriteMaterial);
                    //circle.body.setZeroDamping();
                    circle.body.setCollisionGroup(circleCollisionGroup);
                    circle.body.collides(circleCollisionGroup);
                    circle.body.angle = UtilityService.randomInt(0,359);
                    circle.body.moveForward(UtilityService.randomInt(500,750));
                } else {
                    circle.width = radius * 2;
                    circle.height = circle.width;
                    circle.body.setCircle(radius,0,0,0);

                    //circle.body.setMaterial(spriteMaterial);
                    circle.body.setCollisionGroup(circleCollisionGroup);
                    circle.body.collides(circleCollisionGroup);
                    circle.body.angle = UtilityService.randomInt(0,359);
                    //circle.body.moveForward(UtilityService.randomInt(500,1000));
                    circle.body.mass = radius;
                }
            }

            //circle.body.moveForward(1000);

        }

        function update() {
//            updatedText.text = 'updated: ' + updatedCount++;
//            fpsText.text = 'fps: ' + game.time.fps;

            for (var i = 0; i < 2; i++)
            {
                var circle = circles.children[i];
                if (circle.body.velocity.x > -2.0 && circle.body.velocity.x < 2.0 && circle.body.velocity.y > -2.0 && circle.body.velocity.y < 2.0) {
                    circle.body.angle = UtilityService.randomInt(0,359);
                    circle.body.moveForward(UtilityService.randomInt(200,500));
                }
            }
        }

        function init() {
            $scope.pageName = "Phaser.js Collisions";
            var v1 = {};
            var radius = {};
            var startPos = {};
            var i = 0;
        }

        init();
    });<|endoftext|>


<commit_before><commit_msg>node爬虫<commit_after><|endoftext|>


<commit_before>var childProcess = require('child_process')
var expect = require('chai').expect
var PouchDB = require('pouchdb-core')
var os = require('os')
var fs = require('fs')
var path = require('path')
PouchDB.plugin(require('pouchdb-adapter-http'))
describe('index', () => {
  var pouchServer
  before(() => {
    pouchServer = childProcess.spawn('node_modules/.bin/pouchdb-server', ['--in-memory', '--port', '3000'])
  })
  after((done) => {
    pouchServer.kill()
    pouchServer.on('exit', () => {
      done()
    })
  })
  var db
  var src
  var dst
  var machine = os.hostname()
  beforeEach((done) => {
    var tmpdir = path.join(os.tmpdir(), (new Date().getTime()).toString())
    fs.mkdirSync(tmpdir)
    src = path.join(tmpdir, 'src')
    dst = path.join(tmpdir, 'dst')
    childProcess.spawn('cp', ['-r', 'test/src', src]).on('exit', (code) => {
      if (code === 0) {
        db = new PouchDB('http://localhost:3000/test_db')
        var counter = 20
        var wait = () => {
          db.allDocs().then(() => done()).catch((err) => {
            if (err.code === 'ECONNREFUSED' && counter-- > 0) {
              setTimeout(wait, 100)
            } else {
              done(err)
            }
          })
        }
        wait()
      } else {
        done(new Error(`Source directory copy failed 'cp', ['-r', 'test/src', ${src}]`))
      }
    })
  })
  afterEach((done) => {
    db.destroy().then(() => done()).catch(done)
  })
  it('Should fail with no arguments', (done) => {
    childProcess.fork('./index', []).on('exit', (code) => {
      expect(code).not.to.be.equal(0)
      done()
    })
  })

  it('Should scan source directory', (done) => {
    childProcess.fork('./index', ['-a', 'http://localhost:3000/test_db', '-p', path.join(src, '**'), '-t', dst]).on('exit', (code) => {
      db.allDocs({
        include_docs: true
      }).then((docs) => {
        expect(docs).to.be.containSubset({
          rows: [{
            doc: {
              files: {
                [machine]: {
                  [path.join(src, 'file1.jpg')]: 'PRESENT'
                }
              }
            }
          }]
        })
        done()
      }).catch(done)
    })
  })
})
<commit_msg>Added timeout to index tests<commit_after>var childProcess = require('child_process')
var expect = require('chai').expect
var PouchDB = require('pouchdb-core')
var os = require('os')
var fs = require('fs')
var path = require('path')
PouchDB.plugin(require('pouchdb-adapter-http'))
describe('index', () => {
  var pouchServer
  before(() => {
    pouchServer = childProcess.spawn('node_modules/.bin/pouchdb-server', ['--in-memory', '--port', '3000'])
  })
  after((done) => {
    pouchServer.kill()
    pouchServer.on('exit', () => {
      done()
    })
  })
  var db
  var src
  var dst
  var machine = os.hostname()
  beforeEach((done) => {
    var tmpdir = path.join(os.tmpdir(), (new Date().getTime()).toString())
    fs.mkdirSync(tmpdir)
    src = path.join(tmpdir, 'src')
    dst = path.join(tmpdir, 'dst')
    childProcess.spawn('cp', ['-r', 'test/src', src]).on('exit', (code) => {
      if (code === 0) {
        db = new PouchDB('http://localhost:3000/test_db')
        var counter = 20
        var wait = () => {
          db.allDocs().then(() => done()).catch((err) => {
            if (err.code === 'ECONNREFUSED' && counter-- > 0) {
              setTimeout(wait, 100)
            } else {
              done(err)
            }
          })
        }
        wait()
      } else {
        done(new Error(`Source directory copy failed 'cp', ['-r', 'test/src', ${src}]`))
      }
    })
  })
  afterEach((done) => {
    db.destroy().then(() => done()).catch(done)
  })
  it('Should fail with no arguments', (done) => {
    childProcess.fork('./index', []).on('exit', (code) => {
      expect(code).not.to.be.equal(0)
      done()
    })
  })

  it('Should scan source directory', (done) => {
    childProcess.fork('./index', ['-a', 'http://localhost:3000/test_db', '-p', path.join(src, '**'), '-t', dst]).on('exit', (code) => {
      db.allDocs({
        include_docs: true
      }).then((docs) => {
        expect(docs).to.be.containSubset({
          rows: [{
            doc: {
              files: {
                [machine]: {
                  [path.join(src, 'file1.jpg')]: 'PRESENT'
                }
              }
            }
          }]
        })
        done()
      }).catch(done)
    })
  })
}).timeout(5000)
<|endoftext|>


<commit_before>// TODO: make with real data
import React, {PropTypes} from 'react';
import _ from 'lodash';

const AlertsTable = React.createClass({
  propTypes: {
    alerts: PropTypes.arrayOf(PropTypes.shape({
      name: PropTypes.string,
      time: PropTypes.string,
      value: PropTypes.string,
      host: PropTypes.string,
      level: PropTypes.string,
    })),
    source: PropTypes.shape({
      id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired,
    }).isRequired,
  },

  getInitialState() {
    return {
      searchTerm: '',
      filteredAlerts: this.props.alerts,
      sortDirection: null,
      sortKey: null,
    };
  },

  componentWillReceiveProps(newProps) {
    this.filterAlerts(newProps.alerts, this.state.searchTerm);
  },

  filterAlerts(allAlerts, searchTerm) {
    const alerts = allAlerts.filter((h) => {
      return h.name.toLowerCase().search(searchTerm.toLowerCase()) !== -1 ||
              h.host.toLowerCase().search(searchTerm.toLowerCase()) !== -1 ||
              h.level.toLowerCase().search(searchTerm.toLowerCase()) !== -1;
    });
    this.setState({searchTerm, filteredAlerts: alerts});
  },

  changeSort(key) {
    // if we're using the key, reverse order; otherwise, set it with ascending
    if (this.state.sortKey === key) {
      const reverseDirection = (this.state.sortDirection === 'asc' ? 'desc' : 'asc');
      this.setState({sortDirection: reverseDirection});
    } else {
      this.setState({sortKey: key, sortDirection: 'asc'});
    }
  },

  sort(alerts, key, direction) {
    switch (direction) {
      case 'asc':
        return _.sortBy(alerts, (e) => e[key]);
      case 'desc':
        return _.sortBy(alerts, (e) => e[key]).reverse();
      default:
        return alerts;
    }
  },

  render() {
    const alerts = this.sort(this.state.filteredAlerts, this.state.sortKey, this.state.sortDirection);
    return (

{this.props.alerts.length} Alerts

          <SearchBar onSearch={_.wrap(this.props.alerts, this.filterAlerts)} />

                 this.changeSort('name')} className="sortable-header">Name
                 this.changeSort('level')} className="sortable-header">Level
                 this.changeSort('time')} className="sortable-header">Time
                 this.changeSort('host')} className="sortable-header">Host
                 this.changeSort('value')} className="sortable-header">Value

              {
                alerts.map(({name, time, value, host, level}) => {
                  return (
                    <tr key={`${name}-${time}-${host}-${value}`}>
                      {name}
                      <td className={`monotype alert-level-${level.toLowerCase()}`}>{level}
                      {(new Date(Number(time)).toISOString())}
                      {host}
                      {value}

                  );
                })
              }

    );
  },
});

const SearchBar = React.createClass({
  propTypes: {
    onSearch: PropTypes.func.isRequired,
  },

  handleChange() {
    this.props.onSearch(this.refs.searchInput.value);
  },

  render() {
    return (

        <input
          type="text"
          className="form-control"
          placeholder="Filter Alerts by Name..."
          ref="searchInput"
          onChange={this.handleChange}
        />

    );
  },
});

export default AlertsTable;
<commit_msg>add links to hosts in alerts table<commit_after>import React, {PropTypes} from 'react';
import _ from 'lodash';
import {Link} from 'react-router';

const AlertsTable = React.createClass({
  propTypes: {
    alerts: PropTypes.arrayOf(PropTypes.shape({
      name: PropTypes.string,
      time: PropTypes.string,
      value: PropTypes.string,
      host: PropTypes.string,
      level: PropTypes.string,
    })),
    source: PropTypes.shape({
      id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired,
    }).isRequired,
  },

  getInitialState() {
    return {
      searchTerm: '',
      filteredAlerts: this.props.alerts,
      sortDirection: null,
      sortKey: null,
    };
  },

  componentWillReceiveProps(newProps) {
    this.filterAlerts(newProps.alerts, this.state.searchTerm);
  },

  filterAlerts(allAlerts, searchTerm) {
    const alerts = allAlerts.filter((h) => {
      return h.name.toLowerCase().search(searchTerm.toLowerCase()) !== -1 ||
              h.host.toLowerCase().search(searchTerm.toLowerCase()) !== -1 ||
              h.level.toLowerCase().search(searchTerm.toLowerCase()) !== -1;
    });
    this.setState({searchTerm, filteredAlerts: alerts});
  },

  changeSort(key) {
    // if we're using the key, reverse order; otherwise, set it with ascending
    if (this.state.sortKey === key) {
      const reverseDirection = (this.state.sortDirection === 'asc' ? 'desc' : 'asc');
      this.setState({sortDirection: reverseDirection});
    } else {
      this.setState({sortKey: key, sortDirection: 'asc'});
    }
  },

  sort(alerts, key, direction) {
    switch (direction) {
      case 'asc':
        return _.sortBy(alerts, (e) => e[key]);
      case 'desc':
        return _.sortBy(alerts, (e) => e[key]).reverse();
      default:
        return alerts;
    }
  },

  render() {
    const {id} = this.props.source;
    const alerts = this.sort(this.state.filteredAlerts, this.state.sortKey, this.state.sortDirection);
    return (

{this.props.alerts.length} Alerts

          <SearchBar onSearch={_.wrap(this.props.alerts, this.filterAlerts)} />

                 this.changeSort('name')} className="sortable-header">Name
                 this.changeSort('level')} className="sortable-header">Level
                 this.changeSort('time')} className="sortable-header">Time
                 this.changeSort('host')} className="sortable-header">Host
                 this.changeSort('value')} className="sortable-header">Value

              {
                alerts.map(({name, time, value, host, level}) => {
                  return (
                    <tr key={`${name}-${time}-${host}-${value}`}>
                      {name}
                      <td className={`monotype alert-level-${level.toLowerCase()}`}>{level}
                      {(new Date(Number(time)).toISOString())}

                        <Link to={`/sources/${id}/hosts/${host}`}>
                          {host}
                        </Link>

                      {value}

                  );
                })
              }

    );
  },
});

const SearchBar = React.createClass({
  propTypes: {
    onSearch: PropTypes.func.isRequired,
  },

  handleChange() {
    this.props.onSearch(this.refs.searchInput.value);
  },

  render() {
    return (

        <input
          type="text"
          className="form-control"
          placeholder="Filter Alerts by Name..."
          ref="searchInput"
          onChange={this.handleChange}
        />

    );
  },
});

export default AlertsTable;
<|endoftext|>