<commit_before>import React, { PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

import {Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle} from 'material-ui/Toolbar'
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'
import RaisedButton from 'material-ui/RaisedButton'

import AppBaseComponent from '../components/AppBaseComponent'

import * as actions from '../actions'

class TimeCard extends AppBaseComponent {
  static propTypes = {
    actions: PropTypes.object.isRequired,
    params: PropTypes.object.isRequired
  }

  render() {
    return (

          <RaisedButton label='TOP' onClick={() => {super.handleUrlChange('/')}} />
          <RaisedButton label='テスト' onClick={() => {this.props.actions.timecardLoadAction(this.props.params.yearMonth)}} />

        <Toolbar>
          <ToolbarGroup>
            <ToolbarTitle text="2017/01" />
          </ToolbarGroup>
        </Toolbar>

            <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
              <TableRow>
                <TableHeaderColumn>年月日</TableHeaderColumn>
                <TableHeaderColumn>開始時間</TableHeaderColumn>
                <TableHeaderColumn>終了時間</TableHeaderColumn>
                <TableHeaderColumn>休暇タイプ</TableHeaderColumn>
                <TableHeaderColumn>備考</TableHeaderColumn>
              </TableRow>
            </TableHeader>
            <TableBody displayRowCheckbox={false}>
              <TableRow>
                <TableRowColumn>1/1</TableRowColumn>
                <TableRowColumn>9:00</TableRowColumn>
                <TableRowColumn>18:00</TableRowColumn>
              </TableRow>
              <TableRow>
                <TableRowColumn>1/2</TableRowColumn>
                <TableRowColumn>9:00</TableRowColumn>
                <TableRowColumn>18:00</TableRowColumn>
              </TableRow>
              <TableRow>
                <TableRowColumn>1/3</TableRowColumn>
                <TableRowColumn>9:00</TableRowColumn>
                <TableRowColumn>18:00</TableRowColumn>
              </TableRow>
              <TableRow>
                <TableRowColumn>1/4</TableRowColumn>
                <TableRowColumn>9:00</TableRowColumn>
                <TableRowColumn>18:00</TableRowColumn>
              </TableRow>
            </TableBody>

    )
  }
}

function mapStateToProps(state, ownProps) {
  return {
    params: ownProps.params
  }
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actions, dispatch) }
}

export default connect(mapStateToProps, mapDispatchToProps)(TimeCard)
<commit_msg>開始/終了時間のリストを、サーバデータを表示するように変更<commit_after>import React, { PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import Immutable from 'immutable'
import moment from 'moment'

import {Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle} from 'material-ui/Toolbar'
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'
import RaisedButton from 'material-ui/RaisedButton'

import AppBaseComponent from '../components/AppBaseComponent'

import * as actions from '../actions'

class TimeCard extends AppBaseComponent {
  static propTypes = {
    actions: PropTypes.object.isRequired,
    params: PropTypes.object.isRequired,
    timecard: PropTypes.object
  }

  componentDidMount() {
    this.props.actions.timecardLoadAction(this.props.params.yearMonth)
  }

  render() {
    if (!this.props.timecard) {
      return

    }
    const rows = this.props.timecard.get('days', Immutable.fromJS([])).map((v, i) => {
      const bizDate = moment(v.get('bizDate')).format('YYYY/MM/DD(ddd)')
      const start = v.get('startDatetime') ? moment(v.get('startDatetime')).format('HH:mm') : ''
      const end = v.get('endDatetime') ? moment(v.get('endDatetime')).format('HH:mm') : ''
      return (
        <TableRow key={i}>
          <TableRowColumn>{bizDate}</TableRowColumn>
          <TableRowColumn>{start}</TableRowColumn>
          <TableRowColumn>{end}</TableRowColumn>
          <TableRowColumn>{v.get('vacationTypeCode')}</TableRowColumn>
          <TableRowColumn>{v.get('note')}</TableRowColumn>
        </TableRow>
      )
    })
    const buttonMargin = {margin: '10px'}
    return (

          <RaisedButton label='TOP' style={buttonMargin} onClick={() => {super.handleUrlChange('/')}} />
          <RaisedButton label='テスト' style={buttonMargin} onClick={() => {this.props.actions.timecardLoadAction(this.props.params.yearMonth)}} />

        <Toolbar>
          <ToolbarGroup>
            <ToolbarTitle text="2017/01" />
          </ToolbarGroup>
        </Toolbar>

            <TableHeader displaySelectAll={false} adjustForCheckbox={false}>
              <TableRow>
                <TableHeaderColumn>年月日</TableHeaderColumn>
                <TableHeaderColumn>開始時間</TableHeaderColumn>
                <TableHeaderColumn>終了時間</TableHeaderColumn>
                <TableHeaderColumn>休暇タイプ</TableHeaderColumn>
                <TableHeaderColumn>備考</TableHeaderColumn>
              </TableRow>
            </TableHeader>
            <TableBody displayRowCheckbox={false}>
              {rows}
            </TableBody>

    )
  }
}

function mapStateToProps(state, ownProps) {
  const s = Immutable.fromJS(state)
  return {
    timecard: s.getIn(['api', 'TIMECARD_LOAD_SUCCESS']),
    params: ownProps.params
  }
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actions, dispatch) }
}

export default connect(mapStateToProps, mapDispatchToProps)(TimeCard)
<|endoftext|>


<commit_before>function main(){
  console.log("MAIN");
}

window.addEventListener("load",main);
<commit_msg>Test Travis<commit_after>function main(){
  console.log("MAIN");
  var ctx=canvas.getElementById("a").getContext("2d");
}

window.addEventListener("load",main);
<|endoftext|>


<commit_before>'use strict';

/**
 * if using a feature that requires a browser-polyfill
 * @see https://babeljs.io/docs/usage/polyfill/
 */
require('babel/browser-polyfill');
/**
 * Talkie.js
 */
import Bacon   from 'baconjs';

import util    from './util';
import control from './control';
import query   from './query';

import Slide      from './slide';
import Paging     from './paging';
import FullScreen from './fullscreen';
import Responsive from './responsive';
import Pointer    from './pointer';
import Backface   from './backface';

const IDENT_NEXT     = 'next';
const IDENT_PREV     = 'prev';
const IDENT_SCALER   = 'scaler';
const IDENT_CONTROL  = 'control';
const IDENT_PAGE     = 'page';
const IDENT_TOTAL    = 'total';
const IDENT_PROGRESS = 'progress';
const IDENT_POINTER  = 'pointer';
const IDENT_BACKFACE = 'backface';
const MIME_MARKDOWN  = 'text/x-markdown';
const ATTR_LAYOUT    = 'layout';
const ATTR_BODY_BG   = 'body-bg';
const ATTR_NO_TRANS  = 'no-transition';

const NORMAL_WIDTH  = 1024;
const NORMAL_HEIGHT = 768;
const WIDE_WIDTH    = 1366;
const WIDE_HEIGHT   = 768;

/**
 * @typedef {Object} TalkieOptions
 * @property {Boolean} [api]
 * @property {Boolean} [wide]
 * @property {Boolean} [control]
 * @property {Boolean} [pointer]
 * @property {Boolean} [progress]
 * @property {Boolean} [backface]
 */

/**
 * @param {TalkieOptions} options
 */
export default function(options = {}) {
  if (options.api) {
    return {
      main       : main,
      util       : util,
      control    : control,
      query      : query,
      slide      : Slide,
      paging     : Paging,
      fullScreen : FullScreen,
      responsive : Responsive,
      pointer    : Pointer,
      backface   : Backface,
      Bacon      : Bacon
    };
  } else {
    return main(options);
  }
}

/**
 * @param {TalkieOptions} _options
 */
function main(_options = {}) {

  /**
   * apply default options
   * @type {*|Object}
   */
  let options = util.extend(util.defaults(_options, {
    api          : false,
    wide         : false,
    control      : true,
    pointer      : true,
    progress     : true,
    backface     : true,
    notransition : false
  }), query(location.search));

  /**
   * Init slide sizes
   */
  let width  = options.wide ? WIDE_WIDTH  : NORMAL_WIDTH;
  let height = options.wide ? WIDE_HEIGHT : NORMAL_HEIGHT;
  document.querySelector('head').insertAdjacentHTML('beforeend', `
    `
  );

  /**
   * Init slide sections
   */
  let mds = util.toArray(document.querySelectorAll(`[type="${MIME_MARKDOWN}"]`));
  mds.forEach(Slide.compileMarkdown);
  let slides = util.toArray(document.querySelectorAll(`[${ATTR_LAYOUT}]`));
  let notes  = slides.map(Slide.extractNote);

  /**
   * Responsive scaling
   */
  document.body.insertAdjacentHTML('beforeend', `

  `);
  let scalerEl = util.getById(IDENT_SCALER);
  slides.forEach((el) => scalerEl.appendChild(el));

  let responsive = Responsive({
    width  : width,
    height : height,
    target : scalerEl
  });
  responsive.scaleBus.plug(control.resize());

  /**
   * Paging control
   */
  let paging = Paging({
    startPage     : util.getPageNumberFromHash() || 1,
    endPage       : slides.length,
    slideElements : slides
  });

  paging.nextBus.plug(control.keydown('right').throttle(100));
  paging.prevBus.plug(control.keydown('left').throttle(100));

  paging.nextBus.plug(control.swipeLeft());
  paging.prevBus.plug(control.swipeRight());

  // sync location.hash
  paging.moveBus.plug(control.hashchange().map(util.getPageNumberFromHash));
  paging.currentEs.onValue((page) => {
    (page === 1 && !location.hash) || (location.hash = page);
  });

  // sync body background attribute
  paging.changedEs
    .map('.getAttribute', ATTR_LAYOUT)
    .onValue(util.attributeAssignOf(document.body, ATTR_BODY_BG));

  /**
   * Insert Ui Elements
   */
  if (options.notransition) {
    Bacon.once(1)
      .onValue(util.attributeAssignOf(document.body, ATTR_NO_TRANS));
  }

  if (options.pointer) {
    document.body.insertAdjacentHTML('beforeend', `<div id="${IDENT_POINTER}"></div>`);
    let {coordBus, toggleBus} = Pointer(util.getById(IDENT_POINTER));
    coordBus.plug(control.mousemove());
    toggleBus.plug(control.key('b'));
  }

  if (options.backface) {
    document.body.insertAdjacentHTML('beforeend', `<div id="${IDENT_BACKFACE}"></div>`);
    let {bgImageBus, bgFilterBus} = Backface(util.getById(IDENT_BACKFACE));
    bgImageBus.plug(paging.changedEs);
    bgFilterBus.plug(paging.changedEs);
  }

  if (options.control) {
    document.body.insertAdjacentHTML('beforeend', `

◀
        Page 0 of 0
        ▶

    `);

    let nextEl = util.getById(IDENT_NEXT);
    let prevEl = util.getById(IDENT_PREV);

    // next button
    paging.nextBus.plug(control.click(nextEl));

    // prev button
    paging.prevBus.plug(control.click(prevEl));

    // current page
    paging.currentEs.onValue(util.textAssignOf(util.getById(IDENT_PAGE)));

    // total of page
    Bacon.once(slides.length).onValue(util.textAssignOf(util.getById(IDENT_TOTAL)));
  }

  if (options.progress) {
    document.body.insertAdjacentHTML('beforeend', `<div id="${IDENT_PROGRESS}"></div>`);

    // progress bar
    paging.percentEs.onValue(util.styleAssignOf(util.getById(IDENT_PROGRESS), 'width'));
  }

  /**
   * FullScreen
   */
  FullScreen(document.body).plug(control.key('f'));

  /**
   * export some of control
   *
   * @typedef {Object} TalkieExport
   * @param {Object.<Function>} control
   * @param {Bacon.EventStream} changed
   * @param {Bacon.Bus} next
   * @param {Bacon.Bus} prev
   * @param {Bacon.Bus} jump
   */
  return {
    Bacon   : Bacon,
    control : control,
    changed : paging.changedEs,
    next    : paging.nextBus,
    prev    : paging.prevBus,
    jump    : paging.moveBus,
    ratio   : responsive.currentRatio,
    notes   : notes
  };
}
<commit_msg>refactor md traverse<commit_after>'use strict';

/**
 * if using a feature that requires a browser-polyfill
 * @see https://babeljs.io/docs/usage/polyfill/
 */
require('babel/browser-polyfill');
/**
 * Talkie.js
 */
import Bacon   from 'baconjs';

import util    from './util';
import control from './control';
import query   from './query';

import Slide      from './slide';
import Paging     from './paging';
import FullScreen from './fullscreen';
import Responsive from './responsive';
import Pointer    from './pointer';
import Backface   from './backface';

const IDENT_NEXT     = 'next';
const IDENT_PREV     = 'prev';
const IDENT_SCALER   = 'scaler';
const IDENT_CONTROL  = 'control';
const IDENT_PAGE     = 'page';
const IDENT_TOTAL    = 'total';
const IDENT_PROGRESS = 'progress';
const IDENT_POINTER  = 'pointer';
const IDENT_BACKFACE = 'backface';

const SELECTOR_MD = '[type="text/x-markdown"]';

const ATTR_LAYOUT   = 'layout';
const ATTR_BODY_BG  = 'body-bg';
const ATTR_NO_TRANS = 'no-transition';

const NORMAL_WIDTH  = 1024;
const NORMAL_HEIGHT = 768;
const WIDE_WIDTH    = 1366;
const WIDE_HEIGHT   = 768;

/**
 * @typedef {Object} TalkieOptions
 * @property {Boolean} [api]
 * @property {Boolean} [wide]
 * @property {Boolean} [control]
 * @property {Boolean} [pointer]
 * @property {Boolean} [progress]
 * @property {Boolean} [backface]
 */

/**
 * @param {TalkieOptions} options
 */
export default function(options = {}) {
  if (options.api) {
    return {
      main       : main,
      util       : util,
      control    : control,
      query      : query,
      slide      : Slide,
      paging     : Paging,
      fullScreen : FullScreen,
      responsive : Responsive,
      pointer    : Pointer,
      backface   : Backface,
      Bacon      : Bacon
    };
  } else {
    return main(options);
  }
}

/**
 * @param {TalkieOptions} _options
 */
function main(_options = {}) {

  /**
   * apply default options
   * @type {*|Object}
   */
  let options = util.extend(util.defaults(_options, {
    api          : false,
    wide         : false,
    control      : true,
    pointer      : true,
    progress     : true,
    backface     : true,
    notransition : false
  }), query(location.search));

  /**
   * Init slide sizes
   */
  let width  = options.wide ? WIDE_WIDTH  : NORMAL_WIDTH;
  let height = options.wide ? WIDE_HEIGHT : NORMAL_HEIGHT;
  document.querySelector('head').insertAdjacentHTML('beforeend', `
    `
  );

  /**
   * Init slide sections
   */
  let mds = util.toArray(document.querySelectorAll(SELECTOR_MD));
  mds.forEach(Slide.compileMarkdown);
  let slides = util.toArray(document.querySelectorAll(`[${ATTR_LAYOUT}]`));
  let notes  = slides.map(Slide.extractNote);

  /**
   * Responsive scaling
   */
  document.body.insertAdjacentHTML('beforeend', `

  `);
  let scalerEl = util.getById(IDENT_SCALER);
  slides.forEach((el) => scalerEl.appendChild(el));

  let responsive = Responsive({
    width  : width,
    height : height,
    target : scalerEl
  });
  responsive.scaleBus.plug(control.resize());

  /**
   * Paging control
   */
  let paging = Paging({
    startPage     : util.getPageNumberFromHash() || 1,
    endPage       : slides.length,
    slideElements : slides
  });

  paging.nextBus.plug(control.keydown('right').throttle(100));
  paging.prevBus.plug(control.keydown('left').throttle(100));

  paging.nextBus.plug(control.swipeLeft());
  paging.prevBus.plug(control.swipeRight());

  // sync location.hash
  paging.moveBus.plug(control.hashchange().map(util.getPageNumberFromHash));
  paging.currentEs.onValue((page) => {
    (page === 1 && !location.hash) || (location.hash = page);
  });

  // sync body background attribute
  paging.changedEs
    .map('.getAttribute', ATTR_LAYOUT)
    .onValue(util.attributeAssignOf(document.body, ATTR_BODY_BG));

  /**
   * Insert Ui Elements
   */
  if (options.notransition) {
    Bacon.once(1)
      .onValue(util.attributeAssignOf(document.body, ATTR_NO_TRANS));
  }

  if (options.pointer) {
    document.body.insertAdjacentHTML('beforeend', `<div id="${IDENT_POINTER}"></div>`);
    let {coordBus, toggleBus} = Pointer(util.getById(IDENT_POINTER));
    coordBus.plug(control.mousemove());
    toggleBus.plug(control.key('b'));
  }

  if (options.backface) {
    document.body.insertAdjacentHTML('beforeend', `<div id="${IDENT_BACKFACE}"></div>`);
    let {bgImageBus, bgFilterBus} = Backface(util.getById(IDENT_BACKFACE));
    bgImageBus.plug(paging.changedEs);
    bgFilterBus.plug(paging.changedEs);
  }

  if (options.control) {
    document.body.insertAdjacentHTML('beforeend', `

◀
        Page 0 of 0
        ▶

    `);

    let nextEl = util.getById(IDENT_NEXT);
    let prevEl = util.getById(IDENT_PREV);

    // next button
    paging.nextBus.plug(control.click(nextEl));

    // prev button
    paging.prevBus.plug(control.click(prevEl));

    // current page
    paging.currentEs.onValue(util.textAssignOf(util.getById(IDENT_PAGE)));

    // total of page
    Bacon.once(slides.length).onValue(util.textAssignOf(util.getById(IDENT_TOTAL)));
  }

  if (options.progress) {
    document.body.insertAdjacentHTML('beforeend', `<div id="${IDENT_PROGRESS}"></div>`);

    // progress bar
    paging.percentEs.onValue(util.styleAssignOf(util.getById(IDENT_PROGRESS), 'width'));
  }

  /**
   * FullScreen
   */
  FullScreen(document.body).plug(control.key('f'));

  /**
   * export some of control
   *
   * @typedef {Object} TalkieExport
   * @param {Object.<Function>} control
   * @param {Bacon.EventStream} changed
   * @param {Bacon.Bus} next
   * @param {Bacon.Bus} prev
   * @param {Bacon.Bus} jump
   */
  return {
    Bacon   : Bacon,
    control : control,
    changed : paging.changedEs,
    next    : paging.nextBus,
    prev    : paging.prevBus,
    jump    : paging.moveBus,
    ratio   : responsive.currentRatio,
    notes   : notes
  };
}
<|endoftext|>


<commit_before>function getOs() {
  var platform = navigator.platform.toUpperCase();
  switch (platform) {
    case 'MAC':
      return 'mac';
      break;
    case 'WIN':
      return 'windows';
      break;
    case 'LINUX':
      return 'linux';
      break;
    default:
      return 'windows';
      break;
  }
}

function isYaml (str) {
  return /\.(ya?ml)$/.test(str);
}

function stripQuotes (str) {
  return str.replace(/^"(.*)"$/, '$1');
}

function setDefaults (links) {
  return links.map(function (i) {
    if (typeof i.type === 'undefined') {
      i.type = 'page';
    }
    return i;
  });
}

function getEngine (links) {
  links = setDefaults(links);

  return new Bloodhound({
    datumTokenizer: function (obj) {
      var tokens = [];
      tokens = tokens
        .concat(Bloodhound.tokenizers.whitespace(obj.name))
        .concat(obj.tags.map(function(i) { return '#' + i; }))
        .concat(obj.url);
      return tokens;
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: links,
    identify: function (obj) {
      return obj._source + '/' + obj.tags.join('/') + '/' + obj.name;
    }
  });
}

function startTypeahead (links) {
  var input = $('#typeahead');

  links = getEngine(links);

  input.typeahead({
    hint: false,
    highlight: true,
    minLength: 1
  }, {
    name: 'links',
    source: links,
    limit: 10,
    templates: {
      suggestion: function (obj) {
        tags = obj.tags.map(function (i) { return '#' + i; }).join(' ');

        return '

' +
          '' + obj.name + '' +
          '
' + obj._url + '' +
          '' + tags + '' +
          '

';
      }
    },
    display: 'name'
  });

  input.bind('typeahead:select', function(e, obj) {
    var target = target = localStorage.getItem('ngStorage-' + (obj.type === 'page' ? 'openPage' : 'openFile'));
    target = stripQuotes(target);
    target = target == 'new' ? '_blank' : '_self';
    window.open(obj.url, target);
  });
}

angular
.module('App', ['ngStorage', 'angular-cache'])
.factory('Typeahead', function ($http, $rootScope, $q) {
  function getData (response) {
    var url = response.config.url;
    var data = null;
    if (isYaml(url)) {
      data = jsyaml.load(response.data);
    } else {
      data = response.data;
    }
    // Add _url to all response data object
    data._url = url;
    return data;
  }

  function mapResponses (responses) {
    return responses.map(function(response) {
      return getData(response);
    });
  }

  function combineObjects (objArray) {
    var allLinks = [];
    objArray.forEach(function (obj) {
      // _source for identify - base64
      var links = obj.links.map(function (link) {
        link._url = obj._url;
        link._source = window.btoa(obj._url)
        return link;
      });
      allLinks = allLinks.concat(links);
    });
    objArray.push(allLinks);
    return objArray;
  }

  return {
    load: function () {
      var urls = $rootScope.settings.url.split('\n');
      var promises = urls.map(function (url) { return $http.get(url); });

      $q
        .all(promises)
        .then(mapResponses)
        .then(combineObjects)
        .then(function (arr) {
          var allLinks = arr.slice(-1)[0];
          startTypeahead(allLinks);
        });
    }
  };
})
.factory('Settings', function ($localStorage) {
  var urls = [
    '/db/db-global.yml',
    '/db/db-' + getOs() + '.yml'
  ].join('\n');

  var storageDefault = {
    url: urls,
    openFile: 'current',
    openPage: 'new',
    cache: true
  };

  return {
    reset: function () { return $localStorage.$reset(storageDefault); },
    storage: $localStorage.$default(storageDefault)
  };
})
.controller('SettingsCtrl', function ($scope, $rootScope, Settings) {
  $scope.reset = function () {
    Settings.reset();
  };
})
.filter('noReferrer', function () {
  return function (input) {
    return 'https://href.li/?' + input;
  };
})
.filter('getFaviconUrl', function () {
  return function (input) {
    return 'https://www.google.com/s2/favicons?domain_url=' + input;
  };
})
.run(function ($http, $rootScope, Settings, Typeahead, CacheFactory) {
  $rootScope.settings = Settings.storage;

  if ($rootScope.settings.cache === true) {
    $http.defaults.cache = CacheFactory('defaultCache', {
      maxAge: 15 * 60 * 1000,
      cacheFlushInterval: 60 * 60 * 1000,
      deleteOnExpire: 'aggressive',
      storageMode: 'localStorage'
    });
  }

  Typeahead.load();
});<commit_msg>Fix getOs<commit_after>function getOs() {
  var platform = navigator.platform.toUpperCase();
  if (platform.indexOf('MAC') > -1) return 'mac';
  if (platform.indexOf('WIN') > -1) return 'windows';
  if (platform.indexOf('LINUX') > -1) return 'linux';
  return 'windows';
}

function isYaml (str) {
  return /\.(ya?ml)$/.test(str);
}

function stripQuotes (str) {
  return str.replace(/^"(.*)"$/, '$1');
}

function setDefaults (links) {
  return links.map(function (i) {
    if (typeof i.type === 'undefined') {
      i.type = 'page';
    }
    return i;
  });
}

function getEngine (links) {
  links = setDefaults(links);

  return new Bloodhound({
    datumTokenizer: function (obj) {
      var tokens = [];
      tokens = tokens
        .concat(Bloodhound.tokenizers.whitespace(obj.name))
        .concat(obj.tags.map(function(i) { return '#' + i; }))
        .concat(obj.url);
      return tokens;
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: links,
    identify: function (obj) {
      return obj._source + '/' + obj.tags.join('/') + '/' + obj.name;
    }
  });
}

function startTypeahead (links) {
  var input = $('#typeahead');

  links = getEngine(links);

  input.typeahead({
    hint: false,
    highlight: true,
    minLength: 1
  }, {
    name: 'links',
    source: links,
    limit: 10,
    templates: {
      suggestion: function (obj) {
        tags = obj.tags.map(function (i) { return '#' + i; }).join(' ');

        return '

' +
          '' + obj.name + '' +
          '
' + obj._url + '' +
          '' + tags + '' +
          '

';
      }
    },
    display: 'name'
  });

  input.bind('typeahead:select', function(e, obj) {
    var target = target = localStorage.getItem('ngStorage-' + (obj.type === 'page' ? 'openPage' : 'openFile'));
    target = stripQuotes(target);
    target = target == 'new' ? '_blank' : '_self';
    window.open(obj.url, target);
  });
}

angular
.module('App', ['ngStorage', 'angular-cache'])
.factory('Typeahead', function ($http, $rootScope, $q) {
  function getData (response) {
    var url = response.config.url;
    var data = null;
    if (isYaml(url)) {
      data = jsyaml.load(response.data);
    } else {
      data = response.data;
    }
    // Add _url to all response data object
    data._url = url;
    return data;
  }

  function mapResponses (responses) {
    return responses.map(function(response) {
      return getData(response);
    });
  }

  function combineObjects (objArray) {
    var allLinks = [];
    objArray.forEach(function (obj) {
      // _source for identify - base64
      var links = obj.links.map(function (link) {
        link._url = obj._url;
        link._source = window.btoa(obj._url)
        return link;
      });
      allLinks = allLinks.concat(links);
    });
    objArray.push(allLinks);
    return objArray;
  }

  return {
    load: function () {
      var urls = $rootScope.settings.url.split('\n');
      var promises = urls.map(function (url) { return $http.get(url); });

      $q
        .all(promises)
        .then(mapResponses)
        .then(combineObjects)
        .then(function (arr) {
          var allLinks = arr.slice(-1)[0];
          startTypeahead(allLinks);
        });
    }
  };
})
.factory('Settings', function ($localStorage) {
  var urls = [
    '/db/db-global.yml',
    '/db/db-' + getOs() + '.yml'
  ].join('\n');

  var storageDefault = {
    url: urls,
    openFile: 'current',
    openPage: 'new',
    cache: true
  };

  return {
    reset: function () { return $localStorage.$reset(storageDefault); },
    storage: $localStorage.$default(storageDefault)
  };
})
.controller('SettingsCtrl', function ($scope, $rootScope, Settings) {
  $scope.reset = function () {
    Settings.reset();
  };
})
.filter('noReferrer', function () {
  return function (input) {
    return 'https://href.li/?' + input;
  };
})
.filter('getFaviconUrl', function () {
  return function (input) {
    return 'https://www.google.com/s2/favicons?domain_url=' + input;
  };
})
.run(function ($http, $rootScope, Settings, Typeahead, CacheFactory) {
  $rootScope.settings = Settings.storage;

  if ($rootScope.settings.cache === true) {
    $http.defaults.cache = CacheFactory('defaultCache', {
      maxAge: 15 * 60 * 1000,
      cacheFlushInterval: 60 * 60 * 1000,
      deleteOnExpire: 'aggressive',
      storageMode: 'localStorage'
    });
  }

  Typeahead.load();
});<|endoftext|>


<commit_before>import React, {Component, Children, PropTypes} from 'react';

// express.js` path matching
import pathToRegexp from 'path-to-regexp';

import {createHistory, createMemoryHistory, useBeforeUnload} from 'history';

// setup a hidden singleton history object. a good default.
const isBrowser = typeof window !== 'undefined';
if (isBrowser){
  window.__routah_history__ = window.__routah_history__ || useBeforeUnload(createHistory)();
}

const has = {}.hasOwnProperty;

function find(arr, fn){
  for (let el of arr){
    let res = fn(el);
    if (res){
      return res;
    }
  }
}

// a helper to get the current location from the history object
function currentLocation(h){
  let loc;
  h.listen(location => loc = location)();
  return loc;
}

function decode_param(val) {
  if (typeof val !== 'string' || val.length === 0) {
    return val;
  }

  try {
    return decodeURIComponent(val);
  } catch (err) {
    if (err instanceof URIError) {
      err.message = 'Failed to decode param \'' + val + '\'';
      err.status = err.statusCode = 400;
    }

    throw err;
  }
}

// pattern matching for urls
function pathMatch(pattern, path){
  let keys = [], params = {}, _path,
    regexp = pathToRegexp(pattern, keys), m = regexp.exec(path);
  if (!m){
    return false;
  }
  _path = m[0];

  for (var i = 1; i < m.length; i++) {
    var key = keys[i - 1];
    var prop = key.name;
    var val = decode_param(m[i]);

    if (val !== undefined || !(params::has(prop))) {
      params[prop] = val;
    }
  }
  return params;

}

function matches(patterns, url){
  if (!patterns){
    return true;
  }
  if (!Array.isArray(patterns)){
    return pathMatch(patterns, url);
  }

  return find(patterns, p => pathMatch(p, url));
}

// top level component. pass in a history object.
// <Router history={history}>
//   <App/>
// </Router>
// todo - use a default history singleton in browser
export class Router extends Component{
  state = {
    location: null
  };
  static propTypes = {
    history: PropTypes.object,
    url: PropTypes.string  // only for server side
  };
  static defaultProps = {
    url: '/'
  };
  static contextTypes = {
    // discover if we're nested in abother <Router/>
    routah: PropTypes.object
  };
  static childContextTypes = {
    routah: PropTypes.object.isRequired
  };
  __routah_history__ = isBrowser ? global.__routah_history__ : useBeforeUnload(createMemoryHistory)(this.props.url);
  getChildContext(){

    return {
      routah: {
        history: (this.props::has('history') && this.props.history) || (this.context.routah || {}).history || this.__routah_history__
      }
    };
  }
  render(){
    return typeof this.props.children === 'function' ?
      this.props.children(this.props.history || global.__routah_history__) :
      this.props.children;
  }
}

// The big idea -
// `<Route path={...} .../>` will render only when `path` matches the current browser url
// that's it.
// we introduce some lifecycle hooks and customizability for ease of dev
export class Route extends Component{
  static propTypes = {
    path: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
    component: PropTypes.func,
    notFound: PropTypes.func,
    props: PropTypes.object,
    onMount: PropTypes.func,
    onLeave: PropTypes.func,
    onEnter: PropTypes.func,
    onUnload: PropTypes.func,
    children: PropTypes.func
  };
  static defaultProps = {
    notFound: () => null,
    props: {},
    onMount: () => {},
    onEnter: (l, cb) => cb(),
    onLeave: (l, cb) => cb(),
    onUnload: () => {}
  };
  static contextTypes = {
    routah: PropTypes.object
  };
  refresh = (location = currentLocation(this.context.routah.history), props = this.props) => {
    let doesMatch = true, match;
    if (props.path){
      match = matches(props.path, this.context.routah.history.createHref(location));
      doesMatch = !!match;
    }

    this.setState({
      location: {
        ...location,
        params: match || {}
      },
      matches: doesMatch
    });
  };
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(this.refresh);

  }
  componentDidMount(){
    let h = this.context.routah.history;
    if (matches(this.props.path,  h.createHref(currentLocation(h)))){
      this.props.onMount(currentLocation(h));
    }

    this.disposeBefore = this.context.routah.history.listenBefore((location, callback) => {
      let matchesCurrent = matches(this.props.path,  h.createHref(currentLocation(h)));
      let matchesNext = matches(this.props.path,  h.createHref(location));
      if (!matchesCurrent && matchesNext){
        return this.props.onEnter(location, callback);
      }
      if (matchesCurrent && !matchesNext){
        return this.props.onLeave(location, callback);
      }

      return callback();
    });

    this.disposeUnload = this.context.routah.history.listenBeforeUnload(() => {
      if (matches(this.props.path,  h.createHref(currentLocation(h)))){
        return this.props.onUnload(currentLocation(h));
      }
    });
  }
  componentWillReceiveProps(next){
    if (next.path !== this.props.path){
      // todo - fire onenter/onleave hooks here too?
      this.refresh(undefined, next);
    }
  }
  render(){

    let {location} = this.state;
    let {history} = this.context.routah;
    let el;
    if (this.state.matches){
      if (this.props.component){
        // components / props flavor
        el = React.createElement(this.props.component, {location, history, ...this.props.props});
      }
      else {
        // render callback
        el = this.props.children(location, history);
      }
    }
    return el || this.props.notFound(location);
  }
  componentWillUnmount(){
    this.dispose();
    this.disposeBefore();
    this.disposeUnload();
    delete this.dispose;
    delete this.disposeBefore;
    delete this.disposeUnload;
  }
}

// a useful replacement for <a> elements.
// includes clickjacking, and custom styling when 'active',
export class Link extends Component{
  static contextTypes = {
    routah: PropTypes.object
  };
  static propTypes = {
    to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    onClick: PropTypes.func,
    className: PropTypes.string,
    style: PropTypes.object,
    activeClass: PropTypes.string,
    activeStyle: PropTypes.object
  };

  static defaultProps = {
    onClick: () => {},
    className: '',
    activeClass: 'active',
    style: {},
    activeStyle: {}
  };

  state = {
    location: '/'
  };

  onClick = e => {
    e.preventDefault();
    this.props.onClick(e);
    this.context.routah.history.push(this.props.to);
  };
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(location =>this.setState({location}));
  }

  render(){
    let h = this.context.routah.history;
    let active = h.createHref(this.props.to) === h.createHref(this.state.location);

    return <a
      href={h.createHref(this.props.to)}
      {...this.props}
      className={`${this.props.className} ${active ? this.props.activeClass : ''}`}
      style={{...this.props.style, ...(active ? this.props.activeStyle : {})}}
      onClick={this.onClick}>
      {this.props.children}
    </a>;
  }
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(location =>this.setState({location}));
  }
  componentWillUnmount(){
    this.dispose();
    delete this.dispose;
  }
}

// `<Redirect to={...}/>` simply triggers `history.push()` when rendered
// todo - handle server side redirect
export class Redirect extends Component{

  static contextTypes = {
    routah: PropTypes.object
  };
  componentDidMount(){
    this.context.routah.history.push(this.props.to);
  }
  render(){
    return null;
  }
}

// a la react-router, only the first-matching `<Route/>` child is rendered.
export class RouteStack extends Component{
  static contextTypes = {
    routah: PropTypes.object
  };

  static propTypes = {
    notFound: PropTypes.func,
    children: (props, key) => {
      let bad = find(Children.toArray(props.children), c => c.type !== Route);
      if (bad){
        return new Error('<RouteStack/> only accepts <Route/>s as children\n');
      }
      return null;
    }
  };
  static defaultProps = {
    notFound: () => null
  };
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(location => this.setState({location}));
  }
  componentWillUnmount(){
    this.dispose();
    delete this.dispose;
  }
  render(){
    let url = this.context.routah.history.createHref(this.state.location);
    return find(Children.toArray(this.props.children), c => matches(c.props.path, url) ? c : false);
  }
}

<commit_msg>RouteStack.notFound works<commit_after>import React, {Component, Children, PropTypes} from 'react';

// express.js` path matching
import pathToRegexp from 'path-to-regexp';

import {createHistory, createMemoryHistory, useBeforeUnload} from 'history';

// setup a hidden singleton history object. a good default.
const isBrowser = typeof window !== 'undefined';
if (isBrowser){
  window.__routah_history__ = window.__routah_history__ || useBeforeUnload(createHistory)();
}

const has = {}.hasOwnProperty;

function find(arr, fn){
  for (let el of arr){
    let res = fn(el);
    if (res){
      return res;
    }
  }
}

// a helper to get the current location from the history object
function currentLocation(h){
  let loc;
  h.listen(location => loc = location)();
  return loc;
}

function decode_param(val) {
  if (typeof val !== 'string' || val.length === 0) {
    return val;
  }

  try {
    return decodeURIComponent(val);
  } catch (err) {
    if (err instanceof URIError) {
      err.message = 'Failed to decode param \'' + val + '\'';
      err.status = err.statusCode = 400;
    }

    throw err;
  }
}

// pattern matching for urls
function pathMatch(pattern, path){
  let keys = [], params = {}, _path,
    regexp = pathToRegexp(pattern, keys), m = regexp.exec(path);
  if (!m){
    return false;
  }
  _path = m[0];

  for (var i = 1; i < m.length; i++) {
    var key = keys[i - 1];
    var prop = key.name;
    var val = decode_param(m[i]);

    if (val !== undefined || !(params::has(prop))) {
      params[prop] = val;
    }
  }
  return params;

}

function matches(patterns, url){
  if (!patterns){
    return true;
  }
  if (!Array.isArray(patterns)){
    return pathMatch(patterns, url);
  }

  return find(patterns, p => pathMatch(p, url));
}

// top level component. pass in a history object.
// <Router history={history}>
//   <App/>
// </Router>
// todo - use a default history singleton in browser
export class Router extends Component{
  state = {
    location: null
  };
  static propTypes = {
    history: PropTypes.object,
    url: PropTypes.string  // only for server side
  };
  static defaultProps = {
    url: '/'
  };
  static contextTypes = {
    // discover if we're nested in abother <Router/>
    routah: PropTypes.object
  };
  static childContextTypes = {
    routah: PropTypes.object.isRequired
  };
  __routah_history__ = isBrowser ? global.__routah_history__ : useBeforeUnload(createMemoryHistory)(this.props.url);
  getChildContext(){

    return {
      routah: {
        history: (this.props::has('history') && this.props.history) || (this.context.routah || {}).history || this.__routah_history__
      }
    };
  }
  render(){
    return typeof this.props.children === 'function' ?
      this.props.children(this.props.history || global.__routah_history__) :
      this.props.children;
  }
}

// The big idea -
// `<Route path={...} .../>` will render only when `path` matches the current browser url
// that's it.
// we introduce some lifecycle hooks and customizability for ease of dev
export class Route extends Component{
  static propTypes = {
    path: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
    component: PropTypes.func,
    notFound: PropTypes.func,
    props: PropTypes.object,
    onMount: PropTypes.func,
    onLeave: PropTypes.func,
    onEnter: PropTypes.func,
    onUnload: PropTypes.func,
    children: PropTypes.func
  };
  static defaultProps = {
    notFound: () => null,
    props: {},
    onMount: () => {},
    onEnter: (l, cb) => cb(),
    onLeave: (l, cb) => cb(),
    onUnload: () => {}
  };
  static contextTypes = {
    routah: PropTypes.object
  };
  refresh = (location = currentLocation(this.context.routah.history), props = this.props) => {
    let doesMatch = true, match;
    if (props.path){
      match = matches(props.path, this.context.routah.history.createHref(location));
      doesMatch = !!match;
    }

    this.setState({
      location: {
        ...location,
        params: match || {}
      },
      matches: doesMatch
    });
  };
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(this.refresh);

  }
  componentDidMount(){
    let h = this.context.routah.history;
    if (matches(this.props.path,  h.createHref(currentLocation(h)))){
      this.props.onMount(currentLocation(h));
    }

    this.disposeBefore = this.context.routah.history.listenBefore((location, callback) => {
      let matchesCurrent = matches(this.props.path,  h.createHref(currentLocation(h)));
      let matchesNext = matches(this.props.path,  h.createHref(location));
      if (!matchesCurrent && matchesNext){
        return this.props.onEnter(location, callback);
      }
      if (matchesCurrent && !matchesNext){
        return this.props.onLeave(location, callback);
      }

      return callback();
    });

    this.disposeUnload = this.context.routah.history.listenBeforeUnload(() => {
      if (matches(this.props.path,  h.createHref(currentLocation(h)))){
        return this.props.onUnload(currentLocation(h));
      }
    });
  }
  componentWillReceiveProps(next){
    if (next.path !== this.props.path){
      // todo - fire onenter/onleave hooks here too?
      this.refresh(undefined, next);
    }
  }
  render(){

    let {location} = this.state;
    let {history} = this.context.routah;
    let el;
    if (this.state.matches){
      if (this.props.component){
        // components / props flavor
        el = React.createElement(this.props.component, {location, history, ...this.props.props});
      }
      else {
        // render callback
        el = this.props.children(location, history);
      }
    }
    return el || this.props.notFound(location);
  }
  componentWillUnmount(){
    this.dispose();
    this.disposeBefore();
    this.disposeUnload();
    delete this.dispose;
    delete this.disposeBefore;
    delete this.disposeUnload;
  }
}

// a useful replacement for <a> elements.
// includes clickjacking, and custom styling when 'active',
export class Link extends Component{
  static contextTypes = {
    routah: PropTypes.object
  };
  static propTypes = {
    to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    onClick: PropTypes.func,
    className: PropTypes.string,
    style: PropTypes.object,
    activeClass: PropTypes.string,
    activeStyle: PropTypes.object
  };

  static defaultProps = {
    onClick: () => {},
    className: '',
    activeClass: 'active',
    style: {},
    activeStyle: {}
  };

  state = {
    location: '/'
  };

  onClick = e => {
    e.preventDefault();
    this.props.onClick(e);
    this.context.routah.history.push(this.props.to);
  };
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(location =>this.setState({location}));
  }

  render(){
    let h = this.context.routah.history;
    let active = h.createHref(this.props.to) === h.createHref(this.state.location);

    return <a
      href={h.createHref(this.props.to)}
      {...this.props}
      className={`${this.props.className} ${active ? this.props.activeClass : ''}`}
      style={{...this.props.style, ...(active ? this.props.activeStyle : {})}}
      onClick={this.onClick}>
      {this.props.children}
    </a>;
  }
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(location =>this.setState({location}));
  }
  componentWillUnmount(){
    this.dispose();
    delete this.dispose;
  }
}

// `<Redirect to={...}/>` simply triggers `history.push()` when rendered
// todo - handle server side redirect
export class Redirect extends Component{

  static contextTypes = {
    routah: PropTypes.object
  };
  componentDidMount(){
    this.context.routah.history.push(this.props.to);
  }
  render(){
    return null;
  }
}

// a la react-router, only the first-matching `<Route/>` child is rendered.
export class RouteStack extends Component{
  static contextTypes = {
    routah: PropTypes.object
  };

  static propTypes = {
    notFound: PropTypes.func,
    children(props) {
      return find(Children.toArray(props.children), c => c.type !== Route) ?
        new Error('<RouteStack/> only accepts <Route/>s as children\n') :
        null;
    }
  };
  static defaultProps = {
    notFound: () => null
  };
  componentWillMount(){
    this.dispose = this.context.routah.history.listen(location => this.setState({location}));
  }
  componentWillUnmount(){
    this.dispose();
    delete this.dispose;
  }
  render(){
    let url = this.context.routah.history.createHref(this.state.location);
    return find(Children.toArray(this.props.children), c => matches(c.props.path, url) ? c : false) || this.props.notFound();
  }
}

<|endoftext|>


<commit_before>import capitalize from 'capitalize';
import connect from './helpers/connect';
import connectAudioNodes from './helpers/connectAudioNodes';
import createVirtualAudioNode from './helpers/createVirtualAudioNode';
import updateAudioNodeAndVirtualAudioGraph from './helpers/updateAudioNodeAndVirtualAudioGraph';
import disconnect from './helpers/disconnect';

const startTimePath = params => params[2] && params[2].startTime;
const stopTimePath = params => params[2] && params[2].stopTime;

export default class VirtualAudioGraph {
  constructor ({audioContext = new AudioContext(),
                output = audioContext.destination} = {}) {
    this.audioContext = audioContext;
    this.output = output;
    this.virtualNodes = {};
    this.customNodes = {};
  }

  get currentTime () {
    return this.audioContext.currentTime;
  }

  defineNode (customNodeParamsFactory, name) {
    if (this.audioContext[`create${capitalize(name)}`]) {
      throw new Error(`${name} is a standard audio node name and cannot be overwritten`);
    }

    this.customNodes[name] = customNodeParamsFactory;
    return this;
  }

  getAudioNodeById (id) {
    return this.virtualNodes[id].audioNode;
  }

  update (virtualGraphParams) {
    const virtualGraphParamsKeys = Object.keys(virtualGraphParams);

    Object.keys(this.virtualNodes).forEach(id => {
      if (virtualGraphParamsKeys.indexOf(id) === -1) {
        disconnect(this.virtualNodes[id]);
        delete this.virtualNodes[id];
      }
    });

    virtualGraphParamsKeys
      .forEach(key => {
        if (key === 'output') {
          throw new Error(`'output' is not a valid id`);
        }
        const virtualAudioNodeParams = virtualGraphParams[key];
        const [node, output] = virtualAudioNodeParams;
        if (output == null && node !== 'mediaStreamDestination') {
          throw new Error(`output not specified for node key ${key}`);
        }
        const virtualAudioNode = this.virtualNodes[key];
        if (virtualAudioNode == null) {
          this.virtualNodes[key] = createVirtualAudioNode.call(this, virtualAudioNodeParams);
          return;
        }
        if (startTimePath(virtualAudioNodeParams) !== startTimePath(virtualAudioNode) ||
          stopTimePath(virtualAudioNodeParams) !== stopTimePath(virtualAudioNode)) {
          disconnect(virtualAudioNode);
          delete this.virtualNodes[key];
        }
        updateAudioNodeAndVirtualAudioGraph.call(this, virtualAudioNode, virtualAudioNodeParams, key);
      });

    connectAudioNodes(this.virtualNodes,
                      virtualNode => connect(virtualNode, this.output));

    return this;
  }
}
<commit_msg>stored data in different form than params<commit_after>import capitalize from 'capitalize';
import connect from './helpers/connect';
import connectAudioNodes from './helpers/connectAudioNodes';
import createVirtualAudioNode from './helpers/createVirtualAudioNode';
import updateAudioNodeAndVirtualAudioGraph from './helpers/updateAudioNodeAndVirtualAudioGraph';
import disconnect from './helpers/disconnect';

const startTimePathParams = params => params[2] && params[2].startTime;
const stopTimePathParams = params => params[2] && params[2].stopTime;
const startTimePathStored = virtualNode => virtualNode.params && virtualNode.params.startTime;
const stopTimePathStored = virtualNode => virtualNode.params && virtualNode.params.stopTime;

export default class VirtualAudioGraph {
  constructor ({audioContext = new AudioContext(),
                output = audioContext.destination} = {}) {
    this.audioContext = audioContext;
    this.output = output;
    this.virtualNodes = {};
    this.customNodes = {};
  }

  get currentTime () {
    return this.audioContext.currentTime;
  }

  defineNode (customNodeParamsFactory, name) {
    if (this.audioContext[`create${capitalize(name)}`]) {
      throw new Error(`${name} is a standard audio node name and cannot be overwritten`);
    }

    this.customNodes[name] = customNodeParamsFactory;
    return this;
  }

  getAudioNodeById (id) {
    return this.virtualNodes[id].audioNode;
  }

  update (virtualGraphParams) {
    const virtualGraphParamsKeys = Object.keys(virtualGraphParams);

    Object.keys(this.virtualNodes).forEach(id => {
      if (virtualGraphParamsKeys.indexOf(id) === -1) {
        disconnect(this.virtualNodes[id]);
        delete this.virtualNodes[id];
      }
    });

    virtualGraphParamsKeys
      .forEach(key => {
        if (key === 'output') {
          throw new Error(`'output' is not a valid id`);
        }
        const virtualAudioNodeParams = virtualGraphParams[key];
        const [node, output] = virtualAudioNodeParams;
        if (output == null && node !== 'mediaStreamDestination') {
          throw new Error(`output not specified for node key ${key}`);
        }
        const virtualAudioNode = this.virtualNodes[key];
        if (virtualAudioNode == null) {
          this.virtualNodes[key] = createVirtualAudioNode.call(this, virtualAudioNodeParams);
          return;
        }
        if (startTimePathParams(virtualAudioNodeParams) !== startTimePathStored(virtualAudioNode) ||
          stopTimePathParams(virtualAudioNodeParams) !== stopTimePathStored(virtualAudioNode)) {
          disconnect(virtualAudioNode);
          delete this.virtualNodes[key];
        }
        updateAudioNodeAndVirtualAudioGraph.call(this, virtualAudioNode, virtualAudioNodeParams, key);
      });

    connectAudioNodes(this.virtualNodes,
                      virtualNode => connect(virtualNode, this.output));

    return this;
  }
}
<|endoftext|>


<commit_before>var mongoose = require('mongoose');

/**
 * botkit-storage-mongoose - MongoDB/Mongoose driver for Botkit
 *
 * @param  {Object} config Must contain a mongoUri property
 * @return {Object} A storage object conforming to the Botkit storage interface
 */
module.exports = function(config) {

    if (!config) {
        throw new Error('Need to provide mongo address or a mongoose instance');
    }

    if (!config.mongoUri && !config.db) {
        throw new Error('Need to provide mongo address or a mongoose instance');
    }

    var db = config.db || mongoose.createConnection(config.mongoUri);
    var storage = {};

    var zones = ['teams', 'channels', 'users'];

    config.tables && config.tables.forEach(function(table) {
        if (typeof table === 'string') zones.push(table);
    });

    zones.forEach(function(zone) {
        var model = createModel(db, zone);
        storage[zone] = getStorage(model);
    });

    return storage;
};

function createModel(db, zone) {
    var schema = new mongoose.Schema({}, {
        strict: false,
        collection: zone
    });
    return db.model(zone, schema);
}

function getStorage(table) {

    return {
        get: function(id, cb) {
            return table.findOne({
                id: id
            }).lean().exec(cb);
        },
        save: function(data, cb) {
            return table.findOneAndUpdate({
                id: data.id
            }, data, {
                upsert: true,
                new: true
            }).lean().exec(cb);
        },
        all: function(cb) {
            return table.find({}).lean().exec(cb);
        },
        find: function(data, cb, options) {
            return table.find(data ,null, options).lean().exec(cb);
        }
    };
}
<commit_msg>Update index.js<commit_after>var mongoose = require('mongoose');

/**
 * botkit-storage-mongoose - MongoDB/Mongoose driver for Botkit
 *
 * @param  {Object} config Must contain a mongoUri property
 * @return {Object} A storage object conforming to the Botkit storage interface
 */
module.exports = function(config) {

    if (!config) {
        throw new Error('Need to provide mongo address or a mongoose instance');
    }

    if (!config.mongoUri && !config.db) {
        throw new Error('Need to provide mongo address or a mongoose instance');
    }

    var db = config.db || mongoose.createConnection(config.mongoUri);
    var storage = {};

    var zones = ['teams', 'channels', 'users'];

    config.tables && config.tables.forEach(function(table) {
        if (typeof table === 'string') zones.push(table);
    });

    zones.forEach(function(zone) {
        var model = createModel(db, zone);
        storage[zone] = getStorage(model);
    });

    return storage;
};

function createModel(db, zone) {
    var schema = new mongoose.Schema({}, {
        strict: false,
        collection: zone
    });

    try {
        return db.model(zone, schema);
    } catch (e) {
        if(e.name === 'OverwriteModelError'){
            return db.model(zone);
        }
    }
}

function getStorage(table) {

    return {
        get: function(id, cb) {
            return table.findOne({
                id: id
            }).lean().exec(cb);
        },
        save: function(data, cb) {
            return table.findOneAndUpdate({
                id: data.id
            }, data, {
                upsert: true,
                new: true
            }).lean().exec(cb);
        },
        all: function(cb) {
            return table.find({}).lean().exec(cb);
        },
        find: function(data, cb, options) {
            return table.find(data ,null, options).lean().exec(cb);
        }
    };
}
<|endoftext|>


<commit_before>import 'babel-polyfill';
import {
	koaRouter
} from './router';
import context from './common/context';
//import context from './common/context';

const bodypraser = require('koa-bodyparser');
const mount = require('koa-mount');
const oauthserver = require('koa-oauth-server');
const model = require('./models/oauth.schema');

const Koa = require('koa');
//const mongoose = require('mongoose');
const app = new Koa();

app.oauth = oauthserver({
	model: model, // See https://github.com/thomseddon/node-oauth2-server for specification
	grants: ['password'],
	debug: true
});

app.use(bodypraser());

//import controllers to app, we should do this or our controller will not execute!
//把要使用到的controller引到当前app中，我们必须这样做，否则controller被不会被加载运行。
import controllers from './controllers';
controllers.bindRouters();

// Mount `oauth2` route prefix.
app.use(mount('/oauth2', koaRouter.middleware()));

// Register `/token` POST path on oauth router (i.e. `/oauth2/token`).
koaRouter.post('/token', app.oauth.grant());

app.use(koaRouter.routes())
	.use(koaRouter.allowedMethods());

var mongoose = require('mongoose');
mongoose.connect(context.dburl);

app.listen(8088);
console.log('server started : http://localhost:8088/');<commit_msg>remove oauth we will move the oauth to a separate service<commit_after>import 'babel-polyfill';
import {
	koaRouter
} from './router';
import context from './common/context';

const Koa = require('koa');
const app = new Koa();

//import controllers to app, we should do this or our controller will not execute!
//把要使用到的controller引到当前app中，我们必须这样做，否则controller被不会被加载运行。
import controllers from './controllers';
controllers.bindRouters();

app.use(koaRouter.routes())
	.use(koaRouter.allowedMethods());

var mongoose = require('mongoose');
mongoose.openUri(context.dburl);

app.listen(8088);
console.log('server started : http://localhost:8088/');<|endoftext|>


<commit_before>import toReference from "./helpers/ast/to-reference";
import toFunctionCall from "./helpers/ast/to-function-call";

import extractOpenArguments from "./helpers/extract-open-arguments";
import attrsToAttrCalls from "./helpers/attributes-to-attr-calls";
import buildChildren from "./helpers/build-children";
import flattenExpressions from "./helpers/flatten-expressions";
import filterEagerDeclarators from "./helpers/filter-eager-declarators";
import statementsWithReturnLast from "./helpers/statements-with-return-last";
import partitionDeclarators from "./helpers/partition-declarators";

import injectJSXWrapper from "./helpers/runtime/jsx-wrapper";

function nullObject() {
  return Object.create(null);
}

const jsxVisitor = {
  shouldSkip(path) {
    return path.node === path.state.node;
  },

  JSXElement(node, parent, scope, state) {
    state.otherJSX = true;
    this.stop();
  }
};

export default function ({ Plugin, types: t }) {
  return new Plugin("incremental-dom", { visitor : {
    Program: function(program, parent, scope, file) {
      // A map to store helper variable references
      // for each file
      file.setDynamic("incremental-dom-helpers", nullObject);

      // A map of semaphores for each helper, so that
      // a dependency is not injected multiple times.
      // We use this instead of only helperReferences,
      // so that we may create dependency references
      // and later unshift the actual definition,
      // placing dependency definitions before the
      // dependent.
      file.setDynamic("incremental-dom-helpers-defs", nullObject);
    },

    JSXElement: {
      enter(node) {
        const inReturnStatement = this.parentPath.isReturnStatement();
        const inCallExpression = this.parentPath.isCallExpression();
        let inLoop = false;
        let inAttribute = false;
        let inExpressionContainer = false;
        let inAssignment = false;
        let inCollection = false;
        let containingJSXElement;
        let eagerDeclarators = [];

        this.findParent((path) => {
          if (path.isJSXElement()) {
            containingJSXElement = path;
            return true;
          }
          if (path.isFunction() || path.isProgram()) {
            return true;
          }
          if (path.isJSXAttribute()) {
            inAttribute = true;
          } else if (path.isJSXExpressionContainer()) {
            inExpressionContainer = true;
          } else if (path.isAssignmentExpression() || path.isVariableDeclarator()) {
            inAssignment = true;
          } else if (path.isArrayExpression() || path.isObjectExpression()) {
            inCollection = true;
          } else if (path.isLoop()) {
            inLoop = true;
          }
        });

        let needsWrapper = inAttribute || inCollection;

        this.setData("inLoop", inLoop);
        this.setData("inAttribute", inAttribute);
        this.setData("inAssignment", inAssignment);
        this.setData("inCallExpression", inCallExpression);
        this.setData("inReturnStatement", inReturnStatement);
        this.setData("containingJSXElement", containingJSXElement);
        this.setData("inExpressionContainer", inExpressionContainer);

        // If we are somewhere inside a JSXExpressionContainer,
        // no need to worry about wrapping the children, since JSXElement
        // containing this container will be wrapped if needed.

        let state = { otherJSX: needsWrapper, node: node };
        let containerNeedsWrapper = false;
        if (containingJSXElement) {
           containerNeedsWrapper = containingJSXElement.getData("containerNeedsWrapper") || containingJSXElement.getData("needsWrapper");
        }

        if (!needsWrapper && !containerNeedsWrapper) {
          // Determine if there are JSXElement in higher scopes.
          this.findParent((path) => {
            if (path.isJSXElement()) {
              state.node = path.node;
            } else if (path.isFunction()) {
              path.parentPath.traverse(jsxVisitor, state);
            } else if (path.isProgram()) {
              path.traverse(jsxVisitor, state);
            }

            return state.otherJSX;
          });
          needsWrapper = state.otherJSX;
        }

        this.setData("needsWrapper", needsWrapper);
        this.setData("containerNeedsWrapper", containerNeedsWrapper);
        if (containingJSXElement) {
          eagerDeclarators = containingJSXElement.getData("eagerDeclarators");
        }
        this.setData("eagerDeclarators", eagerDeclarators);
      },

      exit(node, parent, scope, file) {
        // Filter out empty children, and transform JSX expressions
        // into normal expressions.
        const openingElement = node.openingElement;
        const closingElement = node.closingElement;
        const eager = this.getData("needsWrapper") || this.getData("containerNeedsWrapper");
        const children = buildChildren(t, scope, file, node.children, eager);
        const containingJSXElement = this.getData("containingJSXElement");
        const needsWrapper = this.getData("needsWrapper");
        const inLoop = this.getData("inLoop");
        const inAttribute = this.getData("inAttribute");
        const inAssignment = this.getData("inAssignment");
        const inCallExpression = this.getData("inCallExpression");
        const eagerDeclarators = this.getData("eagerDeclarators");
        const inReturnStatement = this.getData("inReturnStatement");
        const inExpressionContainer = this.getData("inExpressionContainer");

        let elements = [
          openingElement,
          ...children
        ];
        if (closingElement) { elements.push(closingElement); }

        // If we're inside a JSX node, flattening expressions
        // may force us into an unwanted function scope.
        if (t.isJSXElement(parent)) {
          elements = filterEagerDeclarators(t, elements, eagerDeclarators);
          return elements;
        } else if (inExpressionContainer && !needsWrapper) {
          let sequence = t.sequenceExpression(elements);
          sequence._wasJSX = true;
          return sequence;
        }

        // Values are useless if they aren't assigned.
        // ```
        //   var a = 1;
        //   <div /> // Useless JSX node
        // ```
        if (!(inReturnStatement || inAssignment || inCallExpression || inExpressionContainer)) {
          this.dangerouslyRemove();
          return;
        }

        elements = flattenExpressions(t, elements);

        if (needsWrapper) {
          elements = filterEagerDeclarators(t, elements, eagerDeclarators);
        }

        let parentStatement = this.findParent((path) => {
          return path.isStatement();
        });

        if (eagerDeclarators.length && !inExpressionContainer) {
          let declaration = t.variableDeclaration("let", eagerDeclarators);
          parentStatement.insertBefore(declaration);
        }

        elements = statementsWithReturnLast(t, elements);

        if (needsWrapper) {
          const jsxWrapperRef = injectJSXWrapper(t, file);
          const wrapper = toFunctionCall(t, jsxWrapperRef, [
            t.functionExpression(null, [], t.blockStatement(elements))
          ])
          wrapper._wasJSX = true;
          return wrapper;
        } else {
          this.parentPath.replaceWithMultiple(elements);
          return;
        }
      }
    },

    JSXOpeningElement: {
      exit(node, parent, scope, file) {
        let tag = toReference(t, node.name);
        let args = [tag];
        let elementFunction = node.selfClosing ? "elementVoid" : "elementOpen";
        let parentPath = this.parentPath;
        let eager = parentPath.getData("needsWrapper") || parentPath.getData("containerNeedsWrapper");
        let {
          key,
          statics,
          attrs,
          attributeDeclarators,
          hasSpread
        } = extractOpenArguments(t, scope, node.attributes, eager);

        // Only push arguments if they're needed
        if (key || statics) {
          args.push(key || t.literal(null));
        }
        if (statics) {
          args.push(t.arrayExpression(statics));
        }

        parentPath.getData("eagerDeclarators").push(...attributeDeclarators);

        // If there is a spread element, we need to use
        // the elementOpenStart/elementOpenEnd syntax.
        // This allows spreads to be transformed into
        // attr(name, value) calls.
        if (hasSpread) {
          attrs = attrsToAttrCalls(t, file, attrs);

          let expressions = [
            toFunctionCall(t, "elementOpenStart", args),
            ...attrs,
            toFunctionCall(t, "elementOpenEnd", [tag])
          ];
          if (node.selfClosing) {
            expressions.push(toFunctionCall(t, "elementClose", [tag]));
          }

          return t.sequenceExpression(expressions);
        } else if (attrs) {

          // Only push key and statics if they have not
          // already been pushed.
          if (!statics) {
            if (!key) {
              args.push(t.literal(null));
            }
            args.push(t.literal(null));
          }

          for (let [name, value] of attrs) {
            args.push(name, value);
          }
        }

        return toFunctionCall(t, elementFunction, args);
      }
    },

    JSXClosingElement: {
      exit(node) {
        return toFunctionCall(t, "elementClose", [toReference(t, node.name)]);
      }
    }
  }});
}
<commit_msg>Remove unused inLoop<commit_after>import toReference from "./helpers/ast/to-reference";
import toFunctionCall from "./helpers/ast/to-function-call";

import extractOpenArguments from "./helpers/extract-open-arguments";
import attrsToAttrCalls from "./helpers/attributes-to-attr-calls";
import buildChildren from "./helpers/build-children";
import flattenExpressions from "./helpers/flatten-expressions";
import filterEagerDeclarators from "./helpers/filter-eager-declarators";
import statementsWithReturnLast from "./helpers/statements-with-return-last";
import partitionDeclarators from "./helpers/partition-declarators";

import injectJSXWrapper from "./helpers/runtime/jsx-wrapper";

function nullObject() {
  return Object.create(null);
}

const jsxVisitor = {
  shouldSkip(path) {
    return path.node === path.state.node;
  },

  JSXElement(node, parent, scope, state) {
    state.otherJSX = true;
    this.stop();
  }
};

export default function ({ Plugin, types: t }) {
  return new Plugin("incremental-dom", { visitor : {
    Program: function(program, parent, scope, file) {
      // A map to store helper variable references
      // for each file
      file.setDynamic("incremental-dom-helpers", nullObject);

      // A map of semaphores for each helper, so that
      // a dependency is not injected multiple times.
      // We use this instead of only helperReferences,
      // so that we may create dependency references
      // and later unshift the actual definition,
      // placing dependency definitions before the
      // dependent.
      file.setDynamic("incremental-dom-helpers-defs", nullObject);
    },

    JSXElement: {
      enter(node) {
        const inReturnStatement = this.parentPath.isReturnStatement();
        const inCallExpression = this.parentPath.isCallExpression();
        let inAttribute = false;
        let inExpressionContainer = false;
        let inAssignment = false;
        let inCollection = false;
        let containingJSXElement;
        let eagerDeclarators = [];

        this.findParent((path) => {
          if (path.isJSXElement()) {
            containingJSXElement = path;
            return true;
          }
          if (path.isFunction() || path.isProgram()) {
            return true;
          }
          if (path.isJSXAttribute()) {
            inAttribute = true;
          } else if (path.isJSXExpressionContainer()) {
            inExpressionContainer = true;
          } else if (path.isAssignmentExpression() || path.isVariableDeclarator()) {
            inAssignment = true;
          } else if (path.isArrayExpression() || path.isObjectExpression()) {
            inCollection = true;
          }
        });

        let needsWrapper = inAttribute || inCollection;

        this.setData("inAttribute", inAttribute);
        this.setData("inAssignment", inAssignment);
        this.setData("inCallExpression", inCallExpression);
        this.setData("inReturnStatement", inReturnStatement);
        this.setData("containingJSXElement", containingJSXElement);
        this.setData("inExpressionContainer", inExpressionContainer);

        // If we are somewhere inside a JSXExpressionContainer,
        // no need to worry about wrapping the children, since JSXElement
        // containing this container will be wrapped if needed.

        let state = { otherJSX: needsWrapper, node: node };
        let containerNeedsWrapper = false;
        if (containingJSXElement) {
           containerNeedsWrapper = containingJSXElement.getData("containerNeedsWrapper") || containingJSXElement.getData("needsWrapper");
        }

        if (!needsWrapper && !containerNeedsWrapper) {
          // Determine if there are JSXElement in higher scopes.
          this.findParent((path) => {
            if (path.isJSXElement()) {
              state.node = path.node;
            } else if (path.isFunction()) {
              path.parentPath.traverse(jsxVisitor, state);
            } else if (path.isProgram()) {
              path.traverse(jsxVisitor, state);
            }

            return state.otherJSX;
          });
          needsWrapper = state.otherJSX;
        }

        this.setData("needsWrapper", needsWrapper);
        this.setData("containerNeedsWrapper", containerNeedsWrapper);
        if (containingJSXElement) {
          eagerDeclarators = containingJSXElement.getData("eagerDeclarators");
        }
        this.setData("eagerDeclarators", eagerDeclarators);
      },

      exit(node, parent, scope, file) {
        // Filter out empty children, and transform JSX expressions
        // into normal expressions.
        const openingElement = node.openingElement;
        const closingElement = node.closingElement;
        const eager = this.getData("needsWrapper") || this.getData("containerNeedsWrapper");
        const children = buildChildren(t, scope, file, node.children, eager);
        const containingJSXElement = this.getData("containingJSXElement");
        const needsWrapper = this.getData("needsWrapper");
        const inAttribute = this.getData("inAttribute");
        const inAssignment = this.getData("inAssignment");
        const inCallExpression = this.getData("inCallExpression");
        const eagerDeclarators = this.getData("eagerDeclarators");
        const inReturnStatement = this.getData("inReturnStatement");
        const inExpressionContainer = this.getData("inExpressionContainer");

        let elements = [
          openingElement,
          ...children
        ];
        if (closingElement) { elements.push(closingElement); }

        // If we're inside a JSX node, flattening expressions
        // may force us into an unwanted function scope.
        if (t.isJSXElement(parent)) {
          elements = filterEagerDeclarators(t, elements, eagerDeclarators);
          return elements;
        } else if (inExpressionContainer && !needsWrapper) {
          let sequence = t.sequenceExpression(elements);
          sequence._wasJSX = true;
          return sequence;
        }

        // Values are useless if they aren't assigned.
        // ```
        //   var a = 1;
        //   <div /> // Useless JSX node
        // ```
        if (!(inReturnStatement || inAssignment || inCallExpression || inExpressionContainer)) {
          this.dangerouslyRemove();
          return;
        }

        elements = flattenExpressions(t, elements);

        if (needsWrapper) {
          elements = filterEagerDeclarators(t, elements, eagerDeclarators);
        }

        let parentStatement = this.findParent((path) => {
          return path.isStatement();
        });

        if (eagerDeclarators.length && !inExpressionContainer) {
          let declaration = t.variableDeclaration("let", eagerDeclarators);
          parentStatement.insertBefore(declaration);
        }

        elements = statementsWithReturnLast(t, elements);

        if (needsWrapper) {
          const jsxWrapperRef = injectJSXWrapper(t, file);
          const wrapper = toFunctionCall(t, jsxWrapperRef, [
            t.functionExpression(null, [], t.blockStatement(elements))
          ])
          wrapper._wasJSX = true;
          return wrapper;
        } else {
          this.parentPath.replaceWithMultiple(elements);
          return;
        }
      }
    },

    JSXOpeningElement: {
      exit(node, parent, scope, file) {
        let tag = toReference(t, node.name);
        let args = [tag];
        let elementFunction = node.selfClosing ? "elementVoid" : "elementOpen";
        let parentPath = this.parentPath;
        let eager = parentPath.getData("needsWrapper") || parentPath.getData("containerNeedsWrapper");
        let {
          key,
          statics,
          attrs,
          attributeDeclarators,
          hasSpread
        } = extractOpenArguments(t, scope, node.attributes, eager);

        // Only push arguments if they're needed
        if (key || statics) {
          args.push(key || t.literal(null));
        }
        if (statics) {
          args.push(t.arrayExpression(statics));
        }

        parentPath.getData("eagerDeclarators").push(...attributeDeclarators);

        // If there is a spread element, we need to use
        // the elementOpenStart/elementOpenEnd syntax.
        // This allows spreads to be transformed into
        // attr(name, value) calls.
        if (hasSpread) {
          attrs = attrsToAttrCalls(t, file, attrs);

          let expressions = [
            toFunctionCall(t, "elementOpenStart", args),
            ...attrs,
            toFunctionCall(t, "elementOpenEnd", [tag])
          ];
          if (node.selfClosing) {
            expressions.push(toFunctionCall(t, "elementClose", [tag]));
          }

          return t.sequenceExpression(expressions);
        } else if (attrs) {

          // Only push key and statics if they have not
          // already been pushed.
          if (!statics) {
            if (!key) {
              args.push(t.literal(null));
            }
            args.push(t.literal(null));
          }

          for (let [name, value] of attrs) {
            args.push(name, value);
          }
        }

        return toFunctionCall(t, elementFunction, args);
      }
    },

    JSXClosingElement: {
      exit(node) {
        return toFunctionCall(t, "elementClose", [toReference(t, node.name)]);
      }
    }
  }});
}
<|endoftext|>


<commit_before>var DEFAULT_NODE = 0
var RECYCLED_NODE = 1
var LAZY_NODE = 2
var TEXT_NODE = 3
var EMPTY_OBJECT = {}
var EMPTY_ARRAY = []
var map = EMPTY_ARRAY.map
var isArray = Array.isArray
var defer = requestAnimationFrame || setTimeout

var createClass = function(obj) {
  var out = ""
  var tmp = typeof obj

  if (tmp === "string" || tmp === "number") return obj

  if (isArray(obj) && obj.length > 0) {
    for (var i = 0; i < obj.length; i++) {
      if ((tmp = createClass(obj[i])) !== "") out += (out && " ") + tmp
    }
  } else {
    for (var i in obj) {
      if (obj[i]) out += (out && " ") + i
    }
  }

  return out
}

var merge = function(a, b) {
  var out = {}

  for (var i in a) out[i] = a[i]
  for (var i in b) out[i] = b[i]

  return out
}

var flatten = function(arr) {
  return arr.reduce(function(out, obj) {
    return out.concat(
      !obj || obj === true
        ? false
        : typeof obj[0] === "function"
        ? [obj]
        : flatten(obj)
    )
  }, EMPTY_ARRAY)
}

var isSameAction = function(a, b) {
  return isArray(a) && isArray(b) && a[0] === b[0] && typeof a[0] === "function"
}

var shouldRestart = function(a, b) {
  for (var k in merge(a, b)) {
    if (a[k] === b[k] || isSameAction(a[k], b[k])) b[k] = a[k]
    else return true
  }
}

var patchSub = function(sub, newSub, dispatch) {
  for (var i = 0, a, b, out = []; i < sub.length || i < newSub.length; i++) {
    a = sub[i]
    out.push(
      (b = newSub[i])
        ? !a || b[0] !== a[0] || shouldRestart(b[1], a[1])
          ? [b[0], b[1], b[0](b[1], dispatch), a && a[2]()]
          : a
        : a && a[2]()
    )
  }
  return out
}

var updateProperty = function(element, name, value, newValue, eventCb, isSvg) {
  if (name === "key") {
  } else if (name === "style") {
    for (var i in merge(value, newValue)) {
      var style = newValue == null || newValue[i] == null ? "" : newValue[i]
      if (i[0] === "-") {
        element[name].setProperty(i, style)
      } else {
        element[name][i] = style
      }
    }
  } else if (name[0] === "o" && name[1] === "n") {
    if (
      !((element.events || (element.events = {}))[
        (name = name.slice(2))
      ] = newValue)
    ) {
      element.removeEventListener(name, eventCb)
    } else if (!value) {
      element.addEventListener(name, eventCb)
    }
  } else if (name !== "list" && !isSvg && name in element) {
    element[name] = newValue == null ? "" : newValue
  } else if (
    newValue == null ||
    newValue === false ||
    (name === "class" && !(newValue = createClass(newValue)))
  ) {
    element.removeAttribute(name)
  } else {
    element.setAttribute(name, newValue)
  }
}

var removeElement = function(parent, node) {
  parent.removeChild(node.element)
}

var createElement = function(node, eventCb, isSvg) {
  var element =
    node.type === TEXT_NODE
      ? document.createTextNode(node.name)
      : (isSvg = isSvg || node.name === "svg")
      ? document.createElementNS("http://www.w3.org/2000/svg", node.name)
      : document.createElement(node.name)
  var props = node.props

  for (var k in props) {
    updateProperty(element, k, null, props[k], eventCb, isSvg)
  }

  for (var i = 0, len = node.children.length; i < len; i++) {
    element.appendChild(
      createElement(
        (node.children[i] = getNode(node.children[i])),
        eventCb,
        isSvg
      )
    )
  }

  return (node.element = element)
}

var updateElement = function(element, props, newProps, eventCb, isSvg) {
  for (var k in merge(props, newProps)) {
    if (
      (k === "value" || k === "selected" || k === "checked"
        ? element[k]
        : props[k]) !== newProps[k]
    ) {
      updateProperty(element, k, props[k], newProps[k], eventCb, isSvg)
    }
  }
}

var getKey = function(node) {
  return node == null ? null : node.key
}

var patch = function(parent, element, node, newNode, eventCb, isSvg) {
  if (newNode === node) {
  } else if (
    node != null &&
    node.type === TEXT_NODE &&
    newNode.type === TEXT_NODE
  ) {
    if (node.name !== newNode.name) element.nodeValue = newNode.name
  } else if (node == null || node.name !== newNode.name) {
    var newElement = parent.insertBefore(
      createElement((newNode = getNode(newNode)), eventCb, isSvg),
      element
    )

    if (node != null) removeElement(parent, node)

    element = newElement
  } else {
    updateElement(
      element,
      node.props,
      newNode.props,
      eventCb,
      (isSvg = isSvg || newNode.name === "svg")
    )

    var savedNode
    var childNode

    var key
    var children = node.children
    var start = 0
    var end = children.length - 1

    var newKey
    var newChildren = newNode.children
    var newStart = 0
    var newEnd = newChildren.length - 1

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[start])
      newKey = getKey(newChildren[newStart])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[start].element,
        children[start],
        (newChildren[newStart] = getNode(
          newChildren[newStart],
          children[start]
        )),
        eventCb,
        isSvg
      )

      start++
      newStart++
    }

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[end])
      newKey = getKey(newChildren[newEnd])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[end].element,
        children[end],
        (newChildren[newEnd] = getNode(newChildren[newEnd], children[end])),
        eventCb,
        isSvg
      )

      end--
      newEnd--
    }

    if (start > end) {
      while (newStart <= newEnd) {
        element.insertBefore(
          createElement(
            (newChildren[newStart] = getNode(newChildren[newStart++])),
            eventCb,
            isSvg
          ),
          (childNode = children[start]) && childNode.element
        )
      }
    } else if (newStart > newEnd) {
      while (start <= end) {
        removeElement(element, children[start++])
      }
    } else {
      for (var i = start, keyed = {}, newKeyed = {}; i <= end; i++) {
        if ((key = children[i].key) != null) {
          keyed[key] = children[i]
        }
      }

      while (newStart <= newEnd) {
        key = getKey((childNode = children[start]))
        newKey = getKey(
          (newChildren[newStart] = getNode(newChildren[newStart], childNode))
        )

        if (
          newKeyed[key] ||
          (newKey != null && newKey === getKey(children[start + 1]))
        ) {
          if (key == null) {
            removeElement(element, childNode)
          }
          start++
          continue
        }

        if (newKey == null || node.type === RECYCLED_NODE) {
          if (key == null) {
            patch(
              element,
              childNode && childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newStart++
          }
          start++
        } else {
          if (key === newKey) {
            patch(
              element,
              childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newKeyed[newKey] = true
            start++
          } else {
            if ((savedNode = keyed[newKey]) != null) {
              patch(
                element,
                element.insertBefore(
                  savedNode.element,
                  childNode && childNode.element
                ),
                savedNode,
                newChildren[newStart],
                eventCb,
                isSvg
              )
              newKeyed[newKey] = true
            } else {
              patch(
                element,
                childNode && childNode.element,
                null,
                newChildren[newStart],
                eventCb,
                isSvg
              )
            }
          }
          newStart++
        }
      }

      while (start <= end) {
        if (getKey((childNode = children[start++])) == null) {
          removeElement(element, childNode)
        }
      }

      for (var key in keyed) {
        if (newKeyed[key] == null) {
          removeElement(element, keyed[key])
        }
      }
    }
  }

  return (newNode.element = element)
}

var shouldUpdate = function(a, b) {
  for (var k in a) if (a[k] !== b[k]) return true
  for (var k in b) if (a[k] !== b[k]) return true
}

var getNode = function(newNode, node) {
  return newNode.type === LAZY_NODE
    ? !node || shouldUpdate(newNode.lazy, node.lazy)
      ? newNode.render()
      : node
    : newNode
}

var createVNode = function(name, props, children, element, key, type) {
  return {
    name: name,
    props: props,
    children: children,
    element: element,
    type: type,
    key: key
  }
}

var createTextVNode = function(text, element) {
  return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
}

var recycleElement = function(element) {
  return element.nodeType === TEXT_NODE
    ? createTextVNode(element.nodeValue, element)
    : createVNode(
        element.nodeName.toLowerCase(),
        EMPTY_OBJECT,
        map.call(element.childNodes, recycleElement),
        element,
        null,
        RECYCLED_NODE
      )
}

export var Lazy = function(props) {
  return {
    type: LAZY_NODE,
    key: props.key,
    lazy: props,
    render: function() {
      var node = props.render(props)
      node.lazy = props
      return node
    }
  }
}

export var h = function(name, props) {
  for (var node, rest = [], children = [], i = arguments.length; i-- > 2; ) {
    rest.push(arguments[i])
  }

  while (rest.length > 0) {
    if (isArray((node = rest.pop()))) {
      for (i = node.length; i-- > 0; ) rest.push(node[i])
    } else if (node === false || node === true || node == null) {
    } else {
      children.push(typeof node === "object" ? node : createTextVNode(node))
    }
  }

  props = props || EMPTY_OBJECT

  return typeof name === "function"
    ? name(props, children)
    : createVNode(name, props, children, null, props.key, DEFAULT_NODE)
}

export var app = function(props, decorateDispatch) {
  var container = props.container
  var element = container && container.children[0]
  var node = element && recycleElement(element)
  var subs = props.subscriptions
  var view = props.view
  var lock = false
  var state = {}
  var sub = []
  var decorator = decorateDispatch || (function (d) { return d })

  var eventCb = function(event) {
    dispatch(event.currentTarget.events[event.type], event)
  }

  var setState = function(newState) {
    if (!(state === newState || lock)) defer(render, (lock = true))
    state = newState
  }

  var dispatch = decorator(function(obj, props) {
    if (typeof obj === "function") {
      dispatch(obj(state, props))
    } else if (isArray(obj)) {
      if (typeof obj[0] === "function") {
        dispatch(obj[0](state, obj[1], props))
      } else {
        flatten(obj.slice(1)).map(function(fx) {
          fx && fx[0](fx[1], dispatch)
        }, setState(obj[0]))
      }
    } else {
      setState(obj)
    }
  })

  var render = function() {
    lock = false
    if (subs) sub = patchSub(sub, flatten(subs(state)), dispatch)
    if (view) {
      element = patch(container, element, node, (node = view(state)), eventCb)
    }
  }

  dispatch(props.init)
}
<commit_msg>Consolidate custom/default payload into one argument (#830)<commit_after>var DEFAULT_NODE = 0
var RECYCLED_NODE = 1
var LAZY_NODE = 2
var TEXT_NODE = 3
var EMPTY_OBJECT = {}
var EMPTY_ARRAY = []
var map = EMPTY_ARRAY.map
var isArray = Array.isArray
var defer = requestAnimationFrame || setTimeout

var createClass = function(obj) {
  var out = ""
  var tmp = typeof obj

  if (tmp === "string" || tmp === "number") return obj

  if (isArray(obj) && obj.length > 0) {
    for (var i = 0; i < obj.length; i++) {
      if ((tmp = createClass(obj[i])) !== "") out += (out && " ") + tmp
    }
  } else {
    for (var i in obj) {
      if (obj[i]) out += (out && " ") + i
    }
  }

  return out
}

var merge = function(a, b) {
  var out = {}

  for (var i in a) out[i] = a[i]
  for (var i in b) out[i] = b[i]

  return out
}

var flatten = function(arr) {
  return arr.reduce(function(out, obj) {
    return out.concat(
      !obj || obj === true
        ? false
        : typeof obj[0] === "function"
        ? [obj]
        : flatten(obj)
    )
  }, EMPTY_ARRAY)
}

var isSameAction = function(a, b) {
  return isArray(a) && isArray(b) && a[0] === b[0] && typeof a[0] === "function"
}

var shouldRestart = function(a, b) {
  for (var k in merge(a, b)) {
    if (a[k] === b[k] || isSameAction(a[k], b[k])) b[k] = a[k]
    else return true
  }
}

var patchSub = function(sub, newSub, dispatch) {
  for (var i = 0, a, b, out = []; i < sub.length || i < newSub.length; i++) {
    a = sub[i]
    out.push(
      (b = newSub[i])
        ? !a || b[0] !== a[0] || shouldRestart(b[1], a[1])
          ? [b[0], b[1], b[0](b[1], dispatch), a && a[2]()]
          : a
        : a && a[2]()
    )
  }
  return out
}

var updateProperty = function(element, name, value, newValue, eventCb, isSvg) {
  if (name === "key") {
  } else if (name === "style") {
    for (var i in merge(value, newValue)) {
      var style = newValue == null || newValue[i] == null ? "" : newValue[i]
      if (i[0] === "-") {
        element[name].setProperty(i, style)
      } else {
        element[name][i] = style
      }
    }
  } else if (name[0] === "o" && name[1] === "n") {
    if (
      !((element.events || (element.events = {}))[
        (name = name.slice(2))
      ] = newValue)
    ) {
      element.removeEventListener(name, eventCb)
    } else if (!value) {
      element.addEventListener(name, eventCb)
    }
  } else if (name !== "list" && !isSvg && name in element) {
    element[name] = newValue == null ? "" : newValue
  } else if (
    newValue == null ||
    newValue === false ||
    (name === "class" && !(newValue = createClass(newValue)))
  ) {
    element.removeAttribute(name)
  } else {
    element.setAttribute(name, newValue)
  }
}

var removeElement = function(parent, node) {
  parent.removeChild(node.element)
}

var createElement = function(node, eventCb, isSvg) {
  var element =
    node.type === TEXT_NODE
      ? document.createTextNode(node.name)
      : (isSvg = isSvg || node.name === "svg")
      ? document.createElementNS("http://www.w3.org/2000/svg", node.name)
      : document.createElement(node.name)
  var props = node.props

  for (var k in props) {
    updateProperty(element, k, null, props[k], eventCb, isSvg)
  }

  for (var i = 0, len = node.children.length; i < len; i++) {
    element.appendChild(
      createElement(
        (node.children[i] = getNode(node.children[i])),
        eventCb,
        isSvg
      )
    )
  }

  return (node.element = element)
}

var updateElement = function(element, props, newProps, eventCb, isSvg) {
  for (var k in merge(props, newProps)) {
    if (
      (k === "value" || k === "selected" || k === "checked"
        ? element[k]
        : props[k]) !== newProps[k]
    ) {
      updateProperty(element, k, props[k], newProps[k], eventCb, isSvg)
    }
  }
}

var getKey = function(node) {
  return node == null ? null : node.key
}

var patch = function(parent, element, node, newNode, eventCb, isSvg) {
  if (newNode === node) {
  } else if (
    node != null &&
    node.type === TEXT_NODE &&
    newNode.type === TEXT_NODE
  ) {
    if (node.name !== newNode.name) element.nodeValue = newNode.name
  } else if (node == null || node.name !== newNode.name) {
    var newElement = parent.insertBefore(
      createElement((newNode = getNode(newNode)), eventCb, isSvg),
      element
    )

    if (node != null) removeElement(parent, node)

    element = newElement
  } else {
    updateElement(
      element,
      node.props,
      newNode.props,
      eventCb,
      (isSvg = isSvg || newNode.name === "svg")
    )

    var savedNode
    var childNode

    var key
    var children = node.children
    var start = 0
    var end = children.length - 1

    var newKey
    var newChildren = newNode.children
    var newStart = 0
    var newEnd = newChildren.length - 1

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[start])
      newKey = getKey(newChildren[newStart])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[start].element,
        children[start],
        (newChildren[newStart] = getNode(
          newChildren[newStart],
          children[start]
        )),
        eventCb,
        isSvg
      )

      start++
      newStart++
    }

    while (newStart <= newEnd && start <= end) {
      key = getKey(children[end])
      newKey = getKey(newChildren[newEnd])

      if (key == null || key !== newKey) break

      patch(
        element,
        children[end].element,
        children[end],
        (newChildren[newEnd] = getNode(newChildren[newEnd], children[end])),
        eventCb,
        isSvg
      )

      end--
      newEnd--
    }

    if (start > end) {
      while (newStart <= newEnd) {
        element.insertBefore(
          createElement(
            (newChildren[newStart] = getNode(newChildren[newStart++])),
            eventCb,
            isSvg
          ),
          (childNode = children[start]) && childNode.element
        )
      }
    } else if (newStart > newEnd) {
      while (start <= end) {
        removeElement(element, children[start++])
      }
    } else {
      for (var i = start, keyed = {}, newKeyed = {}; i <= end; i++) {
        if ((key = children[i].key) != null) {
          keyed[key] = children[i]
        }
      }

      while (newStart <= newEnd) {
        key = getKey((childNode = children[start]))
        newKey = getKey(
          (newChildren[newStart] = getNode(newChildren[newStart], childNode))
        )

        if (
          newKeyed[key] ||
          (newKey != null && newKey === getKey(children[start + 1]))
        ) {
          if (key == null) {
            removeElement(element, childNode)
          }
          start++
          continue
        }

        if (newKey == null || node.type === RECYCLED_NODE) {
          if (key == null) {
            patch(
              element,
              childNode && childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newStart++
          }
          start++
        } else {
          if (key === newKey) {
            patch(
              element,
              childNode.element,
              childNode,
              newChildren[newStart],
              eventCb,
              isSvg
            )
            newKeyed[newKey] = true
            start++
          } else {
            if ((savedNode = keyed[newKey]) != null) {
              patch(
                element,
                element.insertBefore(
                  savedNode.element,
                  childNode && childNode.element
                ),
                savedNode,
                newChildren[newStart],
                eventCb,
                isSvg
              )
              newKeyed[newKey] = true
            } else {
              patch(
                element,
                childNode && childNode.element,
                null,
                newChildren[newStart],
                eventCb,
                isSvg
              )
            }
          }
          newStart++
        }
      }

      while (start <= end) {
        if (getKey((childNode = children[start++])) == null) {
          removeElement(element, childNode)
        }
      }

      for (var key in keyed) {
        if (newKeyed[key] == null) {
          removeElement(element, keyed[key])
        }
      }
    }
  }

  return (newNode.element = element)
}

var shouldUpdate = function(a, b) {
  for (var k in a) if (a[k] !== b[k]) return true
  for (var k in b) if (a[k] !== b[k]) return true
}

var getNode = function(newNode, node) {
  return newNode.type === LAZY_NODE
    ? !node || shouldUpdate(newNode.lazy, node.lazy)
      ? newNode.render()
      : node
    : newNode
}

var createVNode = function(name, props, children, element, key, type) {
  return {
    name: name,
    props: props,
    children: children,
    element: element,
    type: type,
    key: key
  }
}

var createTextVNode = function(text, element) {
  return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
}

var recycleElement = function(element) {
  return element.nodeType === TEXT_NODE
    ? createTextVNode(element.nodeValue, element)
    : createVNode(
        element.nodeName.toLowerCase(),
        EMPTY_OBJECT,
        map.call(element.childNodes, recycleElement),
        element,
        null,
        RECYCLED_NODE
      )
}

export var Lazy = function(props) {
  return {
    type: LAZY_NODE,
    key: props.key,
    lazy: props,
    render: function() {
      var node = props.render(props)
      node.lazy = props
      return node
    }
  }
}

export var h = function(name, props) {
  for (var node, rest = [], children = [], i = arguments.length; i-- > 2; ) {
    rest.push(arguments[i])
  }

  while (rest.length > 0) {
    if (isArray((node = rest.pop()))) {
      for (i = node.length; i-- > 0; ) rest.push(node[i])
    } else if (node === false || node === true || node == null) {
    } else {
      children.push(typeof node === "object" ? node : createTextVNode(node))
    }
  }

  props = props || EMPTY_OBJECT

  return typeof name === "function"
    ? name(props, children)
    : createVNode(name, props, children, null, props.key, DEFAULT_NODE)
}

export var app = function(props, enhance) {
  var container = props.container
  var element = container && container.children[0]
  var node = element && recycleElement(element)
  var subs = props.subscriptions
  var view = props.view
  var lock = false
  var state = {}
  var sub = []

  var eventCb = function(event) {
    dispatch(event.currentTarget.events[event.type], event)
  }

  var setState = function(newState) {
    return (
      state === newState || lock || defer(render, (lock = true)),
      (state = newState)
    )
  }

  var dispatch = (enhance ||
    function(a) {
      return a
    })(function(obj, props) {
    return typeof obj === "function"
      ? dispatch(obj(state, props))
      : isArray(obj)
      ? typeof obj[0] === "function"
        ? dispatch(obj[0], typeof obj[1] === "function" ? obj[1](props) : obj[1])
        : (flatten(obj.slice(1)).map(function(fx) {
            fx && fx[0](fx[1], dispatch)
          }, setState(obj[0])),
          state)
      : setState(obj)
  })

  var render = function() {
    lock = false
    if (subs) sub = patchSub(sub, flatten(subs(state)), dispatch)
    if (view) {
      element = patch(container, element, node, (node = view(state)), eventCb)
    }
  }

  dispatch(props.init)
}
<|endoftext|>