<commit_before>'use strict';

var projectState = angular.module( 'projectState' );

projectState.controller( 'ProjectStateController', function( $rootScope, $scope, $state, $stateParams, Project, $interval, $http, screenSize, $timeout )
{

	//helper method
	$scope.printAddress = function(it){
		if(it.address){
			return it.address
		} else {
			var loc_comps = [it.city, it.state, it.country]
			var res = []
			angular.forEach(loc_comps, function(value){
				if(value){
					res.push(value)
				}
			})
			return res.join(", ")
		}
	}

	$scope.pageLoaded = false

	$scope.stateParams = $state.params;

	// Save original index for modal 'close' button purposes
	$scope.$on( '$stateChangeSuccess', function( event, toState, toParams, fromState, fromParams )
	{
		if ( fromState.name === 'root.section-state.sorting-state' || fromParams.section === 'search' )
		{
			$rootScope.originalIndex = {
				section: fromParams.section,
				sortingType: fromParams.sortingType,
				q: fromParams.q,
				s: fromParams.s,
				e: fromParams.e,
				m: null
			}
			console.log( 'originalIndex:', $rootScope.originalIndex );
		}
	});

	$scope.mobile = screenSize.on( 'xs', function( match )
	{
		$scope.mobile = match;
	});

	// Zipped-up Morphosis team (project credits)
	$scope.showMorphTeam = false;

	// 'People' or 'Project' layout?
	switch( $scope.stateParams.section )
	{
		case 'search':
		case 'about':
			if( $scope.stateParams.m === "person" )
			{
				$http(
				{
					method: 'GET',
					url: 'https://morphosisapi.herokuapp.com/people/' + $scope.stateParams.projectId + '.json'
				} ).then( function( response )
				{
					$scope.activeItem = response.data;
				} );
			}
			else
			{
				Project.get( { id: $scope.stateParams.projectId } ).$promise.then( function( response )
				{

					$scope.activeItem = response.result;
				} );
			}
		break;

		default:
			$scope.throbberOn = true;
			Project.get( { id: $scope.stateParams.projectId } ).$promise.then( function( response )
			{
				$scope.activeItem = response.result;
				$scope.throbberOn = false;
			} );
		break;
	}

	$scope.stateName = 'section-state.project-state';

	console.log( 'ProjectStateController active!' );

	$scope.closeProject = function(  )
	{
		var originalIndex = $rootScope.originalIndex;
		if ( originalIndex )
		{
			$state.transitionTo( 'root.section-state.sorting-state', originalIndex, { reload: true, inherit: false, notify: true } );

			// Clear originalIndex
			$rootScope.originalIndex = null;
		}
		else
		{
			$state.go( '^' );
		}
	}

	// var isLeft;
	// var velocity;

	// $scope.startScroll = function( event )
	// {
	// 	var imageGalleryWrapper = document.getElementsByClassName( 'image-gallery-section-wrapper' )[ 0 ];

	// 	var imageWrapperX = imageGalleryWrapper.getBoundingClientRect(  ).left;
	// 	var imageWrapperMiddle = imageGalleryWrapper.offsetWidth / 2;
	// 	var mouseX = event.pageX;
	// 	var posX = mouseX - imageWrapperX;
	// 	var imageGallery = event.currentTarget.getElementsByClassName( 'image-gallery-section' )[ 0 ];

	// 	isLeft = posX < imageWrapperMiddle;

	// 	if ( isLeft )
	// 	{
	// 		velocity = 50 / -2
	// 	}
	// 	else
	// 	{
	// 		velocity = 50 / 2
	// 	}

	// 	$scope.scrollInterval = $interval( function(  )
	// 	{
	// 		imageGallery.scrollLeft += velocity;
	// 	}, 50 );
	// }

	// $scope.updateScroll = function( event )
	// {
	// 	$interval.cancel( $scope.scrollInterval );
	// 	$scope.startScroll( event );
	// }

	// $scope.stopScroll = function(  )
	// {
	// 	$interval.cancel( $scope.scrollInterval );
	// }

} );
<commit_msg>Fix project-page 'x' pagination issue<commit_after>'use strict';

var projectState = angular.module( 'projectState' );

projectState.controller( 'ProjectStateController', function( $rootScope, $scope, $state, $stateParams, Project, $interval, $http, screenSize, $timeout )
{

	//helper method
	$scope.printAddress = function(it){
		if(it.address){
			return it.address
		} else {
			var loc_comps = [it.city, it.state, it.country]
			var res = []
			angular.forEach(loc_comps, function(value){
				if(value){
					res.push(value)
				}
			})
			return res.join(", ")
		}
	}

	$scope.pageLoaded = false

	$scope.stateParams = $state.params;

	// Save original index for modal 'close' button purposes
	$scope.$on( '$stateChangeSuccess', function( event, toState, toParams, fromState, fromParams )
	{
		if ( fromState.name === 'root.section-state.sorting-state' || fromParams.section === 'search' )
		{
			$rootScope.originalIndex = {
				section: fromParams.section,
				sortingType: fromParams.sortingType,
				q: fromParams.q,
				s: fromParams.s,
				e: fromParams.e,
				p: fromParams.p,
				m: null
			}
			console.log( 'originalIndex:', $rootScope.originalIndex );
		}
	});

	$scope.mobile = screenSize.on( 'xs', function( match )
	{
		$scope.mobile = match;
	});

	// Zipped-up Morphosis team (project credits)
	$scope.showMorphTeam = false;

	// 'People' or 'Project' layout?
	switch( $scope.stateParams.section )
	{
		case 'search':
		case 'about':
			if( $scope.stateParams.m === "person" )
			{
				$http(
				{
					method: 'GET',
					url: 'https://morphosisapi.herokuapp.com/people/' + $scope.stateParams.projectId + '.json'
				} ).then( function( response )
				{
					$scope.activeItem = response.data;
				} );
			}
			else
			{
				Project.get( { id: $scope.stateParams.projectId } ).$promise.then( function( response )
				{

					$scope.activeItem = response.result;
				} );
			}
		break;

		default:
			$scope.throbberOn = true;
			Project.get( { id: $scope.stateParams.projectId } ).$promise.then( function( response )
			{
				$scope.activeItem = response.result;
				$scope.throbberOn = false;
			} );
		break;
	}

	$scope.stateName = 'section-state.project-state';

	console.log( 'ProjectStateController active!' );

	$scope.closeProject = function(  )
	{
		var originalIndex = $rootScope.originalIndex;
		if ( originalIndex )
		{
			$state.transitionTo( 'root.section-state.sorting-state', originalIndex, { reload: true, inherit: false, notify: true } );

			// Clear originalIndex
			$rootScope.originalIndex = null;
		}
		else
		{
			$state.go( '^' );
		}
	}

	// var isLeft;
	// var velocity;

	// $scope.startScroll = function( event )
	// {
	// 	var imageGalleryWrapper = document.getElementsByClassName( 'image-gallery-section-wrapper' )[ 0 ];

	// 	var imageWrapperX = imageGalleryWrapper.getBoundingClientRect(  ).left;
	// 	var imageWrapperMiddle = imageGalleryWrapper.offsetWidth / 2;
	// 	var mouseX = event.pageX;
	// 	var posX = mouseX - imageWrapperX;
	// 	var imageGallery = event.currentTarget.getElementsByClassName( 'image-gallery-section' )[ 0 ];

	// 	isLeft = posX < imageWrapperMiddle;

	// 	if ( isLeft )
	// 	{
	// 		velocity = 50 / -2
	// 	}
	// 	else
	// 	{
	// 		velocity = 50 / 2
	// 	}

	// 	$scope.scrollInterval = $interval( function(  )
	// 	{
	// 		imageGallery.scrollLeft += velocity;
	// 	}, 50 );
	// }

	// $scope.updateScroll = function( event )
	// {
	// 	$interval.cancel( $scope.scrollInterval );
	// 	$scope.startScroll( event );
	// }

	// $scope.stopScroll = function(  )
	// {
	// 	$interval.cancel( $scope.scrollInterval );
	// }

} );
<|endoftext|>


<commit_before>
$(document).ready(function(){
        $("#add_row").click(function(){
                $("tbody").append(
                        "
remove
");
                $.uiTableEdit($("table"), {find: 'tbody > tr > td.editable', dataVerify: check_cell});
        });
        $("#save_table").click(send_table);
        $("#add_to_bl").click(add_to_blacklist);
        $("#save_settings").click(save_settings);
        $.getJSON("/disco/ctrl/load_config_table", new_table);
        $.getJSON("/disco/ctrl/get_blacklist", update_blacklist);
        $.getJSON("/disco/ctrl/get_settings", update_settings);
        $('tbody').click(function(event) {	// event delegation - to hook event handlers for dynamic contents
                var $real_target = $(event.target);
                if ($real_target.is('a.remove')) {
                    $real_target.parents("tr").remove();
                }
        });
});

function update_blacklist(data){
        $("#blacklist").html($.map(data, function(item, i){
                return $.create("div", {"class": "bnode"}, [item]);
        }));
        $(".bnode").click(whitelist);
}

function whitelist(){
        post_req("/disco/ctrl/whitelist",
                JSON.stringify($(this).text()),
                function(){
                        $.getJSON("/disco/ctrl/get_blacklist",
                                update_blacklist);
        });
}

function save_settings(){
        var s = {}
        $.each($(".setting"), function(){
                s[$(this).attr("id")] = $(this).val();
        });
        post_req("/disco/ctrl/save_settings",
                JSON.stringify(s),
                function(){
                        $.getJSON("/disco/ctrl/get_settings",
                                update_settings);
        });
}

function update_settings(data){
        for (var k in data){
                $("#" + k).val(data[k]);
        }
}

function add_to_blacklist(){
        post_req("/disco/ctrl/blacklist",
                JSON.stringify($("#jobname").val()),
                function(){
                        $.getJSON("/disco/ctrl/get_blacklist",
                                update_blacklist);
        });
}

function send_table(){
        var table = $("tbody > tr").map(function(){
                var arr = $.makeArray($(this).children().map(function(){
                          return jQuery.trim($(this).text());}));
                arr.shift();  // throw away the first node - 'remove'
                return JSON.stringify(arr);
        });
        jsonTable = ("[" + $.makeArray(table).join(",") + "]");
        post_req("/disco/ctrl/save_config_table", jsonTable);
}

function check_cell(val, orig, ev){
        $("tr > td:empty").parent().remove();
}

function new_table(data){
        $("tbody").html($.map(data, function(item, i){
                return $.create("tr", {}, $.map(item, function(item2, i){
                        if (i % 2 == 0)
                                return [$.create("td", {}, [$.create("a", {'class':'remove','href':'#'}, ["remove"])]),
                                        $.create("td", {'class':'editable'}, [item2])];
			else
                                return $.create("td", {'class':'editable'}, [item2]);
                }));
        }));
        $.uiTableEdit($("table"), {find: 'tbody > tr > td.editable', dataVerify: check_cell});

}

<commit_msg>Fix for sending invalid configuration data.<commit_after>
$(document).ready(function(){
        $("#add_row").click(function(){
                $("tbody").append(
                        "
remove
");
                $.uiTableEdit($("table"), {find: 'tbody > tr > td.editable', dataVerify: check_cell});
        });
        $("#save_table").click(send_table);
        $("#add_to_bl").click(add_to_blacklist);
        $("#save_settings").click(save_settings);
        $.getJSON("/disco/ctrl/load_config_table", new_table);
        $.getJSON("/disco/ctrl/get_blacklist", update_blacklist);
        $.getJSON("/disco/ctrl/get_settings", update_settings);
        $('tbody').click(function(event) {	// event delegation - to hook event handlers for dynamic contents
                var $real_target = $(event.target);
                if ($real_target.is('a.remove')) {
                    $real_target.parents("tr").remove();
                }
        });
});

function update_blacklist(data){
        $("#blacklist").html($.map(data, function(item, i){
                return $.create("div", {"class": "bnode"}, [item]);
        }));
        $(".bnode").click(whitelist);
}

function whitelist(){
        post_req("/disco/ctrl/whitelist",
                JSON.stringify($(this).text()),
                function(){
                        $.getJSON("/disco/ctrl/get_blacklist",
                                update_blacklist);
        });
}

function save_settings(){
        var s = {}
        $.each($(".setting"), function(){
                s[$(this).attr("id")] = $(this).val();
        });
        post_req("/disco/ctrl/save_settings",
                JSON.stringify(s),
                function(){
                        $.getJSON("/disco/ctrl/get_settings",
                                update_settings);
        });
}

function update_settings(data){
        for (var k in data){
                $("#" + k).val(data[k]);
        }
}

function add_to_blacklist(){
        post_req("/disco/ctrl/blacklist",
                JSON.stringify($("#jobname").val()),
                function(){
                        $.getJSON("/disco/ctrl/get_blacklist",
                                update_blacklist);
        });
}

function send_table(){
        var table = $("tbody > tr").map(function(){
                var arr = $.makeArray($(this).children().map(function(){
                        return jQuery.trim($(this).text() || $(this).find('input').val());}));
                arr.shift();  // throw away the first node - 'remove'
                return JSON.stringify(arr);
        });
        jsonTable = ("[" + $.makeArray(table).join(",") + "]");
        post_req("/disco/ctrl/save_config_table", jsonTable);
}

function check_cell(val, orig, ev){
        $("tr > td:empty").parent().remove();
}

function new_table(data){
        $("tbody").html($.map(data, function(item, i){
                return $.create("tr", {}, $.map(item, function(item2, i){
                        if (i % 2 == 0)
                                return [$.create("td", {}, [$.create("a", {'class':'remove','href':'#'}, ["remove"])]),
                                        $.create("td", {'class':'editable'}, [item2])];
			else
                                return $.create("td", {'class':'editable'}, [item2]);
                }));
        }));
        $.uiTableEdit($("table"), {find: 'tbody > tr > td.editable', dataVerify: check_cell});

}

<|endoftext|>


<commit_before>// @flow

import * as React from "react";
import * as Immutable from "immutable";

import {
  state as stateModule,
  selectors,
  actions,
  TitleBar,
  NotebookApp,
  NotebookMenu,
  NewNotebookNavigation
} from "@nteract/core";

// TODO: Make a proper epic
import { contents } from "rx-jupyter";
const urljoin = require("url-join");
import { first, map, mergeMap } from "rxjs/operators";

import { dirname } from "path";

import { default as Directory } from "./directory";
import { default as File } from "./file";

type ContentRef = stateModule.ContentRef;

import { connect } from "react-redux";

type ContentsProps = {
  contentType: "dummy" | "notebook" | "directory" | "file",
  contentRef: ContentRef,
  filepath: string,
  basePath: string,
  serverConfig: *
};

const mapStateToProps = (
  state: stateModule.AppState,
  ownProps: *
): ContentsProps => {
  const contentRef = selectors.currentContentRef(state);
  const host = state.app.host;
  if (host.type !== "jupyter") {
    throw new Error("this component only works with jupyter apps");
  }
  const serverConfig = selectors.serverConfig(host);

  if (!contentRef) {
    throw new Error("cant display without a contentRef");
  }

  const content = selectors.content(state, { contentRef });
  if (!content) {
    throw new Error("need content to view content, check your contentRefs");
  }

  return {
    contentType: content.type,
    contentRef,
    filepath: content.filepath,
    basePath: host.basePath,
    serverConfig
  };
};

const Container = ({ children }) => (

    {children}

);

class Contents extends React.Component<ContentsProps, null> {
  constructor(props) {
    super(props);
    (this: any).openNotebook = this.openNotebook.bind(this);
  }

  openNotebook(ks: stateModule.KernelspecRecord | stateModule.KernelspecProps) {
    // Our base directory is the literal directory we're in otherwise it's relative
    // to the file being viewed.
    const baseDir =
      this.props.contentType === "directory"
        ? this.props.filepath
        : dirname(this.props.filepath);

    const serverConfig = this.props.serverConfig;

    // The notebook they get to start with
    const notebook = {
      cells: [
        {
          cell_type: "code",
          execution_count: null,
          metadata: {},
          outputs: [],
          source: []
        }
      ],
      metadata: {
        kernelspec: {
          display_name: ks.displayName,
          language: ks.language,
          name: ks.name
        }
      },
      nbformat: 4,
      nbformat_minor: 2
    };

    // NOTE: For the sake of expediency, all the logic to launch a new is
    //       happening here instead of an epic
    contents
      // Create UntitledXYZ.ipynb by letting the server do it
      .create(this.props.serverConfig, baseDir, {
        type: "notebook"
        // NOTE: The contents API appears to ignore the content field for new
        // notebook creation.
        //
        // It would be nice if it could take it. Instead we'll create a new
        // notebook for the user and redirect them after we've put in the
        // content we want.
        //
        // Amusingly, this could be used for more general templates to, as
        // well as introduction notebooks.
      })
      .pipe(
        // We only expect one response, it's ajax and we want this subscription
        // to finish so we don't have to unsubscribe
        first(),
        mergeMap(({ response, status }) => {
          const filepath = response.path;

          // Save our initial notebook document
          return contents.save(this.props.serverConfig, filepath, {
            type: "notebook",
            content: notebook
          });
        }),
        first(),
        map(({ response, status }) => {
          const url = urljoin(
            // User path
            this.props.basePath,
            // nteract edit path
            "/nteract/edit",
            // Actual file
            response.path
          );
          // Always open new notebooks in new windows
          window.open(url, "_blank");
        })
      )
      .subscribe();
  }

  render() {
    switch (this.props.contentType) {
      case "notebook":
        return (
          <React.Fragment>
            <TitleBar />
            <NotebookMenu />
            <NotebookApp contentRef={this.props.contentRef} />
          </React.Fragment>
        );
      case "file":
        return (
          <React.Fragment>
            <TitleBar />
            <Container>
              <File contentRef={this.props.contentRef} />
            </Container>
          </React.Fragment>
        );
      case "dummy":
        return (
          <React.Fragment>
            <TitleBar />
          </React.Fragment>
        );
      case "directory":
        return (
          <React.Fragment>
            <TitleBar />
            <NewNotebookNavigation onClick={this.openNotebook} />
            <Directory contentRef={this.props.contentRef} />
          </React.Fragment>
        );
      default:
        return (

{`content type ${this.props.contentType} not implemented`}

        );
    }
  }
}

export default connect(mapStateToProps)(Contents);
<commit_msg>launch a session for the user while we're at it<commit_after>// @flow

import * as React from "react";
import * as Immutable from "immutable";

import {
  state as stateModule,
  selectors,
  actions,
  TitleBar,
  NotebookApp,
  NotebookMenu,
  NewNotebookNavigation
} from "@nteract/core";

// TODO: Make a proper epic
import { contents, sessions } from "rx-jupyter";
const urljoin = require("url-join");
import { first, map, mergeMap } from "rxjs/operators";
import { forkJoin } from "rxjs/observable/forkJoin";

import { dirname } from "path";

import { default as Directory } from "./directory";
import { default as File } from "./file";

type ContentRef = stateModule.ContentRef;

import { connect } from "react-redux";

type ContentsProps = {
  contentType: "dummy" | "notebook" | "directory" | "file",
  contentRef: ContentRef,
  filepath: string,
  basePath: string,
  serverConfig: *
};

const mapStateToProps = (
  state: stateModule.AppState,
  ownProps: *
): ContentsProps => {
  const contentRef = selectors.currentContentRef(state);
  const host = state.app.host;
  if (host.type !== "jupyter") {
    throw new Error("this component only works with jupyter apps");
  }
  const serverConfig = selectors.serverConfig(host);

  if (!contentRef) {
    throw new Error("cant display without a contentRef");
  }

  const content = selectors.content(state, { contentRef });
  if (!content) {
    throw new Error("need content to view content, check your contentRefs");
  }

  return {
    contentType: content.type,
    contentRef,
    filepath: content.filepath,
    basePath: host.basePath,
    serverConfig
  };
};

const Container = ({ children }) => (

    {children}

);

class Contents extends React.Component<ContentsProps, null> {
  constructor(props) {
    super(props);
    (this: any).openNotebook = this.openNotebook.bind(this);
  }

  openNotebook(ks: stateModule.KernelspecRecord | stateModule.KernelspecProps) {
    // Our base directory is the literal directory we're in otherwise it's relative
    // to the file being viewed.
    const baseDir =
      this.props.contentType === "directory"
        ? this.props.filepath
        : dirname(this.props.filepath);

    const serverConfig = this.props.serverConfig;

    // The notebook they get to start with
    const notebook = {
      cells: [
        {
          cell_type: "code",
          execution_count: null,
          metadata: {},
          outputs: [],
          source: []
        }
      ],
      metadata: {
        kernelspec: {
          display_name: ks.displayName,
          language: ks.language,
          name: ks.name
        }
      },
      nbformat: 4,
      nbformat_minor: 2
    };

    // NOTE: For the sake of expediency, all the logic to launch a new is
    //       happening here instead of an epic
    contents
      // Create UntitledXYZ.ipynb by letting the server do it
      .create(this.props.serverConfig, baseDir, {
        type: "notebook"
        // NOTE: The contents API appears to ignore the content field for new
        // notebook creation.
        //
        // It would be nice if it could take it. Instead we'll create a new
        // notebook for the user and redirect them after we've put in the
        // content we want.
        //
        // Amusingly, this could be used for more general templates to, as
        // well as introduction notebooks.
      })
      .pipe(
        // We only expect one response, it's ajax and we want this subscription
        // to finish so we don't have to unsubscribe
        first(),
        mergeMap(({ response, status }) => {
          const filepath = response.path;

          const sessionPayload = {
            kernel: {
              id: null,
              name: ks.name
            },
            name: "",
            path: filepath,
            type: "notebook"
          };

          return forkJoin(
            // Get their kernel started up
            sessions.create(this.props.serverConfig, sessionPayload),
            // Save our initial notebook document
            contents.save(this.props.serverConfig, filepath, {
              type: "notebook",
              content: notebook
            })
          );
        }),
        first(),
        map(([session, content]) => {
          const { response, status } = content;

          const url = urljoin(
            // User path
            this.props.basePath,
            // nteract edit path
            "/nteract/edit",
            // Actual file
            response.path
          );

          // Always open new notebooks in new windows
          window.open(url, "_blank");
        })
      )
      .subscribe();
  }

  render() {
    switch (this.props.contentType) {
      case "notebook":
        return (
          <React.Fragment>
            <TitleBar />
            <NotebookMenu />
            <NotebookApp contentRef={this.props.contentRef} />
          </React.Fragment>
        );
      case "file":
        return (
          <React.Fragment>
            <TitleBar />
            <Container>
              <File contentRef={this.props.contentRef} />
            </Container>
          </React.Fragment>
        );
      case "dummy":
        return (
          <React.Fragment>
            <TitleBar />
          </React.Fragment>
        );
      case "directory":
        return (
          <React.Fragment>
            <TitleBar />
            <NewNotebookNavigation onClick={this.openNotebook} />
            <Directory contentRef={this.props.contentRef} />
          </React.Fragment>
        );
      default:
        return (

{`content type ${this.props.contentType} not implemented`}

        );
    }
  }
}

export default connect(mapStateToProps)(Contents);
<|endoftext|>


<commit_before>/**
 * Hopefully plays TicTacToe
 *
 * Written By: Jay Harris
 * Date Written: 29/07/2015
 */
var games = [];

/**
 * Removes a game
*/
function removeGame(game) {
    for (var i = 0; i < games.length; ++i) {
        if (games[i] === game) {
            games.splice(i, 1);
            return;
        }
    }
}

/**
 * Finds a game given a player and a thread id.
 * Returns undefined if no games are found
*/
function findGame(thread, player) {
    for (var i in games) {
        var game = games[i];

        //If the game has a different thread, exit
        if (game.thread !== thread) {
            continue;
        }

        //If there is already a game with this player, return it
        if (game.noughts === player || game.crosses === player) {
            return game;
        }
    }
}

/**
 * Places a piece in a certain game
*/
function place(game, player, move) {
    //Work out what piece we are using.
    var piece = "X",
        board = game.board;

    if (player === game.noughts) {
        piece = "O";
    }

    //It's not even your turn
    if (player !== game.turn) {
        return "Invalid Move! (it's not your turn " + player + ")";
    }

    //You tried to put it on top of an existing piece
    if (board[move[0]][move[1]] !== '-') {
        return "Invalid Move! (there's already something there " + player + ")";
    }

    //Make your move
    board[move[0]][move[1]] = piece;

    //Swap the current player
    if (player === game.noughts) {
        game.turn = game.crosses;
    } else {
        game.turn = game.noughts;
    }
}

/**
 * Creates a new TicTacToe game
*/
function createGame(player1, player2, thread) {
    var board = [['-','-','-'],['-','-','-'],['-','-','-']],
        noughts = player1,
        crosses = player2,
        game = {
            thread: thread,
            board: board,
            noughts: player1,
            crosses: player2,
            turn: crosses
        };

    return game;
}

/**
*prints the game to the chat
*/
function printGame(game) {
    var output = "",
        board = game.board;

    for (var i = 0; i < board.length; ++i) {
        for (var j = 0; j < board[i].length; ++j) {
            if (j > 0) {
                output += "|";
            }

            output += board[i][j];
        }

        if (i < 2) {
            output += "\n";
        }
    }

    return output;
}

/**
* Checks to see if a player has won. Returns the winner or undefined
*/
function checkWin(game, player) {
    var board = game.board,
        piece = player === game.nought ? "O" : "X";

    //Check rows
    for (var i in board) {
        var row = board[i];

        if (row[0] === piece && row[1] === piece && row[2] === piece) {
            return player;
        }
    }

    //Check columns
    for (var i = 0; i < 3; ++i) {
        if (board[0][i] === piece && board[1][i] === piece && board[2][i] === piece) {
            return player;
        }
    }

    //Check Diagonal
    if (board[0][0] === piece && board[1][1] === piece && board[2][2] === piece) {
        return player;
    }

    //Check Anti-Diagonal
    if (board[0][2] === piece && board[1][1] === piece && board[2][0] === piece) {
        return player;
    }
}

exports.match = function(text) {
    return text.startsWith(this.platform.commandPrefix + 'tictactoe')
        || text.startsWith(this.platform.commandPrefix + 'move')
        || text.startsWith(this.platform.commandPrefix + 'surrender');
};

exports.help = function() {
    return this.platform.commandPrefix + "tictactoe <opponent's full name> : starts a new game against the specified opponent\n" +
           this.platform.commandPrefix + "move <row><column> : places a piece at the specified row and column, if you are in a game\n" +
           this.platform.commandPrefix + "surrender : gives up on a game";
};

exports.run = function(api, event) {
    "use strict"
    var command = event.body,
        commandPrefix = this.platform ? this.platform.commandPrefix : "/";

    //If we are creating a new game
    if (command.startsWith(commandPrefix + "tictactoe")) {
        var split = command.split('"');

        //There are way to many quotes for this to end well
        if (split.length !== 3 && split.length !== 5)  {
            api.sendMessage('And just what do you expect me to do with that?', event.thread_id);
            return;
        }

        var player1 = event.sender_name.trim(),
            player2 = split[1],
            game = createGame(player1, player2, event.thread_id);

        if (findGame(event.thread_id, player1)) {
            api.sendMessage(player1 + " is already in a game on this thread!", event.thread_id);
            return;
        }

        if (findGame(event.thread_id, player2)) {
            api.sendMessage(player2 + " is already in a game on this thread!", event.thread_id);
            return;
        }

        games[games.length] = game;

        var output = printGame(game);
        api.sendMessage(output, event.thread_id);
    }

    //If we are trying to make a move
    if (command.startsWith(commandPrefix + "move")) {
        var offset = commandPrefix.length + "move".length + 1,
            move = command.substr(offset),
            game = findGame(event.thread_id, event.sender_name.trim());

        if (!game) {
            api.sendMessage("You're not even playing " + event.sender_name.trim(), event.thread_id);
            return;
        }

        if (move.length !== 2) {
            api.sendMessage("Um. Is that even a coordinate?");
        }

        move = {
            0: move.substr(0, 1),
            1: move.substr(1, 1)
        };

        var output = place(game, event.sender_name.trim(), move);
        if (output) {
            api.sendMessage(output, event.thread_id);
            return;
        }

        output = printGame(game);
        api.sendMessage(output, event.thread_id);

        output = checkWin(game, event.sender_name.trim());
        if (output) {
            api.sendMessage("Game Over! " + output + " wins!", event.thread_id);
            removeGame(game);
        } else {
            api.sendMessage(game.turn + "'s turn!", event.thread_id);
        }
    }

    //If we are surrendering
    if (command.startsWith(commandPrefix + "surrender")) {
        var game = findGame(event.thread_id, event.sender_name.trim());

        if (!game) {
            api.sendMessage("You're not even in a game! Why are you surrendering?");
            return;
        }

        removeGame(game);

        api.sendMessage(event.sender_name.trim() + " surrenders! " + (event.sender_name.trim() !== game.noughts ? game.noughts : game.crosses) + " wins!");
    }
};

exports.run({sendMessage: function (message) { console.log(message);}}, {body: '/tictactoe "A"', thread_id: 1, sender_name: "B"});
<commit_msg>Removes testing code, updates coordinate system and improves error handling<commit_after>/**
 * Hopefully plays TicTacToe
 *
 * Written By: Jay Harris
 * Date Written: 29/07/2015
 */
var games = [];

/**
 * Maps a coordinate to something a programmer would use
*/
function mapToCoord(coord) {
    var rows = {"A":0, "B":1, "C":2},
        columns = {"1":0, "2":1, "3":2};

    if (rows[coord] !== undefined){
        return rows[coord];
    }
    else if (columns[coord] !== undefined){
        return columns[coord];
    }
}

/**
 * Removes a game
*/
function removeGame(game) {
    for (var i = 0; i < games.length; ++i) {
        if (games[i] === game) {
            games.splice(i, 1);
            return;
        }
    }
}

/**
 * Finds a game given a player and a thread id.
 * Returns undefined if no games are found
*/
function findGame(thread, player) {
    for (var i in games) {
        var game = games[i];

        //If the game has a different thread, exit
        if (game.thread !== thread) {
            continue;
        }

        //If there is already a game with this player, return it
        if (game.noughts === player || game.crosses === player) {
            return game;
        }
    }
}

/**
 * Places a piece in a certain game
*/
function place(game, player, move) {
    //Work out what piece we are using.
    var piece = "X",
        board = game.board;

    if (player === game.noughts) {
        piece = "O";
    }

    //It's not even your turn
    if (player !== game.turn) {
        return "Invalid Move! (it's not your turn " + player + ")";
    }

    //You tried to put it on top of an existing piece
    if (board[move[0]][move[1]] !== '-') {
        return "Invalid Move! (there's already something there " + player + ")";
    }

    //Make your move
    board[move[0]][move[1]] = piece;

    //Swap the current player
    if (player === game.noughts) {
        game.turn = game.crosses;
    } else {
        game.turn = game.noughts;
    }
}

/**
 * Creates a new TicTacToe game
*/
function createGame(player1, player2, thread) {
    var board = [['-','-','-'],['-','-','-'],['-','-','-']],
        noughts = player1,
        crosses = player2,
        game = {
            thread: thread,
            board: board,
            noughts: player1,
            crosses: player2,
            turn: crosses
        };

    return game;
}

/**
*prints the game to the chat
*/
function printGame(game) {
    var output = "",
        board = game.board,
        rows = ["A", "B", "C"];

    output += "  1 2 3\n";

    for (var i = 0; i < board.length; ++i) {
        for (var j = 0; j < board[i].length; ++j) {
            if (j === 0) {
                output += rows[i] + " ";
            }
            else {
                output += "|";
            }

            output += board[i][j];
        }

        if (i < 2) {
            output += "\n";
        }
    }

    return output;
}

/**
* Checks to see if a player has won. Returns the winner or undefined
*/
function checkWin(game, player) {
    var board = game.board,
        piece = player === game.nought ? "O" : "X";

    //Check rows
    for (var i in board) {
        var row = board[i];

        if (row[0] === piece && row[1] === piece && row[2] === piece) {
            return player;
        }
    }

    //Check columns
    for (var i = 0; i < 3; ++i) {
        if (board[0][i] === piece && board[1][i] === piece && board[2][i] === piece) {
            return player;
        }
    }

    //Check Diagonal
    if (board[0][0] === piece && board[1][1] === piece && board[2][2] === piece) {
        return player;
    }

    //Check Anti-Diagonal
    if (board[0][2] === piece && board[1][1] === piece && board[2][0] === piece) {
        return player;
    }
}

exports.match = function(text) {
    return text.startsWith(this.platform.commandPrefix + 'tictactoe')
        || text.startsWith(this.platform.commandPrefix + 'move')
        || text.startsWith(this.platform.commandPrefix + 'surrender');
};

exports.help = function() {
    return this.platform.commandPrefix + "tictactoe <opponent's full name> : starts a new game against the specified opponent\n" +
           this.platform.commandPrefix + "move <row><column> : places a piece at the specified row and column, if you are in a game\n" +
           this.platform.commandPrefix + "surrender : gives up on a game";
};

exports.run = function(api, event) {
    "use strict"
    var command = event.body,
        commandPrefix = this.platform ? this.platform.commandPrefix : "/";

    //If we are creating a new game
    if (command.startsWith(commandPrefix + "tictactoe")) {
        var split = command.split('"');

        //There are way to many quotes for this to end well
        if (split.length !== 3 && split.length !== 5)  {
            api.sendMessage('And just what do you expect me to do with that?', event.thread_id);
            return;
        }

        var player1 = event.sender_name.trim(),
            player2 = split[1],
            game = createGame(player1, player2, event.thread_id);

        if (findGame(event.thread_id, player1)) {
            api.sendMessage(player1 + " is already in a game on this thread!", event.thread_id);
            return;
        }

        if (findGame(event.thread_id, player2)) {
            api.sendMessage(player2 + " is already in a game on this thread!", event.thread_id);
            return;
        }

        games[games.length] = game;

        var output = printGame(game);
        api.sendMessage(output, event.thread_id);
    }

    //If we are trying to make a move
    if (command.startsWith(commandPrefix + "move")) {
        var offset = commandPrefix.length + "move".length + 1,
            move = command.substr(offset),
            game = findGame(event.thread_id, event.sender_name.trim());

        if (!game) {
            api.sendMessage("You're not even playing " + event.sender_name.trim(), event.thread_id);
            return;
        }

        if (move.length !== 2) {
            api.sendMessage("Um. Is that even a coordinate?");
        }

        console.log(move);
        var y = mapToCoord(move.substr(0, 1)),
            x = mapToCoord(move.substr(1, 1));

        move = {
            0: y,
            1: x
        };

        if (move[0] === undefined || move[1] === undefined) {
            api.sendMessage("Do at least TRY and pick a coordinate on the board", event.thread_id);
            return;
        }

        var output = place(game, event.sender_name.trim(), move);
        if (output) {
            api.sendMessage(output, event.thread_id);
            return;
        }

        output = printGame(game);
        api.sendMessage(output, event.thread_id);

        output = checkWin(game, event.sender_name.trim());
        if (output) {
            api.sendMessage("Game Over! " + output + " wins!", event.thread_id);
            removeGame(game);
        } else {
            api.sendMessage(game.turn + "'s turn!", event.thread_id);
        }
    }

    //If we are surrendering
    if (command.startsWith(commandPrefix + "surrender")) {
        var game = findGame(event.thread_id, event.sender_name.trim());

        if (!game) {
            api.sendMessage("You're not even in a game! Why are you surrendering?");
            return;
        }

        removeGame(game);

        api.sendMessage(event.sender_name.trim() + " surrenders! " + (event.sender_name.trim() !== game.noughts ? game.noughts : game.crosses) + " wins!");
    }
};<|endoftext|>


<commit_before>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var __ = require('underscore');

var utils = require('../util/utils');
var interaction = require('../util/interaction');

exports.init = function (cli) {

  var log = cli.output;
  var site = cli.category('site');
  var siteConnectionStrings = site.category('connectionstring')
    .description('Commands to manage your Web Site connection strings');

  siteConnectionStrings.command('list [name]')
    .usage('[options] [name]')
    .description('Show your site application settings')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      site.lookupSiteNameAndWebSpace(context, _);

      var siteConfigurations = site.doSiteConfigGet(context, _);
      siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);
      interaction.formatOutput(cli, siteConfigurations.ConnectionStrings.ConnStringInfo, function (data) {
        if (data.length > 0) {
          log.table(data, function (row, item) {
            row.cell('Name', item.Name);
            row.cell('Type', item.Type);
          });
        } else {
          log.info('No connection strings defined yet.');
        }
      });
    });

  siteConnectionStrings.command('add [connectionname] [value] [type] [name]')
    .usage('[options] <connectionname> <value> <type> [name]')
    .description('Adds a connection string to your site')
    .option('-c, --connectionname <connectionname>', 'the connection string name')
    .option('-v, --value <value>', 'the connection string value')
    .option('-t, --type <type>', 'the connection string type')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (connectionname, value, type, name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      var params = utils.normalizeParameters({
        connectionname: [connectionname, options.connectionname],
        value: [value, options.value],
        type: [type, options.type]
      });

      if (params.err) { throw params.err; }

      connectionname = interaction.promptIfNotGiven(cli, 'Connection String Name: ', params.values.connectionname, _);
      value = interaction.promptIfNotGiven(cli, 'Connection String Value: ', params.values.value, _);
      type = interaction.chooseIfNotGiven(cli, 'Connection String Type: ', 'Getting types', params.values.type,
          function (cb) {
            cb(null, [ 'SQLAzure', 'SQLServer', 'Custom', 'MySQL' ]);
          }, _);

      if (type !== 'SQLAzure' && type !== 'SQLServer' && type !== 'Custom' && type !== 'MySQL') {
        throw new Error('Invalid connection string type. Valid types are: SQLAzure, SQLServer, Custom or MySQL');
      }

      site.lookupSiteNameAndWebSpace(context, _);
      var siteConfigurations = site.doSiteConfigGet(context, _);
      siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);
      siteConfigurations.ConnectionStrings.ConnStringInfo.push({
        ConnectionString: value,
        Name: connectionname,
        Type: type
      });

      site.doSiteConfigPUT(siteConfigurations, context, _);
    });

  siteConnectionStrings.command('delete <connectionname> [name]')
    .usage('[options] <connectionname> [name]')
    .description('Deletes a connection string for your site')
    .option('-c, --connectionname <connectionname>', 'the connection string name')
    .option('-q, --quiet', 'quiet mode, do not ask for delete confirmation')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (connectionname, name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      var params = utils.normalizeParameters({
        connectionname: [connectionname, options.connectionname]
      });

      if (params.err) { throw params.err; }

      connectionname = interaction.promptIfNotGiven(cli, 'Connection String Name: ', params.values.connectionname, _);

      if (!options.quiet && !interaction.confirm(cli, util.format('Delete %s connection string? (y/n) ', connectionname), _)) {
        return;
      }

      site.lookupSiteNameAndWebSpace(context, _);
      var siteConfigurations = site.doSiteConfigGet(context, _);

      var found = false;
      if (siteConfigurations.ConnectionStrings && siteConfigurations.ConnectionStrings.ConnStringInfo) {
        siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);

        for (var i = 0; i < siteConfigurations.ConnectionStrings.ConnStringInfo.length; i++) {
          if (utils.ignoreCaseEquals(siteConfigurations.ConnectionStrings.ConnStringInfo[i].Name, connectionname)) {
            siteConfigurations.ConnectionStrings.ConnStringInfo.splice(i, 1);
            found = true;
            i--;
          }
        }

        if (found) {
          if (siteConfigurations.ConnectionStrings.ConnStringInfo.length === 0) {
            siteConfigurations.ConnectionStrings = { };
          }

          site.doSiteConfigPUT(siteConfigurations, context, _);
        }
      }

      if (!found) {
        throw new Error(util.format('Connection string with name "%s" does not exist.', connectionname));
      }
    });

  siteConnectionStrings.command('show <connectionname> [name]')
    .usage('[options] <connectionname> [name]')
    .description('Shows a connection string for your site')
    .option('-c, --connectionname <connectionname>', 'the connection string name')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (connectionname, name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      var params = utils.normalizeParameters({
        connectionname: [connectionname, options.connectionname]
      });

      if (params.err) { throw params.err; }

      connectionname = interaction.promptIfNotGiven(cli, 'Connection String Name: ', params.values.connectionname, _);

      site.lookupSiteNameAndWebSpace(context, _);
      var siteConfigurations = site.doSiteConfigGet(context, _);
      siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);
      var match = siteConfigurations.ConnectionStrings.ConnStringInfo.filter(function (c) {
        return utils.ignoreCaseEquals(c.Name, connectionname);
      })[0];

      if (match) {
        interaction.formatOutput(cli, match, function (data) {
          interaction.logEachData(cli, 'Connection String', data);
        });
      } else {
        throw new Error(util.format('Connection string with name "%s" does not exist.', connectionname));
      }
    });

  function getConnectionStrings(connectionStrings) {
    if (!connectionStrings) {
      connectionStrings = {};
    }

    if (!connectionStrings.ConnStringInfo) {
      connectionStrings.ConnStringInfo = [ ];
    } else if (!__.isArray(connectionStrings.ConnStringInfo)) {
      connectionStrings.ConnStringInfo = [ connectionStrings.ConnStringInfo ];
    }

    return connectionStrings;
  }
};<commit_msg>Add missing reference<commit_after>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var util = require('util');
var __ = require('underscore');

var utils = require('../util/utils');
var interaction = require('../util/interaction');

exports.init = function (cli) {

  var log = cli.output;
  var site = cli.category('site');
  var siteConnectionStrings = site.category('connectionstring')
    .description('Commands to manage your Web Site connection strings');

  siteConnectionStrings.command('list [name]')
    .usage('[options] [name]')
    .description('Show your site application settings')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      site.lookupSiteNameAndWebSpace(context, _);

      var siteConfigurations = site.doSiteConfigGet(context, _);
      siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);
      interaction.formatOutput(cli, siteConfigurations.ConnectionStrings.ConnStringInfo, function (data) {
        if (data.length > 0) {
          log.table(data, function (row, item) {
            row.cell('Name', item.Name);
            row.cell('Type', item.Type);
          });
        } else {
          log.info('No connection strings defined yet.');
        }
      });
    });

  siteConnectionStrings.command('add [connectionname] [value] [type] [name]')
    .usage('[options] <connectionname> <value> <type> [name]')
    .description('Adds a connection string to your site')
    .option('-c, --connectionname <connectionname>', 'the connection string name')
    .option('-v, --value <value>', 'the connection string value')
    .option('-t, --type <type>', 'the connection string type')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (connectionname, value, type, name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      var params = utils.normalizeParameters({
        connectionname: [connectionname, options.connectionname],
        value: [value, options.value],
        type: [type, options.type]
      });

      if (params.err) { throw params.err; }

      connectionname = interaction.promptIfNotGiven(cli, 'Connection String Name: ', params.values.connectionname, _);
      value = interaction.promptIfNotGiven(cli, 'Connection String Value: ', params.values.value, _);
      type = interaction.chooseIfNotGiven(cli, 'Connection String Type: ', 'Getting types', params.values.type,
          function (cb) {
            cb(null, [ 'SQLAzure', 'SQLServer', 'Custom', 'MySQL' ]);
          }, _);

      if (type !== 'SQLAzure' && type !== 'SQLServer' && type !== 'Custom' && type !== 'MySQL') {
        throw new Error('Invalid connection string type. Valid types are: SQLAzure, SQLServer, Custom or MySQL');
      }

      site.lookupSiteNameAndWebSpace(context, _);
      var siteConfigurations = site.doSiteConfigGet(context, _);
      siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);
      siteConfigurations.ConnectionStrings.ConnStringInfo.push({
        ConnectionString: value,
        Name: connectionname,
        Type: type
      });

      site.doSiteConfigPUT(siteConfigurations, context, _);
    });

  siteConnectionStrings.command('delete <connectionname> [name]')
    .usage('[options] <connectionname> [name]')
    .description('Deletes a connection string for your site')
    .option('-c, --connectionname <connectionname>', 'the connection string name')
    .option('-q, --quiet', 'quiet mode, do not ask for delete confirmation')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (connectionname, name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      var params = utils.normalizeParameters({
        connectionname: [connectionname, options.connectionname]
      });

      if (params.err) { throw params.err; }

      connectionname = interaction.promptIfNotGiven(cli, 'Connection String Name: ', params.values.connectionname, _);

      if (!options.quiet && !interaction.confirm(cli, util.format('Delete %s connection string? (y/n) ', connectionname), _)) {
        return;
      }

      site.lookupSiteNameAndWebSpace(context, _);
      var siteConfigurations = site.doSiteConfigGet(context, _);

      var found = false;
      if (siteConfigurations.ConnectionStrings && siteConfigurations.ConnectionStrings.ConnStringInfo) {
        siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);

        for (var i = 0; i < siteConfigurations.ConnectionStrings.ConnStringInfo.length; i++) {
          if (utils.ignoreCaseEquals(siteConfigurations.ConnectionStrings.ConnStringInfo[i].Name, connectionname)) {
            siteConfigurations.ConnectionStrings.ConnStringInfo.splice(i, 1);
            found = true;
            i--;
          }
        }

        if (found) {
          if (siteConfigurations.ConnectionStrings.ConnStringInfo.length === 0) {
            siteConfigurations.ConnectionStrings = { };
          }

          site.doSiteConfigPUT(siteConfigurations, context, _);
        }
      }

      if (!found) {
        throw new Error(util.format('Connection string with name "%s" does not exist.', connectionname));
      }
    });

  siteConnectionStrings.command('show <connectionname> [name]')
    .usage('[options] <connectionname> [name]')
    .description('Shows a connection string for your site')
    .option('-c, --connectionname <connectionname>', 'the connection string name')
    .option('-s, --subscription <id>', 'use the subscription id')
    .execute(function (connectionname, name, options, _) {
      var context = {
        subscription: cli.category('account').lookupSubscriptionId(options.subscription),
        site: { name: name }
      };

      var params = utils.normalizeParameters({
        connectionname: [connectionname, options.connectionname]
      });

      if (params.err) { throw params.err; }

      connectionname = interaction.promptIfNotGiven(cli, 'Connection String Name: ', params.values.connectionname, _);

      site.lookupSiteNameAndWebSpace(context, _);
      var siteConfigurations = site.doSiteConfigGet(context, _);
      siteConfigurations.ConnectionStrings = getConnectionStrings(siteConfigurations.ConnectionStrings);
      var match = siteConfigurations.ConnectionStrings.ConnStringInfo.filter(function (c) {
        return utils.ignoreCaseEquals(c.Name, connectionname);
      })[0];

      if (match) {
        interaction.formatOutput(cli, match, function (data) {
          interaction.logEachData(cli, 'Connection String', data);
        });
      } else {
        throw new Error(util.format('Connection string with name "%s" does not exist.', connectionname));
      }
    });

  function getConnectionStrings(connectionStrings) {
    if (!connectionStrings) {
      connectionStrings = {};
    }

    if (!connectionStrings.ConnStringInfo) {
      connectionStrings.ConnStringInfo = [ ];
    } else if (!__.isArray(connectionStrings.ConnStringInfo)) {
      connectionStrings.ConnStringInfo = [ connectionStrings.ConnStringInfo ];
    }

    return connectionStrings;
  }
};<|endoftext|>


<commit_before>var IncomingCallBack = require('../constructors/callback');
var NameSpace = require('../constructors/namespace');
var routeController = require('./routeController');

var core;

var incomingCallbacks = {};
var outgoingCallbacks = {};
var nameSpaces = {};

var executionController = {

    initialize: function(samsaaraCore) {
        core = samsaaraCore;

        nameSpaces.core = new NameSpace('core', {});
        nameSpaces.internal = new NameSpace('internal', {
            callItBack: callItBack,
            callItBackError: callItBackError
        });
    },

    // Outgoing Execution

    execute: function(channel, route, executorArray, namespaceName, funcName, args) {

        var packet = {
            func: funcName,
            ns: namespaceName || 'core',
            args: args
        };

        if (typeof args[args.length - 1] === 'function') {
            packet.args = Array.slice(args);
            createCallBack(packet.args.pop(), executorArray, packet);
        }

        routeController.routeOutgoingPacket(channel, route, packet);
    },

    executeRaw: function(channel, route, executorArray, packet, callBack) {

        if (typeof callBack === 'function') {
            createCallBack(callBack, executorArray, packet);
        }

        routeController.routeOutgoingPacket(channel, route, packet);
    },

    // Incoming Execution

    executeFunction: function(executor, context, incomingPacket, callBackGenerator) {

        var functionName = incomingPacket.func;
        var namespaceName = incomingPacket.ns || 'core';
        var namespace = this.nameSpace(namespaceName);
        var namespaceMethods;
        var messageArgs;
        var theCallBack;
        var callbackID;

        if (namespace !== undefined) {

            namespaceMethods = namespace.methods;

            if (typeof namespaceMethods[functionName] === 'function') {

                messageArgs = incomingPacket.args || [];

                callBackGenerator = callBackGenerator || generateOutgoingCallBackClosure;
                callbackID = incomingPacket.callBack;

                if (typeof callbackID === 'string' && callbackID.match(/^([a-zA-Z0-9\.]+)$/)) {
                    theCallBack = outgoingCallbacks[callbackID] = callBackGenerator(callbackID, executor);
                    messageArgs.push(theCallBack);
                }

                namespaceMethods[functionName].apply(context, messageArgs);

            } else {
                console.error('Samsaara Method Execution ERROR: Call by:', executor.id, ':', functionName, 'is not an exposed Samsaara Object that can be executed.');
            }

        } else {
            console.error('Samsaara Method Execution ERROR: Call by:', executor.id, ':', namespaceName, 'is not valid namespace.');
        }
    },

    // Exported to Core

    createNamespace: function(namespaceName, methods) {
        var nameSpace = null;

        if (namespaceName !== 'core' && namespaceName !== 'internal') {
            nameSpace = new NameSpace(namespaceName, methods);
            nameSpaces[namespaceName] = nameSpace;
        }

        return core;
    },

    nameSpace: function(namespaceName) {
        return nameSpaces[namespaceName];
    },

    expose: function(set) {
        this.nameSpace('core').expose(set);
        return core;
    }
};

// a method to process a packet for multiple executors
// args is initially an arguments object
function processPacket(executorArray, packet, args) {

    if (typeof args[args.length - 1] === 'function') {
        args = Array.slice(args);
        createCallBack(args.pop(), executorArray, packet);
    }

    packet.args = args;

    return packet;
}

// Incoming CallBack Generator
// Creates an expected Callback method, whose index is sent to clients.
// The callback will expect a certain number of processes/clients to execute before getting deleted/set to undefined.
function createCallBack(theCallBack, executorArray, packet) {
    var incomingCallback = new IncomingCallBack(theCallBack, executorArray, destroyCallBack);
    var callbackID = incomingCallback.id;

    incomingCallbacks[callbackID] = incomingCallback;
    packet.callBack = callbackID;

    return incomingCallback;
}

function destroyCallBack(callbackID) {
    incomingCallbacks[callbackID] = undefined;
}

// Outgoing CallBack Generator
// Returns a function to send a message answering a callBack request sent from the client
function generateOutgoingCallBackClosure(callbackID, executor) {

    var theCallBack = function() {
        var args = Array.slice(arguments),
            packet = {
                ns: 'internal',
                func: 'callItBack',
                args: [callbackID, args]
            },
            aCallBack;

        if (typeof args[args.length - 1] !== 'function') {
            executor.executeRaw(packet);
        } else {
            aCallBack = args.pop();
            executor.executeRaw(packet, aCallBack);
        }

        delete outgoingCallbacks[callbackID];
    };

    return theCallBack;
}

// Exposed CallBack Execution Method
// Allows the client to execute an indexed method that was stored for callback
function callItBack(callbackID, args) {

    var executor = this;
    var executorID = executor.id;
    var theCallBack = incomingCallbacks[callbackID];

    if (theCallBack !== undefined && args instanceof Array) {

        if (typeof arguments[arguments.length - 1] === 'function') {
            args.push(arguments[arguments.length - 1]);
        }

        theCallBack.executeCallBack(executorID, executor, args);
    }
}

// Exposed CallBack Execution Error Method
// Allows the client to execute an indexed method that was stored for callback
function callItBackError(callbackID, args) {

    var executor = this;
    var executorID = executor.id;
    var theCallBack = incomingCallbacks[callbackID];

    if (theCallBack !== undefined) {
        theCallBack.callBackError(executorID, executor, args);
    }
}

module.exports = executionController;
<commit_msg>Fixing Array.slice call bug.<commit_after>var IncomingCallBack = require('../constructors/callback');
var NameSpace = require('../constructors/namespace');
var routeController = require('./routeController');

var core;

var incomingCallbacks = {};
var outgoingCallbacks = {};
var nameSpaces = {};

var executionController = {

    initialize: function(samsaaraCore) {
        core = samsaaraCore;

        nameSpaces.core = new NameSpace('core', {});
        nameSpaces.internal = new NameSpace('internal', {
            callItBack: callItBack,
            callItBackError: callItBackError
        });
    },

    // Outgoing Execution

    execute: function(channel, route, executorArray, namespaceName, funcName, args) {

        var packet = {
            func: funcName,
            ns: namespaceName || 'core',
            args: args
        };

        if (typeof args[args.length - 1] === 'function') {
            packet.args = Array.prototype.slice.call(args);
            createCallBack(packet.args.pop(), executorArray, packet);
        }

        routeController.routeOutgoingPacket(channel, route, packet);
    },

    executeRaw: function(channel, route, executorArray, packet, callBack) {

        if (typeof callBack === 'function') {
            createCallBack(callBack, executorArray, packet);
        }

        routeController.routeOutgoingPacket(channel, route, packet);
    },

    // Incoming Execution

    executeFunction: function(executor, context, incomingPacket, callBackGenerator) {

        var functionName = incomingPacket.func;
        var namespaceName = incomingPacket.ns || 'core';
        var namespace = this.nameSpace(namespaceName);
        var namespaceMethods;
        var messageArgs;
        var theCallBack;
        var callbackID;

        if (namespace !== undefined) {

            namespaceMethods = namespace.methods;

            if (typeof namespaceMethods[functionName] === 'function') {

                messageArgs = incomingPacket.args || [];

                callBackGenerator = callBackGenerator || generateOutgoingCallBackClosure;
                callbackID = incomingPacket.callBack;

                if (typeof callbackID === 'string' && callbackID.match(/^([a-zA-Z0-9\.]+)$/)) {
                    theCallBack = outgoingCallbacks[callbackID] = callBackGenerator(callbackID, executor);
                    messageArgs.push(theCallBack);
                }

                namespaceMethods[functionName].apply(context, messageArgs);

            } else {
                console.error('Samsaara Method Execution ERROR: Call by:', executor.id, ':', functionName, 'is not an exposed Samsaara Object that can be executed.');
            }

        } else {
            console.error('Samsaara Method Execution ERROR: Call by:', executor.id, ':', namespaceName, 'is not valid namespace.');
        }
    },

    // Exported to Core

    createNamespace: function(namespaceName, methods) {
        var nameSpace = null;

        if (namespaceName !== 'core' && namespaceName !== 'internal') {
            nameSpace = new NameSpace(namespaceName, methods);
            nameSpaces[namespaceName] = nameSpace;
        }

        return core;
    },

    nameSpace: function(namespaceName) {
        return nameSpaces[namespaceName];
    },

    expose: function(set) {
        this.nameSpace('core').expose(set);
        return core;
    }
};

// a method to process a packet for multiple executors
// args is initially an arguments object
function processPacket(executorArray, packet, args) {

    if (typeof args[args.length - 1] === 'function') {
        args = Array.prototype.slice.call(args);
        createCallBack(args.pop(), executorArray, packet);
    }

    packet.args = args;

    return packet;
}

// Incoming CallBack Generator
// Creates an expected Callback method, whose index is sent to clients.
// The callback will expect a certain number of processes/clients to execute before getting deleted/set to undefined.
function createCallBack(theCallBack, executorArray, packet) {
    var incomingCallback = new IncomingCallBack(theCallBack, executorArray, destroyCallBack);
    var callbackID = incomingCallback.id;

    incomingCallbacks[callbackID] = incomingCallback;
    packet.callBack = callbackID;

    return incomingCallback;
}

function destroyCallBack(callbackID) {
    incomingCallbacks[callbackID] = undefined;
}

// Outgoing CallBack Generator
// Returns a function to send a message answering a callBack request sent from the client
function generateOutgoingCallBackClosure(callbackID, executor) {

    var theCallBack = function() {
        var args = Array.slice(arguments),
            packet = {
                ns: 'internal',
                func: 'callItBack',
                args: [callbackID, args]
            },
            aCallBack;

        if (typeof args[args.length - 1] !== 'function') {
            executor.executeRaw(packet);
        } else {
            aCallBack = args.pop();
            executor.executeRaw(packet, aCallBack);
        }

        delete outgoingCallbacks[callbackID];
    };

    return theCallBack;
}

// Exposed CallBack Execution Method
// Allows the client to execute an indexed method that was stored for callback
function callItBack(callbackID, args) {

    var executor = this;
    var executorID = executor.id;
    var theCallBack = incomingCallbacks[callbackID];

    if (theCallBack !== undefined && args instanceof Array) {

        if (typeof arguments[arguments.length - 1] === 'function') {
            args.push(arguments[arguments.length - 1]);
        }

        theCallBack.executeCallBack(executorID, executor, args);
    }
}

// Exposed CallBack Execution Error Method
// Allows the client to execute an indexed method that was stored for callback
function callItBackError(callbackID, args) {

    var executor = this;
    var executorID = executor.id;
    var theCallBack = incomingCallbacks[callbackID];

    if (theCallBack !== undefined) {
        theCallBack.callBackError(executorID, executor, args);
    }
}

module.exports = executionController;
<|endoftext|>


<commit_before>'use strict';

var Q = require('q'),
  swig = require('swig'),
  fs = require('fs'),
  _ = require('lodash'),
  path = require('path'),
  util = require('./util'),
  DependableList = require('./dependablelist'),
  search = require('./search');

var _modules = new DependableList();

function lowerCaseFirstLetter(string) {
  return string.charAt(0).toLowerCase() + string.slice(1);
}

//finding modules
//
function findModulesError (defer, error) {
  console.error('Error loading modules', error);
  defer.resolve();
}

function jQueryMinMapHandler(jqueryminmap,req,res){
  res.send(jqueryminmap);
}

function aggregatedJSSender(res,data){
  res.send(data);
}

function aggregatedJSHandler(meanioinstance, req, res) {
  res.setHeader('content-type', 'text/javascript');
  meanioinstance.aggregated('js', req.query.group ? req.query.group : 'footer', aggregatedJSSender.bind(null,res));
}

function aggregatedMapHandler(meanioinstance, req, res) {
    res.setHeader('content-type', 'application/octet-stream');
    meanioinstance.aggregated('map', req.query.group ? req.query.group : 'footer', aggregatedJSSender.bind(null,res));
}

function aggregatedCSSSender(res,data){
  res.send(data);
};

function aggregatedCSSHandler(meanioinstance, req, res) {
  res.setHeader('content-type', 'text/css');
  meanioinstance.aggregated('css', req.query.group ? req.query.group : 'header', aggregatedCSSSender.bind(null,res));
};

function getModulesHandler(meanioinstance,req,res,next){
  res.json(meanioinstance.exportable_modules_list);
};

function findModulesDone (meanioinstance, app, defer) {
  var config = meanioinstance.config.clean;
  app.get('/_getModules',getModulesHandler.bind(null,meanioinstance));
  if(config.aggregation!==false){
    var jqueryminmap = fs.readFileSync(config.root + '/bower_components/jquery/dist/jquery.min.map');
    app.get('/modules/jquery.min.map',jQueryMinMapHandler.bind(null,jqueryminmap));
    app.get('/modules/aggregated.js', aggregatedJSHandler.bind(null,meanioinstance));
    app.get('/modules/aggregated.map', aggregatedMapHandler.bind(null,meanioinstance));
    app.get('/modules/aggregated.css', aggregatedCSSHandler.bind(null,meanioinstance));
    app.useStatic('/bower_components', config.root + '/bower_components');
  }
  if(!_modules.unresolved.empty()){
    throw 'Packages with unresolved dependencies: '+_modules.listOfUnresolved();
  }
  //Meanio.onModulesFoundAggregate('js',{}); //TODO: let each module aggregate its 'js'
  enableModules(meanioinstance,defer);
}
//

//enabling modules
//
function moduleActivator(defers,meaniosingleton,loadedmodule){
  if(loadedmodule){
    var defer = Q.defer();
    defers.push(defer);
    loadedmodule.activate();
    meaniosingleton.resolve(loadedmodule.name,defer.resolve.bind(defer));
  }
}

function moduleRegistrator(meaniosingleton,loadedmodule){
  if(loadedmodule){
    meaniosingleton.exportable_modules_list.push ({
      name:loadedmodule.name,
      angularDependencies: loadedmodule.angularDependencies
    });
  }
}

function onModulesEnabled(meanioinstance,defer){
  _modules.traverse(moduleRegistrator.bind(null,meanioinstance));
  defer.resolve();
}

function enableModules(meanioinstance,defer) {
  var defers = [];
  _modules.traverse(moduleActivator.bind(null,defers,meanioinstance));
  Q.all(defers).done(onModulesEnabled.bind(null,meanioinstance,defer));
}
//

function findModules(meanioinstance,defer,app) {
  var disabled = _.toArray(meanioinstance.config.clean.disabledModules);
  Q.all([
    search(_modules, disabled, 'node_modules'),
    search(_modules, disabled, 'packages'),
    search(_modules, disabled, 'packages/core'),
    search(_modules, disabled, 'packages/custom'),
    search(_modules, disabled, 'packages/contrib')
  ]).done(findModulesDone.bind(null, meanioinstance, app, defer), findModulesError.bind(null, defer));
}

function onInstance(meanioinstance,defer){
  meanioinstance.resolve('app',findModules.bind(null,meanioinstance,defer));
}

function moduleHasName(targetname,module){
  if(targetname===module.name){
    return true;
  }
}

function supportModules(Meanio){
  Meanio.onInstance(onInstance);
  Meanio.prototype.moduleEnabled = function(name) {
    return this.modules.traverseConditionally(moduleHasName.bind(null,name)) || false;
  };

  //static property
  Meanio.modules = _modules;

  //instance property
  Meanio.prototype.modules = Meanio.modules;

  Meanio.prototype.exportable_modules_list = [];

  function onModuleAngularDependenciesRegistered(callback){
    Meanio.createModels();
    callback();
  }

  function requireModel (path) {
    var mdl = require(path);
    if (mdl.register) {Meanio.applyModels(mdl.register);}
  }

  function Module(name) {
    this.loadedmodule = Meanio.modules.moduleNamed(name);
    if(!this.loadedmodule){
      Meanio.modules.dumpToConsole();
      throw 'Module with name '+name+' is not loaded';
    }
    this.name = lowerCaseFirstLetter(this.loadedmodule.name);
    this.menus = Meanio.Singleton.menus;
    this.config = Meanio.Singleton.config;

    // bootstrap models
    util.walk(this.loadedmodule.path('server'), 'model', null, requireModel);
  }

  Module.prototype.render = function(view, options, callback) {
    swig.renderFile(this.loadedmodule.path('server') + '/views/' + view + '.html', options, callback);
  };

  Module.prototype.setDefaultTemplate = function(template) {
    Meanio.Singleton.template = template;
  };

  Module.prototype.routes = function() {
    var args = Array.prototype.slice.call(arguments);
    util.walk(this.loadedmodule.path('server'), 'route', 'middlewares', this.onRoute.bind(this,[this].concat(args)));
  };

  Module.prototype.onRoute = function(args,route) {
    require(route).apply(this, args);
  }

  Module.prototype.register = function(callback) {
    Meanio.Singleton.register(this.name, callback);
  };

  Module.prototype.angularDependencies = function(dependencies) {
    this.angularDependencies = dependencies;
    this.loadedmodule.angularDependencies = dependencies;
  };
  function updateSettings(Package, name, settings, callback) {
    Package.findOneAndUpdate({
      name: name
    }, {
      $set: {
        settings: settings,
      updated: new Date()
      }
    }, {
      upsert: true,
      multi: false
    }, function(err, doc) {
      if (err) {
        console.log(err);
        return callback(true, 'Failed to update settings');
      }
      return callback(null, doc);
    });
  }

  function getSettings(Package, name, callback) {
    Package.findOne({
      name: name
    }, function(err, doc) {
      if (err) {
        console.log(err);
        return callback(true, 'Failed to retrieve settings');
      }
      return callback(null, doc);
    });
  }

  Module.prototype.settings = function() {

    if (!arguments.length) return;

    var database = Meanio.Singleton.get('database');
    if (!database || !database.connection) {
      return {
        err: true,
        message: 'No database connection'
      };
    }

    if (!database.connection.models.Package) {
      require('../modules/package')(database);
    }

    var Package = database.connection.model('Package');
    if (arguments.length === 2) return updateSettings(Package, this.name, arguments[0], arguments[1]);
    if (arguments.length === 1 && typeof arguments[0] === 'object') return updateSettings(Package, this.name, arguments[0], function() {});
    if (arguments.length === 1 && typeof arguments[0] === 'function') return getSettings(Package, this.name, arguments[0]);

  };
  Module.bootstrapModules = function(callback){
    findModules(enableModules.bind(null,callback));
  };

  Meanio.prototype.Module = Module;
  require('./aggregation')(Meanio);

}

module.exports = supportModules;
<commit_msg>Added map support<commit_after>'use strict';

var fs = require('fs'),
  request = require('request'),
  uglify = require('uglify-js'),
  crypto = require('crypto'),
  path = require('path'),
  List = require('complex-list'),
  inherit = require('./inherit'),
  assetmanager = require('assetmanager'),
  async = true;

function ascending(a,b){
  return a.options.weight>=b.options.weight;
}

function WeightedList(){
  List.call(this,ascending);
  this.data = '';
  this.src = []
  this.dirty = false;
}
inherit(WeightedList,List);
WeightedList.prototype.add = function(content){
  this.dirty = true;
  List.prototype.add.call(this,content);
};
WeightedList.prototype.getData = function(){
  if(this.dirty){
    this.buildScalars();
  }
  return this.data;
};
WeightedList.prototype.getSrc = function(){
  if(this.dirty){
    this.buildScalars();
  }
  return this.src;
};
WeightedList.prototype.buildScalars = function(){
  this.data = '';
  this.src = [];
  this.traverse(this.addToScalars.bind(this));
  this.dirty = false;
};
WeightedList.prototype.addToScalars = function(content){
  if(!content){return;}
  if(content.src){
    this.src.push(content.src);
  }
  if(content.data){
    if(this.data){
      this.data += '\n';
    }
    this.data += content.data;
  }
};

var aggregated = {
  css: new WeightedList(),
  js : {
    header: new WeightedList(),
    footer: new WeightedList()
  }
};

function Asset(src,options){
  this.src = src;
  this.options = options;
  if(!this.options.weight){
    this.options.weight=0;
  }
  this.data = null;
}
Asset.prototype.destroy = function(){
  this.data = null;
  this.options = null;
  this.src = null;
};
Asset.prototype.minifyData = function(stringdata){
  this.data = stringdata;
};
//Asset.prototype.minifyJSData = function(stringdata){
//  var ugly;
//  try {
//    ugly = uglify.minify(stringdata, {
//      fromString: true,
//      mangle: false
//    });
//  }
//  catch (e) {
//    console.log('\\n\nError in', stringdata, 'on line', e.line);
//    console.log(e.message);
//    throw e;
//  }
//
////    console.log('minifyJSData >>>>>', ugly.map);
//  this.data = ugly.code;
//};
Asset.prototype.storeCSS = function(){
  aggregated.css.add(this);
};
Asset.prototype.storeJS = function(){
  aggregated.js[this.group()].add(this);
};
Asset.prototype.group = function(){
  var ret = this.options.group || 'footer';
  return ret;
};
Asset.prototype.shouldAggregate = function(){
  return this.options.aggregate !== false;
};
Asset.prototype.shouldMinify = function(){
  return this.options.debug!==true;
};
Asset.prototype.isGlobal = function(){
  return this.options.global===true;
};
Asset.prototype.processStringData = function(stringdata){
  if(this.shouldAggregate()){
    if(stringdata.length){
      this.aggregateStringData(stringdata);
    }else{
      console.log('but not, since data is of 0 length');
    }
  }
  this.store();
};
Asset.prototype.processJSStringData = function(stringdata){
  if(!(stringdata && stringdata.length)){
    this.destroy();
    return;
  }
  if(!this.isGlobal()){
    stringdata = '(function(){'+stringdata+'})();';
  }
  Asset.prototype.processStringData.call(this,stringdata);
};
Asset.prototype.aggregateStringData = function(stringdata){
  if(this.shouldMinify()){
    this.minifyData(stringdata);
  }else{
    this.data = stringdata;
  }
};

function InlineAsset(src,data,options){
  Asset.call(this,src,options);
  this.processData(data);
}
inherit(InlineAsset,Asset);

function InlineCSSAsset(src,options){
  InlineAsset.call(this,"<style>\n"+src+"\n</style>",src,options);
}
inherit(InlineCSSAsset,InlineAsset);
InlineCSSAsset.prototype.store = Asset.prototype.storeCSS;

function InlineJSAsset(src,options){
  InlineAsset.call(this,"<script language='javascript'>\n"+src+"\n</script>",src,options);
}
inherit(InlineJSAsset,InlineAsset);
InlineJSAsset.prototype.store = Asset.prototype.storeJS;
InlineJSAsset.prototype.processStringData = Asset.prototype.processJSStringData;

function RemoteAsset(src,options){
  Asset.call(this,src,options);
  this.fetchData();
}
inherit(RemoteAsset,Asset);
RemoteAsset.prototype.fetchData = function(){
  request(this.src, this.onRemoteData.bind(this));
};
RemoteAsset.prototype.onRemoteData = function(err, res, body) {
  if (!err && res.statusCode === 200) {
    this.processStringData(body);
  }else{
    this.destroy();
  }
};

function RemoteCSSAsset(src,options){
  RemoteAsset.call(this,src,options);
}
inherit(RemoteCSSAsset,RemoteAsset);
RemoteCSSAsset.prototype.store = Asset.prototype.storeCSS;

function RemoteJSAsset(src,options){
  RemoteAsset.call(this,src,options);
}
inherit(RemoteJSAsset,RemoteAsset);
RemoteJSAsset.prototype.store = Asset.prototype.storeJS;
RemoteJSAsset.prototype.processStringData = Asset.prototype.processJSStringData;

function FileAsset(filepath,src,options){
  this.path = filepath;
  if(src.charAt(0)!=='/'){
    src = '/'+src;
  }
  Asset.call(this,src.replace(/\\/g, "/"),options);
  this.read();
}
inherit(FileAsset,Asset);
FileAsset.prototype.destroy = function(){
  Asset.prototype.destroy.call(this);
  this.path = null;
};
FileAsset.prototype.read = function(){
  if(!fs.existsSync(this.path)){
    console.log(this.path,'not found');
    this.destroy();
    return;
  }
  if(async){
    fs.readFile(this.path,this.onErrorAndData.bind(this));
  }else{
    this.onData(fs.readFileSync(this.path));
  }
};
FileAsset.prototype.onErrorAndData = function(err,data){
  if(err){
    return;
  }
  this.onData(data);
};
FileAsset.prototype.onData = function(data){
  this.processStringData(data.toString());
};
FileAsset.prototype.aggregateData = function(stringdata){
};

function CSSFileAsset(filepath,src,options){
  FileAsset.call(this,filepath,src,options);
}
inherit(CSSFileAsset,FileAsset);
CSSFileAsset.prototype.store = Asset.prototype.storeCSS;

function JSFileAsset(filepath,src,options){
  FileAsset.call(this,filepath,src,options);
}
inherit(JSFileAsset,FileAsset);
JSFileAsset.prototype.store = Asset.prototype.storeJS;
JSFileAsset.prototype.processStringData = Asset.prototype.processJSStringData;

function AssetDir(ext,dirpath,src,options){
  this.ext = ext;
  this.path = dirpath;
  this.src = src;
  this.options = options;
  this.readdir();
}
AssetDir.prototype.destroy = function(){
  this.options = null;
  this.src = null;
  this.path = null;
  this.ext = null;
};
AssetDir.prototype.readdir = function(){
  if(!fs.existsSync(this.path)){
    this.destroy();
    return;
  }
  if(async){
    fs.readdir(this.path,this.onErrorAndItems.bind(this));
  }else{
    this.onItems(fs.readdirSync(this.path));
  }
};
AssetDir.prototype.onErrorAndItems = function(error,items){
  if(error){
    this.destroy();
    return;
  }
  this.onItems(items);
};
AssetDir.prototype.onItems = function(items){
  items.forEach(this.produceAsset.bind(this));
  this.destroy();
};
AssetDir.prototype.produceAsset = function(item){
  if(item==='assets'){
    return;
  }
  if(item==='tests'){
    return;
  }
  AssetDir.produceAssetFromPath(path.join(this.path,item),this.ext,this.options,path.join(this.src,item));
};
AssetDir.produceAssetFromPath = function(fpath,ext,options,src){
  fpath = fpath.split('?')[0];
  if(!fs.existsSync(fpath)){
    return;
  }
  var fstats = fs.statSync(fpath);
  if(fstats.isDirectory()){
    new AssetDir(ext,fpath,src,options);
  }else{
    if(fstats.isFile()){
      if (path.extname(fpath) !== '.' + ext){
        return;
      }
      switch(ext){
        case 'css':
          new CSSFileAsset(fpath,src,options);
          return;
        case 'js':
          new JSFileAsset(fpath,src,options);
          return;
      }
    }
  }
};

function PackageDir(ext,rootpath,name,options){
  AssetDir.call(this,ext,path.join(rootpath,name,'public'),name,options);
}
inherit(PackageDir,AssetDir);

function moduleAggregateTraverser(ext,options,module){
  new PackageDir(ext,path.join(process.cwd(), module.source), module.name, options);
}

function onAggregatedSrc(loc,ext,res,next,data){
  res.locals.aggregatedassets[loc][ext] = data;
  next && next();
}

function aggregationRequestHandler(meanioinstance, req, res, next){
  //res.locals.assets = assets;
  res.locals.aggregatedassets = {header:{},footer:{}};
  meanioinstance.aggregatedsrc('css', 'header', onAggregatedSrc.bind(null,'header','css',res,null));
  meanioinstance.aggregatedsrc('js', 'header', onAggregatedSrc.bind(null,'header','js',res,null));
  meanioinstance.aggregatedsrc('css', 'footer', onAggregatedSrc.bind(null,'footer','css',res,null));
  meanioinstance.aggregatedsrc('js', 'footer', onAggregatedSrc.bind(null,'footer','js',res,null));
  meanioinstance.aggregatedsrc('map', 'header', onAggregatedSrc.bind(null,'header','map',res,null));
  meanioinstance.aggregatedsrc('map', 'footer', onAggregatedSrc.bind(null,'footer','map',res,next));
}

function configureApp(Meanio,meanioinstance,defer,app){
  Meanio.modules.dependableConstructor().prototype.aggregatePackage = function(){
    new PackageDir('js',path.join(process.cwd(), this.source), this.name, {aggregate:Meanio.Singleton.config.clean.aggregate});
    app.useStatic('/'+this.name, this.path('public'));
  };
  var assets = assetmanager.process({
    assets: require(path.join(process.cwd(),'config','assets.json')),
    debug: true, //process.env.NODE_ENV !== 'production',
    webroot: /public\/|packages\//g
  });
  for(var i in assets.core.css){
    meanioinstance.aggregate('css',assets.core.css[i],{group:'header',singlefile:true},meanioinstance.config.clean);
  }
  for(var i in assets.core.js){
    meanioinstance.aggregate('js',assets.core.js[i],{group:'footer',singlefile:true,global:true,weight:-1000000+parseInt(i)},meanioinstance.config.clean);
  }

  // Add assets to local variables
  app.use(aggregationRequestHandler.bind(null,meanioinstance));
  defer.resolve();
}

function onInstance(Meanio,instance,defer){
  instance.resolve('app',configureApp.bind(null,Meanio,instance,defer));
}

function minifyJSData(stringData){
    var ugly;
    try {
        ugly = uglify.minify(stringData, {
            fromString: true,
            mangle: false,
            outSourceMap: "/modules/aggregated.map"
        });
    }
    catch (e) {
        console.log('\\n\nError in', stringdata, 'on line', e.line);
        console.log(e.message);
        throw e;
    }

    return ugly;
};

function supportAggregate(Meanio) {

  Meanio.onInstance(onInstance.bind(null,Meanio));
  Meanio.prototype.aggregated = function(ext, group, callback) {
    //  \\ Data already exists and is ready
    if (Meanio.Singleton.config.clean.aggregate === false){
      return callback('');
    }
    if(ext==='css' && group==='header'){
      callback(aggregated.css.getData());
      return;
    }
    var mapLocation = '\n//# sourceMappingURL=/modules/aggregated.map';
    if(ext==='js'){
        if (!this.minify) {
            this.minify = {};
        }
        if (!this.minify[group]) {
            this.minify[group] = minifyJSData(aggregated.js[group].getData());
        }
      callback(this.minify[group].code);
      return;
    }
    if(ext==='map'){
        if (!this.minify) {
            this.minify = {};
        }
        if (!this.minify[group]) {
            this.minify[group] = minifyJSData(aggregated.js[group].getData());
        }
      return callback(this.minify[group].map);
      return;
    }
    callback('');
  };

  Meanio.prototype.aggregatedsrc = function(ext, group, callback) {
    // Aggregated Data already exists and is ready
    if (Meanio.Singleton.config.clean.aggregate !== false){
      if(ext==='js'){
        if(group==='header'){
          return callback(['/modules/aggregated.js?group=header']);
        }else{
          return callback(['/modules/aggregated.js']);
        }
      }else if(ext==='css' && group==='header'){
        return callback(['/modules/aggregated.css']);
      }
      return callback([]);
    }
    if(ext==='css'){
      callback(group==='header' ? (aggregated.css ? aggregated.css.getSrc() : []) : []);
      return;
    }
    if(ext==='js'){
      callback(aggregated.js && aggregated.js[group] ? aggregated.js[group].getSrc() : []);
      return
    }
    callback([]);
  };

  Meanio.prototype.Module.prototype.aggregateAsset = function(type, asset, options) {
    options = options || {};
    options.aggregate = Meanio.Singleton.config.clean.aggregate;
    options.debug = Meanio.Singleton.config.clean.debug;
    if (options.inline){
      switch(type){
        case 'css':
          new InlineCSSAsset(asset,options);
          return;
        case 'js':
          new InlineJSAsset(asset,options);
          return;
      }
      return;
    }
    else if (options.url){
      switch(type){
        case 'css':
          new RemoteCSSAsset(asset,options);
          return;
        case 'js':
          new RemoteJSAsset(asset,options);
          return;
      }
      return;
    }else{
      var fpath = path.join(this.loadedmodule.path('public'),'assets',type,asset)
      switch(type){
        case 'css':
          new CSSFileAsset(fpath,path.join(this.name,'assets',type,asset),options);
          return;
        case 'js':
          new JSFileAsset(fpath,path.join(this.name,'assets',type,asset),options);
          return;
      }
    }
  };

  Meanio.onModulesFoundAggregate = function(ext, options) {
    options = options||{};
    options.aggregate = Meanio.Singleton.config.clean.aggregate;
    options.debug = Meanio.Singleton.config.clean.debug;
    Meanio.modules.traverse(moduleAggregateTraverser.bind(null,ext,options));
  };

  Meanio.aggregate = function(ext, asset, options, config) {
    if (!asset) {
      return;
    }
    options = options||{};
    options.aggregate = Meanio.Singleton.config.clean.aggregate;
    options.debug = Meanio.Singleton.config.clean.debug;
    if (options.inline){
      switch(ext){
        case 'css':
          new InlineCSSAsset(asset,options);
          return;
        case 'js':
          new InlineJSAsset(asset,options);
          return;
      }
      return;
    }
    else if (options.url){
      switch(ext){
        case 'css':
          new RemoteCSSAsset(asset,options);
          return;
        case 'js':
          new RemoteJSAsset(asset,options);
          return;
      }
      return;
    }
    AssetDir.produceAssetFromPath(path.join(process.cwd(),asset),ext,options,asset);
  };

  Meanio.prototype.aggregate = Meanio.aggregate;
}

module.exports = supportAggregate;
<|endoftext|>


<commit_before>Package.describe({
  summary: "REPLACEME - What does this package (or the original one you're wrapping) do?"
});

Package.on_use(function (api, where) {
  api.add_files('accounts-pages.js', ['client', 'server']);
});

Package.on_test(function (api) {
  api.use('accounts-pages');

  api.add_files('accounts-pages_tests.js', ['client', 'server']);
});
<commit_msg>Update package file with proper api configuration<commit_after>Package.describe({
  summary: "Meteor smart package for full authentication pages styled with Semantic UI"
});

Package.on_use(function (api, where) {

  // client
  api.use([
    'handlebars',
    'less',
    'templating'
    ], 'client');

  api.add_files([
    'client/views/account_button.html',
    'client/views/account_button.js',
    'client/views/sign_in.html',
    'client/views/sign_in.js',
    'client/views/forgot_password.html',
    'client/views/forgot_password.js',
    'client/views/sign_up.html',
    'client/views/sign_up.js'
  ], 'client');

  // client and server
  api.export('AccountsPages', ['client', 'server']);
  api.use('iron-router', ['client', 'server']);
  api.add_files('lib/router.js', ['client', 'server']);

});

Package.on_test(function (api) {

});
<|endoftext|>


<commit_before>Package.describe({
  name: 'nicocrm:syncforce',
  version: '0.0.18',
  // Brief, one-line summary of the package.
  summary: 'Automate synchronization between Mongo and Salesforce Entities',
  // URL to the Git repository containing the source code for this package.
  git: 'https://github.com/nicocrm/meteor-syncforce',
  // By default, Meteor will default to using README.md for documentation.
  // To avoid submitting documentation, set this field to null.
  documentation: 'README.md'
});

Npm.depends({
  'jsforce': '1.8.0'
});

Package.onUse(function (api) {
  api.versionsFrom('1.4.4.1');
  api.use('ecmascript');
  api.use('check');
  api.use('matb33:collection-hooks@0.8.4');
  api.use('tmeasday:check-npm-versions@0.3.1');
  api.mainModule('syncforce-server.js', 'server');
  // API exported for both client and server
  // (the server file includes it, so that we don't have 2 main modules for the server)
  api.mainModule('syncforce-shared.js', 'client');
});

Package.onTest(function (api) {
  api.use('practicalmeteor:mocha')
  api.use('ecmascript');
  api.use('nicocrm:syncforce');
  // MUST specify the version when testing, or Meteor will load the oldest version it can find!
  api.use('matb33:collection-hooks@0.8.4');
  api.mainModule('syncforce-tests.js', ['client', 'server']);
  api.mainModule('syncforce-server-tests.js', 'server');
});
<commit_msg>version<commit_after>Package.describe({
  name: 'nicocrm:syncforce',
  version: '0.0.19',
  // Brief, one-line summary of the package.
  summary: 'Automate synchronization between Mongo and Salesforce Entities',
  // URL to the Git repository containing the source code for this package.
  git: 'https://github.com/nicocrm/meteor-syncforce',
  // By default, Meteor will default to using README.md for documentation.
  // To avoid submitting documentation, set this field to null.
  documentation: 'README.md'
});

Npm.depends({
  'jsforce': '1.8.0'
});

Package.onUse(function (api) {
  api.versionsFrom('1.4.4.1');
  api.use('ecmascript');
  api.use('check');
  api.use('matb33:collection-hooks@0.8.4');
  api.use('tmeasday:check-npm-versions@0.3.1');
  api.mainModule('syncforce-server.js', 'server');
  // API exported for both client and server
  // (the server file includes it, so that we don't have 2 main modules for the server)
  api.mainModule('syncforce-shared.js', 'client');
});

Package.onTest(function (api) {
  api.use('practicalmeteor:mocha')
  api.use('ecmascript');
  api.use('nicocrm:syncforce');
  // MUST specify the version when testing, or Meteor will load the oldest version it can find!
  api.use('matb33:collection-hooks@0.8.4');
  api.mainModule('syncforce-tests.js', ['client', 'server']);
  api.mainModule('syncforce-server-tests.js', 'server');
});
<|endoftext|>


<commit_before>Package.describe({
  name: 'babrahams:constellation',
  version: '0.1.10',
  summary: 'A curated set of packages for Constellation',
  git: 'https://github.com/JackAdams/constellation-distro.git',
  documentation: 'README.md',
  debugOnly: true
});

Package.onUse(function(api) {

  api.versionsFrom('1.1');

  api.use('constellation:console@1.2.2');
  api.use('babrahams:temple@0.3.4');
  api.use('constellation:subscriptions@0.3.2');
  api.use('constellation:session@0.3.3');
  api.use('constellation:autopublish@0.3.5');
  api.use('constellation:tiny@0.3.2');
  api.use('constellation:position@0.3.3');
  api.use('lai:ddp-inspector@1.1.7');
  api.use('constellation:plugins@0.1.2');

  api.imply('constellation:console');

});

Package.onTest(function(api) {
  api.use('tinytest');
});
<commit_msg>Updated dependencies<commit_after>Package.describe({
  name: 'babrahams:constellation',
  version: '0.1.11',
  summary: 'A curated set of packages for Constellation',
  git: 'https://github.com/JackAdams/constellation-distro.git',
  documentation: 'README.md',
  debugOnly: true
});

Package.onUse(function(api) {

  api.versionsFrom('1.1');

  api.use('constellation:console@1.2.3');
  api.use('babrahams:temple@0.3.5');
  api.use('constellation:subscriptions@0.3.3');
  api.use('constellation:session@0.3.4');
  api.use('constellation:autopublish@0.3.6');
  api.use('constellation:tiny@0.3.3');
  api.use('constellation:position@0.3.4');
  api.use('lai:ddp-inspector@1.1.7');
  api.use('constellation:plugins@0.1.3');

  api.imply('constellation:console');

});

Package.onTest(function(api) {
  api.use('tinytest');
});
<|endoftext|>


<commit_before>Package.describe({
  name: 'xolvio:private-packages',
  version: '1.0.0',
  summary: 'Allows you to add private packages to your app.',
  git: '',
  documentation: 'README.md'
});

Npm.depends({
  'mgp': '0.0.7'
})

Package.onUse(function(api) {
  api.versionsFrom('1.1.0.2');
  api.use('velocity:chokidar@1.0.1');
  api.use('sanjo:meteor-files-helpers@1.1.0_4');
  api.use('sanjo:long-running-child-process@1.1.1');
  api.addFiles('private-packages.js');
});
<commit_msg>Adds git url to package<commit_after>Package.describe({
  name: 'xolvio:private-packages',
  version: '1.0.0',
  summary: 'Allows you to add private packages to your app.',
  git: 'https://github.com/xolvio/meteor-private-packages.git',
  documentation: 'README.md'
});

Npm.depends({
  'mgp': '0.0.7'
})

Package.onUse(function(api) {
  api.versionsFrom('1.1.0.2');
  api.use('velocity:chokidar@1.0.1');
  api.use('sanjo:meteor-files-helpers@1.1.0_4');
  api.use('sanjo:long-running-child-process@1.1.1');
  api.addFiles('private-packages.js');
});
<|endoftext|>