<commit_before>(  function ( $ ) {
    /*Collection = function() {}*/

    //Collection.prototype.list = [];

    //Collection.prototype.push = function(string) {
        //this.list.push(string);
    //}

    //Collection.prototype.displayElementAt = function(index) {
        //console.log(Collection.prototype.list[index]);
    //}

    //$.fn.test = function(string) {
        //col = new Collection();

        //col.push(string);
        //col.displayElementAt(0);
    /*}*/

    /* Frames collection
       ===================================================*/
    var Frames = function() {};

    Frames.prototype.list = [];

    Frames.prototype.push = function(array) {
        this.list.push(array);
    }

    Frames.prototype.pop = function() {
        this.list.pop();
    }

    Frames.prototype.assignArray = function(array, index) {
        this.list[index] = array;
    }

    Frames.prototype._empty = function() {
        this.list = [];
    }

    Frames.prototype.indexAt = function(index) {
        return this.list[index];
    }

    Frames.prototype.last = function() {
        return this.list[this.list.length - 1];
    }

    /* properties
     */
    var frames = new Frames();
    var frameCounter = 0;

    /* adds current frame to Frames collection
     * $this used to reference object calling the function
     */
    var addCurrentFrame = function($this, frames) {
        var bulbArray = [];

        $this.find('button').each(function(i) {
            if ( this.value == "" ) {
                bulbArray[i] = 0;
            } else {
                bulbArray[i] = parseInt(this.value);
            }
        });
        frames.push(bulbArray);
    }

    var updateCurrentFrame = function($this, frames) {
        var bulbArray = [];

        $this.find('button').each(function(i) {
            if ( this.value == "" ) {
                bulbArray[i] = 0;
            } else {
                bulbArray[i] = parseInt(this.value);
            }
        });
        frames.assignArray(bulbArray, frameCounter);
    }

    var toggleLightBulb = function($this) {
        if ( $this.value == 0 ) {
            $($this).find('i').removeClass('fa-square').addClass('fa-square-o');
        } else {
            $($this).find('i').removeClass('fa-square-o').addClass('fa-square');
        }
    }

    var toggleBulbs = function($this, frames) {
        console.log("Toggling bulbs");
        $this.find('button').each(function(i) {
            //console.log(frameCounter);
            //console.log(frames.indexAt(frameCounter)[i]);
            this.value = frames.indexAt(frameCounter)[i];
            toggleLightBulb(this);
        });
    }

    var clearFrame = function($this) {
        $this.find('button').each(function() {
            this.value = 0;
        });
        $this.find('i').each(function() {
            $(this).removeClass('fa-square').addClass('fa-square-o');
        });
    }

    $.fn.addFrame = function() {
        console.log(frames);
        console.log(this);
        addCurrentFrame(this, frames);
        clearFrame(this);
        frameCounter++;
        console.log("Frame: " + frameCounter);
    }

    $.fn.nextFrame = function() {
        console.log(frames);
        console.log(frames.list);
        addCurrentFrame(this, frames);
        clearFrame(this);
        frameCounter++;
        console.log("Frame: " + frameCounter);
    }

    $.fn.previousFrame = function() {
        if ( frameCounter-1 < 0 ) {
            frameCounter = 0;
            console.log("This is the first frame, you can't go back.");
            console.log("Frame: " + frameCounter);
        } else {
            updateCurrentFrame(this, frames);
            clearFrame(this);
            frameCounter--;
            toggleBulbs(this, frames);
            console.log("Frame: " + frameCounter);
        }
    }
}( jQuery ));
<commit_msg>refactored addCurrentFrame method<commit_after>(  function ( $ ) {
    /*Collection = function() {}*/

    //Collection.prototype.list = [];

    //Collection.prototype.push = function(string) {
        //this.list.push(string);
    //}

    //Collection.prototype.displayElementAt = function(index) {
        //console.log(Collection.prototype.list[index]);
    //}

    //$.fn.test = function(string) {
        //col = new Collection();

        //col.push(string);
        //col.displayElementAt(0);
    /*}*/

    /* Frames collection
       ===================================================*/
    var Frames = function() {};

    Frames.prototype.list = [];

    Frames.prototype.push = function(array) {
        this.list.push(array);
    }

    Frames.prototype.pop = function() {
        this.list.pop();
    }

    Frames.prototype.assignArray = function(array, index) {
        this.list[index] = array;
    }

    Frames.prototype._empty = function() {
        this.list = [];
    }

    Frames.prototype.indexAt = function(index) {
        return this.list[index];
    }

    Frames.prototype.last = function() {
        return this.list[this.list.length - 1];
    }

    /* properties
     */
    var frames = new Frames();
    var frameCounter = 0;

    /* adds current frame to Frames collection
     * $this used to reference object calling the function
     */
    var updateCurrentFrame = function($this, frames) {
        var bulbArray = [];

        $this.find('button').each(function(i) {
            if ( this.value == "" ) {
                bulbArray[i] = 0;
            } else {
                bulbArray[i] = parseInt(this.value);
            }
        });
        if ( frames.indexAt(frameCounter) == undefined ) {
            frames.push(bulbArray);
        } else {
            frames.assignArray(bulbArray, frameCounter);
        }
    }

    var toggleLightBulb = function($this) {
        if ( $this.value == 0 ) {
            $($this).find('i').removeClass('fa-square').addClass('fa-square-o');
        } else {
            $($this).find('i').removeClass('fa-square-o').addClass('fa-square');
        }
    }

    var toggleBulbs = function($this, frames) {
        console.log("Toggling bulbs");
        $this.find('button').each(function(i) {
            //console.log(frameCounter);
            //console.log(frames.indexAt(frameCounter)[i]);
            this.value = frames.indexAt(frameCounter)[i];
            toggleLightBulb(this);
        });
    }

    var clearFrame = function($this) {
        $this.find('button').each(function() {
            this.value = 0;
        });
        $this.find('i').each(function() {
            $(this).removeClass('fa-square').addClass('fa-square-o');
        });
    }

    $.fn.addFrame = function() {
        console.log(frames);
        console.log(this);
        updateCurrentFrame(this, frames);
        clearFrame(this);
        frameCounter++;
        console.log("Frame: " + frameCounter);
    }

    $.fn.nextFrame = function() {
        console.log(frames);
        console.log(frames.list);
        updateCurrentFrame(this, frames);
        clearFrame(this);
        frameCounter++;
        console.log("Frame: " + frameCounter);
    }

    $.fn.previousFrame = function() {
        if ( frameCounter-1 < 0 ) {
            frameCounter = 0;
            console.log("This is the first frame, you can't go back.");
            console.log("Frame: " + frameCounter);
        } else {
            updateCurrentFrame(this, frames);
            clearFrame(this);
            frameCounter--;
            toggleBulbs(this, frames);
            console.log("Frame: " + frameCounter);
        }
    }
}( jQuery ));
<|endoftext|>


<commit_before>import {
  always,
  assocPartialU,
  identicalU,
  inherit,
  isArray,
  isObject
} from "infestines"
import {Observable, Property, combine} from "kefir"
import {get, modify, set} from "partial.lenses"

//

const header = "kefir.atom: "

function error(m) {
  throw new Error(header + m)
}

function errorGiven(m, o) {
  console.error(header + m + " - given:", o)
  error(m)
}

//

let lock = 0

const prevs = []
const atoms = []

function release() {
  while (prevs.length) {
    const prev = prevs.shift()
    const atom = atoms.shift()
    const next = atom._currentEvent.value

    if (!identicalU(prev, next))
      atom._emitValue(next)
  }
}

export function holding(ef) {
  ++lock
  try {
    return ef()
  } finally {
    if (!--lock)
      release()
  }
}

//

export function AbstractMutable() {
  Property.call(this)
}

inherit(AbstractMutable, Property, {
  set(value) {
    this.modify(always(value))
  },
  remove() {
    this.set()
  },
  view(lens) {
    if (process.env.NODE_ENV !== "production" && arguments.length !== 1)
      errorGiven("The `view` method takes exactly 1 argument", arguments.length)
    return new LensedAtom(this, lens)
  },
  _maybeEmitValue(next) {
    const prev = this._currentEvent
    if (!prev || !identicalU(prev.value, next))
      this._emitValue(next)
  }
})

//

export function MutableWithSource(source) {
  if (process.env.NODE_ENV !== "production" && !(source instanceof Observable))
    errorGiven("Expected an Observable", source)
  AbstractMutable.call(this)
  this._source = source
  this._$onAny = null
}

inherit(MutableWithSource, AbstractMutable, {
  get() {
    const current = this._currentEvent
    if (current && !lock)
      return current.value
    else
      return this._getFromSource()
  },
  _onAny() {
    this._maybeEmitValue(this._getFromSource())
  },
  _onActivation() {
    const onAny = () => this._onAny()
    this._$onAny = onAny
    this._source.onAny(onAny)
  },
  _onDeactivation() {
    this._source.offAny(this._$onAny)
    this._$onAny = null
    this._currentEvent = null
  }
})

//

export function LensedAtom(source, lens) {
  MutableWithSource.call(this, source)
  this._lens = lens
}

inherit(LensedAtom, MutableWithSource, {
  set(v) {
    this._source.set(set(this._lens, v, this._source.get()))
  },
  modify(fn) {
    this._source.modify(modify(this._lens, fn))
  },
  _getFromSource() {
    return get(this._lens, this._source.get())
  }
})

//

export function Atom() {
  AbstractMutable.call(this)
  if (arguments.length)
    this._emitValue(arguments[0])
}

inherit(Atom, AbstractMutable, {
  get() {
    const current = this._currentEvent
    return current ? current.value : void 0
  },
  set(v) {
    const current = this._currentEvent
    this._set(current, current ? current.value : void 0, v)
  },
  modify(fn) {
    const current = this._currentEvent
    const prev = current ? current.value : void 0
    this._set(current, prev, fn(prev))
  },
  _set(current, prev, next) {
    if (lock) {
      if (atoms.indexOf(this) < 0) {
        prevs.push(current ? prev : error /* <- just needs to be unique */)
        atoms.push(this)
      }
      if (current)
        current.value = next
      else
        this._currentEvent = {type: "value", value: next}
    } else {
      this._maybeEmitValue(next)
    }
  }
})

//

function pushMutables(template, mutables) {
  if (template instanceof AbstractMutable &&
      mutables.indexOf(template) < 0) {
    mutables.push(template)
  } else {
    if (isArray(template))
      for (let i=0, n=template.length; i<n; ++i)
        pushMutables(template[i], mutables)
    else if (isObject(template))
      for (const k in template)
        pushMutables(template[k], mutables)
  }
}

function molecule(template) {
  if (template instanceof AbstractMutable) {
    return template.get()
  } else {
    if (isArray(template)) {
      const n = template.length
      let next = template
      for (let i=0; i<n; ++i) {
        const v = molecule(template[i])
        if (!identicalU(next[i], v)) {
          if (next === template)
            next = template.slice(0)
          next[i] = v
        }
      }
      return next
    } else if (isObject(template)) {
      let next = template
      for (const k in template) {
        const v = molecule(template[k])
        if (!identicalU(next[k], v)) {
          if (next === template)
            next = assocPartialU(void 0, void 0, template) // Avoid Object.assign
          next[k] = v
        }
      }
      return next
    } else {
      return template
    }
  }
}

function setMutables(template, value) {
  if (template instanceof AbstractMutable) {
    return template.set(value)
  } else {
    if (isArray(template) && isArray(value))
      for (let i=0, n=template.length; i<n; ++i)
        setMutables(template[i], value[i])
    else if (isObject(template) && isObject(value))
      for (const k in template)
        setMutables(template[k], value[k])
    else if (!identicalU(template, value))
      error("Molecule cannot change the template.")
  }
}

export function Molecule(template) {
  const mutables = []
  pushMutables(template, mutables)
  MutableWithSource.call(this, combine(mutables))
  this._template = template
}

inherit(Molecule, MutableWithSource, {
  _getFromSource() {
    return molecule(this._template)
  },
  modify(fn) {
    const next = fn(this.get())
    holding(() => setMutables(this._template, next))
  }
})

//

export default function atom() {
  if (arguments.length)
    return new Atom(arguments[0])
  else
    return new Atom()
}
<commit_msg>Prefer undefined. Tweak code.<commit_after>import {
  always,
  assocPartialU,
  identicalU,
  inherit,
  isArray,
  isObject
} from "infestines"
import {Observable, Property, combine} from "kefir"
import {get, modify, set} from "partial.lenses"

//

const header = "kefir.atom: "

function error(m) {
  throw new Error(header + m)
}

function errorGiven(m, o) {
  console.error(header + m + " - given:", o)
  error(m)
}

//

let lock = 0

const prevs = []
const atoms = []

function release() {
  while (prevs.length) {
    const prev = prevs.shift()
    const atom = atoms.shift()
    const next = atom._currentEvent.value

    if (!identicalU(prev, next))
      atom._emitValue(next)
  }
}

export function holding(ef) {
  ++lock
  try {
    return ef()
  } finally {
    if (!--lock)
      release()
  }
}

//

export function AbstractMutable() {
  Property.call(this)
}

inherit(AbstractMutable, Property, {
  set(value) {
    this.modify(always(value))
  },
  remove() {
    this.set()
  },
  view(lens) {
    if (process.env.NODE_ENV !== "production" && arguments.length !== 1)
      errorGiven("The `view` method takes exactly 1 argument", arguments.length)
    return new LensedAtom(this, lens)
  },
  _maybeEmitValue(next) {
    const prev = this._currentEvent
    if (!prev || !identicalU(prev.value, next))
      this._emitValue(next)
  }
})

//

export function MutableWithSource(source) {
  if (process.env.NODE_ENV !== "production" && !(source instanceof Observable))
    errorGiven("Expected an Observable", source)
  AbstractMutable.call(this)
  this._source = source
  this._$onAny = void 0
}

inherit(MutableWithSource, AbstractMutable, {
  get() {
    const current = this._currentEvent
    if (current && !lock)
      return current.value
    else
      return this._getFromSource()
  },
  _onAny() {
    this._maybeEmitValue(this._getFromSource())
  },
  _onActivation() {
    this._source.onAny(this._$onAny = e => this._onAny(e))
  },
  _onDeactivation() {
    this._source.offAny(this._$onAny)
    this._$onAny =
    this._currentEvent = void 0
  }
})

//

export function LensedAtom(source, lens) {
  MutableWithSource.call(this, source)
  this._lens = lens
}

inherit(LensedAtom, MutableWithSource, {
  set(v) {
    this._source.set(set(this._lens, v, this._source.get()))
  },
  modify(fn) {
    this._source.modify(modify(this._lens, fn))
  },
  _getFromSource() {
    return get(this._lens, this._source.get())
  }
})

//

export function Atom() {
  AbstractMutable.call(this)
  if (arguments.length)
    this._emitValue(arguments[0])
}

inherit(Atom, AbstractMutable, {
  get() {
    const current = this._currentEvent
    return current ? current.value : void 0
  },
  set(v) {
    const current = this._currentEvent
    this._set(current, current ? current.value : void 0, v)
  },
  modify(fn) {
    const current = this._currentEvent
    const prev = current ? current.value : void 0
    this._set(current, prev, fn(prev))
  },
  _set(current, prev, next) {
    if (lock) {
      if (atoms.indexOf(this) < 0) {
        prevs.push(current ? prev : error /* <- just needs to be unique */)
        atoms.push(this)
      }
      if (current)
        current.value = next
      else
        this._currentEvent = {type: "value", value: next}
    } else {
      this._maybeEmitValue(next)
    }
  }
})

//

function pushMutables(template, mutables) {
  if (template instanceof AbstractMutable &&
      mutables.indexOf(template) < 0) {
    mutables.push(template)
  } else {
    if (isArray(template))
      for (let i=0, n=template.length; i<n; ++i)
        pushMutables(template[i], mutables)
    else if (isObject(template))
      for (const k in template)
        pushMutables(template[k], mutables)
  }
}

function molecule(template) {
  if (template instanceof AbstractMutable) {
    return template.get()
  } else {
    if (isArray(template)) {
      const n = template.length
      let next = template
      for (let i=0; i<n; ++i) {
        const v = molecule(template[i])
        if (!identicalU(next[i], v)) {
          if (next === template)
            next = template.slice(0)
          next[i] = v
        }
      }
      return next
    } else if (isObject(template)) {
      let next = template
      for (const k in template) {
        const v = molecule(template[k])
        if (!identicalU(next[k], v)) {
          if (next === template)
            next = assocPartialU(void 0, void 0, template) // Avoid Object.assign
          next[k] = v
        }
      }
      return next
    } else {
      return template
    }
  }
}

function setMutables(template, value) {
  if (template instanceof AbstractMutable) {
    return template.set(value)
  } else {
    if (isArray(template) && isArray(value))
      for (let i=0, n=template.length; i<n; ++i)
        setMutables(template[i], value[i])
    else if (isObject(template) && isObject(value))
      for (const k in template)
        setMutables(template[k], value[k])
    else if (!identicalU(template, value))
      error("Molecule cannot change the template.")
  }
}

export function Molecule(template) {
  const mutables = []
  pushMutables(template, mutables)
  MutableWithSource.call(this, combine(mutables))
  this._template = template
}

inherit(Molecule, MutableWithSource, {
  _getFromSource() {
    return molecule(this._template)
  },
  modify(fn) {
    const next = fn(this.get())
    holding(() => setMutables(this._template, next))
  }
})

//

export default function atom() {
  if (arguments.length)
    return new Atom(arguments[0])
  else
    return new Atom()
}
<|endoftext|>


<commit_before>/* eslint-disable */
const ptbr = {
  headings: {
    contact: 'Contato',
    experience: 'Experiência Profissional',
    education: 'Educação',
    skills: 'Competências',
    about: 'Sobre'
  }
};
export default ptbr;
<commit_msg>Update the "Education" term.<commit_after>/* eslint-disable */
const ptbr = {
  headings: {
    contact: 'Contato',
    experience: 'Experiência Profissional',
    education: 'Formação Acadêmica', /*You can choose, "Educação" or "Formação Acadêmica"! But the second one is more professional and is more used.*/
    skills: 'Competências',
    about: 'Sobre'
  }
};
export default ptbr;
<|endoftext|>


<commit_before>var com = require('./com.js');
var hashData = require('./hashData.js');

var VER = 1;
var TYPE = 'gardr';
var REFRESH_KEY = 'refresh-' + TYPE;
var FAILED_CLASS = TYPE + '-failed';
var SEPARATOR = '_|_';

function validSize(v) {
    if (typeof v === 'string' && v.indexOf('px') !== -1) { return v; }
    if ( (typeof v === 'string' && v.indexOf('%') === -1) || typeof v === 'number') {
        return v + 'px';
    }
    return v;
}

function getOrigin(loc) {
    return loc.origin || (loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port : ''));
}

function Iframe(id, options) {
    this.id = id;
    if (!options || typeof options.iframeUrl === 'undefined') {
        throw new Error('Iframe missing options and iframeUrl');
    }
    this.element = null;
    this.iframeUrl = options.iframeUrl;
    this.width = options.width || '100%';
    this.height = options.height || '100px';
    this.classes = options.classes || '';
    this.hidden = options.hidden;
    this.data = {};
    this.key = options.key || com.PARENT_PREFIX;
}

Iframe.prototype.SEPARATOR = SEPARATOR;
Iframe.prototype.remove = function() {
    this.wrapper.parentNode.removeChild(this.wrapper);
    this.wrapper = null;
    this.element = null;
    return this;
};

Iframe.prototype.resize = function(w, h) {
    if (w) { this.width = w; }
    if (h) { this.height = h; }
    this.element.style.width = validSize(this.width);
    this.element.style.height = validSize(this.height);
    return this;
};

Iframe.prototype.addFailedClass = function() {
    var val;
    if (this.wrapper && ((val = this.wrapper.className.indexOf()) === -1)) {
        this.wrapper.className = val + ' ' + FAILED_CLASS;
    }
};

Iframe.prototype.setData = function (data) {
    this.data = data;
};

Iframe.prototype._getUrl = function(src) {
    var baseUrl = this.iframeUrl;
    if (typeof baseUrl != 'string') {
        throw new Error('iframeUrl must be a string');
    }
    var sep = baseUrl.indexOf('?') !== -1 ? '&' : '?';
    var refresh = src && src.indexOf(REFRESH_KEY) === -1 ? REFRESH_KEY + '=true&' : '';
    return [
        baseUrl,
        sep,
        'ver=', VER,
        '&',
        refresh,
        // Wrapped args in predefined order
        hashData.encode(this.id, {key: this.key, origin: getOrigin(document.location)}, this.data)
    ].join('');
};

Iframe.prototype.refresh = function () {
    this.element.src = this._getUrl(this.element.src);
};

Iframe.prototype.makeIframe = function() {
    var wrapper = this.wrapper = document.createElement('div');
    var i = this.element = document.createElement('iframe');
    var inner = document.createElement('div');
    var classes = [TYPE, TYPE + '-' + this.id];

    if (this.classes) {
        classes.push(this.classes);
    }
    if (this.hidden) {
        classes.push(TYPE + '-hidden');
        wrapper.style.display = 'none';
    }
    //wrapper.id = this.id;
    wrapper.className = (classes.join(' ')).toLowerCase();
    wrapper.setAttribute('data-' + TYPE, this.id);
    i.setAttribute('data-automation-id', this.id);

    i.src = this._getUrl();
    i.className = TYPE + '-iframe';
    // IE 7-8
    i.marginWidth = 0;
    i.marginHeight = 0;
    i.frameBorder = '0';
    i.allowTransparency = 'true';
    // Safari will will not show iframe until scroll with width/height == 0px
    //i.width = validSize(this.width);
    //i.height = this.height;
    i.style.width = validSize(this.width);
    i.style.height = validSize(this.height);
    i.style.border = '0';
    i.style.display = 'block';
    // stop scroll
    i.style.overflow = 'hidden';
    i.scrolling = 'no';

    inner.appendChild(i);
    inner.className = TYPE + '-inner';
    wrapper.appendChild(inner);
    return this;
};

module.exports = Iframe;
<commit_msg>Moved hashData.js to it's own npm package<commit_after>var com          = require('./com.js');
var iframeParams = require('gardr-iframe-params');

var VER = 1;
var TYPE = 'gardr';
var REFRESH_KEY = 'refresh-' + TYPE;
var FAILED_CLASS = TYPE + '-failed';
var SEPARATOR = '_|_';

function validSize(v) {
    if (typeof v === 'string' && v.indexOf('px') !== -1) { return v; }
    if ( (typeof v === 'string' && v.indexOf('%') === -1) || typeof v === 'number') {
        return v + 'px';
    }
    return v;
}

function getOrigin(loc) {
    return loc.origin || (loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port : ''));
}

function Iframe(id, options) {
    this.id = id;
    if (!options || typeof options.iframeUrl === 'undefined') {
        throw new Error('Iframe missing options and iframeUrl');
    }
    this.element = null;
    this.iframeUrl = options.iframeUrl;
    this.width = options.width || '100%';
    this.height = options.height || '100px';
    this.classes = options.classes || '';
    this.hidden = options.hidden;
    this.data = {};
    this.key = options.key || com.PARENT_PREFIX;
}

Iframe.prototype.SEPARATOR = SEPARATOR;
Iframe.prototype.remove = function() {
    this.wrapper.parentNode.removeChild(this.wrapper);
    this.wrapper = null;
    this.element = null;
    return this;
};

Iframe.prototype.resize = function(w, h) {
    if (w) { this.width = w; }
    if (h) { this.height = h; }
    this.element.style.width = validSize(this.width);
    this.element.style.height = validSize(this.height);
    return this;
};

Iframe.prototype.addFailedClass = function() {
    var val;
    if (this.wrapper && ((val = this.wrapper.className.indexOf()) === -1)) {
        this.wrapper.className = val + ' ' + FAILED_CLASS;
    }
};

Iframe.prototype.setData = function (data) {
    this.data = data;
};

Iframe.prototype._getUrl = function(src) {
    var baseUrl = this.iframeUrl;
    if (typeof baseUrl != 'string') {
        throw new Error('iframeUrl must be a string');
    }
    var sep = baseUrl.indexOf('?') !== -1 ? '&' : '?';
    var refresh = src && src.indexOf(REFRESH_KEY) === -1 ? REFRESH_KEY + '=true&' : '';
    return [
        baseUrl,
        sep,
        'ver=', VER,
        '&',
        refresh,
        // Wrapped args in predefined order
        iframeParams.encode(this.id, {key: this.key, origin: getOrigin(document.location)}, this.data)
    ].join('');
};

Iframe.prototype.refresh = function () {
    this.element.src = this._getUrl(this.element.src);
};

Iframe.prototype.makeIframe = function() {
    var wrapper = this.wrapper = document.createElement('div');
    var i = this.element = document.createElement('iframe');
    var inner = document.createElement('div');
    var classes = [TYPE, TYPE + '-' + this.id];

    if (this.classes) {
        classes.push(this.classes);
    }
    if (this.hidden) {
        classes.push(TYPE + '-hidden');
        wrapper.style.display = 'none';
    }
    //wrapper.id = this.id;
    wrapper.className = (classes.join(' ')).toLowerCase();
    wrapper.setAttribute('data-' + TYPE, this.id);
    i.setAttribute('data-automation-id', this.id);

    i.src = this._getUrl();
    i.className = TYPE + '-iframe';
    // IE 7-8
    i.marginWidth = 0;
    i.marginHeight = 0;
    i.frameBorder = '0';
    i.allowTransparency = 'true';
    // Safari will will not show iframe until scroll with width/height == 0px
    //i.width = validSize(this.width);
    //i.height = this.height;
    i.style.width = validSize(this.width);
    i.style.height = validSize(this.height);
    i.style.border = '0';
    i.style.display = 'block';
    // stop scroll
    i.style.overflow = 'hidden';
    i.scrolling = 'no';

    inner.appendChild(i);
    inner.className = TYPE + '-inner';
    wrapper.appendChild(inner);
    return this;
};

module.exports = Iframe;
<|endoftext|>


<commit_before>"use strict";

const _ = require('lodash');
const P = require('bluebird');
const hash = require('./hash');
const readfile = P.promisify(require('fs').readFile);
const Component = require('./foundation').Component;
const coerce = require('./lang').coerce;
const string = require('./string');
const mmm = require('mmmagic');
const Magic = mmm.Magic;
const mime = require('./mime');
const t = require('util').format;
const moment = require('moment');
const sql = require('./sql');
const e = require('./exceptions');
const fs = require('fs');

///////////////////////////////////////////////////////////////////////////

const NotImplemented = e.NotImplemented;
const InvalidType = e.InvalidType;
const InvalidState = e.InvalidState;
const AlreadyOptimized = e.AlreadyOptimized;
const Conflict = e.Conflict;
const NotFound = e.NotFound;

///////////////////////////////////////////////////////////////////////////

/**
 * Manager encapsulates various operations that can be performed on a
 * database table.
 */
const Manager = class Manager extends Component {

  db () {
    return this.get('db') || Manager.db;
  }

  model () {
    return this.get('model');
  }

  table () {
    return this.model().prototype.table();
  }

  /**
   * Return model instances that exactly match the supplied parameters
   * @param {Object} params
   * @return {Array}
   */
  filter (params, options) {
    options = options || {};

    let db = this.db();
    let ModelClass = this.model();
    let table = this.table();
    let bindings = _.map(params, (value, col) => t('`%s` = :%s', col, col));
    let conditionals = bindings.join(' AND ');
    let stmt = t('SELECT * FROM `%s` WHERE %s', table, conditionals);

    if (options.limit) {
      stmt = t('%s %s', stmt, 'LIMIT :limit');
      params.limit = options.limit;
    }

    return new P((resolve, reject) => {
      return db.execute(stmt, params, (err, rows) => {
        err ? reject(err) : resolve(rows.map((row) => new ModelClass(row)));
      });
    });
  }

  /**
   * Count the number of persistent models matching the given parameters
   * @async
   * @param {Object} params
   * @param {Object} options
   * @return {Number}
   */
  count (params, options) {
    options = options || {};

    let db = this.db();
    let ModelClass = this.model();
    let table = ModelClass.prototype.table();
    let bindings = _.map(params, (value, col) => t('`%s` = :%s', col, col));
    let conditionals = bindings.join(' AND ');
    let stmt = t('SELECT COUNT(1) as `aggregate` FROM `%s` WHERE %s', table, conditionals);

    if (options.limit) {
      stmt = t('%s %s', stmt, 'LIMIT :limit');
      params.limit = options.limit;
    }

    return new P((resolve, reject) => {
      return db.execute(stmt, params, (err, rows) => {
        if (err) {
          return reject(err);
        }
        resolve(rows[0].aggregate);
      });
    });
  }

  /**
   * Return a single model instance that matches the given parameters
   * @param {Object} params
   * @param
   */
  first (params, options) {
    let opts = _.defaults({limit: 1}, options || {});

    return this.filter(params, opts)

    .then((models) => {
      let model = models.shift() || null;

      if (!model && opts.fail) {
        throw new NotFound();
      }

      return model;
    });
  }

  /**
   * Return model instances that matches the given primary key
   * @async
   * @param {Object} params
   * @return {Model}
   */
  find (id, options) {
    let opts = _.defaults({fail: false}, options || {});
    let model = this.model().prototype;
    let params = {};

    params[model.pk()] = id;

    return this.first(params, opts);
  }

  /**
   * Create a peristent model instance having the given attributes
   * @async
   * @param {Object} attrs
   * @return {Model}
   */
  create (attrs) {
    let ModelClass = this.model();
    let model = new ModelClass(attrs || {});

    return model.insert();
  }

}

//////////////////
Manager.db = null;
//////////////////

exports.Manager = Manager;

///////////////////////////////////////////////////////////////////////////

/**
 * Model is like an active record object.
 * @class Model
 * @extends foundation:Component
 */
const Model = class Model extends Component {

  /**
   * Return the model manager instance
   * @param void
   * @return {Manager}
   */
  manager () {
    return this.constructor.objects;
  }

  /**
   * Return the mysql2.Connection instance
   * @param void
   * @return {mysql2.Connection}
   */
  db () {
    return this.get('db') || this.manager().db();
  }

  /**
   * Return a string that identifies the model's database table. Subclasses
   * *must* override this.
   * @param void
   * @return {String}
   */
  table () {
    throw new NotImplemented();
  }

  /**
   * Return a string that identifies the primary key.
   * @param void
   * @return {String}
   */
  pk () {
    return 'id';
  }

  /**
   * Return a list of attributes that identify columns in the db table
   * @param void
   * @return {Array}
   */
  columns () {
    return [this.pk()];
  }

  /**
   * Return true if the model has truthy a primary key value
   * @param void
   * @return {Boolean}
   */
  persistent () {
    return Boolean(this.get(this.pk()));
  }

  /**
   * Return a list of db column attributes that have changed since the
   * model was instantiated.
   * @async
   * @param void
   * @return {Array}
   */
  dirty () {
    throw new NotImplemented();
  }

  /**
   * Write model attributes to the database
   * @async
   * @param void
   * @return {Model}
   */
  save () {
    return this.persistent() ? this.update() : this.insert();
  }

  /**
   * Enter a new row in the database table
   * @async
   * @param void
   * @return {Model}
   */
  insert () {
    let db = this.db();
    let table = this.table();
    let columns = this.columns();
    let pk = this.pk();
    let params = {};
    let bindings = [];

    columns.forEach((col) => {
      params[col] = this.get(col);
      bindings.push(t('`%s` = :%s', col, col));
    });

    if (!params[pk]) {
      params[pk] = null;
    }

    let stmt = t('INSERT INTO `%s` SET %s', table, bindings.join(', '));

    return new P((resolve, reject) => {
      db.execute(stmt, params, (err, result) => {
        err ? reject(err) : resolve(result);
      });
    })

    .then((result) => {
      result.insertId && this.set(this.pk(), result.insertId);
      return this;
    })

    .catch((e) => {
      if (e.message.match(/^Duplicate/)) {
        return P.reject(new Conflict(e.message));
      }
      throw e;
    });
  }

  /**
   * Save model attributes to the matching row in the database table
   * @async
   * @param void
   * @return {Model}
   */
  update () {
    throw new NotImplemented();
  }

  /**
   * Remove the matching row in the database table
   * @async
   * @param void
   * @return {}
   */
  delete () {
    if (!this.persistent()) {
      throw new InvalidState('model does not have a primary key');
    }

    let db = this.db();
    let table = this.table();
    let pk = this.pk();
    let stmt = t('DELETE FROM `%s` WHERE `%s` = :%s', table, pk, pk);
    let bindings = {};

    bindings[this.pk()] = this.get(this.pk());

    return new P((resolve, reject) => {
      db.execute(stmt, bindings, (err) => {
        err ? reject(err) : resolve();
      });
    });
  }

}

exports.Model = Model;

///////////////////////////////////////////////////////////////////////////

const SemaphoreManager = class SemaphoreManager extends Manager {

  defaults () {
    return {
      model: Semaphore,
    };
  }

  /**
   * Remove semaphores older than maxage (milliseconds)
   * @async
   * @param {Number}   maxage
   * @param {Date}     now         - for testing
   * @return void
   */
  cleanup (maxage, now) {
    let db = this.db();
    let model = this.get('model').prototype;
    let table = model.table();
    let stmt = t('DELETE FROM `%s` WHERE `created_at` <= ?', table);
    let threshold = moment(now || new Date()).subtract(maxage, 'milliseconds');
    let sqltime = sql.format.datetime(threshold);

    return new P((resolve, reject) => {
      db.execute(stmt, [sqltime], (err, result) => {
        err ? reject(err) : resolve(result);
      });
    })
  }
}

const Semaphore = class Semaphore extends Model {

  table () {
    return 'semaphore';
  }

  defaults () {
    return {
      id: null,
    };
  }

}

Semaphore.objects = new SemaphoreManager({model: Semaphore});

exports.Semaphore = Semaphore;

///////////////////////////////////////////////////////////////////////////

const BlobManager = exports.BlobManager = class BlobManager extends Manager {

  defaults () {
    return {
      model: Blob,
      mime: mime,
      hasher: hash,
      allowed: {
        'image/jpeg': ['jpeg', 'jpg'],
        'image/png': ['png'],
      }
    };
  }

  /**
   * Return an array of JPEG and PNG file glob patterns
   * @param {String} source   optional source directory
   * @return {Array}
   */
  globs (source) {
    return _.flatten(_.map(this.get('allowed'), (exts, type) => {
      return _.map(exts, (ext) => t('%s/**/*.%s', source || '.', ext));
    }))
  }

  /**
   * Return a Blob instance representing the given image path or buffer
   * @async
   * @param {String} source   optional source directory
   * @return {Blob}
   */
  blob (arg) {
    if (arg instanceof Buffer) {
      return this.fromBuffer(arg);
    }
    return this.fromFile(arg);
  }

  /**
   * Return a non-persistent Blob instance representing the given image path
   * @async
   * @param {String} filepath
   * @return {Blob}
   */
  fromFile (filepath) {
    return readfile(filepath).then((buffer) => {
      return this.fromBuffer(buffer);
    });
  }

  /**
   * Return a non-persistent Blob instance representing the given buffer
   * @async
   * @param {Buffer} buffer
   * @return {Blob}
   */
  fromBuffer (buffer) {
    let ModelClass = this.model();
    let allowed = this.get('allowed');
    let mime = this.get('mime');

    return mime.type(buffer).then((type) => {
      if (!allowed.hasOwnProperty(type)) {
        throw new InvalidType('invalid mime type');
      }
    })

    .then(() => {
      return new ModelClass({buffer: buffer});
    })
  }

}

exports.BlobManager = BlobManager;

const Blob = exports.Blob = class Blob extends Model {

  columns () {
    return [this.pk(), 'hash'];
  }

  defaults () {
    return {
      id: null,
      hash: null,
      buffer: null,
      paths: BlobPath.objects,
    };
  }

  table () {
    return 'blob';
  }

  /**
   * Magic setter for the "buffer" attribute. Generate a binary SHA-1 hash digest
   * and assign it to the "hash" attribute.
   * @param {Buffer} value
   * @return {Buffer}
   */
  set buffer (value) {
    let kosher = value instanceof Buffer;

    if (!kosher) {
      throw new InvalidType('expected Buffer instance');
    }

    let hasher = this.manager().get('hasher');

    this.set('hash', hasher.digest(value));

    return value;
  }

  /**
   * Optimize the blob and resolve a Buffer instance that contains the raw
   * optimized image.
   * @async
   * @param {tinify}
   * @return {Blob}
   */
  optimize (tinify) {
    let manager = this.manager();
    let buffer = this.get('buffer');
    let attrs = this.attrs;

    return this.optimized()

    .then((optimized) => {
      if (optimized) {
        let e = new AlreadyOptimized();
        e.blob = optimized;

        throw e;
      }
    })

    .then(() => {
      return tinify.fromBuffer(buffer).toBuffer();
    })

    .then((optimized_buffer) => {
      this.set('buffer', buffer);

      return this.save().then(() => this);
    })
  }

  /**
   * Check whether the blob is already optimized. A blob is considered
   * optimized if its hash exists in the "blob" table. Return the matching
   * blob instance if there is a match on the hash.
   * @async
   * @param void
   * @return {models.Blob}
   */
  optimized () {
    let sum = this.get('hash');

    return this.manager().first({hash: sum}).then((model) => {
      return model;
    });
  }

  /**
   * Return a list of BlobPath objects related to the Blob
   * @async
   * @param {Object} options
   * @return {Promise}
   */
  paths (options) {
    let opts = _.defaults(options || {}, {strings: false});
    let params = {blob_id: this.get('id')};

    return this.get('paths').filter(params).then((blobpaths) => {
      if (opts.strings) {
        return blobpaths.map((blobpath) => blobpath.get('path'));
      }
      return blobpaths;
    });
  }

}

Blob.objects = new BlobManager({model: Blob});

exports.Blob = Blob;

///////////////////////////////////////////////////////////////////////////

const BlobPath = exports.BlobPath = class BlobPath extends Model {

  defaults () {
    return {
      id: null,
      blob_id: null,
      hash: null,
      path: null,
    };
  }

  columns () {
    return [this.pk(), 'blob_id', 'hash', 'path'];
  }

  table () {
    return 'blob_path';
  }

  /**
   * Magic setter for the "path" attribute. Generate a binary SHA-1 sum of the
   * blob path and assign it to the "hash" attribute.
   * @param {String} value
   * @return {String}
   */
  set path (value) {
    this.set('hash', hash.digest(value));
    return value;
  }

  /**
   * Read the contents of the BlobPath into a Buffer. You need to supply
   * the prefix argument since we are storing paths relative to the source directory
   * @async
   * @param {String} prefix  path prefix
   * @param {Object} filesystem   optional filesystem
   * @return {Buffer}
   */
  read (prefix, filesystem) {
    filesystem = filesystem || fs;

    let abspath = path.join(prefix, this.get('path'));

    return new P((resolve, reject) => {
      filesystem.readFile(abspath, 'binary', (err, buffer) => {
        err ? reject(err) : resolve(buffer);
      })
    });
  }

}

BlobPath.objects = new Manager({model: BlobPath});

exports.BlobPath = BlobPath;

///////////////////////////////////////////////////////////////////////////

<commit_msg>bugfix in models.Manager#find()<commit_after>"use strict";

const _ = require('lodash');
const P = require('bluebird');
const hash = require('./hash');
const readfile = P.promisify(require('fs').readFile);
const Component = require('./foundation').Component;
const coerce = require('./lang').coerce;
const string = require('./string');
const mmm = require('mmmagic');
const Magic = mmm.Magic;
const mime = require('./mime');
const t = require('util').format;
const moment = require('moment');
const sql = require('./sql');
const e = require('./exceptions');
const fs = require('fs');

///////////////////////////////////////////////////////////////////////////

const NotImplemented = e.NotImplemented;
const InvalidType = e.InvalidType;
const InvalidState = e.InvalidState;
const AlreadyOptimized = e.AlreadyOptimized;
const Conflict = e.Conflict;
const NotFound = e.NotFound;

///////////////////////////////////////////////////////////////////////////

/**
 * Manager encapsulates various operations that can be performed on a
 * database table.
 */
const Manager = class Manager extends Component {

  db () {
    return this.get('db') || Manager.db;
  }

  model () {
    return this.get('model');
  }

  table () {
    return this.model().prototype.table();
  }

  /**
   * Return model instances that exactly match the supplied parameters
   * @param {Object} params
   * @return {Array}
   */
  filter (params, options) {
    options = options || {};

    let db = this.db();
    let ModelClass = this.model();
    let table = this.table();
    let bindings = _.map(params, (value, col) => t('`%s` = :%s', col, col));
    let conditionals = bindings.join(' AND ');
    let stmt = t('SELECT * FROM `%s` WHERE %s', table, conditionals);

    if (options.limit) {
      stmt = t('%s %s', stmt, 'LIMIT :limit');
      params.limit = options.limit;
    }

    return new P((resolve, reject) => {
      return db.execute(stmt, params, (err, rows) => {
        err ? reject(err) : resolve(rows.map((row) => new ModelClass(row)));
      });
    });
  }

  /**
   * Count the number of persistent models matching the given parameters
   * @async
   * @param {Object} params
   * @param {Object} options
   * @return {Number}
   */
  count (params, options) {
    options = options || {};

    let db = this.db();
    let ModelClass = this.model();
    let table = ModelClass.prototype.table();
    let bindings = _.map(params, (value, col) => t('`%s` = :%s', col, col));
    let conditionals = bindings.join(' AND ');
    let stmt = t('SELECT COUNT(1) as `aggregate` FROM `%s` WHERE %s', table, conditionals);

    if (options.limit) {
      stmt = t('%s %s', stmt, 'LIMIT :limit');
      params.limit = options.limit;
    }

    return new P((resolve, reject) => {
      return db.execute(stmt, params, (err, rows) => {
        if (err) {
          return reject(err);
        }
        resolve(rows[0].aggregate);
      });
    });
  }

  /**
   * Return a single model instance that matches the given parameters
   * @param {Object} params
   * @param
   */
  first (params, options) {
    let opts = _.defaults({limit: 1}, options || {});

    return this.filter(params, opts)

    .then((models) => {
      let model = models.shift() || null;

      if (!model && opts.fail) {
        throw new NotFound();
      }

      return model;
    });
  }

  /**
   * Return model instances that matches the given primary key
   * @async
   * @param {Object} params
   * @return {Model}
   */
  find (id, options) {
    let opts = _.defaults(options || {}, {fail: false});
    let model = this.model().prototype;
    let params = {};

    params[model.pk()] = id;

    return this.first(params, opts);
  }

  /**
   * Create a peristent model instance having the given attributes
   * @async
   * @param {Object} attrs
   * @return {Model}
   */
  create (attrs) {
    let ModelClass = this.model();
    let model = new ModelClass(attrs || {});

    return model.insert();
  }

}

//////////////////
Manager.db = null;
//////////////////

exports.Manager = Manager;

///////////////////////////////////////////////////////////////////////////

/**
 * Model is like an active record object.
 * @class Model
 * @extends foundation:Component
 */
const Model = class Model extends Component {

  /**
   * Return the model manager instance
   * @param void
   * @return {Manager}
   */
  manager () {
    return this.constructor.objects;
  }

  /**
   * Return the mysql2.Connection instance
   * @param void
   * @return {mysql2.Connection}
   */
  db () {
    return this.get('db') || this.manager().db();
  }

  /**
   * Return a string that identifies the model's database table. Subclasses
   * *must* override this.
   * @param void
   * @return {String}
   */
  table () {
    throw new NotImplemented();
  }

  /**
   * Return a string that identifies the primary key.
   * @param void
   * @return {String}
   */
  pk () {
    return 'id';
  }

  /**
   * Return a list of attributes that identify columns in the db table
   * @param void
   * @return {Array}
   */
  columns () {
    return [this.pk()];
  }

  /**
   * Return true if the model has truthy a primary key value
   * @param void
   * @return {Boolean}
   */
  persistent () {
    return Boolean(this.get(this.pk()));
  }

  /**
   * Return a list of db column attributes that have changed since the
   * model was instantiated.
   * @async
   * @param void
   * @return {Array}
   */
  dirty () {
    throw new NotImplemented();
  }

  /**
   * Write model attributes to the database
   * @async
   * @param void
   * @return {Model}
   */
  save () {
    return this.persistent() ? this.update() : this.insert();
  }

  /**
   * Enter a new row in the database table
   * @async
   * @param void
   * @return {Model}
   */
  insert () {
    let db = this.db();
    let table = this.table();
    let columns = this.columns();
    let pk = this.pk();
    let params = {};
    let bindings = [];

    columns.forEach((col) => {
      params[col] = this.get(col);
      bindings.push(t('`%s` = :%s', col, col));
    });

    if (!params[pk]) {
      params[pk] = null;
    }

    let stmt = t('INSERT INTO `%s` SET %s', table, bindings.join(', '));

    return new P((resolve, reject) => {
      db.execute(stmt, params, (err, result) => {
        err ? reject(err) : resolve(result);
      });
    })

    .then((result) => {
      result.insertId && this.set(this.pk(), result.insertId);
      return this;
    })

    .catch((e) => {
      if (e.message.match(/^Duplicate/)) {
        return P.reject(new Conflict(e.message));
      }
      throw e;
    });
  }

  /**
   * Save model attributes to the matching row in the database table
   * @async
   * @param void
   * @return {Model}
   */
  update () {
    throw new NotImplemented();
  }

  /**
   * Remove the matching row in the database table
   * @async
   * @param void
   * @return {}
   */
  delete () {
    if (!this.persistent()) {
      throw new InvalidState('model does not have a primary key');
    }

    let db = this.db();
    let table = this.table();
    let pk = this.pk();
    let stmt = t('DELETE FROM `%s` WHERE `%s` = :%s', table, pk, pk);
    let bindings = {};

    bindings[this.pk()] = this.get(this.pk());

    return new P((resolve, reject) => {
      db.execute(stmt, bindings, (err) => {
        err ? reject(err) : resolve();
      });
    });
  }

}

exports.Model = Model;

///////////////////////////////////////////////////////////////////////////

const SemaphoreManager = class SemaphoreManager extends Manager {

  defaults () {
    return {
      model: Semaphore,
    };
  }

  /**
   * Remove semaphores older than maxage (milliseconds)
   * @async
   * @param {Number}   maxage
   * @param {Date}     now         - for testing
   * @return void
   */
  cleanup (maxage, now) {
    let db = this.db();
    let model = this.get('model').prototype;
    let table = model.table();
    let stmt = t('DELETE FROM `%s` WHERE `created_at` <= ?', table);
    let threshold = moment(now || new Date()).subtract(maxage, 'milliseconds');
    let sqltime = sql.format.datetime(threshold);

    return new P((resolve, reject) => {
      db.execute(stmt, [sqltime], (err, result) => {
        err ? reject(err) : resolve(result);
      });
    })
  }
}

const Semaphore = class Semaphore extends Model {

  table () {
    return 'semaphore';
  }

  defaults () {
    return {
      id: null,
    };
  }

}

Semaphore.objects = new SemaphoreManager({model: Semaphore});

exports.Semaphore = Semaphore;

///////////////////////////////////////////////////////////////////////////

const BlobManager = exports.BlobManager = class BlobManager extends Manager {

  defaults () {
    return {
      model: Blob,
      mime: mime,
      hasher: hash,
      allowed: {
        'image/jpeg': ['jpeg', 'jpg'],
        'image/png': ['png'],
      }
    };
  }

  /**
   * Return an array of JPEG and PNG file glob patterns
   * @param {String} source   optional source directory
   * @return {Array}
   */
  globs (source) {
    return _.flatten(_.map(this.get('allowed'), (exts, type) => {
      return _.map(exts, (ext) => t('%s/**/*.%s', source || '.', ext));
    }))
  }

  /**
   * Return a Blob instance representing the given image path or buffer
   * @async
   * @param {String} source   optional source directory
   * @return {Blob}
   */
  blob (arg) {
    if (arg instanceof Buffer) {
      return this.fromBuffer(arg);
    }
    return this.fromFile(arg);
  }

  /**
   * Return a non-persistent Blob instance representing the given image path
   * @async
   * @param {String} filepath
   * @return {Blob}
   */
  fromFile (filepath) {
    return readfile(filepath).then((buffer) => {
      return this.fromBuffer(buffer);
    });
  }

  /**
   * Return a non-persistent Blob instance representing the given buffer
   * @async
   * @param {Buffer} buffer
   * @return {Blob}
   */
  fromBuffer (buffer) {
    let ModelClass = this.model();
    let allowed = this.get('allowed');
    let mime = this.get('mime');

    return mime.type(buffer).then((type) => {
      if (!allowed.hasOwnProperty(type)) {
        throw new InvalidType('invalid mime type');
      }
    })

    .then(() => {
      return new ModelClass({buffer: buffer});
    })
  }

}

exports.BlobManager = BlobManager;

const Blob = exports.Blob = class Blob extends Model {

  columns () {
    return [this.pk(), 'hash'];
  }

  defaults () {
    return {
      id: null,
      hash: null,
      buffer: null,
      paths: BlobPath.objects,
    };
  }

  table () {
    return 'blob';
  }

  /**
   * Magic setter for the "buffer" attribute. Generate a binary SHA-1 hash digest
   * and assign it to the "hash" attribute.
   * @param {Buffer} value
   * @return {Buffer}
   */
  set buffer (value) {
    let kosher = value instanceof Buffer;

    if (!kosher) {
      throw new InvalidType('expected Buffer instance');
    }

    let hasher = this.manager().get('hasher');

    this.set('hash', hasher.digest(value));

    return value;
  }

  /**
   * Optimize the blob and resolve a Buffer instance that contains the raw
   * optimized image.
   * @async
   * @param {tinify}
   * @return {Blob}
   */
  optimize (tinify) {
    let manager = this.manager();
    let buffer = this.get('buffer');
    let attrs = this.attrs;

    return this.optimized()

    .then((optimized) => {
      if (optimized) {
        let e = new AlreadyOptimized();
        e.blob = optimized;

        throw e;
      }
    })

    .then(() => {
      return tinify.fromBuffer(buffer).toBuffer();
    })

    .then((optimized_buffer) => {
      this.set('buffer', buffer);

      return this.save().then(() => this);
    })
  }

  /**
   * Check whether the blob is already optimized. A blob is considered
   * optimized if its hash exists in the "blob" table. Return the matching
   * blob instance if there is a match on the hash.
   * @async
   * @param void
   * @return {models.Blob}
   */
  optimized () {
    let sum = this.get('hash');

    return this.manager().first({hash: sum}).then((model) => {
      return model;
    });
  }

  /**
   * Return a list of BlobPath objects related to the Blob
   * @async
   * @param {Object} options
   * @return {Promise}
   */
  paths (options) {
    let opts = _.defaults(options || {}, {strings: false});
    let params = {blob_id: this.get('id')};

    return this.get('paths').filter(params).then((blobpaths) => {
      if (opts.strings) {
        return blobpaths.map((blobpath) => blobpath.get('path'));
      }
      return blobpaths;
    });
  }

}

Blob.objects = new BlobManager({model: Blob});

exports.Blob = Blob;

///////////////////////////////////////////////////////////////////////////

const BlobPath = exports.BlobPath = class BlobPath extends Model {

  defaults () {
    return {
      id: null,
      blob_id: null,
      hash: null,
      path: null,
    };
  }

  columns () {
    return [this.pk(), 'blob_id', 'hash', 'path'];
  }

  table () {
    return 'blob_path';
  }

  /**
   * Magic setter for the "path" attribute. Generate a binary SHA-1 sum of the
   * blob path and assign it to the "hash" attribute.
   * @param {String} value
   * @return {String}
   */
  set path (value) {
    this.set('hash', hash.digest(value));
    return value;
  }

  /**
   * Read the contents of the BlobPath into a Buffer. You need to supply
   * the prefix argument since we are storing paths relative to the source directory
   * @async
   * @param {String} prefix  path prefix
   * @param {Object} filesystem   optional filesystem
   * @return {Buffer}
   */
  read (prefix, filesystem) {
    filesystem = filesystem || fs;

    let abspath = path.join(prefix, this.get('path'));

    return new P((resolve, reject) => {
      filesystem.readFile(abspath, 'binary', (err, buffer) => {
        err ? reject(err) : resolve(buffer);
      })
    });
  }

}

BlobPath.objects = new Manager({model: BlobPath});

exports.BlobPath = BlobPath;

///////////////////////////////////////////////////////////////////////////

<|endoftext|>


<commit_before>import {getDocument} from 'pdfjs-dist/webpack'
import {PDFJS} from 'pdfjs-dist/web/pdf_viewer'
import 'pdfjs-dist/web/compatibility'
import shortid from 'shortid'
import {fabric} from 'fabric'
import normalizeWheel from './normalizeWheel'

PDFJS.disableTextLayer = true
const {PDFViewer} = PDFJS
const CSS_UNITS = 96.0 / 72.0

function Viewer(container, options = {}) {
  const self = this

  self.load = load

  const viewerElem = document.createElement("div")
  viewerElem.id = shortid.generate()
  // viewerElem.style.border = "medium dotted yellow"
  viewerElem.style.position = 'absolute'
  // viewerElem.style.width = container.style.width
  // viewerElem.style.height = container.clientHeight || 500
  // viewerElem.style.overflow = 'auto'
  container.appendChild(viewerElem)

  let viewport = null
  let pinCanvas = null
  let page = null

  const pdfViewer = new PDFViewer({
    container,
    viewer: viewerElem,
  })

  function load(url) {
    return getDocument(url)
      .then(pdf => {
        return pdf.getPage(1)
          .then(data => {
            page = data
            viewport = page.getViewport(1)
            const scale = (container.clientWidth / viewport.width) / CSS_UNITS  //
            viewport = page.getViewport(scale)
            return pdfViewer.setDocument(pdf)
              .then(() => {
                pdfViewer.currentScale = scale
                initPinCanvas(viewport.width * CSS_UNITS, viewport.height * CSS_UNITS)
              })
          })
      })
  }

  function initPinCanvas(width, height) {

    const canvasElem = document.createElement("canvas")
    canvasElem.id = shortid.generate()
    canvasElem.width = width
    canvasElem.height = height
    // canvasElem.style.border = "medium dashed green"
    container.appendChild(canvasElem)

    pinCanvas = new fabric.Canvas(canvasElem.id)
    fabric.Object.prototype.transparentCorners = false

    pinCanvas.on('mouse:dblclick', e => {
      const point = pinCanvas.getPointer(e.e)
      // const point = {x: e.e.offsetX, y: e.e.offsetY}
      addPin(point)
    })

    pinCanvas.on('mouse:wheel', e => {
      const delta = normalizeWheel(e.e).pixelY / 3600
      zoomIn(delta)

      viewport = page.getViewport(pdfViewer.currentScale)
      pinCanvas.getObjects().forEach(obj => {
        obj.set('top', viewport.height * obj.topRange)
        obj.set('left', viewport.width * obj.leftRange)
        obj.setCoords()

        // const [x, y] = obj.pdfPoint
        // const [top, left] = viewport.convertToViewportPoint(x, y)
        // obj.set('top', top - obj.height)
        // obj.set('left', left - obj.width / 2)
      })
      pinCanvas.renderAll()
    })
  }

  function addPin(point) {
    new fabric.Image.fromURL('../data/location.png', imgInstance => {
      let top = point.y - imgInstance.height
      let left = point.x - imgInstance.width / 2
      imgInstance.top = top
      imgInstance.left = left
      imgInstance.lockUniScaling = true
      imgInstance.lockRotation = true
      imgInstance.topRange = top / viewport.height
      imgInstance.leftRange = left / viewport.width
      imgInstance.opacity = 0.85
      // imgInstance.setCoords()
      imgInstance.cornerColor = 'green'

      // const pdfPoint = viewport.convertToPdfPoint(point.x, point.y)
      // imgInstance.pdfPoint = pdfPoint
      pinCanvas.add(imgInstance)

      imgInstance.on('selected', e => {
        console.log('event: selected')
      })

      imgInstance.on('moving', e => {
        const point = pinCanvas.getPointer(e.e)
        // imgInstance.set('top', point.y - imgInstance.height)
        // imgInstance.set('left', point.x - imgInstance.width / 2)
        imgInstance.topRange = imgInstance.top / viewport.height
        imgInstance.leftRange = imgInstance.left / viewport.width
        imgInstance.setCoords()
        console.log('event: moving')
      })

    })

  }

  // function zoomOut(delta) {
  // }

  function zoomIn(delta) {
    const currentScale = pdfViewer.currentScale
    const newScale = currentScale + delta
    const factor = newScale / currentScale
    pdfViewer.currentScale = newScale

    const height = pinCanvas.getHeight()
    const width = pinCanvas.getWidth()
    pinCanvas.setHeight(height * factor);
    pinCanvas.setWidth(width * factor);
    pinCanvas.renderAll();
    pinCanvas.calcOffset();
  }
}

module.exports = Viewer
<commit_msg>update code<commit_after>import {getDocument} from 'pdfjs-dist/webpack'
import {PDFJS} from 'pdfjs-dist/web/pdf_viewer'
import 'pdfjs-dist/web/compatibility'
import shortid from 'shortid'
import {fabric} from 'fabric'
import normalizeWheel from './normalizeWheel'

PDFJS.disableTextLayer = true
const {PDFViewer} = PDFJS
const CSS_UNITS = 96.0 / 72.0

function Viewer(container, options = {}) {
  const self = this

  self.load = load

  const viewerElem = document.createElement("div")
  viewerElem.id = shortid.generate()
  // viewerElem.style.border = "medium dotted yellow"
  viewerElem.style.position = 'absolute'
  // viewerElem.style.width = container.style.width
  // viewerElem.style.height = container.clientHeight || 500
  // viewerElem.style.overflow = 'auto'
  container.appendChild(viewerElem)

  let viewport = null
  let pinCanvas = null
  let page = null

  const pdfViewer = new PDFViewer({
    container,
    viewer: viewerElem,
  })

  function load(url) {
    return getDocument(url)
      .then(pdf => {
        return pdf.getPage(1)
          .then(data => {
            page = data
            viewport = page.getViewport(1)
            const scale = (container.clientWidth / viewport.width) / CSS_UNITS  //
            viewport = page.getViewport(scale)
            return pdfViewer.setDocument(pdf)
              .then(() => {
                pdfViewer.currentScale = scale
                initPinCanvas(viewport.width * CSS_UNITS, viewport.height * CSS_UNITS)
              })
          })
      })
  }

  function initPinCanvas(width, height) {

    const canvasElem = document.createElement("canvas")
    canvasElem.id = shortid.generate()
    canvasElem.width = width
    canvasElem.height = height
    // canvasElem.style.border = "medium dashed green"
    container.appendChild(canvasElem)

    pinCanvas = new fabric.Canvas(canvasElem.id)
    fabric.Object.prototype.transparentCorners = false

    pinCanvas.on('mouse:dblclick', e => {
      const point = pinCanvas.getPointer(e.e)
      // const point = {x: e.e.offsetX, y: e.e.offsetY}
      addPin(point)
    })

    pinCanvas.on('mouse:wheel', e => {
      const delta = normalizeWheel(e.e).pixelY / 3600
      zoomIn(delta)

      viewport = page.getViewport(pdfViewer.currentScale)
      pinCanvas.getObjects().forEach(obj => {
        obj.set('top', viewport.height * obj.topRate - obj.height)
        obj.set('left', viewport.width * obj.leftRate - obj.width / 2)
        obj.setCoords()

        // const [x, y] = obj.pdfPoint
        // const [top, left] = viewport.convertToViewportPoint(x, y)
        // obj.set('top', top - obj.height)
        // obj.set('left', left - obj.width / 2)
      })
      pinCanvas.renderAll()
    })
  }

  function addPin(point) {
    new fabric.Image.fromURL('../data/location.png', imgInstance => {
      imgInstance.top = point.y - imgInstance.height
      imgInstance.left = point.x - imgInstance.width / 2
      imgInstance.lockUniScaling = true
      imgInstance.lockRotation = true
      imgInstance.topRate = point.y / viewport.height
      imgInstance.leftRate = point.x / viewport.width
      imgInstance.opacity = 0.85
      // imgInstance.setCoords()
      imgInstance.cornerColor = 'green'

      // const pdfPoint = viewport.convertToPdfPoint(point.x, point.y)
      // imgInstance.pdfPoint = pdfPoint
      pinCanvas.add(imgInstance)

      imgInstance.on('selected', e => {
        console.log('event: selected')
      })

      imgInstance.on('moving', e => {
        imgInstance.topRate = (imgInstance.top + imgInstance.height) / viewport.height
        imgInstance.leftRate = (imgInstance.left + imgInstance.width / 2) / viewport.width
        imgInstance.setCoords()
        console.log('event: moving')
      })

    })

  }

  // function zoomOut(delta) {
  // }

  function zoomIn(delta) {
    const currentScale = pdfViewer.currentScale
    const newScale = currentScale + delta
    const factor = newScale / currentScale
    pdfViewer.currentScale = newScale

    const height = pinCanvas.getHeight()
    const width = pinCanvas.getWidth()
    pinCanvas.setHeight(height * factor);
    pinCanvas.setWidth(width * factor);
    pinCanvas.renderAll();
    pinCanvas.calcOffset();
  }
}

module.exports = Viewer
<|endoftext|>


<commit_before>"use strict"

const app = require('app')
const BrowserWindow = require('browser-window')
const Menu = require('menu')
const shell = require('shell')
const googleAuth = require('./googleAuth')
const constants = require('../shared/constants')
const update = require('./update')
const appMenu = require('./appMenu')
const ipcMain = require('electron').ipcMain

class WMail {

	/*****************************************************************************/
	// Lifecycle
	/*****************************************************************************/

	/**
	* @param injected items
	*/
  constructor(injection) {
  	this.analytics = injection.analytics
  	this.localStorage = injection.localStorage
    this.mailboxWindow = null
    this.fullQuit = null
    this.mailboxWindowSaver = null
    this.appMenuSelectors = {
	    fullQuit : () => { this.fullQuit = true; app.quit() },
	    fullscreenToggle : () => { this.mailboxWindow.setFullScreen(!this.mailboxWindow.isFullScreen()) },
	    reload : () => { this.mailboxWindow.webContents.reload() },
	    devTools : () => { this.mailboxWindow.webContents.openDevTools() },
	    learnMore : () => { shell.openExternal(constants.GITHUB_URL) },
	    bugReport : () => { shell.openExternal(constants.GITHUB_ISSUE_URL) },
	    hide : () => {
        this.mailboxWindow.hide()
      },
	    zoomIn : () => { this.mailboxWindow.webContents.send('mailbox-zoom-in', { }) },
	    zoomOut : () => { this.mailboxWindow.webContents.send('mailbox-zoom-out', { }) },
	    zoomReset : () => { this.mailboxWindow.webContents.send('mailbox-zoom-reset', { }) },
	    mailbox : (mailboxId) => {
	      this.mailboxWindow.webContents.send('switch-mailbox', {mailboxId:mailboxId })
	    }
	  }
  }

  /**
  * Starts the app
  */
  start() {
  	this.createMailboxWindow()
  	this.createAppMenu()
  	this.listenToIPC()
  	this.startUpdatesAnalytics()
  }

  /*****************************************************************************/
	// Mailbox window
	/*****************************************************************************/

	/**
	* Creates and shows the mailbox window
	*/
  createMailboxWindow() {
  	this.mailboxWindow = new BrowserWindow(Object.assign({
	    minWidth          : 955,
	    minHeight         : 400,
	    titleBarStyle     : 'hidden',
	    title             : 'Mailbox',
	    webPreferences: {
	      nodeIntegration : true
	    }
	  }, this.loadWindowState()))
	  this.mailboxWindow.loadURL('file://' + __dirname + '/../mailbox.html')

	  //Bind to window events
	  this.mailboxWindow.on('close', (evt) => {
	    if (this.mailboxWindow.isFocused() && !this.fullQuit) {
	      evt.preventDefault()
	      this.mailboxWindow.hide()
	    }
	  })
	  this.mailboxWindow.on('closed', (evt) => {
	    this.mailboxWindow = null
	    app.quit()
	  })
	  this.mailboxWindow.on('resize', (evt) => {
	  	this.saveWindowState()
	  })
	  this.mailboxWindow.on('move', (evt) => {
	  	this.saveWindowState()
	  })
  }

  /**
  * Saves the window state to disk
  */
  saveWindowState() {
  	clearTimeout(this.mailboxWindowSaver)
  	this.mailboxWindowSaver = setTimeout(() => {
  		const state = {
  			fullscreen : this.mailboxWindow.isMaximized()
  		}
  		if (!this.mailboxWindow.isMaximized() && !this.mailboxWindow.isMinimized()) {
	  		const position = this.mailboxWindow.getPosition()
	  		const size = this.mailboxWindow.getSize();
	  		state.x = position[0]
	  		state.y = position[1]
	  		state.width = size[0]
	  		state.height = size[1]
	  	}

	  	this.localStorage.setItem('mailbox_window_state', JSON.stringify(state))
  	}, 2000)
  }

  /**
  * Loads the window state
  * @return the state
  */
  loadWindowState() {
  	if (this.localStorage.getItem('mailbox_window_state')) {
  		return JSON.parse(this.localStorage.getItem('mailbox_window_state'))
  	} else {
  		return {
  			width: 1024,
  			height: 600,
  			fullscreen: false
  		}
  	}
  }

  /*****************************************************************************/
	// App Menu
	/*****************************************************************************/

	/**
	* Creates the app menu and corresponding shortcuts
	*/
  createAppMenu() {
	  Menu.setApplicationMenu(appMenu.build(this.appMenuSelectors, []))
	  appMenu.bindHiddenShortcuts(this.appMenuSelectors)
  }

  /*****************************************************************************/
	// IPC
	/*****************************************************************************/

	/**
	* Listens to the render from
	*/
  listenToIPC() {
  	ipcMain.on('mailboxes-changed', (evt, body) => {
	    Menu.setApplicationMenu(appMenu.build(this.appMenuSelectors, body.mailboxes))
	  })
  }

  /*****************************************************************************/
	// App
	/*****************************************************************************/

	/**
	* Starts the update checker and analytics
	*/
  startUpdatesAnalytics() {
	  update.checkNow(this.mailboxWindow)
	  this.analytics.appOpened(this.mailboxWindow)
	  setInterval(() => {
	    this.analytics.appHeartbeat(this.mailboxWindow)
	  }, 1000 * 60 * 5) // 5 mins
  }
}

module.exports = WMail<commit_msg>Removed now unised hide command<commit_after>"use strict"

const app = require('app')
const BrowserWindow = require('browser-window')
const Menu = require('menu')
const shell = require('shell')
const googleAuth = require('./googleAuth')
const constants = require('../shared/constants')
const update = require('./update')
const appMenu = require('./appMenu')
const ipcMain = require('electron').ipcMain

class WMail {

	/*****************************************************************************/
	// Lifecycle
	/*****************************************************************************/

	/**
	* @param injected items
	*/
  constructor(injection) {
  	this.analytics = injection.analytics
  	this.localStorage = injection.localStorage
    this.mailboxWindow = null
    this.fullQuit = null
    this.mailboxWindowSaver = null
    this.appMenuSelectors = {
	    fullQuit : () => { this.fullQuit = true; app.quit() },
	    fullscreenToggle : () => { this.mailboxWindow.setFullScreen(!this.mailboxWindow.isFullScreen()) },
	    reload : () => { this.mailboxWindow.webContents.reload() },
	    devTools : () => { this.mailboxWindow.webContents.openDevTools() },
	    learnMore : () => { shell.openExternal(constants.GITHUB_URL) },
	    bugReport : () => { shell.openExternal(constants.GITHUB_ISSUE_URL) },
	    zoomIn : () => { this.mailboxWindow.webContents.send('mailbox-zoom-in', { }) },
	    zoomOut : () => { this.mailboxWindow.webContents.send('mailbox-zoom-out', { }) },
	    zoomReset : () => { this.mailboxWindow.webContents.send('mailbox-zoom-reset', { }) },
	    mailbox : (mailboxId) => {
	      this.mailboxWindow.webContents.send('switch-mailbox', {mailboxId:mailboxId })
	    }
	  }
  }

  /**
  * Starts the app
  */
  start() {
  	this.createMailboxWindow()
  	this.createAppMenu()
  	this.listenToIPC()
  	this.startUpdatesAnalytics()
  }

  /*****************************************************************************/
	// Mailbox window
	/*****************************************************************************/

	/**
	* Creates and shows the mailbox window
	*/
  createMailboxWindow() {
  	this.mailboxWindow = new BrowserWindow(Object.assign({
	    minWidth          : 955,
	    minHeight         : 400,
	    titleBarStyle     : 'hidden',
	    title             : 'Mailbox',
	    webPreferences: {
	      nodeIntegration : true
	    }
	  }, this.loadWindowState()))
	  this.mailboxWindow.loadURL('file://' + __dirname + '/../mailbox.html')

	  //Bind to window events
	  this.mailboxWindow.on('close', (evt) => {
	    if (this.mailboxWindow.isFocused() && !this.fullQuit) {
	      evt.preventDefault()
	      this.mailboxWindow.hide()
	    }
	  })
	  this.mailboxWindow.on('closed', (evt) => {
	    this.mailboxWindow = null
	    app.quit()
	  })
	  this.mailboxWindow.on('resize', (evt) => {
	  	this.saveWindowState()
	  })
	  this.mailboxWindow.on('move', (evt) => {
	  	this.saveWindowState()
	  })
  }

  /**
  * Saves the window state to disk
  */
  saveWindowState() {
  	clearTimeout(this.mailboxWindowSaver)
  	this.mailboxWindowSaver = setTimeout(() => {
  		const state = {
  			fullscreen : this.mailboxWindow.isMaximized()
  		}
  		if (!this.mailboxWindow.isMaximized() && !this.mailboxWindow.isMinimized()) {
	  		const position = this.mailboxWindow.getPosition()
	  		const size = this.mailboxWindow.getSize();
	  		state.x = position[0]
	  		state.y = position[1]
	  		state.width = size[0]
	  		state.height = size[1]
	  	}

	  	this.localStorage.setItem('mailbox_window_state', JSON.stringify(state))
  	}, 2000)
  }

  /**
  * Loads the window state
  * @return the state
  */
  loadWindowState() {
  	if (this.localStorage.getItem('mailbox_window_state')) {
  		return JSON.parse(this.localStorage.getItem('mailbox_window_state'))
  	} else {
  		return {
  			width: 1024,
  			height: 600,
  			fullscreen: false
  		}
  	}
  }

  /*****************************************************************************/
	// App Menu
	/*****************************************************************************/

	/**
	* Creates the app menu and corresponding shortcuts
	*/
  createAppMenu() {
	  Menu.setApplicationMenu(appMenu.build(this.appMenuSelectors, []))
	  appMenu.bindHiddenShortcuts(this.appMenuSelectors)
  }

  /*****************************************************************************/
	// IPC
	/*****************************************************************************/

	/**
	* Listens to the render from
	*/
  listenToIPC() {
  	ipcMain.on('mailboxes-changed', (evt, body) => {
	    Menu.setApplicationMenu(appMenu.build(this.appMenuSelectors, body.mailboxes))
	  })
  }

  /*****************************************************************************/
	// App
	/*****************************************************************************/

	/**
	* Starts the update checker and analytics
	*/
  startUpdatesAnalytics() {
	  update.checkNow(this.mailboxWindow)
	  this.analytics.appOpened(this.mailboxWindow)
	  setInterval(() => {
	    this.analytics.appHeartbeat(this.mailboxWindow)
	  }, 1000 * 60 * 5) // 5 mins
  }
}

module.exports = WMail<|endoftext|>


<commit_before>var touch = require('touch')
var spawn = require('child_process').spawn

// flow control is fun!
function queue () {
  var args = [].slice.call(arguments)
  var cb = args.pop()
  go(args.shift())
  function go (fn) {
    if (!fn) return cb()
    fn(function (er) {
      if (er) return cb(er)
      go(args.shift())
    })
  }
}

var children = []
function exec (cmd, args, wait, cb) {
  if (typeof wait === 'function') cb = wait, wait = 200
  var opts = {stdio:'inherit'}
  // windows is kind of a jerk sometimes.
  if (process.platform === 'win32') {
    args = ['/c', '/s', '"' + args.map(JSON.stringify).join(' ') + '"']
    cmd = 'cmd'
    opts.windowsVerbatimArguments = true
  }
  var child = spawn(cmd, args, opts)
  var called = false

  var timer = setTimeout(function () {
    called = true
    cb()
  }, wait)

  child.on('exit', function (code) {
    if (wait) return cb(code)
    clearTimeout(timer)
    if (code) {
      msg = cmd + ' ' + args.join(' ') + ' fell over: '+code
      console.error(msg)
      if (!called) cb(new Error(msg))
    }
  })
  children.push(child)
}

queue(function (cb) {
  // first, make sure that we have the databases, or replicate will fail
  touch('dev/couch/registry.couch', cb)

}, function (cb) {
  touch('dev/couch/public_users.couch', cb)

}, function (cb) {
  // spawn couchdb, and make sure it stays up for a little bit
  exec('couchdb', ['-a', 'dev/couch/couch.ini'], cb)

}, function (cb) {
  // do the same for redis.
  exec('redis-server', ['dev/redis/redis.conf'], cb)

}, function (cb) {
  // give it a few seconds to download some interesting data.
  // otherwise the site is pretty empty.
  exec(process.execPath, [require.resolve('./replicate.js')], 5000, cb)

}, function (er) {
  if (er) throw er

  console.error('\n\n\nSTARTING DEV SITE NOW\n\n\n')

  // force the configs to be pointed at our local redis and couchdb.
  var config = {}
  config.couchAuth = 'admin:admin'
  config.registryCouch = 'http://localhost:15984/'
  config.registryCouch = 'http://localhost:15984/'
  config.redis = { host: '127.0.0.1', port: 16379 }
  config.redisAuth = 'i-am-using-redis-in-development-mode-for-npm-www'
  config.keys = ['these keys are for dev mode only']

  // TODO:
  // set expots.mailTransPortType and exports.mailTransportSettings
  // so that it'll send email using the localhost's sendmail, maybe?

  // fakey fake SSL certs for convenience.
  var fs = require('fs')
  config.https = {
    key: fs.readFileSync(require.resolve('./ssl/server.key'), 'utf8'),
    cert: fs.readFileSync(require.resolve('./ssl/server.crt'), 'utf8')
  }

  config.port = 15443
  config.host = 'localhost'
  config.httpPort = 15080

  config.npm = config.npm || {
    registry: 'http://127.0.0.1:15984/',
    'strict-ssl': false,
    loglevel: 'warn',
    username: '',
    _password: '',
    _auth: '',
    _token: ''
  }

  config.debug = true

  // write to the dev admin config.
  fs.writeFileSync('config.dev.js',
                   'module.exports = ' + JSON.stringify(config, null, 2),
                   'utf8')

  process.env.NODE_ENV = 'dev'

  // now we've replicated everything, and set up the configs,
  // and it worked, so start up the master http server.
  require('../server.js')
})
<commit_msg>Add cmd to args array<commit_after>var touch = require('touch')
var spawn = require('child_process').spawn

// flow control is fun!
function queue () {
  var args = [].slice.call(arguments)
  var cb = args.pop()
  go(args.shift())
  function go (fn) {
    if (!fn) return cb()
    fn(function (er) {
      if (er) return cb(er)
      go(args.shift())
    })
  }
}

var children = []
function exec (cmd, args, wait, cb) {
  if (typeof wait === 'function') cb = wait, wait = 200
  var opts = {stdio:'inherit'}
  // windows is kind of a jerk sometimes.
  if (process.platform === 'win32') {
    args = [cmd].concat(args)
    args = ['/c', '/s', '"' + args.map(JSON.stringify).join(' ') + '"']
    cmd = 'cmd'
    opts.windowsVerbatimArguments = true
  }
  var child = spawn(cmd, args, opts)
  var called = false

  var timer = setTimeout(function () {
    called = true
    cb()
  }, wait)

  child.on('exit', function (code) {
    if (wait) return cb(code)
    clearTimeout(timer)
    if (code) {
      msg = cmd + ' ' + args.join(' ') + ' fell over: '+code
      console.error(msg)
      if (!called) cb(new Error(msg))
    }
  })
  children.push(child)
}

queue(function (cb) {
  // first, make sure that we have the databases, or replicate will fail
  touch('dev/couch/registry.couch', cb)

}, function (cb) {
  touch('dev/couch/public_users.couch', cb)

}, function (cb) {
  // spawn couchdb, and make sure it stays up for a little bit
  exec('couchdb', ['-a', 'dev/couch/couch.ini'], cb)

}, function (cb) {
  // do the same for redis.
  exec('redis-server', ['dev/redis/redis.conf'], cb)

}, function (cb) {
  // give it a few seconds to download some interesting data.
  // otherwise the site is pretty empty.
  exec(process.execPath, [require.resolve('./replicate.js')], 5000, cb)

}, function (er) {
  if (er) throw er

  console.error('\n\n\nSTARTING DEV SITE NOW\n\n\n')

  // force the configs to be pointed at our local redis and couchdb.
  var config = {}
  config.couchAuth = 'admin:admin'
  config.registryCouch = 'http://localhost:15984/'
  config.registryCouch = 'http://localhost:15984/'
  config.redis = { host: '127.0.0.1', port: 16379 }
  config.redisAuth = 'i-am-using-redis-in-development-mode-for-npm-www'
  config.keys = ['these keys are for dev mode only']

  // TODO:
  // set expots.mailTransPortType and exports.mailTransportSettings
  // so that it'll send email using the localhost's sendmail, maybe?

  // fakey fake SSL certs for convenience.
  var fs = require('fs')
  config.https = {
    key: fs.readFileSync(require.resolve('./ssl/server.key'), 'utf8'),
    cert: fs.readFileSync(require.resolve('./ssl/server.crt'), 'utf8')
  }

  config.port = 15443
  config.host = 'localhost'
  config.httpPort = 15080

  config.npm = config.npm || {
    registry: 'http://127.0.0.1:15984/',
    'strict-ssl': false,
    loglevel: 'warn',
    username: '',
    _password: '',
    _auth: '',
    _token: ''
  }

  config.debug = true

  // write to the dev admin config.
  fs.writeFileSync('config.dev.js',
                   'module.exports = ' + JSON.stringify(config, null, 2),
                   'utf8')

  process.env.NODE_ENV = 'dev'

  // now we've replicated everything, and set up the configs,
  // and it worked, so start up the master http server.
  require('../server.js')
})
<|endoftext|>


<commit_before>const logging = require('../../../../../shared/logging');

// settings with new groups
const typeGroupMapping = [{
    keys: [
        'members_public_key',
        'members_private_key',
        'members_email_auth_secret'
    ],
    from: 'members',
    to: 'core'
}, {
    keys: [
        'title',
        'description',
        'logo',
        'cover_image',
        'icon',
        'accent_color',
        'lang',
        'timezone',
        'codeinjection_head',
        'codeinjection_foot',
        'facebook',
        'twitter',
        'navigation',
        'secondary_navigation',
        'meta_title',
        'meta_description',
        'og_image',
        'og_title',
        'og_description',
        'twitter_image',
        'twitter_title',
        'twitter_description'

    ],
    from: 'blog',
    to: 'site'
}, {
    keys: ['amp'],
    from: 'blog',
    to: 'amp'
}, {
    keys: ['labs'],
    from: 'blog',
    to: 'labs'
}, {
    keys: ['slack'],
    from: 'blog',
    to: 'slack'
}, {
    keys: ['unsplash'],
    from: 'blog',
    to: 'unsplash'
}, {
    keys: ['shared_views'],
    from: 'blog',
    to: 'views'
}, {
    keys: ['bulk_email_settings'],
    from: 'bulk_email',
    to: 'email'
}];

// settings with the same groups
const groupMapping = [{
    group: 'core',
    keys: [
        'db_hash',
        'next_update_check',
        'notifications',
        'session_secret',
        'theme_session_secret',
        'ghost_public_key',
        'ghost_private_key'
    ]
}, {
    group: 'theme',
    keys: ['active_theme']
}, {
    group: 'private',
    keys: [
        'is_private',
        'password',
        'public_hash'
    ]
}, {
    group: 'members',
    keys: [
        'default_content_visibility',
        'members_subscription_settings',
        'stripe_connect_integration'
    ]
}, {
    group: 'portal',
    keys: [
        'portal_name',
        'portal_button',
        'portal_plans'
    ]
}];

// flags to be added to settings
const flagMapping = [{
    key: 'title',
    flags: 'PUBLIC'
}, {
    key: 'description',
    flags: 'PUBLIC'
}, {
    key: 'accent_color',
    flags: 'PUBLIC'
}, {
    key: 'active_theme',
    flags: 'RO'
}];

module.exports = {
    config: {
        transaction: true
    },

    async up(options) {
        // set the new group for each changed setting and rename type
        await Promise.map(typeGroupMapping, async (typeGroupMap) => {
            return await Promise.map(typeGroupMap.keys, async (key) => {
                logging.info(`Moving setting ${key} from ${typeGroupMap.from} to ${typeGroupMap.to}`);

                return await options
                    .transacting('settings')
                    .where('key', key)
                    .update({
                        group: typeGroupMap.to,
                        type: typeGroupMap.to
                    });
            });
        });

        // set the correct group value settings which aren't changing type
        await Promise.map(groupMapping, async (groupMap) => {
            return await Promise.map(groupMap.keys, async (key) => {
                logging.info(`Adding setting ${key} to ${groupMap.group}`);

                return await options
                    .transacting('settings')
                    .where('key', key)
                    .update({
                        group: groupMap.group
                    });
            });
        });

        return await Promise.map(flagMapping, async (flagMap) => {
            logging.info(`Adding ${flagMap.flags} flag to ${flagMap.key} setting`);

            return await options
                .transacting('settings')
                .where('key', flagMap.key)
                .update({
                    flags: flagMap.flags
                });
        });
    },

    async down(options) {
        // clear all flags values
        logging.info('Clearing all settings flags values');
        await options
            .transacting('settings')
            .update({
                flags: null
            });

        // put type values back but leave all group values as-is because we
        // didn't change them from anything specific in `up`
        return await Promise.map(typeGroupMapping, async (typeGroupMap) => {
            return await Promise.map(typeGroupMap.keys, async (key) => {
                logging.info(`Moving setting ${key} from ${typeGroupMap.from} to ${typeGroupMap.to}`);

                return await options
                    .transacting('settings')
                    .where('key', key)
                    .update({
                        type: typeGroupMap.from
                    });
            });
        });
    }
};
<commit_msg>Added missing PUBLIC flag for logo setting in migration<commit_after>const logging = require('../../../../../shared/logging');

// settings with new groups
const typeGroupMapping = [{
    keys: [
        'members_public_key',
        'members_private_key',
        'members_email_auth_secret'
    ],
    from: 'members',
    to: 'core'
}, {
    keys: [
        'title',
        'description',
        'logo',
        'cover_image',
        'icon',
        'accent_color',
        'lang',
        'timezone',
        'codeinjection_head',
        'codeinjection_foot',
        'facebook',
        'twitter',
        'navigation',
        'secondary_navigation',
        'meta_title',
        'meta_description',
        'og_image',
        'og_title',
        'og_description',
        'twitter_image',
        'twitter_title',
        'twitter_description'

    ],
    from: 'blog',
    to: 'site'
}, {
    keys: ['amp'],
    from: 'blog',
    to: 'amp'
}, {
    keys: ['labs'],
    from: 'blog',
    to: 'labs'
}, {
    keys: ['slack'],
    from: 'blog',
    to: 'slack'
}, {
    keys: ['unsplash'],
    from: 'blog',
    to: 'unsplash'
}, {
    keys: ['shared_views'],
    from: 'blog',
    to: 'views'
}, {
    keys: ['bulk_email_settings'],
    from: 'bulk_email',
    to: 'email'
}];

// settings with the same groups
const groupMapping = [{
    group: 'core',
    keys: [
        'db_hash',
        'next_update_check',
        'notifications',
        'session_secret',
        'theme_session_secret',
        'ghost_public_key',
        'ghost_private_key'
    ]
}, {
    group: 'theme',
    keys: ['active_theme']
}, {
    group: 'private',
    keys: [
        'is_private',
        'password',
        'public_hash'
    ]
}, {
    group: 'members',
    keys: [
        'default_content_visibility',
        'members_subscription_settings',
        'stripe_connect_integration'
    ]
}, {
    group: 'portal',
    keys: [
        'portal_name',
        'portal_button',
        'portal_plans'
    ]
}];

// flags to be added to settings
const flagMapping = [{
    key: 'title',
    flags: 'PUBLIC'
}, {
    key: 'description',
    flags: 'PUBLIC'
}, {
    key: 'logo',
    flags: 'PUBLIC'
}, {
    key: 'accent_color',
    flags: 'PUBLIC'
}, {
    key: 'active_theme',
    flags: 'RO'
}];

module.exports = {
    config: {
        transaction: true
    },

    async up(options) {
        // set the new group for each changed setting and rename type
        await Promise.map(typeGroupMapping, async (typeGroupMap) => {
            return await Promise.map(typeGroupMap.keys, async (key) => {
                logging.info(`Moving setting ${key} from ${typeGroupMap.from} to ${typeGroupMap.to}`);

                return await options
                    .transacting('settings')
                    .where('key', key)
                    .update({
                        group: typeGroupMap.to,
                        type: typeGroupMap.to
                    });
            });
        });

        // set the correct group value settings which aren't changing type
        await Promise.map(groupMapping, async (groupMap) => {
            return await Promise.map(groupMap.keys, async (key) => {
                logging.info(`Adding setting ${key} to ${groupMap.group}`);

                return await options
                    .transacting('settings')
                    .where('key', key)
                    .update({
                        group: groupMap.group
                    });
            });
        });

        return await Promise.map(flagMapping, async (flagMap) => {
            logging.info(`Adding ${flagMap.flags} flag to ${flagMap.key} setting`);

            return await options
                .transacting('settings')
                .where('key', flagMap.key)
                .update({
                    flags: flagMap.flags
                });
        });
    },

    async down(options) {
        // clear all flags values
        logging.info('Clearing all settings flags values');
        await options
            .transacting('settings')
            .update({
                flags: null
            });

        // put type values back but leave all group values as-is because we
        // didn't change them from anything specific in `up`
        return await Promise.map(typeGroupMapping, async (typeGroupMap) => {
            return await Promise.map(typeGroupMap.keys, async (key) => {
                logging.info(`Moving setting ${key} from ${typeGroupMap.from} to ${typeGroupMap.to}`);

                return await options
                    .transacting('settings')
                    .where('key', key)
                    .update({
                        type: typeGroupMap.from
                    });
            });
        });
    }
};
<|endoftext|>


<commit_before>import React from "react"
import Helmet from "react-helmet"

import Styles from "./Home.css"

import CurrentUser from "../graphql/CurrentUser.gql"
console.log("Loading GraphQL queries works:", CurrentUser.kind === "Document")

import Config from "../Config.yml"
console.log("Loading YAML works:", Config.colors.main != null)

import { format } from "date-fns"
console.log("Today:", format(Date.now(), "DD.MM.YYYY"))

function Home() {
  return (

      <Helmet title="Home" />

        Home Component

  )
}

export default Home
<commit_msg>Cleanup yaml test<commit_after>import React from "react"
import Helmet from "react-helmet"

import Styles from "./Home.css"

import CurrentUser from "../graphql/CurrentUser.gql"
console.log("Loading GraphQL queries works:", CurrentUser.kind === "Document")

import { format } from "date-fns"
console.log("Today:", format(Date.now(), "DD.MM.YYYY"))

function Home() {
  return (

      <Helmet title="Home" />

        Home Component

  )
}

export default Home
<|endoftext|>


<commit_before>import { Component } from '../dom'

export default class SelectableNodeComponent extends Component {
  getInitialState () {
    const editorState = this.context.editorState
    const selectionState = editorState.selectionState
    const selected = (selectionState.node && selectionState.node.id === this.props.node.id)
    return { selected }
  }

  didMount () {
    const editorState = this.context.editorState
    if (editorState) {
      editorState.addObserver(['selectionState'], this._onSelectionChange, this, { stage: 'update' })
      editorState.addObserver(['selection', 'document'], this._rerenderIfSelectionChanged, this, {
        document: { path: [this.props.node.id] },
        stage: 'render'
      })
    }
  }

  dispose () {
    const editorState = this.context.editorState
    if (editorState) {
      editorState.removeObserver(this)
    }
  }

  _onSelectionChange (selectionState) {
    const selectedNode = selectionState.node
    if (this.state.selected) {
      if (!selectedNode || selectedNode !== this.props.node) {
        this._newSelectionState = { selected: false }
      }
    } else {
      if (selectedNode === this.props.node) {
        this._newSelectionState = { selected: true }
      }
    }
  }

  _rerenderIfSelectionChanged () {
    if (this._newSelectionState) {
      this.extendState(this._newSelectionState)
      this._newSelectionState = null
    } else if (this.context.editorState.isDirty('document')) {
      this.rerender()
    }
  }
}
<commit_msg>Improve selection detection for SelectableNodeComponents.<commit_after>import { Component } from '../dom'

export default class SelectableNodeComponent extends Component {
  getInitialState () {
    const editorState = this.context.editorState
    const selectionState = editorState.selectionState
    const selected = (selectionState.node && selectionState.node.id === this.props.node.id)
    return { selected }
  }

  didMount () {
    const editorState = this.context.editorState
    if (editorState) {
      editorState.addObserver(['selectionState'], this._onSelectionChange, this, { stage: 'update' })
      editorState.addObserver(['selection', 'document'], this._rerenderIfSelectionChanged, this, {
        document: { path: [this.props.node.id] },
        stage: 'render'
      })
    }
  }

  dispose () {
    const editorState = this.context.editorState
    if (editorState) {
      editorState.removeObserver(this)
    }
  }

  _onSelectionChange (selectionState) {
    const sel = selectionState.selection
    // NOTE: selectionState.node is also set for property selections
    // but we are only interested in custom selections
    const selectedNode = (sel && sel.isCustomSelection()) ? selectionState.node : null
    if (this.state.selected) {
      if (!selectedNode || selectedNode !== this.props.node) {
        this._newSelectionState = { selected: false }
      }
    } else {
      if (selectedNode === this.props.node) {
        this._newSelectionState = { selected: true }
      }
    }
  }

  _rerenderIfSelectionChanged () {
    if (this._newSelectionState) {
      this.extendState(this._newSelectionState)
      this._newSelectionState = null
    } else if (this.context.editorState.isDirty('document')) {
      this.rerender()
    }
  }
}
<|endoftext|>