<commit_before>/*global document window */
import { parse } from 'babylon';
import * as walk from 'babylon-walk';

import copy from 'copy-to-clipboard';

let container = null;

export const bindConsole = __console => {
  const apply = ['log', 'warn', 'assert', 'debug', 'clear'];

  apply.forEach(method => {
    container.contentWindow.console[method] = (...args) => {
      window.top.console[method].apply(window.top.console, args);
      __console[method].apply(__console, args);
    };
  });
};

export function createContainer() {
  container = document.createElement('iframe');
  container.width = container.height = 1;
  container.style.opacity = 0;
  container.style.border = 0;
  container.style.position = 'absolute';
  container.style.top = '-100px';
  container.setAttribute('name', '<proxy>');
  document.body.appendChild(container);
  setContainer(container);
}

export function setContainer(iframe) {
  container = iframe;
  const win = container.contentWindow;
  const doc = container.contentDocument;

  win.copy = copy;
  win.$$ = s => Array.from(doc.querySelectorAll(s));
  win.$ = s => doc.querySelector(s);
}

export default async function run(command) {
  return new Promise(async resolve => {
    const res = {
      error: false,
      command,
    };

    try {
      // // trick from devtools
      // // via https://chromium.googlesource.com/chromium/src.git/+/4fd348fdb9c0b3842829acdfb2b82c86dacd8e0a%5E%21/#F2
      if (/^\s*\{/.test(command) && /\}\s*$/.test(command)) {
        command = `(${command})`;
      }

      const { content, additionalCode } = preProcess(command);

      // IMPORTANT: because we're going across iframe bridge here, the constructor
      // of the response value is changed to Object, so even if we return an error
      // or a promise, `value instanceof Error` will always be false.
      // This is why across all the code, I actually use the `isa` pattern to get
      // the original constructor from ({}).toString.call(value)

      if (content.startsWith('(async () => ')) {
        res.value = await container.contentWindow.eval(content);
      } else {
        res.value = container.contentWindow.eval(content);
      }

      // if there's no extra code (usually to block out a const), then let's
      // go ahead and store the result in $_
      if (!additionalCode) {
        container.contentWindow.$_ = res.value;
      }

      if (additionalCode !== null) {
        const doc = container.contentDocument;
        const script = doc.createElement('script');
        const blob = new Blob([additionalCode], {
          type: 'application/javascript',
        });
        script.src = URL.createObjectURL(blob);
        container.contentWindow.onerror = (message, file, line, col, error) => {
          res.error = true;
          res.value = error;
          resolve(res);
        };
        script.onload = () => {
          resolve(res);
          container.contentWindow.onerror = () => {};
        };
        doc.documentElement.appendChild(script);
      } else {
        return resolve(res);
      }
    } catch (error) {
      res.error = true;
      res.value = error;
      return resolve(res);
    }
  });
}

function preProcess(content) {
  var wrapped = '(async () => {' + content + '})()';
  var root = parse(wrapped, { ecmaVersion: 8 });
  var body = root.program.body[0].expression.callee.body;

  var changes = [];
  var containsAwait = false;
  var containsReturn = false;

  const visitors = {
    ClassDeclaration(node) {
      if (node.parent === body)
        changes.push({
          text: node.id.name + '=',
          start: node.start,
          end: node.start,
        });
    },
    FunctionDeclaration(node) {
      changes.push({
        text: node.id.name + '=',
        start: node.start,
        end: node.start,
      });
      return node;
    },
    AwaitExpression(node) {
      containsAwait = true;
    },
    ReturnStatement(node) {
      containsReturn = true;
    },
    VariableDeclaration(node) {
      if (node.kind !== 'var' && node.parent !== body) return;
      var onlyOneDeclaration = node.declarations.length === 1;
      changes.push({
        text: onlyOneDeclaration ? 'void' : 'void (',
        start: node.start,
        end: node.start + node.kind.length,
      });
      for (var declaration of node.declarations) {
        if (!declaration.init) {
          changes.push({
            text: '(',
            start: declaration.start,
            end: declaration.start,
          });
          changes.push({
            text: '=undefined)',
            start: declaration.end,
            end: declaration.end,
          });
          continue;
        }
        changes.push({
          text: '(',
          start: declaration.start,
          end: declaration.start,
        });
        changes.push({
          text: ')',
          start: declaration.end,
          end: declaration.end,
        });
      }
      if (!onlyOneDeclaration) {
        var last = node.declarations.peekLast();
        changes.push({ text: ')', start: last.end, end: last.end });
      }
    },
  };

  walk.simple(body, visitors);

  var last = body.body[body.body.length - 1];

  if (last.type === 'ExpressionStatement') {
    changes.push({
      text: 'return window.$_ = (',
      start: last.start,
      end: last.start,
    });
    if (wrapped[last.end - 1] !== ';')
      changes.push({ text: ')', start: last.end, end: last.end });
    else changes.push({ text: ')', start: last.end - 1, end: last.end - 1 });
  }

  let additionalCode = null;

  if (last.type === 'VariableDeclaration' && last.kind === 'const') {
    additionalCode = `const ${last.declarations['0'].id.name} = $_`;

    changes.push({
      text: `const ${last.declarations['0'].id.name} = window.$_`,
      start: last.start,
      end: last.declarations['0'].id.end,
    });
  }

  if (!containsAwait || containsReturn) {
    if (additionalCode) {
      const offset = 14; // length of `(async () => {`
      content =
        content.substr(0, last.declarations['0'].id.end - offset) +
        ' = window.$_' +
        content.substr(last.declarations['0'].id.end - offset);
    }
    return { content, additionalCode };
  }

  while (changes.length) {
    var change = changes.pop();
    wrapped =
      wrapped.substr(0, change.start) +
      change.text +
      wrapped.substr(change.end);
  }

  return { content: wrapped, additionalCode };
}
<commit_msg>fix: console log in embed<commit_after>/*global document window */
import { parse } from 'babylon';
import * as walk from 'babylon-walk';

import copy from 'copy-to-clipboard';

let container = null;

export const bindConsole = __console => {
  const apply = ['log', 'warn', 'assert', 'debug', 'clear'];

  apply.forEach(method => {
    container.contentWindow.console[method] = (...args) => {
      window.console[method].apply(window.console, args);
      __console[method].apply(__console, args);
    };
  });
};

export function createContainer() {
  container = document.createElement('iframe');
  container.width = container.height = 1;
  container.style.opacity = 0;
  container.style.border = 0;
  container.style.position = 'absolute';
  container.style.top = '-100px';
  container.setAttribute('name', '<proxy>');
  document.body.appendChild(container);
  setContainer(container);
}

export function setContainer(iframe) {
  container = iframe;
  const win = container.contentWindow;
  const doc = container.contentDocument;

  win.copy = copy;
  win.$$ = s => Array.from(doc.querySelectorAll(s));
  win.$ = s => doc.querySelector(s);
}

export default async function run(command) {
  return new Promise(async resolve => {
    const res = {
      error: false,
      command,
    };

    try {
      // // trick from devtools
      // // via https://chromium.googlesource.com/chromium/src.git/+/4fd348fdb9c0b3842829acdfb2b82c86dacd8e0a%5E%21/#F2
      if (/^\s*\{/.test(command) && /\}\s*$/.test(command)) {
        command = `(${command})`;
      }

      const { content, additionalCode } = preProcess(command);

      // IMPORTANT: because we're going across iframe bridge here, the constructor
      // of the response value is changed to Object, so even if we return an error
      // or a promise, `value instanceof Error` will always be false.
      // This is why across all the code, I actually use the `isa` pattern to get
      // the original constructor from ({}).toString.call(value)

      if (content.startsWith('(async () => ')) {
        res.value = await container.contentWindow.eval(content);
      } else {
        res.value = container.contentWindow.eval(content);
      }

      // if there's no extra code (usually to block out a const), then let's
      // go ahead and store the result in $_
      if (!additionalCode) {
        container.contentWindow.$_ = res.value;
      }

      if (additionalCode !== null) {
        const doc = container.contentDocument;
        const script = doc.createElement('script');
        const blob = new Blob([additionalCode], {
          type: 'application/javascript',
        });
        script.src = URL.createObjectURL(blob);
        container.contentWindow.onerror = (message, file, line, col, error) => {
          res.error = true;
          res.value = error;
          resolve(res);
        };
        script.onload = () => {
          resolve(res);
          container.contentWindow.onerror = () => {};
        };
        doc.documentElement.appendChild(script);
      } else {
        return resolve(res);
      }
    } catch (error) {
      res.error = true;
      res.value = error;
      return resolve(res);
    }
  });
}

function preProcess(content) {
  var wrapped = '(async () => {' + content + '})()';
  var root = parse(wrapped, { ecmaVersion: 8 });
  var body = root.program.body[0].expression.callee.body;

  var changes = [];
  var containsAwait = false;
  var containsReturn = false;

  const visitors = {
    ClassDeclaration(node) {
      if (node.parent === body)
        changes.push({
          text: node.id.name + '=',
          start: node.start,
          end: node.start,
        });
    },
    FunctionDeclaration(node) {
      changes.push({
        text: node.id.name + '=',
        start: node.start,
        end: node.start,
      });
      return node;
    },
    AwaitExpression(node) {
      containsAwait = true;
    },
    ReturnStatement(node) {
      containsReturn = true;
    },
    VariableDeclaration(node) {
      if (node.kind !== 'var' && node.parent !== body) return;
      var onlyOneDeclaration = node.declarations.length === 1;
      changes.push({
        text: onlyOneDeclaration ? 'void' : 'void (',
        start: node.start,
        end: node.start + node.kind.length,
      });
      for (var declaration of node.declarations) {
        if (!declaration.init) {
          changes.push({
            text: '(',
            start: declaration.start,
            end: declaration.start,
          });
          changes.push({
            text: '=undefined)',
            start: declaration.end,
            end: declaration.end,
          });
          continue;
        }
        changes.push({
          text: '(',
          start: declaration.start,
          end: declaration.start,
        });
        changes.push({
          text: ')',
          start: declaration.end,
          end: declaration.end,
        });
      }
      if (!onlyOneDeclaration) {
        var last = node.declarations.peekLast();
        changes.push({ text: ')', start: last.end, end: last.end });
      }
    },
  };

  walk.simple(body, visitors);

  var last = body.body[body.body.length - 1];

  if (last.type === 'ExpressionStatement') {
    changes.push({
      text: 'return window.$_ = (',
      start: last.start,
      end: last.start,
    });
    if (wrapped[last.end - 1] !== ';')
      changes.push({ text: ')', start: last.end, end: last.end });
    else changes.push({ text: ')', start: last.end - 1, end: last.end - 1 });
  }

  let additionalCode = null;

  if (last.type === 'VariableDeclaration' && last.kind === 'const') {
    additionalCode = `const ${last.declarations['0'].id.name} = $_`;

    changes.push({
      text: `const ${last.declarations['0'].id.name} = window.$_`,
      start: last.start,
      end: last.declarations['0'].id.end,
    });
  }

  if (!containsAwait || containsReturn) {
    if (additionalCode) {
      const offset = 14; // length of `(async () => {`
      content =
        content.substr(0, last.declarations['0'].id.end - offset) +
        ' = window.$_' +
        content.substr(last.declarations['0'].id.end - offset);
    }
    return { content, additionalCode };
  }

  while (changes.length) {
    var change = changes.pop();
    wrapped =
      wrapped.substr(0, change.start) +
      change.text +
      wrapped.substr(change.end);
  }

  return { content: wrapped, additionalCode };
}
<|endoftext|>


<commit_before>module.exports = {
  gutterWidth: 32,

  font: 'Roboto',

  nodeSizes: {
    parent: 120,
    contextAgent: 80,
    default: 40
  },

  colors: {
    black: 'black',
    lightGrey: '#f5f5f5',
    charcoal: '#333333',
    gray: '#999999',
    ashGray: '#cccccc',
    silver: '#e9e9e9',
    brown: '#815b3a',
    cheetoorange: '#f79232',
    tan: '#f1a257',
    lightBrown: '#d39c3f',
    cyan: '#59afe1',
    slate: '#4a6785',
    coolBlue: '#84bbc6',
    limeBreen: '#8eb021',
    midGreen: '#67ab49',
    violet: '#654982',
    mauve: '#ac707a',
    brightPink: '#f15c75',
    rosie: '#f691b2'
  },

  //all of these appropriate as the background for black text
  //http://leaverou.github.io/contrast-ratio/
  lightBackground: [
    '#f5f5f5', //lightGrey
    '#ebf2f9', //pale blue
    '#14892c', //green
    '#f6c342', //yellow
    '#d04437', //red
    '#59afe1', //cyan
    '#d39c3f', //lightBrown
    '#f691b2', //rosie
    '#ac707a' //mauve
  ],

  nodesAndLinks: [
    '#707070', //grey
    '#3572b0', //blue
    // '#14892c', //green
    '#d04437', //red
    '#815b3a', //brown
    '#654982', //violet
  ],

  roleIcons: [
    'star-outline',
    'triangle-outline',
    'circle-outline',
    'square-outline'
  ],

  overlay: {
    darken: 'rgba(0,0,0,0.12)'
  },

  fontSize: {
    button: {
      large: 17,
      medium: 14
    }
  }
}
<commit_msg>add graphSize vars<commit_after>module.exports = {
  gutterWidth: 32,

  font: 'Roboto',

  nodeSizes: {
    parent: 120,
    contextAgent: 80,
    default: 40
  },

  graphSize: {
    width: 700,
    height: 700
  },

  colors: {
    mediumGray: '#707070',
    black: 'black',
    lightGrey: '#f5f5f5',
    charcoal: '#333333',
    gray: '#999999',
    ashGray: '#cccccc',
    silver: '#e9e9e9',
    brown: '#815b3a',
    cheetoorange: '#f79232',
    tan: '#f1a257',
    lightBrown: '#d39c3f',
    cyan: '#59afe1',
    slate: '#4a6785',
    coolBlue: '#84bbc6',
    limeBreen: '#8eb021',
    midGreen: '#67ab49',
    violet: '#654982',
    mauve: '#ac707a',
    brightPink: '#f15c75',
    rosie: '#f691b2'
  },

  //all of these appropriate as the background for black text
  //http://leaverou.github.io/contrast-ratio/
  lightBackground: [
    '#f5f5f5', //lightGrey
    '#ebf2f9', //pale blue
    '#14892c', //green
    '#f6c342', //yellow
    '#d04437', //red
    '#59afe1', //cyan
    '#d39c3f', //lightBrown
    '#f691b2', //rosie
    '#ac707a' //mauve
  ],

  nodesAndLinks: [
    '#707070', //grey
    '#3572b0', //blue
    // '#14892c', //green
    '#d04437', //red
    '#815b3a', //brown
    '#654982', //violet
  ],

  roleIcons: [
    'star-outline',
    'triangle-outline',
    'circle-outline',
    'square-outline'
  ],

  overlay: {
    darken: 'rgba(0,0,0,0.12)'
  },

  fontSize: {
    button: {
      large: 17,
      medium: 14
    }
  }
}
<|endoftext|>


<commit_before>if("undefined"==typeof OGX)var OGX=function(){};OGX.prototype.Roulette=function(t){"use strict";function e(t){t?c.on("mousedown",function(t){console.log("down"),t.preventDefault(),t.stopImmediatePropagation(),_=(new Date).getTime(),h=t.pageY,v=t.pageY,o(!0),e(!1),n(!0),a(!0)}):c.off("mousedown")}function o(t){if(t){var i,r,s,u,p;$(document).on("mouseup",function(t){console.log("up"),a(!1),n(!1),o(!1),e(!0),t.preventDefault(),t.stopImmediatePropagation(),x=(new Date).getTime(),m=t.pageY,i=Math.abs(m-h),i>g?i=g:null,w=m>h?1:-1,r=i/(x-_)*O.force_coef,s=l(f),console.log("trans",s),p=Math.round(s/g)*w,i=p*g-s*w,u=Math.round(r*O.time_coef*100)/100,console.log("on tile",p,"dist",i,"trans",s,"time",u,"force",r),f.css({transition:"all 0.2s ease-out",transform:"translate3D(0px, "+(s+i*w)+"px, 0px)"})})}else $(document).off("mouseup")}function n(t){if(t){var e,o;$(document).on("mousemove",function(t){console.log("move"),t.preventDefault(),t.stopImmediatePropagation(),o=t.pageY>v?1:-1,o!==w?(e=0,v=t.pageY):(e=t.pageY-v,v=t.pageY),w=o,f.css({transition:"none",transform:"translate3D(0px, "+(l(f)+e)+"px, 0px)"})})}else $(document).off("mousemove")}function a(t){t?D=setInterval(i,10):clearInterval(D)}function i(){var t,e,o;t=Math.floor((f.position().top+g*w)/(g*O.data.length)*-1),t!==I&&(0===f.children('.ogx_roulette_stripe[data-id="'+t+'"]').length&&(e=Y.clone(),e.css("top",t*(g*O.data.length)+"px"),e.attr("data-id",t),f.append(e)),f.children(".ogx_roulette_stripe").each(function(t,e){if(o=f.position().top+$(e).position().top,Math.ceil(o+g*O.data.length)<-g||o>g)return void $(e).remove()}),I=t)}function r(){for(var t='
',e=0;e<2;e++){t+='
';for(var o=0;o<O.data.length;o++)t+='
'+O.data[o].label+"
";t+="
"}t+="
",c.html(t),f=c.children(".ogx_roulette_stripes:first"),y=f.children(".ogx_roulette_stripe:first"),Y=f.children(".ogx_roulette_stripe:last"),Y=Y.detach();var n=s(O.value);f.css({transition:"none",transform:"translate3D(0px, "+-n*g+"px, 0px)"})}function s(t){for(var e=0;e<O.data.length;e++)if(O.data[e].value===t)return e}function l(t){var e=0;return"none"!==t.css("transform")&&(e=Number(t.css("transform").split(",")[5].split(")")[0])),e}function u(){for(var t in G)O.hasOwnProperty(t)||(O[t]=G[t]);c=b.el=$(O.container),c.addClass("ogx_roulette"),d=c.width(),g=c.height()}function p(){u(),r(),e(!0)}var c,f,d,g,h,m,v,_,x,w,D,y,Y,b=this,O=t,G={force_coef:10,time_coef:.1,min_force_pitch:2,value:0},I=0;this.el=null,this.val=function(t,e){if("undefined"==typeof e)var e=!0;O.val=t},p()},OGX.Roulette=function(t){"use strict";return new OGX.prototype.Roulette(t)};<commit_msg>Added destroy method<commit_after>if("undefined"==typeof OGX)var OGX=function(){};OGX.prototype.Roulette=function(t){"use strict";function e(t){t?p.on("mousedown",function(t){console.log("down"),t.preventDefault(),t.stopImmediatePropagation(),_=(new Date).getTime(),h=t.pageY,v=t.pageY,o(!0),e(!1),n(!0),a(!0)}):p.off("mousedown")}function o(t){if(t){var i,r,s,u,c;$(document).on("mouseup",function(t){console.log("up"),a(!1),n(!1),o(!1),e(!0),t.preventDefault(),t.stopImmediatePropagation(),x=(new Date).getTime(),m=t.pageY,i=Math.abs(m-h),i>g?i=g:null,w=m>h?1:-1,r=i/(x-_)*O.force_coef,s=l(f),console.log("trans",s),c=Math.round(s/g)*w,i=c*g-s*w,u=Math.round(r*O.time_coef*100)/100,console.log("on tile",c,"dist",i,"trans",s,"time",u,"force",r),f.css({transition:"all 0.2s ease-out",transform:"translate3D(0px, "+(s+i*w)+"px, 0px)"})})}else $(document).off("mouseup")}function n(t){if(t){var e,o;$(document).on("mousemove",function(t){console.log("move"),t.preventDefault(),t.stopImmediatePropagation(),o=t.pageY>v?1:-1,o!==w?(e=0,v=t.pageY):(e=t.pageY-v,v=t.pageY),w=o,f.css({transition:"none",transform:"translate3D(0px, "+(l(f)+e)+"px, 0px)"})})}else $(document).off("mousemove")}function a(t){t?y=setInterval(i,10):clearInterval(y)}function i(){var t,e,o;t=Math.floor((f.position().top+g*w)/(g*O.data.length)*-1),t!==I&&(0===f.children('.ogx_roulette_stripe[data-id="'+t+'"]').length&&(e=Y.clone(),e.css("top",t*(g*O.data.length)+"px"),e.attr("data-id",t),f.append(e)),f.children(".ogx_roulette_stripe").each(function(t,e){if(o=f.position().top+$(e).position().top,Math.ceil(o+g*O.data.length)<-g||o>g)return void $(e).remove()}),I=t)}function r(){for(var t='
',e=0;e<2;e++){t+='
';for(var o=0;o<O.data.length;o++)t+='
'+O.data[o].label+"
";t+="
"}t+="
",p.html(t),f=p.children(".ogx_roulette_stripes:first"),D=f.children(".ogx_roulette_stripe:first"),Y=f.children(".ogx_roulette_stripe:last"),Y=Y.detach();var n=s(O.value);f.css({transition:"none",transform:"translate3D(0px, "+-n*g+"px, 0px)"})}function s(t){for(var e=0;e<O.data.length;e++)if(O.data[e].value===t)return e}function l(t){var e=0;return"none"!==t.css("transform")&&(e=Number(t.css("transform").split(",")[5].split(")")[0])),e}function u(){for(var t in G)O.hasOwnProperty(t)||(O[t]=G[t]);p=b.el=$(O.container),p.addClass("ogx_roulette"),d=p.width(),g=p.height()}function c(){u(),r(),e(!0)}var p,f,d,g,h,m,v,_,x,w,y,D,Y,b=this,O=t,G={force_coef:10,time_coef:.1,min_force_pitch:2,value:0},I=0;this.el=null,this.val=function(t,e){if("undefined"==typeof e)var e=!0;O.val=t},this.destroy=function(){o(!1),e(!1),n(!1),a(!1)},c()},OGX.Roulette=function(t){"use strict";return new OGX.prototype.Roulette(t)};<|endoftext|>


<commit_before>/**
 * @module ol/control/ScaleLine
 */
import {getChangeEventType} from '../Object.js';
import {assert} from '../asserts.js';
import Control from '../control/Control.js';
import {CLASS_UNSELECTABLE} from '../css.js';
import {listen} from '../events.js';
import {getPointResolution, METERS_PER_UNIT} from '../proj.js';
import ProjUnits from '../proj/Units.js';

/**
 * @type {string}
 */
const UNITS_PROP = 'units';

/**
 * Units for the scale line. Supported values are `'degrees'`, `'imperial'`,
 * `'nautical'`, `'metric'`, `'us'`.
 * @enum {string}
 */
export const Units = {
  DEGREES: 'degrees',
  IMPERIAL: 'imperial',
  NAUTICAL: 'nautical',
  METRIC: 'metric',
  US: 'us'
};

/**
 * @const
 * @type {Array<number>}
 */
const LEADING_DIGITS = [1, 2, 5];

/**
 * @typedef {Object} Options
 * @property {string} [className='ol-scale-line'] CSS Class name.
 * @property {number} [minWidth=64] Minimum width in pixels.
 * @property {function(import("../MapEvent.js").default)} [render] Function called when the control
 * should be re-rendered. This is called in a `requestAnimationFrame` callback.
 * @property {HTMLElement|string} [target] Specify a target if you want the control
 * to be rendered outside of the map's viewport.
 * @property {Units|string} [units='metric'] Units.
 */

/**
 * @classdesc
 * A control displaying rough y-axis distances, calculated for the center of the
 * viewport. For conformal projections (e.g. EPSG:3857, the default view
 * projection in OpenLayers), the scale is valid for all directions.
 * No scale line will be shown when the y-axis distance of a pixel at the
 * viewport center cannot be calculated in the view projection.
 * By default the scale line will show in the bottom left portion of the map,
 * but this can be changed by using the css selector `.ol-scale-line`.
 *
 * @api
 */
class ScaleLine extends Control {

  /**
   * @param {Options=} opt_options Scale line options.
   */
  constructor(opt_options) {

    const options = opt_options ? opt_options : {};

    const className = options.className !== undefined ? options.className : 'ol-scale-line';

    super({
      element: document.createElement('div'),
      render: options.render || render,
      target: options.target
    });

    /**
     * @private
     * @type {HTMLElement}
     */
    this.innerElement_ = document.createElement('div');
    this.innerElement_.className = className + '-inner';

    this.element.className = className + ' ' + CLASS_UNSELECTABLE;
    this.element.appendChild(this.innerElement_);

    /**
     * @private
     * @type {?import("../View.js").State}
     */
    this.viewState_ = null;

    /**
     * @private
     * @type {number}
     */
    this.minWidth_ = options.minWidth !== undefined ? options.minWidth : 64;

    /**
     * @private
     * @type {boolean}
     */
    this.renderedVisible_ = false;

    /**
     * @private
     * @type {number|undefined}
     */
    this.renderedWidth_ = undefined;

    /**
     * @private
     * @type {string}
     */
    this.renderedHTML_ = '';

    listen(
      this, getChangeEventType(UNITS_PROP),
      this.handleUnitsChanged_, this);

    this.setUnits(/** @type {Units} */ (options.units) ||
        Units.METRIC);

  }

  /**
   * Return the units to use in the scale line.
   * @return {Units|undefined} The units
   * to use in the scale line.
   * @observable
   * @api
   */
  getUnits() {
    return (
      /** @type {Units|undefined} */ (this.get(UNITS_PROP))
    );
  }

  /**
   * @private
   */
  handleUnitsChanged_() {
    this.updateElement_();
  }

  /**
   * Set the units to use in the scale line.
   * @param {Units} units The units to use in the scale line.
   * @observable
   * @api
   */
  setUnits(units) {
    this.set(UNITS_PROP, units);
  }

  /**
   * @private
   */
  updateElement_() {
    const viewState = this.viewState_;

    if (!viewState) {
      if (this.renderedVisible_) {
        this.element.style.display = 'none';
        this.renderedVisible_ = false;
      }
      return;
    }

    const center = viewState.center;
    const projection = viewState.projection;
    const units = this.getUnits();
    const pointResolutionUnits = units == Units.DEGREES ?
      ProjUnits.DEGREES :
      ProjUnits.METERS;
    let pointResolution =
        getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
    if (projection.getUnits() != ProjUnits.DEGREES && projection.getMetersPerUnit()
      && pointResolutionUnits == ProjUnits.METERS) {
      pointResolution *= projection.getMetersPerUnit();
    }

    let nominalCount = this.minWidth_ * pointResolution;
    let suffix = '';
    if (units == Units.DEGREES) {
      const metersPerDegree = METERS_PER_UNIT[ProjUnits.DEGREES];
      if (projection.getUnits() == ProjUnits.DEGREES) {
        nominalCount *= metersPerDegree;
      } else {
        pointResolution /= metersPerDegree;
      }
      if (nominalCount < metersPerDegree / 60) {
        suffix = '\u2033'; // seconds
        pointResolution *= 3600;
      } else if (nominalCount < metersPerDegree) {
        suffix = '\u2032'; // minutes
        pointResolution *= 60;
      } else {
        suffix = '\u00b0'; // degrees
      }
    } else if (units == Units.IMPERIAL) {
      if (nominalCount < 0.9144) {
        suffix = 'in';
        pointResolution /= 0.0254;
      } else if (nominalCount < 1609.344) {
        suffix = 'ft';
        pointResolution /= 0.3048;
      } else {
        suffix = 'mi';
        pointResolution /= 1609.344;
      }
    } else if (units == Units.NAUTICAL) {
      pointResolution /= 1852;
      suffix = 'nm';
    } else if (units == Units.METRIC) {
      if (nominalCount < 0.001) {
        suffix = 'μm';
        pointResolution *= 1000000;
      } else if (nominalCount < 1) {
        suffix = 'mm';
        pointResolution *= 1000;
      } else if (nominalCount < 1000) {
        suffix = 'm';
      } else {
        suffix = 'km';
        pointResolution /= 1000;
      }
    } else if (units == Units.US) {
      if (nominalCount < 0.9144) {
        suffix = 'in';
        pointResolution *= 39.37;
      } else if (nominalCount < 1609.344) {
        suffix = 'ft';
        pointResolution /= 0.30480061;
      } else {
        suffix = 'mi';
        pointResolution /= 1609.3472;
      }
    } else {
      assert(false, 33); // Invalid units
    }

    let i = 3 * Math.floor(
      Math.log(this.minWidth_ * pointResolution) / Math.log(10));
    let count, width;
    while (true) {
      count = LEADING_DIGITS[((i % 3) + 3) % 3] *
          Math.pow(10, Math.floor(i / 3));
      width = Math.round(count / pointResolution);
      if (isNaN(width)) {
        this.element.style.display = 'none';
        this.renderedVisible_ = false;
        return;
      } else if (width >= this.minWidth_) {
        break;
      }
      ++i;
    }

    const html = count + ' ' + suffix;
    if (this.renderedHTML_ != html) {
      this.innerElement_.innerHTML = html;
      this.renderedHTML_ = html;
    }

    if (this.renderedWidth_ != width) {
      this.innerElement_.style.width = width + 'px';
      this.renderedWidth_ = width;
    }

    if (!this.renderedVisible_) {
      this.element.style.display = '';
      this.renderedVisible_ = true;
    }

  }
}

/**
 * Update the scale line element.
 * @param {import("../MapEvent.js").default} mapEvent Map event.
 * @this {ScaleLine}
 * @api
 */
export function render(mapEvent) {
  const frameState = mapEvent.frameState;
  if (!frameState) {
    this.viewState_ = null;
  } else {
    this.viewState_ = frameState.viewState;
  }
  this.updateElement_();
}

export default ScaleLine;
<commit_msg>Change ol/control/ScaleLine getUnits return type<commit_after>/**
 * @module ol/control/ScaleLine
 */
import {getChangeEventType} from '../Object.js';
import {assert} from '../asserts.js';
import Control from '../control/Control.js';
import {CLASS_UNSELECTABLE} from '../css.js';
import {listen} from '../events.js';
import {getPointResolution, METERS_PER_UNIT} from '../proj.js';
import ProjUnits from '../proj/Units.js';

/**
 * @type {string}
 */
const UNITS_PROP = 'units';

/**
 * Units for the scale line. Supported values are `'degrees'`, `'imperial'`,
 * `'nautical'`, `'metric'`, `'us'`.
 * @enum {string}
 */
export const Units = {
  DEGREES: 'degrees',
  IMPERIAL: 'imperial',
  NAUTICAL: 'nautical',
  METRIC: 'metric',
  US: 'us'
};

/**
 * @const
 * @type {Array<number>}
 */
const LEADING_DIGITS = [1, 2, 5];

/**
 * @typedef {Object} Options
 * @property {string} [className='ol-scale-line'] CSS Class name.
 * @property {number} [minWidth=64] Minimum width in pixels.
 * @property {function(import("../MapEvent.js").default)} [render] Function called when the control
 * should be re-rendered. This is called in a `requestAnimationFrame` callback.
 * @property {HTMLElement|string} [target] Specify a target if you want the control
 * to be rendered outside of the map's viewport.
 * @property {Units|string} [units='metric'] Units.
 */

/**
 * @classdesc
 * A control displaying rough y-axis distances, calculated for the center of the
 * viewport. For conformal projections (e.g. EPSG:3857, the default view
 * projection in OpenLayers), the scale is valid for all directions.
 * No scale line will be shown when the y-axis distance of a pixel at the
 * viewport center cannot be calculated in the view projection.
 * By default the scale line will show in the bottom left portion of the map,
 * but this can be changed by using the css selector `.ol-scale-line`.
 *
 * @api
 */
class ScaleLine extends Control {

  /**
   * @param {Options=} opt_options Scale line options.
   */
  constructor(opt_options) {

    const options = opt_options ? opt_options : {};

    const className = options.className !== undefined ? options.className : 'ol-scale-line';

    super({
      element: document.createElement('div'),
      render: options.render || render,
      target: options.target
    });

    /**
     * @private
     * @type {HTMLElement}
     */
    this.innerElement_ = document.createElement('div');
    this.innerElement_.className = className + '-inner';

    this.element.className = className + ' ' + CLASS_UNSELECTABLE;
    this.element.appendChild(this.innerElement_);

    /**
     * @private
     * @type {?import("../View.js").State}
     */
    this.viewState_ = null;

    /**
     * @private
     * @type {number}
     */
    this.minWidth_ = options.minWidth !== undefined ? options.minWidth : 64;

    /**
     * @private
     * @type {boolean}
     */
    this.renderedVisible_ = false;

    /**
     * @private
     * @type {number|undefined}
     */
    this.renderedWidth_ = undefined;

    /**
     * @private
     * @type {string}
     */
    this.renderedHTML_ = '';

    listen(
      this, getChangeEventType(UNITS_PROP),
      this.handleUnitsChanged_, this);

    this.setUnits(/** @type {Units} */ (options.units) || Units.METRIC);

  }

  /**
   * Return the units to use in the scale line.
   * @return {Units} The units
   * to use in the scale line.
   * @observable
   * @api
   */
  getUnits() {
    return this.get(UNITS_PROP);
  }

  /**
   * @private
   */
  handleUnitsChanged_() {
    this.updateElement_();
  }

  /**
   * Set the units to use in the scale line.
   * @param {Units} units The units to use in the scale line.
   * @observable
   * @api
   */
  setUnits(units) {
    this.set(UNITS_PROP, units);
  }

  /**
   * @private
   */
  updateElement_() {
    const viewState = this.viewState_;

    if (!viewState) {
      if (this.renderedVisible_) {
        this.element.style.display = 'none';
        this.renderedVisible_ = false;
      }
      return;
    }

    const center = viewState.center;
    const projection = viewState.projection;
    const units = this.getUnits();
    const pointResolutionUnits = units == Units.DEGREES ?
      ProjUnits.DEGREES :
      ProjUnits.METERS;
    let pointResolution =
        getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
    if (projection.getUnits() != ProjUnits.DEGREES && projection.getMetersPerUnit()
      && pointResolutionUnits == ProjUnits.METERS) {
      pointResolution *= projection.getMetersPerUnit();
    }

    let nominalCount = this.minWidth_ * pointResolution;
    let suffix = '';
    if (units == Units.DEGREES) {
      const metersPerDegree = METERS_PER_UNIT[ProjUnits.DEGREES];
      if (projection.getUnits() == ProjUnits.DEGREES) {
        nominalCount *= metersPerDegree;
      } else {
        pointResolution /= metersPerDegree;
      }
      if (nominalCount < metersPerDegree / 60) {
        suffix = '\u2033'; // seconds
        pointResolution *= 3600;
      } else if (nominalCount < metersPerDegree) {
        suffix = '\u2032'; // minutes
        pointResolution *= 60;
      } else {
        suffix = '\u00b0'; // degrees
      }
    } else if (units == Units.IMPERIAL) {
      if (nominalCount < 0.9144) {
        suffix = 'in';
        pointResolution /= 0.0254;
      } else if (nominalCount < 1609.344) {
        suffix = 'ft';
        pointResolution /= 0.3048;
      } else {
        suffix = 'mi';
        pointResolution /= 1609.344;
      }
    } else if (units == Units.NAUTICAL) {
      pointResolution /= 1852;
      suffix = 'nm';
    } else if (units == Units.METRIC) {
      if (nominalCount < 0.001) {
        suffix = 'μm';
        pointResolution *= 1000000;
      } else if (nominalCount < 1) {
        suffix = 'mm';
        pointResolution *= 1000;
      } else if (nominalCount < 1000) {
        suffix = 'm';
      } else {
        suffix = 'km';
        pointResolution /= 1000;
      }
    } else if (units == Units.US) {
      if (nominalCount < 0.9144) {
        suffix = 'in';
        pointResolution *= 39.37;
      } else if (nominalCount < 1609.344) {
        suffix = 'ft';
        pointResolution /= 0.30480061;
      } else {
        suffix = 'mi';
        pointResolution /= 1609.3472;
      }
    } else {
      assert(false, 33); // Invalid units
    }

    let i = 3 * Math.floor(
      Math.log(this.minWidth_ * pointResolution) / Math.log(10));
    let count, width;
    while (true) {
      count = LEADING_DIGITS[((i % 3) + 3) % 3] *
          Math.pow(10, Math.floor(i / 3));
      width = Math.round(count / pointResolution);
      if (isNaN(width)) {
        this.element.style.display = 'none';
        this.renderedVisible_ = false;
        return;
      } else if (width >= this.minWidth_) {
        break;
      }
      ++i;
    }

    const html = count + ' ' + suffix;
    if (this.renderedHTML_ != html) {
      this.innerElement_.innerHTML = html;
      this.renderedHTML_ = html;
    }

    if (this.renderedWidth_ != width) {
      this.innerElement_.style.width = width + 'px';
      this.renderedWidth_ = width;
    }

    if (!this.renderedVisible_) {
      this.element.style.display = '';
      this.renderedVisible_ = true;
    }

  }
}

/**
 * Update the scale line element.
 * @param {import("../MapEvent.js").default} mapEvent Map event.
 * @this {ScaleLine}
 * @api
 */
export function render(mapEvent) {
  const frameState = mapEvent.frameState;
  if (!frameState) {
    this.viewState_ = null;
  } else {
    this.viewState_ = frameState.viewState;
  }
  this.updateElement_();
}

export default ScaleLine;
<|endoftext|>


<commit_before>/* eslint-disable import/prefer-default-export */
/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { View } from 'react-native';
import { SearchBar } from 'react-native-ui-components';

import { MODAL_KEYS, getAllPrograms } from '../utilities';
import { buttonStrings, modalStrings } from '../localization';
import { UIDatabase } from '../database';
import Settings from '../settings/MobileAppSettings';
import { BottomConfirmModal, DataTablePageModal } from '../widgets/modals';
import { PageButton } from '../widgets';
import { DataTable, DataTableHeaderRow, DataTableRow } from '../widgets/DataTable';
import {
  sortData,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  closeBasicModal,
  deleteRequisitions,
  openBasicModal,
} from './dataTableUtilities/actions';
import { getItemLayout, recordKeyExtractor } from './dataTableUtilities/utilities';
import globalStyles, { SUSSOL_ORANGE, newDataTableStyles, newPageStyles } from '../globalStyles';
import usePageReducer from '../hooks/usePageReducer';
import DataTablePageView from './containers/DataTablePageView';

import {
  gotoStocktakeManagePage,
  createStocktake,
  gotoStocktakeEditPage,
} from '../navigation/actions';

const keyExtractor = item => item.id;

export const StocktakesPage = ({ routeName, currentUser, dispatch: reduxDispatch }) => {
  const [state, dispatch, instantDebouncedDispatch, debouncedDispatch] = usePageReducer(routeName, {
    backingData: UIDatabase.objects('Stocktake'),
    data: UIDatabase.objects('Stocktake')
      .sorted('createdDate', false)
      .slice(),
    keyExtractor: recordKeyExtractor,
    dataState: new Map(),
    searchTerm: '',
    filterDataKeys: ['name'],
    sortBy: 'createdDate',
    isAscending: false,
    modalKey: '',
    hasSelection: false,
    currentUser,
    reduxDispatch,
    usingPrograms: getAllPrograms(Settings, UIDatabase).length > 0,
  });

  const {
    data,
    dataState,
    sortBy,
    isAscending,
    columns,
    modalKey,
    hasSelection,
    usingPrograms,
  } = state;

  const { PROGRAM_STOCKTAKE } = MODAL_KEYS;

  const getAction = useCallback((colKey, propName) => {
    switch (colKey) {
      case 'remove':
        if (propName === 'onCheckAction') return selectRow;
        return deselectRow;
      default:
        return null;
    }
  });

  const renderRow = useCallback(
    listItem => {
      const { item, index } = listItem;
      const rowKey = keyExtractor(item);
      const { row, alternateRow } = newDataTableStyles;

      return (
        <DataTableRow
          rowData={data[index]}
          rowState={dataState.get(rowKey)}
          rowKey={rowKey}
          style={index % 2 === 0 ? alternateRow : row}
          columns={columns}
          dispatch={dispatch}
          getAction={getAction}
          onPress={() => reduxDispatch(gotoStocktakeEditPage(item))}
        />
      );
    },
    [data, dataState]
  );

  const newStocktake = () => {
    if (usingPrograms) return dispatch(openBasicModal(PROGRAM_STOCKTAKE));
    return reduxDispatch(gotoStocktakeManagePage({ stocktakeName: '' }));
  };

  const renderButtons = () => {
    const { verticalContainer, topButton } = globalStyles;
    return (
      <View style={verticalContainer}>
        <PageButton
          style={topButton}
          text={buttonStrings.new_stocktake}
          onPress={() => newStocktake()}
        />
      </View>
    );
  };

  const getModalOnSelect = () => {
    switch (modalKey) {
      case PROGRAM_STOCKTAKE:
        return ({ stocktakeName, program }) => {
          reduxDispatch(createStocktake({ program, stocktakeName, currentUser }));
          dispatch(closeBasicModal());
        };
      default:
        return null;
    }
  };

  const renderHeader = () => (
    <DataTableHeaderRow
      columns={columns}
      dispatch={instantDebouncedDispatch}
      sortAction={sortData}
      isAscending={isAscending}
      sortBy={sortBy}
    />
  );

  const {
    newPageTopSectionContainer,
    newPageTopLeftSectionContainer,
    newPageTopRightSectionContainer,
    searchBar,
  } = newPageStyles;
  return (
    <DataTablePageView>
      <View style={newPageTopSectionContainer}>
        <View style={newPageTopLeftSectionContainer}>
          <SearchBar
            onChange={value => debouncedDispatch(filterData(value))}
            style={searchBar}
            color={SUSSOL_ORANGE}
            placeholder=""
          />
        </View>
        <View style={newPageTopRightSectionContainer}>{renderButtons()}</View>
      </View>
      <DataTable
        data={data}
        extraData={dataState}
        renderRow={renderRow}
        renderHeader={renderHeader}
        keyExtractor={keyExtractor}
        getItemLayout={getItemLayout}
      />
      <BottomConfirmModal
        isOpen={hasSelection}
        questionText={modalStrings.remove_these_items}
        onCancel={() => dispatch(deselectAll())}
        onConfirm={() => dispatch(deleteRequisitions())}
        confirmText={modalStrings.remove}
      />
      <DataTablePageModal
        fullScreen={false}
        isOpen={!!modalKey}
        modalKey={modalKey}
        onClose={() => dispatch(closeBasicModal())}
        onSelect={getModalOnSelect()}
        dispatch={dispatch}
      />
    </DataTablePageView>
  );
};

StocktakesPage.propTypes = {
  routeName: PropTypes.string.isRequired,
  dispatch: PropTypes.func.isRequired,
  currentUser: PropTypes.object.isRequired,
};
<commit_msg>Add basic functionality stocktakes page<commit_after>/* eslint-disable import/prefer-default-export */
/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { View } from 'react-native';
import { SearchBar } from 'react-native-ui-components';

import { MODAL_KEYS, getAllPrograms } from '../utilities';
import { buttonStrings, modalStrings } from '../localization';
import { UIDatabase } from '../database';
import Settings from '../settings/MobileAppSettings';
import { BottomConfirmModal, DataTablePageModal } from '../widgets/modals';
import { PageButton } from '../widgets';
import { DataTable, DataTableHeaderRow, DataTableRow } from '../widgets/DataTable';
import {
  sortData,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  closeBasicModal,
  deleteRequisitions,
  openBasicModal,
} from './dataTableUtilities/actions';
import { getItemLayout, recordKeyExtractor } from './dataTableUtilities/utilities';
import globalStyles, { SUSSOL_ORANGE, newDataTableStyles, newPageStyles } from '../globalStyles';
import usePageReducer from '../hooks/usePageReducer';
import DataTablePageView from './containers/DataTablePageView';

import {
  gotoStocktakeManagePage,
  createStocktake,
  gotoStocktakeEditPage,
} from '../navigation/actions';

const keyExtractor = item => item.id;

export const StocktakesPage = ({ routeName, currentUser, dispatch: reduxDispatch }) => {
  const [state, dispatch, instantDebouncedDispatch, debouncedDispatch] = usePageReducer(routeName, {
    backingData: UIDatabase.objects('Stocktake'),
    data: UIDatabase.objects('Stocktake')
      .sorted('createdDate', false)
      .slice(),
    keyExtractor: recordKeyExtractor,
    dataState: new Map(),
    searchTerm: '',
    filterDataKeys: ['name'],
    sortBy: 'createdDate',
    isAscending: false,
    modalKey: '',
    hasSelection: false,
    currentUser,
    reduxDispatch,
    usingPrograms: getAllPrograms(Settings, UIDatabase).length > 0,
  });

  const {
    data,
    dataState,
    sortBy,
    isAscending,
    columns,
    modalKey,
    hasSelection,
    usingPrograms,
  } = state;

  const { PROGRAM_STOCKTAKE } = MODAL_KEYS;

  const getAction = useCallback((colKey, propName) => {
    switch (colKey) {
      case 'remove':
        if (propName === 'onCheckAction') return selectRow;
        return deselectRow;
      default:
        return null;
    }
  });

  const renderRow = useCallback(
    listItem => {
      const { item, index } = listItem;
      const rowKey = keyExtractor(item);
      const { row, alternateRow } = newDataTableStyles;
      return (
        <DataTableRow
          rowData={data[index]}
          rowState={dataState.get(rowKey)}
          rowKey={rowKey}
          style={index % 2 === 0 ? alternateRow : row}
          columns={columns}
          dispatch={dispatch}
          getAction={getAction}
          onPress={() => reduxDispatch(gotoStocktakeEditPage(item))}
        />
      );
    },
    [data, dataState]
  );

  const newStocktake = () => {
    if (usingPrograms) return dispatch(openBasicModal(PROGRAM_STOCKTAKE));
    return reduxDispatch(gotoStocktakeManagePage({ stocktakeName: '' }));
  };

  const renderButtons = () => {
    const { verticalContainer, topButton } = globalStyles;
    return (
      <View style={verticalContainer}>
        <PageButton
          style={topButton}
          text={buttonStrings.new_stocktake}
          onPress={() => newStocktake()}
        />
      </View>
    );
  };

  const getModalOnSelect = () => {
    switch (modalKey) {
      case PROGRAM_STOCKTAKE:
        return ({ stocktakeName, program }) => {
          reduxDispatch(createStocktake({ program, stocktakeName, currentUser }));
          dispatch(closeBasicModal());
        };
      default:
        return null;
    }
  };

  const renderHeader = () => (
    <DataTableHeaderRow
      columns={columns}
      dispatch={instantDebouncedDispatch}
      sortAction={sortData}
      isAscending={isAscending}
      sortBy={sortBy}
    />
  );

  const {
    newPageTopSectionContainer,
    newPageTopLeftSectionContainer,
    newPageTopRightSectionContainer,
    searchBar,
  } = newPageStyles;
  return (
    <DataTablePageView>
      <View style={newPageTopSectionContainer}>
        <View style={newPageTopLeftSectionContainer}>
          <SearchBar
            onChange={value => debouncedDispatch(filterData(value))}
            style={searchBar}
            color={SUSSOL_ORANGE}
            placeholder=""
          />
        </View>
        <View style={newPageTopRightSectionContainer}>{renderButtons()}</View>
      </View>
      <DataTable
        data={data}
        extraData={dataState}
        renderRow={renderRow}
        renderHeader={renderHeader}
        keyExtractor={keyExtractor}
        getItemLayout={getItemLayout}
      />
      <BottomConfirmModal
        isOpen={hasSelection}
        questionText={modalStrings.remove_these_items}
        onCancel={() => dispatch(deselectAll())}
        onConfirm={() => dispatch(deleteRequisitions())}
        confirmText={modalStrings.remove}
      />
      <DataTablePageModal
        fullScreen={false}
        isOpen={!!modalKey}
        modalKey={modalKey}
        onClose={() => dispatch(closeBasicModal())}
        onSelect={getModalOnSelect()}
        dispatch={dispatch}
      />
    </DataTablePageView>
  );
};

StocktakesPage.propTypes = {
  routeName: PropTypes.string.isRequired,
  dispatch: PropTypes.func.isRequired,
  currentUser: PropTypes.object.isRequired,
};
<|endoftext|>


<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2017 Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

/* jshint esversion:6 */

var _ = require('lodash');
var React = require('react');
var cx = require('classnames');

var basicsActions = require('../../logic/actions');
var BasicsUtils = require('../BasicsUtils');

var constants = require('../../logic/constants');

var Selector = React.createClass({
  mixins: [BasicsUtils],
  propTypes: {
    data: React.PropTypes.object,
    selectedSubtotal: React.PropTypes.string.isRequired,
    selectorOptions: React.PropTypes.object.isRequired,
    selectorMetaData: React.PropTypes.object.isRequired,
    updateBasicsSettings: React.PropTypes.func.isRequired,
    sectionId: React.PropTypes.string.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
  },
  render: function() {
    var self = this;

    return (

        {this.renderMessage()}
        {this.renderOptions()}

    );
  },
  renderMessage: function() {
    if (!this.props.selectorMetaData.hasOwnProperty('latestPump')) {
      return;
    }

    var message;
    var type = this.props.selectedSubtotal;
    var {
      latestPump,
      canUpdateSettings,
      patientName,
    } = this.props.selectorMetaData;

    if (canUpdateSettings) {
      switch(type) {
        case constants.SITE_CHANGE_TUBING:
          message = [
            'We are using ',
            this.subAction(latestPump, constants.SITE_CHANGE_TUBING),
            ' to visualize your infusion site changes.'
          ];
          break;
        case constants.SITE_CHANGE_CANNULA:
          message = [
            'We are using ',
            this.subAction(latestPump, constants.SITE_CHANGE_CANNULA),
            ' to visualize your infusion site changes.'
          ];
          break;
        default:
          message = ['Please select how you would like to see infusion site changes:'];
          break;
      }
    }
    else {
      switch(type) {
        case constants.SITE_CHANGE_TUBING:
          message = [
            patientName,
            ' is using ',
            this.subAction(latestPump, constants.SITE_CHANGE_TUBING),
            ' to see infusion site changes.'
          ];
          break;
        case constants.SITE_CHANGE_CANNULA:
          message = [
            patientName,
            ' is using ',
            this.subAction(latestPump, constants.SITE_CHANGE_CANNULA),
            ' to see infusion site changes.'
          ];
          break;
        default:
          message = [
            'Please ask ',
            patientName,
            ' to select how they would like to see infusion site changes.'
          ];
          break;
        }
    }

    var messageClass = cx({
      'SiteChangeSelector-message': true,
      'SiteChangeSelector-message--disabled': (!canUpdateSettings),
      'SiteChangeSelector-message--cannula': (type === constants.SITE_CHANGE_CANNULA),
      'SiteChangeSelector-message--tubing': (type === constants.SITE_CHANGE_TUBING),
    });

    return (

{message}

    );
  },
  renderOptions: function() {
    var self = this;

    if (!self.props.selectorMetaData.hasOwnProperty('canUpdateSettings') || !self.props.selectorMetaData.canUpdateSettings) {
      return;
    }

    var optionRows = self.props.selectorOptions.rows;

    return optionRows.map(function(row, id) {
      var options = row.map(self.renderOption);
      return (

          {options}

      );
    });
  },
  renderOption: function(option) {
    var optionClass = cx({
      'SiteChangeSelector-option': true,
      'SiteChangeSelector-option--cannula': (option.key === constants.SITE_CHANGE_CANNULA),
      'SiteChangeSelector-option--tubing': (option.key === constants.SITE_CHANGE_TUBING),
      'SiteChangeSelector-option--selected': (option.key === this.props.selectedSubtotal),
    });

    var latestPump = 'default';
    if (this.props.selectorMetaData.hasOwnProperty('latestPump')) {
      latestPump = this.props.selectorMetaData.latestPump;
    }

    return (

        <input type="radio" name="site_change_event" value={option.key} onChange={this.handleSelectSubtotal.bind(null, option.key, option.label)} checked={option.key === this.props.selectedSubtotal} />
        {this.subAction(latestPump, option.key)}

    );
  },
  subAction: function(pump, action) {
    var pumpVocabulary = {
      [constants.ANIMAS]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Go Rewind',
        [constants.SITE_CHANGE_TUBING]: 'Go Prime',
        [constants.SITE_CHANGE_CANNULA]: 'Fill Cannula',
      },
      [constants.INSULET]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Change Pod',
        [constants.SITE_CHANGE_TUBING]: 'Activate Pod',
        [constants.SITE_CHANGE_CANNULA]: 'Prime',
      },
      [constants.MEDTRONIC]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Rewind',
        [constants.SITE_CHANGE_TUBING]: 'Prime',
        [constants.SITE_CHANGE_CANNULA]: 'Prime Cannula',
      },
      [constants.TANDEM]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Change Cartridge',
        [constants.SITE_CHANGE_TUBING]: 'Fill Tubing',
        [constants.SITE_CHANGE_CANNULA]: 'Fill Cannula',
      },
      default: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Change Cartridge',
        [constants.SITE_CHANGE_TUBING]: 'Fill Tubing',
        [constants.SITE_CHANGE_CANNULA]: 'Fill Cannula',
      }
    };

    if (pumpVocabulary.hasOwnProperty(pump)) {
      return (
        {pumpVocabulary[pump][action]}
      );
    }

    return (
      {pumpVocabulary.default[action]}
    );
  },
  handleSelectSubtotal: function(selectedSubtotal, optionLabel) {
    basicsActions.setSiteChangeEvent(this.props.sectionId, selectedSubtotal, optionLabel, this.props.trackMetric, this.props.updateBasicsSettings);
  }
});

module.exports = Selector;
<commit_msg>Nitpick<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2017 Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

/* jshint esversion:6 */

var _ = require('lodash');
var React = require('react');
var cx = require('classnames');

var basicsActions = require('../../logic/actions');
var BasicsUtils = require('../BasicsUtils');

var constants = require('../../logic/constants');

var Selector = React.createClass({
  mixins: [BasicsUtils],
  propTypes: {
    data: React.PropTypes.object,
    selectedSubtotal: React.PropTypes.string.isRequired,
    selectorOptions: React.PropTypes.object.isRequired,
    selectorMetaData: React.PropTypes.object.isRequired,
    updateBasicsSettings: React.PropTypes.func.isRequired,
    sectionId: React.PropTypes.string.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
  },
  render: function() {
    var self = this;

    return (

        {this.renderMessage()}
        {this.renderOptions()}

    );
  },
  renderMessage: function() {
    if (!this.props.selectorMetaData.hasOwnProperty('latestPump')) {
      return;
    }

    var message;
    var type = this.props.selectedSubtotal;
    var {
      latestPump,
      canUpdateSettings,
      patientName,
    } = this.props.selectorMetaData;

    if (canUpdateSettings) {
      switch(type) {
        case constants.SITE_CHANGE_TUBING:
          message = [
            'We are using ',
            this.subAction(latestPump, constants.SITE_CHANGE_TUBING),
            ' to visualize your infusion site changes.'
          ];
          break;
        case constants.SITE_CHANGE_CANNULA:
          message = [
            'We are using ',
            this.subAction(latestPump, constants.SITE_CHANGE_CANNULA),
            ' to visualize your infusion site changes.'
          ];
          break;
        default:
          message = ['Please select how you would like to see infusion site changes:'];
          break;
      }
    }
    else {
      switch(type) {
        case constants.SITE_CHANGE_TUBING:
          message = [
            patientName,
            ' is using ',
            this.subAction(latestPump, constants.SITE_CHANGE_TUBING),
            ' to see infusion site changes.'
          ];
          break;
        case constants.SITE_CHANGE_CANNULA:
          message = [
            patientName,
            ' is using ',
            this.subAction(latestPump, constants.SITE_CHANGE_CANNULA),
            ' to see infusion site changes.'
          ];
          break;
        default:
          message = [
            'Please ask ',
            patientName,
            ' to select how they would like to see infusion site changes.'
          ];
          break;
        }
    }

    var messageClass = cx({
      'SiteChangeSelector-message': true,
      'SiteChangeSelector-message--disabled': (!canUpdateSettings),
      'SiteChangeSelector-message--cannula': (type === constants.SITE_CHANGE_CANNULA),
      'SiteChangeSelector-message--tubing': (type === constants.SITE_CHANGE_TUBING),
    });

    return (

{message}

    );
  },
  renderOptions: function() {
    var self = this;

    if (!self.props.selectorMetaData.canUpdateSettings) {
      return;
    }

    var optionRows = self.props.selectorOptions.rows;

    return optionRows.map(function(row, id) {
      var options = row.map(self.renderOption);
      return (

          {options}

      );
    });
  },
  renderOption: function(option) {
    var optionClass = cx({
      'SiteChangeSelector-option': true,
      'SiteChangeSelector-option--cannula': (option.key === constants.SITE_CHANGE_CANNULA),
      'SiteChangeSelector-option--tubing': (option.key === constants.SITE_CHANGE_TUBING),
      'SiteChangeSelector-option--selected': (option.key === this.props.selectedSubtotal),
    });

    var latestPump = 'default';
    if (this.props.selectorMetaData.hasOwnProperty('latestPump')) {
      latestPump = this.props.selectorMetaData.latestPump;
    }

    return (

        <input type="radio" name="site_change_event" value={option.key} onChange={this.handleSelectSubtotal.bind(null, option.key, option.label)} checked={option.key === this.props.selectedSubtotal} />
        {this.subAction(latestPump, option.key)}

    );
  },
  subAction: function(pump, action) {
    var pumpVocabulary = {
      [constants.ANIMAS]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Go Rewind',
        [constants.SITE_CHANGE_TUBING]: 'Go Prime',
        [constants.SITE_CHANGE_CANNULA]: 'Fill Cannula',
      },
      [constants.INSULET]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Change Pod',
        [constants.SITE_CHANGE_TUBING]: 'Activate Pod',
        [constants.SITE_CHANGE_CANNULA]: 'Prime',
      },
      [constants.MEDTRONIC]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Rewind',
        [constants.SITE_CHANGE_TUBING]: 'Prime',
        [constants.SITE_CHANGE_CANNULA]: 'Prime Cannula',
      },
      [constants.TANDEM]: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Change Cartridge',
        [constants.SITE_CHANGE_TUBING]: 'Fill Tubing',
        [constants.SITE_CHANGE_CANNULA]: 'Fill Cannula',
      },
      default: {
        [constants.SITE_CHANGE_RESERVOIR]: 'Change Cartridge',
        [constants.SITE_CHANGE_TUBING]: 'Fill Tubing',
        [constants.SITE_CHANGE_CANNULA]: 'Fill Cannula',
      }
    };

    if (pumpVocabulary.hasOwnProperty(pump)) {
      return (
        {pumpVocabulary[pump][action]}
      );
    }

    return (
      {pumpVocabulary.default[action]}
    );
  },
  handleSelectSubtotal: function(selectedSubtotal, optionLabel) {
    basicsActions.setSiteChangeEvent(this.props.sectionId, selectedSubtotal, optionLabel, this.props.trackMetric, this.props.updateBasicsSettings);
  }
});

module.exports = Selector;
<|endoftext|>


<commit_before><commit_msg>Trimmed version for display<commit_after>describe("Jasmine webOS Version", function () {
  beforeEach(function() {
    jasmine.webos.version = {
      major: 1,
      minor: 2,
      build: 3,
      revision: 4567890
    }
  });

  it("#versionString should return the correct version string", function() {
    expect(jasmine.webos.versionString()).toEqual('Jasmine webOS 1.2.3 v.4567890');
  });
});
<|endoftext|>


<commit_before>define([
    'require',
    '../lib/dist/underscore',
    '../../lib/chosen.jquery',
    '../logging'
], function(require) {
    var log = require('../logging').getLogger('breadcrumbs');

    var init = function($el, opts) {
        // wrap elements in a UL in case none exists
        if (!$el.is(':has(ul)')) {
            $el.children().wrapAll('

').wrap('

');
        }
        var $ul = $el.find('ul');

        // put content into a container that can be shifted around
        var $shift = $('shift')
                .prependTo($el).hide();
    };

    var pattern = {
        markup_trigger: 'nav.breadcrumbs',
        init: init
    };
    return pattern;
});<commit_msg>adjust breadcrumb markup<commit_after>define([
    'require',
    '../lib/dist/underscore',
    '../../lib/chosen.jquery',
    '../logging'
], function(require) {
    var log = require('../logging').getLogger('breadcrumbs');

    var init = function($el, opts) {
        // wrap elements in a DIV
        $el.children().wrapAll('

');

        // put content into a container that can be shifted around
        var $shift = $('shift')
                .prependTo($el).hide();
    };

    var pattern = {
        markup_trigger: 'nav.breadcrumbs',
        init: init
    };
    return pattern;
});<|endoftext|>


<commit_before>/*
 * changes:
 * - open($el, opts) instead of open($el, duration)
 * - same for close
 */
define([
    "jquery",
    "./inject",
    "../logging",
    "../core/parser",
    "../core/store",
    "../registry"
], function($, inject, logging, Parser, store, registry) {
    var log = logging.getLogger("collapsible"),
        parser = new Parser("collapsible");

    parser.add_argument("load-content");
    parser.add_argument("store", "none", ["none", "session", "local"]);
    parser.add_argument("duration", "fast");
    parser.add_argument("easing", "linear");
    parser.add_argument("closed", false);

    var _ = {
        name: "collapsible",
        trigger: ".pat-collapsible",

        init: function($el, opts) {
            return $el.each(function() {
                var $el = $(this),
                    options = _._validateOptions(this, parser.parse($el, opts)),
                // create collapsible structure
                    $trigger = $el.children(':first'),
                    $content = $el.children(':gt(0)'),
                    $panel, state;
                if ($content.length > 0)
                    $panel = $content.wrapAll('
')
                        .parent();
                else
                    $panel = $('
').insertAfter($trigger);

                $el.data("patternCollapsible", options);
                state=(options.closed || $el.hasClass("closed")) ? "closed" : "open";
                if (options.store!=="none") {
                    storage=(options.store==="local" ? store.local : store.session)(_.name);
                    state=storage.get(this.id) || state;
                }

                if (state==="closed") {
                    $el.removeClass("open").addClass("closed");
                    $panel.hide();
                } else {
                    _.loadContent($el);
                    $el.addClass("open");
                    $panel.show();
                }

                $trigger
                    .off(".pat-collapsible")
                    .on("click.pat-collapsible", null, $el, _._onClick);

                return $el;
            });
        },

        _onClick: function(event) {
            _.toggle(event.data);
        },

        destroy: function($el) {
            $el.removeData("patternCollapsible");
            $el.children(":first").off('.pat-collapsible');
        },

        open: function($el) {
            if (!$el.hasClass("open"))
                _.toggle($el);
            return $el;
        },

        close: function($el) {
            if (!$el.hasClass("closed"))
                _.toggle($el);
            return $el;
        },

        _validateOptions: function(trigger, options) {
            if (options.store!=="none") {
                if (!trigger.id) {
                    log.warn("state persistance requested, but element has no id");
                    options.store="none";
                } else if (!store.supported) {
                    log.warn("state persistance requested, but browser does not support webstorage");
                    options.store="none";
                }
            }
            return options;
        },

        loadContent: function($el) {
            var options = $el.data("patternCollapsible");
            if (!options.loadContent)
                return;
            var components = options.loadContent.split('#'),
                url = components[0],
                id = components[1] ? '#' + components[1] : null,
                opts = [{
                    url: url,
                    source: id,
                    $targets: $('.panel-content', $el)
                }];
            inject.execute(opts);
        },

        toggle: function($el) {
            var options = $el.data("patternCollapsible"),
                $panel = $el.find('.panel-content'),
                new_state = $el.hasClass("closed") ? "open" : "closed";

            if (options.store!=="none") {
                var storage=(options.store==="local" ? store.local : store.session)(_.name);
                storage.set($el.attr("id"), new_state);
            }

            if (new_state==="open") {
                $el.trigger('patterns-collapsible-open');
                _._transit($el, $panel, "closed", "open", options);
            } else {
                $el.trigger('patterns-collapsible-close');
                _._transit($el, $panel, "open", "closed", options);
            }

            // allow for chaining
            return $el;
        },

        _transit: function($el, $panel, from_cls, to_cls, options) {
            if (to_cls === "open")
                _.loadContent($el);
            $el.removeClass(from_cls);
            if (options.duration)
                $el.addClass("in-progress");
            $panel.slideToggle(options.duration, options.easing, function() {
                $el
                    .removeClass("in-progress")
                    .addClass(to_cls);
            });
        }
    };

    registry.register(_);
    return _;
});
// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<commit_msg>fix collapsible with inject<commit_after>/*
 * changes:
 * - open($el, opts) instead of open($el, duration)
 * - same for close
 */
define([
    "jquery",
    "./inject",
    "../logging",
    "../core/parser",
    "../core/store",
    "../registry"
], function($, inject, logging, Parser, store, registry) {
    var log = logging.getLogger("collapsible"),
        parser = new Parser("collapsible");

    parser.add_argument("load-content");
    parser.add_argument("store", "none", ["none", "session", "local"]);
    parser.add_argument("duration", "fast");
    parser.add_argument("easing", "linear");
    parser.add_argument("closed", false);

    var _ = {
        name: "collapsible",
        trigger: ".pat-collapsible",

        init: function($el, opts) {
            return $el.each(function() {
                var $el = $(this),
                    options = _._validateOptions(this, parser.parse($el, opts)),
                // create collapsible structure
                    $trigger = $el.children(':first'),
                    $content = $el.children(':gt(0)'),
                    $panel, state;
                if ($content.length > 0)
                    $panel = $content.wrapAll('
')
                        .parent();
                else
                    $panel = $('
').insertAfter($trigger);

                $el.data("patternCollapsible", options);
                state=(options.closed || $el.hasClass("closed")) ? "closed" : "open";
                if (options.store!=="none") {
                    storage=(options.store==="local" ? store.local : store.session)(_.name);
                    state=storage.get(this.id) || state;
                }

                if (state==="closed") {
                    $el.removeClass("open").addClass("closed");
                    $panel.hide();
                } else {
                    _.loadContent($el);
                    $el.addClass("open");
                    $panel.show();
                }

                $trigger
                    .off(".pat-collapsible")
                    .on("click.pat-collapsible", null, $el, _._onClick);

                return $el;
            });
        },

        _onClick: function(event) {
            _.toggle(event.data);
        },

        destroy: function($el) {
            $el.removeData("patternCollapsible");
            $el.children(":first").off('.pat-collapsible');
        },

        open: function($el) {
            if (!$el.hasClass("open"))
                _.toggle($el);
            return $el;
        },

        close: function($el) {
            if (!$el.hasClass("closed"))
                _.toggle($el);
            return $el;
        },

        _validateOptions: function(trigger, options) {
            if (options.store!=="none") {
                if (!trigger.id) {
                    log.warn("state persistance requested, but element has no id");
                    options.store="none";
                } else if (!store.supported) {
                    log.warn("state persistance requested, but browser does not support webstorage");
                    options.store="none";
                }
            }
            return options;
        },

        loadContent: function($el) {
            var options = $el.data("patternCollapsible");
            if (!options.loadContent)
                return;
            var components = options.loadContent.split('#'),
                url = components[0],
                id = components[1] ? '#' + components[1] : null,
                opts = [{
                    url: url,
                    source: id,
                    $target: $('.panel-content', $el)
                }];
            inject.execute(opts);
        },

        toggle: function($el) {
            var options = $el.data("patternCollapsible"),
                $panel = $el.find('.panel-content'),
                new_state = $el.hasClass("closed") ? "open" : "closed";

            if (options.store!=="none") {
                var storage=(options.store==="local" ? store.local : store.session)(_.name);
                storage.set($el.attr("id"), new_state);
            }

            if (new_state==="open") {
                $el.trigger('patterns-collapsible-open');
                _._transit($el, $panel, "closed", "open", options);
            } else {
                $el.trigger('patterns-collapsible-close');
                _._transit($el, $panel, "open", "closed", options);
            }

            // allow for chaining
            return $el;
        },

        _transit: function($el, $panel, from_cls, to_cls, options) {
            if (to_cls === "open")
                _.loadContent($el);
            $el.removeClass(from_cls);
            if (options.duration)
                $el.addClass("in-progress");
            $panel.slideToggle(options.duration, options.easing, function() {
                $el
                    .removeClass("in-progress")
                    .addClass(to_cls);
            });
        }
    };

    registry.register(_);
    return _;
});
// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<|endoftext|>


<commit_before>function FeedbackControl($scope, FeedbackControlService, FeedbackSignal) {

    $scope.selected = [];
    $scope.checkboxes = $("input[type=checkbox][name=feedid]");

    var update_selected = function(action, id) {

        if (action == 'add' && $scope.selected.indexOf(id) == -1) {
            $scope.selected.push(id);
        }

        if (action == 'remove' && $scope.selected.indexOf(id) != -1) {
            $scope.selected.splice($scope.selected.indexOf(id), 1);
        }

    }

    $scope.feedback_status = function(id, feed_status) {
        console.log(feed_status + " id: " + id);

        FeedbackSignal.set_status_message(feed_status)
        FeedbackSignal.set_feed_id(id);

        FeedbackControlService.change_status(id, feed_status);
    }

    $scope.reply_feedback = function(id) {
        console.log("reply id:" + id);
    }

    $scope.update_selection = function($event, feed) {

        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');

        update_selected(action, feed);

        if(checkbox.checked) {
            $(checkbox).parents('.dashboard-feedback').css({'background-color': '#F1F1f1'});
        } else {
            $(checkbox).parents('.dashboard-feedback').css({'background-color': '#FFF'});
        }

    }

    $scope.select_all = function($event) {

        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');

        for(var i=0; i < $scope.checkboxes.length; i++) {
            var entity = $($scope.checkboxes[i]);

            if(action == "add") {
                entity.prop("checked", true);
            } else {
                entity.prop("checked", false);
            }

            update_selected(action, parseInt(entity.val(), 10));
        }
    }

    $scope.is_selected = function(id) {
        return $scope.selected.indexOf(id) >= 0;
    }

    $scope.is_selected_all = function() {
        return $scope.selected.length === $scope.checkboxes.length;
    }
}

function CheckyBox($scope, FeedbackSignal) {

    var status_selection;
    var feed_id;

    $scope.undo = function() {
        console.log("Undo id: " + feed_id);
    }

    $scope.$on('checkFeedbackStatus', function() {
        status_selection = FeedbackSignal.feed_status;
        feed_id = FeedbackSignal.feed_id;
    });
}
<commit_msg>calm down friends<commit_after>function FeedbackControl($scope, FeedbackControlService, FeedbackSignal) {

    $scope.selected = [];
    $scope.checkboxes = $("input[type=checkbox][name=feedid]");

    var update_selected = function(action, id) {

        if (action == 'add' && $scope.selected.indexOf(id) == -1) {
            $scope.selected.push(id);
        }

        if (action == 'remove' && $scope.selected.indexOf(id) != -1) {
            $scope.selected.splice($scope.selected.indexOf(id), 1);
        }

    }

    $scope.feedback_status = function(id, feed_status) {
        console.log(feed_status + " id: " + id);

        FeedbackSignal.set_status_message(feed_status)
        FeedbackSignal.set_feed_id(id);

        FeedbackControlService.change_status(id, feed_status);
    }

    $scope.reply_feedback = function(id) {
        console.log("reply id:" + id);
    }

    $scope.update_selection = function($event, feed) {

        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');

        update_selected(action, feed);

        if(checkbox.checked) {
            $(checkbox).parents('.dashboard-feedback').css({'background-color': '#F1F1f1'});
        } else {
            $(checkbox).parents('.dashboard-feedback').css({'background-color': '#FFF'});
        }

    }

    $scope.select_all = function($event) {

        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');

        for(var i=0; i < $scope.checkboxes.length; i++) {
            var entity = $($scope.checkboxes[i]);

            if(action == "add") {
                entity.prop("checked", true);
            } else {
                entity.prop("checked", false);
            }

            update_selected(action, parseInt(entity.val(), 10));
        }
    }

    $scope.is_selected = function(id) {
        return $scope.selected.indexOf(id) >= 0;
    }

    $scope.is_selected_all = function() {
        return $scope.selected.length === $scope.checkboxes.length;
    }
}

function CheckyBox($scope, FeedbackSignal) {

    $scope.status_selection;
    var feed_id;

    $scope.undo = function() {
        console.log("Undo id: " + feed_id);
    }

    $scope.$on('checkFeedbackStatus', function() {
        $scope.status_selection = FeedbackSignal.feed_status;
        feed_id = FeedbackSignal.feed_id;
    });
}
<|endoftext|>


<commit_before>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var Fx = require('../cartesian/graph_interact');

function createGeoZoomReset(geo, geoLayout) {
    var projection = geo.projection,
        zoom = geo.zoom;

    var zoomReset = function() {
        geo.makeProjection(geoLayout);
        geo.makePath();

        zoom.scale(projection.scale());
        zoom.translate(projection.translate());

        Fx.loneUnhover(geo.hoverContainer);

        geo.render();
    };

    return zoomReset;
}

module.exports = createGeoZoomReset;
<commit_msg>no need to manually clear hover labels on zoom reset<commit_after>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

module.exports = function createGeoZoomReset(geo, geoLayout) {
    var projection = geo.projection,
        zoom = geo.zoom;

    var zoomReset = function() {
        geo.makeProjection(geoLayout);
        geo.makePath();

        zoom.scale(projection.scale());
        zoom.translate(projection.translate());

        geo.render();
    };

    return zoomReset;
};
<|endoftext|>


<commit_before>module.exports = {
  // @オーディオ
  'オーディオ開': { // @オーディオファイルのURLを指定して、オーディオを読み込み、Audioオブジェクトを返す // @おーでぃおひらく
    type: 'func',
    josi: [['を', 'の']],
    pure: true,
    fn: function (url, sys) {
      const a = new Audio()
      a.src = url
      a.addEventListener('timeupdate', (e) => {
        sys.__v0['オーディオ再生位置'] = a.currentTime
      })
      return a
    },
    return_none: false
  },
  'オーディオ再生位置': {type: 'const', value: 0}, // @おーでぃおさいせいいち
  'オーディオ再生': { // @AudioオブジェクトOBJを指定してオーディをを再生 // @おーでぃおさいせい
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ再生する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.currentTime = sys.__v0['オーディオ再生位置']
      obj.play()
    },
    return_none: true
  },
  'オーディオ停止': { // @AudioオブジェクトOBJを指定してオーディを停止 // @おーでぃおていし
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ停止する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.pause()
      sys.__v0['オーディオ再生位置'] = 0 // 暫定
      // オーディオ停止で再生位置が0に戻らない問題(#715)
      setTimeout(() => {
        sys.__v0['オーディオ再生位置'] = 0 // イベント後停止
      }, 10)
    },
    return_none: true
  },
  'オーディオ一時停止': { // @AudioオブジェクトOBJを指定してオーディを一時停止 // @おーでぃおていし
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ停止する前に、オーディオ開くで音声ファイルを読み込んでください')
      sys.__v0['オーディオ再生位置'] = obj.currentTime
      obj.pause()
    },
    return_none: true
  }
}
<commit_msg>オーディオ再生機能の刷新 #1017<commit_after>module.exports = {
  // @オーディオ
  'オーディオ開': { // @オーディオファイルのURLを指定して、オーディオを読み込み、Audioオブジェクトを返す // @おーでぃおひらく
    type: 'func',
    josi: [['を', 'の']],
    pure: true,
    fn: function (url, sys) {
      const a = new Audio()
      a.src = url
      return a
    },
    return_none: false
  },
  'オーディオ再生': { // @AudioオブジェクトOBJを指定してオーディを再生 // @おーでぃおさいせい
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ再生する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.loop = false
      obj.play()
    },
    return_none: true
  },
  'オーディオループ再生': { // @AudioオブジェクトOBJを指定してオーディをループ再生する // @おーでぃおるーぷさいせい
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ再生する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.loop = true
      obj.play()
    },
    return_none: true
  },
  'オーディオ停止': { // @AudioオブジェクトOBJを指定してオーディを停止 // @おーでぃおていし
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ停止する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.pause()
      obj.currentTime = 0 // 暫定
      // オーディオ停止で再生位置が0に戻らない問題(#715)
      setTimeout(() => {
        obj.currentTime = 0 // しっかりと設定
      }, 10)
    },
    return_none: true
  },
  'オーディオ一時停止': { // @AudioオブジェクトOBJを指定してオーディを一時停止 // @おーでぃおいちじていし
    type: 'func',
    josi: [['を']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ一時停止する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.pause()
    },
    return_none: true
  },
  'オーディオ音量取得': { // @AudioオブジェクトOBJの音量を取得して返す // @おーでぃおおんりょうしゅとく
    type: 'func',
    josi: [['の', 'から']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ長取得する前に、オーディオ開くで音声ファイルを読み込んでください')
      return obj.volume
    }
  },
  'オーディオ音量設定': { // @AudioオブジェクトOBJの音量をV(0-1)に設定する // @おーでぃおおんりょうせってい
    type: 'func',
    josi: [['を'],['に','へ']],
    pure: true,
    fn: function (obj, v, sys) {
      if (!obj) throw new Error('オーディオ長取得する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.volume = v
    },
    return_none: true
  },
  'オーディオ長取得': { // @AudioオブジェクトOBJを指定してオーディの長さを取得して返す // @おーでぃおながさしゅとく
    type: 'func',
    josi: [['の', 'から']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ長取得する前に、オーディオ開くで音声ファイルを読み込んでください')
      return obj.duration
    }
  },
  'オーディオ再生位置取得': { // @AudioオブジェクトOBJを指定してオーディの再生位置を取得して返す // @おーでぃおさいせいいちしゅとく
    type: 'func',
    josi: [['の', 'から']],
    pure: true,
    fn: function (obj, sys) {
      if (!obj) throw new Error('オーディオ再生位置取得する前に、オーディオ開くで音声ファイルを読み込んでください')
      return obj.currentTime
    }
  },
  'オーディオ再生位置設定': { // @AudioオブジェクトOBJを指定してオーディの位置を数値Vで設定する // @おーでぃおさいせい
    type: 'func',
    josi: [['を'],['に','へ']],
    pure: true,
    fn: function (obj, v, sys) {
      if (!obj) throw new Error('オーディオ停止する前に、オーディオ開くで音声ファイルを読み込んでください')
      obj.currentTime = v
    },
    return_none: true
  }
}
<|endoftext|>


<commit_before>"use strict";

meta.class("UI.Button", "Entity.Geometry",
{
	init: function() {
		this.picking = true;
	},

	onHoverEnter: function(data) {
		meta.engine.cursor = "pointer";
	},

	onHoverExit: function(data) {
		meta.engine.cursor = "auto";
	},

	onDown: function() {
		this.offset(2, 2);
	},

	onUp: function() {
		this.offset(0, 0);
	},

	set text(str)
	{
		if(!this._text)
		{
			this._text = new Entity.Text(str);
			this._text.size = 12;
			this._text.color = "#ffffff";
			this.attach(this._text);

			this._text.pivot(0.5);
			this._text.anchor(0.5);
			this._text.pickable = false;
		}
		else {
			this._text.setText(str);
		}
	},

	get text()
	{
		if(!this._text) {
			return "";
		}

		return this._text._text;
	},

	//
	_text: null
});<commit_msg>UI.Button this.fofset replaced with this.move<commit_after>"use strict";

meta.class("UI.Button", "Entity.Geometry",
{
	init: function() {
		this.picking = true;
	},

	onHoverEnter: function(data) {
		meta.engine.cursor = "pointer";
	},

	onHoverExit: function(data) {
		meta.engine.cursor = "auto";
	},

	onDown: function() {
		this.move(2, 2);
	},

	onUp: function() {
		this.move(-2, -2);
	},

	set text(str)
	{
		if(!this._text)
		{
			this._text = new Entity.Text(str);
			this._text.size = 12;
			this._text.color = "#ffffff";
			this.attach(this._text);

			this._text.pivot(0.5);
			this._text.anchor(0.5);
			this._text.pickable = false;
		}
		else {
			this._text.setText(str);
		}
	},

	get text()
	{
		if(!this._text) {
			return "";
		}

		return this._text._text;
	},

	//
	_text: null
});<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage } from 'react-intl'
import NonIETransitionGroup from './NonIETransitionGroup'

class Footer extends React.Component {
  constructor (props) {
    super(props)
    this.handleChangeLanguage = this.handleChangeLanguage.bind(this)
  }

  handleChangeLanguage () {
    this.props.loadLanguage(this.props.locale === 'no' ? 'en' : 'no')
  }

  render () {
    return (

        <NonIETransitionGroup
          transitionName="fade-in"
          transitionAppear
          transitionAppearTimeout={500}
          transitionEnterTimeout={500}
          transitionLeaveTimeout={500}
          component="div"
          className="footer-content">

                  <FormattedMessage {...messages.contactUs} />

                  <FormattedMessage {...messages.openingHours} />

<FormattedMessage {...messages.languageChoice} />

                  <FormattedMessage {...messages.aboutUs} />

            <FormattedHTMLMessage {...messages.info} />

                <FormattedMessage {...messages.feedback} />

        </NonIETransitionGroup>

    )
  }
}

Footer.propTypes = {
  loadLanguage: PropTypes.func.isRequired,
  locale: PropTypes.string.isRequired,
  intl: intlShape.isRequired
}

export const messages = defineMessages({
  contactUs: {
    id: 'Footer.contactUs',
    description: 'Label for the contact us link',
    defaultMessage: 'Contact us'
  },
  openingHours: {
    id: 'Footer.openingHours',
    description: 'Label for the opening hours link',
    defaultMessage: 'Opening hours'
  },
  languageChoice: {
    id: 'Footer.languageChoice',
    description: 'Label for the link that changes the language, will be displayed in the language being chosen',
    defaultMessage: 'På norsk'
  },
  currentLanguage: {
    id: 'Footer.currentLanguage',
    description: 'The value of the currently applied language',
    defaultMessage: 'English'
  },
  aboutUs: {
    id: 'Footer.aboutUs',
    description: 'Label for the about us link',
    defaultMessage: 'About us'
  },
  info: {
    id: 'Footer.info',
    description: 'The text containing the address, telephone number and other information',
    defaultMessage: 'Deichmanske bibliotek - Oslo public library
Oslo kommune
Arne Garborgs plass 4, 0179 Oslo, Norway
Telephone: +47 23 43 29 00
Editor: Knut Skansen (acting director)
'
  },
  feedback: {
    id: 'Footer.feedback',
    description: 'Feeback description',
    defaultMessage: 'Give feedback on search or My page'
  }
})

export default injectIntl(Footer)
<commit_msg>The "in English" button is now clickable on sok.deichman<commit_after>import React, { PropTypes } from 'react'
import { injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage } from 'react-intl'
import NonIETransitionGroup from './NonIETransitionGroup'

class Footer extends React.Component {
  constructor (props) {
    super(props)
    this.handleChangeLanguage = this.handleChangeLanguage.bind(this)
  }

  handleChangeLanguage () {
    this.props.loadLanguage(this.props.locale === 'no' ? 'en' : 'no')
  }

  ignore (event) {
    event.prevent.default()
  }

  render () {
    return (

        <NonIETransitionGroup
          transitionName="fade-in"
          transitionAppear
          transitionAppearTimeout={500}
          transitionEnterTimeout={500}
          transitionLeaveTimeout={500}
          component="div"
          className="footer-content">

                  <FormattedMessage {...messages.contactUs} />

                  <FormattedMessage {...messages.openingHours} />

                  <FormattedMessage {...messages.languageChoice} />

                  <FormattedMessage {...messages.aboutUs} />

            <FormattedHTMLMessage {...messages.info} />

                <FormattedMessage {...messages.feedback} />

        </NonIETransitionGroup>

    )
  }
}

Footer.propTypes = {
  loadLanguage: PropTypes.func.isRequired,
  locale: PropTypes.string.isRequired,
  intl: intlShape.isRequired
}

export const messages = defineMessages({
  contactUs: {
    id: 'Footer.contactUs',
    description: 'Label for the contact us link',
    defaultMessage: 'Contact us'
  },
  openingHours: {
    id: 'Footer.openingHours',
    description: 'Label for the opening hours link',
    defaultMessage: 'Opening hours'
  },
  languageChoice: {
    id: 'Footer.languageChoice',
    description: 'Label for the link that changes the language, will be displayed in the language being chosen',
    defaultMessage: 'På norsk'
  },
  currentLanguage: {
    id: 'Footer.currentLanguage',
    description: 'The value of the currently applied language',
    defaultMessage: 'English'
  },
  aboutUs: {
    id: 'Footer.aboutUs',
    description: 'Label for the about us link',
    defaultMessage: 'About us'
  },
  info: {
    id: 'Footer.info',
    description: 'The text containing the address, telephone number and other information',
    defaultMessage: 'Deichmanske bibliotek - Oslo public library
Oslo kommune
Arne Garborgs plass 4, 0179 Oslo, Norway
Telephone: +47 23 43 29 00
Editor: Knut Skansen (acting director)
'
  },
  feedback: {
    id: 'Footer.feedback',
    description: 'Feeback description',
    defaultMessage: 'Give feedback on search or My page'
  }
})

export default injectIntl(Footer)
<|endoftext|>