<commit_before>require( 'source-map-support' ).install();

var path = require( 'path' );
var relative = require( 'require-relative' );
var handleError = require( './handleError' );
var chalk = require( 'chalk' );
var rollup = require( '../' );

// log to stderr to keep `rollup main.js > bundle.js` from breaking
var log = console.error.bind(console);

module.exports = function ( command ) {
	if ( command._.length > 1 ) {
		handleError({ code: 'ONE_AT_A_TIME' });
	}

	if ( command._.length === 1 ) {
		if ( command.input ) {
			handleError({ code: 'DUPLICATE_IMPORT_OPTIONS' });
		}

		command.input = command._[0];
	}

	if ( command.environment ) {
		command.environment.split( ',' ).forEach( function ( pair ) {
			var index = pair.indexOf( ':' );
			if ( ~index ) {
				process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 );
			} else {
				process.env[ pair ] = true;
			}
		});
	}

	var config = command.config === true ? 'rollup.config.js' : command.config;

	if ( config ) {
		config = path.resolve( config );

		rollup.rollup({
			entry: config,
			onwarn: function ( message ) {
				if ( /Treating .+ as external dependency/.test( message ) ) return;
				log( message );
			}
		}).then( function ( bundle ) {
			var code = bundle.generate({
				format: 'cjs'
			}).code;

			// temporarily override require
			var defaultLoader = require.extensions[ '.js' ];
			require.extensions[ '.js' ] = function ( m, filename ) {
				if ( filename === config ) {
					m._compile( code, filename );
				} else {
					defaultLoader( m, filename );
				}
			};

			try {
				var options = require( path.resolve( config ) );
				if ( Object.keys( options ).length === 0 ) {
					handleError({ code: 'MISSING_CONFIG' });
				}
			} catch ( err ) {
				handleError( err );
			}

			execute( options, command );

			require.extensions[ '.js' ] = defaultLoader;
		})
		.catch(log);
	} else {
		execute( {}, command );
	}
};

var equivalents = {
	banner: 'banner',
	footer: 'footer',
	format: 'format',
	globals: 'globals',
	id: 'moduleId',
	indent: 'indent',
	input: 'entry',
	intro: 'intro',
	name: 'moduleName',
	output: 'dest',
	outro: 'outro',
	sourcemap: 'sourceMap',
	treeshake: 'treeshake'
};

function execute ( options, command ) {
	var external = ( options.external || [] )
		.concat( command.external ? command.external.split( ',' ) : []  );

	if ( command.globals ) {
		var globals = Object.create( null );

		command.globals.split( ',' ).forEach(function ( str ) {
			var names = str.split( ':' );
			globals[ names[0] ] = names[1];

			// Add missing Module IDs to external.
			if ( external.indexOf( names[0] ) === -1 ) {
				external.push( names[0] );
			}
		});

		command.globals = globals;
	}

	options.onwarn = options.onwarn || log;

	options.external = external;

	options.noConflict = command.conflict === false;
	delete command.conflict;

	// Use any options passed through the CLI as overrides.
	Object.keys( equivalents ).forEach( function ( cliOption ) {
		if ( command.hasOwnProperty( cliOption ) ) {
			options[ equivalents[ cliOption ] ] = command[ cliOption ];
		}
	});

	try {
		if ( command.watch ) {
			if ( !options.entry || !options.dest ) {
				handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' });
			}

			try {
				var watch = relative( 'rollup-watch', process.cwd() );
				var watcher = watch( rollup, options );

				watcher.on( 'event', event => {
					switch ( event.code ) {
						case 'STARTING':
							console.error( 'checking rollup-watch version...' );
							break;

						case 'BUILD_START':
							console.error( 'bundling...' );
							break;

						case 'BUILD_END':
							console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' );
							break;

						default:
							console.error( 'unknown event', event );
					}
				});
			} catch ( err ) {
				if ( err.code === 'MODULE_NOT_FOUND' ) {
					err.code = 'ROLLUP_WATCH_NOT_INSTALLED';
				}

				handleError( err );
			}
		} else {
			bundle( options ).catch( handleError );
		}
	} catch ( err ) {
		handleError( err );
	}
}

function bundle ( options ) {
	if ( !options.entry ) {
		handleError({ code: 'MISSING_INPUT_OPTION' });
	}

	return rollup.rollup( options ).then( function ( bundle ) {
		if ( options.dest ) {
			return bundle.write( options );
		}

		if ( options.targets ) {
			var result = null;

			options.targets.forEach( function ( target ) {
				result = bundle.write(target);
			});

			return result;
		}

		if ( options.sourceMap && options.sourceMap !== 'inline' ) {
			handleError({ code: 'MISSING_OUTPUT_OPTION' });
		}

		var result = bundle.generate( options );

		var code = result.code,
			map = result.map;

		if ( options.sourceMap === 'inline' ) {
			code += '\n//# sourceMappingURL=' + map.toUrl();
		}

		process.stdout.write( code );
	});
}
<commit_msg>oops i did it again<commit_after>require( 'source-map-support' ).install();

var path = require( 'path' );
var relative = require( 'require-relative' );
var handleError = require( './handleError' );
var chalk = require( 'chalk' );
var rollup = require( '../' );

// log to stderr to keep `rollup main.js > bundle.js` from breaking
var log = console.error.bind(console);

module.exports = function ( command ) {
	if ( command._.length > 1 ) {
		handleError({ code: 'ONE_AT_A_TIME' });
	}

	if ( command._.length === 1 ) {
		if ( command.input ) {
			handleError({ code: 'DUPLICATE_IMPORT_OPTIONS' });
		}

		command.input = command._[0];
	}

	if ( command.environment ) {
		command.environment.split( ',' ).forEach( function ( pair ) {
			var index = pair.indexOf( ':' );
			if ( ~index ) {
				process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 );
			} else {
				process.env[ pair ] = true;
			}
		});
	}

	var config = command.config === true ? 'rollup.config.js' : command.config;

	if ( config ) {
		config = path.resolve( config );

		rollup.rollup({
			entry: config,
			onwarn: function ( message ) {
				if ( /Treating .+ as external dependency/.test( message ) ) return;
				log( message );
			}
		}).then( function ( bundle ) {
			var code = bundle.generate({
				format: 'cjs'
			}).code;

			// temporarily override require
			var defaultLoader = require.extensions[ '.js' ];
			require.extensions[ '.js' ] = function ( m, filename ) {
				if ( filename === config ) {
					m._compile( code, filename );
				} else {
					defaultLoader( m, filename );
				}
			};

			try {
				var options = require( path.resolve( config ) );
				if ( Object.keys( options ).length === 0 ) {
					handleError({ code: 'MISSING_CONFIG' });
				}
			} catch ( err ) {
				handleError( err );
			}

			execute( options, command );

			require.extensions[ '.js' ] = defaultLoader;
		})
		.catch(log);
	} else {
		execute( {}, command );
	}
};

var equivalents = {
	banner: 'banner',
	footer: 'footer',
	format: 'format',
	globals: 'globals',
	id: 'moduleId',
	indent: 'indent',
	input: 'entry',
	intro: 'intro',
	name: 'moduleName',
	output: 'dest',
	outro: 'outro',
	sourcemap: 'sourceMap',
	treeshake: 'treeshake'
};

function execute ( options, command ) {
	var external = ( options.external || [] )
		.concat( command.external ? command.external.split( ',' ) : []  );

	if ( command.globals ) {
		var globals = Object.create( null );

		command.globals.split( ',' ).forEach(function ( str ) {
			var names = str.split( ':' );
			globals[ names[0] ] = names[1];

			// Add missing Module IDs to external.
			if ( external.indexOf( names[0] ) === -1 ) {
				external.push( names[0] );
			}
		});

		command.globals = globals;
	}

	options.onwarn = options.onwarn || log;

	options.external = external;

	options.noConflict = command.conflict === false;
	delete command.conflict;

	// Use any options passed through the CLI as overrides.
	Object.keys( equivalents ).forEach( function ( cliOption ) {
		if ( command.hasOwnProperty( cliOption ) ) {
			options[ equivalents[ cliOption ] ] = command[ cliOption ];
		}
	});

	try {
		if ( command.watch ) {
			if ( !options.entry || !options.dest ) {
				handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' });
			}

			try {
				var watch = relative( 'rollup-watch', process.cwd() );
				var watcher = watch( rollup, options );

				watcher.on( 'event', function ( event ) {
					switch ( event.code ) {
						case 'STARTING':
							console.error( 'checking rollup-watch version...' );
							break;

						case 'BUILD_START':
							console.error( 'bundling...' );
							break;

						case 'BUILD_END':
							console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' );
							break;

						default:
							console.error( 'unknown event', event );
					}
				});
			} catch ( err ) {
				if ( err.code === 'MODULE_NOT_FOUND' ) {
					err.code = 'ROLLUP_WATCH_NOT_INSTALLED';
				}

				handleError( err );
			}
		} else {
			bundle( options ).catch( handleError );
		}
	} catch ( err ) {
		handleError( err );
	}
}

function bundle ( options ) {
	if ( !options.entry ) {
		handleError({ code: 'MISSING_INPUT_OPTION' });
	}

	return rollup.rollup( options ).then( function ( bundle ) {
		if ( options.dest ) {
			return bundle.write( options );
		}

		if ( options.targets ) {
			var result = null;

			options.targets.forEach( function ( target ) {
				result = bundle.write(target);
			});

			return result;
		}

		if ( options.sourceMap && options.sourceMap !== 'inline' ) {
			handleError({ code: 'MISSING_OUTPUT_OPTION' });
		}

		var result = bundle.generate( options );

		var code = result.code,
			map = result.map;

		if ( options.sourceMap === 'inline' ) {
			code += '\n//# sourceMappingURL=' + map.toUrl();
		}

		process.stdout.write( code );
	});
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM for NodeJS is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
var config = require ('spm-agent').Config
var fs = require ('fs')
delete config._
delete config.rcFlat
delete config.config
delete config.agentsToLoad

if (process.argv.length == 3){
	config.tokens.spm = process.argv[2]
	console.log (process.argv[2])
}

if (process.env.SPM_TOKEN)
		config.tokens.spm = process.env.SPM_TOKEN

fs.writeFileSync ('.spmagentrc', JSON.stringify (config, null, '\t'))
console.log ('Create default config to file: ./.spmagentrc \n' + JSON.stringify  (config, null, '\t'))

<commit_msg>simplified config generation in ini file format<commit_after>#!/usr/bin/env node

/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM for NodeJS is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
var fs = require ('fs')
var spm_token = ""
if (process.argv.length == 3){
  spm_token = process.argv[2]
}
if (process.env.SPM_TOKEN)
		spm_token = process.env.SPM_TOKEN

var cfgFileContent = '[tokens]\n  spm = ' + spm_token
fs.writeFileSync ('.spmagentrc', cfgFileContent)
console.log ('Create default config to file: ./.spmagentrc \n' + cfgFileContent)

<|endoftext|>


<commit_before>export const renewToken = (userId) => {
  callApi('renewToken', { userId }, 'POST')
    .then(res => res.json())
    .then(({ token }) => localStorage.setItem('token', token))
    .catch(err => console.log(err));
};

export const uploadFile = (file, signedRequest) => (
  fetch(signedRequest, {
    method: 'PUT',
    body: file
  })
);

const callApi = (endpoint, body, method = 'GET') => {
  const token = localStorage.getItem('token') || null;
  const apiUrl = 'localhost:3001';
  const urlScheme = apiUrl === 'localhost:3001' ? 'http://' : '';

  return fetch(`${urlScheme}${apiUrl}/${endpoint}`, {
    method,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`
    },
    body: JSON.stringify(body),
  });
};

export default callApi;
<commit_msg>Small refactor for apiCaller<commit_after>export const renewToken = (userId) => {
  callApi('renewToken', { userId }, 'POST')
    .then(res => res.json())
    .then(({ token }) => localStorage.setItem('token', token))
    .catch(err => console.log(err));
};

export const uploadFile = (file, signedRequest) =>
  fetch(signedRequest, {
    method: 'PUT',
    body: file
  });

const callApi = (endpoint, body, method = 'GET') => {
  const token = localStorage.getItem('token') || null;
  const apiUrl = 'localhost:3001';
  const urlScheme = apiUrl === 'localhost:3001' ? 'http://' : '';

  return fetch(`${urlScheme}${apiUrl}/${endpoint}`, {
    method,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`
    },
    body: JSON.stringify(body),
  });
};

export default callApi;
<|endoftext|>


<commit_before>// Copyright 2016 The HongJiang Library Project Authors. All right reserved.
// Use of this source code is governed by a Apache-style
// license that can be found in the LICENSE file.
//
//　主應用服務之簡體中文語言包
//
// @authors hjboss <hongjiangproject@gmail.com> 2016-07-05 13:45:04 CST $$
// @version 0.1.0
module.exports = {
        'siteTitle': 'Collavis China',
        'homeTitle': '康莱美姿',
        'siteKeyword': '康莱美姿 collavis.com.cn',
        'siteDescription': '康莱美姿 化妆品国际著名品牌',
        'siteAuthor': 'collavis.com.cn',
        'siteCopyright': 'collavis.com.cn, 2016 co.ltd',
        'footerCompany': '济南康婷生物科技有限公司 JINAN CO.LTD',
        'footerCopyright': '联系我们：400-636-9331 联系时间：周一至周五 09:00-18:00（法定节假日除外）',

        'commonSearch': '搜索关键词',
        'searchLabel': '代理授权',
        'searchButton': '查询',
        'searchComment': '输入您的微信号查询代理授权',
        'searchNotfound': '对不起，没有查询到您的代理授权信息',
        'more': '更多',
        'nomore': '没有更多',
        'totalNum': '共计',
        'totalUnit': '项',
        'listNO': '编号',
        'listTitle': '标题',
        'listDate': '日期',
        'listVisit': '访问量',
        'grantWX': '微信号',
        'grantName': '真实姓名',
        'grantLevel':  '授权级别',
        'grantBegins': '开始时间',
        'grantFinish': '结束时间',
        'grantTimeout': '剩余时间',
        'grantDay': '天',
        'storeName': '名称',
        'storeAddress': '地址',
        'storeMobile': '联系方式',
        'storeInfo': '详细',
        'storeArea': '选择地区',
        'productAll': '全部商品',
        'productDescription': '产品介绍',
        'productSize': '容量',
        'productPrice': '零售价',
        'productShop': '购买方式',
        'productShopN': '专柜导航',
        'nav': {
                'n001': '招募政策',
                'n002': '合作门店',
                'n003': '会社案内',
                'n004': '购买方式',
                'n100': '产品介绍',
                'n101': '胶原蛋白',
                'n200': '胶原女神',
                'n201': '女神向导',
                'n202': '美肌TV',
                'n300': '中国合伙人',
                'n301': '招募政策',
                'n302': '微商学院',
                'n303': '授权查询',
                'n304': '创业故事',
                'n400': '关于我们',
                'n401': '最新动态',
                'n402': '品牌介绍',
                'n403': '会社案内',
                'n404': '合作门店',
                'n405': '电商渠道'
        }
}
<commit_msg>Initial commit<commit_after>// Copyright 2016 The HongJiang Library Project Authors. All right reserved.
// Use of this source code is governed by a Apache-style
// license that can be found in the LICENSE file.
//
//　主應用服務之簡體中文語言包
//
// @authors hjboss <hongjiangproject@gmail.com> 2016-07-05 13:45:04 CST $$
// @version 0.1.0
module.exports = {
        'siteTitle': 'Collavis China',
        'homeTitle': '康莱美姿',
        'siteKeyword': '康莱美姿 collavis.com.cn',
        'siteDescription': '康莱美姿 化妆品国际著名品牌',
        'siteAuthor': 'collavis.com.cn',
        'siteCopyright': 'collavis.com.cn, 2016 co.ltd',
        'footerCompany': '济南康婷生物科技有限公司 JINAN CO.LTD',
        'footerCopyright': '联系我们：400-636-9331 联系时间：周一至周五 09:00-18:00（法定节假日除外）',
        'footerBenan': '鲁ICP备16027155号-1',

        'commonSearch': '搜索关键词',
        'searchLabel': '代理授权',
        'searchButton': '查询',
        'searchComment': '输入您的微信号查询代理授权',
        'searchNotfound': '对不起，没有查询到您的代理授权信息',
        'more': '更多',
        'nomore': '没有更多',
        'totalNum': '共计',
        'totalUnit': '项',
        'listNO': '编号',
        'listTitle': '标题',
        'listDate': '日期',
        'listVisit': '访问量',
        'grantWX': '微信号',
        'grantName': '真实姓名',
        'grantLevel':  '授权级别',
        'grantBegins': '开始时间',
        'grantFinish': '结束时间',
        'grantTimeout': '剩余时间',
        'grantDay': '天',
        'storeName': '名称',
        'storeAddress': '地址',
        'storeMobile': '联系方式',
        'storeInfo': '详细',
        'storeArea': '选择地区',
        'productAll': '全部商品',
        'productDescription': '产品介绍',
        'productSize': '容量',
        'productPrice': '零售价',
        'productShop': '购买方式',
        'productShopN': '专柜导航',
        'nav': {
                'n001': '招募政策',
                'n002': '合作门店',
                'n003': '会社案内',
                'n004': '购买方式',
                'n100': '产品介绍',
                'n101': '胶原蛋白',
                'n200': '胶原女神',
                'n201': '女神向导',
                'n202': '美肌TV',
                'n300': '中国合伙人',
                'n301': '招募政策',
                'n302': '微商学院',
                'n303': '授权查询',
                'n304': '创业故事',
                'n400': '关于我们',
                'n401': '最新动态',
                'n402': '品牌介绍',
                'n403': '会社案内',
                'n404': '合作门店',
                'n405': '电商渠道'
        }
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, 2013 Rich Porter - see LICENSE for further details

$report = function(){
};

(function($report) {

  $report.levels = {
    INT_DEBUG   : 0,
    DEBUG       : 1,
    INFORMATION : 2,
    NOTE        : 3,
    SUCCESS     : 4,
    WARNING     : 5,
    ERROR       : 6,
    INTERNAL    : 7,
    FATAL       : 8,
    _SIZE       : 9,
    severity    : function (level) {
      for (var l in this) {
        if (this[l] === level) {
          return l;
	}
      }
    }
  };

  $report.report = function(){
    var report;
    return function(){
      return report || (report = $('#report'));
    };
  }();
  $report.tabs = function(){
    var tabs;
    return function(){
	return (tabs || (tabs = $report.report().tabs)).apply($report.report(), arguments);
    };
  }();
  $report.tab_id = function() {
    var id;
    return function() {
      id = (id===undefined)?0:id+1;
      return 'log-'+id;
    }
  }();

  $report.hijax = function(panel){
    $('a', panel).click(function() {
      if (this.href == '') return true;
       /**makes children 'a' on panel load via ajax, hence hijax*/
       $(panel).load(this.href, null, function(){
         /**recursively apply the hijax to newly loaded panels*/
         hijax(panel);
       });
       /**prevents propagation of click to document*/
       return false;
    });
  };

  $report.testJSON = function(data, anchor){
    anchor = anchor || $report.tabs();

    var get = function(severity, attr) {
      var result = this.msgs.filter(function(a){return a.severity === severity})[0];
      if (attr === undefined) return result;
      if (result === undefined) return '';
      if (attr instanceof Function) {
        return attr(result);
      } else if (result.hasOwnProperty(attr)) {
        return result[attr];
      }
      return '';
    }

    this.render = function() {
      var container = $('

');
      $('table', container).dataTable({
        "bJQueryUI": true,
        "bPaginate": false,
        "bFilter": false,
        "aaData" : this.rows(),
        "aoColumns": this.cols(),
        "aoColumnDefs": [
          {
            "aTargets": [this.cols().length-1], // last col
            "fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
              $(nTd).addClass(sData);
            },
          }
        ],
        "aaSorting": [[0, "desc"]],
        "fnCreatedRow": function(nRow, aData, iDisplayIndex) {
          $(nRow).bind('click.example', {log_id : aData[0], children : aData[8], anchor : anchor},
            function(event) {
              var log;
              if (event.data.children) {
                // this will be a tab-within-tab
                log = new $report.openRegr(event.data);
              } else {
                // place report log in new tab
                log = new $report.openLog(event.data);
              }
              log.add(anchor);
            }
          );
        }
      });
      return container;
    }

    this.cols = function() {
      return [
	{ "sTitle": "log id" },
	{ "sTitle": "user" },
	{ "sTitle": "description" },
	{ "sTitle": "fatals" },
	{ "sTitle": "internals" },
	{ "sTitle": "errors" },
	{ "sTitle": "warnings" },
	{ "sTitle": "message" },
	{ "sTitle": "children" },
	{ "sTitle": "status" },
      ];
    };

    this.rows = function() {
      function popup(attr) {
          return ''+attr.count+'';
      }
      return data.map(function(log){
        return [log.log.log_id, log.log.user, log.log.description, log.get('FATAL', popup), log.get('INTERNAL', popup), log.get('ERROR', popup), log.get('WARNING', popup), log.status.reason, log.log.children, log.status.status];
      });
    };

    // attach methods to individual data
    for (log in data) {
      data[log].get = get;
    }
  };

  $report.openLog = function(data, anchor) {
    var self = this;
    this.id  = $report.tab_id();
    this.div = $('
', {class: "tab", id:self.id});
    anchor = anchor || data.anchor;

    this.widget = function() {
      function has_ident(json) {
        return json[0].ident !== null || (json.length > 1 && has_ident(json.splice(1)));
      }
      var nodes  = $('code', self.div);
      var widget = $('
').appendTo(self.div);
      var align  = function() {
        widget.animate({top:$(self.div).scrollTop()},{duration:100,queue:false});
      };
      $(this.div).scroll(align);
      // show/hide timestamp
      $('<input type="checkbox">').appendTo(widget).bind('change.time', function(event){$('time', self.div).toggle()}).wrap('
Show time
');
      var ident =  $('<input type="checkbox">').appendTo(widget).bind('change.tag', function(event){$('ident', self.div).toggle()}).wrap('
Show ident
');
      if (has_ident(self.json)) {
        ident.trigger('click');
      } else {
        ident.prop('title', 'there are no given idents');
      }
      // filter by severity
      var slider = $('
').appendTo(widget);
      var lower  = $("
").css({ position : 'absolute' , top : 10, left : 0 }).text($report.levels.severity(0)).hide();
      var upper  = $("
").css({ position : 'absolute' , top : 10, left : 0 }).text($report.levels.severity($report.levels._SIZE-1)).hide();
      slider.slider({
        range: true,
        min: 0,
        max: $report.levels._SIZE-1,
        values: [ 0, $report.levels._SIZE-1 ]
      }).bind('slide.example', function(event, ui) {
        self.div.hide();
        lower.text($report.levels.severity(ui.values[0]));
        upper.text($report.levels.severity(ui.values[1]));
        nodes.each(function(index){if(($(this).attr('level') >= ui.values[0]) && ($(this).attr('level') <= ui.values[1])){$(this).show()}else{$(this).hide()}})
        self.div.show();
      });
      slider.find(".ui-slider-handle:first")
        .append(lower)
        .bind('mouseenter.example', function(event){lower.show()})
        .bind('mouseleave.example', function(event){lower.hide()});
      slider.find(".ui-slider-handle:last")
        .append(upper)
        .bind('mouseenter.example', function(event){upper.show()})
        .bind('mouseleave.example', function(event){upper.hide()});
      // message indexed by severity
      function getBySeverity() {
        function sorted(nodes) {
          function children(nodes) {
            return nodes.slice(0,11).map(
              function(it, idx){
                return {
                  "title"    : (idx>9)?'...':$report.levels.severity(parseInt($(it).attr('level'))),
                  "key"      : it.idx
                };
            });
          };
          return Object.keys(nodes).sort().map(
            function(it) {
              return {
        	      "title"    : '(' + it.slice(1) + ') ' + $report.levels.severity(parseInt(it.slice(1))) + ' <s' + parseInt(it.slice(1))/10 + '>' + nodes[it].length + '</s>',
                "key"      : nodes[it][0].idx,
                "children" : children(nodes[it])
             }}
          );
        };
  	return sorted(nodes.toArray().reduce(function(levels, node, idx) {
          var level = 's'+$(node).attr('level');
          node.idx = idx;
          if (!levels.hasOwnProperty(level)) levels[level]=[];
          levels[level].push(node);
          return levels;
        }, {}));
      }

      var msgIndex = $('
').appendTo(widget);
      msgIndex.dynatree({
        children : [
            {title : "Messages", isFolder : true, children : getBySeverity(nodes)},
        ],
        onActivate: function(node) {
            self.div.animate({scrollTop : $(nodes[node.data.key]).offset().top - self.div.offset().top + self.div.scrollTop() - self.div.height()/2});
        },
        onRender : function(dtnode, nodeSpan) {
          $('a', dtnode.li).hover(
            function(){$(nodes[$.ui.dynatree.getNode(this).data.key]).addClass(   'example-highlight')},
            function(){$(nodes[$.ui.dynatree.getNode(this).data.key]).removeClass('example-highlight')}
          );
          align();
        }
      });
    }

    this.add = function(tabs) {
      tabs.tabs('add', '#'+self.id, data.log_id+' log');
    }

    this.div.appendTo(anchor);
    $.ajax({
      url : 'msgs/'+data.log_id,
      dataType : 'json',
      success : function(data) {
        self.json = data;
        self.div.jqoteapp('#template', self.json);
        self.widget();
      },
      error : function(xhr, status, index) {
        console.log(xhr, status, index);
      }
    });

  };

  $report.openLog.justify = function (c, l) {
    l = l || 12;
    return Array(l).join(' ').substr(c.length) + c;
  }
  $report.openLog.msg = function (m) {
    return m.replace(/>/g, '>').replace(/</g, '<');
  }

  $report.openHier = function(data, anchor){
    var self = this;
    this.id  = $report.tab_id();
    this.div = $('
', {id : this.id});
    this.explorer = $('
');
    this.children = $('
');

    // find all logs with given parent id and return with children
    // in extreme cases it will be more expedient to do this on the server
    // as output is grouped by parent
    this.build = function build(parent) {
      return self.json.filter(
        function(it){
          if (it.log.parent === parent) {
            it.children = build(it.log.log_id);
            return true;
          }
          return false;
        });
    };

    this.add = function(tabs) {
      tabs.tabs('add', '#'+self.id, data.log_id+' hier');
    };

    this.table = function(log_id) {
      this.children.html((new $report.testJSON(self.json, anchor)).render());
    };

    this.pane = function() {
      function hier(json) {
        return json.map(function(it){return {title : it.log.description + '(' + it.log.log_id + ')', isFolder : it.children.length, key : it.log.log_id, children : hier(it.children || [])}});
      }
      var tree = $('
').dynatree({
        children : [
          {title : "ALL", isFolder : true, key : null, children : hier(self.json)},
          hier(self.tree)[0]
        ],
        onActivate: function(node) {
          self.table(node.data.key);
        },
      });
      this.explorer.append(tree);
    }

    this.div.appendTo(anchor);
    this.div.append(this.explorer, this.children);
    $.ajax({
      url : 'rgr/'+data.log_id,
      dataType : 'json',
      success : function(data) {
        self.json = data;
        self.tree = self.build(null);
        self.pane();
      },
      error : function(xhr, status, index) {
        console.log(xhr, status, index);
      }
    });
  }

  $report.openRegr = function(data){
    var self = this;
    this.id  = $report.tab_id();
    this.div = $('
', {id : this.id}).append('
');
    this.add = function(tabs) {
      tabs.tabs('add', '#'+self.id, data.log_id+' regr');
    };

    this.div.appendTo(data.anchor);
    this.tabs = this.div.tabs();

    this.hier = new $report.openHier(data, this.tabs);
    this.hier.add(this.tabs);

    this.log = new $report.openLog(data, this.tabs);
    this.log.add(this.tabs);
  }

})($report);

<commit_msg>allow regression open with tab<commit_after>// Copyright (c) 2012, 2013 Rich Porter - see LICENSE for further details

$report = function(){
};

(function($report) {

  $report.levels = {
    INT_DEBUG   : 0,
    DEBUG       : 1,
    INFORMATION : 2,
    NOTE        : 3,
    SUCCESS     : 4,
    WARNING     : 5,
    ERROR       : 6,
    INTERNAL    : 7,
    FATAL       : 8,
    _SIZE       : 9,
    severity    : function (level) {
      for (var l in this) {
        if (this[l] === level) {
          return l;
	}
      }
    }
  };

  $report.report = function(){
    var report;
    return function(){
      return report || (report = $('#report'));
    };
  }();
  $report.tabs = function(){
    var tabs;
    return function(){
	return (tabs || (tabs = $report.report().tabs)).apply($report.report(), arguments);
    };
  }();
  $report.tab_id = function() {
    var id;
    return function() {
      id = (id===undefined)?0:id+1;
      return 'log-'+id;
    }
  }();

  $report.hijax = function(panel){
    $('a', panel).click(function() {
      if (this.href == '') return true;
       /**makes children 'a' on panel load via ajax, hence hijax*/
       $(panel).load(this.href, null, function(){
         /**recursively apply the hijax to newly loaded panels*/
         hijax(panel);
       });
       /**prevents propagation of click to document*/
       return false;
    });
  };

  $report.testJSON = function(data, anchor){
    anchor = anchor || $report.tabs();

    var get = function(severity, attr) {
      var result = this.msgs.filter(function(a){return a.severity === severity})[0];
      if (attr === undefined) return result;
      if (result === undefined) return '';
      if (attr instanceof Function) {
        return attr(result);
      } else if (result.hasOwnProperty(attr)) {
        return result[attr];
      }
      return '';
    }

    this.render = function() {
      var container = $('

');
      $('table', container).dataTable({
        "bJQueryUI": true,
        "bPaginate": false,
        "bFilter": false,
        "aaData" : this.rows(),
        "aoColumns": this.cols(),
        "aoColumnDefs": [
          {
            "aTargets": [this.cols().length-1], // last col
            "fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
              $(nTd).addClass(sData);
            },
          }
        ],
        "aaSorting": [[0, "desc"]],
        "fnCreatedRow": function(nRow, aData, iDisplayIndex) {
          $(nRow).bind('click.example', {log_id : aData[0], children : aData[8], anchor : anchor},
            function(event) {
              var log;
              if (event.data.children) {
                // this will be a tab-within-tab
                log = new $report.openRegr(event.data);
              } else {
                // place report log in new tab
                log = new $report.openLog(event.data);
              }
              log.add(anchor);
            }
          );
        }
      });
      return container;
    }

    this.cols = function() {
      return [
	{ "sTitle": "log id" },
	{ "sTitle": "user" },
	{ "sTitle": "description" },
	{ "sTitle": "fatals" },
	{ "sTitle": "internals" },
	{ "sTitle": "errors" },
	{ "sTitle": "warnings" },
	{ "sTitle": "message" },
	{ "sTitle": "children" },
	{ "sTitle": "status" },
      ];
    };

    this.rows = function() {
      function popup(attr) {
          return ''+attr.count+'';
      }
      return data.map(function(log){
        return [log.log.log_id, log.log.user, log.log.description, log.get('FATAL', popup), log.get('INTERNAL', popup), log.get('ERROR', popup), log.get('WARNING', popup), log.status.reason, log.log.children, log.status.status];
      });
    };

    // attach methods to individual data
    for (log in data) {
      data[log].get = get;
    }
  };

  $report.openLog = function(data, anchor) {
    var self = this;
    this.id  = $report.tab_id();
    this.div = $('
', {class: "tab", id:self.id});
    anchor = anchor || data.anchor;

    this.widget = function() {
      function has_ident(json) {
        return json[0].ident !== null || (json.length > 1 && has_ident(json.splice(1)));
      }
      var nodes  = $('code', self.div);
      var widget = $('
').appendTo(self.div);
      var align  = function() {
        widget.animate({top:$(self.div).scrollTop()},{duration:100,queue:false});
      };
      $(this.div).scroll(align);
      // show/hide timestamp
      $('<input type="checkbox">').appendTo(widget).bind('change.time', function(event){$('time', self.div).toggle()}).wrap('
Show time
');
      var ident =  $('<input type="checkbox">').appendTo(widget).bind('change.tag', function(event){$('ident', self.div).toggle()}).wrap('
Show ident
');
      if (has_ident(self.json)) {
        ident.trigger('click');
      } else {
        ident.prop('title', 'there are no given idents');
      }
      // filter by severity
      var slider = $('
').appendTo(widget);
      var lower  = $("
").css({ position : 'absolute' , top : 10, left : 0 }).text($report.levels.severity(0)).hide();
      var upper  = $("
").css({ position : 'absolute' , top : 10, left : 0 }).text($report.levels.severity($report.levels._SIZE-1)).hide();
      slider.slider({
        range: true,
        min: 0,
        max: $report.levels._SIZE-1,
        values: [ 0, $report.levels._SIZE-1 ]
      }).bind('slide.example', function(event, ui) {
        self.div.hide();
        lower.text($report.levels.severity(ui.values[0]));
        upper.text($report.levels.severity(ui.values[1]));
        nodes.each(function(index){if(($(this).attr('level') >= ui.values[0]) && ($(this).attr('level') <= ui.values[1])){$(this).show()}else{$(this).hide()}})
        self.div.show();
      });
      slider.find(".ui-slider-handle:first")
        .append(lower)
        .bind('mouseenter.example', function(event){lower.show()})
        .bind('mouseleave.example', function(event){lower.hide()});
      slider.find(".ui-slider-handle:last")
        .append(upper)
        .bind('mouseenter.example', function(event){upper.show()})
        .bind('mouseleave.example', function(event){upper.hide()});
      // message indexed by severity
      function getBySeverity() {
        function sorted(nodes) {
          function children(nodes) {
            return nodes.slice(0,11).map(
              function(it, idx){
                return {
                  "title"    : (idx>9)?'...':$report.levels.severity(parseInt($(it).attr('level'))),
                  "key"      : it.idx
                };
            });
          };
          return Object.keys(nodes).sort().map(
            function(it) {
              return {
        	      "title"    : '(' + it.slice(1) + ') ' + $report.levels.severity(parseInt(it.slice(1))) + ' <s' + parseInt(it.slice(1))/10 + '>' + nodes[it].length + '</s>',
                "key"      : nodes[it][0].idx,
                "children" : children(nodes[it])
             }}
          );
        };
  	return sorted(nodes.toArray().reduce(function(levels, node, idx) {
          var level = 's'+$(node).attr('level');
          node.idx = idx;
          if (!levels.hasOwnProperty(level)) levels[level]=[];
          levels[level].push(node);
          return levels;
        }, {}));
      }

      var msgIndex = $('
').appendTo(widget);
      msgIndex.dynatree({
        children : [
            {title : "Messages", isFolder : true, children : getBySeverity(nodes)},
        ],
        onActivate: function(node) {
            self.div.animate({scrollTop : $(nodes[node.data.key]).offset().top - self.div.offset().top + self.div.scrollTop() - self.div.height()/2});
        },
        onRender : function(dtnode, nodeSpan) {
          $('a', dtnode.li).hover(
            function(){$(nodes[$.ui.dynatree.getNode(this).data.key]).addClass(   'example-highlight')},
            function(){$(nodes[$.ui.dynatree.getNode(this).data.key]).removeClass('example-highlight')}
          );
          align();
        }
      });
    }

    this.add = function(tabs) {
      tabs.tabs('add', '#'+self.id, data.log_id+' log');
    }

    this.div.appendTo(anchor);
    $.ajax({
      url : 'msgs/'+data.log_id,
      dataType : 'json',
      success : function(data) {
        self.json = data;
        self.div.jqoteapp('#template', self.json);
        self.widget();
      },
      error : function(xhr, status, index) {
        console.log(xhr, status, index);
      }
    });

  };

  $report.openLog.justify = function (c, l) {
    l = l || 12;
    return Array(l).join(' ').substr(c.length) + c;
  }
  $report.openLog.msg = function (m) {
    return m.replace(/>/g, '>').replace(/</g, '<');
  }

  $report.openHier = function(data, anchor){
    var self = this;
    this.id  = $report.tab_id();
    this.div = $('
', {id : this.id});
    this.explorer = $('
');
    this.children = $('
');

    // find all logs with given parent id and return with children
    // in extreme cases it will be more expedient to do this on the server
    // as output is grouped by parent
    this.build = function build(parent) {
      return self.json.filter(
        function(it){
          if (it.log.parent === parent) {
            it.children = build(it.log.log_id);
            return true;
          }
          return false;
        });
    };
    // opposite-ish of above
    this.flatten = function flatten(json) {
	return json.concat(json.reduce(function(p,c){return p.concat(flatten(c.children));}, Array()));
    }

    this.find = function (log_id) {
      for (o in self.json) if (self.json[o].log.log_id == log_id) return self.json[o];
    }

    this.add = function(tabs) {
      tabs.tabs('add', '#'+self.id, data.log_id+' hier');
    };

    this.table = function(log_id) {
      this.children.html((new $report.testJSON(self.json, anchor)).render());
    };

    this.pane = function() {
      function hier(json, flat) {
        flat = flat || false;
          return json.map(function(it){return {title : it.log.description + '(' + it.log.log_id + ')', isFolder : it.children.length, key : it.log.log_id, children : flat?[]:hier(it.children || [], flat)}});
      }
      var tree = $('
').dynatree({
        children : [
            {title : "ALL", isFolder : true, key : null, children : hier(self.json, true)},
          hier(self.tree)[0]
        ],
        onExpand: function(flag, node) {
          if (flag) {
            self.table(node.data.key.log_id);
	  }
        },
        onActivate: function(node) {
          var create = node.data.children.length?$report.openRegr:$report.openLog;
          // this will be a tab-within-tab
          (new create({log_id : node.data.key, hier : [self.find(node.data.key),], anchor : anchor})).add(anchor);
        },
      });
      this.explorer.append(tree);
    }

    this.init = function(data) {
      self.json = data;
      self.tree = self.build(null);
      self.pane();
    }

    this.div.appendTo(anchor);
    this.div.append(this.explorer, this.children);
    if (data.hasOwnProperty('hier')) {
      self.tree = data.hier;
      self.json = self.flatten(self.tree);
      self.pane();
    } else {
      $.ajax({
        url : 'rgr/'+data.log_id,
        dataType : 'json',
        success : function(data) {
          self.json = data;
          self.tree = self.build(null);
          self.pane();
        },
        error : function(xhr, status, index) {
          console.log(xhr, status, index);
        }
      });
    }
  }

  $report.openRegr = function(data){
    var self = this;
    this.id  = $report.tab_id();
    this.div = $('
', {id : this.id}).append('
');
    this.add = function(tabs) {
      tabs.tabs('add', '#'+self.id, data.log_id+' regr');
    };

    this.div.appendTo(data.anchor);
    this.tabs = this.div.tabs();

    this.hier = new $report.openHier(data, this.tabs);
    this.hier.add(this.tabs);

    this.log = new $report.openLog(data, this.tabs);
    this.log.add(this.tabs);
  }

})($report);

<|endoftext|>


<commit_before>// Copyright Chris Mills
// https://developer.mozilla.org/en-US/profiles/chrisdavidmills,
// Mozilla Development Network and individual MDN contributors.
// Arbitrarily modified by David Corking.

// Unless otherwise indicated, the content is available under the
// terms of the Creative Commons Attribution-ShareAlike license
// (CC-BY-SA), v2.5 or any later version.
// http://creativecommons.org/licenses/by-sa/2.5/ --> Made by
// following the tutorial at
// https://developer.mozilla.org/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript

// global singleton to contain game
var BG = {
  rightPressed: false,
  leftPressed: false
};

// event handlers must be defined before they are registered
BG.keyDownHandler = function (e) {
  if(e.keyCode == 39) {
    BG.rightPressed = true;
  }
  else if(e.keyCode == 37) {
    BG.leftPressed = true;
  }
};

BG.keyUpHandler = function (e) {
  if(e.keyCode == 39) {
    BG.rightPressed = false;
  }
  else if(e.keyCode == 37) {
    BG.leftPressed = false;
  }
};

BG.canvas = document.getElementById("myCanvas");
BG.ctx = BG.canvas.getContext("2d");

// constants
BG.paddle = {
  height: 10,
  width: 75,
  speed: 3
};
BG.ball = {
  radius: 10
};
BG.wall = {
  rowCount: 3,
  columnCount: 5,
  offsetTop: 30,
  offsetLeft: 30
};
BG.wall.brick = {
  width: 75,
  height: 20,
  padding: 10
};

// bounce in the opposite Y direction, for example off a brick
BG.ball.bounceY = function () {
  this.dy = - this.dy;
};

BG.ball.draw = function (ctx) {
  ctx.beginPath();
  ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
};

BG.ball.step = function () {
  // TODO: poss. refactor to avoid referring
  // directly to BG ?
  // collision with top
  if (this.y - this.radius + this.dy < 0) {
    this.dy = - this.dy;
  };
  // collision with paddle - y too big
  if ((this.y + this.radius + this.dy + BG.paddle.height >
      BG.canvas.height)    &&
      this.x > BG.paddle.x &&
      this.x - BG.paddle.x < BG.paddle.width) {
    this.dy = - this.dy;
  };
  // collision with sides
  if (this.x - this.radius + this.dx < 0 ||
      this.x + this.radius + this.dx > BG.canvas.width ) {
    this.dx = - this.dx;
  };
  // only one ball, so lose it and it's game over
  if (this.y + this.radius + this.dy > BG.canvas.height ) {
    BG.gameOver = true;
  };
  // collision with a brick
  BG.wall.collisionDetection(this);
  //move
  this.x += this.dx;
  this.y += this.dy;
};

BG.wall.collisionDetection = function(ball) {
  for(c=0; c< BG.wall.columnCount; c++) {
    for(r=0; r<BG.wall.rowCount; r++) {
      var brick = BG.wall.bricks[c][r];
      if (BG.wall.overlaps(ball, brick)) {
        BG.wall.bricks[c][r] = { x: -100, y: -100 };
        ball.bounceY();
      }
    }
  }
}

BG.paddle.draw = function (ctx) {
  ctx.beginPath();
  ctx.rect(this.x,
           BG.canvas.height - this.height,
           this.width, this.height);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
};

BG.paddle.step = function () {
  if (BG.rightPressed && this.x + this.width < BG.canvas.width ) {
    this.x += this.speed;
  };
  if (BG.leftPressed && this.x > 0) {
    this.x -= this.speed;
  };
};

// build a 2D array of bricks to represent a wall
BG.wall.build = function () {
  for(c=0; c < this.columnCount; c++) {
    this.bricks[c] = [];
    for(r=0; r < this.rowCount; r++ ) {
      var brickX = (c * (this.brick.width + this.brick.padding)) +
            this.offsetLeft;
      var brickY = (r * (this.brick.height + this.brick.padding)) +
            this.offsetTop;
      this.bricks[c][r] = { x: 0, y: 0};
      this.bricks[c][r].x = brickX;
      this.bricks[c][r].y = brickY;
    }
  }
};

// render a wall
BG.wall.draw = function (ctx) {
  for(c=0; c < this.columnCount; c++) {
    for(r=0; r < this.rowCount; r++) {
      var brickX = this.bricks[c][r].x
      var brickY = this.bricks[c][r].y
      ctx.beginPath();
      ctx.rect(brickX, brickY, this.brick.width, this.brick.height);
      ctx.fillStyle = "#0095DD";
      ctx.fill();
      ctx.closePath();
    }
  }
};

// boolean
BG.wall.overlaps = function (ball, brick) {
  return (ball.x > brick.x &&
          ball.x < (brick.x + BG.wall.brick.width) &&
          ball.y > brick.y &&
          ball.y < (brick.y + BG.wall.brick.height));
}

// Draw the world, then update it
BG.draw = function () {
  // When setInterval invokes BG.draw, 'this' is the global object
  // so this doesn't refer to my game object
  // When I wrap the callback in setInterval to an anonymous function, as:
  //    function(){BG.draw()}
  // then 'this' does indeed become the game object.

  if (! BG.gameOver) {
    BG.ctx.clearRect(0, 0, BG.canvas.width, BG.canvas.height);
    BG.wall.draw(BG.ctx);
    BG.ball.draw(BG.ctx);
    BG.ball.step();
    BG.paddle.draw(BG.ctx);
    BG.paddle.step();
    }
  else {
    window.clearInterval(BG.drawAction); // stop the world
    document.write ("
Game over!

Reload page to play again.
");
  };
};

////////////////////////////////////////////////////////
// Main program                                       //
////////////////////////////////////////////////////////

// initialize game
BG.score = 0;
BG.gameOver = false;
// initialize ball
// velocity
BG.ball.dx = 2;  // rightwards
BG.ball.dy = -2; // upwards
// position
BG.ball.x = BG.canvas.width / 2;
BG.ball.y = BG.canvas.height - BG.paddle.height - BG.ball.radius + BG.ball.dy;
// paddle starts in middle
BG.paddle.x = (BG.canvas.width - BG.paddle.width ) / 2;
// initialize wall
BG.wall.bricks = [];
BG.wall.build();

document.addEventListener("keydown", BG.keyDownHandler, false);
document.addEventListener("keyup", BG.keyUpHandler, false);

// repeatedly draw and update the world
BG.drawAction = window.setInterval(
  function(){BG.draw();},
  10);
<commit_msg>breakout: more maintainable erasure of bricks<commit_after>// Copyright Chris Mills
// https://developer.mozilla.org/en-US/profiles/chrisdavidmills,
// Mozilla Development Network and individual MDN contributors.
// Arbitrarily modified by David Corking.

// Unless otherwise indicated, the content is available under the
// terms of the Creative Commons Attribution-ShareAlike license
// (CC-BY-SA), v2.5 or any later version.
// http://creativecommons.org/licenses/by-sa/2.5/ --> Made by
// following the tutorial at
// https://developer.mozilla.org/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript

// global singleton to contain game
var BG = {
  rightPressed: false,
  leftPressed: false
};

// event handlers must be defined before they are registered
BG.keyDownHandler = function (e) {
  if(e.keyCode == 39) {
    BG.rightPressed = true;
  }
  else if(e.keyCode == 37) {
    BG.leftPressed = true;
  }
};

BG.keyUpHandler = function (e) {
  if(e.keyCode == 39) {
    BG.rightPressed = false;
  }
  else if(e.keyCode == 37) {
    BG.leftPressed = false;
  }
};

BG.canvas = document.getElementById("myCanvas");
BG.ctx = BG.canvas.getContext("2d");

// constants
BG.paddle = {
  height: 10,
  width: 75,
  speed: 3
};
BG.ball = {
  radius: 10
};
BG.wall = {
  rowCount: 3,
  columnCount: 5,
  offsetTop: 30,
  offsetLeft: 30
};
BG.wall.brick = {
  width: 75,
  height: 20,
  padding: 10
};

// bounce in the opposite Y direction, for example off a brick
BG.ball.bounceY = function () {
  this.dy = - this.dy;
};

BG.ball.draw = function (ctx) {
  ctx.beginPath();
  ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
};

BG.ball.step = function () {
  // TODO: poss. refactor to avoid referring
  // directly to BG ?
  // collision with top
  if (this.y - this.radius + this.dy < 0) {
    this.dy = - this.dy;
  };
  // collision with paddle - y too big
  if ((this.y + this.radius + this.dy + BG.paddle.height >
      BG.canvas.height)    &&
      this.x > BG.paddle.x &&
      this.x - BG.paddle.x < BG.paddle.width) {
    this.dy = - this.dy;
  };
  // collision with sides
  if (this.x - this.radius + this.dx < 0 ||
      this.x + this.radius + this.dx > BG.canvas.width ) {
    this.dx = - this.dx;
  };
  // only one ball, so lose it and it's game over
  if (this.y + this.radius + this.dy > BG.canvas.height ) {
    BG.gameOver = true;
  };
  // collision with a brick
  BG.wall.collisionDetection(this);
  //move
  this.x += this.dx;
  this.y += this.dy;
};

BG.wall.collisionDetection = function(ball) {
  for(c=0; c< BG.wall.columnCount; c++) {
    for(r=0; r<BG.wall.rowCount; r++) {
      var brick = BG.wall.bricks[c][r];
      if (BG.wall.overlaps(ball, brick)) {
        BG.wall.bricks[c][r].visible = false;
        ball.bounceY();
      }
    }
  }
}

BG.paddle.draw = function (ctx) {
  ctx.beginPath();
  ctx.rect(this.x,
           BG.canvas.height - this.height,
           this.width, this.height);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
};

BG.paddle.step = function () {
  if (BG.rightPressed && this.x + this.width < BG.canvas.width ) {
    this.x += this.speed;
  };
  if (BG.leftPressed && this.x > 0) {
    this.x -= this.speed;
  };
};

// build a 2D array of bricks to represent a wall
BG.wall.build = function () {
  for(c=0; c < this.columnCount; c++) {
    this.bricks[c] = [];
    for(r=0; r < this.rowCount; r++ ) {
      var brickX = (c * (this.brick.width + this.brick.padding)) +
            this.offsetLeft;
      var brickY = (r * (this.brick.height + this.brick.padding)) +
            this.offsetTop;
      this.bricks[c][r] = { x: 0, y: 0, visible: true };
      this.bricks[c][r].x = brickX;
      this.bricks[c][r].y = brickY;
    }
  }
};

// render a wall
BG.wall.draw = function (ctx) {
  for(c=0; c < this.columnCount; c++) {
    for(r=0; r < this.rowCount; r++) {
      if (this.bricks[c][r].visible) {
        var brickX = this.bricks[c][r].x;
        var brickY = this.bricks[c][r].y;
        ctx.beginPath();
        ctx.rect(brickX, brickY, this.brick.width, this.brick.height);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
      }
    }
  }
};

// boolean
BG.wall.overlaps = function (ball, brick) {
  return (brick.visible &&
          ball.x > brick.x &&
          ball.x < (brick.x + BG.wall.brick.width) &&
          ball.y > brick.y &&
          ball.y < (brick.y + BG.wall.brick.height));
}

// Draw the world, then update it
BG.draw = function () {
  // When setInterval invokes BG.draw, 'this' is the global object
  // so this doesn't refer to my game object
  // When I wrap the callback in setInterval to an anonymous function, as:
  //    function(){BG.draw()}
  // then 'this' does indeed become the game object.

  if (! BG.gameOver) {
    BG.ctx.clearRect(0, 0, BG.canvas.width, BG.canvas.height);
    BG.wall.draw(BG.ctx);
    BG.ball.draw(BG.ctx);
    BG.ball.step();
    BG.paddle.draw(BG.ctx);
    BG.paddle.step();
    }
  else {
    window.clearInterval(BG.drawAction); // stop the world
    document.write ("
Game over!

Reload page to play again.
");
  };
};

////////////////////////////////////////////////////////
// Main program                                       //
////////////////////////////////////////////////////////

// initialize game
BG.score = 0;
BG.gameOver = false;
// initialize ball
// velocity
BG.ball.dx = 2;  // rightwards
BG.ball.dy = -2; // upwards
// position
BG.ball.x = BG.canvas.width / 2;
BG.ball.y = BG.canvas.height - BG.paddle.height - BG.ball.radius + BG.ball.dy;
// paddle starts in middle
BG.paddle.x = (BG.canvas.width - BG.paddle.width ) / 2;
// initialize wall
BG.wall.bricks = [];
BG.wall.build();

document.addEventListener("keydown", BG.keyDownHandler, false);
document.addEventListener("keyup", BG.keyUpHandler, false);

// repeatedly draw and update the world
BG.drawAction = window.setInterval(
  function(){BG.draw();},
  10);
<|endoftext|>


<commit_before>// Config ===============================================

var Q                    = require('q');
var moment               = require('moment');
var Botkit               = require('botkit');
var responses            = require('./responses.js');

var whitelistedUsers     = ['tyler shambora', 'daniel lerman', 'ryan little', 'cory cummings'];
var readOnlyChannels     = ['C1317518C', 'C3G3Y7RFX'];

// Init ===============================================

if (!process.env.BOT_TOKEN) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: true,
  logLevel: 6
});

controller.configureSlackApp({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
  scopes: ['bot', 'chat:write:user', 'chat:write:bot', 'channels:read']
});

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  if (err) {
    throw new Error(err);
  }
  controller.createWebhookEndpoints(controller.webserver);
  controller.createHomepageEndpoint(controller.webserver);
  controller.createOauthEndpoints(controller.webserver, function(err, req, res) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Great Success!');
    }
  });
});

var bot = controller.spawn({
  token: process.env.BOT_TOKEN
});

bot.startRTM(function(err) {
  if (err) {
    console.log('Even if you fall on your face, you\'re still moving forward.');
    throw new Error(err);
  }
});

// // USED TO GET THE MEGA ADMIN TOKEN
// controller.on('create_user',function(bot, user) {
//   console.log('-----');
//   console.log('USER TOKEN:');
//   console.log(user.access_token);
//   console.log('-----');
// });

var _bots = {};
var trackBot = function(bot) {
  _bots[bot.config.token] = bot;
};

controller.on('create_bot',function(bot, config) {
  if (_bots[bot.config.token]) {
    // already online! do nothing.
  } else {
    bot.startRTM(function(err, bot, payload) {
      if (err) {
        console.log('Even if you fall on your face, you\'re still moving forward.');
        throw new Error(err);
      } else {
        trackBot(bot);
      }
    });
  }
});

controller.storage.teams.all(function(err, teams) {
  if (err) {
    throw new Error(err);
  }
  for (var t in teams) {
    if (teams[t].bot) {
      controller.spawn(teams[t]).startRTM(function(err, bot) {
        if (err) {
          console.log('Error connecting bot to Slack:',err);
        } else {
          trackBot(bot);
        }
      });
    }
  }
});

// Helper Functions ===============================================

var getRealNameFromId = function(bot, userId) {
  var deferred = Q.defer();
  var realName = '';
  bot.api.users.info({user: userId}, function(err, response) {
    realName = response.user.real_name.toLowerCase();
    deferred.resolve(realName);
  });
  return deferred.promise;
};

var isValidChannelName = function(bot, channelName) {
  var deferred = Q.defer();
  bot.api.channels.list({}, function(err, response) {
    deferred.resolve(response.channels.some(function(channel) {
      return channel.name === channelName;
    }));
  });
  return deferred.promise;
};

var isValidUser = function(realName) {
  var deferred = Q.defer();
  deferred.resolve(whitelistedUsers.some(function(userName) {
    return userName === realName;
  }));
  return deferred.promise;
};

// Listeners  ===============================================

controller.hears([/post to (\S+)\n([\s\S]*)/], 'direct_message', function(bot, message) {
  var channelName = message.match[1];
  var update = message.match[2];

  var parsedMessages = update.split('\n\n\n').map(function(block) {
    var messageParts = block.split('\n___\n');
    return {
      fallback: messageParts[1],
      title: messageParts[0],
      text: messageParts[1],
      color: 'danger',
      mrkdwn_in: ['fallback', 'text']
    };
  });

  var validateChannel = isValidChannelName(bot, channelName);
  var validateName = getRealNameFromId(bot, message.user).then(isValidUser);
  var isValidated = Q.all([validateChannel, validateName]);

  isValidated.spread(function(validChannel, validUser) {
    if (!validUser) {
      return bot.reply(message, 'Sorry, you\'re not authenticated to post.');
    } else if (!validChannel) {
      return bot.reply(message, 'Sorry, I can\'t post to the channel: ' + channelName + '.');
    } else if (validUser && validChannel) {
      var theDate = moment().format('dddd, MMMM Do YYYY');
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to post the following:*');
        convo.say({
          username: 'Brian Williams: Dev Team News Anchor',
          icon_url: 'http://dev.tylershambora.com/images/father-williams.jpg',
          text: '<!channel>\n\n*Updates for ' + theDate + ':*',
          attachments: parsedMessages
        });
        convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
          responses.yes(bot, channelName, parsedMessages, theDate),
          responses.no(bot),
          responses.default()
        ]);
      });
    }
  });
});

controller.hears(['hey mister'], ['direct_message', 'mention', 'direct_mention'], function(bot, message) {
  getRealNameFromId(bot, message.user)
    .then(isValidUser)
    .then(function(result) {
      bot.reply(message, 'Hello!');
      if (result) {
        bot.reply(message, 'Hey! You\'re pretty valid!');
      }
    });
});

controller.hears([/delete (\S+) from (\S+)/], ['direct_message'], function(bot, message) {
  console.log('ding');
  var channelOptions = {
    token: process.env.MEGA_TOKEN,
    channel: message.match[2],
  };

  var deleteOptions = {
    token: process.env.MEGA_TOKEN,
    ts: message.match[1],
    channel: message.match[2],
    as_user: true
  };

  bot.api.channels.info(channelOptions, function (err, repsonse) {
    if (!response.ok) {
      bot.reply(message, 'incorrect channel id');
    } else {
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to delete:*');
        convo.say(`https://bva.slack.com/archives/${response.channel.name}/p${message.match[1].replace('.', '')}`);
        // convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
        //   responses.yes(bot, channelName, parsedMessages, theDate),
        //   responses.no(bot),
        //   responses.default()
        // ]);
      });
    }
  });

  // bot.api.chat.delete(options, function(err, response) {
  //   if (!response.ok) {
  //     console.log('Unable to delete due to error: ' + err);
  //     console.log('Trying one more time in 2 seconds');
  //     setTimeout(function() {
  //       bot.api.chat.delete(options, function(err, response) {
  //         if (!response.ok) {
  //           console.log('Unable to delete after a second attempt due to error: ' + err);
  //         }
  //       });
  //     }, 2000);
  //   } else {
  //     console.log('Message successfully deleted!');
  //   }
  // });

});

controller.on('direct_message, mention, direct_mention', function(bot, message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'jesus',
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      bot.reply(message, 'go with christ brah.');
    }
  });
});

controller.hears([/[\s\S]*/], ['direct_message', 'direct_mention', 'mention', 'ambient'], function(bot, message) {
  if (readOnlyChannels.indexOf(message.channel) !== -1) {
    getRealNameFromId(bot, message.user).then(function(realName) {
      var options = {
        token: process.env.MEGA_TOKEN,
        ts: message.ts,
        channel: message.channel,
        as_user: true
      };

      console.log('%s said: "%s"', realName, message.text);
      console.log('Attempting to delete the message.' );

      // this whole block looks pretty ripe for some abstraction and recursion (tsham)
      bot.api.chat.delete(options, function(err, response) {
        if (!response.ok) {
          console.log('Unable to delete due to error: ' + err);
          console.log('Trying one more time in 2 seconds');
          setTimeout(function() {
            bot.api.chat.delete(options, function(err, response) {
              if (!response.ok) {
                console.log('Unable to delete after a second attempt due to error: ' + err);
              }
            });
          }, 2000);
        } else {
          console.log('Message successfully deleted!');
        }
      });
    });
  }
});

controller.on('rtm_open', function(bot) {
  console.log('** The RTM api just connected: ' + bot.identity.name);
});

controller.on('rtm_close', function() {
  console.log('** The RTM api just closed');
});
<commit_msg>wip``<commit_after>// Config ===============================================

var Q                    = require('q');
var moment               = require('moment');
var Botkit               = require('botkit');
var responses            = require('./responses.js');

var whitelistedUsers     = ['tyler shambora', 'daniel lerman', 'ryan little', 'cory cummings'];
var readOnlyChannels     = ['C1317518C', 'C3G3Y7RFX'];

// Init ===============================================

if (!process.env.BOT_TOKEN) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: true,
  logLevel: 6
});

controller.configureSlackApp({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
  scopes: ['bot', 'chat:write:user', 'chat:write:bot', 'channels:read']
});

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  if (err) {
    throw new Error(err);
  }
  controller.createWebhookEndpoints(controller.webserver);
  controller.createHomepageEndpoint(controller.webserver);
  controller.createOauthEndpoints(controller.webserver, function(err, req, res) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Great Success!');
    }
  });
});

var bot = controller.spawn({
  token: process.env.BOT_TOKEN
});

bot.startRTM(function(err) {
  if (err) {
    console.log('Even if you fall on your face, you\'re still moving forward.');
    throw new Error(err);
  }
});

// // USED TO GET THE MEGA ADMIN TOKEN
// controller.on('create_user',function(bot, user) {
//   console.log('-----');
//   console.log('USER TOKEN:');
//   console.log(user.access_token);
//   console.log('-----');
// });

var _bots = {};
var trackBot = function(bot) {
  _bots[bot.config.token] = bot;
};

controller.on('create_bot',function(bot, config) {
  if (_bots[bot.config.token]) {
    // already online! do nothing.
  } else {
    bot.startRTM(function(err, bot, payload) {
      if (err) {
        console.log('Even if you fall on your face, you\'re still moving forward.');
        throw new Error(err);
      } else {
        trackBot(bot);
      }
    });
  }
});

controller.storage.teams.all(function(err, teams) {
  if (err) {
    throw new Error(err);
  }
  for (var t in teams) {
    if (teams[t].bot) {
      controller.spawn(teams[t]).startRTM(function(err, bot) {
        if (err) {
          console.log('Error connecting bot to Slack:',err);
        } else {
          trackBot(bot);
        }
      });
    }
  }
});

// Helper Functions ===============================================

var getRealNameFromId = function(bot, userId) {
  var deferred = Q.defer();
  var realName = '';
  bot.api.users.info({user: userId}, function(err, response) {
    realName = response.user.real_name.toLowerCase();
    deferred.resolve(realName);
  });
  return deferred.promise;
};

var isValidChannelName = function(bot, channelName) {
  var deferred = Q.defer();
  bot.api.channels.list({}, function(err, response) {
    deferred.resolve(response.channels.some(function(channel) {
      return channel.name === channelName;
    }));
  });
  return deferred.promise;
};

var isValidUser = function(realName) {
  var deferred = Q.defer();
  deferred.resolve(whitelistedUsers.some(function(userName) {
    return userName === realName;
  }));
  return deferred.promise;
};

// Listeners  ===============================================

controller.hears([/post to (\S+)\n([\s\S]*)/], 'direct_message', function(bot, message) {
  var channelName = message.match[1];
  var update = message.match[2];

  var parsedMessages = update.split('\n\n\n').map(function(block) {
    var messageParts = block.split('\n___\n');
    return {
      fallback: messageParts[1],
      title: messageParts[0],
      text: messageParts[1],
      color: 'danger',
      mrkdwn_in: ['fallback', 'text']
    };
  });

  var validateChannel = isValidChannelName(bot, channelName);
  var validateName = getRealNameFromId(bot, message.user).then(isValidUser);
  var isValidated = Q.all([validateChannel, validateName]);

  isValidated.spread(function(validChannel, validUser) {
    if (!validUser) {
      return bot.reply(message, 'Sorry, you\'re not authenticated to post.');
    } else if (!validChannel) {
      return bot.reply(message, 'Sorry, I can\'t post to the channel: ' + channelName + '.');
    } else if (validUser && validChannel) {
      var theDate = moment().format('dddd, MMMM Do YYYY');
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to post the following:*');
        convo.say({
          username: 'Brian Williams: Dev Team News Anchor',
          icon_url: 'http://dev.tylershambora.com/images/father-williams.jpg',
          text: '<!channel>\n\n*Updates for ' + theDate + ':*',
          attachments: parsedMessages
        });
        convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
          responses.yes(bot, channelName, parsedMessages, theDate),
          responses.no(bot),
          responses.default()
        ]);
      });
    }
  });
});

controller.hears(['hey mister'], ['direct_message', 'mention', 'direct_mention'], function(bot, message) {
  getRealNameFromId(bot, message.user)
    .then(isValidUser)
    .then(function(result) {
      bot.reply(message, 'Hello!');
      if (result) {
        bot.reply(message, 'Hey! You\'re pretty valid!');
      }
    });
});

controller.hears([/delete (\S+) from (\S+)/], ['direct_message'], function(bot, message) {
  console.log('ding');
  var channelOptions = {
    token: process.env.MEGA_TOKEN,
    channel: message.match[2],
  };

  var deleteOptions = {
    token: process.env.MEGA_TOKEN,
    ts: message.match[1],
    channel: message.match[2],
    as_user: true
  };

  bot.api.channels.info(channelOptions, function (err, response) {
    if (!response.ok) {
      bot.reply(message, 'incorrect channel id');
    } else {
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to delete:*');
        convo.say(`https://bva.slack.com/archives/${response.channel.name}/p${message.match[1].replace('.', '')}`);
        // convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
        //   responses.yes(bot, channelName, parsedMessages, theDate),
        //   responses.no(bot),
        //   responses.default()
        // ]);
      });
    }
  });

  // bot.api.chat.delete(options, function(err, response) {
  //   if (!response.ok) {
  //     console.log('Unable to delete due to error: ' + err);
  //     console.log('Trying one more time in 2 seconds');
  //     setTimeout(function() {
  //       bot.api.chat.delete(options, function(err, response) {
  //         if (!response.ok) {
  //           console.log('Unable to delete after a second attempt due to error: ' + err);
  //         }
  //       });
  //     }, 2000);
  //   } else {
  //     console.log('Message successfully deleted!');
  //   }
  // });

});

controller.on('direct_message, mention, direct_mention', function(bot, message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'jesus',
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      bot.reply(message, 'go with christ brah.');
    }
  });
});

controller.hears([/[\s\S]*/], ['direct_message', 'direct_mention', 'mention', 'ambient'], function(bot, message) {
  if (readOnlyChannels.indexOf(message.channel) !== -1) {
    getRealNameFromId(bot, message.user).then(function(realName) {
      var options = {
        token: process.env.MEGA_TOKEN,
        ts: message.ts,
        channel: message.channel,
        as_user: true
      };

      console.log('%s said: "%s"', realName, message.text);
      console.log('Attempting to delete the message.' );

      // this whole block looks pretty ripe for some abstraction and recursion (tsham)
      bot.api.chat.delete(options, function(err, response) {
        if (!response.ok) {
          console.log('Unable to delete due to error: ' + err);
          console.log('Trying one more time in 2 seconds');
          setTimeout(function() {
            bot.api.chat.delete(options, function(err, response) {
              if (!response.ok) {
                console.log('Unable to delete after a second attempt due to error: ' + err);
              }
            });
          }, 2000);
        } else {
          console.log('Message successfully deleted!');
        }
      });
    });
  }
});

controller.on('rtm_open', function(bot) {
  console.log('** The RTM api just connected: ' + bot.identity.name);
});

controller.on('rtm_close', function() {
  console.log('** The RTM api just closed');
});
<|endoftext|>


<commit_before>// Config ===============================================

var Q                    = require('q');
var moment               = require('moment');
var Botkit               = require('botkit');
var responses            = require('./responses.js');

var whitelistedUsers     = ['tyler shambora', 'daniel lerman', 'ryan little', 'cory cummings'];
var readOnlyChannels     = ['C1317518C'];

// Init ===============================================

if (!process.env.BOT_TOKEN) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: true,
  logLevel: 6
});

controller.configureSlackApp({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
  scopes: ['bot', 'chat:write:user', 'chat:write:bot']
});

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  if (err) {
    throw new Error(err);
  }
  controller.createWebhookEndpoints(controller.webserver);
  controller.createHomepageEndpoint(controller.webserver);
  controller.createOauthEndpoints(controller.webserver, function(err, req, res) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Great Success!');
    }
  });
});

var _bots = {};
var trackBot = function(bot) {
  _bots[bot.config.token] = bot;
};

controller.on('create_bot',function(bot, config) {
  if (_bots[bot.config.token]) {
    // already online! do nothing.
  } else {
    bot.startRTM(function(err, bot, payload) {
      if (err) {
        console.log('Even if you fall on your face, you\'re still moving forward.');
        throw new Error(err);
      } else {
        trackBot(bot);
      }
    });
  }
});

controller.storage.teams.all(function(err, teams) {
  if (err) {
    throw new Error(err);
  }
  for (var t in teams) {
    if (teams[t].bot) {
      controller.spawn(teams[t]).startRTM(function(err, bot) {
        if (err) {
          console.log('Error connecting bot to Slack:',err);
        } else {
          trackBot(bot);
        }
      });
    }
  }
});

// Helper Functions ===============================================

var getRealNameFromId = function(bot, userId) {
  var deferred = Q.defer();
  var realName = '';
  bot.api.users.info({user: userId}, function(err, response) {
    realName = response.user.real_name.toLowerCase();
    deferred.resolve(realName);
  });
  return deferred.promise;
};

var isValidChannelName = function(bot, channelName) {
  var deferred = Q.defer();
  bot.api.channels.list({}, function(err, response) {
    deferred.resolve(response.channels.some(function(channel) {
      return channel.name === channelName;
    }));
  });
  return deferred.promise;
};

var isValidUser = function(realName) {
  var deferred = Q.defer();
  deferred.resolve(whitelistedUsers.some(function(userName) {
    return userName === realName;
  }));
  return deferred.promise;
};

// Listeners  ===============================================

controller.hears([/post to (\S+)\n([\s\S]*)/], 'direct_message', function(bot, message) {
  var channelName = message.match[1];
  var update = message.match[2];

  var parsedMessages = update.split('\n\n\n').map(function(block) {
    var messageParts = block.split('\n___\n');
    return {
      fallback: messageParts[1],
      title: messageParts[0],
      text: messageParts[1],
      color: 'danger',
      mrkdwn_in: ['fallback', 'text']
    };
  });

  var validateChannel = isValidChannelName(bot, channelName);
  var validateName = getRealNameFromId(bot, message.user).then(isValidUser);
  var isValidated = Q.all([validateChannel, validateName]);

  isValidated.spread(function(validChannel, validUser) {
    if (!validUser) {
      return bot.reply(message, 'Sorry, you\'re not authenticated to post.');
    } else if (!validChannel) {
      return bot.reply(message, 'Sorry, I can\'t post to the channel: ' + channelName + '.');
    } else if (validUser && validChannel) {
      var theDate = moment().format('dddd, MMMM Do YYYY');
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to post the following:*');
        convo.say({
          username: 'Brian Williams: Dev Team News Anchor',
          icon_url: 'http://dev.tylershambora.com/images/father-williams.jpg',
          text: '<!channel>\n\n*Updates for ' + theDate + ':*',
          attachments: parsedMessages
        });
        convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
          responses.yes(bot, channelName, parsedMessages, theDate),
          responses.no(bot),
          responses.default()
        ]);
      });
    }
  });
});

controller.hears(['hey mister'], ['direct_message', 'mention', 'direct_mention'], function(bot, message) {
  getRealNameFromId(bot, message.user)
    .then(isValidUser)
    .then(function(result) {
      bot.reply(message, 'Hello!');
      if (result) {
        bot.reply(message, 'Hey! You\'re pretty valid!');
      }
    });
});

controller.on('direct_message, mention, direct_mention', function(bot, message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'jesus',
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      bot.reply(message, 'go with christ brah.');
    }
  });
});

controller.on('ambient', function(bot, message) {
  console.log('ding');
  if (readOnlyChannels.indexOf(message.channel) !== -1) {
    console.log('dang');
    getRealNameFromId(bot, message.user).then(function(realName) {
      console.log('dong: ' + realName);
      var options = {
        token: process.env.MEGA_TOKEN,
        ts: message.ts,
        channel: message.channel,
        as_user: true
      };

      console.log('%s said: "%s"', realName, message.text);
      console.log('Attempting to delete the message.' );

      // this whole block looks pretty ripe for some abstraction and recursion (tsham)
      bot.api.chat.delete(options, function(err, response) {
        if (!response.ok) {
          console.log('Unable to delete due to error: ' + err);
          console.log('Trying one more time in 2 seconds');
          setTimeout(function() {
            bot.api.chat.delete(options, function(err, response) {
              if (!response.ok) {
                console.log('Unable to delete after a second attempt due to error: ' + err);
              }
            });
          }, 2000);
        } else {
          console.log('Message successfully deleted!');
        }
      });
    });
  }
});

controller.on('rtm_open', function(bot) {
  console.log('** The RTM api just connected: ' + bot.identity.name);
});

controller.on('rtm_close', function() {
  console.log('** The RTM api just closed');
});
<commit_msg>go back to old bot?<commit_after>// Config ===============================================

var Q                    = require('q');
var moment               = require('moment');
var Botkit               = require('botkit');
var responses            = require('./responses.js');

var whitelistedUsers     = ['tyler shambora', 'daniel lerman', 'ryan little', 'cory cummings'];
var readOnlyChannels     = ['C1317518C'];

// Init ===============================================

if (!process.env.BOT_TOKEN) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: true,
  logLevel: 6
});

controller.configureSlackApp({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
  scopes: ['bot', 'chat:write:user', 'chat:write:bot']
});

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  if (err) {
    throw new Error(err);
  }
  controller.createWebhookEndpoints(controller.webserver);
  controller.createHomepageEndpoint(controller.webserver);
  controller.createOauthEndpoints(controller.webserver, function(err, req, res) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Great Success!');
    }
  });
});

var bot = controller.spawn({
  token: process.env.BOT_TOKEN
});

bot.startRTM(function(err) {
  if (err) {
    console.log('Even if you fall on your face, you\'re still moving forward.');
    throw new Error(err);
  }
});

// // USED TO GET THE MEGA ADMIN TOKEN
// controller.on('create_user',function(bot, user) {
//   console.log('-----');
//   console.log('USER TOKEN:');
//   console.log(user.access_token);
//   console.log('-----');
// });

// var _bots = {};
// var trackBot = function(bot) {
//   _bots[bot.config.token] = bot;
// };

// controller.on('create_bot',function(bot, config) {
//   if (_bots[bot.config.token]) {
//     // already online! do nothing.
//   } else {
//     bot.startRTM(function(err, bot, payload) {
//       if (err) {
//         console.log('Even if you fall on your face, you\'re still moving forward.');
//         throw new Error(err);
//       } else {
//         trackBot(bot);
//       }
//     });
//   }
// });

// controller.storage.teams.all(function(err, teams) {
//   if (err) {
//     throw new Error(err);
//   }
//   for (var t in teams) {
//     if (teams[t].bot) {
//       controller.spawn(teams[t]).startRTM(function(err, bot) {
//         if (err) {
//           console.log('Error connecting bot to Slack:',err);
//         } else {
//           trackBot(bot);
//         }
//       });
//     }
//   }
// });

// Helper Functions ===============================================

var getRealNameFromId = function(bot, userId) {
  var deferred = Q.defer();
  var realName = '';
  bot.api.users.info({user: userId}, function(err, response) {
    realName = response.user.real_name.toLowerCase();
    deferred.resolve(realName);
  });
  return deferred.promise;
};

var isValidChannelName = function(bot, channelName) {
  var deferred = Q.defer();
  bot.api.channels.list({}, function(err, response) {
    deferred.resolve(response.channels.some(function(channel) {
      return channel.name === channelName;
    }));
  });
  return deferred.promise;
};

var isValidUser = function(realName) {
  var deferred = Q.defer();
  deferred.resolve(whitelistedUsers.some(function(userName) {
    return userName === realName;
  }));
  return deferred.promise;
};

// Listeners  ===============================================

controller.hears([/post to (\S+)\n([\s\S]*)/], 'direct_message', function(bot, message) {
  var channelName = message.match[1];
  var update = message.match[2];

  var parsedMessages = update.split('\n\n\n').map(function(block) {
    var messageParts = block.split('\n___\n');
    return {
      fallback: messageParts[1],
      title: messageParts[0],
      text: messageParts[1],
      color: 'danger',
      mrkdwn_in: ['fallback', 'text']
    };
  });

  var validateChannel = isValidChannelName(bot, channelName);
  var validateName = getRealNameFromId(bot, message.user).then(isValidUser);
  var isValidated = Q.all([validateChannel, validateName]);

  isValidated.spread(function(validChannel, validUser) {
    if (!validUser) {
      return bot.reply(message, 'Sorry, you\'re not authenticated to post.');
    } else if (!validChannel) {
      return bot.reply(message, 'Sorry, I can\'t post to the channel: ' + channelName + '.');
    } else if (validUser && validChannel) {
      var theDate = moment().format('dddd, MMMM Do YYYY');
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to post the following:*');
        convo.say({
          username: 'Brian Williams: Dev Team News Anchor',
          icon_url: 'http://dev.tylershambora.com/images/father-williams.jpg',
          text: '<!channel>\n\n*Updates for ' + theDate + ':*',
          attachments: parsedMessages
        });
        convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
          responses.yes(bot, channelName, parsedMessages, theDate),
          responses.no(bot),
          responses.default()
        ]);
      });
    }
  });
});

controller.hears(['hey mister'], ['direct_message', 'mention', 'direct_mention'], function(bot, message) {
  getRealNameFromId(bot, message.user)
    .then(isValidUser)
    .then(function(result) {
      bot.reply(message, 'Hello!');
      if (result) {
        bot.reply(message, 'Hey! You\'re pretty valid!');
      }
    });
});

controller.on('direct_message, mention, direct_mention', function(bot, message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'jesus',
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      bot.reply(message, 'go with christ brah.');
    }
  });
});

controller.hears([/[\s\S]*/], ['direct_message', 'direct_mention', 'mention', 'ambient'], function(bot, message) {
  console.log('ding');
  if (readOnlyChannels.indexOf(message.channel) !== -1) {
    console.log('dang');
    getRealNameFromId(bot, message.user).then(function(realName) {
      console.log('dong: ' + realName);
      var options = {
        token: process.env.MEGA_TOKEN,
        ts: message.ts,
        channel: message.channel,
        as_user: true
      };

      console.log('%s said: "%s"', realName, message.text);
      console.log('Attempting to delete the message.' );

      // this whole block looks pretty ripe for some abstraction and recursion (tsham)
      bot.api.chat.delete(options, function(err, response) {
        if (!response.ok) {
          console.log('Unable to delete due to error: ' + err);
          console.log('Trying one more time in 2 seconds');
          setTimeout(function() {
            bot.api.chat.delete(options, function(err, response) {
              if (!response.ok) {
                console.log('Unable to delete after a second attempt due to error: ' + err);
              }
            });
          }, 2000);
        } else {
          console.log('Message successfully deleted!');
        }
      });
    });
  }
});

controller.on('rtm_open', function(bot) {
  console.log('** The RTM api just connected: ' + bot.identity.name);
});

controller.on('rtm_close', function() {
  console.log('** The RTM api just closed');
});
<|endoftext|>


<commit_before>/**
 * This module takes care of loading the BridgeSupport XML files for a given
 * framework, and parsing the data into the given framework object.
 */

var fs = require('fs')
  , sax = require('sax')
  , path = require('path')
  , core = require('./core')
  , types = require('./types')
  , join = path.join
  , basename = path.basename
  , exists = path.existsSync
  , DY_SUFFIX = '.dylib'
  , BS_SUFFIX = '.bridgesupport'

/**
 * Architecture-specific function that returns the Obj-C type from one of
 * these BridgeSupport XML nodes.
 */
var getType;
if (process.arch == 'x64')
  getType = function (node) {
    var a = node.attributes;
    return a.type64 || a.type;
  }
else
  getType = function (node) {
    return node.attributes.type;
  }

/**
 * Attempts to retrieve the BridgeSupport files for the given framework.
 * It synchronously reads the contents of the bridgesupport files and parses
 * them in order to add the symbols that the Obj-C runtime functions cannot
 * determine.
 */
function bridgesupport (fw, _global) {

  var bridgeSupportDir = join(fw.basePath, 'Resources', 'BridgeSupport')
    , bridgeSupportXML = join(bridgeSupportDir, fw.name + BS_SUFFIX)
    , bridgeSupportDylib = join(bridgeSupportDir, fw.name + DY_SUFFIX)

  // If there's no BridgeSupport file, then just return the empty object...
  if (!exists(bridgeSupportXML)) {
    //console.warn('No BridgeSupport files found for framework "%s" at: %s', fw.name, bridgeSupportXML);
    return;
  }

  if (exists(bridgeSupportDylib)) {
    fw.inline = core.dlopen(bridgeSupportDylib);
  }

  var contents = fs.readFileSync(bridgeSupportXML, 'utf8')
    , parser = sax.parser(true)
    , gotEnd = false
    // For processing C functions
    , curName
    , curRtnType
    , curArgTypes
    , isInline

  parser.onerror = function (e) { throw e; }
  parser.onopentag = function (node) {
    //console.error(node);
    switch (node.name) {
      case 'depends_on':
        bridgesupport.import(node.attributes.path);
        break;
      case 'class':
        break;
      case 'method':
        break;
      case 'arg':
        if (curName) {
          // class methods also have args, we only want functions though
          curArgTypes.push(getType(node));
        }
        break;
      case 'retval':
        if (curName) {
          // class methods also have retvals, we only want functions though
          curRtnType = getType(node);
        }
        break;
      case 'signatures':
        // ignore
        break;
      case 'string_constant':
        _global[node.attributes.name] = node.attributes.value;
        break;
      case 'enum':
        _global[node.attributes.name] = parseInt(node.attributes.value);
        break;
      case 'struct':
        break;
      case 'field':
        //console.error(node);
        break;
      case 'cftype':
        break;
      case 'constant':
        (function (name, type) {
          _global.__defineGetter__(name, function () {
            var ptr = fw.lib.get(name);
            // TODO: I'm like 99% sure I need to deref the pointer before
            //       wrapping, but I haven't tested yet...
            delete _global[name];
            return _global[name] = core.wrapValue(ptr, type);
          });
        })(node.attributes.name, getType(node));
        break;
      case 'function':
        curName = node.attributes.name;
        curRtnType = 'v';
        curArgTypes = [];
        isInline = node.attributes.inline == 'true';
        // TODO: is variadic? will require a 'function generator'
        break;
      case 'args':
        break;
      case 'opaque':
        break;
      case 'informal_protocol':
        break;
      case 'function_alias':
        break;
      default:
        throw new Error('unkown tag: '+ node.name);
        break;
    }
  };
  parser.onclosetag = function (node) {
    switch (node) {
      case 'function':
        // Binded functions will be lazy-loaded. We simply define a getter that
        // does the creation magic the first time, and replaces the getter with
        // the binded function
        (function (curName, curRtnType, curArgTypes, isInline) {
          if (isInline && !fw.inline) throw new Error('declared inline but could not find inline dylib!');
          _global.__defineGetter__(curName, function () {
            // TODO: Handle 'variadic' arg functions (NSLog), will require
            //       a "function generator" to get a Function from the passed
            //       in args (and guess at the types that were passed in...)
            var f = core.Function(curName, types.map(curRtnType), curArgTypes.map(types.map), false, isInline ? fw.inline : fw.lib);
            delete _global[curName];
            // The unwrapper function unwraps passed in arguments,
            // and wraps up the result if necessary.
            function unwrapper () {
              var args = core.unwrapValues(arguments, curArgTypes)
                , rtn = f.apply(null, args)
              return core.wrapValue(rtn, curRtnType)
            }
            // attach the rtn and arg types to the result Function, nice in the REPL
            unwrapper.func = curName;
            unwrapper.rtn = curRtnType;
            unwrapper.args = curArgTypes;
            return _global[curName] = unwrapper;
          });
        })(curName, curRtnType, curArgTypes, isInline);
        curName = null;
        break;
    }
  };
  parser.onend = function () {
    gotEnd = true;
  };

  // Parse the contents of the file. This should happen synchronously.
  parser.write(contents).close();

  if (!gotEnd) {
    throw new Error('could not parse BridgeSupport files synchronously');
  }
}
module.exports = bridgesupport;
<commit_msg>For BridgeSupport <function>s, export if it was an inlined function, and the original function pointer.<commit_after>/**
 * This module takes care of loading the BridgeSupport XML files for a given
 * framework, and parsing the data into the given framework object.
 */

var fs = require('fs')
  , sax = require('sax')
  , path = require('path')
  , core = require('./core')
  , types = require('./types')
  , join = path.join
  , basename = path.basename
  , exists = path.existsSync
  , DY_SUFFIX = '.dylib'
  , BS_SUFFIX = '.bridgesupport'

/**
 * Architecture-specific function that returns the Obj-C type from one of
 * these BridgeSupport XML nodes.
 */
var getType;
if (process.arch == 'x64')
  getType = function (node) {
    var a = node.attributes;
    return a.type64 || a.type;
  }
else
  getType = function (node) {
    return node.attributes.type;
  }

/**
 * Attempts to retrieve the BridgeSupport files for the given framework.
 * It synchronously reads the contents of the bridgesupport files and parses
 * them in order to add the symbols that the Obj-C runtime functions cannot
 * determine.
 */
function bridgesupport (fw, _global) {

  var bridgeSupportDir = join(fw.basePath, 'Resources', 'BridgeSupport')
    , bridgeSupportXML = join(bridgeSupportDir, fw.name + BS_SUFFIX)
    , bridgeSupportDylib = join(bridgeSupportDir, fw.name + DY_SUFFIX)

  // If there's no BridgeSupport file, then just return the empty object...
  if (!exists(bridgeSupportXML)) {
    //console.warn('No BridgeSupport files found for framework "%s" at: %s', fw.name, bridgeSupportXML);
    return;
  }

  if (exists(bridgeSupportDylib)) {
    fw.inline = core.dlopen(bridgeSupportDylib);
  }

  var contents = fs.readFileSync(bridgeSupportXML, 'utf8')
    , parser = sax.parser(true)
    , gotEnd = false
    // For processing C functions
    , curName
    , curRtnType
    , curArgTypes
    , isInline

  parser.onerror = function (e) { throw e; }
  parser.onopentag = function (node) {
    //console.error(node);
    switch (node.name) {
      case 'depends_on':
        bridgesupport.import(node.attributes.path);
        break;
      case 'class':
        break;
      case 'method':
        break;
      case 'arg':
        if (curName) {
          // class methods also have args, we only want functions though
          curArgTypes.push(getType(node));
        }
        break;
      case 'retval':
        if (curName) {
          // class methods also have retvals, we only want functions though
          curRtnType = getType(node);
        }
        break;
      case 'signatures':
        // ignore
        break;
      case 'string_constant':
        _global[node.attributes.name] = node.attributes.value;
        break;
      case 'enum':
        _global[node.attributes.name] = parseInt(node.attributes.value);
        break;
      case 'struct':
        break;
      case 'field':
        //console.error(node);
        break;
      case 'cftype':
        break;
      case 'constant':
        (function (name, type) {
          _global.__defineGetter__(name, function () {
            var ptr = fw.lib.get(name);
            // TODO: I'm like 99% sure I need to deref the pointer before
            //       wrapping, but I haven't tested yet...
            delete _global[name];
            return _global[name] = core.wrapValue(ptr, type);
          });
        })(node.attributes.name, getType(node));
        break;
      case 'function':
        curName = node.attributes.name;
        curRtnType = 'v';
        curArgTypes = [];
        isInline = node.attributes.inline == 'true';
        // TODO: is variadic? will require a 'function generator'
        break;
      case 'args':
        break;
      case 'opaque':
        break;
      case 'informal_protocol':
        break;
      case 'function_alias':
        break;
      default:
        throw new Error('unkown tag: '+ node.name);
        break;
    }
  };
  parser.onclosetag = function (node) {
    switch (node) {
      case 'function':
        // Binded functions will be lazy-loaded. We simply define a getter that
        // does the creation magic the first time, and replaces the getter with
        // the binded function
        (function (curName, curRtnType, curArgTypes, isInline) {
          if (isInline && !fw.inline) throw new Error('declared inline but could not find inline dylib!');
          _global.__defineGetter__(curName, function () {
            // TODO: Handle 'variadic' arg functions (NSLog), will require
            //       a "function generator" to get a Function from the passed
            //       in args (and guess at the types that were passed in...)
            var f = core.Function(curName, types.map(curRtnType), curArgTypes.map(types.map), false, isInline ? fw.inline : fw.lib);
            delete _global[curName];
            // The unwrapper function unwraps passed in arguments,
            // and wraps up the result if necessary.
            function unwrapper () {
              var args = core.unwrapValues(arguments, curArgTypes)
                , rtn = f.apply(null, args)
              return core.wrapValue(rtn, curRtnType)
            }
            // attach the rtn and arg types to the result Function, nice in the REPL
            unwrapper.func = curName;
            unwrapper.rtn = curRtnType;
            unwrapper.args = curArgTypes;
            unwrapper.inline = isInline;
            unwrapper.pointer = f.pointer;
            return _global[curName] = unwrapper;
          });
        })(curName, curRtnType, curArgTypes, isInline);
        curName = null;
        break;
    }
  };
  parser.onend = function () {
    gotEnd = true;
  };

  // Parse the contents of the file. This should happen synchronously.
  parser.write(contents).close();

  if (!gotEnd) {
    throw new Error('could not parse BridgeSupport files synchronously');
  }
}
module.exports = bridgesupport;
<|endoftext|>