<commit_before>var EnglishTengwarTranscriber2 = function()
{
    var runeToPhonemeMap = {};

    // Combinations.
    runeToPhonemeMap[[ TengwaRune.THREE_DOTS, TengwaRune.YANTA ]] = "ai";
    runeToPhonemeMap[[ TengwaRune.BAR, TengwaRune.ANDO ]] = "and";
    runeToPhonemeMap[[ TengwaRune.DOT, TengwaRune.DOT ]] = "ee";
    runeToPhonemeMap[[ TengwaRune.LEFT_CURL, TengwaRune.LONG_CARRIER ]] = "oo";
    runeToPhonemeMap[[ TengwaRune.ACUTE, TengwaRune.LONG_CARRIER ]] = "y";

    // Check for missing entries.
    // {
    // var values = TengwaRune.values;
    // var properties = TengwaRune.properties;
    //
    // for (var i = 0; i < values.length; i++)
    // {
    // var rune = values[i];
    //
    // if (!runeToPhonemeMap[rune])
    // {
    // LOGGER.error("Missing language letter for "
    // + properties[rune].name);
    // }
    // }
    // }

    var phonemeToLanguageMap = {};

    phonemeToLanguageMap["akkount"] = "account";
    phonemeToLanguageMap["akownt"] = "account";
    phonemeToLanguageMap["aje"] = "age";
    phonemeToLanguageMap["az"] = "as";
    phonemeToLanguageMap["kataklysm"] = "cataclysm";
    phonemeToLanguageMap["certan"] = "certain";
    phonemeToLanguageMap["kristofer"] = "christopher";
    phonemeToLanguageMap["kome"] = "come";
    phonemeToLanguageMap["druedaiin"] = "druedain";
    phonemeToLanguageMap["hireen"] = "herein";
    phonemeToLanguageMap["hobbets"] = "hobbits";
    phonemeToLanguageMap["iz"] = "is";
    phonemeToLanguageMap["jhon"] = "john";
    phonemeToLanguageMap["keng"] = "king";
    phonemeToLanguageMap["destruktion"] = "destruction";
    phonemeToLanguageMap["oksford"] = "oxford";
    phonemeToLanguageMap["powr"] = "power";
    phonemeToLanguageMap["rekovery"] = "recovery";
    phonemeToLanguageMap["riuil"] = "reuel";
    phonemeToLanguageMap["reng"] = "ring";
    phonemeToLanguageMap["skolars"] = "scholars";
    phonemeToLanguageMap["sit"] = "set";
    phonemeToLanguageMap["tolkein"] = "tolkien";
    phonemeToLanguageMap["wor"] = "war";
    phonemeToLanguageMap["wistmarch"] = "westmarch";

    this.getPhonemeToLanguageMap = function()
    {
        return phonemeToLanguageMap;
    }

    this.getRuneToPhonemeMap = function()
    {
        return runeToPhonemeMap;
    }
}

EnglishTengwarTranscriber2.prototype.convertWord = function(word)
{
    var answer = word;
    var map = this.getPhonemeToLanguageMap();
    var word2 = map[word];

    if (word2)
    {
        answer = word2;
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.determineFontLetter = function(rune)
{
    if (!rune) { throw new Error("rune " + rune + " is undefined"); }

    var answer;

    if (Array.isArray(rune))
    {
        answer = [];

        for (var i = 0; i < rune.length; i++)
        {
            var rune2 = rune[i];

            if (this.isPreVowel(rune2))
            {
                if (i + 2 < rune.length && rune2 === "dot"
                        && rune[i + 1] === "dot"
                        && !this.isPreVowel(rune[i + 2]))
                {
                    answer[answer.length] = this
                            .determineFontLetter(rune[i + 2]);
                    answer[answer.length] = "B"; // DOT3
                    i += 2;
                }
                else if (i + 1 < rune.length)
                {
                    answer[answer.length] = this
                            .determineFontLetter(rune[i + 1]);
                    i++;
                }

                answer[answer.length] = this.determineFontLetter(rune2);
            }
            else
            {
                answer[answer.length] = this.determineFontLetter(rune2);
            }
        }
    }
    else
    {
        var properties = TengwaRune.properties;
        try
        {
            var fontLetter = properties[rune].fontLetter;

            if (fontLetter)
            {
                answer = fontLetter;
            }
        }
        catch (e)
        {
            LOGGER.error("Unknown rune " + rune);
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.determineLanguageLetter = function(phoneme)
{
    var answer;

    if (Array.isArray(phoneme))
    {
        answer = "";

        for (var i = 0; i < phoneme.length; i++)
        {
            answer += this.determineLanguageLetter(phoneme[i]);
        }
    }
    else
    {
        answer = phoneme;
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.determinePhoneme = function(rune)
{
    var answer = "?";

    var map = this.getRuneToPhonemeMap();
    var letter = map[rune];

    if (letter)
    {
        answer = letter;
    }
    else
    {
        if (Array.isArray(rune))
        {
            answer = [];

            if (rune.length === 2 && rune[1] == "shortCarrier")
            {
                answer[answer.length] = this.determinePhoneme(rune[0]);
            }
            else if (rune.length === 3 && rune[1] == "shortCarrier")
            {
                answer[answer.length] = this.determinePhoneme(rune[0]);
                answer[answer.length] = this.determinePhoneme(rune[2]);
            }
            else
            {
                for (var i = 0; i < rune.length; i++)
                {
                    if (rune[i] === "underBar" && i - 1 >= 0)
                    {
                        // Repeat the previous letter.
                        answer[answer.length] = this
                                .determinePhoneme(rune[i - 1]);
                    }
                    else
                    {
                        answer[answer.length] = this.determinePhoneme(rune[i]);
                    }
                }
            }
        }
        else
        {
            var properties = TengwaRune.properties;
            var phoneme = properties[rune].phoneme;

            answer = phoneme;
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.isPreVowel = function(rune)
{
    return rune === "acute" || rune === "bar" || rune === "dot"
            || rune === "leftCurl" || rune === "rightCurl"
            || rune === "threeDots" || rune === "topCurl";
}

EnglishTengwarTranscriber2.prototype.phonemesToLanguageWords = function(
        phonemes)
{
    var answer = [];

    var word = "";

    for (var i = 0; i < phonemes.length; i++)
    {
        var phoneme = phonemes[i];

        if (phoneme === " " || phoneme === "," || phoneme === "."
                || phoneme === "\n")
        {
            answer[answer.length] = this.convertWord(word);
            answer[answer.length] = phoneme;
            word = "";
        }
        else if (i === phonemes.length - 1)
        {
            word += this.determineLanguageLetter(phoneme);
            answer[answer.length] = this.convertWord(word);
        }
        else
        {
            word += this.determineLanguageLetter(phoneme);
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.runesToFontLetters = function(runes)
{
    var answer = [];

    for (var i = 0; i < runes.length; i++)
    {
        var rune = runes[i];

        if (!rune) { throw new Error("rune is undefined from " + i + " "
                + runes); }

        if (rune !== "newline")
        {
            answer[answer.length] = this.determineFontLetter(rune);
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.runesToLanguageWords = function(runes)
{
    var phonemes = this.runesToPhonemes(runes);
    var answer = this.phonemesToLanguageWords(phonemes);

    return answer;
}

EnglishTengwarTranscriber2.prototype.runesToPhonemes = function(runes)
{
    var answer = [];

    for (var i = 0; i < runes.length; i++)
    {
        var rune = runes[i];

        if (rune === "underBar" && i - 1 >= 0)
        {
            // Repeat the previous letter.
            answer[answer.length] = runes[i - 1];
        }
        else
        {
            answer[answer.length] = this.determinePhoneme(rune);
        }
    }

    return answer;
}

if (Object.freeze)
{
    Object.freeze(EnglishTengwarTranscriber2);
}
<commit_msg>Code cleanup.<commit_after>var EnglishTengwarTranscriber2 = function()
{
    var runeToPhonemeMap = {};

    // Combinations.
    runeToPhonemeMap[[ TengwaRune.THREE_DOTS, TengwaRune.YANTA ]] = "ai";
    runeToPhonemeMap[[ TengwaRune.BAR, TengwaRune.ANDO ]] = "and";
    runeToPhonemeMap[[ TengwaRune.DOT, TengwaRune.DOT ]] = "ee";
    runeToPhonemeMap[[ TengwaRune.LEFT_CURL, TengwaRune.LONG_CARRIER ]] = "oo";
    runeToPhonemeMap[[ TengwaRune.ACUTE, TengwaRune.LONG_CARRIER ]] = "y";

    // Check for missing entries.
    // {
    // var values = TengwaRune.values;
    // var properties = TengwaRune.properties;
    //
    // for (var i = 0; i < values.length; i++)
    // {
    // var rune = values[i];
    //
    // if (!runeToPhonemeMap[rune])
    // {
    // LOGGER.error("Missing language letter for "
    // + properties[rune].name);
    // }
    // }
    // }

    var phonemeToLanguageMap = {};

    // The Lord Of The Rings
    // Christopher reversed 'e' and 'i' from J.R.R.?
    phonemeToLanguageMap["az"] = "as";
    phonemeToLanguageMap["hireen"] = "herein";
    phonemeToLanguageMap["hobbets"] = "hobbits";
    phonemeToLanguageMap["iz"] = "is";
    phonemeToLanguageMap["jhon"] = "john";
    phonemeToLanguageMap["keng"] = "king";
    phonemeToLanguageMap["riuil"] = "reuel";
    phonemeToLanguageMap["reng"] = "ring";
    phonemeToLanguageMap["sit"] = "set";
    phonemeToLanguageMap["tolkein"] = "tolkien";
    phonemeToLanguageMap["wor"] = "war";
    phonemeToLanguageMap["wistmarch"] = "westmarch";

    // The Silmarillion
    phonemeToLanguageMap["aje"] = "age";
    phonemeToLanguageMap["kome"] = "come";
    phonemeToLanguageMap["powr"] = "power";
    phonemeToLanguageMap["rekovery"] = "recovery";

    // Unfinished Tales Of Numenor And Middle-Earth
    phonemeToLanguageMap["akkount"] = "account";
    phonemeToLanguageMap["kristofer"] = "christopher";
    phonemeToLanguageMap["druedaiin"] = "druedain";

    // Sauron Defeated
    phonemeToLanguageMap["akownt"] = "account";
    phonemeToLanguageMap["kataklysm"] = "cataclysm";
    phonemeToLanguageMap["certan"] = "certain";
    phonemeToLanguageMap["destruktion"] = "destruction";
    phonemeToLanguageMap["oksford"] = "oxford";
    phonemeToLanguageMap["skolars"] = "scholars";

    this.getPhonemeToLanguageMap = function()
    {
        return phonemeToLanguageMap;
    }

    this.getRuneToPhonemeMap = function()
    {
        return runeToPhonemeMap;
    }
}

EnglishTengwarTranscriber2.prototype.convertWord = function(word)
{
    var answer = word;
    var map = this.getPhonemeToLanguageMap();
    var word2 = map[word];

    if (word2)
    {
        answer = word2;
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.determineFontLetter = function(rune)
{
    if (!rune) { throw new Error("rune " + rune + " is undefined"); }

    var answer;

    if (Array.isArray(rune))
    {
        answer = [];

        for (var i = 0; i < rune.length; i++)
        {
            var rune2 = rune[i];

            if (this.isPreVowel(rune2))
            {
                if (i + 2 < rune.length && rune2 === "dot"
                        && rune[i + 1] === "dot"
                        && !this.isPreVowel(rune[i + 2]))
                {
                    answer[answer.length] = this
                            .determineFontLetter(rune[i + 2]);
                    answer[answer.length] = "B"; // DOT3
                    i += 2;
                }
                else if (i + 1 < rune.length)
                {
                    answer[answer.length] = this
                            .determineFontLetter(rune[i + 1]);
                    i++;
                }

                answer[answer.length] = this.determineFontLetter(rune2);
            }
            else
            {
                answer[answer.length] = this.determineFontLetter(rune2);
            }
        }
    }
    else
    {
        var properties = TengwaRune.properties;
        try
        {
            var fontLetter = properties[rune].fontLetter;

            if (fontLetter)
            {
                answer = fontLetter;
            }
        }
        catch (e)
        {
            LOGGER.error("Unknown rune " + rune);
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.determineLanguageLetter = function(phoneme)
{
    var answer;

    if (Array.isArray(phoneme))
    {
        answer = "";

        for (var i = 0; i < phoneme.length; i++)
        {
            answer += this.determineLanguageLetter(phoneme[i]);
        }
    }
    else
    {
        answer = phoneme;
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.determinePhoneme = function(rune)
{
    var answer = "?";

    var map = this.getRuneToPhonemeMap();
    var letter = map[rune];

    if (letter)
    {
        answer = letter;
    }
    else
    {
        if (Array.isArray(rune))
        {
            answer = [];

            if (rune.length === 2 && rune[1] == "shortCarrier")
            {
                answer[answer.length] = this.determinePhoneme(rune[0]);
            }
            else if (rune.length === 3 && rune[1] == "shortCarrier")
            {
                answer[answer.length] = this.determinePhoneme(rune[0]);
                answer[answer.length] = this.determinePhoneme(rune[2]);
            }
            else
            {
                for (var i = 0; i < rune.length; i++)
                {
                    if (rune[i] === "underBar" && i - 1 >= 0)
                    {
                        // Repeat the previous letter.
                        answer[answer.length] = this
                                .determinePhoneme(rune[i - 1]);
                    }
                    else
                    {
                        answer[answer.length] = this.determinePhoneme(rune[i]);
                    }
                }
            }
        }
        else
        {
            var properties = TengwaRune.properties;
            var phoneme = properties[rune].phoneme;

            answer = phoneme;
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.isPreVowel = function(rune)
{
    return rune === "acute" || rune === "bar" || rune === "dot"
            || rune === "leftCurl" || rune === "rightCurl"
            || rune === "threeDots" || rune === "topCurl";
}

EnglishTengwarTranscriber2.prototype.phonemesToLanguageWords = function(
        phonemes)
{
    var answer = [];

    var word = "";

    for (var i = 0; i < phonemes.length; i++)
    {
        var phoneme = phonemes[i];

        if (phoneme === " " || phoneme === "," || phoneme === "."
                || phoneme === "\n")
        {
            answer[answer.length] = this.convertWord(word);
            answer[answer.length] = phoneme;
            word = "";
        }
        else if (i === phonemes.length - 1)
        {
            word += this.determineLanguageLetter(phoneme);
            answer[answer.length] = this.convertWord(word);
        }
        else
        {
            word += this.determineLanguageLetter(phoneme);
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.runesToFontLetters = function(runes)
{
    var answer = [];

    for (var i = 0; i < runes.length; i++)
    {
        var rune = runes[i];

        if (!rune) { throw new Error("rune is undefined from " + i + " "
                + runes); }

        if (rune !== "newline")
        {
            answer[answer.length] = this.determineFontLetter(rune);
        }
    }

    return answer;
}

EnglishTengwarTranscriber2.prototype.runesToLanguageWords = function(runes)
{
    var phonemes = this.runesToPhonemes(runes);
    var answer = this.phonemesToLanguageWords(phonemes);

    return answer;
}

EnglishTengwarTranscriber2.prototype.runesToPhonemes = function(runes)
{
    var answer = [];

    for (var i = 0; i < runes.length; i++)
    {
        var rune = runes[i];

        if (rune === "underBar" && i - 1 >= 0)
        {
            // Repeat the previous letter.
            answer[answer.length] = runes[i - 1];
        }
        else
        {
            answer[answer.length] = this.determinePhoneme(rune);
        }
    }

    return answer;
}

if (Object.freeze)
{
    Object.freeze(EnglishTengwarTranscriber2);
}
<|endoftext|>


<commit_before>'use strict';

const assert = require('assert');

const WebSocket = require('..');

describe('WebSocket', () => {
  it('communicates successfully with echo service (ws)', (done) => {
    const ws = new WebSocket('ws://websocket-echo.com/', {
      protocolVersion: 13
    });
    const str = Date.now().toString();

    let dataReceived = false;

    ws.on('open', () => ws.send(str));
    ws.on('close', () => {
      assert.ok(dataReceived);
      done();
    });
    ws.on('message', (data) => {
      dataReceived = true;
      assert.strictEqual(data, str);
      ws.close();
    });
  });

  it('communicates successfully with echo service (wss)', (done) => {
    const ws = new WebSocket('wss://websocket-echo.com/', {
      protocolVersion: 13
    });
    const str = Date.now().toString();

    let dataReceived = false;

    ws.on('open', () => ws.send(str));
    ws.on('close', () => {
      assert.ok(dataReceived);
      done();
    });
    ws.on('message', (data) => {
      dataReceived = true;
      assert.strictEqual(data, str);
      ws.close();
    });
  });
});
<commit_msg>[test] Fix failing tests<commit_after>'use strict';

const assert = require('assert');

const WebSocket = require('..');

describe('WebSocket', () => {
  it('communicates successfully with echo service (ws)', (done) => {
    const ws = new WebSocket('ws://websocket-echo.com/', {
      protocolVersion: 13
    });

    let dataReceived = false;

    ws.on('open', () => {
      ws.send('hello');
    });

    ws.on('close', () => {
      assert.ok(dataReceived);
      done();
    });

    ws.on('message', (message, isBinary) => {
      dataReceived = true;
      assert.ok(!isBinary);
      assert.strictEqual(message.toString(), 'hello');
      ws.close();
    });
  });

  it('communicates successfully with echo service (wss)', (done) => {
    const ws = new WebSocket('wss://websocket-echo.com/', {
      protocolVersion: 13
    });

    let dataReceived = false;

    ws.on('open', () => {
      ws.send('hello');
    });

    ws.on('close', () => {
      assert.ok(dataReceived);
      done();
    });

    ws.on('message', (message, isBinary) => {
      dataReceived = true;
      assert.ok(!isBinary);
      assert.strictEqual(message.toString(), 'hello');
      ws.close();
    });
  });
});
<|endoftext|>


<commit_before>var ROWS = 20;
var COLS = 10;
var SIZE = 32;

var canvas;
var context;
var lineScore;
var currentBlock;
var isGameOver;
var previousTime;
var currentTime;

$(window).load(function(){

	canvas = document.getElementById('gameCanvas');
	context = canvas.getContext('2d');
	lineScore = $('#lines');
	previousTime = 0;
	currentTime = 0;
	startGame();
	$(document).keydown(getKeyCode);
	// drawBoard();
	// block = getRandomBlock()
	// drawBlock(block);
})

function startGame() {
	var row, col;
	currentLines = 0;
	isGameOver = false;

	gameData = new Array();

		for(row= 0; row < ROWS; row++) {
			gameData[row] = new Array();
			for(col = 0; col < COLS; col++) {
				// gameData[r].push(0);
				gameData[row][col] = 0;
			}
		}

	currentBlock = getRandomBlock();
	var requestAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
			window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

	window.requestAnimationFrame = requestAnimFrame;

	requestAnimationFrame(updateGame);
}

function drawBoard() {
	// context.drawImage(bgImg, 0, 0, 320, 640, 0, 0, 320, 640);
	context.rect(0, 0, 320, 640);
	context.fillStyle="blue";
	context.fill();
	context.lineWidth = "2";
	context.strokeStyle = "yellow";
	context.stroke();

	for(var row = 0; row < ROWS; row++) {
		for(var col = 0; col < COLS; col++) {
			if(gameData[row][col] != 0) {
				// context.drawImage(blockImg, (gameData[row][col] - 1) * SIZE, 0, SIZE, SIZE, col * SIZE, row * SIZE, SIZE, SIZE); -->
				context.rect(col * SIZE, row * SIZE, SIZE, SIZE);
				context.fillStyle="red";
				context.fill();
			}
		}
	}
}

function drawBlock(block) {
	var drawX = block.gridX;
	var drawY = block.gridY;
	var rotation = block.currentRotation;

// drawY = 10;

	for(var row = 0, len = block.rotations[rotation].length; row < len; row++) {
		for(var col = 0, len2 = block.rotations[rotation][row].length; col < len2; col++) {
			if(block.rotations[rotation][row][col] == 1 && drawY >= 0) {
				// context.drawImage(blockImg, block.color * SIZE, 0, SIZE, SIZE, drawX * SIZE, drawY * SIZE, SIZE, SIZE);
				// context.rect(drawX * SIZE, drawY * SIZE , SIZE, SIZE);
				context.beginPath();
				context.rect(drawX * SIZE, drawY * SIZE , SIZE, SIZE);
				context.fillStyle="green";
				context.fill();

			}
			drawX += 1;
		}

		drawX = block.gridX;
		drawY += 1;
	}
}

function getKeyCode(e) {
	// if(!e) { var e = window.event; }
	console.log(e);
	e.preventDefault();

	if(isGameOver != true) {
		switch(e.keyCode) {
			case 37: {
				if( validateMove(currentBlock.gridX - 1, currentBlock.gridY, currentBlock.currentRotation) )
					currentBlock.gridX--;
			}
			break;

			case 39: {
				if( validateMove(currentBlock.gridX + 1, currentBlock.gridY, currentBlock.currentRotation) )
					currentBlock.gridX++;
			}
			break;

			case 38: {
				var newRotation = currentBlock.currentRotation - 1;
				if(newRotation < 0)
					newRotation = currentBlock.rotations.length - 1;

				if( validateMove(currentBlock.gridX, currentBlock.gridY, newRotation) )
					currentBlock.currentRotation = newRotation;
			}
			break;

			case 40: {
				if( validateMove(currentBlock.gridX, currentBlock.gridY + 1, currentBlock.currentRotation) )
					currentBlock.gridY++;
			}
			break;
		}
	}
	else {
		startGame();
	}
}

function validateMove(xpos, ypos, newRotation)
{
	var result = true;
	var newx = xpos;
	var newy = ypos;

	for(var row = 0, length1 = currentBlock.rotations[newRotation].length; row < length1; row++) {
		for(var col = 0, length2 = currentBlock.rotations[newRotation][row].length; col < length2; col++) {
			if(newx < 0 || newx >= COLS) {
				result = false;
				col = length2;
				row = length1;
			}

			if(gameData[newy] != undefined && gameData[newy][newx] != 0
				&& currentBlock.rotations[newRotation][row] != undefined && currentBlock.rotations[newRotation][row][col] != 0) {
				result = false;
				col = length2;
				row = length1;
			}

			newx += 1;
		}

		newx = xpos;
		newy += 1;

		if(newy > ROWS) {
			row = length1;
			result = false;
		}
	}

	return result;
}

function updateGame() {
  currentTime = new Date().getTime();

  if (currentTime - previousTime > 500) {
    // drop currentBlock every half-second
    if (validateMove(currentBlock.gridX, currentBlock.gridY + 1, currentBlock.currentRotation)) {
      currentBlock.gridY += 1;
    }
    else {
      landBlock(currentBlock);
      currentBlock = getRandomBlock();
    }

    // update time
    previousTime = currentTime;
  }

  context.clearRect(0, 0, 320, 640);
  drawBoard();
  drawBlock(currentBlock);

  if (isGameOver == false) {
    requestAnimationFrame(updateGame);
  }
  else {
    context.fillText("GAME OVER");
    context.fillStyle = "white";
	}
}

function checkForCompleteLines() {
	var lineFound = false;
	var fullRow = true;
	var row = ROWS - 1;
	var col = COLS - 1;

	while(row >= 0)
	{
		while(col >= 0)
		{
			if(gameData[row][col] == 0)
			{
				fullRow = false;
				col = -1;
			}
			col--;
		}
		if(fullRow == true)
		{
			zeroRow(row);
			row++;
			lineFound = true;
			currentLines++;
		}
		fullRow = true;
		col = COLS - 1;
		row--;
	}
	if(lineFound)
	{
		lineSpan.innerHTML = currentLines.toString();
	}
}<commit_msg>Add clearCompletedRow function<commit_after>var ROWS = 20;
var COLS = 10;
var SIZE = 32;

var canvas;
var context;
var lineScore;
var currentBlock;
var isGameOver;
var previousTime;
var currentTime;

$(window).load(function(){

	canvas = document.getElementById('gameCanvas');
	context = canvas.getContext('2d');
	lineScore = $('#lines');
	previousTime = 0;
	currentTime = 0;
	startGame();
	$(document).keydown(getKeyCode);
	// drawBoard();
	// block = getRandomBlock()
	// drawBlock(block);
})

function startGame() {
	var row, col;
	currentLines = 0;
	isGameOver = false;

	gameData = new Array();

		for(row= 0; row < ROWS; row++) {
			gameData[row] = new Array();
			for(col = 0; col < COLS; col++) {
				// gameData[r].push(0);
				gameData[row][col] = 0;
			}
		}

	currentBlock = getRandomBlock();
	var requestAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
			window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

	window.requestAnimationFrame = requestAnimFrame;

	requestAnimationFrame(updateGame);
}

function drawBoard() {
	// context.drawImage(bgImg, 0, 0, 320, 640, 0, 0, 320, 640);
	context.rect(0, 0, 320, 640);
	context.fillStyle="blue";
	context.fill();
	context.lineWidth = "2";
	context.strokeStyle = "yellow";
	context.stroke();

	for(var row = 0; row < ROWS; row++) {
		for(var col = 0; col < COLS; col++) {
			if(gameData[row][col] != 0) {
				// context.drawImage(blockImg, (gameData[row][col] - 1) * SIZE, 0, SIZE, SIZE, col * SIZE, row * SIZE, SIZE, SIZE); -->
				context.rect(col * SIZE, row * SIZE, SIZE, SIZE);
				context.fillStyle="red";
				context.fill();
			}
		}
	}
}

function drawBlock(block) {
	var drawX = block.gridX;
	var drawY = block.gridY;
	var rotation = block.currentRotation;

// drawY = 10;

	for(var row = 0, len = block.rotations[rotation].length; row < len; row++) {
		for(var col = 0, len2 = block.rotations[rotation][row].length; col < len2; col++) {
			if(block.rotations[rotation][row][col] == 1 && drawY >= 0) {
				// context.drawImage(blockImg, block.color * SIZE, 0, SIZE, SIZE, drawX * SIZE, drawY * SIZE, SIZE, SIZE);
				// context.rect(drawX * SIZE, drawY * SIZE , SIZE, SIZE);
				context.beginPath();
				context.rect(drawX * SIZE, drawY * SIZE , SIZE, SIZE);
				context.fillStyle="green";
				context.fill();

			}
			drawX += 1;
		}

		drawX = block.gridX;
		drawY += 1;
	}
}

function getKeyCode(e) {
	// if(!e) { var e = window.event; }
	console.log(e);
	e.preventDefault();

	if(isGameOver != true) {
		switch(e.keyCode) {
			case 37: {
				if( validateMove(currentBlock.gridX - 1, currentBlock.gridY, currentBlock.currentRotation) )
					currentBlock.gridX--;
			}
			break;

			case 39: {
				if( validateMove(currentBlock.gridX + 1, currentBlock.gridY, currentBlock.currentRotation) )
					currentBlock.gridX++;
			}
			break;

			case 38: {
				var newRotation = currentBlock.currentRotation - 1;
				if(newRotation < 0)
					newRotation = currentBlock.rotations.length - 1;

				if( validateMove(currentBlock.gridX, currentBlock.gridY, newRotation) )
					currentBlock.currentRotation = newRotation;
			}
			break;

			case 40: {
				if( validateMove(currentBlock.gridX, currentBlock.gridY + 1, currentBlock.currentRotation) )
					currentBlock.gridY++;
			}
			break;
		}
	}
	else {
		startGame();
	}
}

function validateMove(xpos, ypos, newRotation) {
	var result = true;
	var newx = xpos;
	var newy = ypos;

	for(var row = 0, length1 = currentBlock.rotations[newRotation].length; row < length1; row++) {
		for(var col = 0, length2 = currentBlock.rotations[newRotation][row].length; col < length2; col++) {
			if(newx < 0 || newx >= COLS) {
				result = false;
				col = length2;
				row = length1;
			}

			if(gameData[newy] != undefined && gameData[newy][newx] != 0
				&& currentBlock.rotations[newRotation][row] != undefined && currentBlock.rotations[newRotation][row][col] != 0) {
				result = false;
				col = length2;
				row = length1;
			}

			newx += 1;
		}

		newx = xpos;
		newy += 1;

		if(newy > ROWS) {
			row = length1;
			result = false;
		}
	}

	return result;
}

function updateGame() {
  currentTime = new Date().getTime();

  if (currentTime - previousTime > 500) {
    // drop currentBlock every half-second
    if (validateMove(currentBlock.gridX, currentBlock.gridY + 1, currentBlock.currentRotation)) {
      currentBlock.gridY += 1;
    }
    else {
      landBlock(currentBlock);
      currentBlock = getRandomBlock();
    }

    // update time
    previousTime = currentTime;
  }

  context.clearRect(0, 0, 320, 640);
  drawBoard();
  drawBlock(currentBlock);

  if (isGameOver == false) {
    requestAnimationFrame(updateGame);
  }
  else {
    context.fillText("GAME OVER");
    context.fillStyle = "white";
	}
}

function checkForCompleteLines() {
	var lineFound = false;
	var fullRow = true;
	var row = ROWS - 1;
	var col = COLS - 1;

	while(row >= 0) {
		while(col >= 0) {
			if(gameData[row][col] == 0) {
				fullRow = false;
				col = -1;
			}
			col--;
		}
		if(fullRow == true) {
			zeroRow(row);
			row++;
			lineFound = true;
			currentLines++;
		}
		fullRow = true;
		col = COLS - 1;
		row--;
	}
	if(lineFound) {
		lineSpan.innerHTML = currentLines.toString();
	}
}

function clearCompletedRow(row) {
	var row = row;
	var col = 0;

	while(row >= 0) {
		while(col < COLS) {
			if(row > 0)
				gameData[row][col] = gameData[row-1][col];
			else
				gameData[row][col] = 0;

			col++;
		}
		col = 0;
		row --;
	}
}<|endoftext|>


<commit_before>import React from 'react';

let Trigger; // eslint-disable-line

if (process.env.REACT === '15') {
  const ActualTrigger = require.requireActual('rc-trigger');
  // cannot use object destruction, cause react 15 test cases fail
  const render = ActualTrigger.prototype.render; // eslint-disable-line

  ActualTrigger.prototype.render = function () {
    const { popupVisible } = this.state; // eslint-disable-line
    let component;

    if (popupVisible || this._component) { // eslint-disable-line
      component = this.getComponent(); // eslint-disable-line
    }

    return (

        {render.call(this)}
        {component}

    );
  };
  Trigger = ActualTrigger;
} else {
  const TriggerMock = require('rc-trigger/lib/mock'); // eslint-disable-line
  Trigger = TriggerMock;
}

export default Trigger;
<commit_msg>:lipstick: fix eslint warning<commit_after>import React from 'react';

let Trigger; // eslint-disable-line

if (process.env.REACT === '15') {
  const ActualTrigger = require.requireActual('rc-trigger');
  // cannot use object destruction, cause react 15 test cases fail
  const render = ActualTrigger.prototype.render; // eslint-disable-line

  ActualTrigger.prototype.render = function triggerRender() {
    const { popupVisible } = this.state; // eslint-disable-line
    let component;

    if (popupVisible || this._component) { // eslint-disable-line
      component = this.getComponent(); // eslint-disable-line
    }

    return (

        {render.call(this)}
        {component}

    );
  };
  Trigger = ActualTrigger;
} else {
  const TriggerMock = require('rc-trigger/lib/mock'); // eslint-disable-line
  Trigger = TriggerMock;
}

export default Trigger;
<|endoftext|>


<commit_before>/*
 * STORY-BASED TESTING
 *
 * This uses StoryShots to iterate over stories created in Storybook to
 * automatically create DOM, image snapshot, static markup accessibility tests.
 *
 * This file is list of "Story Kind" names that are created from strings
 * in `utilities/constants.js` within each `storybook-stories.jsx` file.
 *
 * By default, Jest will test all Storybook stories, to exclude a
 * component's stories from testing, add it below.
 *
 * For more information, please visit:
 * https://github.com/storybooks/storybook/tree/master/addons/storyshots
 */

const deprecatedComponents = [
	'SLDSInlineEdit',
	'SLDSLookup',
	'SLDSNotification',
	'SLDSMenuPicklist',
];

const excludeFromTests = {
	accessibility: {
		storyKind: [...deprecatedComponents],
	},
	domSnapshot: {
		storyKind: [
			'SLDSAppLauncher',
			'SLDSGlobalNavigationBar',
			'SLDSDatePicker',
			'SLDSIconSettings',
			'SLDSModal',
			'SLDSPanel',
			'SLDSTimepicker',
			'SLDSWelcomeMat',
			...deprecatedComponents,
		],
	},
	visualRegression: {
		storyKind: [
			'SLDSAppLauncher',
			'SLDSGlobalNavigationBar',
			'SLDSDatePicker',
			'SLDSIconSettings',
			'SLDSModal',
			'SLDSPanel',
			'SLDSTimepicker',
			'SLDSWelcomeMat',
			...deprecatedComponents,
		],
	},
};

export default excludeFromTests;
<commit_msg>Exclude Expression from a11y tests<commit_after>/*
 * STORY-BASED TESTING
 *
 * This uses StoryShots to iterate over stories created in Storybook to
 * automatically create DOM, image snapshot, static markup accessibility tests.
 *
 * This file is list of "Story Kind" names that are created from strings
 * in `utilities/constants.js` within each `storybook-stories.jsx` file.
 *
 * By default, Jest will test all Storybook stories, to exclude a
 * component's stories from testing, add it below.
 *
 * For more information, please visit:
 * https://github.com/storybooks/storybook/tree/master/addons/storyshots
 */

const deprecatedComponents = [
	'SLDSInlineEdit',
	'SLDSLookup',
	'SLDSNotification',
	'SLDSMenuPicklist',
];

const excludeFromTests = {
	accessibility: {
		storyKind: ['SLDSExpression', ...deprecatedComponents],
	},
	domSnapshot: {
		storyKind: [
			'SLDSAppLauncher',
			'SLDSGlobalNavigationBar',
			'SLDSDatePicker',
			'SLDSIconSettings',
			'SLDSModal',
			'SLDSPanel',
			'SLDSTimepicker',
			'SLDSWelcomeMat',
			...deprecatedComponents,
		],
	},
	visualRegression: {
		storyKind: [
			'SLDSAppLauncher',
			'SLDSGlobalNavigationBar',
			'SLDSDatePicker',
			'SLDSIconSettings',
			'SLDSModal',
			'SLDSPanel',
			'SLDSTimepicker',
			'SLDSWelcomeMat',
			...deprecatedComponents,
		],
	},
};

export default excludeFromTests;
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-2015, Egret Technology Inc.
//  All rights reserved.
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Egret nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////

function Main(){

    egret.DisplayObjectContainer.call(this);

    var p = Main.prototype;
    p.onCreate = function(){

        var context = egret.MainContext.instance;
        context.touchContext = new egret.HTML5TouchContext();
        context.deviceContext = new egret.HTML5DeviceContext();
        context.netContext = new egret.HTML5NetContext();

        egret.StageDelegate.getInstance().setDesignSize(480, 800);
        context.stage = new egret.Stage();
        var scaleMode = egret.MainContext.deviceType == egret.MainContext.DEVICE_MOBILE ? egret.StageScaleMode.SHOW_ALL : egret.StageScaleMode.NO_SCALE;
        context.stage.scaleMode = scaleMode;

        //WebGL is a Egret's beta property. It's off by default.
        //WebGL是egret的Beta特性，默认关闭
        var rendererType = 0;
        if (rendererType == 1) {// egret.WebGLUtils.checkCanUseWebGL()) {
            console.log("Use WebGL mode");
            context.rendererContext = new egret.WebGLRenderer();
        }
        else {
            context.rendererContext = new egret.HTML5CanvasRenderer();
        }

        egret.MainContext.instance.rendererContext.texture_scale_factor = 1;
        context.run();

        context.stage.addChild(this);

        this.onGameStart();

    }

    p.onGameStart = function(){

        var textField = new egret.TextField();
        this.addChild(textField);
        textField.x = textField.y = 100;
        textField.text = "Hello Egret";
    }

}

Main.prototype = Object.create(egret.DisplayObjectContainer.prototype);

var main = new Main();
main.onCreate();<commit_msg>删除冗余代码<commit_after>//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-2015, Egret Technology Inc.
//  All rights reserved.
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Egret nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////

function Main(){

    egret.DisplayObjectContainer.call(this);

    var p = Main.prototype;
    p.onCreate = function(){

        var context = egret.MainContext.instance;
        context.touchContext = new egret.HTML5TouchContext();
        context.deviceContext = new egret.HTML5DeviceContext();
        context.netContext = new egret.HTML5NetContext();

        egret.StageDelegate.getInstance().setDesignSize(480, 800);
        context.stage = new egret.Stage();
        var scaleMode = egret.MainContext.deviceType == egret.MainContext.DEVICE_MOBILE ? egret.StageScaleMode.SHOW_ALL : egret.StageScaleMode.NO_SCALE;
        context.stage.scaleMode = scaleMode;
        context.rendererContext = new egret.HTML5CanvasRenderer();

        egret.MainContext.instance.rendererContext.texture_scale_factor = 1;
        context.run();

        context.stage.addChild(this);

        this.onGameStart();

    }

    p.onGameStart = function(){

        var textField = new egret.TextField();
        this.addChild(textField);
        textField.x = textField.y = 100;
        textField.text = "Hello Egret";
    }

}

Main.prototype = Object.create(egret.DisplayObjectContainer.prototype);

var main = new Main();
main.onCreate();<|endoftext|>


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

angular.module('mm.core.courses')

/**
 * Courses handlers factory.
 *
 * @module mm.core.courses
 * @ngdoc service
 * @name $mmCoursesHandlers
 */
.factory('$mmCoursesHandlers', function($mmSite, $state, $mmCourses, $q, $mmUtil, $translate, $timeout, $mmCourse,
            mmCoursesEnrolInvalidKey) {

    var self = {};

    /**
     * Content links handler.
     *
     * @module mm.core.courses
     * @ngdoc method
     * @name $mmCoursesHandlers#linksHandler
     */
    self.linksHandler = function() {

        var self = {},
            patterns = ['/enrol/index.php', '/course/enrol.php', '/course/view.php'];

        /**
         * Action to perform when an enrol link is clicked.
         *
         * @param  {Number} courseId Course ID.
         * @param  {String} url      Treated URL.
         * @return {Void}
         */
        function actionEnrol(courseId, url) {
            var modal = $mmUtil.showModalLoading(),
                isEnrolUrl = url.indexOf(patterns[0]) > -1 || url.indexOf(patterns[1]) > -1;

            // Check if user is enrolled in the course.
            $mmCourses.getUserCourse(courseId).catch(function() {
                // User is not enrolled in the course. Check if can self enrol.
                return canSelfEnrol(courseId).then(function() {
                    var promise;
                    modal.dismiss();

                    // The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
                    promise = isEnrolUrl ? $q.when() : $mmUtil.showConfirm($translate('mm.courses.confirmselfenrol'));

                    return promise.then(function() {
                        // Enrol URL or user confirmed.
                        return selfEnrol(courseId).catch(function(error) {
                            if (typeof error == 'string') {
                                $mmUtil.showErrorModal(error);
                            }
                            return $q.reject();
                        });
                    }, function() {
                        // User cancelled. Check if the user can view the course contents (guest access or similar).
                        return $mmCourse.getSections(courseId);
                    });
                }, function(error) {
                    // Can't self enrol. Check if the user can view the course contents (guest access or similar).
                    return $mmCourse.getSections(courseId).catch(function() {
                        // Error. Show error message and allow the user to open the link in browser.
                        modal.dismiss();
                        if (typeof error != 'string') {
                            error = $translate.instant('mm.courses.notenroled');
                        }

                        var body = $translate('mm.core.twoparagraphs',
                                        {p1: error, p2: $translate.instant('mm.core.confirmopeninbrowser')});
                        $mmUtil.showConfirm(body).then(function() {
                            $mmUtil.openInBrowser(url);
                        });
                        return $q.reject();
                    });
                });
            }).then(function() {
                modal.dismiss();
                // Use redirect to make the course the new history root (to avoid "loops" in history).
                $state.go('redirect', {
                    siteid: $mmSite.getId(),
                    state: 'site.mm_course',
                    params: {courseid: courseId}
                });
            });
        }

        /**
         * Check if a user can be "automatically" self enrolled in a course.
         *
         * @param  {Number} courseId Course ID.
         * @return {Promise}         Promise resolved if user is can be enrolled in a course, rejected otherwise.
         */
        function canSelfEnrol(courseId) {
            // Check if self enrolment is enabled.
            if (!$mmCourses.isSelfEnrolmentEnabled()) {
                return $q.reject();
            }

            // Check that the course has self enrolment enabled.
            return $mmCourses.getCourseEnrolmentMethods(courseId).then(function(methods) {
                var isSelfEnrolEnabled = false,
                    instances = 0;
                angular.forEach(methods, function(method) {
                    if (method.type == 'self' && method.status) {
                        isSelfEnrolEnabled = true;
                        instances++;
                    }
                });

                if (!isSelfEnrolEnabled || instances != 1) {
                    // Self enrol not enabled or more than one instance.
                    return $q.reject();
                }
            });
        }

        /**
         * Try to self enrol a user in a course.
         *
         * @param  {Number} courseId Course ID.
         * @param  {String} password Password.
         * @return {Promise}         Promiser esolved when the user is enrolled, rejected otherwise.
         */
        function selfEnrol(courseId, password) {
            var modal = $mmUtil.showModalLoading();
            return $mmCourses.selfEnrol(courseId, password).then(function() {
                // Success self enrolling the user, invalidate the courses list.
                return $mmCourses.invalidateUserCourses().catch(function() {
                    // Ignore errors.
                }).then(function() {
                    // For some reason, if we get the course list right after self enrolling
                    // we won't retrieve the new course. Let's delay it a bit.
                    return $timeout(function() {}, 4000).finally(function() {
                        modal.dismiss();
                    });
                });

            }).catch(function(error) {
                modal.dismiss();
                if (error && error.code === mmCoursesEnrolInvalidKey) {
                    // Invalid password. Allow the user to input password.
                    var title = $translate.instant('mm.courses.selfenrolment'),
                        body = ' ', // Empty message.
                        placeholder = $translate.instant('mm.courses.password');

                    if (typeof password != 'undefined') {
                        // The user attempted a password. Show an error message.
                        $mmUtil.showErrorModal(error.message);
                    }

                    return $mmUtil.showPrompt(body, title, placeholder).then(function(password) {
                        return selfEnrol(courseId, password);
                    });
                } else {
                    return $q.reject(error);
                }
            });
        }

        /**
         * Get actions to perform with the link.
         *
         * @param {String[]} siteIds Site IDs the URL belongs to.
         * @param {String} url       URL to treat.
         * @return {Object[]}        List of actions. See {@link $mmContentLinksDelegate#registerLinkHandler}.
         */
        self.getActions = function(siteIds, url) {
            // Check if it's a course URL.
            if (typeof self.handles(url) != 'undefined') {
                var params = $mmUtil.extractUrlParams(url),
                    courseId = parseInt(params.id, 10);
                if (courseId && courseId != 1) {
                    // Return actions.
                    return [{
                        message: 'mm.core.view',
                        icon: 'ion-eye',
                        sites: siteIds,
                        action: function(siteId) {
                            siteId = siteId || $mmSite.getId();
                            if (siteId == $mmSite.getId()) {
                                actionEnrol(courseId, url);
                            } else {
                                // Use redirect to make the course the new history root (to avoid "loops" in history).
                                $state.go('redirect', {
                                    siteid: siteId,
                                    state: 'site.mm_course',
                                    params: {courseid: courseId}
                                });
                            }
                        }
                    }];
                }
            }
            return [];
        };

        /**
         * Check if the URL is handled by this handler. If so, returns the URL of the site.
         *
         * @param  {String} url URL to check.
         * @return {String}     Site URL. Undefined if the URL doesn't belong to this handler.
         */
        self.handles = function(url) {
            // Accept any of these patterns.
            for (var i = 0; i < patterns.length; i++) {
                var position = url.indexOf(patterns[i]);
                if (position > -1) {
                    return url.substr(0, position);
                }
            }
        };

        return self;
    };

    return self;
});
<commit_msg>MOBILE-1653 courses: Handle course and course/index.php links<commit_after>// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

angular.module('mm.core.courses')

/**
 * Courses handlers factory.
 *
 * @module mm.core.courses
 * @ngdoc service
 * @name $mmCoursesHandlers
 */
.factory('$mmCoursesHandlers', function($mmSite, $state, $mmCourses, $q, $mmUtil, $translate, $timeout, $mmCourse,
            mmCoursesEnrolInvalidKey) {

    var self = {};

    /**
     * Content links handler.
     *
     * @module mm.core.courses
     * @ngdoc method
     * @name $mmCoursesHandlers#linksHandler
     */
    self.linksHandler = function() {

        var self = {},
            patterns = [
                /(\/enrol\/index\.php)|(\/course\/enrol\.php)/, // Enrol in course.
                /\/course\/view\.php/, // View course.
                /\/course\/?(index\.php.*)?$/ // My courses.
            ];

        /**
         * Action to perform when an enrol link is clicked.
         *
         * @param  {Number} courseId Course ID.
         * @param  {String} url      Treated URL.
         * @return {Void}
         */
        function actionEnrol(courseId, url) {
            var modal = $mmUtil.showModalLoading(),
                isEnrolUrl = url.indexOf(patterns[0]) > -1 || url.indexOf(patterns[1]) > -1;

            // Check if user is enrolled in the course.
            $mmCourses.getUserCourse(courseId).catch(function() {
                // User is not enrolled in the course. Check if can self enrol.
                return canSelfEnrol(courseId).then(function() {
                    var promise;
                    modal.dismiss();

                    // The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
                    promise = isEnrolUrl ? $q.when() : $mmUtil.showConfirm($translate('mm.courses.confirmselfenrol'));

                    return promise.then(function() {
                        // Enrol URL or user confirmed.
                        return selfEnrol(courseId).catch(function(error) {
                            if (typeof error == 'string') {
                                $mmUtil.showErrorModal(error);
                            }
                            return $q.reject();
                        });
                    }, function() {
                        // User cancelled. Check if the user can view the course contents (guest access or similar).
                        return $mmCourse.getSections(courseId);
                    });
                }, function(error) {
                    // Can't self enrol. Check if the user can view the course contents (guest access or similar).
                    return $mmCourse.getSections(courseId).catch(function() {
                        // Error. Show error message and allow the user to open the link in browser.
                        modal.dismiss();
                        if (typeof error != 'string') {
                            error = $translate.instant('mm.courses.notenroled');
                        }

                        var body = $translate('mm.core.twoparagraphs',
                                        {p1: error, p2: $translate.instant('mm.core.confirmopeninbrowser')});
                        $mmUtil.showConfirm(body).then(function() {
                            $mmUtil.openInBrowser(url);
                        });
                        return $q.reject();
                    });
                });
            }).then(function() {
                modal.dismiss();
                // Use redirect to make the course the new history root (to avoid "loops" in history).
                $state.go('redirect', {
                    siteid: $mmSite.getId(),
                    state: 'site.mm_course',
                    params: {courseid: courseId}
                });
            });
        }

        /**
         * Check if a user can be "automatically" self enrolled in a course.
         *
         * @param  {Number} courseId Course ID.
         * @return {Promise}         Promise resolved if user is can be enrolled in a course, rejected otherwise.
         */
        function canSelfEnrol(courseId) {
            // Check if self enrolment is enabled.
            if (!$mmCourses.isSelfEnrolmentEnabled()) {
                return $q.reject();
            }

            // Check that the course has self enrolment enabled.
            return $mmCourses.getCourseEnrolmentMethods(courseId).then(function(methods) {
                var isSelfEnrolEnabled = false,
                    instances = 0;
                angular.forEach(methods, function(method) {
                    if (method.type == 'self' && method.status) {
                        isSelfEnrolEnabled = true;
                        instances++;
                    }
                });

                if (!isSelfEnrolEnabled || instances != 1) {
                    // Self enrol not enabled or more than one instance.
                    return $q.reject();
                }
            });
        }

        /**
         * Try to self enrol a user in a course.
         *
         * @param  {Number} courseId Course ID.
         * @param  {String} password Password.
         * @return {Promise}         Promiser esolved when the user is enrolled, rejected otherwise.
         */
        function selfEnrol(courseId, password) {
            var modal = $mmUtil.showModalLoading();
            return $mmCourses.selfEnrol(courseId, password).then(function() {
                // Success self enrolling the user, invalidate the courses list.
                return $mmCourses.invalidateUserCourses().catch(function() {
                    // Ignore errors.
                }).then(function() {
                    // For some reason, if we get the course list right after self enrolling
                    // we won't retrieve the new course. Let's delay it a bit.
                    return $timeout(function() {}, 4000).finally(function() {
                        modal.dismiss();
                    });
                });

            }).catch(function(error) {
                modal.dismiss();
                if (error && error.code === mmCoursesEnrolInvalidKey) {
                    // Invalid password. Allow the user to input password.
                    var title = $translate.instant('mm.courses.selfenrolment'),
                        body = ' ', // Empty message.
                        placeholder = $translate.instant('mm.courses.password');

                    if (typeof password != 'undefined') {
                        // The user attempted a password. Show an error message.
                        $mmUtil.showErrorModal(error.message);
                    }

                    return $mmUtil.showPrompt(body, title, placeholder).then(function(password) {
                        return selfEnrol(courseId, password);
                    });
                } else {
                    return $q.reject(error);
                }
            });
        }

        /**
         * Get actions to perform with the link.
         *
         * @param {String[]} siteIds Site IDs the URL belongs to.
         * @param {String} url       URL to treat.
         * @return {Object[]}        List of actions. See {@link $mmContentLinksDelegate#registerLinkHandler}.
         */
        self.getActions = function(siteIds, url) {
            // Check if it's a course URL.
            if (typeof self.handles(url) != 'undefined') {
                if (url.search(patterns[2]) > -1) {
                    // My courses. Return actions.
                    return [{
                        message: 'mm.core.view',
                        icon: 'ion-eye',
                        sites: siteIds,
                        action: function(siteId) {
                            // Use redirect to go to history root.
                            $state.go('redirect', {
                                siteid: siteId || $mmSite.getId(),
                                state: 'site.mm_courses'
                            });
                        }
                    }];
                } else {
                    // Course view or enrol.
                    var params = $mmUtil.extractUrlParams(url),
                        courseId = parseInt(params.id, 10);
                    if (courseId && courseId != 1) {
                        // Return actions.
                        return [{
                            message: 'mm.core.view',
                            icon: 'ion-eye',
                            sites: siteIds,
                            action: function(siteId) {
                                siteId = siteId || $mmSite.getId();
                                if (siteId == $mmSite.getId()) {
                                    actionEnrol(courseId, url);
                                } else {
                                    // Use redirect to make the course the new history root (to avoid "loops" in history).
                                    $state.go('redirect', {
                                        siteid: siteId,
                                        state: 'site.mm_course',
                                        params: {courseid: courseId}
                                    });
                                }
                            }
                        }];
                    }
                }
            }

            return [];
        };

        /**
         * Check if the URL is handled by this handler. If so, returns the URL of the site.
         *
         * @param  {String} url URL to check.
         * @return {String}     Site URL. Undefined if the URL doesn't belong to this handler.
         */
        self.handles = function(url) {
            // Accept any of these patterns.
            for (var i = 0; i < patterns.length; i++) {
                var position = url.search(patterns[i]);
                if (position > -1) {
                    return url.substr(0, position);
                }
            }
        };

        return self;
    };

    return self;
});
<|endoftext|>


<commit_before>angular.module("omniControllers")
	.controller("ExchangePendingController",["$scope", "$http", "hashExplorer", "ADDRESS_EXPLORER_URL", "Transaction", "SATOSHI_UNIT", "$filter",
		function ExchangePendingController($scope, $http, hashExplorer, ADDRESS_EXPLORER_URL, Transaction, SATOSHI_UNIT, $filter) {
		  $scope.setHashExplorer = hashExplorer.setHash.bind(hashExplorer)
		  //$scope.selectedAddress = $scope.wallet.addresses[ $scope.wallet.addresses.length-1 ].address;
		  $scope.currencyUnit = 'stom'
		  $scope.pendingThinking = true
		  $scope.hasAddressesWithPrivkey = $scope.wallet.addresses.filter(function(address){
		    return address.privkey && address.privkey.length == 58
		  }).map(function(e){
		          return e.hash;
		        });
		  $scope.selectedAddress = $scope.hasAddressesWithPrivkey[0];
		  $scope.wallet.assets.filter(function(currency){
		       return currency.tradable;
		  }).forEach(function(coin){
		    if(coin.symbol=='BTC'){
		      $scope.selectedCoin = coin;
		    }
		  });

		  //Get All data
		  $scope.timeNow = Date.now();
		  $scope.selectedTimeframe = $scope.timeNow - 1394834400000;
		  //$scope.selectedTimeframe = "604800"
		  $scope.filterData = function(time) {
		    var orderbook = JSON.parse($scope.orderBookStorage);

		    var now = Date.now()
		    var filtered_transaction_data = orderbook.filter(function(item) {
		      console.log('time2', +item.tx_time, '>= ?', (now - (+time)))
		      return true //(+item.tx_time) <= (now - (+time) )
		    });
		    $scope.orderbook = filtered_transaction_data;
		  }
		  $scope.getData = function(time) {
		    $scope.orderbook = []
		    var transaction_data = []
		    var postData = {
		      type: 'ADDRESS',
		      currencyType: 'BOTH',
		      address: JSON.stringify($scope.hasAddressesWithPrivkey),
		      offerType: 'BOTH'
		    };
		    $http.post('/v1/exchange/offers', postData).success(function(offerSuccess) {
		      console.log(offerSuccess, ' ofsec');

		      //capture data
		      var nestedData = offerSuccess.data,
		        nestedLevels = 0,
		        capturedData = [];
		      while (typeof nestedData == 'object' && nestedLevels < 5) {
		        var savedData = []
		        if (nestedData instanceof Object && !(nestedData instanceof Array)) { //DEBUG console.log('got obj', nestedData);
		          var data_keys = Object.keys(nestedData)
		          data_keys.forEach(function(key) {
		            savedData = savedData.concat(nestedData[key])
		          });
		        }
		        if (nestedData instanceof Array) { //DEBUG console.log('got arr', nestedData);
		          var arrayOfObjects = []
		          nestedData.forEach(function(elem) {
		            if (elem instanceof Array || !(elem instanceof Object))
		              capturedData.push(elem)
		            else if (elem instanceof Object && !(elem instanceof Array)) { //DEBUG console.log('got obj', elem);
		              var elem_keys = Object.keys(elem)
		              elem_keys.forEach(function(key) { //DEBUG console.log('got item', typeof elem[key])
		                if (typeof elem[key] == 'object' && key != 'invalid')
		                  arrayOfObjects = arrayOfObjects.concat(elem[key])
		              });
		              //DEBUG console.log('check len', arrayOfObjects.length)
		              if (arrayOfObjects.length == 0)
		                capturedData.push(elem)
		            }
		          });
		          savedData = arrayOfObjects
		        }
		        //console.log('nesteddata orig', nestedData, 'data saved', savedData)
		        nestedData = savedData
		        nestedLevels++
		      }

		      transaction_data = capturedData;
		      transaction_data.forEach(function(tx) {
		        if (tx != "ADDRESS_NOT_FOUND") {
		          transaction_data_keys = ['formatted_amount', 'formatted_amount_available',
		            'formatted_bitcoin_amount_desired', 'formatted_fee_required', 'formatted_price_per_coin', 'bitcoin_required'];
		          transaction_data_keys.forEach(function(key) {
		            tx[key] = tx[key];
		          });
		        }
		      });

		      var filtered_transaction_data = transaction_data.filter(function(item) {
		        //console.log('stf', item, typeof item != 'string', 'inv', item.invalid == false && item.invalid.length == undefined)
		        return (typeof item == 'object' && (item.invalid == false && item.invalid.length == undefined))
		      });

		      //DEBUG console.log(filtered_transaction_data, 'tettst')
		      //DEBUG console.log('filtered tx data, pending offers',filtered_transaction_data)

		      $scope.filtered_buys = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.status ? item.status.toLowerCase() : undefined;
		        //DEBUG console.log(item.tx_type_str, item.status, orderStatus)
		        return (orderType == 'sell accept') && (orderStatus != 'expired') && (orderStatus != 'closed')
		      });

		      $scope.filtered_sells = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.color.match(/(bgc-done|expired|invalid)/gi) || []
		        //DEBUG console.log(orderStatus, item.color)
		        return (orderType == 'sell offer') && (orderStatus.length == 0)
		      });

		      angular.forEach(filtered_transaction_data, function(transaction, index) {
		        //DEBUG console.log(new Date(Number(transaction.tx_time)))
		        filtered_transaction_data[index].tx_hash_concat = transaction.tx_hash.substring(0, 22) + '...';
		      });

		      transaction_data = filtered_transaction_data;
		      //if null, then append simple message
		      $scope.orderbook = transaction_data.length != 0 ? transaction_data : [{
		            tx_hash: 'No offers/bids found for this timeframe'
		          }];

		      //store around for filtering
		      $scope.orderBookStorage = JSON.stringify($scope.orderbook);
		    });
		  };
		  $scope.purchaseCoin = function(tx) {
		    $scope.pendingThinking = false;
		    $scope.buyTransaction = tx;
		    $scope.sendTo = tx.to_address;
		    $scope.sendAmount = tx.bitcoin_required;
		    $scope.selectedAddress = $scope.wallet.getAddress(tx.from_address);
		    $scope.selectedAsset = $scope.wallet.getAsset(0);
		    $http.get('/v1/transaction/tx/' + tx.sell_offer_txid + '.json').success(function(data) {
		      var sell_tx = data[0];
		      $scope.minersFee= new Big(sell_tx.formatted_fee_required);
		      $http.post('/v1/blocks/getlast',{origin:"blockchain"}).success(function(block){
		        $scope.remainingBlocks = sell_tx.formatted_block_time_limit - (block.height - tx.block);
		      });
		    });
		  };

		  $scope.isCancel=true;
		  $scope.confirmCancel = function(tx) {
		  	var fee = new Big(0.0001);
	        var exchangeCancel = new Transaction(20,$scope.wallet.getAddress(tx.from_address),fee,{
	            transaction_version:1,
	            amount_for_sale: 0,
	            amount_desired: 0,
	            min_buyer_fee: 0,
	            blocks: 10,
	            currency_identifier: (+tx.currencyId) == 1 ? 'OMNI' : 'T-OMNI',
	            action:3,
	            donate: $scope.account.getSetting("donate")
	          });

	        $scope.modalManager.openConfirmationModal({
	          dataTemplate: '/views/modals/partials/cancel.html',
	          scope:{
	            title:"EXCHANGE.MYOFFERS.CANCELTITLE",
	            confirmText:"EXCHANGE.MYOFFERS.CANCELCONFIRM",
	            explorerUrl:ADDRESS_EXPLORER_URL,
	            successRedirect:"/exchange/myoffers"
	          },
	          transaction:exchangeCancel
	        })
		  }

		  $scope.sendTransaction = function(){
			// TODO: Validations
			var fee = $scope.minersFee;
			var amount = $scope.sendAmount;
			var acceptSend = new Transaction(0,$scope.selectedAddress,fee,{
		        transaction_version:0,
		        currency_identifier:$scope.selectedAsset.id,
		        amount_to_transfer : $scope.selectedAsset.divisible ? +new Big(amount).times(SATOSHI_UNIT).valueOf() : +amount,
		        transaction_to: $scope.sendTo,
		        donate: $scope.account.getSetting("donate"),
		        marker: true
		    });

			var btcPrice = $scope.selectedAsset.price;

			var modalScope = {
				title:"WALLET.SEND.CONFIRM",
				token:$filter('truncate')($scope.selectedAsset.name,15,0),
				sendAmount:$scope.sendAmount,
				symbol:$scope.selectedAsset.symbol,
				sendValue:$scope.sendAmount * btcPrice,
				toAddress:$scope.sendTo,
				fees:acceptSend.totalCost,
				confirmText:"WALLET.SEND.FUNDS",
            	successRedirect:"/wallet"
			};

			$scope.modalManager.openConfirmationModal({
				dataTemplate: '/views/modals/partials/send.html',
				footerTemplate: $scope.selectedAsset.id == 0 ? '/views/modals/partials/send_footer.html' : undefined,
				scope: $scope.selectedAsset.id != 0 ? modalScope : angular.extend(modalScope, {
					btcValueChanged:false,
					bitcoinValue:btcPrice,
					bitcoin:$scope.selectedAsset
				}),
				transaction:acceptSend
			})
		};
		}])<commit_msg>Fix cancel currencyId as well<commit_after>angular.module("omniControllers")
	.controller("ExchangePendingController",["$scope", "$http", "hashExplorer", "ADDRESS_EXPLORER_URL", "Transaction", "SATOSHI_UNIT", "$filter",
		function ExchangePendingController($scope, $http, hashExplorer, ADDRESS_EXPLORER_URL, Transaction, SATOSHI_UNIT, $filter) {
		  $scope.setHashExplorer = hashExplorer.setHash.bind(hashExplorer)
		  //$scope.selectedAddress = $scope.wallet.addresses[ $scope.wallet.addresses.length-1 ].address;
		  $scope.currencyUnit = 'stom'
		  $scope.pendingThinking = true
		  $scope.hasAddressesWithPrivkey = $scope.wallet.addresses.filter(function(address){
		    return address.privkey && address.privkey.length == 58
		  }).map(function(e){
		          return e.hash;
		        });
		  $scope.selectedAddress = $scope.hasAddressesWithPrivkey[0];
		  $scope.wallet.assets.filter(function(currency){
		       return currency.tradable;
		  }).forEach(function(coin){
		    if(coin.symbol=='BTC'){
		      $scope.selectedCoin = coin;
		    }
		  });

		  //Get All data
		  $scope.timeNow = Date.now();
		  $scope.selectedTimeframe = $scope.timeNow - 1394834400000;
		  //$scope.selectedTimeframe = "604800"
		  $scope.filterData = function(time) {
		    var orderbook = JSON.parse($scope.orderBookStorage);

		    var now = Date.now()
		    var filtered_transaction_data = orderbook.filter(function(item) {
		      console.log('time2', +item.tx_time, '>= ?', (now - (+time)))
		      return true //(+item.tx_time) <= (now - (+time) )
		    });
		    $scope.orderbook = filtered_transaction_data;
		  }
		  $scope.getData = function(time) {
		    $scope.orderbook = []
		    var transaction_data = []
		    var postData = {
		      type: 'ADDRESS',
		      currencyType: 'BOTH',
		      address: JSON.stringify($scope.hasAddressesWithPrivkey),
		      offerType: 'BOTH'
		    };
		    $http.post('/v1/exchange/offers', postData).success(function(offerSuccess) {
		      console.log(offerSuccess, ' ofsec');

		      //capture data
		      var nestedData = offerSuccess.data,
		        nestedLevels = 0,
		        capturedData = [];
		      while (typeof nestedData == 'object' && nestedLevels < 5) {
		        var savedData = []
		        if (nestedData instanceof Object && !(nestedData instanceof Array)) { //DEBUG console.log('got obj', nestedData);
		          var data_keys = Object.keys(nestedData)
		          data_keys.forEach(function(key) {
		            savedData = savedData.concat(nestedData[key])
		          });
		        }
		        if (nestedData instanceof Array) { //DEBUG console.log('got arr', nestedData);
		          var arrayOfObjects = []
		          nestedData.forEach(function(elem) {
		            if (elem instanceof Array || !(elem instanceof Object))
		              capturedData.push(elem)
		            else if (elem instanceof Object && !(elem instanceof Array)) { //DEBUG console.log('got obj', elem);
		              var elem_keys = Object.keys(elem)
		              elem_keys.forEach(function(key) { //DEBUG console.log('got item', typeof elem[key])
		                if (typeof elem[key] == 'object' && key != 'invalid')
		                  arrayOfObjects = arrayOfObjects.concat(elem[key])
		              });
		              //DEBUG console.log('check len', arrayOfObjects.length)
		              if (arrayOfObjects.length == 0)
		                capturedData.push(elem)
		            }
		          });
		          savedData = arrayOfObjects
		        }
		        //console.log('nesteddata orig', nestedData, 'data saved', savedData)
		        nestedData = savedData
		        nestedLevels++
		      }

		      transaction_data = capturedData;
		      transaction_data.forEach(function(tx) {
		        if (tx != "ADDRESS_NOT_FOUND") {
		          transaction_data_keys = ['formatted_amount', 'formatted_amount_available',
		            'formatted_bitcoin_amount_desired', 'formatted_fee_required', 'formatted_price_per_coin', 'bitcoin_required'];
		          transaction_data_keys.forEach(function(key) {
		            tx[key] = tx[key];
		          });
		        }
		      });

		      var filtered_transaction_data = transaction_data.filter(function(item) {
		        //console.log('stf', item, typeof item != 'string', 'inv', item.invalid == false && item.invalid.length == undefined)
		        return (typeof item == 'object' && (item.invalid == false && item.invalid.length == undefined))
		      });

		      //DEBUG console.log(filtered_transaction_data, 'tettst')
		      //DEBUG console.log('filtered tx data, pending offers',filtered_transaction_data)

		      $scope.filtered_buys = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.status ? item.status.toLowerCase() : undefined;
		        //DEBUG console.log(item.tx_type_str, item.status, orderStatus)
		        return (orderType == 'sell accept') && (orderStatus != 'expired') && (orderStatus != 'closed')
		      });

		      $scope.filtered_sells = filtered_transaction_data.filter(function(item) {
		        var orderType = item.tx_type_str.toLowerCase()
		        var orderStatus = item.color.match(/(bgc-done|expired|invalid)/gi) || []
		        //DEBUG console.log(orderStatus, item.color)
		        return (orderType == 'sell offer') && (orderStatus.length == 0)
		      });

		      angular.forEach(filtered_transaction_data, function(transaction, index) {
		        //DEBUG console.log(new Date(Number(transaction.tx_time)))
		        filtered_transaction_data[index].tx_hash_concat = transaction.tx_hash.substring(0, 22) + '...';
		      });

		      transaction_data = filtered_transaction_data;
		      //if null, then append simple message
		      $scope.orderbook = transaction_data.length != 0 ? transaction_data : [{
		            tx_hash: 'No offers/bids found for this timeframe'
		          }];

		      //store around for filtering
		      $scope.orderBookStorage = JSON.stringify($scope.orderbook);
		    });
		  };
		  $scope.purchaseCoin = function(tx) {
		    $scope.pendingThinking = false;
		    $scope.buyTransaction = tx;
		    $scope.sendTo = tx.to_address;
		    $scope.sendAmount = tx.bitcoin_required;
		    $scope.selectedAddress = $scope.wallet.getAddress(tx.from_address);
		    $scope.selectedAsset = $scope.wallet.getAsset(0);
		    $http.get('/v1/transaction/tx/' + tx.sell_offer_txid + '.json').success(function(data) {
		      var sell_tx = data[0];
		      $scope.minersFee= new Big(sell_tx.formatted_fee_required);
		      $http.post('/v1/blocks/getlast',{origin:"blockchain"}).success(function(block){
		        $scope.remainingBlocks = sell_tx.formatted_block_time_limit - (block.height - tx.block);
		      });
		    });
		  };

		  $scope.isCancel=true;
		  $scope.confirmCancel = function(tx) {
		  	var fee = new Big(0.0001);
	        var exchangeCancel = new Transaction(20,$scope.wallet.getAddress(tx.from_address),fee,{
	            transaction_version:1,
	            amount_for_sale: 0,
	            amount_desired: 0,
	            min_buyer_fee: 0,
	            blocks: 10,
	            currency_identifier: tx.currencyId,
	            action:3,
	            donate: $scope.account.getSetting("donate")
	          });

	        $scope.modalManager.openConfirmationModal({
	          dataTemplate: '/views/modals/partials/cancel.html',
	          scope:{
	            title:"EXCHANGE.MYOFFERS.CANCELTITLE",
	            confirmText:"EXCHANGE.MYOFFERS.CANCELCONFIRM",
	            explorerUrl:ADDRESS_EXPLORER_URL,
	            successRedirect:"/exchange/myoffers"
	          },
	          transaction:exchangeCancel
	        })
		  }

		  $scope.sendTransaction = function(){
			// TODO: Validations
			var fee = $scope.minersFee;
			var amount = $scope.sendAmount;
			var acceptSend = new Transaction(0,$scope.selectedAddress,fee,{
		        transaction_version:0,
		        currency_identifier:$scope.selectedAsset.id,
		        amount_to_transfer : $scope.selectedAsset.divisible ? +new Big(amount).times(SATOSHI_UNIT).valueOf() : +amount,
		        transaction_to: $scope.sendTo,
		        donate: $scope.account.getSetting("donate"),
		        marker: true
		    });

			var btcPrice = $scope.selectedAsset.price;

			var modalScope = {
				title:"WALLET.SEND.CONFIRM",
				token:$filter('truncate')($scope.selectedAsset.name,15,0),
				sendAmount:$scope.sendAmount,
				symbol:$scope.selectedAsset.symbol,
				sendValue:$scope.sendAmount * btcPrice,
				toAddress:$scope.sendTo,
				fees:acceptSend.totalCost,
				confirmText:"WALLET.SEND.FUNDS",
            	successRedirect:"/wallet"
			};

			$scope.modalManager.openConfirmationModal({
				dataTemplate: '/views/modals/partials/send.html',
				footerTemplate: $scope.selectedAsset.id == 0 ? '/views/modals/partials/send_footer.html' : undefined,
				scope: $scope.selectedAsset.id != 0 ? modalScope : angular.extend(modalScope, {
					btcValueChanged:false,
					bitcoinValue:btcPrice,
					bitcoin:$scope.selectedAsset
				}),
				transaction:acceptSend
			})
		};
		}])<|endoftext|>


<commit_before>var registry = require('../../src/plugman/registry/registry'),
    manifest = require('../../src/plugman/registry/manifest'),
    fs = require('fs'),
    path = require('path'),
    Q = require('q'),
    shell   = require('shelljs'),
    os = require('os'),
    npm = require('npm');

describe('registry', function() {
    var done;
    beforeEach(function() {
        done = false;
    });
    function registryPromise(shouldSucceed, f) {
        waitsFor(function() { return done; }, 'promise never resolved', 500);
        return f.then(function() {
          done = true;
          expect(shouldSucceed).toBe(true);
        }, function(err) {
          done = err;
          expect(shouldSucceed).toBe(false);
        });
    }

    describe('manifest', function() {
        var pluginDir, packageJson, tmp_plugin, tmp_plugin_xml, tmp_package_json;
        beforeEach(function() {
            pluginDir = __dirname + '/../plugins/EnginePlugin';
            tmp_plugin = path.join(os.tmpdir(), 'plugin');
            tmp_plugin_xml = path.join(tmp_plugin, 'plugin.xml');
            tmp_package_json = path.join(tmp_plugin, 'package.json');
            shell.cp('-R', pluginDir+"/*", tmp_plugin);
        });
        afterEach(function() {
            shell.rm('-rf', tmp_plugin);
        });
        it('should generate a package.json from a plugin.xml', function() {
            registryPromise(true, manifest.generatePackageJsonFromPluginXml(tmp_plugin).then(function() {
                expect(fs.existsSync(tmp_package_json));
                var packageJson = JSON.parse(fs.readFileSync(tmp_package_json));
                expect(packageJson.name).toEqual('com.cordova.engine');
                expect(packageJson.version).toEqual('1.0.0');
                expect(packageJson.engines).toEqual(
                    [ { name : 'cordova', version : '>=2.3.0' }, { name : 'cordova-plugman', version : '>=0.10.0' }, { name : 'mega-fun-plugin', version : '>=1.0.0' }, { name : 'mega-boring-plugin', version : '>=3.0.0' } ]);
            }));
        });
        it('should raise an error if name does not follow com.domain.* format', function() {
            var xmlData = fs.readFileSync(tmp_plugin_xml).toString().replace('id="com.cordova.engine"', 'id="engine"');
            fs.writeFileSync(tmp_plugin_xml, xmlData);
            registryPromise(false, manifest.generatePackageJsonFromPluginXml(tmp_plugin));
        });
        it('should generate a package.json if name uses org.apache.cordova.* for a whitelisted plugin', function() {
            var xmlData = fs.readFileSync(tmp_plugin_xml).toString().replace('id="com.cordova.engine"', 'id="org.apache.cordova.camera"');
            fs.writeFileSync(tmp_plugin_xml, xmlData);
            registryPromise(true, manifest.generatePackageJsonFromPluginXml(tmp_plugin).then(function() {
                expect(!fs.existsSync(tmp_package_json));
            }));
        });
        it('should raise an error if name uses org.apache.cordova.* for a non-whitelisted plugin', function() {
            var xmlData = fs.readFileSync(tmp_plugin_xml).toString().replace('id="com.cordova.engine"', 'id="org.apache.cordova.myinvalidplugin"');
            fs.writeFileSync(tmp_plugin_xml, xmlData);
            registryPromise(false, manifest.generatePackageJsonFromPluginXml(tmp_plugin));
        });
    });
    describe('actions', function() {
        var fakeLoad, fakeNPMCommands;

        beforeEach(function() {
            done = false;
            var fakeSettings = {
                cache: '/some/cache/dir',
                logstream: 'somelogstream@2313213',
                userconfig: '/some/config/dir'
            };

            var fakeNPM = function() {
                if (arguments.length > 0) {
                    var cb = arguments[arguments.length-1];
                    if (cb && typeof cb === 'function') cb(null, true);
                }
            };

            registry.settings = fakeSettings;
            fakeLoad = spyOn(npm, 'load').andCallFake(function(settings, cb) { cb(null, true); });

            fakeNPMCommands = {};
            ['config', 'adduser', 'cache', 'publish', 'unpublish', 'search'].forEach(function(cmd) {
                fakeNPMCommands[cmd] = jasmine.createSpy(cmd).andCallFake(fakeNPM);
            });

            npm.commands = fakeNPMCommands;
            npm.config.set = function(){};
        });
        it('should run config', function() {
            var params = ['set', 'registry', 'http://registry.cordova.io'];
            registryPromise(true, registry.config(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.config).toHaveBeenCalledWith(params, jasmine.any(Function));
            }));
        });
        it('should run adduser', function() {
            registryPromise(true, registry.adduser(null).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.adduser).toHaveBeenCalledWith(null, jasmine.any(Function));
            }));
        });
        it('should run publish', function() {
            var params = [__dirname + '/../plugins/DummyPlugin'];
            var spyGenerate = spyOn(manifest, 'generatePackageJsonFromPluginXml').andReturn(Q());
            var spyUnlink = spyOn(fs, 'unlink');
            registryPromise(true, registry.publish(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(spyGenerate).toHaveBeenCalledWith(params[0]);
                expect(fakeNPMCommands.publish).toHaveBeenCalledWith(params, jasmine.any(Function));
                expect(spyUnlink).toHaveBeenCalledWith(path.resolve(params[0], 'package.json'));
            }));
        });
        it('should run unpublish', function() {
            var params = ['dummyplugin@0.6.0'];
            registryPromise(true, registry.unpublish(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.unpublish).toHaveBeenCalledWith(params, jasmine.any(Function));
                expect(fakeNPMCommands.cache).toHaveBeenCalledWith(['clean'], jasmine.any(Function));
            }));
        });
        it('should run search', function() {
            var params = ['dummyplugin', 'plugin'];
            registryPromise(true, registry.search(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.search).toHaveBeenCalledWith(params, true, jasmine.any(Function));
            }));
        });
    });
});
<commit_msg>解决单元测试不过的问题<commit_after>var registry = require('../../src/plugman/registry/registry'),
    manifest = require('../../src/plugman/registry/manifest'),
    fs = require('fs'),
    path = require('path'),
    Q = require('q'),
    shell   = require('shelljs'),
    os = require('os'),
    npm = require('npm');

describe('registry', function() {
    var done;
    beforeEach(function() {
        done = false;
    });
    function registryPromise(shouldSucceed, f) {
        waitsFor(function() { return done; }, 'promise never resolved', 500);
        return f.then(function() {
          done = true;
          expect(shouldSucceed).toBe(true);
        }, function(err) {
          done = err;
          expect(shouldSucceed).toBe(false);
        });
    }

    describe('manifest', function() {
        var pluginDir, packageJson, tmp_plugin, tmp_plugin_xml, tmp_package_json;
        beforeEach(function() {
            pluginDir = __dirname + '/../plugins/EnginePlugin';
            tmp_plugin = path.join(os.tmpdir(), 'plugin');
            tmp_plugin_xml = path.join(tmp_plugin, 'plugin.xml');
            tmp_package_json = path.join(tmp_plugin, 'package.json');
            shell.cp('-R', pluginDir+"/*", tmp_plugin);
        });
        afterEach(function() {
            shell.rm('-rf', tmp_plugin);
        });
        it('should generate a package.json from a plugin.xml', function() {
            registryPromise(true, manifest.generatePackageJsonFromPluginXml(tmp_plugin).then(function() {
                expect(fs.existsSync(tmp_package_json));
                var packageJson = JSON.parse(fs.readFileSync(tmp_package_json));
                expect(packageJson.name).toEqual('com.cordova.engine');
                expect(packageJson.version).toEqual('1.0.0');
                expect(packageJson.engines).toEqual(
                    [ { name : 'cordova', version : '>=2.3.0' }, { name : 'cordova-plugman', version : '>=0.10.0' }, { name : 'mega-fun-plugin', version : '>=1.0.0' }, { name : 'mega-boring-plugin', version : '>=3.0.0' } ]);
            }));
        });
        it('should raise an error if name does not follow com.domain.* format', function() {
            var xmlData = fs.readFileSync(tmp_plugin_xml).toString().replace('id="com.cordova.engine"', 'id="engine"');
            fs.writeFileSync(tmp_plugin_xml, xmlData);
            registryPromise(false, manifest.generatePackageJsonFromPluginXml(tmp_plugin));
        });
        it('should generate a package.json if name uses org.apache.cordova.* for a whitelisted plugin', function() {
            var xmlData = fs.readFileSync(tmp_plugin_xml).toString().replace('id="com.cordova.engine"', 'id="org.apache.cordova.camera"');
            fs.writeFileSync(tmp_plugin_xml, xmlData);
            registryPromise(true, manifest.generatePackageJsonFromPluginXml(tmp_plugin).then(function() {
                expect(!fs.existsSync(tmp_package_json));
            }));
        });
        it('should raise an error if name uses org.apache.cordova.* for a non-whitelisted plugin', function() {
            var xmlData = fs.readFileSync(tmp_plugin_xml).toString().replace('id="com.cordova.engine"', 'id="org.apache.cordova.myinvalidplugin"');
            fs.writeFileSync(tmp_plugin_xml, xmlData);
            registryPromise(false, manifest.generatePackageJsonFromPluginXml(tmp_plugin));
        });
    });
    describe('actions', function() {
        var fakeLoad, fakeNPMCommands;

        beforeEach(function() {
            done = false;
            var fakeSettings = {
                cache: '/some/cache/dir',
                logstream: 'somelogstream@2313213',
                userconfig: '/some/config/dir'
            };

            var fakeNPM = function() {
                if (arguments.length > 0) {
                    var cb = arguments[arguments.length-1];
                    if (cb && typeof cb === 'function') cb(null, true);
                }
            };

            registry.settings = fakeSettings;
            fakeLoad = spyOn(npm, 'load').andCallFake(function(settings, cb) { cb(null, true); });

            fakeNPMCommands = {};
            ['config', 'adduser', 'cache', 'publish', 'unpublish', 'search'].forEach(function(cmd) {
                fakeNPMCommands[cmd] = jasmine.createSpy(cmd).andCallFake(fakeNPM);
            });

            npm.commands = fakeNPMCommands;
            npm.config.set = function(){};
        });
        it('should run config', function() {
            var params = ['set', 'registry', 'http://registry.cordova.io'];
            registryPromise(true, registry.config(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.config).toHaveBeenCalledWith(params, jasmine.any(Function));
            }));
        });
        it('should run adduser', function() {
            registryPromise(true, registry.adduser(null).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.adduser).toHaveBeenCalledWith(null, jasmine.any(Function));
            }));
        });
        it('should run publish', function() {
            var params = [__dirname + '/../plugins/DummyPlugin'];
            var spyGenerate = spyOn(manifest, 'generatePackageJsonFromPluginXml').andReturn(Q());
            var spyUnlink = spyOn(fs, 'unlink');
            registryPromise(true, registry.publish(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(spyGenerate).toHaveBeenCalledWith(params[0]);
                expect(fakeNPMCommands.publish).toHaveBeenCalledWith(params, jasmine.any(Function));
                expect(spyUnlink).toHaveBeenCalledWith(path.resolve(params[0], 'package.json'));
            }));
        });
        it('should run unpublish', function() {
            var params = ['dummyplugin@0.6.0'];
            registryPromise(true, registry.unpublish(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.unpublish).toHaveBeenCalledWith(params, jasmine.any(Function));
                expect(fakeNPMCommands.cache).toHaveBeenCalledWith(['clean'], jasmine.any(Function));
            }));
        });
        it('should run search', function() {
            var params = ['dummyplugin', 'plugin'];
            registryPromise(true, registry.search(params).then(function() {
                expect(fakeLoad).toHaveBeenCalledWith(registry.settings, jasmine.any(Function));
                expect(fakeNPMCommands.search).toHaveBeenCalledWith(params, false, jasmine.any(Function));
            }));
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

(function(angular, app, undefined){

app.factory('CourseSearch', function(){
	// ranking scores
	var nameScore = 200,
		deptScore = 100,
		numberScore = 75,
		instructorScore = 50,
		beginningBonusMultiplier = 10,
		shortSubstringMaxScore = 1,
		cutoffScore = 50;

	var matches = function(string, substring, scoreBonus){
		var index = string.indexOf(substring);
		if (index >= 0 && substring.length < 3){
			return shortSubstringMaxScore;
		} else if (index === 0){
			return beginningBonusMultiplier * scoreBonus;
		} else if (index > 0){
			return scoreBonus;
		} else {
			return 0;
		}
	};

	return function(courses, query){
		var words = _.compact(query.toLowerCase().split(' '));
		return _(courses).chain().map(function(course){
			var courseName = course.name.toLowerCase();
			var deptCode = course.department.code.toLowerCase();
			var instructors = course.instructors().join(' ').toLowerCase();
			var score = _.reduce(words, function(accum, word){
				var additiveScore = (
					matches(courseName, word, nameScore) +
					matches(deptCode, word, deptScore) +
					matches(String(course.number), word, numberScore) +
					matches(instructors, word, instructorScore)
				);
				if (additiveScore > 0){
					return accum + additiveScore;
				} else {
					return 0;
				}
			}, 0);
			course.score = score;
			return course;
		}).filter(function(course){
			return course.score >= cutoffScore;
		}).sortBy(function(course){
			console.log(course.name, course.score);
			return -course.score; // DESC
		}).value();
	};
});

})(angular, app);

<commit_msg>added comments<commit_after>'use strict';

(function(angular, app, undefined){

app.factory('CourseSearch', function(){
	// score bonus for field matching
	var nameScore = 200,
		deptScore = 100,
		numberScore = 75,
		instructorScore = 50;
	// score modifiers
	var beginningBonusMultiplier = 10,
		shortSubstringMaxScore = 1;

	// "not a match" if less than this
	var cutoffScore = 50;

	var matches = function(string, substring, scoreBonus){
		var index = string.indexOf(substring);
		if (index >= 0 && substring.length < 3){
			return shortSubstringMaxScore;
		} else if (index === 0){
			return beginningBonusMultiplier * scoreBonus;
		} else if (index > 0){
			return scoreBonus;
		} else {
			return 0;
		}
	};

	return function(courses, query){
		var words = _.compact(query.toLowerCase().split(' '));
		return _(courses).chain().map(function(course){
			var courseName = course.name.toLowerCase();
			var deptCode = course.department.code.toLowerCase();
			var instructors = course.instructors().join(' ').toLowerCase();
			var score = _.reduce(words, function(accum, word){
				var additiveScore = (
					matches(courseName, word, nameScore) +
					matches(deptCode, word, deptScore) +
					matches(String(course.number), word, numberScore) +
					matches(instructors, word, instructorScore)
				);
				if (additiveScore > 0){
					return accum + additiveScore;
				} else {
					return 0;
				}
			}, 0);
			course.score = score;
			return course;
		}).filter(function(course){
			return course.score >= cutoffScore;
		}).sortBy(function(course){
			console.log(course.name, course.score);
			return -course.score; // DESC
		}).value();
	};
});

})(angular, app);

<|endoftext|>