<commit_before>/*
//  Ping Pong
//  pingPong.js
//  Created by Ashish Gogna on 4/19/16.
*/

//Global variables
var windowWidth = $(window).width();
var windowHeight = $(window).height();

var gameStarted = 0;

var score = 0;

//The World
var world = {
    ctx:null,
    fps:20,
    themeColor: "#3B444B",
    mouseX:0,
    mouseY:0
}

world.setup = function()
{
	$('#gameDiv').append('<canvas id="gameCanvas">');
    var $canvas = $('#gameCanvas');
    $canvas.attr('width', windowWidth);
    $canvas.attr('height', windowHeight);
    var canvas = $canvas[0];
    ctx = canvas.getContext('2d');

    world.ctx = ctx;

    world.ctx.fillStyle = '#3B444B';
	//ctx.shadowBlur=2;
	//ctx.shadowColor="black";

    //Paint the walls
    world.ctx.fillRect(0, 0, windowWidth, 10);
    world.ctx.fillRect(0, windowHeight-10, windowWidth, 10);

    //Paint the bars
    world.ctx.fillRect(bars.leftBar[0], bars.leftBar[1], bars.leftBar[2], bars.leftBar[3]);
    world.ctx.fillRect(bars.rightBar[0], bars.rightBar[1], bars.rightBar[2], bars.rightBar[3]);

    //Paint the ball
	//world.ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
	//world.ctx.fill();

	//Start moving the ball
    requestAnimationFrame(moveObjects);

}

world.reset = function()
{
    location.reload();
}

var bars = {

	leftBar: [0, windowHeight/2-(150/2), 10, 150],
	rightBar: [windowWidth-10, windowHeight/2-(150/2), 10, 150]
}

var ball = {

	r: 10,
	x: windowWidth/2-(10/2),
	y: windowHeight/2-(10/2),
	dx: 9,
	dy: 9
}

function moveObjects()
{
	world.ctx.clearRect(0, 10, windowWidth, windowHeight-20);

    //Paint the bars
    bars.leftBar[1] = world.mouseY-(100/2);
    bars.rightBar[1] = world.mouseY-(100/2);

    world.ctx.fillRect(bars.leftBar[0], bars.leftBar[1], bars.leftBar[2], bars.leftBar[3]);
    world.ctx.fillRect(bars.rightBar[0], bars.rightBar[1], bars.rightBar[2], bars.rightBar[3]);

    if (gameStarted == 0)
    {
    	ball.x = bars.leftBar[2]+ball.r+5;
    	ball.y = world.mouseY-(ball.r/2);

	    //Paint the ball
	    world.ctx.beginPath();
	    world.ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
	    world.ctx.fill();
	    world.ctx.closePath();
    }
    else
    {
    	ball.x += ball.dx;
    	ball.y += ball.dy;

	    //Paint the ball
	    world.ctx.beginPath();
	    world.ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
	    world.ctx.fill();
	    world.ctx.closePath();
    }

    detectCollision();
    updateScore();

    requestAnimationFrame(moveObjects);
}

function detectCollision()
{
	//Ball and walls collision
	if (ball.y >= windowHeight-15 || ball.y <= 15)
	{
		ball.dy = -ball.dy;
	}

	//Ball and bars collision
	//Check if the ball hits one of the bar's x and ball's y is within the bar's y and height
	if ((ball.x >= bars.rightBar[0]-5 && (ball.y>bars.rightBar[1] && ball.y<bars.rightBar[1]+bars.rightBar[3])) || (ball.x <= bars.leftBar[2]+5 && (ball.y>bars.leftBar[1] && ball.y<bars.leftBar[1]+bars.leftBar[3])))
	{
		ball.dx = -ball.dx;
		score++;

		if (Math.abs(ball.dx) < 17)
		{
			if (ball.dx > 0)
				ball.dx = ball.dx+0.1;
			else
				ball.dx = ball.dx-0.1;
		}

		if (Math.abs(ball.dy) < 17)
		{
			if (ball.dy > 0)
				ball.dy = ball.dy+0.1;
			else
				ball.dy = ball.dy-0.1;
		}

		burstEffect(ball.x, ball.y);
	}

	//Ball's out
	else if (ball.x > windowWidth || ball.x < 0)
		world.reset();
}

function burstEffect(x, y)
{
	console.log(x + " = " + y);
}

function updateScore()
{
	$('#score').html(score);
}

//Animation function
window.requestAnimFrame = (function(callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
    window.setTimeout(callback, 100 / 40);
};
})();

//Mouse coordinates
$(document).mousemove(function(e) {

    world.mouseX = e.pageX;
    world.mouseY = e.pageY;
}).mouseover();

//Document onload function
$(document).ready(function () {

   	//Mouse click
	$("#gameDiv").click(function(){

	    gameStarted = 1;
	});

	world.setup();
});<commit_msg>Particles added<commit_after>/*
//  Ping Pong
//  pingPong.js
//  Created by Ashish Gogna on 4/19/16.
*/

//Global variables
var windowWidth = $(window).width();
var windowHeight = $(window).height();

var gameStarted = 0;

var score = 0;

//The World
var world = {
    ctx:null,
    fps:20,
    themeColor: "#3B444B",
    mouseX:0,
    mouseY:0
}

world.setup = function()
{
	$('#gameDiv').append('<canvas id="gameCanvas">');
    var $canvas = $('#gameCanvas');
    $canvas.attr('width', windowWidth);
    $canvas.attr('height', windowHeight);
    var canvas = $canvas[0];
    ctx = canvas.getContext('2d');

    world.ctx = ctx;

    world.ctx.fillStyle = '#3B444B';
	//ctx.shadowBlur=2;
	//ctx.shadowColor="black";

    //Paint the walls
    world.ctx.fillRect(0, 0, windowWidth, 10);
    world.ctx.fillRect(0, windowHeight-10, windowWidth, 10);

    //Paint the bars
    world.ctx.fillRect(bars.leftBar[0], bars.leftBar[1], bars.leftBar[2], bars.leftBar[3]);
    world.ctx.fillRect(bars.rightBar[0], bars.rightBar[1], bars.rightBar[2], bars.rightBar[3]);

    //Paint the ball
	//world.ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
	//world.ctx.fill();

	//Start moving the ball
    requestAnimationFrame(moveObjects);

}

world.reset = function()
{
    //location.reload();
}

var bars = {

	leftBar: [0, windowHeight/2-(150/2), 10, 150],
	rightBar: [windowWidth-10, windowHeight/2-(150/2), 10, 150]
}

var ball = {

	r: 10,
	x: windowWidth/2-(10/2),
	y: windowHeight/2-(10/2),
	dx: 9,
	dy: 9,
	hitX:0,
	hitY:0
}

var particles = {

    circles:[],
	r: 2
}

function moveObjects()
{
	world.ctx.clearRect(0, 10, windowWidth, windowHeight-20);

    //Paint the bars
    bars.leftBar[1] = world.mouseY-(100/2);
    bars.rightBar[1] = world.mouseY-(100/2);

    world.ctx.fillRect(bars.leftBar[0], bars.leftBar[1], bars.leftBar[2], bars.leftBar[3]);
    world.ctx.fillRect(bars.rightBar[0], bars.rightBar[1], bars.rightBar[2], bars.rightBar[3]);

    if (gameStarted == 0)
    {
    	ball.x = bars.leftBar[2]+ball.r+5;
    	ball.y = world.mouseY-(ball.r/2);

	    //Paint the ball
	    world.ctx.beginPath();
	    world.ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
	    world.ctx.fill();
	    world.ctx.closePath();
    }
    else
    {
    	ball.x += ball.dx;
    	ball.y += ball.dy;

	    //Paint the ball
	    world.ctx.beginPath();
	    world.ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
	    world.ctx.fill();
	    world.ctx.closePath();
    }

    detectCollision();
    updateScore();

    requestAnimationFrame(moveObjects);
}

function detectCollision()
{
	//Ball and walls collision
	if (ball.y >= windowHeight-15 || ball.y <= 15)
	{
		ball.dy = -ball.dy;
	}

	//Ball and bars collision
	//Check if the ball hits one of the bar's x and ball's y is within the bar's y and height
	if ((ball.x >= bars.rightBar[0]-5 && (ball.y>bars.rightBar[1] && ball.y<bars.rightBar[1]+bars.rightBar[3])) || (ball.x <= bars.leftBar[2]+5 && (ball.y>bars.leftBar[1] && ball.y<bars.leftBar[1]+bars.leftBar[3])))
	{
		ball.dx = -ball.dx;
		score++;

		if (Math.abs(ball.dx) < 17)
		{
			if (ball.dx > 0)
				ball.dx = ball.dx+0.1;
			else
				ball.dx = ball.dx-0.1;
		}

		if (Math.abs(ball.dy) < 17)
		{
			if (ball.dy > 0)
				ball.dy = ball.dy+0.1;
			else
				ball.dy = ball.dy-0.1;
		}

		if (particles.circles.length == 0)
			burstEffect(ball.x, ball.y);
	}

	//Ball's out
	else if (ball.x > windowWidth || ball.x < 0)
		world.reset();

	if (particles.circles.length > 0)
		burstEffect();
}

function burstEffect(x, y)
{
	if (particles.circles.length == 0)
	{
		for (var i=0; i<20; i++)
		{
			console.log(x + " = " + windowWidth);

			if (x > windowWidth/2)
				var startX = x-30;
			else if (x < windowWidth/2)
				var startX = x+30;

			var endX = x;

			if (i < 10)
			{
				endY = y+10;
			}

			var startY = y;
			var endY = y+30;

			var randX = getRandomInt(startX, endX);
			var randY = getRandomInt(startY, endY);

			particles.circles.push([randX, randY]);
		}
	}

	for (var i=0; i<particles.circles.length; i++)
	{
		var circle = particles.circles[i];

		var circleX = circle[0];
		var circleY = circle[1];

	    //Paint the ball
	    world.ctx.beginPath();
	    world.ctx.arc(circleX, circleY, particles.r, 0, Math.PI*2);
	    world.ctx.fill();
	    world.ctx.closePath();
	}
}

function updateScore()
{
	$('#score').html(score);
}

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

//Animation function
window.requestAnimFrame = (function(callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
    window.setTimeout(callback, 100 / 40);
};
})();

//Mouse coordinates
$(document).mousemove(function(e) {

    world.mouseX = e.pageX;
    world.mouseY = e.pageY;
}).mouseover();

//Document onload function
$(document).ready(function () {

   	//Mouse click
	$("#gameDiv").click(function(){

	    gameStarted = 1;
	});

	world.setup();
});<|endoftext|>


<commit_before>{
"texts":
    [{
        "title":"The Hobbit - Chapter 1a",
        "character_groups":[{"chars":"In","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"in","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"ground","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"there","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"lived","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hobbit","type":"WORD"},{"chars":". ","type":"NON_WORD"},{"chars":"Not","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"nasty","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"dirty","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"wet","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"filled","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"ends","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"of","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"worms","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"an","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"oozy","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"smell","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"nor","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"yet","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"dry","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"bare","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"sandy","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"nothing","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"in","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"it","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"to","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"sit","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"down","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"on","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"or","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"to","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"eat","type":"WORD"},{"chars":": ","type":"NON_WORD"},{"chars":"it","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"was","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hobbit","type":"WORD"},{"chars":"-","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"that","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"means","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"comfort","type":"WORD"},{"chars":".\r\n\r\n","type":"NON_WORD"},{"chars":"It","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"had","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"perfectly","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"round","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"door","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"like","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"porthole","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"painted","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"green","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"shiny","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"yellow","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"brass","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"knob","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"in","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"exact","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"middle","type":"WORD"},{"chars":". ","type":"NON_WORD"},{"chars":"The","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"door","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"opened","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"on","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"to","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tube","type":"WORD"},{"chars":"-","type":"NON_WORD"},{"chars":"shaped","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hall","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"like","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tunnel","type":"WORD"},{"chars":": ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"very","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"comfortable","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tunnel","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"without","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"smoke","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"panelled","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"walls","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"floors","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tiled","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"carpeted","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"provided","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"polished","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"chairs","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"lots","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"lots","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"of","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"pegs","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"for","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hats","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"coats","type":"WORD"},{"chars":" - ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hobbit","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"was","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"fond","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"of","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"visitors","type":"WORD"},{"chars":". ","type":"NON_WORD"},{"chars":"","type":"WORD"}]
    }],
"media_files":
    [{
        "title":"The Hobbit - Chapter 1a",
        "url":"https://url_to_soundfile",
        "media_type":"AUDIO",
        "file_type":"mp3"
    }],
"media_file_segments":
    {
        1: {"id": 1, "media_file_order":0, "time_start": 0.0, "time_end": 4},
        2: {"id": 2, "media_file_order":0, "time_start": 4, "time_end": 18},
        3: {"id": 3, "media_file_order":0, "time_start": 18, "time_end": 24},
        4: {"id": 4, "media_file_order":0, "time_start": 25.4, "time_end": 25.8},
        99: {"id": 99, "media_file_order":0, "time_start": 25.8, "time_end": 42}
    },
"text_segments":
    {
        1: {"id":1,"text_character_group_orders":["0_0","0_1","0_2","0_3","0_4","0_5","0_6","0_7","0_8","0_9","0_10","0_11","0_12","0_13","0_14","0_15","0_16","0_17","0_18","0_19"]},
        2: {"id":2,"text_character_group_orders":["0_20","0_21","0_22","0_23","0_24","0_25","0_26","0_27","0_28","0_29","0_30","0_31","0_32","0_33","0_34","0_35","0_36","0_37","0_38","0_39","0_40","0_41","0_42","0_43","0_44","0_45","0_46","0_47","0_48","0_49","0_50","0_51","0_52","0_53","0_54","0_55","0_56","0_57","0_58","0_59","0_60","0_61","0_62","0_63","0_64","0_65","0_66","0_67","0_68","0_69","0_70","0_71","0_72","0_73","0_74","0_75","0_76","0_77","0_78","0_79","0_80","0_81","0_82","0_83","0_84","0_85","0_86","0_87","0_88","0_89","0_90","0_91","0_92","0_93","0_94","0_95","0_96","0_97","0_98","0_99","0_100","0_101","0_102","0_103","0_104","0_105"]},
        4: {"id":4,"text_character_group_orders":["0_106","0_107","0_108","0_109","0_110","0_111","0_112","0_113","0_114","0_115","0_116","0_117","0_118","0_119","0_120","0_121","0_122","0_123","0_124","0_125","0_126","0_127","0_128","0_129","0_130","0_131","0_132","0_133","0_134","0_135","0_136","0_137","0_138","0_139","0_140","0_141","0_142","0_143","0_144","0_145","0_146","0_147"]},
        6: {"id":6,"text_character_group_orders":["0_148","0_149","0_150","0_151","0_152","0_153","0_154","0_155","0_156","0_157","0_158","0_159","0_160","0_161","0_162","0_163","0_164","0_165","0_166","0_167","0_168","0_169","0_170","0_171","0_172","0_173","0_174","0_175","0_176","0_177","0_178","0_179","0_180","0_181","0_182","0_183","0_184","0_185","0_186","0_187","0_188","0_189","0_190","0_191","0_192","0_193","0_194","0_195","0_196","0_197","0_198","0_199","0_200","0_201","0_202","0_203","0_204","0_205","0_206","0_207","0_208","0_209","0_210","0_211","0_212","0_213","0_214","0_215","0_216","0_217","0_218","0_219","0_220","0_221","0_222","0_223","0_224","0_225","0_226","0_227","0_228","0_229","0_230","0_231","0_232","0_233","0_234","0_235","0_236","0_237","0_238"]}
    },
"media_text_segment_alignments":
    {
        1: {"id": 1, "media_file_segment_id": 1, "text_segment_id": 1},
        2: {"id": 2, "media_file_segment_id": 2, "text_segment_id": 2},
        4: {"id": 4, "media_file_segment_id": 3, "text_segment_id": 4},
        6: {"id": 6, "media_file_segment_id": 99, "text_segment_id": 6}
    }
}<commit_msg>simplified json format<commit_after>{
"texts":
    [{
        "title":"The Hobbit - Chapter 1a",
        "character_groups":[{"chars":"In","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"in","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"ground","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"there","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"lived","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hobbit","type":"WORD"},{"chars":". ","type":"NON_WORD"},{"chars":"Not","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"nasty","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"dirty","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"wet","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"filled","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"ends","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"of","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"worms","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"an","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"oozy","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"smell","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"nor","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"yet","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"dry","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"bare","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"sandy","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"nothing","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"in","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"it","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"to","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"sit","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"down","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"on","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"or","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"to","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"eat","type":"WORD"},{"chars":": ","type":"NON_WORD"},{"chars":"it","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"was","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hobbit","type":"WORD"},{"chars":"-","type":"NON_WORD"},{"chars":"hole","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"that","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"means","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"comfort","type":"WORD"},{"chars":".\r\n\r\n","type":"NON_WORD"},{"chars":"It","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"had","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"perfectly","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"round","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"door","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"like","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"porthole","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"painted","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"green","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"shiny","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"yellow","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"brass","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"knob","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"in","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"exact","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"middle","type":"WORD"},{"chars":". ","type":"NON_WORD"},{"chars":"The","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"door","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"opened","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"on","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"to","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tube","type":"WORD"},{"chars":"-","type":"NON_WORD"},{"chars":"shaped","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hall","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"like","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tunnel","type":"WORD"},{"chars":": ","type":"NON_WORD"},{"chars":"a","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"very","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"comfortable","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tunnel","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"without","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"smoke","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"panelled","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"walls","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"floors","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"tiled","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"carpeted","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"provided","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"with","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"polished","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"chairs","type":"WORD"},{"chars":", ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"lots","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"lots","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"of","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"pegs","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"for","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hats","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"and","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"coats","type":"WORD"},{"chars":" - ","type":"NON_WORD"},{"chars":"the","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"hobbit","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"was","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"fond","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"of","type":"WORD"},{"chars":" ","type":"NON_WORD"},{"chars":"visitors","type":"WORD"},{"chars":". ","type":"NON_WORD"}]
    }],
"media_files":
    [{
        "title":"The Hobbit - Chapter 1a",
        "url":"https://url_to_soundfile",
        "media_type":"AUDIO",
        "file_type":"mp3"
    }],
"text_segments":
    {
        "1": {"id":1,"media_file_order":0, "time_start": 0.0, "time_end": 4, "text_order": 0, "character_group_start" : 0, "character_group_end" : 19},
        "2": {"id":2,"media_file_order":0, "time_start": 4, "time_end": 18, "text_order": 0, "character_group_start": 20, "character_group_end" : 105},
        "4": {"id":4,"media_file_order":0, "time_start": 18, "time_end": 24, "text_order": 0, "character_group_start": 106, "character_group_end" : 147},
        "6": {"id":6,"media_file_order":0, "time_start": 25.8, "time_end": 42, "text_order": 0, "character_group_start": 148, "character_group_end" : 238}
    }
}<|endoftext|>


<commit_before>//Read http://lodash.com/docs#template to understand what is "${whatever}" is.
//TLDR: do not change ids inside of ${...}

//Value can be a string or function that will return a string

define(function (require, exports, module){
    module.exports = {
        downloads: 'Téléchargements',
        hide: 'Cacher',
        more: 'plus',
        oneMoreVersion: '
... et une version supplémentaire.
',
        sortby: 'Trier par...',
        author: 'Auteur',
        update: 'Dernière màj',
        trending: 'Tendance', //0.3.0
        name: 'Nom',
        daily: 'téléchargements hier', //0.3.0
        stars: 'Favoris', //0.4.0
        forks: 'Fourches', //0.4.0
        themes: 'Thèmes', //0.5.0

        /*BADGES - 0.3.2*/
        badgeAdobe: 'Adobe',
        badgeAdobeTitle: 'Extension d\'Adobe',

        badge100k: '100k Téléchargements',
        badge100kTitle: 'Première extension a avoir 100k téléchargements',

        badgeTop: 'Top',
        badgeTopTitle: 'Extension la plus populaire',

        badgeTrend: 'Tendance',
        badgeTrendTitle: 'Extension la plus tendance',

        badgeNew: 'Nouveau',
        badgeNewTitle: 'Nouvelle extension',

        badgeStarsTitle: 'Extension la plus populaire sur GitHub', //0.4.0
        badgeForksTitle: 'Extension la plus fourchée sur GitHub', //0.4.0

        themeTitle: 'Thème Brackets',
        /*END of BADGES*/

        onlineTitle: 'Nombre d\'utilisateurs qui utilisent l\'extension en ce moment. Cliquez pour connaître le calcul derrière ce chiffre.', //0.5.0
        maxUsersTitle: 'Nombre d\'utilisateurs de l\'extension', //0.5.0

        //Detailed info about ##
        'click-more': 'Infos détaillées', //0.3.0

        //Online for ## days, ## downloads per day
        statusTemplate: '
En ligne depuis ${days} jours, ${daily} ${str_daily}, ${dpd} téléchargements par jour
',

        //v ## from ## - ## downloads

        versionTemplate: '
v ${version} du ${date} - ${downloads} téléchargements
',

        //... and ## more versions
        moreVersionsTemplate: '
... et ${count} versions supplémentaires
',

        //0.5.4
        colorDark: 'Foncé',
        colorLight: 'Clair'

        //0.6.0
        click_for_more: 'Cliquez pour En savoir plus.'
    }
});
<commit_msg>missing comma<commit_after>//Read http://lodash.com/docs#template to understand what is "${whatever}" is.
//TLDR: do not change ids inside of ${...}

//Value can be a string or function that will return a string

define(function (require, exports, module){
    module.exports = {
        downloads: 'Téléchargements',
        hide: 'Cacher',
        more: 'plus',
        oneMoreVersion: '
... et une version supplémentaire.
',
        sortby: 'Trier par...',
        author: 'Auteur',
        update: 'Dernière màj',
        trending: 'Tendance', //0.3.0
        name: 'Nom',
        daily: 'téléchargements hier', //0.3.0
        stars: 'Favoris', //0.4.0
        forks: 'Fourches', //0.4.0
        themes: 'Thèmes', //0.5.0

        /*BADGES - 0.3.2*/
        badgeAdobe: 'Adobe',
        badgeAdobeTitle: 'Extension d\'Adobe',

        badge100k: '100k Téléchargements',
        badge100kTitle: 'Première extension a avoir 100k téléchargements',

        badgeTop: 'Top',
        badgeTopTitle: 'Extension la plus populaire',

        badgeTrend: 'Tendance',
        badgeTrendTitle: 'Extension la plus tendance',

        badgeNew: 'Nouveau',
        badgeNewTitle: 'Nouvelle extension',

        badgeStarsTitle: 'Extension la plus populaire sur GitHub', //0.4.0
        badgeForksTitle: 'Extension la plus fourchée sur GitHub', //0.4.0

        themeTitle: 'Thème Brackets',
        /*END of BADGES*/

        onlineTitle: 'Nombre d\'utilisateurs qui utilisent l\'extension en ce moment. Cliquez pour connaître le calcul derrière ce chiffre.', //0.5.0
        maxUsersTitle: 'Nombre d\'utilisateurs de l\'extension', //0.5.0

        //Detailed info about ##
        'click-more': 'Infos détaillées', //0.3.0

        //Online for ## days, ## downloads per day
        statusTemplate: '
En ligne depuis ${days} jours, ${daily} ${str_daily}, ${dpd} téléchargements par jour
',

        //v ## from ## - ## downloads

        versionTemplate: '
v ${version} du ${date} - ${downloads} téléchargements
',

        //... and ## more versions
        moreVersionsTemplate: '
... et ${count} versions supplémentaires
',

        //0.5.4
        colorDark: 'Foncé',
        colorLight: 'Clair',

        //0.6.0
        click_for_more: 'Cliquez pour en savoir plus.'
    }
});
<|endoftext|>


<commit_before>// Calamars
// ========
//
// An alpha quality, under heavy development, proto-frramework for building
// conversational applications.
//
// This library is a collection of different helper functions and classes,
// currently there are 2 main components:
//
// - [router.js](./router.html)
//   - a helper function to create input → output mappings
// - [luis.js](./luis.html)
//   - a driver for the LUIS webservice
// - [wit.js](./wit.html)
//   - a driver for the wit.ai webservice
//
// ---
//
// Source
// ------
export { version } from '../../package.json';
export {
    createRouter,
    createExactMatchRouter,
    createRegexRouter,
    createRegexFunctionRouter
} from './router';
export {
    LuisDriver,
    previewBaseURL,
    previewApiPath
} from './luis';
<commit_msg>minor documentation update<commit_after>// Calamars
// ========
//
// An alpha quality, under heavy development, proto-frramework for building
// conversational applications.
//
// This library is a collection of different helper functions and classes,
// currently there are 3 main components:
//
// - [router.js](./router.html)
//   - a helper function to create input → output mappings
// - [luis.js](./luis.html)
//   - a driver for the LUIS webservice
// - [wit.js](./wit.html)
//   - a driver for the wit.ai webservice
//
// ---
//
// Source
// ------
export { version } from '../../package.json';
export {
    createRouter,
    createExactMatchRouter,
    createRegexRouter,
    createRegexFunctionRouter
} from './router';
export {
    LuisDriver,
    previewBaseURL,
    previewApiPath
} from './luis';
<|endoftext|>


<commit_before>'use strict'

var timer = {

  setTimeout: function (timeoutCallbackId, delay, callbackId) {
    var sender = this.sender
    var timer = setTimeout(function () {
      sender.performCallback(timeoutCallbackId)
    }, delay)
    sender.performCallback(callbackId, timer)
  },

  clearTimeout: function (timer) {
    clearTimeout(timer)
  }

}

timer._meta = {
  timer: [{
    name: 'setTimeout',
    args: ['function', 'number', 'function']
  }, {
    name: 'clearTimeout',
    args: ['number']
  }]
}

module.exports = timer
<commit_msg>* [html5] retrieving timer id is not currently supported<commit_after>'use strict'

var timer = {

  setTimeout: function (timeoutCallbackId, delay) {
    var sender = this.sender
    var timerId = setTimeout(function () {
      sender.performCallback(timeoutCallbackId)
    }, delay)
  },

  clearTimeout: function (timerId) {
    clearTimeout(timerId)
  }

}

timer._meta = {
  timer: [{
    name: 'setTimeout',
    args: ['function', 'number', 'function']
  }, {
    name: 'clearTimeout',
    args: ['number']
  }]
}

module.exports = timer
<|endoftext|>


<commit_before>"use strict";

var NpdcShowController = function($scope, $location,
  npdcAppConfig, NpdcApplications, NpdcSearchService, NpdcAutocompleteConfigFactory) {
  'ngInject';

  $scope.sections = NpdcApplications.filter(app => app.category === 'public');

  $scope.documents = [{
    link: "https://data.npolar.no/policy/NP-datapolitikk.pdf",
    name: "Data policy",
    img: "/home/img/open-data.jpg",
    description: ""
  }];
  $scope.apps = NpdcApplications.filter(app => app.category === 'public');

  $scope.searchOptions = new NpdcAutocompleteConfigFactory({
    global: true,
    showCollections: false,
    floatingLabel: false
  });

  $scope.search = function(q) {
    let query = Object.assign({},
      $location.search(), {
        q: $scope.searchOptions.q
      });
    NpdcSearchService.globalSearch(query);
  };

  $scope.icon96 = function (app) {
    return app.icons.find(icon => icon.size === 96).src;
  };
};

module.exports = NpdcShowController;
<commit_msg>Currently policy is only available in Norwegian<commit_after>"use strict";

var NpdcShowController = function($scope, $location,
  npdcAppConfig, NpdcApplications, NpdcSearchService, NpdcAutocompleteConfigFactory) {
  'ngInject';

  $scope.sections = NpdcApplications.filter(app => app.category === 'public');

  $scope.documents = [{
    link: "https://data.npolar.no/policy/NP-datapolitikk.pdf",
    name: "Data policy (Norwegian)",
    img: "/home/img/open-data.jpg",
    description: ""
  }];
  $scope.apps = NpdcApplications.filter(app => app.category === 'public');

  $scope.searchOptions = new NpdcAutocompleteConfigFactory({
    global: true,
    showCollections: false,
    floatingLabel: false
  });

  $scope.search = function(q) {
    let query = Object.assign({},
      $location.search(), {
        q: $scope.searchOptions.q
      });
    NpdcSearchService.globalSearch(query);
  };

  $scope.icon96 = function (app) {
    return app.icons.find(icon => icon.size === 96).src;
  };
};

module.exports = NpdcShowController;
<|endoftext|>


<commit_before>'use strict'

const nextTick = require('./nextTick')

const proxies = new WeakMap()
const observers = new WeakMap()
const queuedObservers = new Set()
let queued = false
let currentObserver
const handlers = {get, set, deleteProperty}
const wellKnowSymbols = new Set()

for (let key of Object.getOwnPropertyNames(Symbol)) {
  const value = Symbol[key]
  if (typeof value === 'symbol') {
    wellKnowSymbols.add(value)
  }
}

module.exports = {
  observe,
  unobserve,
  observable,
  isObservable
}

function observe (fn, context, ...args) {
  if (typeof fn !== 'function') {
    throw new TypeError('first argument must be a function')
  }
  args = args.length ? args : undefined
  const observer = {fn, context, args, observedKeys: []}
  runObserver(observer)
  return observer
}

function unobserve (observer) {
  if (typeof observer === 'object' && observer.observedKeys) {
    observer.observedKeys.forEach(unobserveKey, observer)
    observer.fn = observer.context = observer.args = observer.observedKeys = undefined
  }
}

function observable (obj) {
  obj = obj || {}
  if (typeof obj !== 'object') {
    throw new TypeError('first argument must be an object or undefined')
  }
  return proxies.get(obj) || toObservable(obj)
}

function toObservable (obj) {
  const observable = new Proxy(obj, handlers)
  proxies.set(obj, observable)
  proxies.set(observable, observable)
  observers.set(obj, new Map())
  return observable
}

function isObservable (obj) {
  if (typeof obj !== 'object') {
    throw new TypeError('first argument must be an object')
  }
  return (proxies.get(obj) === obj)
}

function get (target, key, receiver) {
  if (key === '$raw') return target
  const result = Reflect.get(target, key, receiver)
  if (typeof key === 'symbol' && wellKnowSymbols.has(key)) {
    return result
  }
  const isObject = (typeof result === 'object' && result !== null)
  const observable = isObject && proxies.get(result)
  if (currentObserver) {
    registerObserver(target, key, currentObserver)
    if (isObject && result.constructor !== Date) {
      return observable || toObservable(result)
    }
  }
  return observable || result
}

function registerObserver (target, key, observer) {
  const observersForTarget = observers.get(target)
  let observersForKey = observersForTarget.get(key)
  if (!observersForKey) {
    observersForKey = new Set()
    observersForTarget.set(key, observersForKey)
  }
  if (!observersForKey.has(observer)) {
    observersForKey.add(observer)
    observer.observedKeys.push(observersForKey)
  }
}

function set (target, key, value, receiver) {
  const observersForKey = observers.get(target).get(key)
  if (observersForKey) {
    observersForKey.forEach(queueObserver)
  }
  return Reflect.set(target, key, value, receiver)
}

function deleteProperty (target, key) {
  const observersForKey = observers.get(target).get(key)
  if (observersForKey) {
    observersForKey.forEach(queueObserver)
  }
  return Reflect.deleteProperty(target, key)
}

function queueObserver (observer) {
  if (!queued) {
    nextTick(runObservers)
    queued = true
  }
  queuedObservers.add(observer)
}

function runObservers () {
  queuedObservers.forEach(runObserver)
  queuedObservers.clear()
  queued = false
}

function runObserver (observer) {
  if (observer.fn) {
    try {
      currentObserver = observer
      observer.fn.apply(observer.context, observer.args)
    } finally {
      currentObserver = undefined
    }
  }
}

function unobserveKey (observersForKey) {
  observersForKey.delete(this)
}
<commit_msg>fix($raw): ensure that wrapped plain object is never polluted with Proxy wrapped props<commit_after>'use strict'

const nextTick = require('./nextTick')

const proxies = new WeakMap()
const observers = new WeakMap()
const queuedObservers = new Set()
let queued = false
let currentObserver
const handlers = {get, set, deleteProperty}
const wellKnowSymbols = new Set()

for (let key of Object.getOwnPropertyNames(Symbol)) {
  const value = Symbol[key]
  if (typeof value === 'symbol') {
    wellKnowSymbols.add(value)
  }
}

module.exports = {
  observe,
  unobserve,
  observable,
  isObservable
}

function observe (fn, context, ...args) {
  if (typeof fn !== 'function') {
    throw new TypeError('first argument must be a function')
  }
  args = args.length ? args : undefined
  const observer = {fn, context, args, observedKeys: []}
  runObserver(observer)
  return observer
}

function unobserve (observer) {
  if (typeof observer === 'object' && observer.observedKeys) {
    observer.observedKeys.forEach(unobserveKey, observer)
    observer.fn = observer.context = observer.args = observer.observedKeys = undefined
  }
}

function observable (obj) {
  obj = obj || {}
  if (typeof obj !== 'object') {
    throw new TypeError('first argument must be an object or undefined')
  }
  return proxies.get(obj) || toObservable(obj)
}

function toObservable (obj) {
  const observable = new Proxy(obj, handlers)
  proxies.set(obj, observable)
  proxies.set(observable, observable)
  observers.set(obj, new Map())
  return observable
}

function isObservable (obj) {
  if (typeof obj !== 'object') {
    throw new TypeError('first argument must be an object')
  }
  return (proxies.get(obj) === obj)
}

function get (target, key, receiver) {
  if (key === '$raw') return target
  const result = Reflect.get(target, key, receiver)
  if (typeof key === 'symbol' && wellKnowSymbols.has(key)) {
    return result
  }
  const isObject = (typeof result === 'object' && result && result.constructor !== Date)
  const observable = isObject && proxies.get(result)
  if (currentObserver) {
    registerObserver(target, key, currentObserver)
    if (isObject) {
      return observable || toObservable(result)
    }
  }
  return observable || result
}

function registerObserver (target, key, observer) {
  const observersForTarget = observers.get(target)
  let observersForKey = observersForTarget.get(key)
  if (!observersForKey) {
    observersForKey = new Set()
    observersForTarget.set(key, observersForKey)
  }
  if (!observersForKey.has(observer)) {
    observersForKey.add(observer)
    observer.observedKeys.push(observersForKey)
  }
}

function set (target, key, value, receiver) {
  const observersForKey = observers.get(target).get(key)
  if (observersForKey) {
    observersForKey.forEach(queueObserver)
  }
  if (typeof value === 'object' && value) {
    value = value.$raw || value
  }
  return Reflect.set(target, key, value, receiver)
}

function deleteProperty (target, key) {
  const observersForKey = observers.get(target).get(key)
  if (observersForKey) {
    observersForKey.forEach(queueObserver)
  }
  return Reflect.deleteProperty(target, key)
}

function queueObserver (observer) {
  if (!queued) {
    nextTick(runObservers)
    queued = true
  }
  queuedObservers.add(observer)
}

function runObservers () {
  queuedObservers.forEach(runObserver)
  queuedObservers.clear()
  queued = false
}

function runObserver (observer) {
  if (observer.fn) {
    try {
      currentObserver = observer
      observer.fn.apply(observer.context, observer.args)
    } finally {
      currentObserver = undefined
    }
  }
}

function unobserveKey (observersForKey) {
  observersForKey.delete(this)
}
<|endoftext|>


<commit_before>/* eslint-disable import/no-named-as-default-member */
import { OrderedMap } from 'immutable';

import PACKAGE from '../package.json';

import { OBJECT_TAG } from './utils/testing/TestUtils';

import * as Lattice from './index';

/* eslint-disable key-spacing */
const EXPECTED_OBJ_EXPORTS = OrderedMap({
  AnalysisApi        : { size: 2 },
  AppApi             : { size: 18 },
  AuthorizationApi   : { size: 2 },
  CodexApi           : { size: 1 },
  DataApi            : { size: 17 },
  DataIntegrationApi : { size: 1 },
  EntityDataModelApi : { size: 51 },
  EntitySetsApi      : { size: 8 },
  FeedsApi           : { size: 1 },
  LinkingApi         : { size: 2 },
  OrganizationsApi   : { size: 31 },
  PermissionsApi     : { size: 3 },
  PersistentSearchApi: { size: 5 },
  PrincipalsApi      : { size: 9 },
  RequestsApi        : { size: 3 },
  SearchApi          : { size: 14 },
  SubscriptionApi    : { size: 3 },
  Constants          : { size: 3 },
  Models             : { size: 61 },
  Types              : { size: 10 },
});
/* eslint-enable key-spacing */

describe('lattice-js named export', () => {

  EXPECTED_OBJ_EXPORTS.forEach(({ size }, key) => {
    test(`should export "${key}`, () => {
      expect(Object.prototype.toString.call(Lattice[key])).toEqual(OBJECT_TAG);
      expect(Object.keys(Lattice[key])).toHaveLength(size);
    });
  });

  test('should export the correct version', () => {
    expect(Lattice.version).toEqual(PACKAGE.version);
  });

  test('should export configure()', () => {
    expect(Lattice.configure).toBeInstanceOf(Function);
  });

});
<commit_msg>Exports 2 apis<commit_after>/* eslint-disable import/no-named-as-default-member */
import { OrderedMap } from 'immutable';

import PACKAGE from '../package.json';

import { OBJECT_TAG } from './utils/testing/TestUtils';

import * as Lattice from './index';

/* eslint-disable key-spacing */
const EXPECTED_OBJ_EXPORTS = OrderedMap({
  AnalysisApi        : { size: 2 },
  AppApi             : { size: 18 },
  AuthorizationApi   : { size: 2 },
  CodexApi           : { size: 1 },
  DataApi            : { size: 17 },
  DataIntegrationApi : { size: 2 },
  EntityDataModelApi : { size: 51 },
  EntitySetsApi      : { size: 8 },
  FeedsApi           : { size: 1 },
  LinkingApi         : { size: 2 },
  OrganizationsApi   : { size: 31 },
  PermissionsApi     : { size: 3 },
  PersistentSearchApi: { size: 5 },
  PrincipalsApi      : { size: 9 },
  RequestsApi        : { size: 3 },
  SearchApi          : { size: 14 },
  SubscriptionApi    : { size: 3 },
  Constants          : { size: 3 },
  Models             : { size: 61 },
  Types              : { size: 10 },
});
/* eslint-enable key-spacing */

describe('lattice-js named export', () => {

  EXPECTED_OBJ_EXPORTS.forEach(({ size }, key) => {
    test(`should export "${key}`, () => {
      expect(Object.prototype.toString.call(Lattice[key])).toEqual(OBJECT_TAG);
      expect(Object.keys(Lattice[key])).toHaveLength(size);
    });
  });

  test('should export the correct version', () => {
    expect(Lattice.version).toEqual(PACKAGE.version);
  });

  test('should export configure()', () => {
    expect(Lattice.configure).toBeInstanceOf(Function);
  });

});
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import {createChildFragment} from '../utils/childUtils';
import Events from '../utils/events';
import keycode from 'keycode';
import FocusRipple from './FocusRipple';
import TouchRipple from './TouchRipple';

let styleInjected = false;
let listening = false;
let tabPressed = false;

function injectStyle() {
  if (!styleInjected) {
    // Remove inner padding and border in Firefox 4+.
    const style = document.createElement('style');
    style.innerHTML = `
      button::-moz-focus-inner,
      input::-moz-focus-inner {
        border: 0;
        padding: 0;
      }
    `;

    document.body.appendChild(style);
    styleInjected = true;
  }
}

function listenForTabPresses() {
  if (!listening) {
    Events.on(window, 'keydown', (event) => {
      tabPressed = keycode(event) === 'tab';
    });
    listening = true;
  }
}

class EnhancedButton extends Component {
  static propTypes = {
    centerRipple: PropTypes.bool,
    children: PropTypes.node,
    containerElement: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.element,
    ]),
    disableFocusRipple: PropTypes.bool,
    disableKeyboardFocus: PropTypes.bool,
    disableTouchRipple: PropTypes.bool,
    disabled: PropTypes.bool,
    focusRippleColor: PropTypes.string,
    focusRippleOpacity: PropTypes.number,
    href: PropTypes.string,
    keyboardFocused: PropTypes.bool,
    onBlur: PropTypes.func,
    onClick: PropTypes.func,
    onFocus: PropTypes.func,
    onKeyDown: PropTypes.func,
    onKeyUp: PropTypes.func,
    onKeyboardFocus: PropTypes.func,
    onTouchTap: PropTypes.func,
    style: PropTypes.object,
    tabIndex: PropTypes.number,
    touchRippleColor: PropTypes.string,
    touchRippleOpacity: PropTypes.number,
    type: PropTypes.string,
  };

  static defaultProps = {
    containerElement: 'button',
    onBlur: () => {},
    onClick: () => {},
    onFocus: () => {},
    onKeyDown: () => {},
    onKeyUp: () => {},
    onKeyboardFocus: () => {},
    onTouchTap: () => {},
    tabIndex: 0,
    type: 'button',
  };

  static contextTypes = {
    muiTheme: PropTypes.object.isRequired,
  };

  state = {
    isKeyboardFocused: false,
  };

  componentWillMount() {
    const {disabled, disableKeyboardFocus, keyboardFocused} = this.props;
    if (!disabled && keyboardFocused && !disableKeyboardFocus) {
      this.setState({isKeyboardFocused: true});
    }
  }

  componentDidMount() {
    injectStyle();
    listenForTabPresses();
    if (this.state.isKeyboardFocused) {
      this.refs.enhancedButton.focus();
      this.props.onKeyboardFocus(null, true);
    }
  }

  componentWillReceiveProps(nextProps) {
    if ((nextProps.disabled || nextProps.disableKeyboardFocus) &&
      this.state.isKeyboardFocused) {
      this.setState({isKeyboardFocused: false});
      if (nextProps.onKeyboardFocus) {
        nextProps.onKeyboardFocus(null, false);
      }
    }
  }

  componentWillUnmount() {
    clearTimeout(this.focusTimeout);
  }

  isKeyboardFocused() {
    return this.state.isKeyboardFocused;
  }

  removeKeyboardFocus(event) {
    if (this.state.isKeyboardFocused) {
      this.setState({isKeyboardFocused: false});
      this.props.onKeyboardFocus(event, false);
    }
  }

  setKeyboardFocus(event) {
    if (!this.state.isKeyboardFocused) {
      this.setState({isKeyboardFocused: true});
      this.props.onKeyboardFocus(event, true);
    }
  }

  cancelFocusTimeout() {
    if (this.focusTimeout) {
      clearTimeout(this.focusTimeout);
      this.focusTimeout = null;
    }
  }

  createButtonChildren() {
    const {
      centerRipple,
      children,
      disabled,
      disableFocusRipple,
      disableKeyboardFocus,
      disableTouchRipple,
      focusRippleColor,
      focusRippleOpacity,
      touchRippleColor,
      touchRippleOpacity,
    } = this.props;
    const {isKeyboardFocused} = this.state;

    // Focus Ripple
    const focusRipple = isKeyboardFocused && !disabled && !disableFocusRipple && !disableKeyboardFocus ? (
      <FocusRipple
        color={focusRippleColor}
        opacity={focusRippleOpacity}
        show={isKeyboardFocused}
      />
    ) : undefined;

    // Touch Ripple
    const touchRipple = !disabled && !disableTouchRipple ? (
      <TouchRipple
        centerRipple={centerRipple}
        color={touchRippleColor}
        opacity={touchRippleOpacity}
      >
        {children}
      </TouchRipple>
    ) : undefined;

    return createChildFragment({
      focusRipple,
      touchRipple,
      children: touchRipple ? undefined : children,
    });
  }

  handleKeyDown = (event) => {
    if (!this.props.disabled && !this.props.disableKeyboardFocus) {
      if (keycode(event) === 'enter' && this.state.isKeyboardFocused) {
        this.handleTouchTap(event);
      }
      if (keycode(event) === 'esc' && this.state.isKeyboardFocused) {
        this.removeKeyboardFocus(event);
      }
    }
    this.props.onKeyDown(event);
  };

  handleKeyUp = (event) => {
    if (!this.props.disabled && !this.props.disableKeyboardFocus) {
      if (keycode(event) === 'space' && this.state.isKeyboardFocused) {
        this.handleTouchTap(event);
      }
    }
    this.props.onKeyUp(event);
  };

  handleBlur = (event) => {
    this.cancelFocusTimeout();
    this.removeKeyboardFocus(event);
    this.props.onBlur(event);
  };

  handleFocus = (event) => {
    if (event) event.persist();
    if (!this.props.disabled && !this.props.disableKeyboardFocus) {
      // setTimeout is needed because the focus event fires first
      // Wait so that we can capture if this was a keyboard focus
      // or touch focus
      this.focusTimeout = setTimeout(() => {
        if (tabPressed) {
          this.setKeyboardFocus(event);
          tabPressed = false;
        }
      }, 150);

      this.props.onFocus(event);
    }
  };

  handleClick = (event) => {
    if (!this.props.disabled) {
      tabPressed = false;
      this.props.onClick(event);
    }
  };

  handleTouchTap = (event) => {
    this.cancelFocusTimeout();
    if (!this.props.disabled) {
      tabPressed = false;
      this.removeKeyboardFocus(event);
      this.props.onTouchTap(event);
    }
  };

  render() {
    const {
      centerRipple, // eslint-disable-line no-unused-vars
      children,
      containerElement,
      disabled,
      disableKeyboardFocus, // eslint-disable-line no-unused-vars
      disableTouchRipple, // eslint-disable-line no-unused-vars
      focusRippleColor, // eslint-disable-line no-unused-vars
      focusRippleOpacity, // eslint-disable-line no-unused-vars
      href,
      keyboardFocused, // eslint-disable-line no-unused-vars
      touchRippleColor, // eslint-disable-line no-unused-vars
      touchRippleOpacity, // eslint-disable-line no-unused-vars
      onBlur, // eslint-disable-line no-unused-vars
      onClick, // eslint-disable-line no-unused-vars
      onFocus, // eslint-disable-line no-unused-vars
      onKeyUp, // eslint-disable-line no-unused-vars
      onKeyDown, // eslint-disable-line no-unused-vars
      onKeyboardFocus, // eslint-disable-line no-unused-vars
      onTouchTap, // eslint-disable-line no-unused-vars
      style,
      tabIndex,
      type,
      ...other
    } = this.props;

    const {
      prepareStyles,
      enhancedButton,
    } = this.context.muiTheme;

    const mergedStyles = Object.assign({
      border: 10,
      boxSizing: 'border-box',
      display: 'inline-block',
      fontFamily: this.context.muiTheme.baseTheme.fontFamily,
      WebkitTapHighlightColor: enhancedButton.tapHighlightColor, // Remove mobile color flashing (deprecated)
      cursor: disabled ? 'default' : 'pointer',
      textDecoration: 'none',
      margin: 0,
      padding: 0,
      outline: 'none',
      fontSize: 'inherit',
      fontWeight: 'inherit',
      verticalAlign: href ? 'middle' : null,
    }, style);

    // Passing both background:none & backgroundColor can break due to object iteration order
    if (!mergedStyles.backgroundColor && !mergedStyles.background) {
      mergedStyles.background = 'none';
    }

    if (disabled && href) {
      return (
        <span
          {...other}
          style={mergedStyles}
        >
          {children}
        </span>
      );
    }

    const buttonProps = {
      ...other,
      style: prepareStyles(mergedStyles),
      ref: 'enhancedButton',
      disabled: disabled,
      href: href,
      onBlur: this.handleBlur,
      onClick: this.handleClick,
      onFocus: this.handleFocus,
      onKeyUp: this.handleKeyUp,
      onKeyDown: this.handleKeyDown,
      onTouchTap: this.handleTouchTap,
      tabIndex: disabled || disableKeyboardFocus ? -1 : tabIndex,
    };

    const buttonChildren = this.createButtonChildren();

    if (React.isValidElement(containerElement)) {
      return React.cloneElement(containerElement, buttonProps, buttonChildren);
    }

    if (!href && containerElement === 'button') {
      buttonProps.type = type;
    }

    return React.createElement(href ? 'a' : containerElement, buttonProps, buttonChildren);
  }
}

export default EnhancedButton;
<commit_msg>don't leak disableFocusRipple to the span<commit_after>import React, {Component, PropTypes} from 'react';
import {createChildFragment} from '../utils/childUtils';
import Events from '../utils/events';
import keycode from 'keycode';
import FocusRipple from './FocusRipple';
import TouchRipple from './TouchRipple';

let styleInjected = false;
let listening = false;
let tabPressed = false;

function injectStyle() {
  if (!styleInjected) {
    // Remove inner padding and border in Firefox 4+.
    const style = document.createElement('style');
    style.innerHTML = `
      button::-moz-focus-inner,
      input::-moz-focus-inner {
        border: 0;
        padding: 0;
      }
    `;

    document.body.appendChild(style);
    styleInjected = true;
  }
}

function listenForTabPresses() {
  if (!listening) {
    Events.on(window, 'keydown', (event) => {
      tabPressed = keycode(event) === 'tab';
    });
    listening = true;
  }
}

class EnhancedButton extends Component {
  static propTypes = {
    centerRipple: PropTypes.bool,
    children: PropTypes.node,
    containerElement: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.element,
    ]),
    disableFocusRipple: PropTypes.bool,
    disableKeyboardFocus: PropTypes.bool,
    disableTouchRipple: PropTypes.bool,
    disabled: PropTypes.bool,
    focusRippleColor: PropTypes.string,
    focusRippleOpacity: PropTypes.number,
    href: PropTypes.string,
    keyboardFocused: PropTypes.bool,
    onBlur: PropTypes.func,
    onClick: PropTypes.func,
    onFocus: PropTypes.func,
    onKeyDown: PropTypes.func,
    onKeyUp: PropTypes.func,
    onKeyboardFocus: PropTypes.func,
    onTouchTap: PropTypes.func,
    style: PropTypes.object,
    tabIndex: PropTypes.number,
    touchRippleColor: PropTypes.string,
    touchRippleOpacity: PropTypes.number,
    type: PropTypes.string,
  };

  static defaultProps = {
    containerElement: 'button',
    onBlur: () => {},
    onClick: () => {},
    onFocus: () => {},
    onKeyDown: () => {},
    onKeyUp: () => {},
    onKeyboardFocus: () => {},
    onTouchTap: () => {},
    tabIndex: 0,
    type: 'button',
  };

  static contextTypes = {
    muiTheme: PropTypes.object.isRequired,
  };

  state = {
    isKeyboardFocused: false,
  };

  componentWillMount() {
    const {disabled, disableKeyboardFocus, keyboardFocused} = this.props;
    if (!disabled && keyboardFocused && !disableKeyboardFocus) {
      this.setState({isKeyboardFocused: true});
    }
  }

  componentDidMount() {
    injectStyle();
    listenForTabPresses();
    if (this.state.isKeyboardFocused) {
      this.refs.enhancedButton.focus();
      this.props.onKeyboardFocus(null, true);
    }
  }

  componentWillReceiveProps(nextProps) {
    if ((nextProps.disabled || nextProps.disableKeyboardFocus) &&
      this.state.isKeyboardFocused) {
      this.setState({isKeyboardFocused: false});
      if (nextProps.onKeyboardFocus) {
        nextProps.onKeyboardFocus(null, false);
      }
    }
  }

  componentWillUnmount() {
    clearTimeout(this.focusTimeout);
  }

  isKeyboardFocused() {
    return this.state.isKeyboardFocused;
  }

  removeKeyboardFocus(event) {
    if (this.state.isKeyboardFocused) {
      this.setState({isKeyboardFocused: false});
      this.props.onKeyboardFocus(event, false);
    }
  }

  setKeyboardFocus(event) {
    if (!this.state.isKeyboardFocused) {
      this.setState({isKeyboardFocused: true});
      this.props.onKeyboardFocus(event, true);
    }
  }

  cancelFocusTimeout() {
    if (this.focusTimeout) {
      clearTimeout(this.focusTimeout);
      this.focusTimeout = null;
    }
  }

  createButtonChildren() {
    const {
      centerRipple,
      children,
      disabled,
      disableFocusRipple,
      disableKeyboardFocus,
      disableTouchRipple,
      focusRippleColor,
      focusRippleOpacity,
      touchRippleColor,
      touchRippleOpacity,
    } = this.props;
    const {isKeyboardFocused} = this.state;

    // Focus Ripple
    const focusRipple = isKeyboardFocused && !disabled && !disableFocusRipple && !disableKeyboardFocus ? (
      <FocusRipple
        color={focusRippleColor}
        opacity={focusRippleOpacity}
        show={isKeyboardFocused}
      />
    ) : undefined;

    // Touch Ripple
    const touchRipple = !disabled && !disableTouchRipple ? (
      <TouchRipple
        centerRipple={centerRipple}
        color={touchRippleColor}
        opacity={touchRippleOpacity}
      >
        {children}
      </TouchRipple>
    ) : undefined;

    return createChildFragment({
      focusRipple,
      touchRipple,
      children: touchRipple ? undefined : children,
    });
  }

  handleKeyDown = (event) => {
    if (!this.props.disabled && !this.props.disableKeyboardFocus) {
      if (keycode(event) === 'enter' && this.state.isKeyboardFocused) {
        this.handleTouchTap(event);
      }
      if (keycode(event) === 'esc' && this.state.isKeyboardFocused) {
        this.removeKeyboardFocus(event);
      }
    }
    this.props.onKeyDown(event);
  };

  handleKeyUp = (event) => {
    if (!this.props.disabled && !this.props.disableKeyboardFocus) {
      if (keycode(event) === 'space' && this.state.isKeyboardFocused) {
        this.handleTouchTap(event);
      }
    }
    this.props.onKeyUp(event);
  };

  handleBlur = (event) => {
    this.cancelFocusTimeout();
    this.removeKeyboardFocus(event);
    this.props.onBlur(event);
  };

  handleFocus = (event) => {
    if (event) event.persist();
    if (!this.props.disabled && !this.props.disableKeyboardFocus) {
      // setTimeout is needed because the focus event fires first
      // Wait so that we can capture if this was a keyboard focus
      // or touch focus
      this.focusTimeout = setTimeout(() => {
        if (tabPressed) {
          this.setKeyboardFocus(event);
          tabPressed = false;
        }
      }, 150);

      this.props.onFocus(event);
    }
  };

  handleClick = (event) => {
    if (!this.props.disabled) {
      tabPressed = false;
      this.props.onClick(event);
    }
  };

  handleTouchTap = (event) => {
    this.cancelFocusTimeout();
    if (!this.props.disabled) {
      tabPressed = false;
      this.removeKeyboardFocus(event);
      this.props.onTouchTap(event);
    }
  };

  render() {
    const {
      centerRipple, // eslint-disable-line no-unused-vars
      children,
      containerElement,
      disabled,
      disableFocusRipple, // eslint-disable-line no-unused-vars
      disableKeyboardFocus, // eslint-disable-line no-unused-vars
      disableTouchRipple, // eslint-disable-line no-unused-vars
      focusRippleColor, // eslint-disable-line no-unused-vars
      focusRippleOpacity, // eslint-disable-line no-unused-vars
      href,
      keyboardFocused, // eslint-disable-line no-unused-vars
      touchRippleColor, // eslint-disable-line no-unused-vars
      touchRippleOpacity, // eslint-disable-line no-unused-vars
      onBlur, // eslint-disable-line no-unused-vars
      onClick, // eslint-disable-line no-unused-vars
      onFocus, // eslint-disable-line no-unused-vars
      onKeyUp, // eslint-disable-line no-unused-vars
      onKeyDown, // eslint-disable-line no-unused-vars
      onKeyboardFocus, // eslint-disable-line no-unused-vars
      onTouchTap, // eslint-disable-line no-unused-vars
      style,
      tabIndex,
      type,
      ...other
    } = this.props;

    const {
      prepareStyles,
      enhancedButton,
    } = this.context.muiTheme;

    const mergedStyles = Object.assign({
      border: 10,
      boxSizing: 'border-box',
      display: 'inline-block',
      fontFamily: this.context.muiTheme.baseTheme.fontFamily,
      WebkitTapHighlightColor: enhancedButton.tapHighlightColor, // Remove mobile color flashing (deprecated)
      cursor: disabled ? 'default' : 'pointer',
      textDecoration: 'none',
      margin: 0,
      padding: 0,
      outline: 'none',
      fontSize: 'inherit',
      fontWeight: 'inherit',
      verticalAlign: href ? 'middle' : null,
    }, style);

    // Passing both background:none & backgroundColor can break due to object iteration order
    if (!mergedStyles.backgroundColor && !mergedStyles.background) {
      mergedStyles.background = 'none';
    }

    if (disabled && href) {
      return (
        <span
          {...other}
          style={mergedStyles}
        >
          {children}
        </span>
      );
    }

    const buttonProps = {
      ...other,
      style: prepareStyles(mergedStyles),
      ref: 'enhancedButton',
      disabled: disabled,
      href: href,
      onBlur: this.handleBlur,
      onClick: this.handleClick,
      onFocus: this.handleFocus,
      onKeyUp: this.handleKeyUp,
      onKeyDown: this.handleKeyDown,
      onTouchTap: this.handleTouchTap,
      tabIndex: disabled || disableKeyboardFocus ? -1 : tabIndex,
    };

    const buttonChildren = this.createButtonChildren();

    if (React.isValidElement(containerElement)) {
      return React.cloneElement(containerElement, buttonProps, buttonChildren);
    }

    if (!href && containerElement === 'button') {
      buttonProps.type = type;
    }

    return React.createElement(href ? 'a' : containerElement, buttonProps, buttonChildren);
  }
}

export default EnhancedButton;
<|endoftext|>


<commit_before>"use strict"; // catch errors easier

const github = require("../github.js"); // GitHub wrapper initialization
const cfg = require("../config.js"); // config file
const newComment = require("../issues/newComment.js"); // create comment

module.exports = exports = function(areaLabel, issueNumber, repoName, repoOwner, issueLabelArray) {
  if (!cfg.areaLabels.has(areaLabel)) return; // if added label isn't an area label, return;
  const areaLabelTeam = cfg.areaLabels.get(areaLabel); // find corresponding area label team
  github.issues.getComments({
    owner: repoOwner,
    repo: repoName,
    number: issueNumber,
    per_page: 100
  }).then((issueComments) => {
    const labelComment = issueComments.data.find((issueComment) => {
      return issueComment.body.includes("this issue was labeled with the") && issueComment.user.login === cfg.username;
    });
    if (labelComment) {
      let issueLabels = []; // initialize array for area labels
      let labelTeams = [];
      issueLabelArray.forEach((issueLabel) => {
        const labelName = issueLabel.name; // label name
        if (cfg.areaLabels.has(labelName) && !issueLabels.includes(labelName)) {
          issueLabels.push(labelName); // push all associated area labels to array
          labelTeams.push(cfg.areaLabels.get(labelName)); // push all associated area labels to array
        }
      }); // add all issue label names and area label teams to issueLabels to labelTeams
      const areaLabelTeams = labelTeams.join(`, @${repoOwner}/`);
      const referencedAreaLabels = issueLabels.join("\", \""); // join corresponding area label teams into one string
      let labelGrammar;
      if (labelTeams.length > 1) {
        labelGrammar = "labels";
      } else if (labelTeams.length === 1) {
        labelGrammar = "label";
      } else return;
      const comment = `Hello @${repoOwner}/${areaLabelTeams} members, this issue was labeled with the "${referencedAreaLabels}" ${labelGrammar}, so you may want to check it out!`; // comment template
      github.issues.editComment({
        owner: repoOwner,
        repo: repoName,
        id: labelComment.id,
        body: comment
      }).catch(console.error);
    } else {
      const comment = `Hello @${repoOwner}/${areaLabelTeam} members, this issue was labeled with the **${areaLabel}** label, so you may want to check it out!`; // comment template
      newComment(repoOwner, repoName, issueNumber, comment); // create comment
    }
  });
};
<commit_msg>issues: Eliminate duplicate issue reference when labeled simultaneously.<commit_after>"use strict"; // catch errors easier

const github = require("../github.js"); // GitHub wrapper initialization
const cfg = require("../config.js"); // config file
const newComment = require("../issues/newComment.js"); // create comment
let referencedIssues = [];

module.exports = exports = function(areaLabel, issueNumber, repoName, repoOwner, issueLabelArray) {
  if (!cfg.areaLabels.has(areaLabel)) return; // if added label isn't an area label, return;
  github.issues.getComments({
    owner: repoOwner,
    repo: repoName,
    number: issueNumber,
    per_page: 100
  }).then((issueComments) => {
    let issueLabels = []; // initialize array for area labels
    let labelTeams = [];
    issueLabelArray.forEach((issueLabel) => {
      const labelName = issueLabel.name; // label name
      if (cfg.areaLabels.has(labelName) && !issueLabels.includes(labelName)) {
        issueLabels.push(labelName); // push all associated area labels to array
        labelTeams.push(cfg.areaLabels.get(labelName)); // push all associated area labels to array
      }
    }); // add all issue label names and area label teams to issueLabels to labelTeams
    const areaLabelTeams = labelTeams.join(`, @${repoOwner}/`);
    const referencedAreaLabels = issueLabels.join("**, **"); // join corresponding area label teams into one string
    let labelGrammar;
    if (labelTeams.length > 1) {
      labelGrammar = "labels";
    } else if (labelTeams.length === 1) {
      labelGrammar = "label";
    } else return;
    const comment = `Hello @${repoOwner}/${areaLabelTeams} members, this issue was labeled with the **${referencedAreaLabels}** ${labelGrammar}, so you may want to check it out!`; // comment template
    const labelComment = issueComments.data.find((issueComment) => {
      return issueComment.body.includes("this issue was labeled with the") && issueComment.user.login === cfg.username;
    });
    if (labelComment) {
      github.issues.editComment({
        owner: repoOwner,
        repo: repoName,
        id: labelComment.id,
        body: comment
      }).catch(console.error);
    } else {
      if (referencedIssues.includes(issueNumber)) return;
      newComment(repoOwner, repoName, issueNumber, comment); // create comment
      referencedIssues.push(issueNumber);
      setTimeout(() => {
        referencedIssues.splice(referencedIssues.indexOf(issueNumber), 1);
      }, 1000);
    }
  });
};
<|endoftext|>


<commit_before>/*global angular*/
(function () {
    "use strict";

    var app = angular.module('myApp', ['ng-admin']);

    app.directive('customPostLink', ['$location', function ($location) {
        return {
            restrict: 'E',
            template: 'View post',
            link: function ($scope) {
                $scope.displayPost = function (entry) {
                    var postId = entry.values.post_id;

                    $location.path('/edit/posts/' + postId);
                };
            }
        };
    }]);

    app.config(function (NgAdminConfigurationProvider, Application, Entity, Field, Reference, ReferencedList,
                         ReferenceMany, DashboardView, ListView, CreateView, EditView, DeleteView) {

        function truncate(value) {
            if (!value) {
                return '';
            }

            return value.length > 50 ? value.substr(0, 50) + '...' : value;
        }

        function pagination(page, maxPerPage) {
            return {
                _start: (page - 1) * maxPerPage,
                _end: page * maxPerPage
            };
        }

        var app = new Application('ng-admin backend demo') // application main title
            .baseApiUrl('http://localhost:3000/'); // main API endpoint

        // define all entities at the top to allow references between them
        var post = new Entity('posts'); // the API endpoint for posts will be http://localhost:3000/posts/:id

        var comment = new Entity('comments')
            .identifier(new Field('id')) // you can optionally customize the identifier used in the api ('id' by default)
            .addMappedField(new Field('post_id')); // a field to be read from the API, even if not displayed in any view (used later in template field)

        var tag = new Entity('tags');

        // set the application entities
        app
            .addEntity(tag)
            .addEntity(post)
            .addEntity(comment);

        // customize entities and views
        post
            .order(1) // post should be the first item in the sidebar menu
            .addView(new DashboardView('post-dashboard') // initialize a view with a name to ease routing
                .order(1) // display the post panel first in the dashboard
                .limit(5) // limit the panel to the 5 latest posts
                .pagination(pagination) // use the custom pagination function to format the API request correctly
                .label('Recent posts')
                .addField(new Field('title').isEditLink(true).map(truncate))
            )
            .addView(new ListView('post-list') // initialize the datagrid
                .title('All posts') // default title is "List of posts"
                .pagination(pagination)
                .addField(new Field('id').label('ID'))
                .addField(new Field('title')) // the default list field type is "string", and displays as a string
                .addField(new ReferenceMany('tags') // a Reference is a particular type of field that references another entity
                    .targetEntity(tag) // the tag entity is defined later in this file
                    .targetField(new Field('name')) // the field to be displayed in this list
                )
            )
            .addView(new CreateView('post-create') // initialize the creation form
                .title('Add a new post') // default title is "Create a post"
                .addField(new Field('title')) // the default edit field type is "string", and displays as a text input
                .addField(new Field('body').type('wysiwyg')) // overriding the type allows rich text editing for the body
            )
            .addView(new EditView('post-edit') // initialize the edition form
                .addField(new Field('title'))
                .addField(new Field('body').type('wysiwyg'))
                .addField(new ReferenceMany('tags')
                    .targetEntity(tag)
                    .targetField(new Field('name'))
                )
                .addField(new ReferencedList('comments')
                    .targetEntity(comment)
                    .targetReferenceField('post_id')
                    .targetFields([
                        new Field('id'),
                        new Field('body').label('Comment')
                    ])
                )
            )
            .addView(new DeleteView('post-delete') // initialize the deletion confirmation page
                .title('Delete a post')
            );

        comment
            .order(2) // comment should be the second item in the sidebar menu
            .addView(new DashboardView('comment-dashboard')
                .order(2) // display the comment panel second in the dashboard
                .limit(5)
                .pagination(pagination)
                .label('Last comments')
                .addField(new Field('id'))
                .addField(new Field('body').label('Comment').map(truncate))
                .addField(new Field() // template fields don't need a name
                    .type('template') // a field which uses a custom template
                    .label('Actions')
                    .template(function () { // template() can take a function or a string
                        return '<custom-post-link></custom-post-link>'; // you can use custom directives, too
                    })
                )
            )
            .addView(new ListView('comment-list')
                .title('Comments')
                .description('List of all comments with an infinite pagination') // description appears under the title
                .pagination(pagination)
                .addField(new Field('id').label('ID'))
                .addField(new Reference('post_id')
                    .label('Post title')
                    .map(truncate)
                    .targetEntity(post)
                    .targetField(new Field('title'))
                )
                .addField(new Field('body').map(truncate))
                .addField(new Field('created_at').label('Creation date').type('date'))
                .addQuickFilter('Today', function () { // a quick filter displays a button to filter the list based on a set of query parameters passed to the API
                    var now = new Date(),
                        year = now.getFullYear(),
                        month = now.getMonth() + 1,
                        day = now.getDate();
                    month = month < 10 ? '0' + month : month;
                    day = day < 10 ? '0' + day : day;
                    return {
                        created_at: [year, month, day].join('-') // ?created_at=... will be appended to the API call
                    };
                })
                )
            .addView(new CreateView('comment-create')
                .addField(new Reference('post_id')
                    .label('Post title')
                    .map(truncate)
                    .targetEntity(post)
                    .targetField(new Field('title'))
                )
                .addField(new Field('body').type('wysiwyg'))
            )
            .addView(new EditView('comment-edit')
                .addField(new Reference('post_id')
                    .label('Post title')
                    .map(truncate)
                    .targetEntity(post)
                    .targetField(new Field('title'))
                )
                .addField(new Field('body').type('wysiwyg'))
                .addField(new Field('created_at').label('Creation date').type('date'))
                .addField(new Field()
                    .type('template')
                    .label('Actions')
                    .template('<custom-post-link></custom-post-link>') // template() can take a function or a string
                )
                )
            .addView(new DeleteView('comment-delete')
                .title('Delete a comment')
            );

        tag
            .order(3)
            .addView(new DashboardView('tag-dashboard')
                .order(3)
                .limit(10)
                .pagination(pagination)
                .label('Recent tags')
                .addField(new Field('id').label('ID'))
                .addField(new Field('name'))
                .addField(new Field('published').label('Is published ?').type('boolean'))
            )
            .addView(new ListView('tags-list')
                .title('List of all tags')
                .infinitePagination(false) // by default, the list view uses infinite pagination. Set to false to use regulat pagination
                .pagination(pagination)
                .addField(new Field('id').label('ID'))
                .addField(new Field('name'))
                .addField(new Field('published').type('boolean'))
                .addField(new Field('custom')
                    .type('template')
                    .label('Upper name')
                    .template(function () {
                        return '{{ entry.values.name.toUpperCase() }}';
                    })
                )
            )
            .addView(new CreateView('tags-create')
                .addField(new Field('name')
                    .type('string')
                    .validation({
                        "required": true,
                        "max-length" : 150
                    })
                )
                .addField(new Field('published').type('boolean'))
            )
            .addView(new EditView('tags_edit')
                .addField(new Field('name').editable(false))
                .addField(new Field('published').type('boolean'))
            )
            .addView(new DeleteView('tags-delete')
                .title('Delete a tag')
            );

        NgAdminConfigurationProvider.configure(app);
    });
}());
<commit_msg>Update example<commit_after>/*global angular*/
(function () {
    "use strict";

    var app = angular.module('myApp', ['ng-admin']);

    app.directive('customPostLink', ['$location', function ($location) {
        return {
            restrict: 'E',
            template: 'View post',
            link: function ($scope) {
                $scope.displayPost = function (entry) {
                    var postId = entry.values.post_id;

                    $location.path('/edit/posts/' + postId);
                };
            }
        };
    }]);

    app.config(function (NgAdminConfigurationProvider, Application, Entity, Field, Reference, ReferencedList,
                         ReferenceMany, DashboardView, ListView, CreateView, EditView, DeleteView) {

        function truncate(value) {
            if (!value) {
                return '';
            }

            return value.length > 50 ? value.substr(0, 50) + '...' : value;
        }

        function pagination(page, maxPerPage) {
            return {
                _start: (page - 1) * maxPerPage,
                _end: page * maxPerPage
            };
        }

        var app = new Application('ng-admin backend demo') // application main title
            .baseApiUrl('http://localhost:3000/'); // main API endpoint

        // define all entities at the top to allow references between them
        var post = new Entity('posts'); // the API endpoint for posts will be http://localhost:3000/posts/:id

        var comment = new Entity('comments')
            .identifier(new Field('id')) // you can optionally customize the identifier used in the api ('id' by default)
            .addMappedField(new Field('post_id')); // a field to be read from the API, even if not displayed in any view (used later in template field)

        var tag = new Entity('tags');

        // set the application entities
        app
            .addEntity(tag)
            .addEntity(post)
            .addEntity(comment);

        // customize entities and views
        post
            .order(1) // post should be the first item in the sidebar menu
            .addView(new DashboardView('post-dashboard') // initialize a view with a name to ease routing
                .order(1) // display the post panel first in the dashboard
                .limit(5) // limit the panel to the 5 latest posts
                .pagination(pagination) // use the custom pagination function to format the API request correctly
                .title('Recent posts')
                .addField(new Field('title').isEditLink(true).map(truncate))
            )
            .addView(new ListView('post-list') // initialize the datagrid
                .title('All posts') // default title is "List of posts"
                .pagination(pagination)
                .addField(new Field('id').label('ID'))
                .addField(new Field('title')) // the default list field type is "string", and displays as a string
                .addField(new ReferenceMany('tags') // a Reference is a particular type of field that references another entity
                    .targetEntity(tag) // the tag entity is defined later in this file
                    .targetField(new Field('name')) // the field to be displayed in this list
                )
            )
            .addView(new CreateView('post-create') // initialize the creation form
                .title('Add a new post') // default title is "Create a post"
                .addField(new Field('title')) // the default edit field type is "string", and displays as a text input
                .addField(new Field('body').type('wysiwyg')) // overriding the type allows rich text editing for the body
            )
            .addView(new EditView('post-edit') // initialize the edition form
                .addField(new Field('title'))
                .addField(new Field('body').type('wysiwyg'))
                .addField(new ReferenceMany('tags')
                    .targetEntity(tag)
                    .targetField(new Field('name'))
                )
                .addField(new ReferencedList('comments')
                    .targetEntity(comment)
                    .targetReferenceField('post_id')
                    .targetFields([
                        new Field('id'),
                        new Field('body').label('Comment')
                    ])
                )
            )
            .addView(new DeleteView('post-delete') // initialize the deletion confirmation page
                .title('Delete a post')
            );

        comment
            .order(2) // comment should be the second item in the sidebar menu
            .addView(new DashboardView('comment-dashboard')
                .order(2) // display the comment panel second in the dashboard
                .limit(5)
                .pagination(pagination)
                .title('Last comments')
                .addField(new Field('id'))
                .addField(new Field('body').label('Comment').map(truncate))
                .addField(new Field() // template fields don't need a name
                    .type('template') // a field which uses a custom template
                    .label('Actions')
                    .template(function () { // template() can take a function or a string
                        return '<custom-post-link></custom-post-link>'; // you can use custom directives, too
                    })
                )
            )
            .addView(new ListView('comment-list')
                .title('Comments')
                .description('List of all comments with an infinite pagination') // description appears under the title
                .pagination(pagination)
                .addField(new Field('id').label('ID'))
                .addField(new Reference('post_id')
                    .label('Post title')
                    .map(truncate)
                    .targetEntity(post)
                    .targetField(new Field('title'))
                )
                .addField(new Field('body').map(truncate))
                .addField(new Field('created_at').label('Creation date').type('date'))
                .addQuickFilter('Today', function () { // a quick filter displays a button to filter the list based on a set of query parameters passed to the API
                    var now = new Date(),
                        year = now.getFullYear(),
                        month = now.getMonth() + 1,
                        day = now.getDate();
                    month = month < 10 ? '0' + month : month;
                    day = day < 10 ? '0' + day : day;
                    return {
                        created_at: [year, month, day].join('-') // ?created_at=... will be appended to the API call
                    };
                })
                )
            .addView(new CreateView('comment-create')
                .addField(new Reference('post_id')
                    .label('Post title')
                    .map(truncate)
                    .targetEntity(post)
                    .targetField(new Field('title'))
                )
                .addField(new Field('body').type('wysiwyg'))
            )
            .addView(new EditView('comment-edit')
                .addField(new Reference('post_id')
                    .label('Post title')
                    .map(truncate)
                    .targetEntity(post)
                    .targetField(new Field('title'))
                )
                .addField(new Field('body').type('wysiwyg'))
                .addField(new Field('created_at').label('Creation date').type('date'))
                .addField(new Field()
                    .type('template')
                    .label('Actions')
                    .template('<custom-post-link></custom-post-link>') // template() can take a function or a string
                )
                )
            .addView(new DeleteView('comment-delete')
                .title('Delete a comment')
            );

        tag
            .order(3)
            .addView(new DashboardView('tag-dashboard')
                .order(3)
                .limit(10)
                .pagination(pagination)
                .title('Recent tags')
                .addField(new Field('id').label('ID'))
                .addField(new Field('name'))
                .addField(new Field('published').label('Is published ?').type('boolean'))
            )
            .addView(new ListView('tags-list')
                .title('List of all tags')
                .infinitePagination(false) // by default, the list view uses infinite pagination. Set to false to use regulat pagination
                .pagination(pagination)
                .addField(new Field('id').label('ID'))
                .addField(new Field('name'))
                .addField(new Field('published').type('boolean'))
                .addField(new Field('custom')
                    .type('template')
                    .label('Upper name')
                    .template(function () {
                        return '{{ entry.values.name.toUpperCase() }}';
                    })
                )
            )
            .addView(new CreateView('tags-create')
                .addField(new Field('name')
                    .type('string')
                    .validation({
                        "required": true,
                        "max-length" : 150
                    })
                )
                .addField(new Field('published').type('boolean'))
            )
            .addView(new EditView('tags_edit')
                .addField(new Field('name').editable(false))
                .addField(new Field('published').type('boolean'))
            )
            .addView(new DeleteView('tags-delete')
                .title('Delete a tag')
            );

        NgAdminConfigurationProvider.configure(app);
    });
}());
<|endoftext|>