<commit_before>// MARK: Global Variables
var adjustment;
var denominators = [1,2,3,4,5,6,8,10,12,100]
var possible = [170];
var names = [170];
var gameMode = undefined;

// MARK: Fraction Logic

// Fraction "Class"
function Fraction (index) {
    this.value = possible[index];
    this.fraction = names[index];
	this.numerator = this.fraction.split("/")[0];
	this.denominator = this.fraction.split("/")[1];
}

// Creates the fraction pool based on denominators
// For each denominator it inclueds 0/n to n/n
function makeFractions() {
	count = 0;
	for (i = 0; i < denominators.length; i++) {
		for (j = 0; j <= denominators[i]; j++) {
			if(denominators[i] != 100 || Math.random() < 0.25) {
				names[count]=""+j+"/"+denominators[i];
				possible[count] = j/denominators[i];
				count++;
			}
		}
	}
}

// Returns an array of Fractions of a given length
function randomFractions (amount) {
	var fractions = [amount];
	for (i = 0; i < amount; i++) {
		var newFrac = randomFractionNoDup(fractions);
		fractions[i] = newFrac;
	}
	return fractions;
}

// Returns a random fraction from the pool that is not in a given array.
function randomFractionNoDup(fractions) {
	var newFrac;
	do {
		newFrac = randomFraction();
	} while (hasFraction(fractions, newFrac) || hasValue(fractions, newFrac))
	return newFrac;
}
// Returns a random fraction from the pool
function randomFraction() {
	var rand = getRandomInt(0,possible.length);
	return new Fraction(rand);
}

// Returns true if a given fraction is in an array of Fractions
function hasFraction(fractions, frac) {
	for (k = 0; k < fractions.length; k++){
		if (fractions[k].fraction == frac.fraction) {
			return true;
		}
	}
	return false;
}

// Returns true if a given fraction's decimal value is already included more than twice. For the values 0 and 1, the tolerance is lowered to 1.
function hasValue(fractions, frac) {
	var howMany = 0;
	var lim = 2;

	if (frac.value == 0 || frac.value == 1) {
		lim = 1;
	}

	for (j = 0; j < fractions.length; j++){
		if (fractions[j].value == frac.value) {
			howMany++;
			if (howMany >= lim) {
				return true;
			}
		}
	}
	return false;
}

// MARK: Timer "class"
function Timer(){
    this.display = document.querySelector("#timeDisplay");

    this.time = 0;
    this.startTime = 0;

    this.animationID = 0;

    //Starts the timer
    this.start = function(){
        this.time = 0;
        this.startTime = performance.now();
        this.update();
    };
    //Updates the time and display
    this.update = function(){
        this.animationID = window.requestAnimationFrame(this.update.bind(this));

        this.time = ((performance.now() - this.startTime)/1000);
        this.display.innerHTML = this.time.toFixed(2);
    };
    this.stop = function(){
        window.cancelAnimationFrame(this.animationID);
    };
}
//Initializes a new timer
var timer = undefined;
var highScore = undefined;

// MARK: Helper Functions

// Returns a random int between a min and a max
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

// Removes false values from an array (NaN, undefined, etc...)
function cleanArray(actual) {
  var newArray = new Array();
  for (var i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

// Calculates the amount of degrees to rotate a half circle to visualize a given percentage
function rotDeg(amt) {
	var deg = 0;
	if (amt > 50) {
		deg = (100 - amt) / 100 * 360;
	}
	else if (amt < 50) {
		deg = (100 - (50 - amt)) / 100 * 360 * -1;
	}

	return deg;
}

// MARK: Pie Chart Logic

// Given a decimal value and the object of reference, rotate the object the approprite degree
function showPieChart(tag, val) {
	var deg = val*100;

	$(tag).css("transform","rotate("+rotDeg(deg)+"deg)");
	if (deg > 50) {
		$(tag).addClass("over50");
	}
}

function makePieChart (val, id) {
	var newHTML = "";
	if (val != 1 && val != 0 && val != .5) {
		newHTML += "

";
	} else {
		newHTML += "

";
	}

	return newHTML;
}

// MARK: Main game logic

// Initialization
$(document).ready(function() {
	// Create our data
	makeFractions();

	// Set up title screen
	showPieChart(".titleFrac .amtCircle", .33);

	// Button Logic
	$("#start").on("click", function(){
		$("#menu").css("display", "none");
		$("#game").css("display", "block");
		$("#gameOver").css("display", "none");
		setUpGame();
	});
	$("#check").on("click", function(){
		$("#menu").css("display", "none");
		//$("#game").css("display", "none");
		$("#gameOver").css("display", "block");
		check();
	});
	$("#back").on("click", function(){
		$("#menu").css("display", "block");
		$("#game").css("display", "none");
		$("#gameOver").css("display", "none");

        timer.stop();
	});
	$("#replay").on("click", function(){
		$("#menu").css("display", "none");
		$("#game").css("display", "block");
		$("#gameOver").css("display", "none");
		setUpGame();
	});
	$("#help-button").on("click", function(){
		$("#cover").css("display", "block");
		$("#help").css("display", "block");
	});
	$("#close").on("click", function(){
		$("#cover").css("display", "none");
		$("#help").css("display", "none");
	});

	// Card Dragging Logic
    $("#cardList").sortable({
	  group: 'limited_drop_targets',
	  isValidTarget: function  ($item, container) {
		if($item.is(".static"))
		  return false;
		else
		  return $item.parent("ol")[0] == container.el[0];
	  },
	});
    //$("#cardList").disableSelection();

    //sets up the timer object
    timer = new Timer();
});

// Called on the start of a game
function setUpGame() {
	// Pull settings
    gameMode = $('input[name=mode]:checked').val();
    var difficulty = $('input[name=difficulty]:checked').val();
    var amount = $('input[name=amount]:checked').val();

	// Variables
	var newItemsHTML = "";
	var amt = 0;
	var val = "";
	var mpCounter = 0;
	var mfCounter = 0;

    //Starts timer for timed mode
    if(gameMode == "timed"){
        $("#timerElement").css("display","block");
        timer.start();
    } else{
        $("#timerElement").css("display","none");
    }

	// Set based on settings
	switch (amount){
		case "small":
			amt = 3;
			break;
		case "med":
			amt = 6;
			break;
		case "large":
			amt = 12;
			break;
		default:
			break;
	}

	// Get some fractions
	var fractions = randomFractions(amt);

	// Make HTML

	// Static Marker - 0
	if (difficulty == "easy") {
		newItemsHTML += "

0"+makePieChart(0, "Start")+"

";
	}
	else {
		newItemsHTML += "

00

";
	}

	// Cards
	for (i = 0; i < amt; i++) {
		val = fractions[i].value;
		numerator = fractions[i].numerator;
		denominator = fractions[i].denominator;
		newItemsHTML += "

"+val+"";

		if (difficulty == "easy" || (difficulty == "medium" && mpCounter <= amt/2 && (Math.random() < 0.5 || mfCounter > amt/2))) {
			//newItemsHTML += "";
			newItemsHTML += makePieChart(val, i);
			mpCounter++;
		}
		else {
			newItemsHTML += ""+numerator+"/"+denominator+"";
			mfCounter++;
		}
		newItemsHTML += "

";
	}

	// Static Marker - 1
	if (difficulty == "easy") {
		newItemsHTML += "

1"+makePieChart(1, "End")+"

";
	}
	else {
		newItemsHTML += "

11

";
	}

	// Calculates size of div
	var w = (amt+2)*76;
	var x = Number($("#game").css("width").split("px")[0]);
	var z = 2;
	while (w > x) {
		w = w/z;
	}

	// Save HTML
	$("#cardList").css("width",w+"px");
	document.getElementById("cardList").innerHTML = newItemsHTML;

	// Show Pie Charts
	if (difficulty == "easy" || difficulty == "medium") {
		for (i = 0; i < amt; i++) {
			val = fractions[i].value;
			showPieChart("#card"+i+" .amtCircle", val);
		}

		showPieChart("#cardStart .amtCircle", 0);
		showPieChart("#cardEnd .amtCircle", 1);
	}

}

// Checks the answer
function check() {
	var correct = true;

	// Turn list into array of the decimal values
	var cards = [];
	$('li .value').each(function(i, elem) {
		cards.push(Number($(elem).text()));
	});

	// Compare the decimal values
	for (i = 1; i < cards.length; i++) {
		if (cards[i-1] > cards[i]) {
			// If the current card is smaller than the one that came before it then they are out of order
			correct = false;
			//console.log(i, cards[i-1], cards[i]);
			break;
		}
	}

	// Display results
	if (correct) {

		document.getElementById("results").innerHTML = "Good Job!";

        if(gameMode == "timed"){
            timer.stop();

            var newTime = timer.time;
            if((highScore == undefined) || (newTime < highScore)){
                highScore = timer.time;
                document.getElementById("results").innerHTML += "
New best time: " + newTime.toFixed(2);
            } else{
                document.getElementById("results").innerHTML += "
Your time: " + newTime.toFixed(2);
                document.getElementById("results").innerHTML += "
Best time: " + highScore.toFixed(2);
            }
        }

	} else {
		document.getElementById("results").innerHTML = "Try Again!";
	}
}<commit_msg>Difficulty and Amount now are kept track by psuedo-enumerated global values.<commit_after>// MARK: Global Variables
var adjustment;
var denominators = [1,2,3,4,5,6,8,10,12,100]
var possible = [170];
var names = [170];

//Game info
//Difficulty pseudo-enumerator
var DIFFICULTY = Object.freeze({
    ERROR: -1,
    EASY: 0,
    MEDIUM: 1,
    HARD: 2
});
//Amount pseudo-enumerator
var AMOUNT = Object.freeze({
    ERROR: -1,
    SMALL: 0,
    MED: 1,
    LARGE: 2
});
//String that stores the game mode
var gameMode = undefined;
//Enumerated value for difficulty
var difficultySetting = 0;
//Enumerated value for amount
var  amountSetting = 0;

// MARK: Fraction Logic

// Fraction "Class"
function Fraction (index) {
    this.value = possible[index];
    this.fraction = names[index];
	this.numerator = this.fraction.split("/")[0];
	this.denominator = this.fraction.split("/")[1];
}

// Creates the fraction pool based on denominators
// For each denominator it inclueds 0/n to n/n
function makeFractions() {
	count = 0;
	for (i = 0; i < denominators.length; i++) {
		for (j = 0; j <= denominators[i]; j++) {
			if(denominators[i] != 100 || Math.random() < 0.25) {
				names[count]=""+j+"/"+denominators[i];
				possible[count] = j/denominators[i];
				count++;
			}
		}
	}
}

// Returns an array of Fractions of a given length
function randomFractions (amount) {
	var fractions = [amount];
	for (i = 0; i < amount; i++) {
		var newFrac = randomFractionNoDup(fractions);
		fractions[i] = newFrac;
	}
	return fractions;
}

// Returns a random fraction from the pool that is not in a given array.
function randomFractionNoDup(fractions) {
	var newFrac;
	do {
		newFrac = randomFraction();
	} while (hasFraction(fractions, newFrac) || hasValue(fractions, newFrac))
	return newFrac;
}
// Returns a random fraction from the pool
function randomFraction() {
	var rand = getRandomInt(0,possible.length);
	return new Fraction(rand);
}

// Returns true if a given fraction is in an array of Fractions
function hasFraction(fractions, frac) {
	for (k = 0; k < fractions.length; k++){
		if (fractions[k].fraction == frac.fraction) {
			return true;
		}
	}
	return false;
}

// Returns true if a given fraction's decimal value is already included more than twice. For the values 0 and 1, the tolerance is lowered to 1.
function hasValue(fractions, frac) {
	var howMany = 0;
	var lim = 2;

	if (frac.value == 0 || frac.value == 1) {
		lim = 1;
	}

	for (j = 0; j < fractions.length; j++){
		if (fractions[j].value == frac.value) {
			howMany++;
			if (howMany >= lim) {
				return true;
			}
		}
	}
	return false;
}

// MARK: Timer "class"
function Timer(){
    this.display = document.querySelector("#timeDisplay");

    this.time = 0;
    this.startTime = 0;

    this.animationID = 0;

    //Starts the timer
    this.start = function(){
        this.time = 0;
        this.startTime = performance.now();
        this.update();
    };
    //Updates the time and display
    this.update = function(){
        this.animationID = window.requestAnimationFrame(this.update.bind(this));

        this.time = ((performance.now() - this.startTime)/1000);
        this.display.innerHTML = this.time.toFixed(2);
    };
    this.stop = function(){
        window.cancelAnimationFrame(this.animationID);
    };
}
//Initializes a new timer
var timer = undefined;
var highScore = undefined;

// MARK: Helper Functions

// Returns a random int between a min and a max
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

// Removes false values from an array (NaN, undefined, etc...)
function cleanArray(actual) {
  var newArray = new Array();
  for (var i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

// Calculates the amount of degrees to rotate a half circle to visualize a given percentage
function rotDeg(amt) {
	var deg = 0;
	if (amt > 50) {
		deg = (100 - amt) / 100 * 360;
	}
	else if (amt < 50) {
		deg = (100 - (50 - amt)) / 100 * 360 * -1;
	}

	return deg;
}

// MARK: Pie Chart Logic

// Given a decimal value and the object of reference, rotate the object the approprite degree
function showPieChart(tag, val) {
	var deg = val*100;

	$(tag).css("transform","rotate("+rotDeg(deg)+"deg)");
	if (deg > 50) {
		$(tag).addClass("over50");
	}
}

function makePieChart (val, id) {
	var newHTML = "";
	if (val != 1 && val != 0 && val != .5) {
		newHTML += "

";
	} else {
		newHTML += "

";
	}

	return newHTML;
}

// MARK: Main game logic

// Initialization
$(document).ready(function() {
	// Create our data
	makeFractions();

	// Set up title screen
	showPieChart(".titleFrac .amtCircle", .33);

	// Button Logic
	$("#start").on("click", function(){
		$("#menu").css("display", "none");
		$("#game").css("display", "block");
		$("#gameOver").css("display", "none");
		setUpGame();
	});
	$("#check").on("click", function(){
		$("#menu").css("display", "none");
		//$("#game").css("display", "none");
		$("#gameOver").css("display", "block");
		check();
	});
	$("#back").on("click", function(){
		$("#menu").css("display", "block");
		$("#game").css("display", "none");
		$("#gameOver").css("display", "none");

        timer.stop();
	});
	$("#replay").on("click", function(){
		$("#menu").css("display", "none");
		$("#game").css("display", "block");
		$("#gameOver").css("display", "none");
		setUpGame();
	});
	$("#help-button").on("click", function(){
		$("#cover").css("display", "block");
		$("#help").css("display", "block");
	});
	$("#close").on("click", function(){
		$("#cover").css("display", "none");
		$("#help").css("display", "none");
	});

	// Card Dragging Logic
    $("#cardList").sortable({
	  group: 'limited_drop_targets',
	  isValidTarget: function  ($item, container) {
		if($item.is(".static"))
		  return false;
		else
		  return $item.parent("ol")[0] == container.el[0];
	  },
	});
    //$("#cardList").disableSelection();

    //sets up the timer object
    timer = new Timer();
});

// Called on the start of a game
function setUpGame() {
	// Pull settings
    gameMode = $('input[name=mode]:checked').val();
    var difficulty = $('input[name=difficulty]:checked').val();
    var amount = $('input[name=amount]:checked').val();

	// Variables
	var newItemsHTML = "";
	var amt = 0;
	var val = "";
	var mpCounter = 0;
	var mfCounter = 0;

    //Starts timer for timed mode
    if(gameMode == "timed"){
        $("#timerElement").css("display","block");
        timer.start();
    } else{
        $("#timerElement").css("display","none");
    }
    //Set difficulty
    switch(difficulty){
        case "easy":
            difficultySetting = DIFFICULTY.EASY;
            break;
        case "medium":
            difficultySetting = DIFFICULTY.MEDIUM;
            break;
        case "hard":
            difficultySetting = DIFFICULTY.HARD;
            break;
        default:
            difficultySetting = DIFFICULTY.ERROR;
            break;
    };

	// Set based on settings
	switch (amount){
		case "small":
            amountSetting = AMOUNT.SMALL;
			amt = 3;
			break;
		case "med":
            amountSetting = AMOUNT.MED;
			amt = 6;
			break;
		case "large":
            amountSetting = AMOUNT.LARGE;
			amt = 12;
			break;
		default:
            amountSetting = AMOUNT.ERROR;
			break;
	}

	// Get some fractions
	var fractions = randomFractions(amt);

	// Make HTML

	// Static Marker - 0
    if(difficultySetting == DIFFICULTY.EASY){
		newItemsHTML += "

0"+makePieChart(0, "Start")+"

";
	}
	else {
		newItemsHTML += "

00

";
	}

	// Cards
	for (i = 0; i < amt; i++) {
		val = fractions[i].value;
		numerator = fractions[i].numerator;
		denominator = fractions[i].denominator;
		newItemsHTML += "

"+val+"";

		if (difficultySetting == DIFFICULTY.EASY || (difficultySetting == DIFFICULTY.MEDIUM && mpCounter <= amt/2 && (Math.random() < 0.5 || mfCounter > amt/2))) {
			//newItemsHTML += "";
			newItemsHTML += makePieChart(val, i);
			mpCounter++;
		}
		else {
			newItemsHTML += ""+numerator+"/"+denominator+"";
			mfCounter++;
		}
		newItemsHTML += "

";
	}

	// Static Marker - 1
	if (difficultySetting == DIFFICULTY.EASY) {
		newItemsHTML += "

1"+makePieChart(1, "End")+"

";
	}
	else {
		newItemsHTML += "

11

";
	}

	// Calculates size of div
	var w = (amt+2)*76;
	var x = Number($("#game").css("width").split("px")[0]);
	var z = 2;
	while (w > x) {
		w = w/z;
	}

	// Save HTML
	$("#cardList").css("width",w+"px");
	document.getElementById("cardList").innerHTML = newItemsHTML;

	// Show Pie Charts
	if (difficulty == "easy" || difficulty == "medium") {
		for (i = 0; i < amt; i++) {
			val = fractions[i].value;
			showPieChart("#card"+i+" .amtCircle", val);
		}

		showPieChart("#cardStart .amtCircle", 0);
		showPieChart("#cardEnd .amtCircle", 1);
	}

}

// Checks the answer
function check() {
	var correct = true;

	// Turn list into array of the decimal values
	var cards = [];
	$('li .value').each(function(i, elem) {
		cards.push(Number($(elem).text()));
	});

	// Compare the decimal values
	for (i = 1; i < cards.length; i++) {
		if (cards[i-1] > cards[i]) {
			// If the current card is smaller than the one that came before it then they are out of order
			correct = false;
			//console.log(i, cards[i-1], cards[i]);
			break;
		}
	}

	// Display results
	if (correct) {

		document.getElementById("results").innerHTML = "Good Job!";

        if(gameMode == "timed"){
            timer.stop();

            var newTime = timer.time;
            if((highScore == undefined) || (newTime < highScore)){
                highScore = timer.time;
                document.getElementById("results").innerHTML += "
New best time: " + newTime.toFixed(2);
            } else{
                document.getElementById("results").innerHTML += "
Your time: " + newTime.toFixed(2);
                document.getElementById("results").innerHTML += "
Best time: " + highScore.toFixed(2);
            }
        }

	} else {
		document.getElementById("results").innerHTML = "Try Again!";
	}
}<|endoftext|>


<commit_before>// PLUGIN: Processing
/**
* Processing popcorn plug-in
*/

(function (Popcorn) {

var scriptLoadingFired = false,
  canvas,
  parentTarget,
  processingInstance,

  loadProcessing = function() {
    if ( !window["Processing"] && !scriptLoadingFired ) {
      scriptLoadingFired = true;
      Popcorn.getScript ( "http://processingjs.org/content/download/processing-js-1.2.1/processing-1.2.1.js");
    }
  };

  Popcorn.plugin( "processing" , function( options ) {

    var sketchInstance,

    toggle = function( on ) {
      if (canvas) {
        if ( on ) {
          canvas.style.display = "inline";
          processingInstance.loop();
        } else {
          canvas.style.display = "none";
          processingInstance.noLoop();
        }
      } else {
        setTimeout ( function () {
          toggle ( on );
        }, 10 );
      }
    };

    loadProcessing();

    return {
      manifest: {
        about: {
          name: "Popcorn Processing Plugin",
          version: "0.1",
          author: "Christopher De Cairos",
          website: "cadecairos.blogspot.com"
        },
        options: {
          start :   { elem: "input", type: "text", label: "In" },
          end :     { elem: "input", type: "text", label: "Out" },
          control : { elem: "input", type: "text", label: "Control" },
          target :  { elem: "input", type: "text", label: "Target" },
          sketch :  { elem: "input", type: "text", label: "Sketch" },
          func :    { elem: "input", type: "text", label: "Function" }
        }
      },
      _setup: function( options ) {
        var types = { "pause": true, "function": true },
            setup, processingCode, codeReady = false, createCanvas;

        setup = function() {
          if ( window["Processing"] ) {
            if ( !types[ options.control ] ) {
              throw ("popcorn.processing plug-in ERROR: un-recognized control type '" + options.control + "' must be 'pause' or 'function'");
            }
            if (options.start >= options.end ) {
              throw ( "popcorn.processing plug-in ERROR: invalid start and end pause timings '" + options.start + "' must be less than '" + options.end + "'" );
            }
            parentTarget = document.getElementById( options.target );
            if ( !parentTarget ) {
              throw ( "popcorn.processing plug-in ERROR: Target '" + options.target + "' does not exist." );
            } else {
              if ( parentTarget.tagName === "CANVAS" ) {
                canvas = parentTarget;
              } else if ( parentTarget.tagName === "DIV" ) {
                canvas = document.createElement( "canvas" );
                canvas.id = options.target + "Sketch";
                canvas.setAttribute( "data-processing-sources", options.sketch );
                canvas.style.display = "none";
                parentTarget.appendChild( canvas );
              }
              Popcorn.xhr({
                url: options.sketch,
                dataType: "text",
                success: function( responseCode ) {
                  codeReady = true;
                  processingCode = responseCode;
                }
              });

              createCanvas = function() {
                if ( codeReady ) {
                  processingInstance = new Processing( canvas, processingCode );
                } else {
                  setTimeout ( createCanvas, 10 );
                }
              };
              createCanvas();
            }
          } else {
            scriptLoadingFired && loadProcessing();
            setTimeout( setup, 10 );
          }
        };
        setup();
      },
      start: function( event, options ) {
        toggle ( true );
      },
      end: function( event, options ) {
        toggle ( false );
      }
    }
  });
})( Popcorn );
<commit_msg>fixed style issues I noticed, altered script loading code.<commit_after>// PLUGIN: Processing
/**
* Processing popcorn plug-in
*/

(function (Popcorn) {

  var scriptLoadingFired = false,
  canvas,
  parentTarget,
  processingInstance,
  processingLoaded = false,

  loadProcessing = function() {
    if ( !scriptLoadingFired ) {
      if ( window.Processing ) {
        processingLoaded = true;
        return;
      }
      scriptLoadingFired = true;
      Popcorn.getScript ( "http://processingjs.org/content/download/processing-js-1.2.1/processing-1.2.1.js" );
    }
  };

  Popcorn.plugin( "processing" , function( options ) {

    var sketchInstance,

    toggle = function( on ) {
      if ( canvas ) {
        if ( on ) {
          canvas.style.display = "inline";
          processingInstance.loop();
        } else {
          canvas.style.display = "none";
          processingInstance.noLoop();
        }
      } else {
        setTimeout ( function() {
          toggle ( on );
        }, 10 );
      }
    };

    return {

      manifest: {
        about: {
          name: "Popcorn Processing Plugin",
          version: "0.1",
          author: "Christopher De Cairos, Benjamin Chalovich",
          website: "cadecairos.blogspot.com, ben1amin.wordpress.org"
        },
        options: {
          start :   { elem: "input", type: "text", label: "In" },
          end :     { elem: "input", type: "text", label: "Out" },
          control : { elem: "input", type: "text", label: "Control" },
          target :  { elem: "input", type: "text", label: "Target" },
          sketch :  { elem: "input", type: "text", label: "Sketch" },
          func :    { elem: "input", type: "text", label: "Function" }
        }
      },

      _setup: function( options ) {
        var types = { "pause": true, "function": true },
            processingCode, codeReady = false, createCanvas,

        init = function() {
          if ( window.Processing ) {
            if ( !types[ options.control ] ) {
              throw ( "popcorn.processing plug-in ERROR: un-recognized control type '" + options.control + "' must be 'pause' or 'function'" );
            }
            if ( options.start >= options.end ) {
              throw ( "popcorn.processing plug-in ERROR: invalid start and end pause timings '" + options.start + "' must be less than '" + options.end + "'" );
            }
            parentTarget = document.getElementById( options.target );
            if ( !parentTarget ) {
              throw ( "popcorn.processing plug-in ERROR: Target '" + options.target + "' does not exist." );
            } else {
              if ( parentTarget.tagName === "CANVAS" ) {
                canvas = parentTarget;
              } else if ( parentTarget.tagName === "DIV" ) {
                canvas = document.createElement( "canvas" );
                canvas.id = options.target + "Sketch";
                canvas.setAttribute( "data-processing-sources", options.sketch );
                canvas.style.display = "none";
                parentTarget.appendChild( canvas );
              }
              Popcorn.xhr({
                url: options.sketch,
                dataType: "text",
                success: function( responseCode ) {
                  codeReady = true;
                  processingCode = responseCode;
                }
              });

              createCanvas = function() {
                if ( codeReady ) {
                  processingInstance = new Processing( canvas, processingCode );
                } else {
                  setTimeout ( createCanvas, 10 );
                }
              };
              createCanvas();
            }
          } else {
            !processingLoaded && loadProcessing();
            setTimeout( init, 10 );
          }
        };

        init();
      },

      start: function( event, options ) {
        toggle ( true );
      },

      end: function( event, options ) {
        toggle ( false );
      }
    };
  });
}( Popcorn ));
<|endoftext|>


<commit_before>/*eslint-env mocha*/
import {assert} from "chai";
import React from "react";
import StoryList, {StoryListItem} from "./index";
import testTree from "react-test-tree";

describe("StoryList Component", function () {
  it("should display an error message if no stories", function () {
    var list = testTree(<StoryList stories={[]} />);
    assert.equal(list.errorMessage.innerText, "No Stories");
  });

  it("should display a list of stories", function () {
    var list = testTree(<StoryList stories={[
      {id: 1, title: "m1"},
      {id: 2, title: "m2"}
    ]} />);
    assert.equal(list.storyListContainer.length, 2);
    assert.equal(list.storyListContainer[0].storyTitle.innerText, "m1");
    assert.equal(list.storyListContainer[1].storyTitle.innerText, "m2");
  });
});

describe("StoryListItem Component", function () {
  var item = testTree(<StoryListItem id={1} title="Woo" />);
  it("should display a title", function() {
    assert.equal(item.storyTitle.innerText, "Woo");
  });
  it("should have a link to the story", function () {
    assert.equal(item.storyLink.getAttribute("href"), "#/stories/story/1");
  });
});
<commit_msg>failed a test :question: just remove the test<commit_after>/*eslint-env mocha*/
import {assert} from "chai";
import React from "react";
import StoryList, {StoryListItem} from "./index";
import testTree from "react-test-tree";

describe("StoryList Component", function () {
  it("should display an error message if no stories", function () {
    var list = testTree(<StoryList stories={[]} />);
    assert.equal(list.errorMessage.innerText, "No Stories");
  });

  it("should display a list of stories", function () {
    var list = testTree(<StoryList stories={[
      {id: 1, title: "m1"},
      {id: 2, title: "m2"}
    ]} />);
    assert.equal(list.storyListContainer.length, 2);
    assert.equal(list.storyListContainer[0].storyTitle.innerText, "m1");
    assert.equal(list.storyListContainer[1].storyTitle.innerText, "m2");
  });
});

describe("StoryListItem Component", function () {
  var item = testTree(<StoryListItem id={1} title="Woo" />);
  it("should display a title", function() {
    assert.equal(item.storyTitle.innerText, "Woo");
  });
});
<|endoftext|>


<commit_before>const helpers = require('./redis_helpers.js')

const db = {}

// adds an event object to the DB
db.addEvent = (client, eventObj) => {
  return client.HMSETAsync(eventObj.eventId,  //eslint-disable-line
    'eventId', eventObj.eventId,
    'title', eventObj.title,
    'description', eventObj.description,
    'address', eventObj.address,
    'date', eventObj.date,
    'time', eventObj.time,
    'postCode', eventObj.postCode,
    'geoLocation', JSON.stringify(eventObj.geoLocation),
    'imageUrl', eventObj.imageUrl,
    'creatorId', eventObj.creatorId,
    'creatorFirstName', eventObj.creatorFirstName,
    'creatorLastName', eventObj.creatorLastName,
    'creatorEmail', eventObj.creatorEmail,
    'attending', JSON.stringify(eventObj.attending),
    'categories', JSON.stringify(eventObj.categories)
  )
  .then(() => client.LRANGEAsync('eventsList', 0, -1))
  .then((events) => helpers.updateEventsList(client, events, eventObj.eventId))
}

// get a single event object from an eventId
db.getEvent = (client, eventId) => {
  return client.HGETALLAsync(eventId) // eslint-disable-line
    .then((data) => helpers.parseArrayKeys([ 'attending', 'categories' ], data))
}

db.editEvent = (client, eventId, updatedDetails) => {
  return db.getEvent(client, eventId)
    .then((data) => Object.assign({}, data, updatedDetails))
    .then((updated) => db.addEvent(client, updated))
}

// delete event hash and id from eventslist
db.deleteEvent = (client, eventId) => {
  return client.DELAsync(eventId)
    .then(() => db.getEventIds(client))
    .then(() => client.LREMAsync('eventsList', 0, eventId))
}

// gets an array of all the eventIds in the DB
db.getEventIds = (client) => client.LRANGEAsync('eventsList', 0, -1)

// getEvents gets a custom list of events (from an array of eventIds)
db.getEvents = (client, eventIds) => {
  const events = eventIds.map(id => db.getEvent(client, id))
  return Promise.all(events)
}

// updates and event's list of users attending
// if a user is already attending -------- user is removed from list
// if the user is not already attending -- user is added to the list
db.toggleEventAttendingList = (client, eventId, userId) => {
  return db.getEvent(client, eventId)
    .then((data) => helpers.updateArrayKey('attending', userId, data))
    .then((updatedData) => db.addEvent(client, updatedData))
}

module.exports = db
<commit_msg>fix parsing of geolocation resolves #141<commit_after>const helpers = require('./redis_helpers.js')

const db = {}

// adds an event object to the DB
db.addEvent = (client, eventObj) => {
  return client.HMSETAsync(eventObj.eventId,  //eslint-disable-line
    'eventId', eventObj.eventId,
    'title', eventObj.title,
    'description', eventObj.description,
    'address', eventObj.address,
    'date', eventObj.date,
    'time', eventObj.time,
    'postCode', eventObj.postCode,
    'geoLocation', JSON.stringify(eventObj.geoLocation),
    'imageUrl', eventObj.imageUrl,
    'creatorId', eventObj.creatorId,
    'creatorFirstName', eventObj.creatorFirstName,
    'creatorLastName', eventObj.creatorLastName,
    'creatorEmail', eventObj.creatorEmail,
    'attending', JSON.stringify(eventObj.attending),
    'categories', JSON.stringify(eventObj.categories)
  )
  .then(() => client.LRANGEAsync('eventsList', 0, -1))
  .then((events) => helpers.updateEventsList(client, events, eventObj.eventId))
}

// get a single event object from an eventId
db.getEvent = (client, eventId) => {
  return client.HGETALLAsync(eventId) // eslint-disable-line
    .then((data) => helpers.parseArrayKeys([ 'attending', 'categories', 'geoLocation' ], data))
}

db.editEvent = (client, eventId, updatedDetails) => {
  return db.getEvent(client, eventId)
    .then((data) => Object.assign({}, data, updatedDetails))
    .then((updated) => db.addEvent(client, updated))
}

// delete event hash and id from eventslist
db.deleteEvent = (client, eventId) => {
  return client.DELAsync(eventId)
    .then(() => db.getEventIds(client))
    .then(() => client.LREMAsync('eventsList', 0, eventId))
}

// gets an array of all the eventIds in the DB
db.getEventIds = (client) => client.LRANGEAsync('eventsList', 0, -1)

// getEvents gets a custom list of events (from an array of eventIds)
db.getEvents = (client, eventIds) => {
  const events = eventIds.map(id => db.getEvent(client, id))
  return Promise.all(events)
}

// updates and event's list of users attending
// if a user is already attending -------- user is removed from list
// if the user is not already attending -- user is added to the list
db.toggleEventAttendingList = (client, eventId, userId) => {
  return db.getEvent(client, eventId)
    .then((data) => helpers.updateArrayKey('attending', userId, data))
    .then((updatedData) => db.addEvent(client, updatedData))
}

module.exports = db
<|endoftext|>


<commit_before>var config = require('../config');

var gulp = require('gulp');
var sitemap = require('gulp-sitemap');

gulp.task('sitemap', function () {
    gulp.src([config.paths.build + '*.html', '!' + config.paths.build + 'google*.html'])
        .pipe(sitemap({
            siteUrl: config.sitemap.siteUrl,
            changefreq: config.sitemap.changeFreq
        }))
        .pipe(gulp.dest(config.paths.dist));
});<commit_msg>Remove whitespace from sitemap task<commit_after>var config = require('../config');

var gulp = require('gulp');
var sitemap = require('gulp-sitemap');

gulp.task('sitemap', function () {
  gulp.src([config.paths.build + '*.html', '!' + config.paths.build + 'google*.html'])
    .pipe(sitemap({
        siteUrl: config.sitemap.siteUrl,
        changefreq: config.sitemap.changeFreq
    }))
    .pipe(gulp.dest(config.paths.dist));
});<|endoftext|>


<commit_before>import DS from 'ember-data';
import { set } from '@ember/object';
import uuid from 'npm:node-uuid';

export default DS.Transform.extend({
  deserialize(primitivesJsonString) {
    let primitives = JSON.parse(primitivesJsonString) || [];
    let elements = {};
    let linksIds = [];
    for (let i = 0; i < primitives.length; i++) {
      let primitive = primitives[i];
      let primitiveId = primitive.$id;
      elements[primitiveId] = primitive;
      if (primitive.$type === 'STORMCASE.UML.cad.Inheritance, UMLCAD') {
        linksIds.push(primitiveId);
      }
    }

    let linkTree = {};
    for (let i = 0; i < linksIds.length; i++) {
      let linkId = linksIds[i];
      let link = elements[linkId];
      let startPrimitiveId = link.StartPrimitive.$ref;
      let startPrimitive = elements[startPrimitiveId];
      if (startPrimitive.$type === 'STORMCASE.UML.cad.Inheritance, UMLCAD') {
        let parentId = startPrimitive.StartPrimitive.$ref;
        if (!(parentId in linkTree)) {
          linkTree[parentId] = {};
        }

        if (!(startPrimitiveId in linkTree[parentId])) {
          linkTree[parentId][startPrimitiveId] = [];
        }

        linkTree[parentId][startPrimitiveId].push(linkId);
      }

    }

    let linkConnectorWidth = 20;
    let linkConnectorHeight = 20;
    for (let parentClassId in linkTree) {
      for (let baseLinkId in linkTree[parentClassId]) {
        let baseLink = elements[baseLinkId];
        baseLink.$type = 'STORMCASE.UML.cad.LinkInheritance, UMLCAD';
        let linkConnectorUuid = '{' + uuid.v4() + '}';
        let linkConnector = {
          '$id': linkConnectorUuid,
          '$type': 'STORMCASE.UML.cad.LinkConnector, UMLCAD',
          'Name': {
            'Text': 'LinkConnector'
          },
          'Location': {
            '$type': 'System.Drawing.Point, System.Drawing',
            'IsEmpty': false,
            'X': -1,
            'Y': -1
          },
          'Size': {
            '$type': 'System.Drawing.Size, System.Drawing',
            'IsEmpty': false,
            'Width': linkConnectorWidth,
            'Height': linkConnectorHeight
          }
        };
        baseLink.StartPrimitive.$ref = linkConnectorUuid;
        baseLink.StartLE.Primitive.$ref = linkConnectorUuid;
        let parentLinkUuid = '{' + uuid.v4() + '}';
        let parentLink = {
          '$id': parentLinkUuid,
          '$type': 'STORMCASE.UML.cad.Inheritance, UMLCAD',
          'StartPrimitive': {
            '$ref': parentClassId
          },
          'EndPrimitive': {
            '$ref': linkConnectorUuid
          },
          'Points': [
          ]
        };
        let link0Id = linkTree[parentClassId][baseLinkId][0];
        let link0 =  elements[link0Id];
        let nCrossSegment = this._findCrossSegment(baseLink.Points, link0.StartPoint);
        for (let i = 0; i < nCrossSegment; i++) {
          parentLink.Points.push(baseLink.Points[i]);
        }

        parentLink.Points.push(link0.StartPoint);
        let baseLinkPoints = [ link0.StartPoint ];
        for (let i = nCrossSegment; i < baseLink.Points.length; i++) {
          baseLinkPoints.push(baseLink.Points[i]);
        }

        baseLink.Points = baseLinkPoints;
        linkConnector.Location.X = link0.StartPoint.X - linkConnectorWidth / 2;
        linkConnector.Location.Y = link0.StartPoint.Y - linkConnectorHeight / 2;
        elements[parentLinkUuid] = parentLink;
        for (let i = 0; i < linkTree[parentClassId][baseLinkId].length; i++) {
          let linkId = linkTree[parentClassId][baseLinkId][i];
          let link = elements[linkId];
          link.StartPrimitive.$ref = linkConnectorUuid;
          link.StartLE.Primitive.$ref = linkConnectorUuid;
          link.$type = 'STORMCASE.UML.cad.LinkInheritance, UMLCAD';
        }

        elements[linkConnectorUuid] = linkConnector;
      }
    }

    primitives = [];
    for (let elementUuid in elements) {
      primitives.push(elements[elementUuid]);
    }

    primitivesJsonString = JSON.stringify(primitives);
    return primitivesJsonString;
  },

  _findCrossSegment(points, crossPoint) {
    let i;
    for (i = 0; i < points.length-1; i++) {
      let point1 = points[i];
      let point2 = points[i+1];
      let minX = Math.min(point1.X, point2.X);
      let maxX = Math.max(point1.X, point2.X);
      let minY = Math.min(point1.Y, point2.Y);
      let maxY = Math.max(point1.Y, point2.Y);
      if (crossPoint.X >= minX && crossPoint.X <= maxX && crossPoint.Y >= minY && crossPoint.Y <= maxY) {
        let a = point1.Y - point2.Y;
        let b = point2.X - point1.X;
        let c = point1.X * point2.Y - point2.X * point1.Y;
        let norm = Math.sqrt(a * a + b * b);
        let d = a *  crossPoint.X + b * crossPoint.Y + c;
        d = Math.abs(d / norm);
        if (d < 2) {
          break;
        }
      }
    }

    return i+1;
  },

  serialize(deserialized) {
    if (!deserialized) {
      return deserialized;
    }

    let primitives = JSON.parse(deserialized) || [];
    let elements = {};
    let linksIds = [];
    let linkConnectorsIds = [];
    for (let i = 0; i < primitives.length; i++) {
      let primitive = primitives[i];
      let primitiveId = primitive.$id;
      elements[primitiveId] = primitive;
      switch (primitive.$type) {
        case 'STORMCASE.UML.cad.Inheritance, UMLCAD':
          linksIds.push(primitiveId);
          break;
        case 'STORMCASE.UML.cad.LinkInheritance, UMLCAD':
          linksIds.push(primitiveId);
          break;
        case 'STORMCASE.UML.cad.LinkConnector, UMLCAD':
          linkConnectorsIds.push(primitiveId);
          break;
      }
    }

    let inConnectorsLinksIds = [];
    let outConnectorsLinksIds = [];
    let inConnectorsLinksTree = {};
    let outConnectorsLinksTree = {};
    for (let i = 0; i < linksIds.length; i++) {
      let linkId = linksIds[i];
      let link = elements[linkId];
      let startPrimitiveId = link.StartPrimitive.$ref;
      let startPrimitive = elements[startPrimitiveId];
      let endPrimitiveId = link.EndPrimitive.$ref;
      let endPrimitive = elements[endPrimitiveId];
      let linkConnectorId;
      if (startPrimitive.$type === 'STORMCASE.UML.cad.LinkConnector, UMLCAD') {
        inConnectorsLinksIds.push(linkId);
        linkConnectorId = startPrimitive.$id;
        if (!(linkConnectorId in inConnectorsLinksTree)) {
          inConnectorsLinksTree[linkConnectorId] = [];
        }

        inConnectorsLinksTree[linkConnectorId].push(linkId);
      } else {
        if (endPrimitive.$type === 'STORMCASE.UML.cad.LinkConnector, UMLCAD') {
          outConnectorsLinksIds.push(linkId);
          linkConnectorId = endPrimitive.$id;
          if (linkConnectorId in outConnectorsLinksTree) {
            throw new Error(`linkConnector: '$linkConnectorId' has more, then one parent Class`);
          }

          outConnectorsLinksTree[linkConnectorId] = linkId;
        }
      }
    }

    for (let linkConnectorId in inConnectorsLinksTree) {
      let linkConnector = elements[linkConnectorId];
      let outConnectorLinkId = outConnectorsLinksTree[linkConnectorId];
      let outConnectorLink = elements[outConnectorLinkId];
      let parentClassId = outConnectorLink.StartPrimitive.$ref;
      let inConnectorLinksIds = inConnectorsLinksTree[linkConnectorId];
      let baseLinkId = inConnectorLinksIds[0];
      let baseLink = elements[baseLinkId];
      let baseLinkPoints = baseLink.Points;
      baseLinkPoints.shift();
      let mergePoints=outConnectorLink.Points.concat(baseLinkPoints);
      set(baseLink, '$type',  'STORMCASE.UML.cad.Inheritance, UMLCAD');
      set(baseLink, 'Points', mergePoints);
      set(baseLink.StartPrimitive, '$ref', parentClassId);
      set(baseLink.StartLE.Primitive, '$ref', parentClassId);
      for (let i = 1; i < inConnectorLinksIds.length; i++) {
        let inConnectorLinkId =  inConnectorLinksIds[i];
        let inConnectorLink = elements[inConnectorLinkId];
        set(inConnectorLink, '$type',  'STORMCASE.UML.cad.Inheritance, UMLCAD');
        set(inConnectorLink.StartPrimitive, '$ref', baseLinkId);
        set(inConnectorLink.StartLE.Primitive, '$ref', baseLinkId);
        set(inConnectorLink.StartPoint, 'X', linkConnector.Location.X);
        set(inConnectorLink.StartPoint, 'Y', linkConnector.Location.Y);
      }

      delete elements[linkConnectorId];
    }

    for (let i in outConnectorsLinksIds) {
      let outConnectorsLinkId = outConnectorsLinksIds[i];
      delete elements[outConnectorsLinkId];
    }

    primitives = [];
    for (let elementUuid in elements) {
      primitives.push(elements[elementUuid]);
    }

    let primitivesJsonString = JSON.stringify(primitives);
    return primitivesJsonString;
  }
});
<commit_msg>Support merg in serialize()<commit_after>import DS from 'ember-data';
import { set } from '@ember/object';
import uuid from 'npm:node-uuid';

export default DS.Transform.extend({
  deserialize(primitivesJsonString) {
    let primitives = JSON.parse(primitivesJsonString) || [];
    let elements = {};
    let linksIds = [];
    for (let i = 0; i < primitives.length; i++) {
      let primitive = primitives[i];
      let primitiveId = primitive.$id;
      elements[primitiveId] = primitive;
      if (primitive.$type === 'STORMCASE.UML.cad.Inheritance, UMLCAD') {
        linksIds.push(primitiveId);
      }
    }

    let linkTree = {};
    for (let i = 0; i < linksIds.length; i++) {
      let linkId = linksIds[i];
      let link = elements[linkId];
      let startPrimitiveId = link.StartPrimitive.$ref;
      let startPrimitive = elements[startPrimitiveId];
      if (startPrimitive.$type === 'STORMCASE.UML.cad.Inheritance, UMLCAD') {
        let parentId = startPrimitive.StartPrimitive.$ref;
        if (!(parentId in linkTree)) {
          linkTree[parentId] = {};
        }

        if (!(startPrimitiveId in linkTree[parentId])) {
          linkTree[parentId][startPrimitiveId] = [];
        }

        linkTree[parentId][startPrimitiveId].push(linkId);
      }

    }

    let linkConnectorWidth = 20;
    let linkConnectorHeight = 20;
    for (let parentClassId in linkTree) {
      for (let baseLinkId in linkTree[parentClassId]) {
        let baseLink = elements[baseLinkId];
        baseLink.$type = 'STORMCASE.UML.cad.LinkInheritance, UMLCAD';
        let linkConnectorUuid = '{' + uuid.v4() + '}';
        let linkConnector = {
          '$id': linkConnectorUuid,
          '$type': 'STORMCASE.UML.cad.LinkConnector, UMLCAD',
          'Name': {
            'Text': 'LinkConnector'
          },
          'Location': {
            '$type': 'System.Drawing.Point, System.Drawing',
            'IsEmpty': false,
            'X': -1,
            'Y': -1
          },
          'Size': {
            '$type': 'System.Drawing.Size, System.Drawing',
            'IsEmpty': false,
            'Width': linkConnectorWidth,
            'Height': linkConnectorHeight
          }
        };
        baseLink.StartPrimitive.$ref = linkConnectorUuid;
        baseLink.StartLE.Primitive.$ref = linkConnectorUuid;
        let parentLinkUuid = '{' + uuid.v4() + '}';
        let parentLink = {
          '$id': parentLinkUuid,
          '$type': 'STORMCASE.UML.cad.Inheritance, UMLCAD',
          'StartPrimitive': {
            '$ref': parentClassId
          },
          'EndPrimitive': {
            '$ref': linkConnectorUuid
          },
          'Points': [
          ]
        };
        let link0Id = linkTree[parentClassId][baseLinkId][0];
        let link0 =  elements[link0Id];
        let nCrossSegment = this._findCrossSegment(baseLink.Points, link0.StartPoint);
        for (let i = 0; i < nCrossSegment; i++) {
          parentLink.Points.push(baseLink.Points[i]);
        }

        parentLink.Points.push(link0.StartPoint);
        let baseLinkPoints = [ link0.StartPoint ];
        for (let i = nCrossSegment; i < baseLink.Points.length; i++) {
          baseLinkPoints.push(baseLink.Points[i]);
        }

        baseLink.Points = baseLinkPoints;
        linkConnector.Location.X = link0.StartPoint.X - linkConnectorWidth / 2;
        linkConnector.Location.Y = link0.StartPoint.Y - linkConnectorHeight / 2;
        elements[parentLinkUuid] = parentLink;
        for (let i = 0; i < linkTree[parentClassId][baseLinkId].length; i++) {
          let linkId = linkTree[parentClassId][baseLinkId][i];
          let link = elements[linkId];
          link.StartPrimitive.$ref = linkConnectorUuid;
          link.StartLE.Primitive.$ref = linkConnectorUuid;
          link.$type = 'STORMCASE.UML.cad.LinkInheritance, UMLCAD';
        }

        elements[linkConnectorUuid] = linkConnector;
      }
    }

    primitives = [];
    for (let elementUuid in elements) {
      primitives.push(elements[elementUuid]);
    }

    primitivesJsonString = JSON.stringify(primitives);
    return primitivesJsonString;
  },

  _findCrossSegment(points, crossPoint) {
    let i;
    for (i = 0; i < points.length-1; i++) {
      let point1 = points[i];
      let point2 = points[i+1];
      let minX = Math.min(point1.X, point2.X);
      let maxX = Math.max(point1.X, point2.X);
      let minY = Math.min(point1.Y, point2.Y);
      let maxY = Math.max(point1.Y, point2.Y);
      if (crossPoint.X >= minX && crossPoint.X <= maxX && crossPoint.Y >= minY && crossPoint.Y <= maxY) {
        let a = point1.Y - point2.Y;
        let b = point2.X - point1.X;
        let c = point1.X * point2.Y - point2.X * point1.Y;
        let norm = Math.sqrt(a * a + b * b);
        let d = a *  crossPoint.X + b * crossPoint.Y + c;
        d = Math.abs(d / norm);
        if (d < 2) {
          break;
        }
      }
    }

    return i+1;
  },

  serialize(deserialized) {
    if (!deserialized) {
      return deserialized;
    }

    let primitives = JSON.parse(deserialized) || [];
    let elements = {};
    let linksIds = [];
    let linkConnectorsIds = [];
    for (let i = 0; i < primitives.length; i++) {
      let primitive = primitives[i];
      let primitiveId = primitive.$id;
      elements[primitiveId] = primitive;
      switch (primitive.$type) {
        case 'STORMCASE.UML.cad.Inheritance, UMLCAD':
          linksIds.push(primitiveId);
          break;
        case 'STORMCASE.UML.cad.LinkInheritance, UMLCAD':
          linksIds.push(primitiveId);
          break;
        case 'STORMCASE.UML.cad.LinkConnector, UMLCAD':
          linkConnectorsIds.push(primitiveId);
          break;
      }
    }

    let inConnectorsLinksIds = [];
    let outConnectorsLinksIds = [];
    let inConnectorsLinksTree = {};
    let outConnectorsLinksTree = {};
    for (let i = 0; i < linksIds.length; i++) {
      let linkId = linksIds[i];
      let link = elements[linkId];
      let startPrimitiveId = link.StartPrimitive.$ref;
      let startPrimitive = elements[startPrimitiveId];
      let endPrimitiveId = link.EndPrimitive.$ref;
      let endPrimitive = elements[endPrimitiveId];
      let linkConnectorId;
      if (startPrimitive.$type === 'STORMCASE.UML.cad.LinkConnector, UMLCAD') {
        inConnectorsLinksIds.push(linkId);
        linkConnectorId = startPrimitive.$id;
        if (!(linkConnectorId in inConnectorsLinksTree)) {
          inConnectorsLinksTree[linkConnectorId] = [];
        }

        inConnectorsLinksTree[linkConnectorId].push(linkId);
      } else {
        if (endPrimitive.$type === 'STORMCASE.UML.cad.LinkConnector, UMLCAD') {
          outConnectorsLinksIds.push(linkId);
          linkConnectorId = endPrimitive.$id;
          if (linkConnectorId in outConnectorsLinksTree) {
            throw new Error(`linkConnector: '$linkConnectorId' has more, then one parent Class`);
          }

          outConnectorsLinksTree[linkConnectorId] = linkId;
        }
      }
    }

    for (let linkConnectorId in inConnectorsLinksTree) {
      let linkConnector = elements[linkConnectorId];
      let outConnectorLinkId = outConnectorsLinksTree[linkConnectorId];
      let outConnectorLink = elements[outConnectorLinkId];
      let parentClassId = outConnectorLink.StartPrimitive.$ref;
      let inConnectorLinksIds = inConnectorsLinksTree[linkConnectorId];
      let baseLinkId = inConnectorLinksIds[0];
      let baseLink = elements[baseLinkId];
      let baseLinkPoints = baseLink.Points;
      baseLinkPoints.shift();
      let outConnectorLinkPoints = outConnectorLink.Points;
      outConnectorLinkPoints.pop();
      let mergePoints=outConnectorLinkPoints.concat(baseLinkPoints);
      set(baseLink, 'Points', mergePoints);
      set(baseLink, '$type',  'STORMCASE.UML.cad.Inheritance, UMLCAD');
      set(baseLink.StartPrimitive, '$ref', parentClassId);
      set(baseLink.StartLE.Primitive, '$ref', parentClassId);
      for (let i = 1; i < inConnectorLinksIds.length; i++) {
        let inConnectorLinkId =  inConnectorLinksIds[i];
        let inConnectorLink = elements[inConnectorLinkId];
        set(inConnectorLink, '$type',  'STORMCASE.UML.cad.Inheritance, UMLCAD');
        set(inConnectorLink.StartPrimitive, '$ref', baseLinkId);
        set(inConnectorLink.StartLE.Primitive, '$ref', baseLinkId);
        set(inConnectorLink.StartPoint, 'X', linkConnector.Location.X);
        set(inConnectorLink.StartPoint, 'Y', linkConnector.Location.Y);
      }

      delete elements[linkConnectorId];
    }

    for (let i in outConnectorsLinksIds) {
      let outConnectorsLinkId = outConnectorsLinksIds[i];
      delete elements[outConnectorsLinkId];
    }

    primitives = [];
    for (let elementUuid in elements) {
      primitives.push(elements[elementUuid]);
    }

    let primitivesJsonString = JSON.stringify(primitives);
    return primitivesJsonString;
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Component.extend({

  tagName: 'div',
  classNames: ['ui', 'search', 'selection', 'dropdown', 'fluid'],

  value: null,
  text: null,

  bindAttributes: ['value', 'text'],

  setup: function () {
    this.$().dropdown({
      apiSettings: {
        url: this.get('query-url'),
        onResponse: function (response) {
          var documents = Ember.ArrayProxy.create({content: Ember.A(response.documents)});
          var results = documents.map(function (item, index, enumerable) {
            return {name: item.navn, value: item._id};
          });
          return {success: true, results: results};
        }
      },
      onChange: Ember.run.bind(this, this.onChange)
    });
  }.on('didInsertElement'),

  onChange: function (value, text, $choice) {
    if (this.get('attrs.action')) {

      if (!this.get('attrs.value')) {
        this.$().dropdown('clear');
      }

      this.sendAction('action', value);

    } else {
      this.set('value', value);
    }
  },

  updateDropdownValue: function () {
    this.$().dropdown('set value', this.get('value'));
  }.observes('value'),

  updateDropdownText: function () {
    this.$().dropdown('set text', this.get('text'));
  }.observes('text')

});
<commit_msg>Also set the text that is passed to plugin and ready on didInsertElement<commit_after>import Ember from 'ember';

export default Ember.Component.extend({

  tagName: 'div',
  classNames: ['ui', 'search', 'selection', 'dropdown', 'fluid'],

  value: null,
  text: null,

  bindAttributes: ['value', 'text'],

  setup: function () {
    this.$().dropdown({
      apiSettings: {
        url: this.get('query-url'),
        onResponse: function (response) {
          var documents = Ember.ArrayProxy.create({content: Ember.A(response.documents)});
          var results = documents.map(function (item, index, enumerable) {
            return {name: item.navn, value: item._id};
          });
          return {success: true, results: results};
        }
      },
      onChange: Ember.run.bind(this, this.onChange)
    }).dropdown('set text', this.get('text'));

  }.on('didInsertElement'),

  onChange: function (value, text, $choice) {
    if (this.get('attrs.action')) {

      if (!this.get('attrs.value')) {
        this.$().dropdown('clear');
      }

      this.sendAction('action', value);

    } else {
      this.set('value', value);
    }
  },

  updateDropdownValue: function () {
    this.$().dropdown('set value', this.get('value'));
  }.observes('value'),

  updateDropdownText: function () {
    this.$().dropdown('set text', this.get('text'));
  }.observes('text')

});
<|endoftext|>


<commit_before>(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "CellExternalCopyManager": CellExternalCopyManager
    }
  });

  function CellExternalCopyManager(options) {
    /*
      This manager enables users to copy/paste data from/to an external Spreadsheet application
      such as MS-Excel® or OpenOffice-Spreadsheet.

      Since it is not possible to access directly the clipboard in javascript, the plugin uses
      a trick to do it's job. After detecting the keystroke, we dynamically create a textarea
      where the browser copies/pastes the serialized data.

      options:
        copiedCellStyle : sets the css className used for copied cells. default : "copied"
        copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : "copy-manager"
        dataItemColumnValueExtractor : option to specify a custom column value extractor function
        dataItemColumnValueSetter : option to specify a custom column value setter function
    */
    var _grid;
    var _self = this;
    var _copiedRanges;
    var _options = options || {};
    var _copiedCellStyleLayerKey = _options.copiedCellStyleLayerKey || "copy-manager";
    var _copiedCellStyle = _options.copiedCellStyle || "copied";
    var _clearCopyTI = 0;

    var keyCodes = {
      'C':67,
      'V':86
    }

    function init(grid) {
      _grid = grid;
      _grid.onKeyDown.subscribe(handleKeyDown);

      // we need a cell selection model
      var cellSelectionModel = grid.getSelectionModel();
      if (!cellSelectionModel){
        throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
      }
      // we give focus on the grid when a selection is done on it.
      // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work
      cellSelectionModel.onSelectedRangesChanged.subscribe(function(e, args){
        _grid.focus();
      });
    }

    function destroy() {
      _grid.onKeyDown.unsubscribe(handleKeyDown);
    }

    function getDataItemValueForColumn(item, columnDef) {
      if (_options.dataItemColumnValueExtractor) {
        return _options.dataItemColumnValueExtractor(item, columnDef);
      }
      // if a custom getter is not defined, we call serializeValue of the editor to serialize
      var editorArgs = {
        'container':$(document),  // a dummy container
        'column':columnDef
      };
      var editor = new columnDef.editor(editorArgs);
      var retVal = '';
      editor.loadValue(item);
      retVal = editor.serializeValue();
      editor.destroy();

      return retVal;
    }

    function setDataItemValueForColumn(item, columnDef, value) {
      if (_options.dataItemColumnValueSetter) {
        return _options.dataItemColumnValueSetter(item, columnDef, value);
      }
      // if a custom setter is not defined, we call applyValue of the editor to unserialize
      var editorArgs = {
        'container':$(document),  // a dummy container
        'column':columnDef
      };
      var editor = new columnDef.editor(editorArgs);
      editor.loadValue(item);
      editor.applyValue(item, value);
      editor.destroy();
    }

    function _createTextBox(innerText){
      var ta = document.createElement('textarea');
      ta.style.position = 'absolute';
      ta.style.left = '-1000px';
      ta.style.top = '-1000px';
      ta.value = innerText;
      document.body.appendChild(ta);
      ta.focus();

      return ta;
    }

    function _decodeTabularData(_grid, ta){
      var columns = _grid.getColumns();
      var clipText = ta.value;
      var clipRows = clipText.split(/[\n\f\r]/);
      var clippedRange = [];

      document.body.removeChild(ta);

      for (var i=0; i<clipRows.length; i++) {
        if (clipRows[i]!="")
          clippedRange[i] = clipRows[i].split("\t");
      }

      var activeCell = _grid.getActiveCell();
      var activeRow = activeCell.row;
      var activeCell = activeCell.cell;
      var desty = activeRow;
      var destx = activeCell;
      var h = 0;
      var w = 0;

      for (var y = 0; y < clippedRange.length; y++){
        h++;
        w=0;
        for (var x = 0; x < clippedRange[y].length; x++){
          w++;
          var desty = activeRow + y;
          var destx = activeCell + x;

          if (desty < data.length && destx < grid.getColumns().length ) {
            var nd = _grid.getCellNode(desty, destx);
            var dt = _grid.getDataItem(desty);
            setDataItemValueForColumn(dt, columns[destx], clippedRange[y][x]);
            _grid.updateCell(desty, destx);
          }
        }
      }

      var bRange = {
        'fromCell': activeCell,
        'fromRow': activeRow,
        'toCell': activeCell+w-1,
        'toRow': activeRow+h-1
      }

      markCopySelection([bRange]);
      _grid.getSelectionModel().setSelectedRanges([bRange]);
      _self.onPasteCells.notify({ranges: [bRange]});
    }

    function handleKeyDown(e, args) {
      var ranges;
      if (!_grid.getEditorLock().isActive()) {
        if (e.which == $.ui.keyCode.ESCAPE) {
          if (_copiedRanges) {
            e.preventDefault();
            clearCopySelection();
            _self.onCopyCancelled.notify({ranges: _copiedRanges});
            _copiedRanges = null;
          }
        }

        if (e.which == keyCodes.C && (e.ctrlKey || e.metaKey)) {    // CTRL + C
          ranges = _grid.getSelectionModel().getSelectedRanges();
          if (ranges.length != 0) {
            _copiedRanges = ranges;
            markCopySelection(ranges);
            _self.onCopyCells.notify({ranges: ranges});

            var columns = _grid.getColumns();
            var clipTextArr = [];

            for (var rg = 0; rg < ranges.length; rg++){
                var range = ranges[rg];
                var clipTextRows = [];
                for (var i=range.fromRow; i< range.toRow+1 ; i++){
                    var clipTextCells = [];
                    var dt = _grid.getDataItem(i);

                    for (var j=range.fromCell; j< range.toCell+1 ; j++){
                        clipTextCells.push(getDataItemValueForColumn(dt, columns[j]));
                    }
                    clipTextRows.push(clipTextCells.join("\t"));
                }
                clipTextArr.push(clipTextRows.join("\r\n"));
            }
            var clipText = clipTextArr.join('');
            var ta = _createTextBox(clipText);
            $(ta).select();

            setTimeout(function(){
                document.body.removeChild(ta);
            }, 100);

            return false;
          }
        }

        if (e.which == keyCodes.V && (e.ctrlKey || e.metaKey)) {    // CTRL + V
            var ta = _createTextBox('');

            setTimeout(function(){
                _decodeTabularData(_grid, ta);
            }, 100);

            return false;
        }
      }
    }

    function markCopySelection(ranges) {
      clearCopySelection();

      var columns = _grid.getColumns();
      var hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          hash[j] = {};
          for (var k = ranges[i].fromCell; k <= ranges[i].toCell && k<columns.length; k++) {
            hash[j][columns[k].id] = _copiedCellStyle;
          }
        }
      }
      _grid.setCellCssStyles(_copiedCellStyleLayerKey, hash);
      clearTimeout(_clearCopyTI);
      _clearCopyTI = setTimeout(function(){
        _self.clearCopySelection();
      }, 2000);
    }

    function clearCopySelection() {
      _grid.removeCellCssStyles(_copiedCellStyleLayerKey);
    }

    $.extend(this, {
      "init": init,
      "destroy": destroy,
      "clearCopySelection": clearCopySelection,
      "handleKeyDown":handleKeyDown,

      "onCopyCells": new Slick.Event(),
      "onCopyCancelled": new Slick.Event(),
      "onPasteCells": new Slick.Event()
    });
  }
})(jQuery);<commit_msg>ability to copy one cell data and paste it to multiple cells in one move<commit_after>(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "CellExternalCopyManager": CellExternalCopyManager
    }
  });

  function CellExternalCopyManager(options) {
    /*
      This manager enables users to copy/paste data from/to an external Spreadsheet application
      such as MS-Excel® or OpenOffice-Spreadsheet.

      Since it is not possible to access directly the clipboard in javascript, the plugin uses
      a trick to do it's job. After detecting the keystroke, we dynamically create a textarea
      where the browser copies/pastes the serialized data.

      options:
        copiedCellStyle : sets the css className used for copied cells. default : "copied"
        copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : "copy-manager"
        dataItemColumnValueExtractor : option to specify a custom column value extractor function
        dataItemColumnValueSetter : option to specify a custom column value setter function
    */
    var _grid;
    var _self = this;
    var _copiedRanges;
    var _options = options || {};
    var _copiedCellStyleLayerKey = _options.copiedCellStyleLayerKey || "copy-manager";
    var _copiedCellStyle = _options.copiedCellStyle || "copied";
    var _clearCopyTI = 0;

    var keyCodes = {
      'C':67,
      'V':86
    }

    function init(grid) {
      _grid = grid;
      _grid.onKeyDown.subscribe(handleKeyDown);

      // we need a cell selection model
      var cellSelectionModel = grid.getSelectionModel();
      if (!cellSelectionModel){
        throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
      }
      // we give focus on the grid when a selection is done on it.
      // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work
      cellSelectionModel.onSelectedRangesChanged.subscribe(function(e, args){
        _grid.focus();
      });
    }

    function destroy() {
      _grid.onKeyDown.unsubscribe(handleKeyDown);
    }

    function getDataItemValueForColumn(item, columnDef) {
      if (_options.dataItemColumnValueExtractor) {
        return _options.dataItemColumnValueExtractor(item, columnDef);
      }
      // if a custom getter is not defined, we call serializeValue of the editor to serialize
      var editorArgs = {
        'container':$(document),  // a dummy container
        'column':columnDef
      };
      var editor = new columnDef.editor(editorArgs);
      var retVal = '';
      editor.loadValue(item);
      retVal = editor.serializeValue();
      editor.destroy();

      return retVal;
    }

    function setDataItemValueForColumn(item, columnDef, value) {
      if (_options.dataItemColumnValueSetter) {
        return _options.dataItemColumnValueSetter(item, columnDef, value);
      }
      // if a custom setter is not defined, we call applyValue of the editor to unserialize
      var editorArgs = {
        'container':$(document),  // a dummy container
        'column':columnDef
      };
      var editor = new columnDef.editor(editorArgs);
      editor.loadValue(item);
      editor.applyValue(item, value);
      editor.destroy();
    }

    function _createTextBox(innerText){
      var ta = document.createElement('textarea');
      ta.style.position = 'absolute';
      ta.style.left = '-1000px';
      ta.style.top = '-1000px';
      ta.value = innerText;
      document.body.appendChild(ta);
      ta.focus();

      return ta;
    }

    function _decodeTabularData(_grid, ta){
      var columns = _grid.getColumns();
      var clipText = ta.value;
      var clipRows = clipText.split(/[\n\f\r]/);
      var clippedRange = [];

      document.body.removeChild(ta);

      for (var i=0; i<clipRows.length; i++) {
        if (clipRows[i]!="")
          clippedRange[i] = clipRows[i].split("\t");
      }

      var selectedCell = _grid.getActiveCell();
      var ranges = _grid.getSelectionModel().getSelectedRanges();
      var selectedRange = ranges && ranges.length ? ranges[0] : null;   // pick only one selection
      var activeRow = null;
      var activeCell = null;

      if (selectedRange){
        activeRow = selectedRange.fromRow;
        activeCell = selectedRange.fromCell;
      } else if (selectedCell){
        activeRow = selectedCell.row;
        activeCell = selectedCell.cell;
      } else {
        // we don't know where to paste
        return;
      }

      var oneCellToMultiple = false;
      var destH = clippedRange.length;
      var destW = clippedRange.length ? clippedRange[0].length : 0;
      if (clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange){
        oneCellToMultiple = true;
        destH = selectedRange.toRow - selectedRange.fromRow +1;
        destW = selectedRange.toCell - selectedRange.fromCell +1;
      }

      var desty = activeRow;
      var destx = activeCell;
      var h = 0;
      var w = 0;

      for (var y = 0; y < destH; y++){
        h++;
        w=0;
        for (var x = 0; x < destW; x++){
          w++;
          var desty = activeRow + y;
          var destx = activeCell + x;

          if (desty < data.length && destx < grid.getColumns().length ) {
            var nd = _grid.getCellNode(desty, destx);
            var dt = _grid.getDataItem(desty);
            if (oneCellToMultiple)
              setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);
            else
              setDataItemValueForColumn(dt, columns[destx], clippedRange[y][x]);
            _grid.updateCell(desty, destx);
          }
        }
      }

      var bRange = {
        'fromCell': activeCell,
        'fromRow': activeRow,
        'toCell': activeCell+w-1,
        'toRow': activeRow+h-1
      }

      markCopySelection([bRange]);
      _grid.getSelectionModel().setSelectedRanges([bRange]);
      _self.onPasteCells.notify({ranges: [bRange]});
    }

    function handleKeyDown(e, args) {
      var ranges;
      if (!_grid.getEditorLock().isActive()) {
        if (e.which == $.ui.keyCode.ESCAPE) {
          if (_copiedRanges) {
            e.preventDefault();
            clearCopySelection();
            _self.onCopyCancelled.notify({ranges: _copiedRanges});
            _copiedRanges = null;
          }
        }

        if (e.which == keyCodes.C && (e.ctrlKey || e.metaKey)) {    // CTRL + C
          ranges = _grid.getSelectionModel().getSelectedRanges();
          if (ranges.length != 0) {
            _copiedRanges = ranges;
            markCopySelection(ranges);
            _self.onCopyCells.notify({ranges: ranges});

            var columns = _grid.getColumns();
            var clipTextArr = [];

            for (var rg = 0; rg < ranges.length; rg++){
                var range = ranges[rg];
                var clipTextRows = [];
                for (var i=range.fromRow; i< range.toRow+1 ; i++){
                    var clipTextCells = [];
                    var dt = _grid.getDataItem(i);

                    for (var j=range.fromCell; j< range.toCell+1 ; j++){
                        clipTextCells.push(getDataItemValueForColumn(dt, columns[j]));
                    }
                    clipTextRows.push(clipTextCells.join("\t"));
                }
                clipTextArr.push(clipTextRows.join("\r\n"));
            }
            var clipText = clipTextArr.join('');
            var ta = _createTextBox(clipText);
            $(ta).select();

            setTimeout(function(){
                document.body.removeChild(ta);
            }, 100);

            return false;
          }
        }

        if (e.which == keyCodes.V && (e.ctrlKey || e.metaKey)) {    // CTRL + V
            var ta = _createTextBox('');

            setTimeout(function(){
                _decodeTabularData(_grid, ta);
            }, 100);

            return false;
        }
      }
    }

    function markCopySelection(ranges) {
      clearCopySelection();

      var columns = _grid.getColumns();
      var hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          hash[j] = {};
          for (var k = ranges[i].fromCell; k <= ranges[i].toCell && k<columns.length; k++) {
            hash[j][columns[k].id] = _copiedCellStyle;
          }
        }
      }
      _grid.setCellCssStyles(_copiedCellStyleLayerKey, hash);
      clearTimeout(_clearCopyTI);
      _clearCopyTI = setTimeout(function(){
        _self.clearCopySelection();
      }, 2000);
    }

    function clearCopySelection() {
      _grid.removeCellCssStyles(_copiedCellStyleLayerKey);
    }

    $.extend(this, {
      "init": init,
      "destroy": destroy,
      "clearCopySelection": clearCopySelection,
      "handleKeyDown":handleKeyDown,

      "onCopyCells": new Slick.Event(),
      "onCopyCancelled": new Slick.Event(),
      "onPasteCells": new Slick.Event()
    });
  }
})(jQuery);<|endoftext|>


<commit_before>/* global describe, it */
'use strict';

var assert = assert || require('assert'),
    jsen = jsen || require('../index.js');

// Reference: https://tools.ietf.org/html/rfc6901
describe('JSON Pointer', function () {
    var doc = {
            foo: ['bar', 'baz'],
            '': 0,
            'a/b': 1,
            'c%d': 2,
            'e^f': 3,
            'g|h': 4,
            'i\\j': 5,
            'k\"l': 6,
            ' ': 7,
            'm~n': 8,
            'k\'l': 9
        },
        expected = [doc, doc.foo, 'bar', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        i;

    it('resolver conforms to JSON Pointer spec and decodes URI-encoded pointers', function () {
        var paths = [
            '#',
            '#/foo',
            '#/foo/0',
            '#/',
            '#/a~1b',
            '#/c%25d',
            '#/e%5Ef',
            '#/g%7Ch',
            '#/i%5Cj',
            '#/k%22l',
            '#/%20',
            '#/m~0n',
            '#/k\'l'
        ];

        for (i = 0; i < paths.length; i++) {
            assert.strictEqual(expected[i], jsen.resolve(doc, paths[i]));
        }
    });

    it('resolver does not parse $refs without # as JSON pointer', function () {
        var schema = {
                id: 'http://jsen.bis/schemaA',
                'http://jsen.bis/schemaB': {
                    type: 'number'
                },
                type: 'object',
                properties: {
                    foo: { $ref: 'http://jsen.bis/schemaB' }
                }
            },
            validate = jsen(schema);

        assert.strictEqual(schema['http://jsen.bis/schemaB'], jsen.resolve(schema, 'http://jsen.bis/schemaB'));

        assert(validate({ foo: 123 }));
        assert(!validate({ foo: '123' }));
    });

    it('resolver does not parse $refs that do not start with `#` as JSON pointer', function () {
        var schema = {
                id: 'http://jsen.bis/schemaA',
                definitions: {
                    foo: {
                        id: 'http://jsen.bis/schemaA#bar',
                        type: 'string'
                    },
                    foo2: { type: 'object' },
                    baz: { type: 'array' }
                },
                bar: { type: 'number' },
                '/definitions/baz': { type: 'boolean' },
                'http://jsen.bis/schemaA#/definitions/foo2': { type: 'null' },
                properties: {
                    foo: { $ref: 'http://jsen.bis/schemaA#bar' },
                    foo2: { $ref: 'http://jsen.bis/schemaA#/definitions/foo2' },
                    bar: { $ref: '#/bar' },
                    baz: { $ref: '/definitions/baz' }
                }
            },
            validate = jsen(schema);

        assert(validate({ foo: 'abc' }));
        assert(!validate({ foo: 123 }));

        assert(validate({ foo2: null }));
        assert(!validate({ foo2: {} }));

        assert(validate({ bar: 123 }));
        assert(!validate({ bar: '123' }));

        assert(validate({ baz: false }));
        assert(!validate({ baz: [] }));
    });
});

describe('$ref', function () {
    it('throws if string is not in correct format', function () {
        assert.throws(function () {
            jsen({ $ref: '' });
        });

        assert.throws(function () {
            jsen({ $ref: '#double//slash' });
        });

        assert.throws(function () {
            jsen({ $ref: '#ends/with/slash/' });
        });

        assert.throws(function () {
            // invalid reference, non-existent schema properties
            jsen({ $ref: '#a/b/c' });
        });

        assert.doesNotThrow(function () {
            // schema resolves to itself
            jsen({ $ref: '#' });
        });

        assert.doesNotThrow(function () {
            jsen({
                a: {
                    b: {
                        c: {
                            type: 'any'
                        }
                    }
                },
                $ref: '#/a/b/c'
            });
        });

        assert.doesNotThrow(function () {
            jsen({
                arr: [
                    { value: { type: 'string'} },
                    { value: { type: 'number'} },
                    { value: { type: 'boolean'} }
                ],
                type: 'object',
                properties: {
                    a: { $ref: '#arr/2/value' }
                }
            });
        });
    });

    describe('external schema', function () {
        it('finds external schema with a hash', function () {
            var external = { type: 'string' },
                schema = { $ref: '#external' },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(validate('abc'));
            assert(!validate(123));
        });

        it('finds external schema without a hash', function () {
            var external = { type: 'string' },
                schema = { $ref: 'external' },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(validate('abc'));
            assert(!validate(123));
        });

        it('throws when no external schema found', function () {
            var schema = { $ref: '#external' };

            assert.throws(function () {
                jsen(schema);
            });
        });

        it('own property takes precendence over external schema', function () {
            var external = { type: 'string' },
                schema = {
                    external: { type: 'number' },
                    $ref: '#external'
                },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(!validate('abc'));
            assert(validate(123));
        });

        it('external schemas have their own dereferencing scope', function () {
            var external = {
                    inner: { type: 'string' },
                    $ref: '#inner'
                },
                schema = {
                    inner: { type: 'number' },
                    $ref: '#external'
                },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(validate('abc'));
            assert(!validate(123));
        });
    });
});<commit_msg>Improve code coverage for SchemaResolver (#68)<commit_after>/* global describe, it */
'use strict';

var assert = assert || require('assert'),
    jsen = jsen || require('../index.js');

// Reference: https://tools.ietf.org/html/rfc6901
describe('JSON Pointer', function () {
    var doc = {
            foo: ['bar', 'baz'],
            '': 0,
            'a/b': 1,
            'c%d': 2,
            'e^f': 3,
            'g|h': 4,
            'i\\j': 5,
            'k\"l': 6,
            ' ': 7,
            'm~n': 8,
            'k\'l': 9
        },
        expected = [doc, doc.foo, 'bar', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        i;

    it('resolver conforms to JSON Pointer spec and decodes URI-encoded pointers', function () {
        var paths = [
            '#',
            '#/foo',
            '#/foo/0',
            '#/',
            '#/a~1b',
            '#/c%25d',
            '#/e%5Ef',
            '#/g%7Ch',
            '#/i%5Cj',
            '#/k%22l',
            '#/%20',
            '#/m~0n',
            '#/k\'l'
        ];

        for (i = 0; i < paths.length; i++) {
            assert.strictEqual(expected[i], jsen.resolve(doc, paths[i]));
        }
    });

    it('resolver does not parse $refs without # as JSON pointer', function () {
        var schema = {
                id: 'http://jsen.bis/schemaA',
                'http://jsen.bis/schemaB': {
                    type: 'number'
                },
                type: 'object',
                properties: {
                    foo: { $ref: 'http://jsen.bis/schemaB' }
                }
            },
            validate = jsen(schema);

        assert.strictEqual(schema['http://jsen.bis/schemaB'], jsen.resolve(schema, 'http://jsen.bis/schemaB'));

        assert(validate({ foo: 123 }));
        assert(!validate({ foo: '123' }));
    });

    it('resolver does not parse $refs that do not start with `#` as JSON pointer', function () {
        var schema = {
                id: 'http://jsen.bis/schemaA',
                definitions: {
                    foo: {
                        id: 'http://jsen.bis/schemaA#bar',
                        type: 'string'
                    },
                    foo2: { type: 'object' },
                    baz: { type: 'array' }
                },
                bar: { type: 'number' },
                '/definitions/baz': { type: 'boolean' },
                'http://jsen.bis/schemaA#/definitions/foo2': { type: 'null' },
                properties: {
                    foo: { $ref: 'http://jsen.bis/schemaA#bar' },
                    foo2: { $ref: 'http://jsen.bis/schemaA#/definitions/foo2' },
                    bar: { $ref: '#/bar' },
                    baz: { $ref: '/definitions/baz' }
                }
            },
            validate = jsen(schema);

        assert(validate({ foo: 'abc' }));
        assert(!validate({ foo: 123 }));

        assert(validate({ foo2: null }));
        assert(!validate({ foo2: {} }));

        assert(validate({ bar: 123 }));
        assert(!validate({ bar: '123' }));

        assert(validate({ baz: false }));
        assert(!validate({ baz: [] }));
    });
});

describe('SchemaResolver', function () {
    var SchemaResolver = require('../lib/resolver.js');

    it('resolve() returns non-object schema arguments', function () {
        var resolver = new SchemaResolver({}),
            arr = [];

        assert.strictEqual(resolver.resolve(), undefined);
        assert.strictEqual(resolver.resolve(null), null);
        assert.strictEqual(resolver.resolve(123), 123);
        assert.strictEqual(resolver.resolve(''), '');
        assert.strictEqual(resolver.resolve(arr), arr);
    });

    it('resolve() returns original object if no $ref', function () {
        var resolver = new SchemaResolver({}),
            obj = {};

        assert.strictEqual(resolver.resolve(obj), obj);
    });
});

describe('$ref', function () {
    it('throws if string is not in correct format', function () {
        assert.throws(function () {
            jsen({ $ref: '' });
        });

        assert.throws(function () {
            jsen({ $ref: '#double//slash' });
        });

        assert.throws(function () {
            jsen({ $ref: '#ends/with/slash/' });
        });

        assert.throws(function () {
            // invalid reference, non-existent schema properties
            jsen({ $ref: '#a/b/c' });
        });

        assert.doesNotThrow(function () {
            // schema resolves to itself
            jsen({ $ref: '#' });
        });

        assert.doesNotThrow(function () {
            jsen({
                a: {
                    b: {
                        c: {
                            type: 'any'
                        }
                    }
                },
                $ref: '#/a/b/c'
            });
        });

        assert.doesNotThrow(function () {
            jsen({
                arr: [
                    { value: { type: 'string'} },
                    { value: { type: 'number'} },
                    { value: { type: 'boolean'} }
                ],
                type: 'object',
                properties: {
                    a: { $ref: '#arr/2/value' }
                }
            });
        });
    });

    describe('external schema', function () {
        it('finds external schema with a hash', function () {
            var external = { type: 'string' },
                schema = { $ref: '#external' },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(validate('abc'));
            assert(!validate(123));
        });

        it('finds external schema without a hash', function () {
            var external = { type: 'string' },
                schema = { $ref: 'external' },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(validate('abc'));
            assert(!validate(123));
        });

        it('throws when no external schema found', function () {
            var schema = { $ref: '#external' };

            assert.throws(function () {
                jsen(schema);
            });
        });

        it('own property takes precendence over external schema', function () {
            var external = { type: 'string' },
                schema = {
                    external: { type: 'number' },
                    $ref: '#external'
                },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(!validate('abc'));
            assert(validate(123));
        });

        it('external schemas have their own dereferencing scope', function () {
            var external = {
                    inner: { type: 'string' },
                    $ref: '#inner'
                },
                schema = {
                    inner: { type: 'number' },
                    $ref: '#external'
                },
                validate = jsen(schema, {
                    schemas: {
                        external: external
                    }
                });

            assert(validate('abc'));
            assert(!validate(123));
        });
    });
});<|endoftext|>


<commit_before>/**
 * Created by ssehacker on 16/7/24.
 */
import MarkDownEditor from './MarkDownEditor';

class ProfileContact extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            defaultValue: this.props.value || ''
        };
    }

    componentDidMount(){
        //Ajax get data...
        this.setState({
            defaultValue: 'defaultValue...'
        });
    }

    handleSubmit(){
        let value = this.refs.editor.getValue();
        console.log(value);
        $.ajax({
            url: '/api/user',
            method: 'PATCH',
            data: {
                fieldName: 'contactMD',
                fieldValue: value
            },
            success: (res)=> {
                if(res.code === 0){
                    alert('保存成功!');
                }else{
                    alert(res.msg);
                }
            }
        })
    }

    render(){
        let me = this;
        return (

                    Tips:以下信息将在你博客中的"联系为"页面中展示.
                    <button className="btn-1" onClick={me.handleSubmit.bind(me)}>保存</button>

                <MarkDownEditor ref="editor" defaultValue={me.state.defaultValue}/>

        );
    }
}

export default ProfileContact;<commit_msg>fix spelling error.<commit_after>/**
 * Created by ssehacker on 16/7/24.
 */
import MarkDownEditor from './MarkDownEditor';

class ProfileContact extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            defaultValue: this.props.value || ''
        };
    }

    componentDidMount(){
        //Ajax get data...
        this.setState({
            defaultValue: 'defaultValue...'
        });
    }

    handleSubmit(){
        let value = this.refs.editor.getValue();
        console.log(value);
        $.ajax({
            url: '/api/user',
            method: 'PATCH',
            data: {
                fieldName: 'contactMD',
                fieldValue: value
            },
            success: (res)=> {
                if(res.code === 0){
                    alert('保存成功!');
                }else{
                    alert(res.msg);
                }
            }
        })
    }

    render(){
        let me = this;
        return (

                    Tips:以下信息将在你博客中的"联系我"页面中展示.
                    <button className="btn-1" onClick={me.handleSubmit.bind(me)}>保存</button>

                <MarkDownEditor ref="editor" defaultValue={me.state.defaultValue}/>

        );
    }
}

export default ProfileContact;<|endoftext|>