<commit_before>/*
 * ccm-component implementing a bugtracker feature.
 */

ccm.component({
    name: 'bugtracker-mwe',
    config: {
        html        : [ccm.store, {local: 'js/templates.json'}],
        store       : [ccm.store, {local: 'js/bugs.json'}],
        remoteStore : [ccm.store, {store: 'bugtracker', url: 'http://ccm2.inf.h-brs.de/index.js' }],
        key         : 'bugtracker',
        style       : [ccm.load, 'css/bug.css']
    },

    Instance: function(){

        var self = this;

        self.render = function(callback){

            var element = ccm.helper.element(self);

            //Private function which builds the overview and attaches bugs
            var buildOverview = function(dataset){

                // Rendern der Grundstrutkur
                element.html(ccm.helper.html(self.html.get('main')));
                var overview = ccm.helper.find(self, '.bugs-overview');

                // Attach header
                var header = $(ccm.helper.html(
                    self.html.get('header'),
                    {
                        bugIdTitle: "ID",
                        nameTitle: "Name",
                        statusTitle: "Status",
                        subscriberTitle: "Subscriber",
                        descriptionTitle: "Describtion"
                    }
                ));
                header.appendTo(overview);

                //Render all bugs
                var i=0;
                while(dataset[i]){

                    // Create html and wrap in to a jQery object
                    var newBug = $(ccm.helper.html(
                        self.html.get('bug'),
                        {
                            bugId       : dataset[i].bugId,
                            subscriber  : dataset[i].subscriber,
                            description : dataset[i].description,
                            status      : dataset[i].state,
                            name        : dataset[i].name
                        }
                    ));
                    // Append it to overview
                    newBug.appendTo(overview);
                    i++;
                }

                // Append button to overview
                newBug.append("
<button class='new_bug'>Neuer Bug</button>");
                newBug.find('.new_bug').click(function () {
                    overview.html("
Add a new bug ...
" + "<form>" +
                        "Subject"
                        + "<textarea id='subject' name='ta_subject' cols='20' rows='5' required></textarea>"
                        + "
"
                        + "Status"
                        + " <select name='Status'>"
                        + "<option value='neu'>Neu</option>"
                        + "<option value='in_bearb'>in Bearbeitung</option>"
                        + "<option value='umgesetzt'>Umgesetzt</option>"
                        + "</select>"
                        + "
"
                        + "Priorität"
                        + " <select name='Priorität'>"
                        + "<option value='niedrig'>niedrig</option>"
                        + "<option value='mittel'>mittel</option>"
                        + "<option value='hoch'>hoch</option>"
                        + "</select>"
                        + "
"
                        + "<button class='return_to_overview'>Bug-Überblick</button>"
                        + "</form>");
                });
            };

            var onClickStatusHeader = function(){
                if ($(this).hasClass('no-order'))
                {
                    $(this).removeClass('no-order');
                    $(this).addClass('asc');
                    sortStatus(0);
                    return;
                }
                if ($(this).hasClass('asc'))
                {
                    $(this).removeClass('asc');
                    $(this).addClass('desc');
                    sortStatus(1);
                    return;
                }
                if ($(this).hasClass('desc'))
                {
                    $(this).removeClass('desc');
                    $(this).addClass('asc');
                    sortStatus(0);
                }
            };

            var onClickAddBug = function(){
                console.log('Add new Bug!')
                // Ein Beispiel:
                var newBug = {};
//                newBug.bugId = "te3";
//                newBug.context = "testcontext";
//                newBug.subsriber = "hans";
//                newBug.name = "Database broken!";
//                newBug.state = "open";
//                newBug.description = "test description ";
//                self.storeBug(newBug);
            };

            // Fetch data from DB and build overview
            self.remoteStore.get(function(response){
                buildOverview(response);
                //Add status header action
                $('.current-status-header').click(onClickStatusHeader);
                //Add new bug submit action
                // Not the correct button, just checking if it works
                $('.new_bug').click(onClickAddBug);
            });

            if(callback) callback();
        };

        //Public function to save bugs into remote database
        self.storeBug = function(bug){

            self.remoteStore.set({
                "bugId"         : bug.bugId,
                "context"       : bug.context,
                "subscriber"    : bug.subscriber,
                "description"   : bug.description,
                "name"          : bug.name,
                "state"         : bug.state
            });
        };

        //Private function to sort bugs after their status
        var sortStatus = function(order){
            //Get overview container
            var overview = $('.bugs-overview');
            //Get all bugs and remove them
            var bugs = overview.find('.bug');
            bugs.remove();

            if(order === 0)
            {
                order = ['open', 'pending', 'closed'];
            } else {
                order = ['closed', 'pending', 'open'];
            }

            order.forEach(function(key){
                bugs.each(function(){
                    if($(this).find('.current-status').html() === key)
                    {
                        $(this).appendTo(overview);
                    }
                });
            });
        };
    }
});
<commit_msg>add remote del && remove local store<commit_after>/*
 * ccm-component implementing a bugtracker feature.
 */

ccm.component({
    name: 'bugtracker-mwe',
    config: {
        html        : [ccm.store, {local: 'js/templates.json'}],
        remoteStore : [ccm.store, {store: 'bugtracker', url: 'http://ccm2.inf.h-brs.de/index.js' }],
        key         : 'bugtracker',
        style       : [ccm.load, 'css/bug.css']
    },

    Instance: function(){

        var self = this;

        self.render = function(callback){

            var element = ccm.helper.element(self);

            //Private function which builds the overview and attaches bugs
            var buildOverview = function(dataset){

                // Rendern der Grundstrutkur
                element.html(ccm.helper.html(self.html.get('main')));
                var overview = ccm.helper.find(self, '.bugs-overview');

                // Attach header
                var header = $(ccm.helper.html(
                    self.html.get('header'),
                    {
                        bugIdTitle: "ID",
                        nameTitle: "Name",
                        statusTitle: "Status",
                        subscriberTitle: "Subscriber",
                        descriptionTitle: "Describtion"
                    }
                ));
                header.appendTo(overview);

                //Render all bugs
                var i=0;
                while(dataset[i]){

                    // Create html and wrap in to a jQery object
                    var newBug = $(ccm.helper.html(
                        self.html.get('bug'),
                        {
                            bugId       : dataset[i].bugId,
                            subscriber  : dataset[i].subscriber,
                            description : dataset[i].description,
                            status      : dataset[i].state,
                            name        : dataset[i].name
                        }
                    ));
                    // Append it to overview
                    newBug.appendTo(overview);
                    i++;
                }

                // Append button to overview
                newBug.append("
<button class='new_bug'>Neuer Bug</button>");
                newBug.find('.new_bug').click(function () {
                    overview.html("
Add a new bug ...
" + "<form>" +
                        "Subject"
                        + "<textarea id='subject' name='ta_subject' cols='20' rows='5' required></textarea>"
                        + "
"
                        + "Status"
                        + " <select name='Status'>"
                        + "<option value='neu'>Neu</option>"
                        + "<option value='in_bearb'>in Bearbeitung</option>"
                        + "<option value='umgesetzt'>Umgesetzt</option>"
                        + "</select>"
                        + "
"
                        + "Priorität"
                        + " <select name='Priorität'>"
                        + "<option value='niedrig'>niedrig</option>"
                        + "<option value='mittel'>mittel</option>"
                        + "<option value='hoch'>hoch</option>"
                        + "</select>"
                        + "
"
                        + "<button class='return_to_overview'>Bug-Überblick</button>"
                        + "</form>");
                });
            };

            var onClickStatusHeader = function(){
                if ($(this).hasClass('no-order'))
                {
                    $(this).removeClass('no-order');
                    $(this).addClass('asc');
                    sortStatus(0);
                    return;
                }
                if ($(this).hasClass('asc'))
                {
                    $(this).removeClass('asc');
                    $(this).addClass('desc');
                    sortStatus(1);
                    return;
                }
                if ($(this).hasClass('desc'))
                {
                    $(this).removeClass('desc');
                    $(this).addClass('asc');
                    sortStatus(0);
                }
            };

            var onClickAddBug = function(){
                console.log('Add new Bug!')
                // Ein Beispiel:
                var newBug = {};
//                newBug.bugId = "te3";
//                newBug.context = "testcontext";
//                newBug.subsriber = "hans";
//                newBug.name = "Database broken!";
//                newBug.state = "open";
//                newBug.description = "test description ";
//                self.storeBug(newBug);
            };

            // Fetch data from DB and build overview
            self.remoteStore.get(function(response){
                buildOverview(response);
                //Add status header action
                $('.current-status-header').click(onClickStatusHeader);
                //Add new bug submit action
                // Not the correct button, just checking if it works
                $('.new_bug').click(onClickAddBug);
            });

            if(callback) callback();
        };

        //Public function to save bugs into remote database
        self.storeBug = function(bug){

            self.remoteStore.set({
                "bugId"         : bug.bugId,
                "context"       : bug.context,
                "subscriber"    : bug.subscriber,
                "description"   : bug.description,
                "name"          : bug.name,
                "state"         : bug.state
            });
        };

        self.removeBug = function(bug){
            if (!bug.key){
                console.log('Bug not persisted yet. Skip delete request.');
            }
            self.remoteStore.del(bug.key, function(){
                console.log('Delete bug with key ' + bug.key);
            });
        };

        //Private function to sort bugs after their status
        var sortStatus = function(order){
            //Get overview container
            var overview = $('.bugs-overview');
            //Get all bugs and remove them
            var bugs = overview.find('.bug');
            bugs.remove();

            if(order === 0)
            {
                order = ['open', 'pending', 'closed'];
            } else {
                order = ['closed', 'pending', 'open'];
            }

            order.forEach(function(key){
                bugs.each(function(){
                    if($(this).find('.current-status').html() === key)
                    {
                        $(this).appendTo(overview);
                    }
                });
            });
        };
    }
});
<|endoftext|>


<commit_before>// Copyright 2014-2018, University of Colorado Boulder

/**
 * Constants that are global to this sim.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const Bounds2 = require( 'DOT/Bounds2' );
  const GQColors = require( 'GRAPHING_QUADRATICS/common/GQColors' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const Range = require( 'DOT/Range' );

  // constants
  const PANEL_CORNER_RADIUS = 5; // corner radius for all panel-like containers

  const GQConstants = {

    SCREEN_VIEW_LAYOUT_BOUNDS: new Bounds2( 0, 0, 1100, 700 ),
    SCREEN_VIEW_X_MARGIN: 20,
    SCREEN_VIEW_Y_MARGIN: 16,

    // range of the graph
    X_AXIS_RANGE: new Range( -10, 10 ),
    Y_AXIS_RANGE: new Range( -10, 10 ),

    // options applied to all AccordionBoxes
    ACCORDION_BOX_OPTIONS: {
      resize: false,
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      titleYMargin: 10,
      buttonLength: 25,
      buttonXMargin: 10,
      buttonYMargin: 10,
      contentXMargin: 20,
      contentYMargin: 15
    },

    // options applied to all Panels
    PANEL_OPTIONS: {
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      xMargin: 20,
      yMargin: 15
    },

    // horizontal space between checkbox text and icon
    CHECKBOX_ICON_SPACING: 8,

    // maxWidth for all checkboxes, determined empirically
    CHECKBOX_TEXT_MAX_WIDTH: 180,

    // vertical space between checkboxes
    CHECKBOXES_Y_SPACING: 15,

    PICKER_TOUCH_AREA_X_DILATION: 30,

    // radius of manipulators, in model coordinates
    MANIPULATOR_RADIUS: 0.425,

    // radius of non-interactive points, in model coordinates
    POINT_RADIUS: 0.25,

    // font sizes
    TITLE_FONT_SIZE: 20,
    INTERACTIVE_EQUATION_FONT_SIZE: 26,
    SLIDER_TICK_LABEL_FONT_SIZE: 16,
    CHECKBOX_LABEL_FONT_SIZE: 20,
    CHECKBOX_EQUATION_FONT_SIZE: 22,
    GRAPH_EQUATION_FONT_SIZE: 18,

    // line widths
    INTERACTIVE_QUADRATIC_LINE_WIDTH: 4,
    SAVED_QUADRATIC_LINE_WIDTH: 3,
    QUADRATIC_TERMS_LINE_WIDTH: 2, // y = ax^2, y = bx, y = c
    AXIS_OF_SYMMETRY_LINE_WIDTH: 3,
    DIRECTRIX_LINE_WIDTH: 3,
    POINT_ON_PARABOLA_LINE_WIDTH: 3, // lines that connect point to focus and directrix

    // line dashes
    AXIS_OF_SYMMETRY_LINE_DASH: [ 5, 5 ],
    DIRECTRIX_LINE_DASH: [ 5, 5 ],
    POINT_ON_PARABOLA_LINE_DASH: [ 5, 5 ], // lines that connect point to focus and directrix

    // decimal places
    AXIS_OF_SYMMETRY_DECIMALS: 2,
    DIRECTRIX_DECIMALS: 2,
    FOCUS_DECIMALS: 2,
    POINT_ON_PARABOLA_DECIMALS: 2,
    POINT_TOOL_DECIMALS: 1,
    ROOTS_DECIMALS: 2,
    VERTEX_DECIMALS: 2,
    EXPLORE_DECIMALS_A: 2,
    EXPLORE_DECIMALS_B: 1,
    EXPLORE_DECIMALS_C: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_A: 3,
    FOCUS_AND_DIRECTRIX_DECIMALS_P: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_H: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_K: 1,

    // slider intervals
    EXPLORE_INTERVAL_A: 0.01,
    EXPLORE_INTERVAL_B: 0.1,
    EXPLORE_INTERVAL_C: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_P: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_H: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_K: 0.1,

    // enums
    EQUATION_FORMS: [ 'standard', 'vertex' ], // form of equations on curves
    PROBE_SIDES: [ 'right', 'left' ], // which side the probe is attached to for the point tool

    // margins between equations and edges of graph
    // Caution! Changing these may cause an equation to go off the graph. Test thoroughly!
    EQUATION_X_MARGIN: 1.5, // distance between equation and left/right edges of graph, in model coordinate frame
    EQUATION_Y_MARGIN: 0.5, // distance between equation and top/bottom edges of graph, in model coordinate frame

    // space between equation and the curve that it labels, in view coordinate frame
    EQUATION_SPACING: 5,

    // maxWidth for all coordinates displays (CoordinateNode instances)
    COORDINATES_MAX_WIDTH: 100
  };

  return graphingQuadratics.register( 'GQConstants', GQConstants );
} );
<commit_msg>doc<commit_after>// Copyright 2014-2018, University of Colorado Boulder

/**
 * Constants that are global to this sim.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const Bounds2 = require( 'DOT/Bounds2' );
  const GQColors = require( 'GRAPHING_QUADRATICS/common/GQColors' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const Range = require( 'DOT/Range' );

  // constants
  const PANEL_CORNER_RADIUS = 5; // corner radius for all panel-like containers

  const GQConstants = {

    SCREEN_VIEW_LAYOUT_BOUNDS: new Bounds2( 0, 0, 1100, 700 ),
    SCREEN_VIEW_X_MARGIN: 20,
    SCREEN_VIEW_Y_MARGIN: 16,

    // range of the graph
    X_AXIS_RANGE: new Range( -10, 10 ),
    Y_AXIS_RANGE: new Range( -10, 10 ),

    // options applied to all AccordionBoxes
    ACCORDION_BOX_OPTIONS: {
      resize: false,
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      titleYMargin: 10,
      buttonLength: 25,
      buttonXMargin: 10,
      buttonYMargin: 10,
      contentXMargin: 20,
      contentYMargin: 15
    },

    // options applied to all Panels
    PANEL_OPTIONS: {
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      xMargin: 20,
      yMargin: 15
    },

    // horizontal space between checkbox text and icon
    CHECKBOX_ICON_SPACING: 8,

    // maxWidth for all checkboxes, determined empirically
    CHECKBOX_TEXT_MAX_WIDTH: 180,

    // vertical space between checkboxes
    CHECKBOXES_Y_SPACING: 15,

    PICKER_TOUCH_AREA_X_DILATION: 30,

    // radius of manipulators, in model coordinates
    MANIPULATOR_RADIUS: 0.425,

    // radius of non-interactive points, in model coordinates
    POINT_RADIUS: 0.25,

    // font sizes
    TITLE_FONT_SIZE: 20,
    INTERACTIVE_EQUATION_FONT_SIZE: 26,
    SLIDER_TICK_LABEL_FONT_SIZE: 16,
    CHECKBOX_LABEL_FONT_SIZE: 20,
    CHECKBOX_EQUATION_FONT_SIZE: 22,
    GRAPH_EQUATION_FONT_SIZE: 18,

    // line widths
    INTERACTIVE_QUADRATIC_LINE_WIDTH: 4,
    SAVED_QUADRATIC_LINE_WIDTH: 3,
    QUADRATIC_TERMS_LINE_WIDTH: 2, // y = ax^2, y = bx, y = c
    AXIS_OF_SYMMETRY_LINE_WIDTH: 3,
    DIRECTRIX_LINE_WIDTH: 3,
    POINT_ON_PARABOLA_LINE_WIDTH: 3, // lines that connect point to focus and directrix

    // line dashes
    AXIS_OF_SYMMETRY_LINE_DASH: [ 5, 5 ],
    DIRECTRIX_LINE_DASH: [ 5, 5 ],
    POINT_ON_PARABOLA_LINE_DASH: [ 5, 5 ], // lines that connect point to focus and directrix

    // decimal places
    AXIS_OF_SYMMETRY_DECIMALS: 2,
    DIRECTRIX_DECIMALS: 2,
    FOCUS_DECIMALS: 2,
    POINT_ON_PARABOLA_DECIMALS: 2,
    POINT_TOOL_DECIMALS: 1,
    ROOTS_DECIMALS: 2,
    VERTEX_DECIMALS: 2,
    EXPLORE_DECIMALS_A: 2,
    EXPLORE_DECIMALS_B: 1,
    EXPLORE_DECIMALS_C: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_A: 3,
    FOCUS_AND_DIRECTRIX_DECIMALS_P: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_H: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_K: 1,

    // slider intervals
    EXPLORE_INTERVAL_A: 0.01,
    EXPLORE_INTERVAL_B: 0.1,
    EXPLORE_INTERVAL_C: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_P: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_H: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_K: 0.1,

    // enums
    EQUATION_FORMS: [ 'standard', 'vertex' ], // form of equations on curves
    PROBE_SIDES: [ 'right', 'left' ], // which side the point tool's probe is on

    // margins between equations and edges of graph
    // Caution! Changing these may cause an equation to go off the graph. Test thoroughly!
    EQUATION_X_MARGIN: 1.5, // distance between equation and left/right edges of graph, in model coordinate frame
    EQUATION_Y_MARGIN: 0.5, // distance between equation and top/bottom edges of graph, in model coordinate frame

    // space between equation and the curve that it labels, in view coordinate frame
    EQUATION_SPACING: 5,

    // maxWidth for all coordinates displays (CoordinateNode instances)
    COORDINATES_MAX_WIDTH: 100
  };

  return graphingQuadratics.register( 'GQConstants', GQConstants );
} );
<|endoftext|>


<commit_before>var screens = [];
var maxState = 38;
//figure out a number of turns until the reckoning. make it more than you'd reasonably need to solve it
//so only if they get distracted does it turn deadly.
//each image you unlock has jr make a comment on the image, and gives you a hint about how to
//get to the denizen to have the puzzle just solved for you. (for a price)

window.onload = function() {
	makeScreens(256);
	loadImages(maxState);
	//eventually call makeDistactions AFTER the user clicks "start". because i want to wait for the images to load without bothering with loading code.
	makeDistactions(maxState);
	renderLoop();
}

function renderLoop(){
	for(var i = 0; i<screens.length; i++){
		screens[i].display();
	}
}

//css will handle putting them into a grid, don't worry about it.
function makeScreens(number){
		for(var i = 0; i< number; i++){
			var html = "<canvas class = 'screen' id = 'screen" + i + "' width = '45' height = '45'></canvas>";
			$("#landScreens").append(html);
			screens.push(new Screen(document.getElementById("screen"+i),maxState));
		}
}

function loadImages(lastImage){
	var html = "";
	for(var i = 0; i<= lastImage; i++){
		html += ""
	}
	$("#loading_image_staging").append(html);

}

function makeDistactions(lastImage){
	for(var i = 0; i<= 1; i++){
		makeDistactionChunks(i,"distaction"+i, screens)
	}
}

function Screen(canvas,maxState){
	this.canvas = canvas;
	this.maxState = maxState;
	this.state = 0;
	this.upperLeftX = 0;
	this.upperLeftY = 0;
	this.size = 45; //<-- don't fucking change this.
	this.distactions = []; //just an array of image data.

	this.changeState = function(state){
		if(state < 0){
			state = 0;
		} else if(state > this.maxState){
			state = maxState;
		}else{
			this.state = state;
		}
		display();
	}

	this.display = function(){
			console.log("diaply");
		  var ctx = canvas.getContext('2d');
		  ctx.putImageData(this.distactions[this.state], 0, 0);
	}
}

function makeDistactionChunks(id, imageDiv, screens){
	for(var i = 0; i<screens.length; i++){
		makeDistactionChunk(id, imageDiv, screens[i]);
	}
}

function makeDistactionChunk(id, imageDiv, screen){
		console.log("Making a chunk")
		//draw to secret canvas, then var pixels =ctx.getImageData(0, 0, canvas.width, canvas.height);
		var canvas = getTemporaryCanvas();
		var ctx = canvas.getContext('2d');
		var img=document.getElementById(imageDiv);
		var width = img.width;
		var height = img.height;
		ctx.drawImage(img,0,0,width,height);
		screen.distactions.push(ctx.getImageData(screen.upperLeftX, screen.upperLeftY, screen.size, screen.size));

}

function getTemporaryCanvas(){
	var tmp_canvas = document.createElement('canvas');
	tmp_canvas.height = 720;
	tmp_canvas.width = 720;
	return tmp_canvas;
}
<commit_msg>y is slightly off<commit_after>var screens = [];
var maxState = 38;
//figure out a number of turns until the reckoning. make it more than you'd reasonably need to solve it
//so only if they get distracted does it turn deadly.
//each image you unlock has jr make a comment on the image, and gives you a hint about how to
//get to the denizen to have the puzzle just solved for you. (for a price)

window.onload = function() {
	makeScreens(256);
	loadImages(maxState);
	//eventually call makeDistactions AFTER the user clicks "start". because i want to wait for the images to load without bothering with loading code.
	makeDistactions(maxState);
	renderLoop();
}

function renderLoop(){
	for(var i = 0; i<screens.length; i++){
		screens[i].display();
	}
}

//css will handle putting them into a grid, don't worry about it.
function makeScreens(number){
		for(var i = 0; i< number; i++){
			var html = "<canvas class = 'screen' id = 'screen" + i + "' width = '45' height = '45'></canvas>";
			$("#landScreens").append(html);
			var uX = i%16 * 45;
			var uY = Math.floor(i/16 * 45);
			screens.push(new Screen(document.getElementById("screen"+i),maxState, uX, uY));
		}
}

function loadImages(lastImage){
	var html = "";
	for(var i = 0; i<= lastImage; i++){
		html += ""
	}
	$("#loading_image_staging").append(html);

}

function makeDistactions(lastImage){
	for(var i = 0; i<= 1; i++){
		makeDistactionChunks(i,"distaction"+i, screens)
	}
}

function Screen(canvas,maxState, uX, uY){
	this.canvas = canvas;
	this.maxState = maxState;
	this.state = 0;
	this.upperLeftX = uX;
	this.upperLeftY = uY;
	this.size = 45; //<-- don't fucking change this.
	this.distactions = []; //just an array of image data.

	this.changeState = function(state){
		if(state < 0){
			state = 0;
		} else if(state > this.maxState){
			state = maxState;
		}else{
			this.state = state;
		}
		display();
	}

	this.display = function(){
			console.log("diaply");
		  var ctx = canvas.getContext('2d');
		  ctx.putImageData(this.distactions[this.state], 0, 0);
	}
}

function makeDistactionChunks(id, imageDiv, screens){
	for(var i = 0; i<screens.length; i++){
		makeDistactionChunk(id, imageDiv, screens[i]);
	}
}

function makeDistactionChunk(id, imageDiv, screen){
		//console.log("Making a chunk")
		//draw to secret canvas, then var pixels =ctx.getImageData(0, 0, canvas.width, canvas.height);
		var canvas = getTemporaryCanvas();
		var ctx = canvas.getContext('2d');
		var img=document.getElementById(imageDiv);
		var width = img.width;
		var height = img.height;
		ctx.drawImage(img,0,0,width,height);
		screen.distactions.push(ctx.getImageData(screen.upperLeftX, screen.upperLeftY, screen.size, screen.size));

}

function getTemporaryCanvas(){
	var tmp_canvas = document.createElement('canvas');
	tmp_canvas.height = 720;
	tmp_canvas.width = 720;
	return tmp_canvas;
}
<|endoftext|>


<commit_before>var support = {
  view: function() {
    return [
      m.component(nav, {page: "support"}),
      m.component(supportContactInfo),
      m.component(footer),
    ]
  }
}

var supportContactInfo = {
  view: function() {
    return m(".support-message hero position-under-nav", m("div", [
      m("h2", "Contact Support"),
      m("hr", {class:"hr-gradient"}),
      m("div", [
        m("p", "Our site is still in development, so we don't have resources on our site for sharing bugs and feedback. " +
        "Reach out to us by posting on our subreddit, where our developers and users are regularly active and can respond and address your question or feedback as soon as possible!"),
        m(".reddit-button-container", m("a", {href: "http://reddit/com/r/adventureguild"}, m("button", "/r/adventureguild"))),
      ]),
      m("div", [
        m("p",
          m("strong", "If you have a query or issue related to your account, payments, microtransactions, critical technical difficulties, or otherwise need to contact us privately, please email us at ",
            m("a", {href:"mailto:yesandgames@gmail.com"}, "yesandgames@gmail.com.")
          )
        ),
      ]),
    ]));
  }
}
<commit_msg>fix reddit link<commit_after>var support = {
  view: function() {
    return [
      m.component(nav, {page: "support"}),
      m.component(supportContactInfo),
      m.component(footer),
    ]
  }
}

var supportContactInfo = {
  view: function() {
    return m(".support-message hero position-under-nav", m("div", [
      m("h2", "Contact Support"),
      m("hr", {class:"hr-gradient"}),
      m("div", [
        m("p", "Our site is still in development, so we don't have resources on our site for sharing bugs and feedback. " +
        "Reach out to us by posting on our subreddit, where our developers and users are regularly active and can respond and address your question or feedback as soon as possible!"),
        m(".reddit-button-container", m("a", {href: "http://reddit.com/r/adventureguild"}, m("button", "/r/adventureguild"))),
      ]),
      m("div", [
        m("p",
          m("strong", "If you have a query or issue related to your account, payments, microtransactions, critical technical difficulties, or otherwise need to contact us privately, please email us at ",
            m("a", {href:"mailto:yesandgames@gmail.com"}, "yesandgames@gmail.com.")
          )
        ),
      ]),
    ]));
  }
}
<|endoftext|>


<commit_before>'use strict';
admin
.controller('ConnectionCtrl', ['$scope', 'Connection', 'AlertService',
  function($scope, Connection, AlertService){
    $scope.connections = Connection.query();
    $scope.connection = new Connection();
    $scope.selectConnection = function(c){
      $scope.connection = c;
    };
    $scope.deleteConnection = function(connection){
      Connection.delete(connection);
      $scope.connections.splice($scope.connections.indexOf(connection),1);
    };
    $scope.save = function(){
      if($scope.connection.slug){
        Connection.update({'slug':$scope.connection.slug},$scope.connection);
      }else{
        $scope.connection.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.connections.push(response);
        });
      }
      $scope.connection = new Connection();
    };
    $scope.newForm = function(){
      $scope.connection = new Connection();
    };
  }])
.controller('CubeCtrl', ['$scope', 'Cube', 'Connection', 'AlertService',
  function($scope, Cube, Connection, AlertService){
    $scope.editorOptions = {
        lineWrapping : true,
        lineNumbers: true,
        readOnly: false,
        mode: 'text/x-sql'
    };
    $scope.cube_valid = false;
    $scope.connections = Connection.query();
    $scope.cubes = Cube.query();
    $scope.cube = new Cube();
    $scope.scheduler_types = [
    {key:'minute', val: 'minute'},
    {key:'hour', val: 'hour'},
    {key:'day', val: 'day'}
    ];
    $scope.show_h = false;
    $scope.show_m = false;
    $scope.hour = 0;
    $scope.min = 0;
    $scope.changeSchedulerType = function(){
      if($scope.cube.scheduler_type == 'day'){
        $scope.show_h = true;
        $scope.show_m = true;
      }else if($scope.cube.scheduler_type == 'minute'){
        $scope.show_h = false;
        $scope.show_m = true;
      }else if($scope.cube.scheduler_type == 'hour'){
        $scope.show_h = true;
        $scope.show_m = false;
      }else{
        $scope.show_h = false;
        $scope.show_m = false;
      }
    }
    $scope.selectCube = function(c){
      $scope.cube = c;
      if($scope.cube.scheduler_type == 'day'){
        $scope.show_h = true;
        $scope.show_m = true;
        $scope.hour = parseInt($scope.cube.scheduler_interval.split(':')[0]);
        $scope.min = parseInt($scope.cube.scheduler_interval.split(':')[1]);
      }else if($scope.cube.scheduler_type == 'minute'){
        $scope.min = parseInt($scope.cube.scheduler_interval);
        $scope.show_h = false;
        $scope.show_m = true;
      }else if($scope.cube.scheduler_type == 'hour'){
        $scope.hour = parseInt($scope.cube.scheduler_interval);
        $scope.show_h = true;
        $scope.show_m = false;
      }else{
        $scope.show_h = false;
        $scope.show_m = false;
      }
    };
    $scope.deleteCube = function(cube){
      Cube.delete(cube);
      $scope.cubes.splice($scope.cubes.indexOf(cube),1);
    };
    $scope.save = function(){
      $scope.cube.scheduler_status = false;
      if($scope.cube.scheduler_type){
        if($scope.cube.scheduler_type == 'day'){
          $scope.cube.scheduler_interval = mining.utils.padLeft(parseInt($scope.hour),2) +':'+ mining.utils.padLeft(parseInt($scope.min),2);
        }else if($scope.cube.scheduler_type == 'minute'){
          $scope.cube.scheduler_interval = parseInt($scope.min);
        }else if($scope.cube.scheduler_type == 'hour'){
          $scope.cube.scheduler_interval = parseInt($scope.hour);
        }
      }else{
        $scope.cube.scheduler_status = false;
      }
      if($scope.cube.slug){
        Cube.update({'slug':$scope.cube.slug},$scope.cube);
      }else{
        $scope.cube.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.cubes.push(response);
        });
      }
      $scope.cube = new Cube();
      $scope.show_h = false;
      $scope.show_m = false;
      $scope.hour = 0;
      $scope.min = 0;
    };
    $scope.testquery = function(){
      Cube.testquery($scope.cube, function(response){
        if(response.status == 'success'){
          $scope.cube_valid = true;
          AlertService.add('success', 'Query is Ok!');
        }else{
          AlertService.add('error', 'Query is not Ok!');
        }
      });
    };
    $scope.newForm = function(){
      $scope.cube = new Cube();
      $scope.show_h = false;
      $scope.show_m = false;
      $scope.hour = 0;
      $scope.min = 0;
    };
  }])
.controller('ElementCtrl', ['$scope', 'Cube', 'Element', 'AlertService', '$http',
  function($scope, Cube, Element, AlertService, $http){
    $scope.types = [
    {'slug':"grid","name":"Grid"},
    {'slug':"chart_line", "name":"Chart line"},
    {'slug':"chart_bar","name":"Chart bar"},
    {'slug':"chart_pie","name":"Chart pie"}
    ];
    $scope.cubes = Cube.query();
    $scope.elements = Element.query();
    $scope.element = new Element();
    $scope.fields = [];
    $scope.selectElement = function(e){
      $scope.element = e;
    };
    $scope.deleteElement = function(element){
      Element.delete(element);
      $scope.elements.splice($scope.elements.indexOf(element),1);
    };
    $scope.save = function(element){
      if($scope.element.slug){
        Element.update({'slug':$scope.element.slug},$scope.element);
      }else{
        $scope.element.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.elements.push(response);
        });
      }
      $scope.element = new Element();
    };
    $scope.loadFields = function(){
      if($scope.element.type != 'grid'){
        $http.get('/api/element/cube/'+$scope.element.cube)
        .success(function(retorno){
          $scope.fields = retorno.columns;
        })
        .error(function(retorno){
          AlertService.add('error', 'Error!');
        });
      }
    };
    $scope.newForm = function(){
      $scope.element = new Element();
    };
  }])
.controller('DashboardCtrl', ['$scope', 'Dashboard', 'Element', 'AlertService', '$rootScope',
  function($scope, Dashboard, Element, AlertService, $rootScope){
    $rootScope.dashboards = Dashboard.query();
    $scope.elements = Element.query();
    $scope.dashboard = new Dashboard();
    $scope.selectDashboard = function(d){
      $scope.dashboard = d;
    };
    $scope.deleteElement = function(dashboard){
      Dashboard.delete(dashboard);
      $rootScope.dashboards.splice($rootScope.dashboards.indexOf(dashboard),1);
    };
    $scope.save = function(dashboard){
      if($scope.dashboard.slug){
        Dashboard.update({'slug':$scope.dashboard.slug},$scope.dashboard);
      }else{
        $scope.dashboard.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $rootScope.dashboards.push(response);
        });
      }
      $scope.dashboard = new Dashboard();
    };
    $scope.newForm = function(){
      $scope.dashboard = new Dashboard();
    };
  }])
.controller('UserCtrl', ['$scope', 'User', 'AlertService', 'Dashboard',
  function($scope, User, AlertService, Dashboard){
    $scope.users = User.query();
    $scope.permissions = Dashboard.getFullList();
    $scope.user = new User();
    $scope.editing = false;
    $scope.change_pass = false;
    function clearPermissions(){
      $($scope.permissions).each(function(key, dash){
          dash.permitted = false;
          $(dash.element).each(function(key, elem){
              elem.permitted = false;
          });
      });
    }
    $scope.selectUser = function(us){
      $scope.user = us;
      $scope.editing = true;
      $scope.change_pass = false;
      clearPermissions();
      $($scope.permissions).each(function(key, dash){
        if($scope.user.permissions[dash.slug]){
          dash.permitted = true;
          $(dash.element).each(function(key, elem){
            if($scope.user.permissions[dash.slug].indexOf(elem.slug) >= 0)
              elem.permitted = true;
          });
        }
      });
    };
    $scope.selectDashboard = function(da){
      for(var x=0; x < da.element.length; x++){
        da.element[x].permitted = !da.permitted;
      }
    };
    $scope.deleteUser = function(user){
      User.delete(user);
      $scope.users.splice($scope.users.indexOf(user),1);
      $scope.change_pass = false;
      $scope.editing = false;
      $scope.newForm();
    };
    $scope.changePass = function(user){
      $scope.user = user;
      $scope.editing = false;
      $scope.change_pass = true;
      clearPermissions();
    };
    $scope.save = function(){
      $scope.user.permissions={};
      $($scope.permissions).each(function(key, dash){
        if(dash.permitted){
          $scope.user.permissions[dash.slug]=[];
          $(dash.element).each(function(key, elem){
            if(elem.permitted)
              $scope.user.permissions[dash.slug].push(elem.slug);
          });
        }
      });
      if($scope.editing){
        User.update({'username':$scope.user.username},$scope.user);
      }else{
        $scope.user.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.users.push(response);
        });
      }
      $scope.user = new User();
      $scope.editing = false;
      $scope.change_pass = false;
    };
    $scope.newForm = function(){
      $scope.user = new User();
      $scope.editing = false;
      $scope.change_pass = false;
      clearPermissions();
    };
  }])
;<commit_msg>fix dashboard delete and cube save (sql empty) ref https://github.com/angular-ui/ui-codemirror/issues/35<commit_after>'use strict';
admin
.controller('ConnectionCtrl', ['$scope', 'Connection', 'AlertService',
  function($scope, Connection, AlertService){
    $scope.connections = Connection.query();
    $scope.connection = new Connection();
    $scope.selectConnection = function(c){
      $scope.connection = c;
    };
    $scope.deleteConnection = function(connection){
      Connection.delete(connection);
      $scope.connections.splice($scope.connections.indexOf(connection),1);
    };
    $scope.save = function(){
      if($scope.connection.slug){
        Connection.update({'slug':$scope.connection.slug},$scope.connection);
      }else{
        $scope.connection.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.connections.push(response);
        });
      }
      $scope.connection = new Connection();
    };
    $scope.newForm = function(){
      $scope.connection = new Connection();
    };
  }])
.controller('CubeCtrl', ['$scope', 'Cube', 'Connection', 'AlertService', '$timeout',
  function($scope, Cube, Connection, AlertService, $timeout){
    $scope.editorOptions = {
      lineWrapping : true,
      lineNumbers: true,
      readOnly: false,
      mode: 'text/x-sql',
      onLoad: function(editor) { // FIX TEMP ISSUE: https://github.com/angular-ui/ui-codemirror/issues/35
        editor.on('blur', function() {
          $timeout(function() {
            $scope.cube.sql = editor.getValue();
          });
        })
      }
    };
    $scope.cube_valid = false;
    $scope.connections = Connection.query();
    $scope.cubes = Cube.query();
    $scope.cube = new Cube();
    $scope.scheduler_types = [
    {key:'minute', val: 'minute'},
    {key:'hour', val: 'hour'},
    {key:'day', val: 'day'}
    ];
    $scope.show_h = false;
    $scope.show_m = false;
    $scope.hour = 0;
    $scope.min = 0;
    $scope.changeSchedulerType = function(){
      if($scope.cube.scheduler_type == 'day'){
        $scope.show_h = true;
        $scope.show_m = true;
      }else if($scope.cube.scheduler_type == 'minute'){
        $scope.show_h = false;
        $scope.show_m = true;
      }else if($scope.cube.scheduler_type == 'hour'){
        $scope.show_h = true;
        $scope.show_m = false;
      }else{
        $scope.show_h = false;
        $scope.show_m = false;
      }
    }
    $scope.selectCube = function(c){
      $scope.cube = c;
      if($scope.cube.scheduler_type == 'day'){
        $scope.show_h = true;
        $scope.show_m = true;
        $scope.hour = parseInt($scope.cube.scheduler_interval.split(':')[0]);
        $scope.min = parseInt($scope.cube.scheduler_interval.split(':')[1]);
      }else if($scope.cube.scheduler_type == 'minute'){
        $scope.min = parseInt($scope.cube.scheduler_interval);
        $scope.show_h = false;
        $scope.show_m = true;
      }else if($scope.cube.scheduler_type == 'hour'){
        $scope.hour = parseInt($scope.cube.scheduler_interval);
        $scope.show_h = true;
        $scope.show_m = false;
      }else{
        $scope.show_h = false;
        $scope.show_m = false;
      }
    };
    $scope.deleteCube = function(cube){
      Cube.delete(cube);
      $scope.cubes.splice($scope.cubes.indexOf(cube),1);
    };
    $scope.save = function(){
      $scope.cube.scheduler_status = false;
      if($scope.cube.scheduler_type){
        if($scope.cube.scheduler_type == 'day'){
          $scope.cube.scheduler_interval = mining.utils.padLeft(parseInt($scope.hour),2) +':'+ mining.utils.padLeft(parseInt($scope.min),2);
        }else if($scope.cube.scheduler_type == 'minute'){
          $scope.cube.scheduler_interval = parseInt($scope.min);
        }else if($scope.cube.scheduler_type == 'hour'){
          $scope.cube.scheduler_interval = parseInt($scope.hour);
        }
      }else{
        $scope.cube.scheduler_status = false;
      }
      if($scope.cube.slug){
        Cube.update({'slug':$scope.cube.slug},$scope.cube);
      }else{
        $scope.cube.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.cubes.push(response);
        });
      }
      $scope.cube = new Cube();
      $scope.show_h = false;
      $scope.show_m = false;
      $scope.hour = 0;
      $scope.min = 0;
    };
    $scope.testquery = function(){
      Cube.testquery($scope.cube, function(response){
        if(response.status == 'success'){
          $scope.cube_valid = true;
          AlertService.add('success', 'Query is Ok!');
        }else{
          AlertService.add('error', 'Query is not Ok!');
        }
      });
    };
    $scope.newForm = function(){
      $scope.cube = new Cube();
      $scope.show_h = false;
      $scope.show_m = false;
      $scope.hour = 0;
      $scope.min = 0;
    };
  }])
.controller('ElementCtrl', ['$scope', 'Cube', 'Element', 'AlertService', '$http',
  function($scope, Cube, Element, AlertService, $http){
    $scope.types = [
    {'slug':"grid","name":"Grid"},
    {'slug':"chart_line", "name":"Chart line"},
    {'slug':"chart_bar","name":"Chart bar"},
    {'slug':"chart_pie","name":"Chart pie"}
    ];
    $scope.cubes = Cube.query();
    $scope.elements = Element.query();
    $scope.element = new Element();
    $scope.fields = [];
    $scope.selectElement = function(e){
      $scope.element = e;
    };
    $scope.deleteElement = function(element){
      Element.delete(element);
      $scope.elements.splice($scope.elements.indexOf(element),1);
    };
    $scope.save = function(element){
      if($scope.element.slug){
        Element.update({'slug':$scope.element.slug},$scope.element);
      }else{
        $scope.element.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.elements.push(response);
        });
      }
      $scope.element = new Element();
    };
    $scope.loadFields = function(){
      if($scope.element.type != 'grid'){
        $http.get('/api/element/cube/'+$scope.element.cube)
        .success(function(retorno){
          $scope.fields = retorno.columns;
        })
        .error(function(retorno){
          AlertService.add('error', 'Error!');
        });
      }
    };
    $scope.newForm = function(){
      $scope.element = new Element();
    };
  }])
.controller('DashboardCtrl', ['$scope', 'Dashboard', 'Element', 'AlertService', '$rootScope',
  function($scope, Dashboard, Element, AlertService, $rootScope){
    $rootScope.dashboards = Dashboard.query();
    $scope.elements = Element.query();
    $scope.dashboard = new Dashboard();
    $scope.selectDashboard = function(d){
      $scope.dashboard = d;
    };
    $scope.deleteDashboard = function(dashboard){
      Dashboard.delete(dashboard);
      $rootScope.dashboards.splice($rootScope.dashboards.indexOf(dashboard),1);
    };
    $scope.save = function(dashboard){
      if($scope.dashboard.slug){
        Dashboard.update({'slug':$scope.dashboard.slug},$scope.dashboard);
      }else{
        $scope.dashboard.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $rootScope.dashboards.push(response);
        });
      }
      $scope.dashboard = new Dashboard();
    };
    $scope.newForm = function(){
      $scope.dashboard = new Dashboard();
    };
  }])
.controller('UserCtrl', ['$scope', 'User', 'AlertService', 'Dashboard',
  function($scope, User, AlertService, Dashboard){
    $scope.users = User.query();
    $scope.permissions = Dashboard.getFullList();
    $scope.user = new User();
    $scope.editing = false;
    $scope.change_pass = false;
    $scope.rules = ['user', 'admin', 'root'];
    function clearPermissions(){
      $($scope.permissions).each(function(key, dash){
          dash.permitted = false;
          $(dash.element).each(function(key, elem){
              elem.permitted = false;
          });
      });
    }
    $scope.selectUser = function(us){
      $scope.user = us;
      $scope.editing = true;
      $scope.change_pass = false;
      clearPermissions();
      $($scope.permissions).each(function(key, dash){
        if($scope.user.permissions[dash.slug]){
          dash.permitted = true;
          $(dash.element).each(function(key, elem){
            if($scope.user.permissions[dash.slug].indexOf(elem.slug) >= 0)
              elem.permitted = true;
          });
        }
      });
    };
    $scope.selectDashboard = function(da){
      for(var x=0; x < da.element.length; x++){
        da.element[x].permitted = !da.permitted;
      }
    };
    $scope.deleteUser = function(user){
      User.delete(user);
      $scope.users.splice($scope.users.indexOf(user),1);
      $scope.newForm();
    };
    $scope.changePass = function(user){
      $scope.user = user;
      $scope.editing = false;
      $scope.change_pass = true;
      clearPermissions();
    };
    $scope.save = function(){
      $scope.user.permissions={};
      $($scope.permissions).each(function(key, dash){
        if(dash.permitted){
          $scope.user.permissions[dash.slug]=[];
          $(dash.element).each(function(key, elem){
            if(elem.permitted)
              $scope.user.permissions[dash.slug].push(elem.slug);
          });
        }
      });
      if($scope.editing){
        User.update({'username':$scope.user.username},$scope.user);
      }else{
        $scope.user.$save().then(function(response) {
          AlertService.add('success', 'Save ok');
          $scope.users.push(response);
        });
      }
      $scope.newForm();
    };
    $scope.newForm = function(){
      $scope.user = new User();
      $scope.editing = false;
      $scope.change_pass = false;
      clearPermissions();
    };
  }])
;<|endoftext|>


<commit_before>$( document ).ready(function() {

    /* Helper Functions */

    /**
     * Remove the grid from a chart
     * @param data
     */
    var removeGrid = function(data) {
        if(data.type === 'grid' && data.index !== 0) {
            data.element.remove();
        }
    };

    /* Prepare Data */

    // Create Dummy Data if datasource is not available
    if (typeof getData == "undefined") {
        getData = function() {
            return 'month,total,Phishing,Information leakage\n' +
                'Jan 2016,3,1,2\n' +
                'Feb 2016,4,1,3\n' +
                'Mar 2016,12,8,4\n'
        }
    }

    var csv = getData();
    var data = $.csv.toObjects(csv);

    console.log(data);

    attackTypes = ['Phishing', 'Information leakage', 'Injection attacks' ,'Malicious code',
        'Ransomware/Cryptoware', 'Denial of service', 'Botnets', 'Cyber espionage',
        'Data breaches', 'Hacking/Cracking', 'Overige', 'Anders', 'Niet van toepassing',
        'Spam', 'Illegal content'];

    var monthLabels = [];
    var attacksTotal = [];
    var attacksNumbers = [];

    for(attack of attackTypes) {
        attacksNumbers[attack] = [];
    }

    for (obj of data) {
        monthLabels.push(obj['month']);
        attacksTotal.push(obj['total']);

        for(attackType of attackTypes) {
            attacksNumbers[attackType].push(obj[attackType]);
        }

    }

    /* Configurations */

    var configBig = {
        lineSmooth: false,
        axisY: {
            type: Chartist.AutoScaleAxis,
            low: 0,
            high: 100,
            onlyInteger: true
        }
    };

    var configMini = {
        lineSmooth: false,
        axisY: {
            type: Chartist.AutoScaleAxis,
            low: 0,
            high: 30,
            onlyInteger: true,
            showGrid: false,
        },
        axisX: {
            showLabel: false,
            offset: 0,
        }
    };

    var configMiniLast = {
        lineSmooth: false,
        axisY: {
            type: Chartist.AutoScaleAxis,
            low: 0,
            high: 30,
            onlyInteger: true
        },
    };

    /* Create Charts */

    var charts = [];

    var chartIncidents = new Chartist.Line('#chart-incidents', {
        labels: monthLabels,
        series: [attacksTotal],
    }, configBig);
    charts.push(chartIncidents);

    var attackCounter = 1

    for (var attack of attackTypes) {
        var chartDivId = "chart-" + attack.replace(/\s/g, "").replace(/\//g, "")

        var chartClass, chartConfig;
        // Last Chart should have the months depicted on the X-axis
        if (attackCounter == attackTypes.length) {
            chartClass = "mini-last";
            chartConfig = configMiniLast;
        } else {
            chartClass = "mini";
            chartConfig = configMini;
        }

        // Convert array to contain numbers
        var currAttackNumbers = attacksNumbers[attack].slice().map(Number);

        // Remove last month from array
        var lastMonth = currAttackNumbers.pop();

        // Calculate Mean and Standard Deviation
        var mean = jStat.mean(currAttackNumbers);
        var sd = jStat.stdev(currAttackNumbers, true);

        // Calculate correct trend inicator
        var trendIndicator = $("<i>").addClass("fa fa-lg");
        if (lastMonth >= mean + (3 * sd)) {
            trendIndicator.addClass("fa-arrow-up");
        } else if (lastMonth >= mean + sd) {
            trendIndicator.addClass("fa-arrow-up rotate-45-right");
        } else if (lastMonth <= mean - (3 * sd)) {
            trendIndicator.addClass("fa-arrow-down");
        } else if (lastMonth <= mean - sd) {
            trendIndicator.addClass("fa-arrow-down rotate-45-left");
        } else {
            trendIndicator.addClass("fa-arrow-right");
        }

        // Create DIVs
        var labelDiv = $("<div>").addClass("col-lg-2 vcenter").html(attack.replace(/\//g, "/ "));
        var chartDiv = $("<div>").addClass("col-lg-9 vcenter ct-chart ct-golden-section autoscaleaxis")
            .addClass(chartClass).attr('id', chartDivId);
        var trendDiv = $("<div>").addClass("col-lg-1 vcenter indicator").html(trendIndicator);

        // Add the chart DIV element to the dom
        $("#charts-incidents-type").append(labelDiv);
        $("#charts-incidents-type").append(chartDiv);
        $("#charts-incidents-type").append(trendDiv);

        // Create the new chart
        chart = new Chartist.Line('#' + chartDivId, {
            labels: monthLabels,
            series: [attacksNumbers[attack]],
        }, chartConfig);

        // Add it to the list of charts
        charts.push(chart);

        // Increase the attack counter to make sure classes are set correctly
        attackCounter++;
    }

    // Remove Grid from all charts
    for(chart of charts) {
        chart.on('draw', removeGrid);
    }

});<commit_msg>Summing up 'other' values<commit_after>$( document ).ready(function() {

    /* Helper Functions */

    /**
     * Remove the grid from a chart
     * @param data
     */
    var removeGrid = function(data) {
        if(data.type === 'grid' && data.index !== 0) {
            data.element.remove();
        }
    };

    /* Prepare Data */

    // Create Dummy Data if datasource is not available
    if (typeof getData == "undefined") {
        getData = function() {
            return 'month,total,Phishing,Information leakage\n' +
                'Jan 2016,3,1,2\n' +
                'Feb 2016,4,1,3\n' +
                'Mar 2016,12,8,4\n'
        }
    }

    var csv = getData();
    var data = $.csv.toObjects(csv);

    // attackTypes in the data
    var attackTypesOriginal = ['Phishing', 'Information leakage', 'Injection attacks' ,'Malicious code',
        'Ransomware/Cryptoware', 'Denial of service', 'Botnets', 'Cyber espionage',
        'Data breaches', 'Hacking/Cracking', 'Overige', 'Anders', 'Niet van toepassing',
        'Spam', 'Illegal content'];

    // Summing up 'others'
    var others = ['Overige', 'Anders', 'Niet van toepassing'];
    var other = 'Other'

    var attackTypes = _.without(attackTypesOriginal, others[0], others[1], others[2]);
    attackTypes.push(other);

    var monthLabels = [];
    var attacksTotal = [];
    var attacksNumbers = [];

    for(var attack of attackTypes) {
        attacksNumbers[attack] = [];
    }

    for (obj of data) {
        monthLabels.push(obj['month']);
        attacksTotal.push(obj['total']);

        for(var attackType of attackTypes) {
            // Only work on the non-others values
            if (attackType != other) {
                attacksNumbers[attackType].push(obj[attackType]);
            }
        }

        // Sum up the 'others' values
        var otherValue = parseInt(obj[others[0]]) + parseInt(obj[others[1]]) + parseInt(obj[others[2]]);
        attacksNumbers[other].push(otherValue);

    }

    /* Configurations */

    var configBig = {
        lineSmooth: false,
        axisY: {
            type: Chartist.AutoScaleAxis,
            low: 0,
            high: 100,
            onlyInteger: true
        }
    };

    var configMini = {
        lineSmooth: false,
        axisY: {
            type: Chartist.AutoScaleAxis,
            low: 0,
            high: 30,
            onlyInteger: true,
            showGrid: false,
        },
        axisX: {
            showLabel: false,
            offset: 0,
        }
    };

    var configMiniLast = {
        lineSmooth: false,
        axisY: {
            type: Chartist.AutoScaleAxis,
            low: 0,
            high: 30,
            onlyInteger: true
        },
    };

    /* Create Charts */

    var charts = [];

    var chartIncidents = new Chartist.Line('#chart-incidents', {
        labels: monthLabels,
        series: [attacksTotal],
    }, configBig);
    charts.push(chartIncidents);

    var attackCounter = 1

    for (var attack of attackTypes) {
        var chartDivId = "chart-" + attack.replace(/\s/g, "").replace(/\//g, "")

        var chartClass, chartConfig;
        // Last Chart should have the months depicted on the X-axis
        if (attackCounter == attackTypes.length) {
            chartClass = "mini-last";
            chartConfig = configMiniLast;
        } else {
            chartClass = "mini";
            chartConfig = configMini;
        }

        // Convert array to contain numbers
        var currAttackNumbers = attacksNumbers[attack].slice().map(Number);

        // Remove last month from array
        var lastMonth = currAttackNumbers.pop();

        // Calculate Mean and Standard Deviation
        var mean = jStat.mean(currAttackNumbers);
        var sd = jStat.stdev(currAttackNumbers, true);

        // Calculate correct trend inicator
        var trendIndicator = $("<i>").addClass("fa fa-lg");
        if (lastMonth >= mean + (3 * sd)) {
            trendIndicator.addClass("fa-arrow-up");
        } else if (lastMonth >= mean + sd) {
            trendIndicator.addClass("fa-arrow-up rotate-45-right");
        } else if (lastMonth <= mean - (3 * sd)) {
            trendIndicator.addClass("fa-arrow-down");
        } else if (lastMonth <= mean - sd) {
            trendIndicator.addClass("fa-arrow-down rotate-45-left");
        } else {
            trendIndicator.addClass("fa-arrow-right");
        }

        // Create DIVs
        var labelDiv = $("<div>").addClass("col-lg-2 vcenter").html(attack.replace(/\//g, "/ "));
        var chartDiv = $("<div>").addClass("col-lg-9 vcenter ct-chart ct-golden-section autoscaleaxis")
            .addClass(chartClass).attr('id', chartDivId);
        var trendDiv = $("<div>").addClass("col-lg-1 vcenter indicator").html(trendIndicator);

        // Add the chart DIV element to the dom
        $("#charts-incidents-type").append(labelDiv);
        $("#charts-incidents-type").append(chartDiv);
        $("#charts-incidents-type").append(trendDiv);

        // Create the new chart
        chart = new Chartist.Line('#' + chartDivId, {
            labels: monthLabels,
            series: [attacksNumbers[attack]],
        }, chartConfig);

        // Add it to the list of charts
        charts.push(chart);

        // Increase the attack counter to make sure classes are set correctly
        attackCounter++;
    }

    // Remove Grid from all charts
    for(chart of charts) {
        chart.on('draw', removeGrid);
    }

});<|endoftext|>


<commit_before>//This page handles all resources page content

//encodes any apostrophes in a string into an escape character
function encodeApos (input)
{

  var encoded = input.replace(/'/g, "&apos");
  return encoded;
}

//decodes any apostrophe escapes back into apostrophes
function decodeApos(input)
{
  var decoded= input.replace(/&apos/g, "'");
  return decoded;
}

const auth = firebase.auth();

//authentication state change
auth.onAuthStateChanged(function(firebaseUser) {
	if(firebaseUser) {
		console.log(firebaseUser);
	} else {
		console.log('not logged in');
	}
});

//defines and appends the submit button for the resource modal
function makeModal(input, id)
{
  firebase.auth().signInAnonymously()
 .catch(function(error) {
  console.log(error)
 });
var inputClean = decodeApos(input);

	$('#modalHeading').html("");
	$('#myModal').modal('toggle');
	$('#modalHeading').append("
"+ inputClean +"
");
	console.log(inputClean);

	printReviews(inputClean);

    $("#modalSubmit").append("<input onclick='makeReview(\"" + id + "\")' type='submit' class='btn btn-success btn-send' value='Submit'>");

};

//Loads all resources on page load
window.onload = onLoad();

function onLoad(){
  allResources();

};

//clears filters for new input
function clearResources(){
	document.getElementById('myCounty').value="";
	document.getElementById('myPhase').value="";
	document.getElementById('myService').value="";
	allResources();
};
//Filters all resources
function allResources() {

	//Clears table of resources
	var tableRef = document.getElementById('table_body');
	while ( tableRef.rows.length > 0 )
	{
	 tableRef.deleteRow(0);
	}

	//Pull resources from Firebase database
	rootref.child("Resources").on("child_added", function(snap) {

		var id = snap.key;
		var stringID = id.toString();
		var county = snap.child("county").val();
		var address = snap.child("address").val();
		var name = snap.child("name").val();
		var phone = snap.child("phone").val();
		var contact = snap.child("contact").val();
		var restriction = snap.child("restriction").val();
		var notes = snap.child("notes").val();
		var url = snap.child("url").val();
		var nameCoded = encodeApos(name);

		var aggRate = calcAggregateRating(nameCoded);
		//console.log("" + nameCoded + " " + aggRate + "");

		//Creates table with resources pulled from firebase
		$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							  "	" + restriction + "	" + url +
							  "	" + notes + "
");
		});
};

//Filters resources based on user input
function filterResources() {
		//Clears table of resources
		var tableRef = document.getElementById('table_body');
		while ( tableRef.rows.length > 0 )
		{
		 tableRef.deleteRow(0);
		}

//Grabs user input for filters
var serviceVal = document.getElementById("myService").value;
var phaseVal = document .getElementById("myPhase").value;
var countyVal = document.getElementById("myCounty").value;

//Pull resources from Firebase database
rootref.child("Resources").on("child_added", function(snap) {

	var id = snap.key;
	var stringID = id.toString();
	var county = snap.child("county").val();
	var address = snap.child("address").val();
	var name = snap.child("name").val();
	var phone = snap.child("phone").val();
	var contact = snap.child("contact").val();
	var restriction = snap.child("restriction").val();
	var notes = snap.child("notes").val();
	var url = snap.child("url").val();
	var phase = snap.child("phase").val();
	var service = snap.child("service").val();
	var nameCoded = encodeApos(name);

//creates table based on user inputs
if(countyVal == county && phaseVal == phase && serviceVal == service) {
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == county && phaseVal == false && serviceVal == false){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == county && phaseVal == phase && serviceVal == false){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == county && phaseVal == false && serviceVal == service){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == false && phaseVal == phase && serviceVal == false){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == false && phaseVal == phase && serviceVal == service){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}

else if (countyVal == false && phaseVal == false && serviceVal == service){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}

});
};

function printReviews(input)
{
  var resourceRef = rootref.child("Resources");
  var inputClean = decodeApos(input);

  resourceRef.orderByChild("name").equalTo(inputClean).on("child_added", function(snap)
  {
    snap.child("reviews").forEach(function(shot)
    {

      var user = shot.child("user").val();
      var rating = shot.child("rating").val();
      var rBody = shot.child("text").val();
      if (rating != 0)
      {
	$("#modal_body").append("
" + user + "	" + rating + "

" + rBody+ "
");
      }
    });
  },
  function(error)
  {
    $("#modal_body").append("
Sorry! No one has reviewed this content! Be the first!
")
  });
}

function makeReview(input)
{
  var rBody = document.getElementById("rMaker");
  var score = document.getElementById("rater");
  var userID = document.getElementById("username");
  var inputClean = decodeApos(input);
	var ref;

  rootref.child("Resources").child(input).child("reviews").push().set(
{
	user: "" + userID.value + "",
	rating: "" + score.value + "",
	text: "" + rBody.value + ""

}
);
		window.location.reload()
    auth.signOut();
};

function calcAggregateRating(input)
{
  var i = 0;
  var j = 0;
  var inputClean = decodeApos(input);
  rootref.child("Resources").orderByChild("name").equalTo(inputClean).once("child_added", function(snap)
  {
    snap.child("reviews").forEach(function(shot)
    {
      j = j + shot.child("rating").val();
      i++;
      console.log(inputClean + " " + i + " " + j + "");

    });
  });

  if (i <= 1)
  {
    return 0;
  }
  else
  {
    var aggRating = j/(i-1);
  }

}
<commit_msg>Update firebase-resources.js<commit_after>//This page handles all resources page content

//encodes any apostrophes in a string into an escape character
function encodeApos (input)
{

  var encoded = input.replace(/'/g, "&apos");
  return encoded;
}

//decodes any apostrophe escapes back into apostrophes
function decodeApos(input)
{
  var decoded= input.replace(/&apos/g, "'");
  return decoded;
}

const auth = firebase.auth();

//authentication state change
auth.onAuthStateChanged(function(firebaseUser) {
	if(firebaseUser) {
		console.log(firebaseUser);
	} else {
		console.log('not logged in');
	}
});

//defines and appends the submit button for the resource modal
function makeModal(input, id)
{
  firebase.auth().signInAnonymously()
 .catch(function(error) {
  console.log(error)
 });
var inputClean = decodeApos(input);

	$('#modalHeading').html("");
	$('#myModal').modal('toggle');
	$('#modalHeading').append("
"+ inputClean +"
");
	console.log(inputClean);

	printReviews(inputClean);

    $("#modalSubmit").append("<input onclick='makeReview(\"" + id + "\")' type='submit' class='btn btn-success btn-send' value='Submit'>");

};

//Loads all resources on page load
window.onload = onLoad();

function onLoad(){
  allResources();

};

//clears filters for new input
function clearResources(){
	document.getElementById('myCounty').value="";
	document.getElementById('myPhase').value="";
	document.getElementById('myService').value="";
	allResources();
};
//Filters all resources
function allResources() {

	//Clears table of resources
	var tableRef = document.getElementById('table_body');
	while ( tableRef.rows.length > 0 )
	{
	 tableRef.deleteRow(0);
	}

	//Pull resources from Firebase database
	rootref.child("Resources").on("child_added", function(snap) {

		var id = snap.key;
		var stringID = id.toString();
		var county = snap.child("county").val();
		var address = snap.child("address").val();
		var name = snap.child("name").val();
		var phone = snap.child("phone").val();
		var contact = snap.child("contact").val();
		var restriction = snap.child("restriction").val();
		var notes = snap.child("notes").val();
		var url = snap.child("url").val();
		var nameCoded = encodeApos(name);

		var aggRate = calcAggregateRating(nameCoded);
		//console.log("" + nameCoded + " " + aggRate + "");

		//Creates table with resources pulled from firebase
		$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							  "	" + restriction + "	" + url +
							  "	" + notes + "
");
		});
};

//Filters resources based on user input
function filterResources() {
		//Clears table of resources
		var tableRef = document.getElementById('table_body');
		while ( tableRef.rows.length > 0 )
		{
		 tableRef.deleteRow(0);
		}

//Grabs user input for filters
var serviceVal = document.getElementById("myService").value;
var phaseVal = document .getElementById("myPhase").value;
var countyVal = document.getElementById("myCounty").value;

//Pull resources from Firebase database
rootref.child("Resources").on("child_added", function(snap) {

	var id = snap.key;
	var stringID = id.toString();
	var county = snap.child("county").val();
	var address = snap.child("address").val();
	var name = snap.child("name").val();
	var phone = snap.child("phone").val();
	var contact = snap.child("contact").val();
	var restriction = snap.child("restriction").val();
	var notes = snap.child("notes").val();
	var url = snap.child("url").val();
	var phase = snap.child("phase").val();
	var service = snap.child("service").val();
	var nameCoded = encodeApos(name);

//creates table based on user inputs
if(countyVal == county && phaseVal == phase && serviceVal == service) {
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == county && phaseVal == false && serviceVal == false){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == county && phaseVal == phase && serviceVal == false){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == county && phaseVal == false && serviceVal == service){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == false && phaseVal == phase && serviceVal == false){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}
else if (countyVal == false && phaseVal == phase && serviceVal == service){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}

else if (countyVal == false && phaseVal == false && serviceVal == service){
	$("#table_body").append("
"+ county +"	" + name + "	"+ address +"	"+ phone +"	" + contact +
							"	" + restriction + "	" + url +
							"	" + notes + "
");
}

});
};

function printReviews(input)
{
  var resourceRef = rootref.child("Resources");
  var inputClean = decodeApos(input);

  resourceRef.orderByChild("name").equalTo(inputClean).on("child_added", function(snap)
  {
    snap.child("reviews").forEach(function(shot)
    {

      var user = shot.child("user").val();
      var rating = shot.child("rating").val();
      var rBody = shot.child("text").val();
      if (rating != 0)
      {
	$("#modal_body").append("
" + user + "	" + rating + "

" + rBody+ "
");
      }
    });
  },
  function(error)
  {
    $("#modal_body").append("
Sorry! No one has reviewed this content! Be the first!
")
  });
}

function makeReview(input)
{
  var rBody = document.getElementById("rMaker");
  var score = document.getElementById("rater");
  var userID = document.getElementById("username");
  var inputClean = decodeApos(input);
	var ref;

  rootref.child("Resources").child(input).child("reviews").push().set(
{
	user: "" + userID.value + "",
	rating: "" + score.value + "",
	text: "" + rBody.value + ""

}
);
		window.location.reload()
    auth.signOut();
};

function calcAggregateRating(input)
{
  var i = 0;
  var j = 0;
  var inputClean = decodeApos(input);
  rootref.child("Resources").orderByChild("name").equalTo(inputClean).once("child_added", function(snap)
  {
    snap.child("reviews").forEach(function(shot)
    {
      j = j + shot.child("rating").val();
      i = i+1;
      console.log(inputClean + " " + i + " " + j + "");

    });
  });

  if (i <= 1)
  {
    return 0;
  }
  else
  {
    var aggRating = j/(i-1);
  }

}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2014 Google Inc. 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.
 */

CLASS({
  package: 'foam.ui',
  name: 'DetailView',

  extendsModel: 'foam.ui.View',

  requires: [
    'Property',
    'foam.ui.TextFieldView',
    'foam.ui.IntFieldView',
    'foam.ui.FloatFieldView',
    'foam.ui.DAOController'
  ],
  exports: [ 'propertyViewProperty' ],

  documentation: function() {/*
    When a default view based on $$DOC{ref:'Property'} values is desired, $$DOC{ref:'foam.ui.DetailView'}
    is the place to start. Either using $$DOC{ref:'foam.ui.DetailView'} directly, implementing
    a .toDetailHTML() $$DOC{ref:'Method'} in your model, or extending
    $$DOC{ref:'foam.ui.DetailView'} to add custom formatting.

Set the $$DOC{ref:'.data'} $$DOC{ref:'Property'} to the $$DOC{ref:'Model'} instance
    you want to display. $$DOC{ref:'foam.ui.DetailView'} will extract the $$DOC{ref:'Model'}
    definition, create editors for the $$DOC{ref:'Property',usePlural:true}, and
    display the current values of your instance. Set $$DOC{ref:'.mode',usePlural:true}
    to indicate read-only if desired.

$$DOC{ref:'Model',usePlural:true} may specify a .toDetailHTML() $$DOC{ref:'Method'} or
    $$DOC{ref:'Template'} to render their contents instead of
    $$DOC{ref:'foam.ui.DetailView.defaultToHTML'}.

For each $$DOC{ref:'Property'} in the $$DOC{ref:'.data'} instance specified,
    a $$DOC{ref:'PropertyView'} is created that selects the appropriate $$DOC{ref:'foam.ui.View'}
    to construct.
  */},

  properties: [
    {
      name: 'className',
      defaultValue: 'detailView',
      documentation: function() {/*
          The CSS class names to use for HTML $$DOC{ref:'foam.ui.View',usePlural:true}.
          Separate class names with spaces. Each instance of a $$DOC{ref:'foam.ui.DetailView'}
          may have different classes specified.
      */}
    },
    {
      name: 'data',
      preSet: function(old,nu) {
        if ( nu.model_ ) {
          this.model = nu.model_;
        }
        return nu;
      }
    },
    {
      name:  'model',
      type:  'Model',
    },
    {
      name: 'title',
      defaultValueFn: function() {
        return /*(this.data && this.data.id ? 'Edit ' : 'New ') +*/ this.model.label;
      },
      documentation: function() {/*

The display title for the $$DOC{ref:'foam.ui.View'}.

      */}
    },
    {
      model_: 'StringProperty',
      name: 'mode',
      defaultValue: 'read-write',
      documentation: function() {/*
        The editing mode. To disable editing set to 'read-only'.
      */}
    },
    {
      model_: 'BooleanProperty',
      name: 'showRelationships',
      defaultValue: false,
      documentation: function() {/*
        Set true to create sub-views to display $$DOC{ref:'Relationship',usePlural:true}
        for the $$DOC{ref:'.model'}.
      */}
    },
    {
      name: 'propertyViewProperty',
      type: 'Property',
      defaultValueFn: function() { return this.Property.DETAIL_VIEW; }
    }
  ],

  methods: {
    // Template Method

    shouldDestroy: function(old,nu) {
      if ( ! old || ! old.model_ || ! nu || ! nu.model_ ) return true;
      return old.model_ !== nu.model_;
    },

    generateContent: function() { /* rebuilds the children of the view */
      if ( ! this.$ ) return;
      this.$.outerHTML = this.toHTML();
      this.initHTML();
    },

    titleHTML: function() {
      /* Title text HTML formatter */
      var title = this.title;

      return title ?
        '
' + title + '
' :
        '';
    },

    startForm: function() { /* HTML formatter */ return '
'; },
    endForm: function() { /* HTML formatter */ return '
'; },

    startColumns: function() { /* HTML formatter */ return '

'; },
    nextColumn:   function() { /* HTML formatter */ return '

'; },
    endColumns:   function() { /* HTML formatter */ return '

'; },

    rowToHTML: function(prop, view) {
      /* HTML formatter for each $$DOC{ref:'Property'} row. */
      var str = '';

      if ( prop.detailViewPreRow ) str += prop.detailViewPreRow(this);

      str += '
';
      if ( this.DAOController.isInstance(view) ) {
        str += "
" + prop.label + "
";
        str += view.toHTML();
        str += '	';
      } else {
        str += "" + prop.label + "	";
        str += '';
        str += view.toHTML();
        str += '	';
      }
      str += '
';

      if ( prop.detailViewPostRow ) str += prop.detailViewPostRow(this);

      return str;
    },

    // If the Model supplies a toDetailHTML method, then use it instead.
    toHTML: function() {
      /* Overridden to create the complete HTML content for the $$DOC{ref:'foam.ui.View'}.

$$DOC{ref:'Model',usePlural:true} may specify a .toDetailHTML() $$DOC{ref:'Method'} or
         $$DOC{ref:'Template'} to render their contents instead of the
          $$DOC{ref:'foam.ui.DetailView.defaultToHTML'} we supply here.
      */

      if ( ! this.data ) return '';

      if ( ! this.model ) throw "DetailView: either 'data' or 'model' must be specified.";

      return (this.model.getPrototype().toDetailHTML || this.defaultToHTML).call(this);
    },

    getDefaultProperties: function() {
      return this.model.getRuntimeProperties();
    },

    defaultToHTML: function() {
      /* For $$DOC{ref:'Model',usePlural:true} that don't supply a .toDetailHTML()
        $$DOC{ref:'Method'} or $$DOC{ref:'Template'}, a default listing of
        $$DOC{ref:'Property'} editors is implemented here.
        */
      this.children = [];
      var model = this.model;
      var str  = "";

      str += '
';
      str += this.startForm();
      str += this.titleHTML();

      var properties = this.getDefaultProperties();
      for ( var i = 0 ; i < properties.length ; i++ ) {
        var prop = properties[i];

        if ( prop.hidden ) continue;

        var view = this.createView(prop);
        //view.data$ = this.data$;
        this.addDataChild(view);
        str += this.rowToHTML(prop, view);
      }

      str += this.endForm();

      if ( this.showRelationships ) {
        var view = this.X.lookup('foam.ui.RelationshipsView').create({
          data: this.data
        });
        //view.data$ = this.data$;
        this.addDataChild(view);
        str += view.toHTML();
      }

      str += '
';

      return str;
    }
  },

  templates: [
    {
      name: 'CSS',
      template: function CSS() {/*
          .detailView {
            border: solid 2px #dddddd;
            background: #fafafa;
            display: table;
          }

          .detailView .heading {
            color: black;
            float: left;
            font-size: 16px;
            margin-bottom: 8px;
            padding: 2px;
          }

          .detailView .propertyLabel {
            font-size: 14px;
            display: block;
            font-weight: bold;
            text-align: right;
            float: left;
          }

          .detailView input {
            font-size: 12px;
            padding: 4px 2px;
            border: solid 1px #aacfe4;
            margin: 2px 0 0px 10px;
          }

          .detailView textarea {
            float: left;
            font-size: 12px;
            padding: 4px 2px;
            border: solid 1px #aacfe4;
            margin: 2px 0 0px 10px;
            width: 98%;
            overflow: auto;
          }

          .detailView select {
            font-size: 12px;
            padding: 4px 2px;
            border: solid 1px #aacfe4;
            margin: 2px 0 0px 10px;
          }

          .detailView .label {
            color: #444;
            font-size: smaller;
            padding-left: 6px;
            padding-top: 8px;
            vertical-align: top;
          }

          .detailArrayLabel {
            font-size: medium;
          }

          .detailArrayLabel .foamTable {
            margin: 1px;
          }
      */}
    }
  ]
});
<commit_msg>Added type checking for model property.<commit_after>/**
 * @license
 * Copyright 2014 Google Inc. 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.
 */

CLASS({
  package: 'foam.ui',
  name: 'DetailView',

  extendsModel: 'foam.ui.View',

  requires: [
    'Property',
    'foam.ui.TextFieldView',
    'foam.ui.IntFieldView',
    'foam.ui.FloatFieldView',
    'foam.ui.DAOController'
  ],
  exports: [ 'propertyViewProperty' ],

  documentation: function() {/*
    When a default view based on $$DOC{ref:'Property'} values is desired, $$DOC{ref:'foam.ui.DetailView'}
    is the place to start. Either using $$DOC{ref:'foam.ui.DetailView'} directly, implementing
    a .toDetailHTML() $$DOC{ref:'Method'} in your model, or extending
    $$DOC{ref:'foam.ui.DetailView'} to add custom formatting.

Set the $$DOC{ref:'.data'} $$DOC{ref:'Property'} to the $$DOC{ref:'Model'} instance
    you want to display. $$DOC{ref:'foam.ui.DetailView'} will extract the $$DOC{ref:'Model'}
    definition, create editors for the $$DOC{ref:'Property',usePlural:true}, and
    display the current values of your instance. Set $$DOC{ref:'.mode',usePlural:true}
    to indicate read-only if desired.

$$DOC{ref:'Model',usePlural:true} may specify a .toDetailHTML() $$DOC{ref:'Method'} or
    $$DOC{ref:'Template'} to render their contents instead of
    $$DOC{ref:'foam.ui.DetailView.defaultToHTML'}.

For each $$DOC{ref:'Property'} in the $$DOC{ref:'.data'} instance specified,
    a $$DOC{ref:'PropertyView'} is created that selects the appropriate $$DOC{ref:'foam.ui.View'}
    to construct.
  */},

  properties: [
    {
      name: 'className',
      defaultValue: 'detailView',
      documentation: function() {/*
          The CSS class names to use for HTML $$DOC{ref:'foam.ui.View',usePlural:true}.
          Separate class names with spaces. Each instance of a $$DOC{ref:'foam.ui.DetailView'}
          may have different classes specified.
      */}
    },
    {
      name: 'data',
      preSet: function(old,nu) {
        if ( nu.model_ ) {
          this.model = nu.model_;
        }
        return nu;
      }
    },
    {
      name: 'model',
      // TODO: Add declarative runtime type checking
      preSet: function(_, model) {
        console.assert(Model.isInstance(model), 'Invalid model specified for ' + this.name_);
        return model;
      }
    },
    {
      name: 'title',
      defaultValueFn: function() {
        return /*(this.data && this.data.id ? 'Edit ' : 'New ') +*/ this.model.label;
      },
      documentation: function() {/*

The display title for the $$DOC{ref:'foam.ui.View'}.

      */}
    },
    {
      model_: 'StringProperty',
      name: 'mode',
      defaultValue: 'read-write',
      documentation: function() {/*
        The editing mode. To disable editing set to 'read-only'.
      */}
    },
    {
      model_: 'BooleanProperty',
      name: 'showRelationships',
      defaultValue: false,
      documentation: function() {/*
        Set true to create sub-views to display $$DOC{ref:'Relationship',usePlural:true}
        for the $$DOC{ref:'.model'}.
      */}
    },
    {
      name: 'propertyViewProperty',
      type: 'Property',
      defaultValueFn: function() { return this.Property.DETAIL_VIEW; }
    }
  ],

  methods: {
    // Template Method

    shouldDestroy: function(old,nu) {
      if ( ! old || ! old.model_ || ! nu || ! nu.model_ ) return true;
      return old.model_ !== nu.model_;
    },

    generateContent: function() { /* rebuilds the children of the view */
      if ( ! this.$ ) return;
      this.$.outerHTML = this.toHTML();
      this.initHTML();
    },

    titleHTML: function() {
      /* Title text HTML formatter */
      var title = this.title;

      return title ?
        '
' + title + '
' :
        '';
    },

    startForm: function() { /* HTML formatter */ return '
'; },
    endForm: function() { /* HTML formatter */ return '
'; },

    startColumns: function() { /* HTML formatter */ return '

'; },
    nextColumn:   function() { /* HTML formatter */ return '

'; },
    endColumns:   function() { /* HTML formatter */ return '

'; },

    rowToHTML: function(prop, view) {
      /* HTML formatter for each $$DOC{ref:'Property'} row. */
      var str = '';

      if ( prop.detailViewPreRow ) str += prop.detailViewPreRow(this);

      str += '
';
      if ( this.DAOController.isInstance(view) ) {
        str += "
" + prop.label + "
";
        str += view.toHTML();
        str += '	';
      } else {
        str += "" + prop.label + "	";
        str += '';
        str += view.toHTML();
        str += '	';
      }
      str += '
';

      if ( prop.detailViewPostRow ) str += prop.detailViewPostRow(this);

      return str;
    },

    // If the Model supplies a toDetailHTML method, then use it instead.
    toHTML: function() {
      /* Overridden to create the complete HTML content for the $$DOC{ref:'foam.ui.View'}.

$$DOC{ref:'Model',usePlural:true} may specify a .toDetailHTML() $$DOC{ref:'Method'} or
         $$DOC{ref:'Template'} to render their contents instead of the
          $$DOC{ref:'foam.ui.DetailView.defaultToHTML'} we supply here.
      */

      if ( ! this.data ) return '';

      if ( ! this.model ) throw "DetailView: either 'data' or 'model' must be specified.";

      return (this.model.getPrototype().toDetailHTML || this.defaultToHTML).call(this);
    },

    getDefaultProperties: function() {
      return this.model.getRuntimeProperties();
    },

    defaultToHTML: function() {
      /* For $$DOC{ref:'Model',usePlural:true} that don't supply a .toDetailHTML()
        $$DOC{ref:'Method'} or $$DOC{ref:'Template'}, a default listing of
        $$DOC{ref:'Property'} editors is implemented here.
        */
      this.children = [];
      var model = this.model;
      var str  = "";

      str += '
';
      str += this.startForm();
      str += this.titleHTML();

      var properties = this.getDefaultProperties();
      for ( var i = 0 ; i < properties.length ; i++ ) {
        var prop = properties[i];

        if ( prop.hidden ) continue;

        var view = this.createView(prop);
        //view.data$ = this.data$;
        this.addDataChild(view);
        str += this.rowToHTML(prop, view);
      }

      str += this.endForm();

      if ( this.showRelationships ) {
        var view = this.X.lookup('foam.ui.RelationshipsView').create({
          data: this.data
        });
        //view.data$ = this.data$;
        this.addDataChild(view);
        str += view.toHTML();
      }

      str += '
';

      return str;
    }
  },

  templates: [
    {
      name: 'CSS',
      template: function CSS() {/*
          .detailView {
            border: solid 2px #dddddd;
            background: #fafafa;
            display: table;
          }

          .detailView .heading {
            color: black;
            float: left;
            font-size: 16px;
            margin-bottom: 8px;
            padding: 2px;
          }

          .detailView .propertyLabel {
            font-size: 14px;
            display: block;
            font-weight: bold;
            text-align: right;
            float: left;
          }

          .detailView input {
            font-size: 12px;
            padding: 4px 2px;
            border: solid 1px #aacfe4;
            margin: 2px 0 0px 10px;
          }

          .detailView textarea {
            float: left;
            font-size: 12px;
            padding: 4px 2px;
            border: solid 1px #aacfe4;
            margin: 2px 0 0px 10px;
            width: 98%;
            overflow: auto;
          }

          .detailView select {
            font-size: 12px;
            padding: 4px 2px;
            border: solid 1px #aacfe4;
            margin: 2px 0 0px 10px;
          }

          .detailView .label {
            color: #444;
            font-size: smaller;
            padding-left: 6px;
            padding-top: 8px;
            vertical-align: top;
          }

          .detailArrayLabel {
            font-size: medium;
          }

          .detailArrayLabel .foamTable {
            margin: 1px;
          }
      */}
    }
  ]
});
<|endoftext|>