<commit_before>(function() {
  // ok joe I am moe
  var pageX = 0,
      pageY  = 0,
      noop = function(){};

  document.addEventListener('mousemove', function(e) {
    pageX = e.pageX;
    pageY = e.pageY;
  });

  document.addEventListener('touchmove', function(e) {
    pageX = e.touches[0].pageX;
    pageY = e.touches[0].pageY;
  });

  var vertexShader = 'attribute vec2 pos;void main(){gl_Position=vec4(pos.x,pos.y,0.0,1.00);}',
      header = [
        '#ifdef GL_ES\n',
        'precision highp float;\n',
        '#endif\n',
        'uniform bool mouseDown;\n',
        'uniform bool mouseUp;\n',
        'uniform bool mouseClicked;\n',
        'uniform vec3 resolution;\n',
        'uniform float time;\n',
        'uniform float millis;\n',
        'uniform vec2 mouse;\n',
        'uniform sampler2D tex0;\n'].join('');

  // Some of this code is based off of this pen http://codepen.io/jaburns/pen/hHuLI
  // by Jeremy Burns https://github.com/jaburns

  // seen variations on this basic code floating around a bunch on github and elsewhere
  // may even originally be from http://shadertoy.com

  window.QuickShader = function(params) {

    if (!params.shader){
      console.warn('You must specify a fragment shader');
    }

    this.width = params.width || 400;
    this.height = params.height || 400;
    this.shader = params.shader;

    this.textureCode = '';
    this.texturesIn = params.textures || [];
    this.textures = [];

    this.inputCode = '';
    this.customData = {};
    this.customInputs = params.inputs || [];
    this.updateFunction = noop;

    this.canvas = document.createElement('canvas');
    this.canvas.width = this.width;
    this.canvas.height = this.height;
    this.addCanvasMouseEvents();

    if (params.parentNode) {
      this.parentNode = typeof params.parentNode === 'object' ?
        params.parentNode : document.querySelector(params.parentNode);

      this.parentNode.appendChild(this.canvas);
    }

    this.pauseOffset = 0;
    this.totalPauseTime = 0;

    // create an alias for play mainly because
    // codepen renames any function call to `play()` to
    // `doNotPlay()` not exactly sure why, maybe for audio/video
    // anyway here is an alias for use on codepen
    this.start = this.play;

    this.init();
  };

  QuickShader.prototype = {

    constructor: QuickShader,

    init: function() {
      var gl, vertices, error;

      gl = this.gl = this.ctx = this.canvas.getContext('experimental-webgl');

      vertices = new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ]);

      this.quadVBO = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      this.texturesIn.forEach(this.addTexture.bind(this));

      this.customInputs.forEach(this.addInput.bind(this));

      this.shader = [header, this.textureCode, this.inputCode, this.shader].join('');

      error = this.configureShader();

      if (error) {
        this.destroy();
        if (this.parentNode) {
         var pre = document.createElement('pre');
         pre.innerHTML = error;
         this.parentNode.appendChild(pre);
        }
        return;
      }

      this.size(this.width, this.height);
      this.millis = new Date().getMilliseconds() / 1000;
    },

    addCanvasMouseEvents: function() {
      this.mouseDown = false;
      this.mouseUp = false;
      this.mouseClicked = false;

      this.onClick = this.onClick.bind(this);
      this.onMouseDown = this.onMouseDown.bind(this);
      this.onMouseUp = this.onMouseUp.bind(this);

      this.canvas.addEventListener('click', this.onClick);
      this.canvas.addEventListener('mousedown', this.onMouseDown);
      this.canvas.addEventListener('touchstart', this.onMouseDown);

      document.addEventListener('mouseup', this.onMouseUp);
      document.addEventListener('touchend', this.onMouseUp);
    },

    onClick: function(e) {
      this.mouseClicked = true;
    },

    onMouseDown: function(e) {
      this.mouseDown = true;
    },

    onMouseUp: function(e) {
      this.mouseUp = true;
      this.mouseDown = false;
    },

    destroy: function() {
      this.reset();
      this.canvas.removeEventListener('click', this.onClick);
      this.canvas.removeEventListener('mousedown', this.onMouseDown);
      document.removeEventListener('mouseup', this.onMouseUp);
      if (this.canvas.parentNode) {
        this.canvas.parentNode.removeChild(this.canvas);
      }
    },

    reset: function() {
      this.startTime = null;
      cancelAnimationFrame(this.animationId);
    },

    play: function() {
      if (this.error) return;

      this.totalPauseTime += this.pauseOffset;
      this.paused = false;

      if (this.startTime) { return; }

      this.startTime = +new Date();
      this.run();
    },

    run: function() {
      var time = (+new Date() - this.startTime - this.totalPauseTime) / 1000;
      this.render(time)
      this.animationId = requestAnimationFrame( this.run.bind(this) );
    },

    pause: function() {
      this.paused = true;
      this.pauseTime = +new Date();
    },

    size: function(width, height) {
      this.width = width;
      this.height = height
      this.canvas.width = width;
      this.canvas.height = height;
      this.gl.viewport( 0, 0, this.width, this.height );
    },

    configureShader: function() {
      var gl = this.gl,
          tempProgram = gl.createProgram(),
          vs = gl.createShader(gl.VERTEX_SHADER),
          fs = gl.createShader(gl.FRAGMENT_SHADER),
          infoLog;

      gl.shaderSource(vs, vertexShader);
      gl.shaderSource(fs, this.shader);

      gl.compileShader(vs);
      gl.compileShader(fs);

      if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
        infoLog = gl.getShaderInfoLog(fs);
        gl.deleteProgram( tempProgram );
        this.error = true;
        return 'shader-error: \n' + infoLog;
      }

      gl.attachShader(tempProgram, vs);
      gl.attachShader(tempProgram, fs);

      gl.deleteShader(vs);
      gl.deleteShader(fs);

      gl.linkProgram(tempProgram);

      if (this.shaderProgram) {
        gl.deleteProgram(this.shaderProgram);
      }

      this.shaderProgram = tempProgram;
    },

    update: function(updateFunction) {
      this.updateFunction = updateFunction.bind(this);
    },

    render: function(time) {
      var gl = this.gl,
          inputs = [],
          textureNum = this.textures.length,
          customInputsLength = this.customInputs.length,
          input,
          tex,
          rect;

      time = time || 0;

      if (this.paused){
        this.pauseOffset = +new Date() - this.pauseTime;
        return;
      }

      gl.viewport(0, 0, this.width, this.height);

      gl.useProgram(this.shaderProgram);

      inputs[0] = gl.getAttribLocation(this.shaderProgram,'pos');
      inputs[1] = gl.getUniformLocation(this.shaderProgram,'time');
      inputs[2] = gl.getUniformLocation(this.shaderProgram,'resolution');
      inputs[3] = gl.getUniformLocation(this.shaderProgram,'millis');
      inputs[4] = gl.getUniformLocation(this.shaderProgram, 'mouse');

      inputs[5] = gl.getUniformLocation(this.shaderProgram, 'mouseDown');
      inputs[6] = gl.getUniformLocation(this.shaderProgram, 'mouseUp');
      inputs[7] = gl.getUniformLocation(this.shaderProgram, 'mouseClicked');

      gl.uniform1f(inputs[1], time);
      gl.uniform3f(inputs[2], this.width, this.height, 1.0);
      gl.uniform1f(inputs[3], this.millis);

      for (var i = 0; i < textureNum; i++){
        tex = gl.getUniformLocation(this.shaderProgram, this.textures[i].name);

        gl.uniform1i(tex, i);
        gl.activeTexture(gl['TEXTURE' + i]);
        gl.bindTexture(gl.TEXTURE_2D, this.textures[i].texture);
      }

      this.updateFunction(this.customData);

      for (var i = 0; i < customInputsLength; i++) {
        var customInput = this.customInputs[i];
        input = gl.getUniformLocation(this.shaderProgram, customInput.name);
        if (customInput.type === 'float') {
          gl.uniform1f(input, this.customData[customInput.name]);
        } else if (customInput.type === 'bool' || customInput.type === 'int') {
          gl.uniform1i(input, this.customData[customInput.name]);
        }
      }

      rect = this.canvas.getBoundingClientRect();
      mouseX = pageX - rect.left;
      mouseY = pageY - rect.top;

      gl.uniform2f(inputs[4], mouseX, mouseY);

      gl.uniform1f(inputs[5], +this.mouseDown);
      gl.uniform1f(inputs[6], +this.mouseUp);
      gl.uniform1f(inputs[7], +this.mouseClicked);

      this.mouseUp = false;
      this.mouseClicked = false;

      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.vertexAttribPointer(inputs[0], 2, gl.FLOAT, false, 0, 0);

      gl.enableVertexAttribArray(inputs[0]);

      gl.drawArrays(gl.TRIANGLES, 0, 6);
      gl.disableVertexAttribArray(inputs[0]);
    },

    addInput: function(input) {
      this.inputCode += [ 'uniform ', input.type, ' ', input.name, ';\n' ].join('');
      this.customData[input.name] = input.value;
    },

    addTexture: function(info) {

      var gl = this.gl,
          img = info.src,
          name = info.name,
          texture = gl.createTexture();

      this.textureCode += [ 'uniform sampler2D ', name, ';\n' ].join('');

      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
      gl.generateMipmap(gl.TEXTURE_2D);
      gl.bindTexture(gl.TEXTURE_2D, null);

      this.textures.push({name: name, texture: texture});
    }

  };

})();

<commit_msg>ubuntu works - adding quick comment<commit_after>// QuickShader by Zevan Rosser 2015
(function() {
  var pageX = 0,
      pageY  = 0,
      noop = function(){};

  document.addEventListener('mousemove', function(e) {
    pageX = e.pageX;
    pageY = e.pageY;
  });

  document.addEventListener('touchmove', function(e) {
    pageX = e.touches[0].pageX;
    pageY = e.touches[0].pageY;
  });

  var vertexShader = 'attribute vec2 pos;void main(){gl_Position=vec4(pos.x,pos.y,0.0,1.00);}',
      header = [
        '#ifdef GL_ES\n',
        'precision highp float;\n',
        '#endif\n',
        'uniform bool mouseDown;\n',
        'uniform bool mouseUp;\n',
        'uniform bool mouseClicked;\n',
        'uniform vec3 resolution;\n',
        'uniform float time;\n',
        'uniform float millis;\n',
        'uniform vec2 mouse;\n',
        'uniform sampler2D tex0;\n'].join('');

  // Some of this code is based off of this pen http://codepen.io/jaburns/pen/hHuLI
  // by Jeremy Burns https://github.com/jaburns

  // seen variations on this basic code floating around a bunch on github and elsewhere
  // may even originally be from http://shadertoy.com

  window.QuickShader = function(params) {

    if (!params.shader){
      console.warn('You must specify a fragment shader');
    }

    this.width = params.width || 400;
    this.height = params.height || 400;
    this.shader = params.shader;

    this.textureCode = '';
    this.texturesIn = params.textures || [];
    this.textures = [];

    this.inputCode = '';
    this.customData = {};
    this.customInputs = params.inputs || [];
    this.updateFunction = noop;

    this.canvas = document.createElement('canvas');
    this.canvas.width = this.width;
    this.canvas.height = this.height;
    this.addCanvasMouseEvents();

    if (params.parentNode) {
      this.parentNode = typeof params.parentNode === 'object' ?
        params.parentNode : document.querySelector(params.parentNode);

      this.parentNode.appendChild(this.canvas);
    }

    this.pauseOffset = 0;
    this.totalPauseTime = 0;

    // create an alias for play mainly because
    // codepen renames any function call to `play()` to
    // `doNotPlay()` not exactly sure why, maybe for audio/video
    // anyway here is an alias for use on codepen
    this.start = this.play;

    this.init();
  };

  QuickShader.prototype = {

    constructor: QuickShader,

    init: function() {
      var gl, vertices, error;

      gl = this.gl = this.ctx = this.canvas.getContext('experimental-webgl');

      vertices = new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ]);

      this.quadVBO = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      this.texturesIn.forEach(this.addTexture.bind(this));

      this.customInputs.forEach(this.addInput.bind(this));

      this.shader = [header, this.textureCode, this.inputCode, this.shader].join('');

      error = this.configureShader();

      if (error) {
        this.destroy();
        if (this.parentNode) {
         var pre = document.createElement('pre');
         pre.innerHTML = error;
         this.parentNode.appendChild(pre);
        }
        return;
      }

      this.size(this.width, this.height);
      this.millis = new Date().getMilliseconds() / 1000;
    },

    addCanvasMouseEvents: function() {
      this.mouseDown = false;
      this.mouseUp = false;
      this.mouseClicked = false;

      this.onClick = this.onClick.bind(this);
      this.onMouseDown = this.onMouseDown.bind(this);
      this.onMouseUp = this.onMouseUp.bind(this);

      this.canvas.addEventListener('click', this.onClick);
      this.canvas.addEventListener('mousedown', this.onMouseDown);
      this.canvas.addEventListener('touchstart', this.onMouseDown);

      document.addEventListener('mouseup', this.onMouseUp);
      document.addEventListener('touchend', this.onMouseUp);
    },

    onClick: function(e) {
      this.mouseClicked = true;
    },

    onMouseDown: function(e) {
      this.mouseDown = true;
    },

    onMouseUp: function(e) {
      this.mouseUp = true;
      this.mouseDown = false;
    },

    destroy: function() {
      this.reset();
      this.canvas.removeEventListener('click', this.onClick);
      this.canvas.removeEventListener('mousedown', this.onMouseDown);
      document.removeEventListener('mouseup', this.onMouseUp);
      if (this.canvas.parentNode) {
        this.canvas.parentNode.removeChild(this.canvas);
      }
    },

    reset: function() {
      this.startTime = null;
      cancelAnimationFrame(this.animationId);
    },

    play: function() {
      if (this.error) return;

      this.totalPauseTime += this.pauseOffset;
      this.paused = false;

      if (this.startTime) { return; }

      this.startTime = +new Date();
      this.run();
    },

    run: function() {
      var time = (+new Date() - this.startTime - this.totalPauseTime) / 1000;
      this.render(time)
      this.animationId = requestAnimationFrame( this.run.bind(this) );
    },

    pause: function() {
      this.paused = true;
      this.pauseTime = +new Date();
    },

    size: function(width, height) {
      this.width = width;
      this.height = height
      this.canvas.width = width;
      this.canvas.height = height;
      this.gl.viewport( 0, 0, this.width, this.height );
    },

    configureShader: function() {
      var gl = this.gl,
          tempProgram = gl.createProgram(),
          vs = gl.createShader(gl.VERTEX_SHADER),
          fs = gl.createShader(gl.FRAGMENT_SHADER),
          infoLog;

      gl.shaderSource(vs, vertexShader);
      gl.shaderSource(fs, this.shader);

      gl.compileShader(vs);
      gl.compileShader(fs);

      if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
        infoLog = gl.getShaderInfoLog(fs);
        gl.deleteProgram( tempProgram );
        this.error = true;
        return 'shader-error: \n' + infoLog;
      }

      gl.attachShader(tempProgram, vs);
      gl.attachShader(tempProgram, fs);

      gl.deleteShader(vs);
      gl.deleteShader(fs);

      gl.linkProgram(tempProgram);

      if (this.shaderProgram) {
        gl.deleteProgram(this.shaderProgram);
      }

      this.shaderProgram = tempProgram;
    },

    update: function(updateFunction) {
      this.updateFunction = updateFunction.bind(this);
    },

    render: function(time) {
      var gl = this.gl,
          inputs = [],
          textureNum = this.textures.length,
          customInputsLength = this.customInputs.length,
          input,
          tex,
          rect;

      time = time || 0;

      if (this.paused){
        this.pauseOffset = +new Date() - this.pauseTime;
        return;
      }

      gl.viewport(0, 0, this.width, this.height);

      gl.useProgram(this.shaderProgram);

      inputs[0] = gl.getAttribLocation(this.shaderProgram,'pos');
      inputs[1] = gl.getUniformLocation(this.shaderProgram,'time');
      inputs[2] = gl.getUniformLocation(this.shaderProgram,'resolution');
      inputs[3] = gl.getUniformLocation(this.shaderProgram,'millis');
      inputs[4] = gl.getUniformLocation(this.shaderProgram, 'mouse');

      inputs[5] = gl.getUniformLocation(this.shaderProgram, 'mouseDown');
      inputs[6] = gl.getUniformLocation(this.shaderProgram, 'mouseUp');
      inputs[7] = gl.getUniformLocation(this.shaderProgram, 'mouseClicked');

      gl.uniform1f(inputs[1], time);
      gl.uniform3f(inputs[2], this.width, this.height, 1.0);
      gl.uniform1f(inputs[3], this.millis);

      for (var i = 0; i < textureNum; i++){
        tex = gl.getUniformLocation(this.shaderProgram, this.textures[i].name);

        gl.uniform1i(tex, i);
        gl.activeTexture(gl['TEXTURE' + i]);
        gl.bindTexture(gl.TEXTURE_2D, this.textures[i].texture);
      }

      this.updateFunction(this.customData);

      for (var i = 0; i < customInputsLength; i++) {
        var customInput = this.customInputs[i];
        input = gl.getUniformLocation(this.shaderProgram, customInput.name);
        if (customInput.type === 'float') {
          gl.uniform1f(input, this.customData[customInput.name]);
        } else if (customInput.type === 'bool' || customInput.type === 'int') {
          gl.uniform1i(input, this.customData[customInput.name]);
        }
      }

      rect = this.canvas.getBoundingClientRect();
      mouseX = pageX - rect.left;
      mouseY = pageY - rect.top;

      gl.uniform2f(inputs[4], mouseX, mouseY);

      gl.uniform1f(inputs[5], +this.mouseDown);
      gl.uniform1f(inputs[6], +this.mouseUp);
      gl.uniform1f(inputs[7], +this.mouseClicked);

      this.mouseUp = false;
      this.mouseClicked = false;

      gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVBO);
      gl.vertexAttribPointer(inputs[0], 2, gl.FLOAT, false, 0, 0);

      gl.enableVertexAttribArray(inputs[0]);

      gl.drawArrays(gl.TRIANGLES, 0, 6);
      gl.disableVertexAttribArray(inputs[0]);
    },

    addInput: function(input) {
      this.inputCode += [ 'uniform ', input.type, ' ', input.name, ';\n' ].join('');
      this.customData[input.name] = input.value;
    },

    addTexture: function(info) {

      var gl = this.gl,
          img = info.src,
          name = info.name,
          texture = gl.createTexture();

      this.textureCode += [ 'uniform sampler2D ', name, ';\n' ].join('');

      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
      gl.generateMipmap(gl.TEXTURE_2D);
      gl.bindTexture(gl.TEXTURE_2D, null);

      this.textures.push({name: name, texture: texture});
    }

  };

})();

<|endoftext|>


<commit_before>import Immutable from 'immutable'
import {Actions} from 'appkit-tide'
import uuid from 'node-uuid'

const STORAGE_KEY = 'todos-appkit'
// Actions are a set of methods that handle updates
// to the global state in response to user interaction. You should
// also do tracking and other non state modifying things here
// to reduce the logic written in your views as much as possible.
class TodoActions extends Actions {
  load() {
    const items = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
    const todos = items.reduce((acc, item) => (
      acc.set(item.id, Immutable.fromJS(item))
    ), Immutable.OrderedMap())
    this.mutate('todos', todos)
  }

  setFilter(filter) {
    this.mutate('filter', filter)
  }

  setTodoInputText(text) {
    // `this.mutate` mutates a value in the state at the given path.
    // This will trigger a re-render in the components that are listening
    // to this value.
    this.mutate('todoInputText', text)
  }

  addTodo() {
    const title = this.get('todoInputText')
    if (title) {
      const item = Immutable.fromJS({
        id: uuid.v4(),
        completed: false,
        title: title.trim(),
      })

      // If we are planning to make multiple state changes,
      // it's better to use `this.updateState` so that we don't
      // emit more than one change event.
      this.updateState((state) => (
        state
          .set('todos', state.get('todos').set(item.get('id'), item))
          .set('todoInputText', '')
      ))
      this.storeTodos()
    }
  }

  toggleCompleted(todoKeyPath) {
    this.mutate(todoKeyPath.concat(['completed']), (value) => !value)
    this.storeTodos()
  }

  toggleAllCompleted() {
    const allCompleted = this.get('todos').every((todo) => todo.get('completed'))
    this.mutate(['todos'], (todos) => (
      todos.map((todo) => todo.set('completed', !allCompleted))
    ))
    this.storeTodos()
  }

  clearCompleted() {
    this.mutate(['todos'], (todos) => (
      todos.filter((todo) => !todo.get('completed'))
    ))
    this.storeTodos()
  }

  changeTitle(todoKeyPath, value) {
    this.mutate(todoKeyPath.concat(['title']), value)
    this.storeTodos()
  }

  destroy(todoKeyPath) {
    const index = [...todoKeyPath].pop()
    this.mutate(['todos'], (todos) => todos.delete(index))
    this.storeTodos()
  }

  storeTodos() {
    const jsonTodos = JSON.stringify(this.get('todos').toList().toJS())
    localStorage.setItem(STORAGE_KEY, jsonTodos)
  }
}

export default TodoActions
<commit_msg>Small cleanup using mutate<commit_after>import Immutable from 'immutable'
import {Actions} from 'appkit-tide'
import uuid from 'node-uuid'

const STORAGE_KEY = 'todos-appkit'
// Actions are a set of methods that handle updates
// to the global state in response to user interaction. You should
// also do tracking and other non state modifying things here
// to reduce the logic written in your views as much as possible.
class TodoActions extends Actions {
  load() {
    const items = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
    const todos = items.reduce((acc, item) => (
      acc.set(item.id, Immutable.fromJS(item))
    ), Immutable.OrderedMap())
    this.mutate('todos', todos)
  }

  setFilter(filter) {
    this.mutate('filter', filter)
  }

  setTodoInputText(text) {
    // `this.mutate` mutates a value in the state at the given path.
    // This will trigger a re-render in the components that are listening
    // to this value.
    this.mutate('todoInputText', text)
  }

  addTodo() {
    const title = this.get('todoInputText')
    if (title) {
      const item = Immutable.fromJS({
        id: uuid.v4(),
        completed: false,
        title: title.trim(),
      })

      this.mutate(['todos', item.get('id')], item)
      this.mutate('todoInputText', '')
      this.storeTodos()
    }
  }

  toggleCompleted(todoKeyPath) {
    this.mutate(todoKeyPath.concat(['completed']), (value) => !value)
    this.storeTodos()
  }

  toggleAllCompleted() {
    const allCompleted = this.get('todos').every((todo) => todo.get('completed'))
    this.mutate(['todos'], (todos) => (
      todos.map((todo) => todo.set('completed', !allCompleted))
    ))
    this.storeTodos()
  }

  clearCompleted() {
    this.mutate(['todos'], (todos) => (
      todos.filter((todo) => !todo.get('completed'))
    ))
    this.storeTodos()
  }

  changeTitle(todoKeyPath, value) {
    this.mutate(todoKeyPath.concat(['title']), value)
    this.storeTodos()
  }

  destroy(todoKeyPath) {
    const index = [...todoKeyPath].pop()
    this.mutate(['todos'], (todos) => todos.delete(index))
    this.storeTodos()
  }

  storeTodos() {
    const jsonTodos = JSON.stringify(this.get('todos').toList().toJS())
    localStorage.setItem(STORAGE_KEY, jsonTodos)
  }
}

export default TodoActions
<|endoftext|>


<commit_before>// ==UserScript==
// @name        pwnyFilters
// @namespace   pwnyFilters
// @include     http://*
// @include     https://*
// @exclude     http://stackoverflow.com/
// @version     1
// @description:en Load the pwnyBar settings in any page. https://github.com/webdev23/ponyFilters
// @grant       none
// @icon data:image/png;base64,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
// @description Load the pwnyBar settings in any page. https://github.com/webdev23/ponyFilters
// ==/UserScript==

function gtCk(name){
	var re = new RegExp(name + "=([^;]+)"),
      value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
}
document.addEventListener("DOMContentLoaded", function(event) {
	console.log("ponyFilters loaded!\n")
	document.documentElement.style.cssText = gtCk('ponyWebkits')
	document.documentElement.style.cssText += gtCk('ponyFilters')
})

if (document.getElementById('main')){
	document.getElementById('main').style.backgroundColor="white"
	}
if (document.getElementById('page')){
	document.getElementById('page').style.backgroundColor="white"
	}
if (document.getElementById('container')){
	document.getElementById('container').style.backgroundColor="white"
	}
if (document.body.style.backgroundColor){
	document.body.style.backgroundColor="white"
	}

let bzr = document.body.getElementsByTagName("img");
for (i = 0; i < bzr.length;) {
	var wi = bzr[i].width; var he = bzr[i].height;
	bzr[i].setAttribute("ondrag", "window.open(this.src,'this.src','width="+wi+",height="+he+",resizable=1')"), i++;}
<commit_msg>Keyboards shortcuts and tricks<commit_after>// ==UserScript==
// @name        pwnyFilters
// @namespace   pwnyFilters
// @include     http://*
// @include     https://*
// @exclude     http://stackoverflow.com/
// @version     1.2
// @description:en Load the pwnyBar settings in any page. https://github.com/webdev23/ponyFilters
// @grant       none
// @icon data:image/png;base64,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
// @description Load the pwnyBar settings in any page. https://github.com/webdev23/ponyFilters
// ==/UserScript==
function gtCk(name){
	var re = new RegExp(name + "=([^;]+)"),
      value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
}
document.addEventListener("DOMContentLoaded", function(event) {
	console.log("ponyFilters loaded!\n")
	document.documentElement.style.cssText = gtCk('ponyWebkits')
	document.documentElement.style.cssText += gtCk('ponyFilters')
})

var bzs = document.body.getElementsByTagName("img");
for (var i = 0; i < bzs.length;) {
	var wi = bzs[i].width; var he = bzs[i].height;
	bzs[i].setAttribute("onmouseup", "window.open(this.src,'this.src','width="+wi+",height="+he+",resizable=1')"), i++;}

var pwnyStyle0 = document.createElement("style");
pwnyStyle0.innerHTML += "body,html{overflow-X:hidden;background-color:white;background:white;color:#111111}\
.mw{background-color:white;background:white;color:#111111;margin:0;padding:0}"
document.getElementsByTagName("body")[0].children[0].insertBefore(pwnyStyle0,document.getElementsByTagName("script")[0].children[1])
document.getElementsByTagName("body")[0].appendChild(pwnyStyle0)

// writeCookie
function writeCookie() {
	document.cookie = "ponyFilters="+"-webkit-"+document.documentElement.style.cssText + "; expires=Thu, 18 Dec 2017 12:00:00 UTC; path=/"
	document.cookie = "ponyWebkits=" + document.documentElement.style.cssText + "; expires=Thu, 18 Dec 2017 12:00:00 UTC; path=/"
	}

document.addEventListener('keydown', (event) => {

  const keyName = event.key;
  if (keyName === 'Control') {return}
  if (event.ctrlKey) { var yop =  event.key;console.log(yop)
    if (yop ==","){
			document.documentElement.style.cssText='filter:none;-webkit-filter:none';
			writeCookie();
      window.location.reload(true)}
		if (yop ==";"){
			var hold = document.documentElement.style.cssText,
			    target = document.getElementsByTagName('script')[0],
					inj = document.createElement('script');
			inj.src= 'https://ponyhacks.com/open/cdn/pwnyfilter.js';
			target.appendChild(inj);
			document.documentElement.style.cssText = hold}
		if (yop =="!"){
			writeCookie()}
		if (yop =="1"){
			document.documentElement.style.cssText = 'filter: sepia(7%) invert(7%) saturate(7%) brightness(1) grayscale(27%) hue-rotate(0deg);\
-webkit-filter: sepia(7%) invert(7%) saturate(7%) brightness(1) grayscale(27%) hue-rotate(0deg)'}
		if (yop =="2"){
			document.documentElement.style.cssText = 'filter: sepia(41%) invert(11%) saturate(17%) brightness(1) grayscale(17%) hue-rotate(20deg);\
-webkit-filter: sepia(41%) invert(11%) saturate(17%) brightness(1) grayscale(17%) hue-rotate(20deg)'}
  }
 }, false);

<|endoftext|>


<commit_before>#! /usr/local/bin/node

var program = require('../node_modules/commander');
var prompt = require('../node_modules/prompt');
var fs = require('fs');
var yaml = require('../node_modules/js-yaml');
var lifterConfig = require('./lifterConfig.js');
var lifterPrompts = require('./lifterPrompts.js');
var lifterInit = require('./lifterInit.js')

// CLI Details
program
  .version('0.0.1')
  .usage('lifter - making Docker containers easier since 2014')
  .option('config', 'Builds YAML file based on user\'s desired configuration')
  .option('init', 'Initializes container.');

program
  .command('config')
  .description('Configure your container.')
  .action(function() {
    lifterConfig.picker(lifterPrompts.promptList.username);
  });

program
  .command('init')
  .description('Build your container.')
  .action(function() {
    console.log('Time to build your container.');
    lifterInit.start_b2d();
  });

program
  .command('*')
  .description('Handle odd responses')
  .action(function(env){
    console.log('You must be confused.');

  });

program.parse(process.argv);
<commit_msg>tell user to do lifter config if they type in lifter only<commit_after>#! /usr/local/bin/node

var program = require('../node_modules/commander');
var prompt = require('../node_modules/prompt');
var fs = require('fs');
var yaml = require('../node_modules/js-yaml');
var lifterConfig = require('./lifterConfig.js');
var lifterPrompts = require('./lifterPrompts.js');
var lifterInit = require('./lifterInit.js')

// CLI Details
program
  .version('0.0.1')
  .usage('lifter - making Docker containers easier since 2014')
  .option('config', 'Builds YAML file based on user\'s desired configuration')
  .option('init', 'Initializes container.');

program
  .command('config')
  .description('Configure your container.')
  .action(function() {
    lifterConfig.picker(lifterPrompts.promptList.username);
  });

program
  .command('init')
  .description('Build your container.')
  .action(function() {
    console.log('Time to build your container.');
    lifterInit.start_b2d();
  });

program
  .command('*')
  .description('Handle odd responses')
  .action(function(env){
    console.log('You must be confused.');

  });

if ( !program.args ){
  console.log('Please enter in "lifter config" to set your container settings');
}

program.parse(process.argv);
<|endoftext|>


<commit_before>import noOp from './utils/noOp';
import rafBatch from './client/rafBatch';
import createNode from './createNode';
import merge from './utils/merge';
import console from './utils/console';
import emptyObj from './utils/emptyObj';
import restrictObjProp from './utils/restrictObjProp';
import { IS_DEBUG } from './utils/debug';
import globalHook from './globalHook';

function mountComponent() {
    this.__isMounted = true;
    this.onMount();
}

function unmountComponent() {
    this.__isMounted = false;
    this.onUnmount();
}

function patchComponent(nextAttrs, nextChildren, nextContext, callReceivers) {
    if(!this.isMounted()) {
        return;
    }

    nextAttrs = this.__buildAttrs(nextAttrs);

    const prevAttrs = this.attrs,
        prevChildren = this.children,
        prevContext = this.context;

    if(callReceivers) {
        const isUpdating = this.__isUpdating;

        this.__isUpdating = true;

        if(IS_DEBUG) {
            this.__isFrozen = false;
        }

        this.attrs = nextAttrs;

        if(IS_DEBUG) {
            this.__isFrozen = true;
        }

        this.onAttrsReceive(prevAttrs);

        if(IS_DEBUG) {
            this.__isFrozen = false;
        }

        this.children = nextChildren;

        if(IS_DEBUG) {
            this.__isFrozen = true;
        }

        this.onChildrenReceive(prevChildren);

        if(IS_DEBUG) {
            this.__isFrozen = false;
        }

        this.context = nextContext;

        if(IS_DEBUG) {
            Object.freeze(this.context);
            this.__isFrozen = true;
        }

        this.onContextReceive(prevContext);

        this.__isUpdating = isUpdating;
    }

    if(this.__isUpdating) {
        return;
    }

    const shouldRerender = this.shouldRerender(prevAttrs, prevChildren, this.__prevState, prevContext);

    if(IS_DEBUG) {
        const shouldRerenderResType = typeof shouldRerender;

        if(shouldRerenderResType !== 'boolean') {
            console.warn(`Component#shouldRerender() should return boolean instead of ${shouldRerenderResType}`);
        }
    }

    if(shouldRerender) {
        const prevRootNode = this.__rootNode;

        this.__rootNode = this.render();
        prevRootNode.patch(this.__rootNode);
        this.onUpdate(prevAttrs, prevChildren, this.__prevState, prevContext);
    }
}

function shouldComponentRerender() {
    return true;
}

function onComponentRender() {
    return null;
}

function renderComponentToDom(parentNs) {
    return this.__rootNode.renderToDom(parentNs);
}

function renderComponentToString() {
    return this.__rootNode.renderToString();
}

function adoptComponentDom(domNode, domIdx) {
    return this.__rootNode.adoptDom(domNode, domIdx);
}

function getComponentDomNode() {
    return this.__rootNode.getDomNode();
}

function requestChildContext() {
    return emptyObj;
}

function setComponentState(state) {
    let nextState;

    if(this.__rootNode === null) { // wasn't inited
        nextState = state === emptyObj? state : merge(this.state, state);
    }
    else {
        this.update(this.state === this.__prevState? updateComponentPrevState : null);
        nextState = merge(this.state, state);
    }

    if(IS_DEBUG) {
        this.__isFrozen = false;
    }

    this.state = nextState;

    if(IS_DEBUG) {
        Object.freeze(this.state);
        this.__isFrozen = true;
    }
}

function updateComponentPrevState() {
    this.__prevState = this.state;
}

function renderComponent() {
    const onRenderRes = this.onRender(),
        rootNode = onRenderRes === null? createNode('!') : onRenderRes;

    if(IS_DEBUG) {
        if(typeof rootNode !== 'object' || Array.isArray(rootNode)) {
            throw TypeError('vidom: Component#onRender must return a single node on the top level or null.');
        }
    }

    const childCtx = this.onChildContextRequest(),
        rootNodeCtx = childCtx === emptyObj?
            this.context :
            this.context === emptyObj?
                childCtx :
                merge(this.context, childCtx);

    if(IS_DEBUG) {
        Object.freeze(rootNodeCtx);
    }

    rootNode.setCtx(rootNodeCtx);

    return rootNode;
}

function updateComponent(cb) {
    if(this.__isUpdating) {
        cb && rafBatch(() => cb.call(this));
    }
    else {
        this.__isUpdating = true;
        rafBatch(() => {
            if(this.isMounted()) {
                this.__isUpdating = false;
                const prevRootNode = this.__rootNode;

                this.patch(this.attrs, this.children, this.context, false);
                cb && cb.call(this);
                if(IS_DEBUG) {
                    globalHook.emit('replace', prevRootNode, this.__rootNode);
                }
            }
        });
    }
}

function getComponentRootNode() {
    return this.__rootNode;
}

function isComponentMounted() {
    return this.__isMounted;
}

function onComponentRefRequest() {
    return this;
}

function buildComponentAttrs(attrs) {
    if(attrs === this.attrs) {
        return attrs;
    }

    const { defaultAttrs } = this.constructor,
        hasDefaultAttrs = defaultAttrs != null,
        res = attrs === emptyObj?
            hasDefaultAttrs? defaultAttrs : attrs :
            hasDefaultAttrs? merge(defaultAttrs, attrs) : attrs;

    if(IS_DEBUG) {
        Object.freeze(res);
    }

    return res;
}

function createComponent(props, staticProps) {
    const res = function(attrs, children, ctx) {
            if(IS_DEBUG) {
                restrictObjProp(this, 'attrs');
                restrictObjProp(this, 'children');
                restrictObjProp(this, 'state');
                restrictObjProp(this, 'context');

                this.__isFrozen = false;
            }

            this.attrs = this.__buildAttrs(attrs);
            this.children = children;
            this.state = emptyObj;
            this.context = ctx;

            if(IS_DEBUG) {
                this.__isFrozen = true;
            }

            this.__isMounted = false;
            this.__isUpdating = false;

            this.__rootNode = null;

            this.onInit();

            this.__prevState = this.state;
            this.__rootNode = this.render();
        },
        ptp = {
            constructor : res,
            onInit : noOp,
            mount : mountComponent,
            unmount : unmountComponent,
            onMount : noOp,
            onUnmount : noOp,
            onAttrsReceive : noOp,
            onChildrenReceive : noOp,
            onContextReceive : noOp,
            shouldRerender : shouldComponentRerender,
            onRender : onComponentRender,
            onUpdate : noOp,
            isMounted : isComponentMounted,
            setState : setComponentState,
            renderToDom : renderComponentToDom,
            renderToString : renderComponentToString,
            adoptDom : adoptComponentDom,
            getDomNode : getComponentDomNode,
            getRootNode : getComponentRootNode,
            render : renderComponent,
            update : updateComponent,
            patch : patchComponent,
            onChildContextRequest : requestChildContext,
            onRefRequest : onComponentRefRequest,
            __buildAttrs : buildComponentAttrs
        };

    for(const i in props) {
        ptp[i] = props[i];
    }

    res.prototype = ptp;

    for(const i in staticProps) {
        res[i] = staticProps[i];
    }

    res['__vidom__component__'] = true;

    return res;
}

export default createComponent;
<commit_msg>Don't call `render()` inside component constructor<commit_after>import noOp from './utils/noOp';
import rafBatch from './client/rafBatch';
import createNode from './createNode';
import merge from './utils/merge';
import console from './utils/console';
import emptyObj from './utils/emptyObj';
import restrictObjProp from './utils/restrictObjProp';
import { IS_DEBUG } from './utils/debug';
import globalHook from './globalHook';

function mountComponent() {
    this.__isMounted = true;
    this.onMount();
}

function unmountComponent() {
    this.__isMounted = false;
    this.onUnmount();
}

function patchComponent(nextAttrs, nextChildren, nextContext, callReceivers) {
    if(!this.isMounted()) {
        return;
    }

    nextAttrs = this.__buildAttrs(nextAttrs);

    const prevAttrs = this.attrs,
        prevChildren = this.children,
        prevContext = this.context;

    if(callReceivers) {
        const isUpdating = this.__isUpdating;

        this.__isUpdating = true;

        if(IS_DEBUG) {
            this.__isFrozen = false;
        }

        this.attrs = nextAttrs;

        if(IS_DEBUG) {
            this.__isFrozen = true;
        }

        this.onAttrsReceive(prevAttrs);

        if(IS_DEBUG) {
            this.__isFrozen = false;
        }

        this.children = nextChildren;

        if(IS_DEBUG) {
            this.__isFrozen = true;
        }

        this.onChildrenReceive(prevChildren);

        if(IS_DEBUG) {
            this.__isFrozen = false;
        }

        this.context = nextContext;

        if(IS_DEBUG) {
            Object.freeze(this.context);
            this.__isFrozen = true;
        }

        this.onContextReceive(prevContext);

        this.__isUpdating = isUpdating;
    }

    if(this.__isUpdating) {
        return;
    }

    const shouldRerender = this.shouldRerender(prevAttrs, prevChildren, this.__prevState, prevContext);

    if(IS_DEBUG) {
        const shouldRerenderResType = typeof shouldRerender;

        if(shouldRerenderResType !== 'boolean') {
            console.warn(`Component#shouldRerender() should return boolean instead of ${shouldRerenderResType}`);
        }
    }

    if(shouldRerender) {
        const prevRootNode = this.getRootNode();

        this.__rootNode = this.render();
        prevRootNode.patch(this.__rootNode);
        this.onUpdate(prevAttrs, prevChildren, this.__prevState, prevContext);
    }
}

function shouldComponentRerender() {
    return true;
}

function onComponentRender() {
    return null;
}

function renderComponentToDom(parentNs) {
    return this.getRootNode().renderToDom(parentNs);
}

function renderComponentToString() {
    return this.getRootNode().renderToString();
}

function adoptComponentDom(domNode, domIdx) {
    return this.getRootNode().adoptDom(domNode, domIdx);
}

function getComponentDomNode() {
    return this.getRootNode().getDomNode();
}

function requestChildContext() {
    return emptyObj;
}

function setComponentState(state) {
    let nextState;

    if(this.__rootNode === null) { // wasn't inited
        nextState = state === emptyObj? state : merge(this.state, state);
    }
    else {
        this.update(this.state === this.__prevState? updateComponentPrevState : null);
        nextState = merge(this.state, state);
    }

    if(IS_DEBUG) {
        this.__isFrozen = false;
    }

    this.state = nextState;

    if(IS_DEBUG) {
        Object.freeze(this.state);
        this.__isFrozen = true;
    }
}

function updateComponentPrevState() {
    this.__prevState = this.state;
}

function renderComponent() {
    const onRenderRes = this.onRender(),
        rootNode = onRenderRes === null? createNode('!') : onRenderRes;

    if(IS_DEBUG) {
        if(typeof rootNode !== 'object' || Array.isArray(rootNode)) {
            throw TypeError('vidom: Component#onRender must return a single node on the top level or null.');
        }
    }

    const childCtx = this.onChildContextRequest(),
        rootNodeCtx = childCtx === emptyObj?
            this.context :
            this.context === emptyObj?
                childCtx :
                merge(this.context, childCtx);

    if(IS_DEBUG) {
        Object.freeze(rootNodeCtx);
    }

    rootNode.setCtx(rootNodeCtx);

    return rootNode;
}

function updateComponent(cb) {
    if(this.__isUpdating) {
        cb && rafBatch(() => cb.call(this));
    }
    else {
        this.__isUpdating = true;
        rafBatch(() => {
            if(this.isMounted()) {
                this.__isUpdating = false;
                const prevRootNode = this.__rootNode;

                this.patch(this.attrs, this.children, this.context, false);
                cb && cb.call(this);
                if(IS_DEBUG) {
                    globalHook.emit('replace', prevRootNode, this.__rootNode);
                }
            }
        });
    }
}

function getComponentRootNode() {
    return this.__rootNode === null?
        this.__rootNode = this.render() :
        this.__rootNode;
}

function isComponentMounted() {
    return this.__isMounted;
}

function onComponentRefRequest() {
    return this;
}

function buildComponentAttrs(attrs) {
    if(attrs === this.attrs) {
        return attrs;
    }

    const { defaultAttrs } = this.constructor,
        hasDefaultAttrs = defaultAttrs != null,
        res = attrs === emptyObj?
            hasDefaultAttrs? defaultAttrs : attrs :
            hasDefaultAttrs? merge(defaultAttrs, attrs) : attrs;

    if(IS_DEBUG) {
        Object.freeze(res);
    }

    return res;
}

function createComponent(props, staticProps) {
    const res = function(attrs, children, ctx) {
            if(IS_DEBUG) {
                restrictObjProp(this, 'attrs');
                restrictObjProp(this, 'children');
                restrictObjProp(this, 'state');
                restrictObjProp(this, 'context');

                this.__isFrozen = false;
            }

            this.attrs = this.__buildAttrs(attrs);
            this.children = children;
            this.state = emptyObj;
            this.context = ctx;

            if(IS_DEBUG) {
                this.__isFrozen = true;
            }

            this.__isMounted = false;
            this.__isUpdating = false;

            this.__rootNode = null;

            this.onInit();

            this.__prevState = this.state;
        },
        ptp = {
            constructor : res,
            onInit : noOp,
            mount : mountComponent,
            unmount : unmountComponent,
            onMount : noOp,
            onUnmount : noOp,
            onAttrsReceive : noOp,
            onChildrenReceive : noOp,
            onContextReceive : noOp,
            shouldRerender : shouldComponentRerender,
            onRender : onComponentRender,
            onUpdate : noOp,
            isMounted : isComponentMounted,
            setState : setComponentState,
            renderToDom : renderComponentToDom,
            renderToString : renderComponentToString,
            adoptDom : adoptComponentDom,
            getDomNode : getComponentDomNode,
            getRootNode : getComponentRootNode,
            render : renderComponent,
            update : updateComponent,
            patch : patchComponent,
            onChildContextRequest : requestChildContext,
            onRefRequest : onComponentRefRequest,
            __buildAttrs : buildComponentAttrs
        };

    for(const i in props) {
        ptp[i] = props[i];
    }

    res.prototype = ptp;

    for(const i in staticProps) {
        res[i] = staticProps[i];
    }

    res['__vidom__component__'] = true;

    return res;
}

export default createComponent;
<|endoftext|>


<commit_before>let listsColors;
Meteor.startup(() => {
  listsColors = Lists.simpleSchema()._schema.color.allowedValues;
});

BlazeComponent.extendComponent({
  canSeeAddCard() {
    const list = Template.currentData();
    return (
      (!list.getWipLimit('enabled') ||
        list.getWipLimit('soft') ||
        !this.reachedWipLimit()) &&
      !Meteor.user().isWorker()
    );
  },

  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },
  starred(check = undefined) {
    const list = Template.currentData();
    const status = list.isStarred();
    if (check === undefined) {
      // just check
      return status;
    } else {
      list.star(!status);
      return !status;
    }
  },
  editTitle(event) {
    event.preventDefault();
    const newTitle = this.childComponents('inlinedForm')[0]
      .getValue()
      .trim();
    const list = this.currentData();
    if (newTitle) {
      list.rename(newTitle.trim());
    }
  },

  isWatching() {
    const list = this.currentData();
    return list.findWatcher(Meteor.userId());
  },

  limitToShowCardsCount() {
    const currentUser = Meteor.user();
    if (currentUser) {
      return Meteor.user().getLimitToShowCardsCount();
    } else {
      return false;
    }
  },

  cardsCount() {
    const list = Template.currentData();
    let swimlaneId = '';
    if (Utils.boardView() === 'board-view-swimlanes')
      swimlaneId = this.parentComponent()
        .parentComponent()
        .data()._id;

    return list.cards(swimlaneId).count();
  },

  reachedWipLimit() {
    const list = Template.currentData();
    return (
      list.getWipLimit('enabled') &&
      list.getWipLimit('value') <= list.cards().count()
    );
  },

  exceededWipLimit() {
    const list = Template.currentData();
    return (
      list.getWipLimit('enabled') &&
      list.getWipLimit('value') < list.cards().count()
    );
  },

  showCardsCountForList(count) {
    const limit = this.limitToShowCardsCount();
    return limit >= 0 && count >= limit;
  },

  events() {
    return [
      {
        'click .js-list-star'(event) {
          event.preventDefault();
          this.starred(!this.starred());
        },
        'click .js-open-list-menu': Popup.open('listAction'),
        'click .js-add-card'(event) {
          const listDom = $(event.target).parents(
            `#js-list-${this.currentData()._id}`,
          )[0];
          const listComponent = BlazeComponent.getComponentForElement(listDom);
          listComponent.openForm({
            position: 'top',
          });
        },
        'click .js-unselect-list'() {
          Session.set('currentList', null);
        },
        submit: this.editTitle,
      },
    ];
  },
}).register('listHeader');

Template.listHeader.helpers({
  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },

  showDesktopDragHandles() {
    currentUser = Meteor.user();
    if (currentUser) {
      return (currentUser.profile || {}).showDesktopDragHandles;
    } else if (window.localStorage.getItem('showDesktopDragHandles')) {
      return true;
    } else {
      return false;
    }
  },
});

Template.listActionPopup.helpers({
  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },

  isWipLimitEnabled() {
    return Template.currentData().getWipLimit('enabled');
  },

  isWatching() {
    return this.findWatcher(Meteor.userId());
  },
});

Template.listActionPopup.events({
  'click .js-list-subscribe'() {},
  'click .js-set-color-list': Popup.open('setListColor'),
  'click .js-select-cards'() {
    const cardIds = this.allCards().map(card => card._id);
    MultiSelection.add(cardIds);
    Popup.close();
  },
  'click .js-toggle-watch-list'() {
    const currentList = this;
    const level = currentList.findWatcher(Meteor.userId()) ? null : 'watching';
    Meteor.call('watch', 'list', currentList._id, level, (err, ret) => {
      if (!err && ret) Popup.close();
    });
  },
  'click .js-close-list'(event) {
    event.preventDefault();
    this.archive();
    Popup.close();
  },
  'click .js-set-wip-limit': Popup.open('setWipLimit'),
  'click .js-more': Popup.open('listMore'),
});

BlazeComponent.extendComponent({
  applyWipLimit() {
    const list = Template.currentData();
    const limit = parseInt(
      Template.instance()
        .$('.wip-limit-value')
        .val(),
      10,
    );

    if (limit < list.cards().count() && !list.getWipLimit('soft')) {
      Template.instance()
        .$('.wip-limit-error')
        .click();
    } else {
      Meteor.call('applyWipLimit', list._id, limit);
      Popup.back();
    }
  },

  enableSoftLimit() {
    const list = Template.currentData();

    if (
      list.getWipLimit('soft') &&
      list.getWipLimit('value') < list.cards().count()
    ) {
      list.setWipLimit(list.cards().count());
    }
    Meteor.call('enableSoftLimit', Template.currentData()._id);
  },

  enableWipLimit() {
    const list = Template.currentData();
    // Prevent user from using previously stored wipLimit.value if it is less than the current number of cards in the list
    if (
      !list.getWipLimit('enabled') &&
      list.getWipLimit('value') < list.cards().count()
    ) {
      list.setWipLimit(list.cards().count());
    }
    Meteor.call('enableWipLimit', list._id);
  },

  isWipLimitSoft() {
    return Template.currentData().getWipLimit('soft');
  },

  isWipLimitEnabled() {
    return Template.currentData().getWipLimit('enabled');
  },

  wipLimitValue() {
    return Template.currentData().getWipLimit('value');
  },

  events() {
    return [
      {
        'click .js-enable-wip-limit': this.enableWipLimit,
        'click .wip-limit-apply': this.applyWipLimit,
        'click .wip-limit-error': Popup.open('wipLimitError'),
        'click .materialCheckBox': this.enableSoftLimit,
      },
    ];
  },
}).register('setWipLimitPopup');

Template.listMorePopup.events({
  'click .js-delete': Popup.afterConfirm('listDelete', function() {
    Popup.close();
    // TODO how can we avoid the fetch call?
    const allCards = this.allCards().fetch();
    const allCardIds = _.pluck(allCards, '_id');
    // it's okay if the linked cards are on the same list
    if (
      Cards.find({
        $and: [
          { listId: { $ne: this._id } },
          { linkedId: { $in: allCardIds } },
        ],
      }).count() === 0
    ) {
      allCardIds.map(_id => Cards.remove(_id));
      Lists.remove(this._id);
    } else {
      // TODO: Figure out more informative message.
      // Popup with a hint that the list cannot be deleted as there are
      // linked cards. We can adapt the query above so we can list the linked
      // cards.
      // Related:
      //   client/components/cards/cardDetails.js about line 969
      //   https://github.com/wekan/wekan/issues/2785
      const message = `${TAPi18n.__(
        'delete-linked-cards-before-this-list',
      )} linkedId: ${
        this._id
      } at client/components/lists/listHeader.js and https://github.com/wekan/wekan/issues/2785`;
      alert(message);
    }
    Utils.goBoardId(this.boardId);
  }),
});

Template.listHeader.helpers({
  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },
});

BlazeComponent.extendComponent({
  onCreated() {
    this.currentList = this.currentData();
    this.currentColor = new ReactiveVar(this.currentList.color);
  },

  colors() {
    return listsColors.map(color => ({ color, name: '' }));
  },

  isSelected(color) {
    if (this.currentColor.get() === null) {
      return color === 'white';
    } else {
      return this.currentColor.get() === color;
    }
  },

  events() {
    return [
      {
        'click .js-palette-color'() {
          this.currentColor.set(this.currentData().color);
        },
        'click .js-submit'() {
          this.currentList.setColor(this.currentColor.get());
          Popup.close();
        },
        'click .js-remove-color'() {
          this.currentList.setColor(null);
          Popup.close();
        },
      },
    ];
  },
}).register('setListColorPopup');
<commit_msg>Includes JS file to previous commit<commit_after>let listsColors;
Meteor.startup(() => {
  listsColors = Lists.simpleSchema()._schema.color.allowedValues;
});

BlazeComponent.extendComponent({
  canSeeAddCard() {
    const list = Template.currentData();
    return (
      (!list.getWipLimit('enabled') ||
        list.getWipLimit('soft') ||
        !this.reachedWipLimit()) &&
      !Meteor.user().isWorker()
    );
  },

  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },
  starred(check = undefined) {
    const list = Template.currentData();
    const status = list.isStarred();
    if (check === undefined) {
      // just check
      return status;
    } else {
      list.star(!status);
      return !status;
    }
  },
  editTitle(event) {
    event.preventDefault();
    const newTitle = this.childComponents('inlinedForm')[0]
      .getValue()
      .trim();
    const list = this.currentData();
    if (newTitle) {
      list.rename(newTitle.trim());
    }
  },

  isWatching() {
    const list = this.currentData();
    return list.findWatcher(Meteor.userId());
  },

  limitToShowCardsCount() {
    const currentUser = Meteor.user();
    if (currentUser) {
      return Meteor.user().getLimitToShowCardsCount();
    } else {
      return false;
    }
  },

  cardsCount() {
    const list = Template.currentData();
    let swimlaneId = '';
    if (Utils.boardView() === 'board-view-swimlanes')
      swimlaneId = this.parentComponent()
        .parentComponent()
        .data()._id;

    return list.cards(swimlaneId).count();
  },

  reachedWipLimit() {
    const list = Template.currentData();
    return (
      list.getWipLimit('enabled') &&
      list.getWipLimit('value') <= list.cards().count()
    );
  },

  exceededWipLimit() {
    const list = Template.currentData();
    return (
      list.getWipLimit('enabled') &&
      list.getWipLimit('value') < list.cards().count()
    );
  },

  showCardsCountForList(count) {
    const limit = this.limitToShowCardsCount();
    return limit >= 0 && count >= limit;
  },

  cardsCountForListIsOne(count) {
    if (count === 1) {
      return TAPi18n.__('cards-count-one');
    } else {
      return TAPi18n.__('cards-count');
    }
  },

  events() {
    return [
      {
        'click .js-list-star'(event) {
          event.preventDefault();
          this.starred(!this.starred());
        },
        'click .js-open-list-menu': Popup.open('listAction'),
        'click .js-add-card'(event) {
          const listDom = $(event.target).parents(
            `#js-list-${this.currentData()._id}`,
          )[0];
          const listComponent = BlazeComponent.getComponentForElement(listDom);
          listComponent.openForm({
            position: 'top',
          });
        },
        'click .js-unselect-list'() {
          Session.set('currentList', null);
        },
        submit: this.editTitle,
      },
    ];
  },
}).register('listHeader');

Template.listHeader.helpers({
  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },

  showDesktopDragHandles() {
    currentUser = Meteor.user();
    if (currentUser) {
      return (currentUser.profile || {}).showDesktopDragHandles;
    } else if (window.localStorage.getItem('showDesktopDragHandles')) {
      return true;
    } else {
      return false;
    }
  },
});

Template.listActionPopup.helpers({
  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },

  isWipLimitEnabled() {
    return Template.currentData().getWipLimit('enabled');
  },

  isWatching() {
    return this.findWatcher(Meteor.userId());
  },
});

Template.listActionPopup.events({
  'click .js-list-subscribe'() {},
  'click .js-set-color-list': Popup.open('setListColor'),
  'click .js-select-cards'() {
    const cardIds = this.allCards().map(card => card._id);
    MultiSelection.add(cardIds);
    Popup.close();
  },
  'click .js-toggle-watch-list'() {
    const currentList = this;
    const level = currentList.findWatcher(Meteor.userId()) ? null : 'watching';
    Meteor.call('watch', 'list', currentList._id, level, (err, ret) => {
      if (!err && ret) Popup.close();
    });
  },
  'click .js-close-list'(event) {
    event.preventDefault();
    this.archive();
    Popup.close();
  },
  'click .js-set-wip-limit': Popup.open('setWipLimit'),
  'click .js-more': Popup.open('listMore'),
});

BlazeComponent.extendComponent({
  applyWipLimit() {
    const list = Template.currentData();
    const limit = parseInt(
      Template.instance()
        .$('.wip-limit-value')
        .val(),
      10,
    );

    if (limit < list.cards().count() && !list.getWipLimit('soft')) {
      Template.instance()
        .$('.wip-limit-error')
        .click();
    } else {
      Meteor.call('applyWipLimit', list._id, limit);
      Popup.back();
    }
  },

  enableSoftLimit() {
    const list = Template.currentData();

    if (
      list.getWipLimit('soft') &&
      list.getWipLimit('value') < list.cards().count()
    ) {
      list.setWipLimit(list.cards().count());
    }
    Meteor.call('enableSoftLimit', Template.currentData()._id);
  },

  enableWipLimit() {
    const list = Template.currentData();
    // Prevent user from using previously stored wipLimit.value if it is less than the current number of cards in the list
    if (
      !list.getWipLimit('enabled') &&
      list.getWipLimit('value') < list.cards().count()
    ) {
      list.setWipLimit(list.cards().count());
    }
    Meteor.call('enableWipLimit', list._id);
  },

  isWipLimitSoft() {
    return Template.currentData().getWipLimit('soft');
  },

  isWipLimitEnabled() {
    return Template.currentData().getWipLimit('enabled');
  },

  wipLimitValue() {
    return Template.currentData().getWipLimit('value');
  },

  events() {
    return [
      {
        'click .js-enable-wip-limit': this.enableWipLimit,
        'click .wip-limit-apply': this.applyWipLimit,
        'click .wip-limit-error': Popup.open('wipLimitError'),
        'click .materialCheckBox': this.enableSoftLimit,
      },
    ];
  },
}).register('setWipLimitPopup');

Template.listMorePopup.events({
  'click .js-delete': Popup.afterConfirm('listDelete', function() {
    Popup.close();
    // TODO how can we avoid the fetch call?
    const allCards = this.allCards().fetch();
    const allCardIds = _.pluck(allCards, '_id');
    // it's okay if the linked cards are on the same list
    if (
      Cards.find({
        $and: [
          { listId: { $ne: this._id } },
          { linkedId: { $in: allCardIds } },
        ],
      }).count() === 0
    ) {
      allCardIds.map(_id => Cards.remove(_id));
      Lists.remove(this._id);
    } else {
      // TODO: Figure out more informative message.
      // Popup with a hint that the list cannot be deleted as there are
      // linked cards. We can adapt the query above so we can list the linked
      // cards.
      // Related:
      //   client/components/cards/cardDetails.js about line 969
      //   https://github.com/wekan/wekan/issues/2785
      const message = `${TAPi18n.__(
        'delete-linked-cards-before-this-list',
      )} linkedId: ${
        this._id
      } at client/components/lists/listHeader.js and https://github.com/wekan/wekan/issues/2785`;
      alert(message);
    }
    Utils.goBoardId(this.boardId);
  }),
});

Template.listHeader.helpers({
  isBoardAdmin() {
    return Meteor.user().isBoardAdmin();
  },
});

BlazeComponent.extendComponent({
  onCreated() {
    this.currentList = this.currentData();
    this.currentColor = new ReactiveVar(this.currentList.color);
  },

  colors() {
    return listsColors.map(color => ({ color, name: '' }));
  },

  isSelected(color) {
    if (this.currentColor.get() === null) {
      return color === 'white';
    } else {
      return this.currentColor.get() === color;
    }
  },

  events() {
    return [
      {
        'click .js-palette-color'() {
          this.currentColor.set(this.currentData().color);
        },
        'click .js-submit'() {
          this.currentList.setColor(this.currentColor.get());
          Popup.close();
        },
        'click .js-remove-color'() {
          this.currentList.setColor(null);
          Popup.close();
        },
      },
    ];
  },
}).register('setListColorPopup');
<|endoftext|>


<commit_before>/**
  Token Transports
  @description a collection of different token transports in different
    frameworks, exported as a single abstracted API
  @author tylerFowler
**/

const {
  InvalidFlavorError,
  InvalidTransportMethodError
} = require('./errors');

const flavors = require('./flavors');
const transportMethods = {
  HEADER: 'header-transport',
  COOKIE: 'cookie-transport'
};
exports.TransportMethods = transportMethods;

const transports = {
  [flavors.EXPRESSJS]: {
    [transportMethods.HEADER]: {
      extract(req) { return req.get(this.key); },
      inject(res, token) { res.set(this.key, token); }
    },
    [transportMethods.COOKIE]: {
      extract(req) { return req.cookies[this.key]; },
      inject(res, token) { res.cookie(this.key, token, this.opts); }
    }
  }
};

/**
  @name TokenTransport
  @desc creates a new TokenTransport with the given method & flavor
  @param {string} flavor typically the framework being used
  @param {string} transportMethod the method used to carry the token
  @param {string} key the key used to retrieve tokens
  @param {object} injectOpts arbitrary options passed to the injection method
  @returns {object} transport
  @throws {InvalidFlavorError} error
  @throws {InvalidTransportMethodError} error
**/
function TokenTransport(flavor, transportMethod, key, injectOpts = {}) {
  this.key = key;
  this.opts = injectOpts;

  if (!Object.keys(flavors)
    .map(k => flavors[k]).find(f => f === flavor)
  ) throw new InvalidFlavorError(flavor, 'transport');
  this.flavor = flavor;

  if (!Object.keys(transportMethods)
    .map(k => transportMethods[k]).find(m => m === transportMethod)
  ) throw new InvalidTransportMethodError(transportMethod);
  this.transportMethod = transportMethod;
}

TokenTransport.prototype.extractToken = function extractToken(req) {
  return transports[this.flavor][this.transportMethod].extract.call(this, req);
};

TokenTransport.prototype.injectToken = function injectToken(res, token) {
  return transports[this.flavor][this.transportMethod].inject.call(this, res, token);
};

exports.TokenTransport = TokenTransport;
<commit_msg>Make cookie extraction more resilient<commit_after>/**
  Token Transports
  @description a collection of different token transports in different
    frameworks, exported as a single abstracted API
  @author tylerFowler
**/

const {
  InvalidFlavorError,
  InvalidTransportMethodError
} = require('./errors');

const flavors = require('./flavors');
const transportMethods = {
  HEADER: 'header-transport',
  COOKIE: 'cookie-transport'
};
exports.TransportMethods = transportMethods;

const transports = {
  [flavors.EXPRESSJS]: {
    [transportMethods.HEADER]: {
      extract(req) { return req.get(this.key); },
      inject(res, token) { res.set(this.key, token); }
    },
    [transportMethods.COOKIE]: {
      extract(req) {
        if (req.cookies && req.cookies[this.key]) return req.cookies[this.key];
        return null;
      },
      inject(res, token) { res.cookie(this.key, token, this.opts); }
    }
  }
};

/**
  @name TokenTransport
  @desc creates a new TokenTransport with the given method & flavor
  @param {string} flavor typically the framework being used
  @param {string} transportMethod the method used to carry the token
  @param {string} key the key used to retrieve tokens
  @param {object} injectOpts arbitrary options passed to the injection method
  @returns {object} transport
  @throws {InvalidFlavorError} error
  @throws {InvalidTransportMethodError} error
**/
function TokenTransport(flavor, transportMethod, key, injectOpts = {}) {
  this.key = key;
  this.opts = injectOpts;

  if (!Object.keys(flavors)
    .map(k => flavors[k]).find(f => f === flavor)
  ) throw new InvalidFlavorError(flavor, 'transport');
  this.flavor = flavor;

  if (!Object.keys(transportMethods)
    .map(k => transportMethods[k]).find(m => m === transportMethod)
  ) throw new InvalidTransportMethodError(transportMethod);
  this.transportMethod = transportMethod;
}

TokenTransport.prototype.extractToken = function extractToken(req) {
  return transports[this.flavor][this.transportMethod].extract.call(this, req);
};

TokenTransport.prototype.injectToken = function injectToken(res, token) {
  return transports[this.flavor][this.transportMethod].inject.call(this, res, token);
};

exports.TokenTransport = TokenTransport;
<|endoftext|>


<commit_before>angular.module('ionic.wizard', [])
    .directive('ionWizardContent', ['ionContentDirective', function(ionContentDirective) {
      return angular.extend({}, ionContentDirective[0], { scope: false });
    }])
    .directive('ionWizard', ['$rootScope', '$ionicSlideBoxDelegate', function($rootScope, $ionicSlideBoxDelegate) {
        return{
            restrict: 'EA',
            controller: [function() {
                var conditions = [];

                this.addCondition = function(condition) {
                    conditions.push(condition);
                };

                this.getCondition = function(index) {
                    return conditions[index];
                };

                this.checkNextCondition = function(index) {
                    return index > (conditions.length - 1)
                        ? false
                        : conditions[index].next();
                };

                this.checkPreviousCondition = function(index) {
                    return index > (conditions.length - 1)
                        ? false
                        : conditions[index].prev();
                };

            }],
            link: function (scope, element, attrs, controller) {
                var currentIndex = 0;

                $ionicSlideBoxDelegate.enableSlide(false);

                element.css('height', '100%');

                scope.$on("wizard:Previous", function() {
                    if (controller.checkPreviousCondition(currentIndex)) {
                        $ionicSlideBoxDelegate.previous();
                    }
                    else {
                        $rootScope.$broadcast("wizard:StepFailed", {index: currentIndex, direction: "previous"});
                    }
                });
                scope.$on("wizard:Next", function() {

                    if (controller.checkNextCondition(currentIndex)) {
                        $ionicSlideBoxDelegate.next();
                    }
                    else {
                         $rootScope.$broadcast("wizard:StepFailed", {index: currentIndex, direction: "next"});
                    }
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    currentIndex = index;
                });
            }
        }

    }])
    .directive('ionWizardStep', ['$q', function($q) {
        return {
            restrict: 'EA',
            scope: {
                nextConditionFn: '&nextCondition',
                prevConditionFn: "&prevCondition"
            },
            require: '^^ionWizard',
            link: function(scope, element, attrs, controller) {
                var nextFn = function() {
                    return angular.isUndefined(attrs.nextCondition)
                        ? true
                        : scope.nextConditionFn();
                };

                var prevFn = function() {
                    return angular.isUndefined(attrs.prevCondition)
                        ? true
                        : scope.prevConditionFn();
                };

                var conditions = {
                    next: nextFn,
                    prev: prevFn
                };

                controller.addCondition(conditions);
            }
        }
    }])
    .directive('ionWizardPrevious', ['$rootScope', '$ionicSlideBoxDelegate', function($rootScope) {
        return{
            restrict: 'EA',
            scope: {},
            link: function(scope, element, attrs, controller) {

                element.addClass('ng-hide');

                element.on('click', function() {
                    $rootScope.$broadcast("wizard:Previous");
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    element.toggleClass('ng-hide', index == 0);
                });
            }
        }
    }])
    .directive('ionWizardNext', ['$rootScope', '$ionicSlideBoxDelegate', function($rootScope, $ionicSlideBoxDelegate) {
        return{
            restrict: 'EA',
            scope: {},
            link: function(scope, element, attrs, controller) {
                element.on('click', function() {
                    $rootScope.$broadcast("wizard:Next");
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    element.addClass("ng-disabled");
                    element.toggleClass('ng-hide', index == $ionicSlideBoxDelegate.slidesCount() - 1);
                });
            }
        }
    }])
    .directive('ionWizardStart', ['$ionicSlideBoxDelegate', function($ionicSlideBoxDelegate) {
        return{
            restrict: 'EA',
            scope: {
                startFn: '&ionWizardStart'
            },
            link: function(scope, element) {
                element.addClass('ng-hide');

                element.on('click', function() {
                    scope.startFn();
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    element.toggleClass('ng-hide', index < $ionicSlideBoxDelegate.slidesCount() - 1);
                });
            }
        }
    }]);<commit_msg>add events for condition checking<commit_after>angular.module('ionic.wizard', [])
    .directive('ionWizardContent', ['ionContentDirective', function(ionContentDirective) {
      return angular.extend({}, ionContentDirective[0], { scope: false });
    }])
    .directive('ionWizard', ['$rootScope', '$ionicSlideBoxDelegate', function($rootScope, $ionicSlideBoxDelegate) {
        return{
            restrict: 'EA',
            controller: [function() {
                var conditions = [];

                this.addCondition = function(condition) {
                    conditions.push(condition);
                };

                this.getCondition = function(index) {
                    return conditions[index];
                };

                this.checkNextCondition = function(index) {
                    return index > (conditions.length - 1)
                        ? false
                        : conditions[index].next();
                };

                this.checkPreviousCondition = function(index) {
                    return index > (conditions.length - 1)
                        ? false
                        : conditions[index].prev();
                };

            }],
            link: function (scope, element, attrs, controller) {
                var currentIndex = 0;

                $ionicSlideBoxDelegate.enableSlide(false);

                element.css('height', '100%');

                scope.$on("wizard:Previous", function() {
                    if (controller.checkPreviousCondition(currentIndex)) {
                        $ionicSlideBoxDelegate.previous();
                    }
                    else {
                        $rootScope.$broadcast("wizard:StepFailed", {index: currentIndex, direction: "previous"});
                    }
                });
                scope.$on("wizard:Next", function() {

                    if (controller.checkNextCondition(currentIndex)) {
                        $ionicSlideBoxDelegate.next();
                    }
                    else {
                         $rootScope.$broadcast("wizard:StepFailed", {index: currentIndex, direction: "next"});
                    }
                });

                scope.$watch(function() {
                    return controller.checkNextCondition(currentIndex) && controller.checkPreviousCondition(currentIndex);
                }, function() {
                    $rootScope.$broadcast("wizard:NextCondition", controller.checkNextCondition(currentIndex));
                    $rootScope.$broadcast("wizard:PreviousCondition", controller.checkPreviousCondition(currentIndex));
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    currentIndex = index;
                });
            }
        }

    }])
    .directive('ionWizardStep', ['$q', function($q) {
        return {
            restrict: 'EA',
            scope: {
                nextConditionFn: '&nextCondition',
                prevConditionFn: "&prevCondition"
            },
            require: '^^ionWizard',
            link: function(scope, element, attrs, controller) {
                var nextFn = function() {
                    return angular.isUndefined(attrs.nextCondition)
                        ? true
                        : scope.nextConditionFn();
                };

                var prevFn = function() {
                    return angular.isUndefined(attrs.prevCondition)
                        ? true
                        : scope.prevConditionFn();
                };

                var conditions = {
                    next: nextFn,
                    prev: prevFn
                };

                controller.addCondition(conditions);
            }
        }
    }])
    .directive('ionWizardPrevious', ['$rootScope', '$ionicSlideBoxDelegate', function($rootScope) {
        return{
            restrict: 'EA',
            scope: {},
            link: function(scope, element, attrs, controller) {

                element.addClass('ng-hide');

                element.on('click', function() {
                    $rootScope.$broadcast("wizard:Previous");
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    element.toggleClass('ng-hide', index == 0);
                });

                scope.$on("wizard:PreviousCondition", function(e, condition) {
                    element.attr("disabled", !condition);
                });
            }
        }
    }])
    .directive('ionWizardNext', ['$rootScope', '$ionicSlideBoxDelegate', function($rootScope, $ionicSlideBoxDelegate) {
        return{
            restrict: 'EA',
            scope: {},
            link: function(scope, element, attrs, controller) {
                element.on('click', function() {
                    $rootScope.$broadcast("wizard:Next");
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    element.addClass("ng-disabled");
                    element.toggleClass('ng-hide', index == $ionicSlideBoxDelegate.slidesCount() - 1);
                });

                scope.$on("wizard:NextCondition", function(e, condition) {
                    element.attr("disabled", !condition);
                });
            }
        }
    }])
    .directive('ionWizardStart', ['$ionicSlideBoxDelegate', function($ionicSlideBoxDelegate) {
        return{
            restrict: 'EA',
            scope: {
                startFn: '&ionWizardStart'
            },
            link: function(scope, element) {
                element.addClass('ng-hide');

                element.on('click', function() {
                    scope.startFn();
                });

                scope.$on("slideBox.slideChanged", function(e, index) {
                    element.toggleClass('ng-hide', index < $ionicSlideBoxDelegate.slidesCount() - 1);
                });
            }
        }
    }]);<|endoftext|>


<commit_before>const reduxish = require('./lib/reduxish');
const way = require('senseway');

const renderers = [
  require('./menu/render'),
  require('./channelEditor/render'),
  require('./channelStars/render'),
  require('./channelTitles/render'),
  require('./timelineViewer/render'),
  require('./howViewer/render')
];

const reducers = [
  require('./menu/reduce'),
  require('./channelEditor/reduce'),
  require('./channelStars/reduce'),
  require('./channelTitles/reduce'),
  require('./timelineViewer/reduce'),
  require('./howViewer/reduce')
];

const u = null;

module.exports = () => {
  reduxish({
    defaultModel: {
      timeline: [
        //                                   13.6.
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, u, u, u], // aami
        [u, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, u, u, u], // ulko
        [u, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, u, u, u], // sarj
        [u, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, u, u, u], // kast
        [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, u, u, u], // kiip
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, u, u, u], // uimi
        [u, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, u, u, u], // fiil
        [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, u, u, u], // ohje
        [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, u, u, u], // koti
        [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, u, u, u], // ilok
        [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, u, u, u], // kilt
        [u, u, u, u, u, 1, 1, 0, 0, 1, 0, 0, 1, u, u, u], // musa
        [u, u, u, u, u, 0, 0, 0, 0, 0, 0, 0, 0, u, u, u]  // soit
      ],
      frames: [
        { title: 'la 1.6.' },
        { title: 'su 2.6.' },
        { title: 'ma 3.6.' },
        { title: 'ti 4.6.' },
        { title: 'ke 5.6.' },
        { title: 'to 6.6.' },
        { title: 'pe 7.6.' },
        { title: 'la 8.6.' },
        { title: 'su 9.6.' },
        { title: 'ma 10.6.' },
        { title: 'ti 11.6.' },
        { title: 'ke 12.6.' },
        { title: 'to 13.6.' },
        { title: 'pe 14.6.' },
        { title: 'la 15.6.' },
        { title: 'su 16.6.' },
      ],
      channels: [ // Dimensions
        {
          title: 'Aamiainen'
        },
        {
          title: 'Ulkoilu'
        },
        {
          title: 'Sarjan katselu'
        },
        {
          title: 'Kasvien kastelu'
        },
        {
          title: 'Kiipeily'
        },
        {
          title: 'Uiminen'
        },
        {
          title: 'Hyvä fiilis'
        },
        {
          title: 'Ohjelmointi'
        },
        {
          title: 'Koti-ilta'
        },
        {
          title: 'Ilokivi-ilta'
        },
        {
          title: 'Kiltailta'
        },
        {
          title: 'Kuuntelu'
        },
        {
          title: 'Soittelu'
        }
      ],
      channelOnEdit: null,
      contextLength: 7,
      frameOnEdit: null,
      select: {
        channel: 0,
        time: 0
      },
      version: 0 // data model version
    },
    storageName: 'future-model',
    rootElementId: 'content',
    renderers: renderers,
    reducers: reducers
  })
};
<commit_msg>Example dataset to english, no localisation yet<commit_after>const reduxish = require('./lib/reduxish');
const way = require('senseway');

const renderers = [
  require('./menu/render'),
  require('./channelEditor/render'),
  require('./channelStars/render'),
  require('./channelTitles/render'),
  require('./timelineViewer/render'),
  require('./howViewer/render')
];

const reducers = [
  require('./menu/reduce'),
  require('./channelEditor/reduce'),
  require('./channelStars/reduce'),
  require('./channelTitles/reduce'),
  require('./timelineViewer/reduce'),
  require('./howViewer/reduce')
];

const u = null;

module.exports = () => {
  reduxish({
    defaultModel: {
      timeline: [
        //                                   13.6.
        [u, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, u, u, u], // fiil
        [u, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, u, u, u], // ulko
        [u, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, u, u, u], // sarj
        [u, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, u, u, u], // kast
        [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, u, u, u], // kiip
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, u, u, u], // uimi
        [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, u, u, u], // koti
        [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, u, u, u], // friends
        [u, u, u, u, u, 1, 1, 0, 0, 1, 0, 0, 1, u, u, u] // musa
      ],
      frames: [
        { title: 'la 1.6.' },
        { title: 'su 2.6.' },
        { title: 'ma 3.6.' },
        { title: 'ti 4.6.' },
        { title: 'ke 5.6.' },
        { title: 'to 6.6.' },
        { title: 'pe 7.6.' },
        { title: 'la 8.6.' },
        { title: 'su 9.6.' },
        { title: 'ma 10.6.' },
        { title: 'ti 11.6.' },
        { title: 'ke 12.6.' },
        { title: 'to 13.6.' },
        { title: 'pe 14.6.' },
        { title: 'la 15.6.' },
        { title: 'su 16.6.' },
      ],
      channels: [ // Dimensions
        {
          title: 'Good feels',
          star: true
        },
        {
          title: 'Went outside'
        },
        {
          title: 'Watched movie'
        },
        {
          title: 'Watered plants'
        },
        {
          title: 'Climbed somewhere'
        },
        {
          title: 'Swam a bit'
        },
        {
          title: 'Stayed at home'
        },
        {
          title: 'Friends'
        },
        {
          title: 'Played music'
        }
      ],
      channelOnEdit: null,
      contextLength: 7,
      frameOnEdit: null,
      select: {
        channel: 0,
        time: 0
      },
      version: 0 // data model version
    },
    storageName: 'future-model',
    rootElementId: 'content',
    renderers: renderers,
    reducers: reducers
  })
};
<|endoftext|>


<commit_before>(function() {
  'use strict'

  angular.module('app')
    .component('poses', {
      templateUrl: '/templates/poses.template.html',
      controller: PosesController
    })

  PosesController.$inject = ['$http', '$stateParams', '$state']

  function PosesController() {
    console.log("you are in the Poses Controller")
  }
})()
<commit_msg>poses state work<commit_after>(function() {
  'use strict'

  angular.module('app')
    .component('main.poses', {
      templateUrl: '/templates/poses.template.html',
      controller: PosesController
    })

  PosesController.$inject = ['$http', '$stateParams', '$state']

  function PosesController() {
    console.log("you are in the Poses Controller")
  }
})()
<|endoftext|>


<commit_before>{
        'type': 'Shotter Space', // game or console
        'name': 'Space War',
        'authors': ['Steve Russel', 'Dan Edwards','Alan Kotok','Peter Sampson','Wayne Wiitanen Graetz'],
        'company': [' Massachusetts Institute of Technology(MIT)'],
        'year': '1951',
        'date': '20-06-1951', // Day, Month, Year
        'headline': 'First Game about sport',
        'resume': [
            'Lorem ipsum dolor sit amet, ut viverra vestibulum odio, ',
            'aliquam in massa, velit rutrum pede ipsum mauris duis, ',
            'congue massa sem elit, integer risus. Faucibus in lacus, ',
            'ligula ornare nibh, elit suspendisse tortor sed volutpat, ',
            'etiam tempus wisi semper montes odio, lorem vitae vel eu '
        ].join(''),
        'full_text': [
            'Lorem ipsum dolor sit amet, ut viverra vestibulum odio, ',
            'aliquam in massa, velit rutrum pede ipsum mauris duis, ',
            'congue massa sem elit, integer risus. Faucibus in lacus, ',
            'ligula ornare nibh, elit suspendisse tortor sed volutpat, ',
            'etiam tempus wisi semper montes odio, lorem vitae vel eu ',
            'convallis. Volutpat blandit egestas et libero eu per, venenatis ',
            'aenean, proin quis aliquam viverra potenti vestibulum auctor, ',
            'non amet tellus sodales. In ullamco tellus risus nisl morbi amet. ',
            'Vel quisque nunc in placerat. Vitae id urna, nulla suspendisse, ',
            'molestie sodales ac nisl nulla, tempus occaecati. Sodales lectus, ',
            'mauris dis lectus amet, nascetur ipsum, hac suspendisse blandit eros.'
        ].join(''),
        'thumbnail': 'thumbnail_example.png',
        'main_img': {'name': 'main_picture.png', 'caption': "description"},
        'images': [
            {'name': 'picture1.png', 'caption': "description1"},
            {'name': 'picture2.png', 'caption': "description2"},
            {'name': 'picture3.png', 'caption': "description3"}
        ],
        'video_gameplay': [
            {'url': 'video_url', 'caption': "description", 'type': "youtube"} // type: youtube or vimeo
        ],
        'demos': [
            {'url': 'demonstration_url', 'caption': "description"}
        ],
        'references': [
            {'url': 'reference_url1', 'caption': "description"},
            {'url': 'reference_url2', 'caption': "description"},
            {'url': 'reference_url3', 'caption': "description"}
        ]
}
<commit_msg>Update Spacewar_temp.js<commit_after>{
        'type': 'Shotter Space', // game or console
        'name': 'Space War',
        'authors': ['Steve Russel', 'Dan Edwards','Alan Kotok','Peter Sampson','Wayne Wiitanen Graetz'],
        'company': [' Massachusetts Institute of Technology(MIT)'],
        'year': '1961',
        'date': '30-07-1961', // Day, Month, Year
        'headline': 'First Game about space',
        'resume': [
            'Tendo o grosso de seu programa feito por Steve "Slug" (Lesma) Russell1 2 , com o auxílio de seus colegas Dan Edwards, Alan  ',
            ' Kotok, Peter Sampson, Wayne Wiitanen e Martin Graetz3 , eles se inspiraram nos livros do autor E. E. "Doc" Smith para criar seu',
            'jogo de tiro, uma batalha espacial.'
            'O programa foi inteiramente desenvolvido no DEC PDP-1, um computador que ocupava uma mesa inteira. Nessa época não  ',
            'existiam computadores caseiros, e os criadores de Spacewar! não pensavam em ganhar dinheiro com a invenção. '
        ].join(''),
        'full_text': [
            'Lorem ipsum dolor sit amet, ut viverra vestibulum odio, ',
            'aliquam in massa, velit rutrum pede ipsum mauris duis, ',
            'congue massa sem elit, integer risus. Faucibus in lacus, ',
            'ligula ornare nibh, elit suspendisse tortor sed volutpat, ',
            'etiam tempus wisi semper montes odio, lorem vitae vel eu ',
            'convallis. Volutpat blandit egestas et libero eu per, venenatis ',
            'aenean, proin quis aliquam viverra potenti vestibulum auctor, ',
            'non amet tellus sodales. In ullamco tellus risus nisl morbi amet. ',
            'Vel quisque nunc in placerat. Vitae id urna, nulla suspendisse, ',
            'molestie sodales ac nisl nulla, tempus occaecati. Sodales lectus, ',
            'mauris dis lectus amet, nascetur ipsum, hac suspendisse blandit eros.'
        ].join(''),
        'thumbnail': 'thumbnail_example.png',
        'main_img': {'name': 'main_picture.png', 'caption': "description"},
        'images': [
            {'name': 'picture1.png', 'caption': "description1"},
            {'name': 'picture2.png', 'caption': "description2"},
            {'name': 'picture3.png', 'caption': "description3"}
        ],
        'video_gameplay': [
            {'url': 'video_url', 'caption': "description", 'type': "youtube"} // type: youtube or vimeo
        ],
        'demos': [
            {'url': 'demonstration_url', 'caption': "description"}
        ],
        'references': [
            {'url': 'reference_url1', 'caption': "description"},
            {'url': 'reference_url2', 'caption': "description"},
            {'url': 'reference_url3', 'caption': "description"}
        ]
}
<|endoftext|>