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

import * as tf from '@tensorflow/tfjs';
import * as tfvis from '@tensorflow/tfjs-vis';

import {BostonHousingDataset, featureDescriptions} from './data';
import * as normalization from './normalization';
import * as ui from './ui';

// Some hyperparameters for model training.
const NUM_EPOCHS = 200;
const BATCH_SIZE = 40;
const LEARNING_RATE = 0.01;

const bostonData = new BostonHousingDataset();
const tensors = {};

// Convert loaded data into tensors and creates normalized versions of the
// features.
export function arraysToTensors() {
  tensors.rawTrainFeatures = tf.tensor2d(bostonData.trainFeatures);
  tensors.trainTarget = tf.tensor2d(bostonData.trainTarget);
  tensors.rawTestFeatures = tf.tensor2d(bostonData.testFeatures);
  tensors.testTarget = tf.tensor2d(bostonData.testTarget);
  // Normalize mean and standard deviation of data.
  let {dataMean, dataStd} =
      normalization.determineMeanAndStddev(tensors.rawTrainFeatures);

  tensors.trainFeatures = normalization.normalizeTensor(
      tensors.rawTrainFeatures, dataMean, dataStd);
  tensors.testFeatures =
      normalization.normalizeTensor(tensors.rawTestFeatures, dataMean, dataStd);
};

/**
 * Builds and returns Linear Regression Model.
 *
 * @returns {tf.Sequential} The linear regression model.
 */
export function linearRegressionModel() {
  const model = tf.sequential();
  model.add(tf.layers.dense({inputShape: [bostonData.numFeatures], units: 1}));

  model.summary();
  return model;
};

/**
 * Builds and returns Multi Layer Perceptron Regression Model
 * with 1 hidden layers, each with 10 units activated by sigmoid.
 *
 * @returns {tf.Sequential} The multi layer perceptron regression model.
 */
export function multiLayerPerceptronRegressionModel1Hidden() {
  const model = tf.sequential();
  model.add(tf.layers.dense({
    inputShape: [bostonData.numFeatures],
    units: 50,
    activation: 'sigmoid',
    kernelInitializer: 'leCunNormal'
  }));
  model.add(tf.layers.dense({units: 1}));

  model.summary();
  return model;
};

/**
 * Builds and returns Multi Layer Perceptron Regression Model
 * with 2 hidden layers, each with 10 units activated by sigmoid.
 *
 * @returns {tf.Sequential} The multi layer perceptron regression mode  l.
 */
export function multiLayerPerceptronRegressionModel2Hidden() {
  const model = tf.sequential();
  model.add(tf.layers.dense({
    inputShape: [bostonData.numFeatures],
    units: 50,
    activation: 'sigmoid',
    kernelInitializer: 'leCunNormal'
  }));
  model.add(tf.layers.dense(
      {units: 50, activation: 'sigmoid', kernelInitializer: 'leCunNormal'}));
  model.add(tf.layers.dense({units: 1}));

  model.summary();
  return model;
};

/**
 * Describe the current linear weights for a human to read.
 *
 * @param {Array} kernel Array of floats of length 12.  One value per feature.
 * @returns {List} List of objects, each with a string feature name, and value
 *     feature weight.
 */
export function describeKerenelElements(kernel) {
  tf.util.assert(
      kernel.length == 12,
      `kernel must be a array of length 12, got ${kernel.length}`);
  const outList = [];
  for (let idx = 0; idx < kernel.length; idx++) {
    outList.push({description: featureDescriptions[idx], value: kernel[idx]});
  }
  return outList;
}

/**
 * Compiles `model` and trains it using the train data and runs model against
 * test data. Issues a callback to update the UI after each epcoh.
 *
 * @param {tf.Sequential} model Model to be trained.
 * @param {boolean} weightsIllustration Whether to print info about the learned
 *  weights.
 */
export async function run(model, modelName, weightsIllustration) {
  model.compile(
      {optimizer: tf.train.sgd(LEARNING_RATE), loss: 'meanSquaredError'});

  let trainLogs = [];
  const container = document.querySelector(`#${modelName} .chart`);

  ui.updateStatus('Starting training process...');
  await model.fit(tensors.trainFeatures, tensors.trainTarget, {
    batchSize: BATCH_SIZE,
    epochs: NUM_EPOCHS,
    validationSplit: 0.2,
    callbacks: {
      onEpochEnd: async (epoch, logs) => {
        await ui.updateModelStatus(
            `Epoch ${epoch + 1} of ${NUM_EPOCHS} completed.`, modelName);
        trainLogs.push(logs);
        tfvis.show.history(container, trainLogs, ['loss', 'val_loss'])

        if (weightsIllustration) {
          model.layers[0].getWeights()[0].data().then(kernelAsArr => {
            const weightsList = describeKerenelElements(kernelAsArr);
            ui.updateWeightDescription(weightsList);
          });
        }
      }
    }
  });

  ui.updateStatus('Running on test data...');
  const result = model.evaluate(
      tensors.testFeatures, tensors.testTarget, {batchSize: BATCH_SIZE});
  const testLoss = result.dataSync()[0];

  const trainLoss = trainLogs[trainLogs.length - 1].loss;
  const valLoss = trainLogs[trainLogs.length - 1].val_loss;
  await ui.updateModelStatus(
      `Final train-set loss: ${trainLoss.toFixed(4)}\n` +
          `Final validation-set loss: ${valLoss.toFixed(4)}\n` +
          `Test-set loss: ${testLoss.toFixed(4)}`,
      modelName);
};

export function computeBaseline() {
  const avgPrice = tf.mean(tensors.trainTarget);
  console.log(`Average price: ${avgPrice.dataSync()}`);
  const baseline = tf.mean(tf.pow(tf.sub(tensors.testTarget, avgPrice), 2));
  console.log(`Baseline loss: ${baseline.dataSync()}`);
  const baselineMsg = `Baseline loss (meanSquaredError) is ${
      baseline.dataSync()[0].toFixed(2)}`;
  ui.updateBaselineStatus(baselineMsg);
};

document.addEventListener('DOMContentLoaded', async () => {
  await bostonData.loadData();
  ui.updateStatus('Data loaded, converting to tensors');
  arraysToTensors();
  ui.updateStatus(
      'Data is now available as tensors.\n' +
      'Click a train button to begin.');
  // TODO Explain what baseline loss is. How it is being computed in this
  // Instance
  ui.updateBaselineStatus('Estimating baseline loss');
  computeBaseline();
  await ui.setup();
}, false);
<commit_msg>Fix a typo in index.js (#199)<commit_after>/**
 * @license
 * Copyright 2018 Google LLC. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =============================================================================
 */

import * as tf from '@tensorflow/tfjs';
import * as tfvis from '@tensorflow/tfjs-vis';

import {BostonHousingDataset, featureDescriptions} from './data';
import * as normalization from './normalization';
import * as ui from './ui';

// Some hyperparameters for model training.
const NUM_EPOCHS = 200;
const BATCH_SIZE = 40;
const LEARNING_RATE = 0.01;

const bostonData = new BostonHousingDataset();
const tensors = {};

// Convert loaded data into tensors and creates normalized versions of the
// features.
export function arraysToTensors() {
  tensors.rawTrainFeatures = tf.tensor2d(bostonData.trainFeatures);
  tensors.trainTarget = tf.tensor2d(bostonData.trainTarget);
  tensors.rawTestFeatures = tf.tensor2d(bostonData.testFeatures);
  tensors.testTarget = tf.tensor2d(bostonData.testTarget);
  // Normalize mean and standard deviation of data.
  let {dataMean, dataStd} =
      normalization.determineMeanAndStddev(tensors.rawTrainFeatures);

  tensors.trainFeatures = normalization.normalizeTensor(
      tensors.rawTrainFeatures, dataMean, dataStd);
  tensors.testFeatures =
      normalization.normalizeTensor(tensors.rawTestFeatures, dataMean, dataStd);
};

/**
 * Builds and returns Linear Regression Model.
 *
 * @returns {tf.Sequential} The linear regression model.
 */
export function linearRegressionModel() {
  const model = tf.sequential();
  model.add(tf.layers.dense({inputShape: [bostonData.numFeatures], units: 1}));

  model.summary();
  return model;
};

/**
 * Builds and returns Multi Layer Perceptron Regression Model
 * with 1 hidden layers, each with 10 units activated by sigmoid.
 *
 * @returns {tf.Sequential} The multi layer perceptron regression model.
 */
export function multiLayerPerceptronRegressionModel1Hidden() {
  const model = tf.sequential();
  model.add(tf.layers.dense({
    inputShape: [bostonData.numFeatures],
    units: 50,
    activation: 'sigmoid',
    kernelInitializer: 'leCunNormal'
  }));
  model.add(tf.layers.dense({units: 1}));

  model.summary();
  return model;
};

/**
 * Builds and returns Multi Layer Perceptron Regression Model
 * with 2 hidden layers, each with 10 units activated by sigmoid.
 *
 * @returns {tf.Sequential} The multi layer perceptron regression mode  l.
 */
export function multiLayerPerceptronRegressionModel2Hidden() {
  const model = tf.sequential();
  model.add(tf.layers.dense({
    inputShape: [bostonData.numFeatures],
    units: 50,
    activation: 'sigmoid',
    kernelInitializer: 'leCunNormal'
  }));
  model.add(tf.layers.dense(
      {units: 50, activation: 'sigmoid', kernelInitializer: 'leCunNormal'}));
  model.add(tf.layers.dense({units: 1}));

  model.summary();
  return model;
};

/**
 * Describe the current linear weights for a human to read.
 *
 * @param {Array} kernel Array of floats of length 12.  One value per feature.
 * @returns {List} List of objects, each with a string feature name, and value
 *     feature weight.
 */
export function describeKernelElements(kernel) {
  tf.util.assert(
      kernel.length == 12,
      `kernel must be a array of length 12, got ${kernel.length}`);
  const outList = [];
  for (let idx = 0; idx < kernel.length; idx++) {
    outList.push({description: featureDescriptions[idx], value: kernel[idx]});
  }
  return outList;
}

/**
 * Compiles `model` and trains it using the train data and runs model against
 * test data. Issues a callback to update the UI after each epcoh.
 *
 * @param {tf.Sequential} model Model to be trained.
 * @param {boolean} weightsIllustration Whether to print info about the learned
 *  weights.
 */
export async function run(model, modelName, weightsIllustration) {
  model.compile(
      {optimizer: tf.train.sgd(LEARNING_RATE), loss: 'meanSquaredError'});

  let trainLogs = [];
  const container = document.querySelector(`#${modelName} .chart`);

  ui.updateStatus('Starting training process...');
  await model.fit(tensors.trainFeatures, tensors.trainTarget, {
    batchSize: BATCH_SIZE,
    epochs: NUM_EPOCHS,
    validationSplit: 0.2,
    callbacks: {
      onEpochEnd: async (epoch, logs) => {
        await ui.updateModelStatus(
            `Epoch ${epoch + 1} of ${NUM_EPOCHS} completed.`, modelName);
        trainLogs.push(logs);
        tfvis.show.history(container, trainLogs, ['loss', 'val_loss'])

        if (weightsIllustration) {
          model.layers[0].getWeights()[0].data().then(kernelAsArr => {
            const weightsList = describeKernelElements(kernelAsArr);
            ui.updateWeightDescription(weightsList);
          });
        }
      }
    }
  });

  ui.updateStatus('Running on test data...');
  const result = model.evaluate(
      tensors.testFeatures, tensors.testTarget, {batchSize: BATCH_SIZE});
  const testLoss = result.dataSync()[0];

  const trainLoss = trainLogs[trainLogs.length - 1].loss;
  const valLoss = trainLogs[trainLogs.length - 1].val_loss;
  await ui.updateModelStatus(
      `Final train-set loss: ${trainLoss.toFixed(4)}\n` +
          `Final validation-set loss: ${valLoss.toFixed(4)}\n` +
          `Test-set loss: ${testLoss.toFixed(4)}`,
      modelName);
};

export function computeBaseline() {
  const avgPrice = tf.mean(tensors.trainTarget);
  console.log(`Average price: ${avgPrice.dataSync()}`);
  const baseline = tf.mean(tf.pow(tf.sub(tensors.testTarget, avgPrice), 2));
  console.log(`Baseline loss: ${baseline.dataSync()}`);
  const baselineMsg = `Baseline loss (meanSquaredError) is ${
      baseline.dataSync()[0].toFixed(2)}`;
  ui.updateBaselineStatus(baselineMsg);
};

document.addEventListener('DOMContentLoaded', async () => {
  await bostonData.loadData();
  ui.updateStatus('Data loaded, converting to tensors');
  arraysToTensors();
  ui.updateStatus(
      'Data is now available as tensors.\n' +
      'Click a train button to begin.');
  // TODO Explain what baseline loss is. How it is being computed in this
  // Instance
  ui.updateBaselineStatus('Estimating baseline loss');
  computeBaseline();
  await ui.setup();
}, false);
<|endoftext|>


<commit_before>"use strict";

var x_d65 = 95.047;
var y_d65 = 100.000;
var z_d65 = 108.883;

function setColorBlock(r, g, b) {
    var color = sprintf('rgb(%d, %d, %d)', r, g, b);
    $('#color-block').css('background-color', color);
}

function setLabValues(l, a, b) {
    $('#lab-l').val(l);
    $('#lab-l-value').text(sprintf('%.2f', l));
    $('#lab-a').val(a);
    $('#lab-a-value').text(sprintf('%.2f', a));
    $('#lab-b').val(b);
    $('#lab-b-value').text(sprintf('%.2f', b));
}

function setCmyValues(c, m, y) {
    $('#cmy-c').val(c);
    $('#cmy-c-value').text(sprintf('%.2f', c));
    $('#cmy-m').val(m);
    $('#cmy-m-value').text(sprintf('%.2f', m));
    $('#cmy-y').val(y);
    $('#cmy-y-value').text(sprintf('%.2f', y));
}

function setHsvValues(h, s, v) {
    $('#hsv-h').val(h);
    $('#hsv-h-value').text(sprintf('%.2f', h));
    $('#hsv-s').val(s);
    $('#hsv-s-value').text(sprintf('%.2f', s));
    $('#hsv-v').val(v);
    $('#hsv-v-value').text(sprintf('%.2f', v));
}

function labToXyz(l, a, b) {
    var delta = 6 / 29;
    var finv = function(t) {
        if (t > delta)
            return t * t * t;
        else
            return 3 * delta * delta * (t - 4 / 29);
    }

    var x = x_d65 * finv((l + 16) / 116 + a / 500) / 100;
    var y = y_d65 * finv((l + 16) / 116) / 100;
    var z = z_d65 * finv((l + 16) / 116 - b / 200) / 100;
    return {
        x: x,
        y: y,
        z: z
    }
}

function xyzToLab(x, y, z) {
    var f = function(t) {
        if (t > Math.pow(6 / 29, 3))
            return Math.pow(t, 1 / 3);
        else
            return 1 / 3 * Math.pow(29 / 6, 2) * t + 4 / 29
    }

    return {
        l: 116 * f(y / y_d65) - 16,
        a: 500 * (f(x / x_d65) - f(y / y_d65)),
        b: 200 * (f(y / y_d65) - f(z / z_d65))
    }
}

function xyzToSrgb(x, y, z) {
    var r_lin = 3.2406 * x - 1.5372 * y - 0.4986 * z;
    var g_lin = -0.9689 * x + 1.8758 * y + 0.0415 * z;
    var b_lin = 0.0557 * x - 0.2040 * y + 1.0570 * z;

    var a = 0.055;
    var linToLog = function(lin) {
        if (lin <= 0.0031308)
            return 12.92 * lin;
        else
            return (1 + a) * Math.pow(lin, 1 / 2.4) - a;
    }

    return {
        r: Math.floor(linToLog(r_lin) * 255),
        g: Math.floor(linToLog(g_lin) * 255),
        b: Math.floor(linToLog(b_lin) * 255)
    }
}

function srgbToXyz(r, g, b) {
    var a = 0.055;
    var toLin = function(c) {
        if (c <= 0.04045)
            return c / 12.92;
        else
            return Math.pow((c + a) / (1 + a), 2.4)
    }

    var r_lin = toLin(r / 255);
    var g_lin = toLin(g / 255);
    var b_lin = toLin(b / 255);

    return {
        x: (0.4124 * r_lin + 0.3576 * g_lin + 0.1805 * b_lin) * 100,
        y: (0.2126 * r_lin + 0.7152 * g_lin + 0.0722 * b_lin) * 100,
        z: (0.0193 * r_lin + 0.1192 * g_lin + 0.9505 * b_lin) * 100
    }
}

function rgbToCmy(r, g, b) {
    return {
        c: (1 - r / 255) * 100,
        m: (1 - g / 255) * 100,
        y: (1 - b / 255) * 100
    }
}

function cmyToRgb(c, m, y) {
    return {
        r: (1 - c / 100) * 255,
        g: (1 - m / 100) * 255,
        b: (1 - y / 100) * 255,
    }
}

function rgbToHsv(r, g, b) {
    r /= 255;
    g /= 255;
    b /= 255;

    var cmax = Math.max(r, g, b);
    var cmin = Math.min(r, g, b);
    var delta = cmax - cmin;

    var h;
    if (delta == 0)
        h = 0;
    else if (cmax == r)
        h = 60 * (((g - b) / delta) % 6);
    else if (cmax == g)
        h = 60 * ((b - r) / delta + 2);
    else
        h = 60 * ((r - g) / delta + 4);
    h = (h + 360) % 360;

    var s;
    if (cmax == 0)
        s = 0;
    else
        s = delta / cmax * 100;

    var v = cmax * 100;

    return {
        h: h,
        s: s,
        v: v
    }
}

function renderLab() {
    var l = parseFloat($('#lab-l').val());
    var a = parseFloat($('#lab-a').val());
    var b = parseFloat($('#lab-b').val());
    setLabValues(l, a, b);

    var xyz = labToXyz(l, a, b);
    var rgb = xyzToSrgb(xyz.x, xyz.y, xyz.z);
    var cmy = rgbToCmy(rgb.r, rgb.g, rgb.b);
    var hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);

    setColorBlock(rgb.r, rgb.g, rgb.b);
    setCmyValues(cmy.c, cmy.m, cmy.y);
    setHsvValues(hsv.h, hsv.s, hsv.v);
}

function renderCmy() {
    var c = parseFloat($('#cmy-c').val());
    var m = parseFloat($('#cmy-m').val());
    var y = parseFloat($('#cmy-y').val());
    setCmyValues(c, m, y);

    var rgb = cmyToRgb(c, m, y);
    var hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
    var xyz = srgbToXyz(rgb.r, rgb.g, rgb.b);
    var lab = xyzToLab(xyz.x, xyz.y, xyz.z);

    setColorBlock(rgb.r, rgb.g, rgb.b);
    setHsvValues(hsv.h, hsv.s, hsv.v);
    setLabValues(lab.l, lab.a, lab.b);
}

$(document).ready(function () {
    setCmyValues(7, 87, 96);
    renderCmy();

    $('#lab-l').on('input', renderLab);
    $('#lab-a').on('input', renderLab);
    $('#lab-b').on('input', renderLab);

    $('#cmy-c').on('input', renderCmy);
    $('#cmy-m').on('input', renderCmy);
    $('#cmy-y').on('input', renderCmy);
});
<commit_msg>Add conversion from hsv<commit_after>"use strict";

var x_d65 = 95.047;
var y_d65 = 100.000;
var z_d65 = 108.883;

function setColorBlock(r, g, b) {
    var color = sprintf('rgb(%d, %d, %d)', r, g, b);
    $('#color-block').css('background-color', color);
}

function setLabValues(l, a, b) {
    $('#lab-l').val(l);
    $('#lab-l-value').text(sprintf('%.2f', l));
    $('#lab-a').val(a);
    $('#lab-a-value').text(sprintf('%.2f', a));
    $('#lab-b').val(b);
    $('#lab-b-value').text(sprintf('%.2f', b));
}

function setCmyValues(c, m, y) {
    $('#cmy-c').val(c);
    $('#cmy-c-value').text(sprintf('%.2f', c));
    $('#cmy-m').val(m);
    $('#cmy-m-value').text(sprintf('%.2f', m));
    $('#cmy-y').val(y);
    $('#cmy-y-value').text(sprintf('%.2f', y));
}

function setHsvValues(h, s, v) {
    $('#hsv-h').val(h);
    $('#hsv-h-value').text(sprintf('%.2f', h));
    $('#hsv-s').val(s);
    $('#hsv-s-value').text(sprintf('%.2f', s));
    $('#hsv-v').val(v);
    $('#hsv-v-value').text(sprintf('%.2f', v));
}

function labToXyz(l, a, b) {
    var delta = 6 / 29;
    var finv = function(t) {
        if (t > delta)
            return t * t * t;
        else
            return 3 * delta * delta * (t - 4 / 29);
    }

    var x = x_d65 * finv((l + 16) / 116 + a / 500) / 100;
    var y = y_d65 * finv((l + 16) / 116) / 100;
    var z = z_d65 * finv((l + 16) / 116 - b / 200) / 100;
    return {
        x: x,
        y: y,
        z: z
    }
}

function xyzToLab(x, y, z) {
    var f = function(t) {
        if (t > Math.pow(6 / 29, 3))
            return Math.pow(t, 1 / 3);
        else
            return 1 / 3 * Math.pow(29 / 6, 2) * t + 4 / 29
    }

    return {
        l: 116 * f(y / y_d65) - 16,
        a: 500 * (f(x / x_d65) - f(y / y_d65)),
        b: 200 * (f(y / y_d65) - f(z / z_d65))
    }
}

function xyzToSrgb(x, y, z) {
    var r_lin = 3.2406 * x - 1.5372 * y - 0.4986 * z;
    var g_lin = -0.9689 * x + 1.8758 * y + 0.0415 * z;
    var b_lin = 0.0557 * x - 0.2040 * y + 1.0570 * z;

    var a = 0.055;
    var linToLog = function(lin) {
        if (lin <= 0.0031308)
            return 12.92 * lin;
        else
            return (1 + a) * Math.pow(lin, 1 / 2.4) - a;
    }

    return {
        r: Math.floor(linToLog(r_lin) * 255),
        g: Math.floor(linToLog(g_lin) * 255),
        b: Math.floor(linToLog(b_lin) * 255)
    }
}

function srgbToXyz(r, g, b) {
    var a = 0.055;
    var toLin = function(c) {
        if (c <= 0.04045)
            return c / 12.92;
        else
            return Math.pow((c + a) / (1 + a), 2.4)
    }

    var r_lin = toLin(r / 255);
    var g_lin = toLin(g / 255);
    var b_lin = toLin(b / 255);

    return {
        x: (0.4124 * r_lin + 0.3576 * g_lin + 0.1805 * b_lin) * 100,
        y: (0.2126 * r_lin + 0.7152 * g_lin + 0.0722 * b_lin) * 100,
        z: (0.0193 * r_lin + 0.1192 * g_lin + 0.9505 * b_lin) * 100
    }
}

function rgbToCmy(r, g, b) {
    return {
        c: (1 - r / 255) * 100,
        m: (1 - g / 255) * 100,
        y: (1 - b / 255) * 100
    }
}

function cmyToRgb(c, m, y) {
    return {
        r: (1 - c / 100) * 255,
        g: (1 - m / 100) * 255,
        b: (1 - y / 100) * 255,
    }
}

function rgbToHsv(r, g, b) {
    r /= 255;
    g /= 255;
    b /= 255;

    var cmax = Math.max(r, g, b);
    var cmin = Math.min(r, g, b);
    var delta = cmax - cmin;

    var h;
    if (delta == 0)
        h = 0;
    else if (cmax == r)
        h = 60 * (((g - b) / delta) % 6);
    else if (cmax == g)
        h = 60 * ((b - r) / delta + 2);
    else
        h = 60 * ((r - g) / delta + 4);
    h = (h + 360) % 360;

    var s;
    if (cmax == 0)
        s = 0;
    else
        s = delta / cmax * 100;

    var v = cmax * 100;

    return {
        h: h,
        s: s,
        v: v
    }
}

function hsvToRgb(h, s, v) {
    s /= 100;
    v /= 100;

    var c = v * s;
    var x = c * (1 - Math.abs(((h / 60) % 2) - 1))
    var m = v - c;

    var r, g, b;
    h = h % 360;
    if (h >= 0 && h < 60) {
        r = c;
        g = x;
        b = 0;
    } else if (h >= 60 && h < 120) {
        r = x;
        g = c;
        b = 0;
    } else if (h >= 120 && h < 180) {
        r = 0;
        g = c;
        b = x;
    } else if (h >= 180 && h < 240) {
        r = 0;
        g = x;
        b = c;
    } else if (h >= 240 && h < 300) {
        r = x;
        g = 0;
        b = c;
    } else if (h >= 300 && h < 360) {
        r = c;
        g = 0;
        b = x;
    }

    return {
        r: (r + m) * 255,
        g: (g + m) * 255,
        b: (b + m) * 255
    }
}

function renderLab() {
    var l = parseFloat($('#lab-l').val());
    var a = parseFloat($('#lab-a').val());
    var b = parseFloat($('#lab-b').val());
    setLabValues(l, a, b);

    var xyz = labToXyz(l, a, b);
    var rgb = xyzToSrgb(xyz.x, xyz.y, xyz.z);
    var cmy = rgbToCmy(rgb.r, rgb.g, rgb.b);
    var hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);

    setColorBlock(rgb.r, rgb.g, rgb.b);
    setCmyValues(cmy.c, cmy.m, cmy.y);
    setHsvValues(hsv.h, hsv.s, hsv.v);
}

function renderCmy() {
    var c = parseFloat($('#cmy-c').val());
    var m = parseFloat($('#cmy-m').val());
    var y = parseFloat($('#cmy-y').val());
    setCmyValues(c, m, y);

    var rgb = cmyToRgb(c, m, y);
    var hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
    var xyz = srgbToXyz(rgb.r, rgb.g, rgb.b);
    var lab = xyzToLab(xyz.x, xyz.y, xyz.z);

    setColorBlock(rgb.r, rgb.g, rgb.b);
    setHsvValues(hsv.h, hsv.s, hsv.v);
    setLabValues(lab.l, lab.a, lab.b);
}

function renderHsv() {
    var h = parseFloat($('#hsv-h').val());
    var s = parseFloat($('#hsv-s').val());
    var v = parseFloat($('#hsv-v').val());
    setHsvValues(h, s, v);

    var rgb = hsvToRgb(h, s, v);
    var cmy = rgbToCmy(rgb.r, rgb.g, rgb.b);
    var xyz = srgbToXyz(rgb.r, rgb.g, rgb.b);
    var lab = xyzToLab(xyz.x, xyz.y, xyz.z);

    setColorBlock(rgb.r, rgb.g, rgb.b);
    setCmyValues(cmy.c, cmy.m, cmy.y);
    setLabValues(lab.l, lab.a, lab.b);
}

$(document).ready(function () {
    setHsvValues(7, 87, 96);
    renderCmy();

    $('#lab-l').on('input', renderLab);
    $('#lab-a').on('input', renderLab);
    $('#lab-b').on('input', renderLab);

    $('#cmy-c').on('input', renderCmy);
    $('#cmy-m').on('input', renderCmy);
    $('#cmy-y').on('input', renderCmy);

    $('#hsv-h').on('input', renderHsv);
    $('#hsv-s').on('input', renderHsv);
    $('#hsv-v').on('input', renderHsv);
});
<|endoftext|>


<commit_before>import {
  default as createStore
} from 'store/createStore'

describe('(Store) createStore', () => {
  let store

  before(() => {
    store = createStore()
  })

  it('should have an empty asyncReducers object', () => {
    expect(store.asyncReducers).to.be.an('object')
    expect(store.asyncReducers).to.be.empty()
  })

  describe('(Location)', () => {
    it('store should be initialized with Location state', () => {
      const location = {
        pathname : '/echo'
      }
      store.dispatch({
        type    : 'LOCATION_CHANGE_BUG',
        payload : location
      })
      expect(store.getState().location).to.deep.equal(location)
    })
  })
})
<commit_msg>I make it<commit_after>import {
  default as createStore
} from 'store/createStore'

describe('(Store) createStore', () => {
  let store

  before(() => {
    store = createStore()
  })

  it('should have an empty asyncReducers object', () => {
    expect(store.asyncReducers).to.be.an('object')
    expect(store.asyncReducers).to.be.empty()
  })

  describe('(Location)', () => {
    it('store should be initialized with Location state', () => {
      const location = {
        pathname : '/echo'
      }
      store.dispatch({
        type    : 'LOCATION_CHANGE',
        payload : location
      })
      expect(store.getState().location).to.deep.equal(location)
    })
  })
})
<|endoftext|>


<commit_before>var leafletDirective = angular.module("leaflet-directive", []);

leafletDirective.directive("leaflet", ["$http", "$log", function ($http, $log) {
    var defaults = {
        maxZoom: 10,
        tileLayer: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        icon: {
            url: 'img/leaflet/marker-icon.png',
            retinaUrl: 'img/leaflet/marker-icon-2x.png',
            size: [25, 41],
            anchor: [12, 40],
            popup: [-3, -76],
            shadow: {
                url: 'img/leaflet/marker-shadow.png',
                retinaUrl: 'img/leaflet/marker-shadow.png',
                size: [41, 41],
                anchor: [12, 40]
            }
        },
        path: {
            weight: 10,
            opacity: 1
        }
    };
    return {
        restrict: "E",
        replace: true,
        transclude: true,
        scope: {
            center: '=center',
            markers: '=markers',
            path: '=path'
        },
        template: '

',
        link: function ($scope, element, attrs /*, ctrl */) {
            var map = new L.Map(element[0]);
            map.setView([0, 0], 1);

            $scope.leaflet = {};
            $scope.leaflet.map = !!attrs.testing ? map : 'Add testing="testing" to <leaflet> tag to inspect this object';
            $scope.leaflet.maxZoom = !!attrs.maxzoom ? parseInt(attrs.maxzoom, defaults.maxZoom) : defaults.maxZoom;
            $scope.leaflet.tileLayer = attrs.tileLayer || defaults.tileLayer;

            L.tileLayer($scope.leaflet.tileLayer, { maxZoom: $scope.leaflet.maxZoom }).addTo(map);

            setupCenter();
            setupMarkers();
            setupPath();

            function setupCenter() {
                if (!$scope.center)
                    return;

                if ($scope.center.lat && $scope.center.lng && $scope.center.zoom)
                    map.setView([$scope.center.lat, $scope.center.lng], $scope.center.zoom);
                else if ($scope.center.autoDiscover === true)
                    map.locate({ setView: true, maxZoom: $scope.maxZoom });

                map.on("dragend", function (/* event */) {
                    $scope.$apply(function (scope) {
                        scope.center.lat = map.getCenter().lat;
                        scope.center.lng = map.getCenter().lng;
                    });
                });

                map.on("zoomend", function (/* event */) {
                    if ($scope.center.zoom !== map.getZoom()) {
                        $scope.$apply(function (s) {
                            s.center.zoom = map.getZoom();
                        });
                    }
                });

                $scope.$watch("center", function (center /*, oldValue */) {
                    if (center.lat && center.lng && center.zoom) {
                        map.setView([center.lat, center.lng], center.zoom);
                    }
                }, true);
            }

            function setupMarkers() {
                var markers = {};
                $scope.leaflet.markers = !!attrs.testing ? markers : 'Add testing="testing" to <leaflet> tag to inspect this object';
                if (!$scope.markers)
                    return;
                addMarkers($scope.markers, markers);

                $scope.$watch("markers", function (newMarkers) {
                    addMarkers(newMarkers, markers);
                }, true);
            }

            function addMarkers(markers, currentMarkers) {
                for (var name in markers)
                    if (currentMarkers[name] === undefined) {
                        var marker = buildMarker(name);

                        marker.on("dragend", function (/* event */) {
                            $scope.$apply(function (/* scope */) {
                                data.lat = marker.getLatLng().lat;
                                data.lng = marker.getLatLng().lng;
                            });
                            if (data.message)
                                marker.openPopup();
                        });

                        $scope.$watch('markers.' + name, function (data, oldData) {
                            if (!data) {
                                map.removeLayer(currentMarkers[name]);
                                delete currentMarkers[name];
                                return;
                            }

                            if (data.draggable !== undefined && data.draggable !== oldData.draggable)
                                if (data.draggable === true)
                                    marker.dragging.enable();
                                else
                                    marker.dragging.disable();

                            if (data.focus !== undefined && data.focus !== oldData.focus)
                                if (data.focus === true)
                                    marker.openPopup();
                                else
                                    marker.closePopup();

                            if (data.message !== undefined && data.message !== oldData.message)
                                marker.bindPopup(data);

                            if (data.lat !== oldData.lat || data.lng !== oldData.lng)
                                marker.setLatLng(new L.LatLng(data.lat, data.lng));
                        }, true);
                        map.addLayer(marker);
                        currentMarkers[name] = marker;
                    }
            }

            function buildMarker(name) {
                var data, marker;
                data = $scope.markers[name];
                marker = new L.marker(
                        $scope.markers[name],
                        {
                            icon: buildIcon(),
                            draggable: data.draggable ? true : false
                        }
                );
                if (data.message)
                    marker.bindPopup(data.message);
                return marker;
            }

            function buildIcon() {
                return L.icon({
                    iconUrl: defaults.icon.url,
                    iconRetinaUrl: defaults.icon.retinaUrl,
                    iconSize: defaults.icon.size,
                    iconAnchor: defaults.icon.anchor,
                    popupAnchor: defaults.icon.popup,
                    shadowUrl: defaults.icon.shadow.url,
                    shadowRetinaUrl: defaults.icon.shadow.retinaUrl,
                    shadowSize: defaults.icon.shadow.size,
                    shadowAnchor: defaults.icon.shadow.anchor
                });
            }

            function setupPath() {
                // TODO Create as many polylines as paths defined in model
                // TODO Manage opacity changes with another $watch block
                if (!$scope.path)
                    return;
                $log.warn("[AngularJS - Leaflet] Creating polylines and adding them to the map will break the directive's scope's inspection in AngularJS Batarang");
                var polyline = new L.Polyline([], { weight: defaults.path.weight, opacity: defaults.path.opacity});
                $scope.leaflet.path = !!attrs.testing ? polyline : 'Add testing="testing" to <leaflet> tag to inspect this object';

                map.addLayer(polyline);

                $scope.$watch("path.latlngs", function (latlngs) {
                    var leafletLatLngs = latlngs
                            .filter(function (latlng) {
                                return !!latlng.lat && !!latlng.lng;
                            })
                            .map(function (latlng) {
                                return new L.LatLng(latlng.lat, latlng.lng);
                            });
                    polyline.setLatLngs(leafletLatLngs);
                }, true);

                $scope.$watch("path.weight", function (weight) {
                    polyline.setStyle({ weight: weight });
                }, true);

                $scope.$watch("path.color", function (color) {
                    polyline.setStyle({ color: color });
                }, true);
            }
        }
    };
}]);
<commit_msg>Added brackets on single-line conditionals<commit_after>var leafletDirective = angular.module("leaflet-directive", []);

leafletDirective.directive("leaflet", ["$http", "$log", function ($http, $log) {
    var defaults = {
        maxZoom: 10,
        tileLayer: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        icon: {
            url: 'img/leaflet/marker-icon.png',
            retinaUrl: 'img/leaflet/marker-icon-2x.png',
            size: [25, 41],
            anchor: [12, 40],
            popup: [-3, -76],
            shadow: {
                url: 'img/leaflet/marker-shadow.png',
                retinaUrl: 'img/leaflet/marker-shadow.png',
                size: [41, 41],
                anchor: [12, 40]
            }
        },
        path: {
            weight: 10,
            opacity: 1
        }
    };
    return {
        restrict: "E",
        replace: true,
        transclude: true,
        scope: {
            center: '=center',
            markers: '=markers',
            path: '=path'
        },
        template: '

',
        link: function ($scope, element, attrs /*, ctrl */) {
            var map = new L.Map(element[0]);
            map.setView([0, 0], 1);

            $scope.leaflet = {};
            $scope.leaflet.map = !!attrs.testing ? map : 'Add testing="testing" to <leaflet> tag to inspect this object';
            $scope.leaflet.maxZoom = !!attrs.maxzoom ? parseInt(attrs.maxzoom, defaults.maxZoom) : defaults.maxZoom;
            $scope.leaflet.tileLayer = attrs.tileLayer || defaults.tileLayer;

            L.tileLayer($scope.leaflet.tileLayer, { maxZoom: $scope.leaflet.maxZoom }).addTo(map);

            setupCenter();
            setupMarkers();
            setupPath();

            function setupCenter() {
                if (!$scope.center) {
                    return;
                }

                if ($scope.center.lat && $scope.center.lng && $scope.center.zoom) {
                    map.setView([$scope.center.lat, $scope.center.lng], $scope.center.zoom);
                } else if ($scope.center.autoDiscover === true) {
                    map.locate({ setView: true, maxZoom: $scope.maxZoom });
                }

                map.on("dragend", function (/* event */) {
                    $scope.$apply(function (scope) {
                        scope.center.lat = map.getCenter().lat;
                        scope.center.lng = map.getCenter().lng;
                    });
                });

                map.on("zoomend", function (/* event */) {
                    if ($scope.center.zoom !== map.getZoom()) {
                        $scope.$apply(function (s) {
                            s.center.zoom = map.getZoom();
                        });
                    }
                });

                $scope.$watch("center", function (center /*, oldValue */) {
                    if (center.lat && center.lng && center.zoom) {
                        map.setView([center.lat, center.lng], center.zoom);
                    }
                }, true);
            }

            function setupMarkers() {
                var markers = {};
                $scope.leaflet.markers = !!attrs.testing ? markers : 'Add testing="testing" to <leaflet> tag to inspect this object';
                if (!$scope.markers) {
                    return;
                }
                addMarkers($scope.markers, markers);

                $scope.$watch("markers", function (newMarkers) {
                    addMarkers(newMarkers, markers);
                }, true);
            }

            function addMarkers(markers, currentMarkers) {
                for (var name in markers) {
                    if (currentMarkers[name] === undefined) {
                        var marker = buildMarker(name);

                        marker.on("dragend", function (/* event */) {
                            $scope.$apply(function (/* scope */) {
                                data.lat = marker.getLatLng().lat;
                                data.lng = marker.getLatLng().lng;
                            });
                            if (data.message) {
                                marker.openPopup();
                            }
                        });

                        $scope.$watch('markers.' + name, function (data, oldData) {
                            if (!data) {
                                map.removeLayer(currentMarkers[name]);
                                delete currentMarkers[name];
                                return;
                            }

                            if (data.draggable !== undefined && data.draggable !== oldData.draggable) {
                                if (data.draggable === true) {
                                    marker.dragging.enable();
                                } else {
                                    marker.dragging.disable();
                                }

                            if (data.focus !== undefined && data.focus !== oldData.focus) {
                                if (data.focus === true) {
                                    marker.openPopup();
                                } else {
                                    marker.closePopup();
                                }

                            if (data.message !== undefined && data.message !== oldData.message) {
                                marker.bindPopup(data);
                            }

                            if (data.lat !== oldData.lat || data.lng !== oldData.lng) {
                                marker.setLatLng(new L.LatLng(data.lat, data.lng));
                            }
                        }, true);
                        map.addLayer(marker);
                        currentMarkers[name] = marker;
                    }
            }

            function buildMarker(name) {
                var data, marker;
                data = $scope.markers[name];
                marker = new L.marker(
                        $scope.markers[name],
                        {
                            icon: buildIcon(),
                            draggable: data.draggable ? true : false
                        }
                );
                if (data.message) {
                    marker.bindPopup(data.message);
                }
                return marker;
            }

            function buildIcon() {
                return L.icon({
                    iconUrl: defaults.icon.url,
                    iconRetinaUrl: defaults.icon.retinaUrl,
                    iconSize: defaults.icon.size,
                    iconAnchor: defaults.icon.anchor,
                    popupAnchor: defaults.icon.popup,
                    shadowUrl: defaults.icon.shadow.url,
                    shadowRetinaUrl: defaults.icon.shadow.retinaUrl,
                    shadowSize: defaults.icon.shadow.size,
                    shadowAnchor: defaults.icon.shadow.anchor
                });
            }

            function setupPath() {
                // TODO Create as many polylines as paths defined in model
                // TODO Manage opacity changes with another $watch block
                if (!$scope.path) {
                    return;
                }
                $log.warn("[AngularJS - Leaflet] Creating polylines and adding them to the map will break the directive's scope's inspection in AngularJS Batarang");
                var polyline = new L.Polyline([], { weight: defaults.path.weight, opacity: defaults.path.opacity});
                $scope.leaflet.path = !!attrs.testing ? polyline : 'Add testing="testing" to <leaflet> tag to inspect this object';

                map.addLayer(polyline);

                $scope.$watch("path.latlngs", function (latlngs) {
                    var leafletLatLngs = latlngs
                            .filter(function (latlng) {
                                return !!latlng.lat && !!latlng.lng;
                            })
                            .map(function (latlng) {
                                return new L.LatLng(latlng.lat, latlng.lng);
                            });
                    polyline.setLatLngs(leafletLatLngs);
                }, true);

                $scope.$watch("path.weight", function (weight) {
                    polyline.setStyle({ weight: weight });
                }, true);

                $scope.$watch("path.color", function (color) {
                    polyline.setStyle({ color: color });
                }, true);
            }
        }
    };
}]);
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */
import * as mongo from 'mongodb';
import Post from '../../models/post';
import User from '../../models/user';
import serialize from '../../serializers/post';

/**
 * Get posts of a user
 *
 * @param {Object} params
 * @param {Object} me
 * @return {Promise<object>}
 */
module.exports = (params, me) =>
	new Promise(async (res, rej) =>
{
	// Get 'user_id' parameter
	let userId = params.user_id;
	if (userId === undefined || userId === null || userId === '') {
		userId = null;
	}

	// Get 'username' parameter
	let username = params.username;
	if (username === undefined || username === null || username === '') {
		username = null;
	}

	if (userId === null && username === null) {
		return rej('user_id or username is required');
	}

	// Get 'with_replies' parameter
	let withReplies = params.with_replies;
	if (withReplies == null) {
		withReplies = false;
	}

	// Get 'with_media' parameter
	let withMedia = params.with_media;
	if (withMedia == null) {
		withMedia = false;
	}

	// Get 'limit' parameter
	let limit = params.limit;
	if (limit !== undefined && limit !== null) {
		limit = parseInt(limit, 10);

		// From 1 to 100
		if (!(1 <= limit && limit <= 100)) {
			return rej('invalid limit range');
		}
	} else {
		limit = 10;
	}

	const since = params.since_id || null;
	const max = params.max_id || null;

	// Check if both of since_id and max_id is specified
	if (since !== null && max !== null) {
		return rej('cannot set since_id and max_id');
	}

	const q = userId != null
		? { _id: new mongo.ObjectID(userId) }
		: { username_lower: username.toLowerCase() } ;

	// Lookup user
	const user = await User.findOne(q, {
		fields: {
			_id: true
		}
	});

	if (user === null) {
		return rej('user not found');
	}

	// Construct query
	const sort = {
		_id: -1
	};
	const query = {
		user_id: user._id
	};
	if (since !== null) {
		sort._id = 1;
		query._id = {
			$gt: new mongo.ObjectID(since)
		};
	} else if (max !== null) {
		query._id = {
			$lt: new mongo.ObjectID(max)
		};
	}

	if (!withReplies) {
		query.reply_to_id = null;
	}

	if (withMedia) {
		query.media_ids = {
			$exists: true,
			$ne: null
		};
	}

	// Issue query
	const posts = await Post
		.find(query, {
			limit: limit,
			sort: sort
		});

	// Serialize
	res(await Promise.all(posts.map(async (post) =>
		await serialize(post, me)
	)));
});
<commit_msg>[API] デフォルトでリプライを含むように<commit_after>'use strict';

/**
 * Module dependencies
 */
import * as mongo from 'mongodb';
import Post from '../../models/post';
import User from '../../models/user';
import serialize from '../../serializers/post';

/**
 * Get posts of a user
 *
 * @param {Object} params
 * @param {Object} me
 * @return {Promise<object>}
 */
module.exports = (params, me) =>
	new Promise(async (res, rej) =>
{
	// Get 'user_id' parameter
	let userId = params.user_id;
	if (userId === undefined || userId === null || userId === '') {
		userId = null;
	}

	// Get 'username' parameter
	let username = params.username;
	if (username === undefined || username === null || username === '') {
		username = null;
	}

	if (userId === null && username === null) {
		return rej('user_id or username is required');
	}

	// Get 'with_replies' parameter
	let withReplies = params.with_replies;
	if (withReplies == null) {
		withReplies = true;
	}

	// Get 'with_media' parameter
	let withMedia = params.with_media;
	if (withMedia == null) {
		withMedia = false;
	}

	// Get 'limit' parameter
	let limit = params.limit;
	if (limit !== undefined && limit !== null) {
		limit = parseInt(limit, 10);

		// From 1 to 100
		if (!(1 <= limit && limit <= 100)) {
			return rej('invalid limit range');
		}
	} else {
		limit = 10;
	}

	const since = params.since_id || null;
	const max = params.max_id || null;

	// Check if both of since_id and max_id is specified
	if (since !== null && max !== null) {
		return rej('cannot set since_id and max_id');
	}

	const q = userId != null
		? { _id: new mongo.ObjectID(userId) }
		: { username_lower: username.toLowerCase() } ;

	// Lookup user
	const user = await User.findOne(q, {
		fields: {
			_id: true
		}
	});

	if (user === null) {
		return rej('user not found');
	}

	// Construct query
	const sort = {
		_id: -1
	};
	const query = {
		user_id: user._id
	};
	if (since !== null) {
		sort._id = 1;
		query._id = {
			$gt: new mongo.ObjectID(since)
		};
	} else if (max !== null) {
		query._id = {
			$lt: new mongo.ObjectID(max)
		};
	}

	if (!withReplies) {
		query.reply_to_id = null;
	}

	if (withMedia) {
		query.media_ids = {
			$exists: true,
			$ne: null
		};
	}

	// Issue query
	const posts = await Post
		.find(query, {
			limit: limit,
			sort: sort
		});

	// Serialize
	res(await Promise.all(posts.map(async (post) =>
		await serialize(post, me)
	)));
});
<|endoftext|>


<commit_before>
(function Component (id) {// @lock

// Add the code that needs to be shared between components here

function constructor (id) {

	// @region beginComponentDeclaration// @startlock
	var $comp = this;
	this.name = 'sitofuori';
	// @endregion// @endlock

	this.load = function (data) {// @lock

	// @region namespaceDeclaration// @startlock
	// @endregion// @endlock

	// eventHandlers// @lock

	// @region eventManager// @startlock
	// @endregion// @endlock

	};// @lock

}// @startlock
return constructor;
})();// @endlock
<commit_msg>Delete sitofuori.js<commit_after><|endoftext|>


<commit_before>require( "../setup" );

var iotivity = require( "../../index" ),
	testUtils = require( "../test-utils" )( iotivity, QUnit.assert );

test( "Simple discovery", function( assert ) {
	var result, stopProcessing,
		done = assert.async(),
		failsafeTimeoutId = null,
		handle = {},
		teardown = function() {

			if ( stopProcessing ) {
				stopProcessing();
			}
			if ( failsafeTimeoutId !== null ) {
				clearTimeout( failsafeTimeoutId );
				failsafeTimeoutId = null;
			}
			assert.deepEqual( handlerWasCalled, true, "OCDoResource handler was called" );
			testUtils.testShutdown();
			done();
		};

	if ( testUtils.testStartup( iotivity.OCMode.OC_CLIENT ) ===
			iotivity.OCStackResult.OC_STACK_OK ) {

		stopProcessing = testUtils.testProcessing( 100, function() {
			teardown();
		} );

		failsafeTimeoutId = setTimeout( function() {
			failsafeTimeoutId = null;
			teardown();
		}, 5000 );

		result = iotivity.OCDoResource(
			handle,
			iotivity.OCMethod.OC_REST_GET,
			"light",
			null,
			null,
			iotivity.OCConnectivityType.OC_ALL,
			iotivity.OCQualityOfService.OC_HIGH_QOS,
			function( handle, response ) {
				handlerWasCalled = true;
				teardown();
			},
			null,
			0 );
	}
} );
<commit_msg>Tests: Simple discovery bounces against test server it starts<commit_after>require( "../setup" );

var iotivity = require( "../../index" ),
	testUtils = require( "../test-utils" )( iotivity, QUnit.assert );

test( "Simple discovery", function( assert ) {
	var result, stopProcessing,
		stopTestServer,
		done = assert.async(),
		failsafeTimeoutId = null,
		handle = {},
		teardown = function() {

			if ( stopTestServer ) {
				stopTestServer();
			}

			if ( stopProcessing ) {
				stopProcessing();
			}

			if ( failsafeTimeoutId !== null ) {
				clearTimeout( failsafeTimeoutId );
				failsafeTimeoutId = null;
			}

			assert.deepEqual( handlerWasCalled, true, "OCDoResource handler was called" );

			testUtils.testShutdown();

			done();
		};

	if ( testUtils.testStartup( iotivity.OCMode.OC_CLIENT ) ===
			iotivity.OCStackResult.OC_STACK_OK ) {

		stopTestServer = testUtils.startTestServer(
			function() {
				stopProcessing = testUtils.testProcessing( 100, function() {
					teardown();
				} );

				failsafeTimeoutId = setTimeout( function() {
					failsafeTimeoutId = null;
					teardown();
				}, 5000 );

				result = iotivity.OCDoResource(
					handle,
					iotivity.OCMethod.OC_REST_GET,
					"light",
					null,
					null,
					iotivity.OCConnectivityType.OC_ALL,
					iotivity.OCQualityOfService.OC_HIGH_QOS,
					function( handle, response ) {
						handlerWasCalled = true;
						teardown();
					},
					null,
					0 );
			},
			function() {
				teardown();
			} );
	}
} );
<|endoftext|>


<commit_before>//@flow
/*
Copyright 2016 Aviral Dasgupta
Copyright 2017 Vector Creations Ltd

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.
*/

import React from 'react';
import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider';
import {PillCompletion} from './Components';
import sdk from '../index';
import FuzzyMatcher from './FuzzyMatcher';
import _pull from 'lodash/pull';
import _sortBy from 'lodash/sortBy';
import MatrixClientPeg from '../MatrixClientPeg';

import type {Room, RoomMember} from 'matrix-js-sdk';

const USER_REGEX = /@\S*/g;

let instance = null;

export default class UserProvider extends AutocompleteProvider {
    users: Array<RoomMember> = [];

    constructor() {
        super(USER_REGEX, {
            keys: ['name'],
        });
        this.matcher = new FuzzyMatcher([], {
            keys: ['name', 'userId'],
            shouldMatchPrefix: true,
        });
    }

    async getCompletions(query: string, selection: {start: number, end: number}, force = false) {
        const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar');

        // Disable autocompletions when composing commands because of various issues
        // (see https://github.com/vector-im/riot-web/issues/4762)
        if (/^(\/ban|\/unban|\/op|\/deop|\/invite|\/kick|\/verify)/.test(query)) {
            return [];
        }

        let completions = [];
        let {command, range} = this.getCurrentCommand(query, selection, force);
        if (command) {
            completions = this.matcher.match(command[0]).map((user) => {
                const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done
                return {
                    // Length of completion should equal length of text in decorator. draft-js
                    // relies on the length of the entity === length of the text in the decoration.
                    completion: user.rawDisplayName.replace(' (IRC)', ''),
                    suffix: range.start === 0 ? ': ' : ' ',
                    href: 'https://matrix.to/#/' + user.userId,
                    component: (
                        <PillCompletion
                            initialComponent={<MemberAvatar member={user} width={24} height={24}/>}
                            title={displayName}
                            description={user.userId} />
                    ),
                    range,
                };
            });
        }
        return completions;
    }

    getName() {
        return '👥 ' + _t('Users');
    }

    setUserListFromRoom(room: Room) {
        const events = room.getLiveTimeline().getEvents();
        const lastSpoken = {};

        for(const event of events) {
            lastSpoken[event.getSender()] = event.getTs();
        }

        const currentUserId = MatrixClientPeg.get().credentials.userId;
        this.users = room.getJoinedMembers().filter((member) => {
            if (member.userId !== currentUserId) return true;
        });

        this.users = _sortBy(this.users, (member) =>
            1E20 - lastSpoken[member.userId] || 1E20,
        );

        this.matcher.setObjects(this.users);
    }

    onUserSpoke(user: RoomMember) {
        if(user.userId === MatrixClientPeg.get().credentials.userId) return;

        // Move the user that spoke to the front of the array
        this.users.splice(
            this.users.findIndex((user2) => user2.userId === user.userId), 1);
        this.users = [user, ...this.users];

        this.matcher.setObjects(this.users);
    }

    static getInstance(): UserProvider {
        if (instance == null) {
            instance = new UserProvider();
        }
        return instance;
    }

    renderCompletions(completions: [React.Component]): ?React.Component {
        return

            {completions}

;
    }

    shouldForceComplete(): boolean {
        return true;
    }
}
<commit_msg>Experimental: Lazy load user autocomplete entries<commit_after>//@flow
/*
Copyright 2016 Aviral Dasgupta
Copyright 2017 Vector Creations Ltd

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.
*/

import React from 'react';
import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider';
import {PillCompletion} from './Components';
import sdk from '../index';
import FuzzyMatcher from './FuzzyMatcher';
import _pull from 'lodash/pull';
import _sortBy from 'lodash/sortBy';
import MatrixClientPeg from '../MatrixClientPeg';

import type {Room, RoomMember} from 'matrix-js-sdk';

const USER_REGEX = /@\S*/g;

let instance = null;

export default class UserProvider extends AutocompleteProvider {
    users: Array<RoomMember> = null;
    room: Room = null;

    constructor() {
        super(USER_REGEX, {
            keys: ['name'],
        });
        this.matcher = new FuzzyMatcher([], {
            keys: ['name', 'userId'],
            shouldMatchPrefix: true,
        });
    }

    async getCompletions(query: string, selection: {start: number, end: number}, force = false) {
        const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar');

        // Disable autocompletions when composing commands because of various issues
        // (see https://github.com/vector-im/riot-web/issues/4762)
        if (/^(\/ban|\/unban|\/op|\/deop|\/invite|\/kick|\/verify)/.test(query)) {
            return [];
        }

        // lazy-load user list into matcher
        if (this.users === null) this._makeUsers();

        let completions = [];
        let {command, range} = this.getCurrentCommand(query, selection, force);
        if (command) {
            completions = this.matcher.match(command[0]).map((user) => {
                const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done
                return {
                    // Length of completion should equal length of text in decorator. draft-js
                    // relies on the length of the entity === length of the text in the decoration.
                    completion: user.rawDisplayName.replace(' (IRC)', ''),
                    suffix: range.start === 0 ? ': ' : ' ',
                    href: 'https://matrix.to/#/' + user.userId,
                    component: (
                        <PillCompletion
                            initialComponent={<MemberAvatar member={user} width={24} height={24}/>}
                            title={displayName}
                            description={user.userId} />
                    ),
                    range,
                };
            });
        }
        return completions;
    }

    getName() {
        return '👥 ' + _t('Users');
    }

    setUserListFromRoom(room: Room) {
        this.room = room;
        this.users = null;
    }

    _makeUsers() {
        const events = this.room.getLiveTimeline().getEvents();
        const lastSpoken = {};

        for(const event of events) {
            lastSpoken[event.getSender()] = event.getTs();
        }

        const currentUserId = MatrixClientPeg.get().credentials.userId;
        this.users = this.room.getJoinedMembers().filter((member) => {
            if (member.userId !== currentUserId) return true;
        });

        this.users = _sortBy(this.users, (member) =>
            1E20 - lastSpoken[member.userId] || 1E20,
        );

        this.matcher.setObjects(this.users);
    }

    onUserSpoke(user: RoomMember) {
        if (this.room === null) return;
        if (user.userId === MatrixClientPeg.get().credentials.userId) return;

        // Move the user that spoke to the front of the array
        this.users.splice(
            this.users.findIndex((user2) => user2.userId === user.userId), 1);
        this.users = [user, ...this.users];

        this.matcher.setObjects(this.users);
    }

    static getInstance(): UserProvider {
        if (instance == null) {
            instance = new UserProvider();
        }
        return instance;
    }

    renderCompletions(completions: [React.Component]): ?React.Component {
        return

            {completions}

;
    }

    shouldForceComplete(): boolean {
        return true;
    }
}
<|endoftext|>


<commit_before>/* global QUnit */
import Em from 'ember';
import ArrayOffset from 'array-offset';

QUnit.module('ArrayOffset');

QUnit.test('constructor exists', function (assert) {
	assert.ok(ArrayOffset, 'ArrayOffset is not null or undefined');
	assert.equal(typeof ArrayOffset, 'function', 'ArrayOffset is function');
});

QUnit.test('can be initialized without content', function (assert) {
	assert.ok(ArrayOffset.create(), 'ArrayOffset is created without content');
});

QUnit.test('content is initialized', function (assert) {
	var arr = Em.A(['a', 'b', 'c']);
	var proxy = ArrayOffset.create({
		content: arr
	});
	assert.equal(proxy.get('arrangedContent.length'), 3);
	assert.equal(proxy.get('content.length'), 3);
	assert.equal(proxy.get('length'), 3);
	assert.equal(proxy.get('arrangedContent').join(''), 'abc');
});
<commit_msg>Test default offset<commit_after>/* global QUnit */
import Em from 'ember';
import ArrayOffset from 'array-offset';

QUnit.module('ArrayOffset');

QUnit.test('constructor exists', function (assert) {
	assert.ok(ArrayOffset, 'ArrayOffset is not null or undefined');
	assert.equal(typeof ArrayOffset, 'function', 'ArrayOffset is function');
});

QUnit.test('can be initialized without content', function (assert) {
	assert.ok(ArrayOffset.create(), 'ArrayOffset is created without content');
});

QUnit.test('content is initialized', function (assert) {
	var arr = Em.A(['a', 'b', 'c']);
	var proxy = ArrayOffset.create({
		content: arr
	});
	assert.equal(proxy.get('arrangedContent.length'), 3);
	assert.equal(proxy.get('content.length'), 3);
	assert.equal(proxy.get('length'), 3);
	assert.equal(proxy.get('arrangedContent').join(''), 'abc');
});

QUnit.test('default offset', function (assert) {
	var proxy = ArrayOffset.create();
	assert.equal(proxy.get('offset'), 0, 'Default offset is zero');
});
<|endoftext|>


<commit_before>'use strict';

const expect = require('../../chai').expect;
const map = require('ember-cli-lodash-subset').map;
const commandOptions = require('../../factories/command-options');
const NewCommand = require('../../../lib/commands/new');
const Blueprint = require('../../../lib/models/blueprint');
const Command = require('../../../lib/models/command');
const Task = require('../../../lib/models/task');
const td = require('testdouble');

describe('new command', function () {
  let command;
  let error;

  beforeEach(function () {
    let options = commandOptions({
      project: {
        isEmberCLIProject() {
          return false;
        },
        blueprintLookupPaths() {
          return [];
        },
      },
    });

    command = new NewCommand(options);

    td.replace(Blueprint, 'lookup', td.function());
  });

  afterEach(function () {
    td.reset();
  });

  it("doesn't allow to create an application named `test`", async function () {
    error = await expect(command.validateAndRun(['test'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `test`.');
  });

  it("doesn't allow to create an application named `ember`", async function () {
    error = await expect(command.validateAndRun(['ember'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `ember`.');
  });

  it("doesn't allow to create an application named `Ember`", async function () {
    error = await expect(command.validateAndRun(['Ember'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `Ember`.');
  });

  it("doesn't allow to create an application named `ember-cli`", async function () {
    error = await expect(command.validateAndRun(['ember-cli'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `ember-cli`.');
  });

  it("doesn't allow to create an application named `vendor`", async function () {
    error = await expect(command.validateAndRun(['vendor'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `vendor`.');
  });

  it("doesn't allow to create an application with a period in the name", async function () {
    error = await expect(command.validateAndRun(['zomg.awesome'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `zomg.awesome`.');
  });

  it("doesn't allow to create an application with a name beginning with a number", async function () {
    error = await expect(command.validateAndRun(['123-my-bagel'])).to.be.rejected;
    expect(error.message).to.equal('We currently do not support a name of `123-my-bagel`.');
  });

  it('shows a suggestion messages when the application name is a period', async function () {
    error = await expect(command.validateAndRun(['.'])).to.be.rejected;
    expect(error.message).to.equal(
      `Trying to generate an application structure in this directory? Use \`ember init\` instead.`
    );
  });

  it('registers blueprint options in beforeRun', function () {
    td.when(Blueprint.lookup('app'), { ignoreExtraArgs: true }).thenReturn({
      availableOptions: [{ name: 'custom-blueprint-option', type: String }],
    });

    command.beforeRun(['app']);
    expect(map(command.availableOptions, 'name')).to.contain('custom-blueprint-option');
  });

  it('passes command options through to init command', async function () {
    command.tasks.CreateAndStepIntoDirectory = Task.extend({
      run() {
        return Promise.resolve();
      },
    });

    command.commands.Init = Command.extend({
      run(commandOptions) {
        expect(commandOptions).to.contain.keys('customOption');
        expect(commandOptions.customOption).to.equal('customValue');
        return Promise.resolve('Called run');
      },
    });

    td.when(Blueprint.lookup('app'), { ignoreExtraArgs: true }).thenReturn({
      availableOptions: [{ name: 'custom-blueprint-option', type: String }],
    });

    let reason = await command.validateAndRun(['foo', '--custom-option=customValue']);
    expect(reason).to.equal('Called run');
  });
});
<commit_msg>inline variable declaration and destructure message<commit_after>'use strict';

const expect = require('../../chai').expect;
const map = require('ember-cli-lodash-subset').map;
const commandOptions = require('../../factories/command-options');
const NewCommand = require('../../../lib/commands/new');
const Blueprint = require('../../../lib/models/blueprint');
const Command = require('../../../lib/models/command');
const Task = require('../../../lib/models/task');
const td = require('testdouble');

describe('new command', function () {
  let command;

  beforeEach(function () {
    let options = commandOptions({
      project: {
        isEmberCLIProject() {
          return false;
        },
        blueprintLookupPaths() {
          return [];
        },
      },
    });

    command = new NewCommand(options);

    td.replace(Blueprint, 'lookup', td.function());
  });

  afterEach(function () {
    td.reset();
  });

  it("doesn't allow to create an application named `test`", async function () {
    let { message } = await expect(command.validateAndRun(['test'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `test`.');
  });

  it("doesn't allow to create an application named `ember`", async function () {
    let { message } = await expect(command.validateAndRun(['ember'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `ember`.');
  });

  it("doesn't allow to create an application named `Ember`", async function () {
    let { message } = await expect(command.validateAndRun(['Ember'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `Ember`.');
  });

  it("doesn't allow to create an application named `ember-cli`", async function () {
    let { message } = await expect(command.validateAndRun(['ember-cli'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `ember-cli`.');
  });

  it("doesn't allow to create an application named `vendor`", async function () {
    let { message } = await expect(command.validateAndRun(['vendor'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `vendor`.');
  });

  it("doesn't allow to create an application with a period in the name", async function () {
    let { message } = await expect(command.validateAndRun(['zomg.awesome'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `zomg.awesome`.');
  });

  it("doesn't allow to create an application with a name beginning with a number", async function () {
    let { message } = await expect(command.validateAndRun(['123-my-bagel'])).to.be.rejected;
    expect(message).to.equal('We currently do not support a name of `123-my-bagel`.');
  });

  it('shows a suggestion messages when the application name is a period', async function () {
    let { message } = await expect(command.validateAndRun(['.'])).to.be.rejected;
    expect(message).to.equal(
      `Trying to generate an application structure in this directory? Use \`ember init\` instead.`
    );
  });

  it('registers blueprint options in beforeRun', function () {
    td.when(Blueprint.lookup('app'), { ignoreExtraArgs: true }).thenReturn({
      availableOptions: [{ name: 'custom-blueprint-option', type: String }],
    });

    command.beforeRun(['app']);
    expect(map(command.availableOptions, 'name')).to.contain('custom-blueprint-option');
  });

  it('passes command options through to init command', async function () {
    command.tasks.CreateAndStepIntoDirectory = Task.extend({
      run() {
        return Promise.resolve();
      },
    });

    command.commands.Init = Command.extend({
      run(commandOptions) {
        expect(commandOptions).to.contain.keys('customOption');
        expect(commandOptions.customOption).to.equal('customValue');
        return Promise.resolve('Called run');
      },
    });

    td.when(Blueprint.lookup('app'), { ignoreExtraArgs: true }).thenReturn({
      availableOptions: [{ name: 'custom-blueprint-option', type: String }],
    });

    let reason = await command.validateAndRun(['foo', '--custom-option=customValue']);
    expect(reason).to.equal('Called run');
  });
});
<|endoftext|>


<commit_before>/*
 * JavaScript tracker for Snowplow: tests/functional/detectors.js
 *
 * Significant portions copyright 2010 Anthon Pang. Remainder copyright
 * 2012-2014 Snowplow Analytics Ltd. 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 Anthon Pang nor Snowplow Analytics Ltd nor the
 *   names of their contributors may be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT
 * OWNER OR 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.
 */

define([
	'intern!object'
], function(registerSuite) {

	registerSuite({

		name: 'Integration setup',

		'Set up the page and send some events to request_recorder': function() {

			return this.remote
				.get(require.toUrl('tests/pages/integration.html'))
				.waitForElementByCssSelector('body.loaded', 5000)
				.sleep(1000);
		}
	});
});
<commit_msg>Increased delay<commit_after>/*
 * JavaScript tracker for Snowplow: tests/functional/detectors.js
 *
 * Significant portions copyright 2010 Anthon Pang. Remainder copyright
 * 2012-2014 Snowplow Analytics Ltd. 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 Anthon Pang nor Snowplow Analytics Ltd nor the
 *   names of their contributors may be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT
 * OWNER OR 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.
 */

define([
	'intern!object'
], function(registerSuite) {

	registerSuite({

		name: 'Integration setup',

		'Set up the page and send some events to request_recorder': function() {

			return this.remote
				.get(require.toUrl('tests/pages/integration.html'))
				.waitForElementByCssSelector('body.loaded', 5000)
				.sleep(2000);
		}
	});
});
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

var modulemapper = require('cordova/modulemapper');

var browserWrap,
    popup,
    navigationButtonsDiv,
    navigationButtonsDivInner,
    backButton,
    forwardButton,
    closeButton;

function attachNavigationEvents(element, callback) {
    var onError = function () {
        callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true});
    };

    element.addEventListener("pageshow", function () {
        callback({ type: "loadstart", url: this.contentWindow.location}, {keepCallback: true});
    });

    element.addEventListener("load", function () {
        callback({ type: "loadstop", url: this.contentWindow.location}, {keepCallback: true});
    });

    element.addEventListener("error", onError);
    element.addEventListener("abort", onError);
}

var IAB = {
    close: function (win, lose) {
        if (browserWrap) {
            if (win) win({ type: "exit" });

            browserWrap.parentNode.removeChild(browserWrap);
            browserWrap = null;
            popup = null;
        }
    },

    show: function (win, lose) {
        if (browserWrap) {
            browserWrap.style.display = "block";
        }
    },

    open: function (win, lose, args) {
        var strUrl = args[0],
            target = args[1],
            features = args[2];

        if (target === "_self" || !target) {
            window.location = strUrl;
        } else if (target === "_system") {
            modulemapper.getOriginalSymbol(window, 'window.open').call(window, strUrl, "_blank");
        } else {
            // "_blank" or anything else
            if (!browserWrap) {
                browserWrap = document.createElement("div");
                browserWrap.style.position = "absolute";
                browserWrap.style.borderWidth = "40px";
                browserWrap.style.width = "calc(100% - 80px)";
                browserWrap.style.height = "calc(100% - 80px)";
                browserWrap.style.borderStyle = "solid";
                browserWrap.style.borderColor = "rgba(0,0,0,0.25)";

                browserWrap.onclick = function () {
                    setTimeout(function () {
                        IAB.close(win);
                    }, 0);
                };

                document.body.appendChild(browserWrap);
            }

            if (features.indexOf("hidden=yes") !== -1) {
                browserWrap.style.display = "none";
            }

            popup = document.createElement("iframe");
            popup.style.borderWidth = "0px";
            popup.style.width = "100%";

            browserWrap.appendChild(popup);

            if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) {
                popup.style.height = "calc(100% - 60px)";

                navigationButtonsDiv = document.createElement("div");
                navigationButtonsDiv.style.height = "60px";
                navigationButtonsDiv.style.backgroundColor = "#404040";
                navigationButtonsDiv.style.zIndex = "999";
                navigationButtonsDiv.onclick = function (e) {
                    e.cancelBubble = true;
                };

                navigationButtonsDivInner = document.createElement("div");
                navigationButtonsDivInner.style.paddingTop = "10px";
                navigationButtonsDivInner.style.height = "50px";
                navigationButtonsDivInner.style.width = "160px";
                navigationButtonsDivInner.style.margin = "0 auto";
                navigationButtonsDivInner.style.backgroundColor = "#404040";
                navigationButtonsDivInner.style.zIndex = "999";
                navigationButtonsDivInner.onclick = function (e) {
                    e.cancelBubble = true;
                };

                backButton = document.createElement("button");
                backButton.style.width = "40px";
                backButton.style.height = "40px";
                backButton.style.borderRadius = "40px";

                backButton.innerHTML = "←";
                backButton.addEventListener("click", function (e) {
                    if (popup.canGoBack)
                        popup.goBack();
                });

                forwardButton = document.createElement("button");
                forwardButton.style.marginLeft = "20px";
                forwardButton.style.width = "40px";
                forwardButton.style.height = "40px";
                forwardButton.style.borderRadius = "40px";

                forwardButton.innerHTML = "→";
                forwardButton.addEventListener("click", function (e) {
                    if (popup.canGoForward)
                        popup.goForward();
                });

                closeButton = document.createElement("button");
                closeButton.style.marginLeft = "20px";
                closeButton.style.width = "40px";
                closeButton.style.height = "40px";
                closeButton.style.borderRadius = "40px";

                closeButton.innerHTML = "✖";
                closeButton.addEventListener("click", function (e) {
                    setTimeout(function () {
                        IAB.close(win);
                    }, 0);
                });

                // iframe navigation is not yet supported
                backButton.disabled = true;
                forwardButton.disabled = true;

                navigationButtonsDivInner.appendChild(backButton);
                navigationButtonsDivInner.appendChild(forwardButton);
                navigationButtonsDivInner.appendChild(closeButton);
                navigationButtonsDiv.appendChild(navigationButtonsDivInner);

                browserWrap.appendChild(navigationButtonsDiv);
            } else {
                popup.style.height = "100%";
            }

            // start listening for navigation events
            attachNavigationEvents(popup, win);

            popup.src = strUrl;
        }
    },

    injectScriptCode: function (win, fail, args) {
        var code = args[0],
            hasCallback = args[1];

        if (browserWrap && popup) {
            try {
                popup.contentWindow.eval(code);
                if (hasCallback) {
                    win([]);
                }
            } catch(e) {
                console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e));
            }
        }
    },

    injectScriptFile: function (win, fail, args) {
        var msg = 'Browser cordova-plugin-inappbrowser injectScriptFile is not yet implemented';
        console.warn(msg);
        if (fail) {
            fail(msg);
        }
    },

    injectStyleCode: function (win, fail, args) {
        var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented';
        console.warn(msg);
        if (fail) {
            fail(msg);
        }
    },

    injectStyleFile: function (win, fail, args) {
        var msg = 'Browser cordova-plugin-inappbrowser injectStyleFile is not yet implemented';
        console.warn(msg);
        if (fail) {
            fail(msg);
        }
    }
};

module.exports = IAB;

require("cordova/exec/proxy").add("InAppBrowser", module.exports);
<commit_msg>Size and position in browser platform<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

var modulemapper = require('cordova/modulemapper');

var browserWrap,
    popup,
    navigationButtonsDiv,
    navigationButtonsDivInner,
    backButton,
    forwardButton,
    closeButton;

function attachNavigationEvents(element, callback) {
    var onError = function () {
        callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true});
    };

    element.addEventListener("pageshow", function () {
        callback({ type: "loadstart", url: this.contentWindow.location}, {keepCallback: true});
    });

    element.addEventListener("load", function () {
        callback({ type: "loadstop", url: this.contentWindow.location}, {keepCallback: true});
    });

    element.addEventListener("error", onError);
    element.addEventListener("abort", onError);
}

var IAB = {
    close: function (win, lose) {
        if (browserWrap) {
            if (win) win({ type: "exit" });

            browserWrap.parentNode.removeChild(browserWrap);
            browserWrap = null;
            popup = null;
        }
    },

    show: function (win, lose) {
        if (browserWrap) {
            browserWrap.style.display = "block";
        }
    },

    open: function (win, lose, args) {
        var strUrl = args[0],
            target = args[1],
            features = args[2];

        if (target === "_self" || !target) {
            window.location = strUrl;
        } else if (target === "_system") {
            modulemapper.getOriginalSymbol(window, 'window.open').call(window, strUrl, "_blank");
        } else {
            // "_blank" or anything else
            if (!browserWrap) {
                browserWrap = document.createElement("div");
                browserWrap.style.position = "absolute";
                browserWrap.style.top = "0";
                browserWrap.style.left = "0";
                browserWrap.style.boxSizing = "border-box";
                browserWrap.style.borderWidth = "40px";
                browserWrap.style.width = "100vw";
                browserWrap.style.height = "100vh";
                browserWrap.style.borderStyle = "solid";
                browserWrap.style.borderColor = "rgba(0,0,0,0.25)";

                browserWrap.onclick = function () {
                    setTimeout(function () {
                        IAB.close(win);
                    }, 0);
                };

                document.body.appendChild(browserWrap);
            }

            if (features.indexOf("hidden=yes") !== -1) {
                browserWrap.style.display = "none";
            }

            popup = document.createElement("iframe");
            popup.style.borderWidth = "0px";
            popup.style.width = "100%";

            browserWrap.appendChild(popup);

            if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) {
                popup.style.height = "calc(100% - 60px)";

                navigationButtonsDiv = document.createElement("div");
                navigationButtonsDiv.style.height = "60px";
                navigationButtonsDiv.style.backgroundColor = "#404040";
                navigationButtonsDiv.style.zIndex = "999";
                navigationButtonsDiv.onclick = function (e) {
                    e.cancelBubble = true;
                };

                navigationButtonsDivInner = document.createElement("div");
                navigationButtonsDivInner.style.paddingTop = "10px";
                navigationButtonsDivInner.style.height = "50px";
                navigationButtonsDivInner.style.width = "160px";
                navigationButtonsDivInner.style.margin = "0 auto";
                navigationButtonsDivInner.style.backgroundColor = "#404040";
                navigationButtonsDivInner.style.zIndex = "999";
                navigationButtonsDivInner.onclick = function (e) {
                    e.cancelBubble = true;
                };

                backButton = document.createElement("button");
                backButton.style.width = "40px";
                backButton.style.height = "40px";
                backButton.style.borderRadius = "40px";

                backButton.innerHTML = "←";
                backButton.addEventListener("click", function (e) {
                    if (popup.canGoBack)
                        popup.goBack();
                });

                forwardButton = document.createElement("button");
                forwardButton.style.marginLeft = "20px";
                forwardButton.style.width = "40px";
                forwardButton.style.height = "40px";
                forwardButton.style.borderRadius = "40px";

                forwardButton.innerHTML = "→";
                forwardButton.addEventListener("click", function (e) {
                    if (popup.canGoForward)
                        popup.goForward();
                });

                closeButton = document.createElement("button");
                closeButton.style.marginLeft = "20px";
                closeButton.style.width = "40px";
                closeButton.style.height = "40px";
                closeButton.style.borderRadius = "40px";

                closeButton.innerHTML = "✖";
                closeButton.addEventListener("click", function (e) {
                    setTimeout(function () {
                        IAB.close(win);
                    }, 0);
                });

                // iframe navigation is not yet supported
                backButton.disabled = true;
                forwardButton.disabled = true;

                navigationButtonsDivInner.appendChild(backButton);
                navigationButtonsDivInner.appendChild(forwardButton);
                navigationButtonsDivInner.appendChild(closeButton);
                navigationButtonsDiv.appendChild(navigationButtonsDivInner);

                browserWrap.appendChild(navigationButtonsDiv);
            } else {
                popup.style.height = "100%";
            }

            // start listening for navigation events
            attachNavigationEvents(popup, win);

            popup.src = strUrl;
        }
    },

    injectScriptCode: function (win, fail, args) {
        var code = args[0],
            hasCallback = args[1];

        if (browserWrap && popup) {
            try {
                popup.contentWindow.eval(code);
                if (hasCallback) {
                    win([]);
                }
            } catch(e) {
                console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e));
            }
        }
    },

    injectScriptFile: function (win, fail, args) {
        var msg = 'Browser cordova-plugin-inappbrowser injectScriptFile is not yet implemented';
        console.warn(msg);
        if (fail) {
            fail(msg);
        }
    },

    injectStyleCode: function (win, fail, args) {
        var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented';
        console.warn(msg);
        if (fail) {
            fail(msg);
        }
    },

    injectStyleFile: function (win, fail, args) {
        var msg = 'Browser cordova-plugin-inappbrowser injectStyleFile is not yet implemented';
        console.warn(msg);
        if (fail) {
            fail(msg);
        }
    }
};

module.exports = IAB;

require("cordova/exec/proxy").add("InAppBrowser", module.exports);
<|endoftext|>


<commit_before>jQuery(function ($) {
	var
		$annotation = $("#annotation"),
		$output = $("#output"),
		$input = $("#input-hex");

	function handleAnnotationRequested(e, data) {
		var
			$el = data.$el,
			$resultValue = $(".result .value", $el),
			text;

		e = e;

		text = (!!data.output) ? data.output() : data.result;
		if (text !== null && !!text.slice) {
			// @NOTE This slice is here to protect from browser crashes,
			//       when appending a 65kb text snippet to the DOM.
			//       There is probably a way to do that right, without
			//       crashing, but even then it would still be a UI
			//       challenge to present 65kb of text data in any
			//       meaningful way.
			text = text.slice(0, 100);
		}

		$resultValue.text(text);
		if (data.error) {
			$resultValue.addClass("error");
		} else {
			$resultValue.removeClass("error");
		}

		$el.data({
			"bitindex-from": data.bitIndex.from,
			"bitindex-to": data.bitIndex.to
		});
		shared.show($el);

		$output.trigger("register/requested", {
			"$el": $el,
			"from": $el.data("bitindex-from"),
			"to": $el.data("bitindex-to")
		});
	}

	function handleMouseenter() {
		var $this = $(this);

		$output.trigger("hover/requested", {
			"$el": $this,
			"from": $this.data("bitindex-from"),
			"to": $this.data("bitindex-to")
		});
	}

	function handleMouseleave() {
		var $this = $(this);

		$output.trigger("unhover/requested", {
			"from": $this.data("bitindex-from"),
			"to": $this.data("bitindex-to")
		});
	}

	function handleInputPassed() {
		$("> fieldset", $annotation).each(function () {
			var
				$el = $(this),
				$resultValue = $(".result .value", $el),
				$toggle = $(".toggle", $el);

			$resultValue.text("").removeClass("error");
			$toggle.trigger("reset/requested");
			shared.hide($el);
		});
	}

	function handleHoverRequested(e, el) {
		var $el = $(el);

		$el.addClass("hover");

		$annotation.parent().stop(true, false).animate({
			"scrollTop": $el.position().top
		}, 300);
	}

	function handleUnhoverRequested(e, el) {
		var $el = $(el);
		$el.removeClass("hover");
	}

	$annotation
		.on("annotation/requested", "fieldset", handleAnnotationRequested)
		.on("mouseenter", "fieldset", handleMouseenter)
		.on("mouseleave", "fieldset", handleMouseleave)
		.on("hover/requested", handleHoverRequested)
		.on("unhover/requested", handleUnhoverRequested);

	$input.on("input/passed", handleInputPassed);
});<commit_msg>MOD: DRYed class<commit_after>jQuery(function ($) {
	var
		classHover = "hover",
		$annotation = $("#annotation"),
		$output = $("#output"),
		$input = $("#input-hex");

	function handleAnnotationRequested(e, data) {
		var
			$el = data.$el,
			$resultValue = $(".result .value", $el),
			text;

		e = e;

		text = (!!data.output) ? data.output() : data.result;
		if (text !== null && !!text.slice) {
			// @NOTE This slice is here to protect from browser crashes,
			//       when appending a 65kb text snippet to the DOM.
			//       There is probably a way to do that right, without
			//       crashing, but even then it would still be a UI
			//       challenge to present 65kb of text data in any
			//       meaningful way.
			text = text.slice(0, 100);
		}

		$resultValue.text(text);
		if (data.error) {
			$resultValue.addClass("error");
		} else {
			$resultValue.removeClass("error");
		}

		$el.data({
			"bitindex-from": data.bitIndex.from,
			"bitindex-to": data.bitIndex.to
		});
		shared.show($el);

		$output.trigger("register/requested", {
			"$el": $el,
			"from": $el.data("bitindex-from"),
			"to": $el.data("bitindex-to")
		});
	}

	function handleMouseenter() {
		var $this = $(this);

		$output.trigger("hover/requested", {
			"$el": $this,
			"from": $this.data("bitindex-from"),
			"to": $this.data("bitindex-to")
		});
	}

	function handleMouseleave() {
		var $this = $(this);

		$output.trigger("unhover/requested", {
			"from": $this.data("bitindex-from"),
			"to": $this.data("bitindex-to")
		});
	}

	function handleInputPassed() {
		$("> fieldset", $annotation).each(function () {
			var
				$el = $(this),
				$resultValue = $(".result .value", $el),
				$toggle = $(".toggle", $el);

			$resultValue.text("").removeClass("error");
			$toggle.trigger("reset/requested");
			shared.hide($el);
		});
	}

	function handleHoverRequested(e, el) {
		var $el = $(el);

		$el.addClass(classHover);

		$annotation.parent().stop(true, false).animate({
			"scrollTop": $el.position().top
		}, 300);
	}

	function handleUnhoverRequested(e, el) {
		var $el = $(el);
		$el.removeClass(classHover);
	}

	$annotation
		.on("annotation/requested", "fieldset", handleAnnotationRequested)
		.on("mouseenter", "fieldset", handleMouseenter)
		.on("mouseleave", "fieldset", handleMouseleave)
		.on("hover/requested", handleHoverRequested)
		.on("unhover/requested", handleUnhoverRequested);

	$input.on("input/passed", handleInputPassed);
});<|endoftext|>