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

CLASS({
  package: 'foam.dao',
  name: 'EasyDAO',
  extendsModel: 'foam.dao.ProxyDAO',

  requires: [
    'MDAO',
    'foam.core.dao.CloningDAO',
    'foam.core.dao.MigrationDAO',
    'foam.core.dao.StorageDAO',
    'foam.dao.CachingDAO',
    'foam.dao.ContextualizingDAO',
    'foam.dao.DeDupDAO',
    'foam.dao.GUIDDAO',
    'foam.dao.SeqNoDAO'
  ],

  help: 'A facade for easy DAO setup.',

  documentation: function() {/*

If you don't know which $$DOC{ref:'DAO'} implementation to choose, $$DOC{ref:'foam.dao.EasyDAO'} is
    ready to help. Simply this.X.EasyDAO.create() and set the flags
    to indicate what behavior you're looking for. Under the hood, $$DOC{ref:'foam.dao.EasyDAO'}
    will create one or more $$DOC{ref:'DAO'} instances to service your requirements.

Since $$DOC{ref:'foam.dao.EasyDAO'} is a proxy, just use it like you would any other
    $$DOC{ref:'DAO'}, without worrying about the internal $$DOC{ref:'DAO'} doing the
    work.

  */},

  properties: [
    {
      name: 'name',
      defaultValueFn: function() { return this.model.plural; },
      documentation: "The developer-friendly name for this $$DOC{ref:'.'}."
    },
    {
      model_: 'BooleanProperty',
      name: 'seqNo',
      defaultValue: false,
      documentation: "Have $$DOC{ref:'.'} use a sequence number to index items. Note that $$DOC{ref:'.seqNo'} and $$DOC{ref:'.guid'} features are mutually exclusive."
    },
    {
      model_: 'BooleanProperty',
      name: 'guid',
      label: 'GUID',
      defaultValue: false,
      documentation: "Have $$DOC{ref:'.'} generate guids to index items. Note that $$DOC{ref:'.seqNo'} and $$DOC{ref:'.guid'} features are mutually exclusive."
    },
    {
      name: 'seqProperty',
      type: 'Property',
      documentation: "The property on your items to use to store the sequence number or guid. This is required for $$DOC{ref:'.seqNo'} or $$DOC{ref:'.guid'} mode."
    },
    {
      model_: 'BooleanProperty',
      name: 'cache',
      defaultValue: false,
      documentation: "Enable local caching of the $$DOC{ref:'DAO'}."
    },
    {
      model_: 'BooleanProperty',
      name: 'dedup',
      defaultValue: false,
      documentation: "Enable value de-duplication to save memory when caching."
    },
    {
      model_: 'BooleanProperty',
      name: 'logging',
      defaultValue: false,
      documentation: "Enable logging on the $$DOC{ref:'DAO'}."
    },
    {
      model_: 'BooleanProperty',
      name: 'timing',
      defaultValue: false,
      documentation: "Enable time tracking for concurrent $$DOC{ref:'DAO'} operations."
    },
    {
      model_: 'BooleanProperty',
      name: 'contextualize',
      defaultValue: false,
      documentation: "Contextualize objects on .find"
    },
    {
      model_: 'BooleanProperty',
      name: 'cloning',
      defaultValue: false,
      documentation: "True to clone results on select"
    },
    {
      name: 'daoType',
      defaultValue: 'foam.dao.IDBDAO',
      documentation: function() { /*

Selects the basic functionality this $$DOC{ref:'foam.dao.EasyDAO'} should provide.
          You can specify an instance of a DAO model definition such as
          $$DOC{ref:'MDAO'}, or a constant indicating your requirements.

Choices are:

$$DOC{ref:'.ALIASES',text:'IDB'}: Use IndexDB for storage.

$$DOC{ref:'.ALIASES',text:'LOCAL'}: Use local storage (for Chrome Apps, this will use local, non-synced storage).

$$DOC{ref:'.ALIASES',text:'SYNC'}: Use synchronized storage (for Chrome Apps, this will use Chrome Sync storage).

       */}
    },
    {
      model_: 'BooleanProperty',
      name: 'autoIndex',
      defaultValue: false,
      documentation: "Automatically generate an index."
    },
    {
      model_: 'ArrayProperty',
      name: 'migrationRules',
      subType: 'foam.core.dao.MigrationRule',
      documentation: "Creates an internal $$DOC{ref:'MigrationDAO'} and applies the given array of $$DOC{ref:'MigrationRule'}."
    }
  ],

  constants: {
    // Aliases for daoType
    ALIASES: {
      IDB:   'foam.dao.IDBDAO',
      LOCAL: 'foam.core.dao.StorageDAO', // Switches to 'ChromeStorageDAO' for Chrome Apps
      SYNC:  'foam.core.dao.StorageDAO'  // Switches to 'ChromeSyncStorageDAO' for Chrome Apps
    }
  },

  methods: [
    function init(args) {
      /*

On initialization, the $$DOC{ref:'.'} creates an appropriate chain of
        internal $$DOC{ref:'DAO'} instances based on the $$DOC{ref:'.'}
        property settings.

This process is transparent to the developer, and you can use your
        $$DOC{ref:'.'} like any other $$DOC{ref:'DAO'}.

      */
      this.SUPER(args);

      if ( window.chrome && chrome.storage ) {
        this.ALIASES.LOCAL = 'foam.core.dao.ChromeStorageDAO';
        this.ALIASES.SYNC  = 'foam.core.dao.ChromeSyncStorageDAO';
      }

      var daoType  = typeof this.daoType === 'string' ? this.ALIASES[this.daoType] || this.daoType : this.daoType;
      var daoModel = typeof daoType === 'string' ? this.X.lookup(daoType) : daoType;
      var params   = { model: this.model, autoIndex: this.autoIndex };

      if ( this.name  ) params.name = this.name;
      if ( this.seqNo || this.guid ) params.property = this.seqProperty;

      var dao = daoModel.create(params);

      if ( MDAO.isInstance(dao) ) {
        this.mdao = dao;
        if ( this.dedup ) dao = this.DeDupDAO.create({delegate: dao});
      } else {
        if ( this.migrationRules && this.migrationRules.length ) {
          dao = this.MigrationDAO.create({
            delegate: dao,
            rules: this.migrationRules,
            name: this.model.name + "_" + daoModel.name + "_" + this.name
          }, this.Y);
        }
        if ( this.cache ) {
          this.mdao = this.MDAO.create(params);
          dao = this.CachingDAO.create({
            cache: this.dedup ?
              this.mdao :
              this.DeDupDAO.create({delegate: this.mdao}),
            src: dao,
            model: this.model});
        }
      }

      if ( this.seqNo && this.guid ) throw "EasyDAO 'seqNo' and 'guid' features are mutually exclusive.";

      if ( this.seqNo ) {
        var args = {__proto__: params, delegate: dao, model: this.model};
        if ( this.seqProperty ) args.property = this.seqProperty;
        dao = this.SeqNoDAO.create(args);
      }

      if ( this.guid ) {
        var args = {__proto__: params, delegate: dao, model: this.model};
        if ( this.seqProperty ) args.property = this.seqProperty;
        dao = this.GUIDDAO.create(args);
      }

      if ( this.contextualize ) dao = this.ContextualizingDAO.create({
        delegate: dao
      });

      if ( this.cloning ) dao = this.CloningDAO.create({
        delegate: dao
      });

      if ( this.timing  ) dao = TimingDAO.create(this.name + 'DAO', dao);
      if ( this.logging ) dao = LoggingDAO.create(dao);

      this.delegate = dao;
    },

    function addIndex() {
      /*
Only relevant if $$DOC{ref:'.cache'} is true or if $$DOC{ref:'.daoType'}
         was set to $$DOC{ref:'MDAO'}, but harmless otherwise.

See $$DOC{ref:'MDAO.addIndex', text:'MDAO.addIndex()'}.
 */
      this.mdao && this.mdao.addIndex.apply(this.mdao, arguments);
      return this;
    },

    function addRawIndex() {
      /*
Only relevant if $$DOC{ref:'.cache'} is true or if $$DOC{ref:'.daoType'}
         was set to $$DOC{ref:'MDAO'}, but harmless otherwise.

See $$DOC{ref:'MDAO.addRawIndex', text:'MDAO.addRawIndex()'}. */
      this.mdao && this.mdao.addRawIndex.apply(this.mdao, arguments);
      return this;
    }
  ]
});
<commit_msg>EasyDAO, create daoModel in this.Y context.<commit_after>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.dao',
  name: 'EasyDAO',
  extendsModel: 'foam.dao.ProxyDAO',

  requires: [
    'MDAO',
    'foam.core.dao.CloningDAO',
    'foam.core.dao.MigrationDAO',
    'foam.core.dao.StorageDAO',
    'foam.dao.CachingDAO',
    'foam.dao.ContextualizingDAO',
    'foam.dao.DeDupDAO',
    'foam.dao.GUIDDAO',
    'foam.dao.SeqNoDAO'
  ],

  help: 'A facade for easy DAO setup.',

  documentation: function() {/*

If you don't know which $$DOC{ref:'DAO'} implementation to choose, $$DOC{ref:'foam.dao.EasyDAO'} is
    ready to help. Simply this.X.EasyDAO.create() and set the flags
    to indicate what behavior you're looking for. Under the hood, $$DOC{ref:'foam.dao.EasyDAO'}
    will create one or more $$DOC{ref:'DAO'} instances to service your requirements.

Since $$DOC{ref:'foam.dao.EasyDAO'} is a proxy, just use it like you would any other
    $$DOC{ref:'DAO'}, without worrying about the internal $$DOC{ref:'DAO'} doing the
    work.

  */},

  properties: [
    {
      name: 'name',
      defaultValueFn: function() { return this.model.plural; },
      documentation: "The developer-friendly name for this $$DOC{ref:'.'}."
    },
    {
      model_: 'BooleanProperty',
      name: 'seqNo',
      defaultValue: false,
      documentation: "Have $$DOC{ref:'.'} use a sequence number to index items. Note that $$DOC{ref:'.seqNo'} and $$DOC{ref:'.guid'} features are mutually exclusive."
    },
    {
      model_: 'BooleanProperty',
      name: 'guid',
      label: 'GUID',
      defaultValue: false,
      documentation: "Have $$DOC{ref:'.'} generate guids to index items. Note that $$DOC{ref:'.seqNo'} and $$DOC{ref:'.guid'} features are mutually exclusive."
    },
    {
      name: 'seqProperty',
      type: 'Property',
      documentation: "The property on your items to use to store the sequence number or guid. This is required for $$DOC{ref:'.seqNo'} or $$DOC{ref:'.guid'} mode."
    },
    {
      model_: 'BooleanProperty',
      name: 'cache',
      defaultValue: false,
      documentation: "Enable local caching of the $$DOC{ref:'DAO'}."
    },
    {
      model_: 'BooleanProperty',
      name: 'dedup',
      defaultValue: false,
      documentation: "Enable value de-duplication to save memory when caching."
    },
    {
      model_: 'BooleanProperty',
      name: 'logging',
      defaultValue: false,
      documentation: "Enable logging on the $$DOC{ref:'DAO'}."
    },
    {
      model_: 'BooleanProperty',
      name: 'timing',
      defaultValue: false,
      documentation: "Enable time tracking for concurrent $$DOC{ref:'DAO'} operations."
    },
    {
      model_: 'BooleanProperty',
      name: 'contextualize',
      defaultValue: false,
      documentation: "Contextualize objects on .find"
    },
    {
      model_: 'BooleanProperty',
      name: 'cloning',
      defaultValue: false,
      documentation: "True to clone results on select"
    },
    {
      name: 'daoType',
      defaultValue: 'foam.dao.IDBDAO',
      documentation: function() { /*

Selects the basic functionality this $$DOC{ref:'foam.dao.EasyDAO'} should provide.
          You can specify an instance of a DAO model definition such as
          $$DOC{ref:'MDAO'}, or a constant indicating your requirements.

Choices are:

$$DOC{ref:'.ALIASES',text:'IDB'}: Use IndexDB for storage.

$$DOC{ref:'.ALIASES',text:'LOCAL'}: Use local storage (for Chrome Apps, this will use local, non-synced storage).

$$DOC{ref:'.ALIASES',text:'SYNC'}: Use synchronized storage (for Chrome Apps, this will use Chrome Sync storage).

       */}
    },
    {
      model_: 'BooleanProperty',
      name: 'autoIndex',
      defaultValue: false,
      documentation: "Automatically generate an index."
    },
    {
      model_: 'ArrayProperty',
      name: 'migrationRules',
      subType: 'foam.core.dao.MigrationRule',
      documentation: "Creates an internal $$DOC{ref:'MigrationDAO'} and applies the given array of $$DOC{ref:'MigrationRule'}."
    }
  ],

  constants: {
    // Aliases for daoType
    ALIASES: {
      IDB:   'foam.dao.IDBDAO',
      LOCAL: 'foam.core.dao.StorageDAO', // Switches to 'ChromeStorageDAO' for Chrome Apps
      SYNC:  'foam.core.dao.StorageDAO'  // Switches to 'ChromeSyncStorageDAO' for Chrome Apps
    }
  },

  methods: [
    function init(args) {
      /*

On initialization, the $$DOC{ref:'.'} creates an appropriate chain of
        internal $$DOC{ref:'DAO'} instances based on the $$DOC{ref:'.'}
        property settings.

This process is transparent to the developer, and you can use your
        $$DOC{ref:'.'} like any other $$DOC{ref:'DAO'}.

      */
      this.SUPER(args);

      if ( window.chrome && chrome.storage ) {
        this.ALIASES.LOCAL = 'foam.core.dao.ChromeStorageDAO';
        this.ALIASES.SYNC  = 'foam.core.dao.ChromeSyncStorageDAO';
      }

      var daoType  = typeof this.daoType === 'string' ? this.ALIASES[this.daoType] || this.daoType : this.daoType;
      var daoModel = typeof daoType === 'string' ? this.X.lookup(daoType) : daoType;
      var params   = { model: this.model, autoIndex: this.autoIndex };

      if ( this.name  ) params.name = this.name;
      if ( this.seqNo || this.guid ) params.property = this.seqProperty;

      var dao = daoModel.create(params, this.Y);

      if ( MDAO.isInstance(dao) ) {
        this.mdao = dao;
        if ( this.dedup ) dao = this.DeDupDAO.create({delegate: dao});
      } else {
        if ( this.migrationRules && this.migrationRules.length ) {
          dao = this.MigrationDAO.create({
            delegate: dao,
            rules: this.migrationRules,
            name: this.model.name + "_" + daoModel.name + "_" + this.name
          }, this.Y);
        }
        if ( this.cache ) {
          this.mdao = this.MDAO.create(params);
          dao = this.CachingDAO.create({
            cache: this.dedup ?
              this.mdao :
              this.DeDupDAO.create({delegate: this.mdao}),
            src: dao,
            model: this.model});
        }
      }

      if ( this.seqNo && this.guid ) throw "EasyDAO 'seqNo' and 'guid' features are mutually exclusive.";

      if ( this.seqNo ) {
        var args = {__proto__: params, delegate: dao, model: this.model};
        if ( this.seqProperty ) args.property = this.seqProperty;
        dao = this.SeqNoDAO.create(args);
      }

      if ( this.guid ) {
        var args = {__proto__: params, delegate: dao, model: this.model};
        if ( this.seqProperty ) args.property = this.seqProperty;
        dao = this.GUIDDAO.create(args);
      }

      if ( this.contextualize ) dao = this.ContextualizingDAO.create({
        delegate: dao
      });

      if ( this.cloning ) dao = this.CloningDAO.create({
        delegate: dao
      });

      if ( this.timing  ) dao = TimingDAO.create(this.name + 'DAO', dao);
      if ( this.logging ) dao = LoggingDAO.create(dao);

      this.delegate = dao;
    },

    function addIndex() {
      /*
Only relevant if $$DOC{ref:'.cache'} is true or if $$DOC{ref:'.daoType'}
         was set to $$DOC{ref:'MDAO'}, but harmless otherwise.

See $$DOC{ref:'MDAO.addIndex', text:'MDAO.addIndex()'}.
 */
      this.mdao && this.mdao.addIndex.apply(this.mdao, arguments);
      return this;
    },

    function addRawIndex() {
      /*
Only relevant if $$DOC{ref:'.cache'} is true or if $$DOC{ref:'.daoType'}
         was set to $$DOC{ref:'MDAO'}, but harmless otherwise.

See $$DOC{ref:'MDAO.addRawIndex', text:'MDAO.addRawIndex()'}. */
      this.mdao && this.mdao.addRawIndex.apply(this.mdao, arguments);
      return this;
    }
  ]
});
<|endoftext|>


<commit_before>var storage = {};
var date = new Date();

chrome.runtime.sendMessage({payload: "localStorage"}, function(response) {
  storage = response;
  displayHistory();
  clearHistory();
  goBack();
})

function displayHistory() {
  for (var key in storage) {
    var session = JSON.parse(storage[key]);
    date.setTime(key);
    $("#history-content").prepend('
' + formatDate(date) + ' - '
              + session.name + '
View
' + '
');
  }
  // once all items are populated, begin load-button listener
  viewHistoryItem();
}

function clearHistory() {
  $("#clear-all").click(function() {
    $("#clear-all-confirm").show();
    $("#all-yes").click(function() {
      chrome.runtime.sendMessage({payload: "clear"}, function(response) {
        $("#clear-all").html(response);
        $("#history-content").html(response);
        $("#clear-all-confirm").hide();
      })
    })

    $("#all-no").click(function() {
      $("#clear-all-confirm").hide();
    })
  })
}

function clearCurrent(key) {
  $("#clear-current").click(function() {
    $("#clear-current-confirm").show();
    $("#current-yes").click(function() {
      chrome.runtime.sendMessage({payload: "delete", key: key}, function(response) {
        $("#clear-current").html(response);
        $("#viz-body").hide();
        $("#history-content").html(response);
        $("#history-content").show();
        $("#clear-current-confirm").hide();
        $("#history").load("history.html");
        $("#viz-body").hide();
      });
    })
    $("#current-no").click(function() {
      $("#clear-current-confirm").hide();
    })
  })
}

function goBack() {
  $("#back").click(function() {
    $("#history").load("history.html");
    $("#viz-body").hide();
    $("#back").hide();
  })
}

function viewHistoryItem() {
  $(".load-button").click(function() {
    var key = $(this).attr('id');
    chrome.runtime.sendMessage({payload: "set", key: key}, function(response) {
      $("#clear-current").show();
      clearCurrent(key);
      $("#viz-body").load("tree.html");
      $("#history-content").hide();
      $("#viz-body").show();
      $("#back").show();
    })
  })
}

// take date object and return it as a string of format "MM/DD/YYYY at HH:MM"
function formatDate(date) {
  // getMonth returns zero-based index of month, so need +1
  month = date.getMonth()
  month += 1;

  return month + '/' + date.getDate()  + '/' + date.getFullYear() + ' at ' +
    date.getHours() + ':' + (date.getMinutes()<10?'0':'') + date.getMinutes();
}
<commit_msg>Fix #59 Always display 2-digit hour in timestamp<commit_after>var storage = {};
var date = new Date();

chrome.runtime.sendMessage({payload: "localStorage"}, function(response) {
  storage = response;
  displayHistory();
  clearHistory();
  goBack();
})

function displayHistory() {
  for (var key in storage) {
    var session = JSON.parse(storage[key]);
    date.setTime(key);
    $("#history-content").prepend('
' + formatDate(date) + ' - '
              + session.name + '
View
' + '
');
  }
  // once all items are populated, begin load-button listener
  viewHistoryItem();
}

function clearHistory() {
  $("#clear-all").click(function() {
    $("#clear-all-confirm").show();
    $("#all-yes").click(function() {
      chrome.runtime.sendMessage({payload: "clear"}, function(response) {
        $("#clear-all").html(response);
        $("#history-content").html(response);
        $("#clear-all-confirm").hide();
      })
    })

    $("#all-no").click(function() {
      $("#clear-all-confirm").hide();
    })
  })
}

function clearCurrent(key) {
  $("#clear-current").click(function() {
    $("#clear-current-confirm").show();
    $("#current-yes").click(function() {
      chrome.runtime.sendMessage({payload: "delete", key: key}, function(response) {
        $("#clear-current").html(response);
        $("#viz-body").hide();
        $("#history-content").html(response);
        $("#history-content").show();
        $("#clear-current-confirm").hide();
        $("#history").load("history.html");
        $("#viz-body").hide();
      });
    })
    $("#current-no").click(function() {
      $("#clear-current-confirm").hide();
    })
  })
}

function goBack() {
  $("#back").click(function() {
    $("#history").load("history.html");
    $("#viz-body").hide();
    $("#back").hide();
  })
}

function viewHistoryItem() {
  $(".load-button").click(function() {
    var key = $(this).attr('id');
    chrome.runtime.sendMessage({payload: "set", key: key}, function(response) {
      $("#clear-current").show();
      clearCurrent(key);
      $("#viz-body").load("tree.html");
      $("#history-content").hide();
      $("#viz-body").show();
      $("#back").show();
    })
  })
}

// take date object and return it as a string of format "MM/DD/YYYY at HH:MM"
function formatDate(date) {
  // getMonth returns zero-based index of month, so need +1
  month = date.getMonth()
  month += 1;

  return month + '/' + date.getDate()  + '/' + date.getFullYear() + ' at ' +
    (date.getHours()<10?'0';'') + date.getHours() + ':' +
    (date.getMinutes()<10?'0':'') + date.getMinutes();
}
<|endoftext|>


<commit_before>'use strict';

var path = require('path');

var src = path.join(__dirname, 'src');

module.exports = {
  devtool: 'sourcemap',
  entry: path.join(src, 'index.js'),
  output: {
    path: path.join(__dirname, 'lib'),
    filename: 'react-router-transition.js',
    sourceMapFilename: 'react-router-transition.map',
    library: 'ReactRouterTransition'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      loader: 'babel',
      include: src
    }]
  },
  resolve: {
    root: src,
    extensions: ['', '.js', '.jsx']
  },
  eslint: {
    configFile: '.eslintrc'
  }
};
<commit_msg>add umd library target.<commit_after>'use strict';

var path = require('path');

var src = path.join(__dirname, 'src');

module.exports = {
  devtool: 'sourcemap',
  entry: path.join(src, 'index.js'),
  output: {
    path: path.join(__dirname, 'lib'),
    filename: 'react-router-transition.js',
    sourceMapFilename: 'react-router-transition.map',
    library: 'ReactRouterTransition',
    libraryTarget: 'umd'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      loader: 'babel',
      include: src
    }]
  },
  resolve: {
    root: src,
    extensions: ['', '.js', '.jsx']
  },
  eslint: {
    configFile: '.eslintrc'
  }
};
<|endoftext|>


<commit_before>/**
 * impress.js
 *
 * impress.js is a presentation tool based on the power of CSS3 transforms and transitions
 * in modern browsers and inspired by the idea behind prezi.com.
 *
 *
 * Copyright 2011-2012 Bartek Szopka (@bartaz)
 *
 * Released under the MIT and GPL Licenses.
 *
 * ------------------------------------------------
 *  author:  Bartek Szopka
 *  version: 0.4pre (in development)
 *  url:     http://bartaz.github.com/impress.js/
 *  source:  http://github.com/bartaz/impress.js/
 */

(function ( document, window ) {
    'use strict';

    // HELPER FUNCTIONS

    var pfx = (function () {

        var style = document.createElement('dummy').style,
            prefixes = 'Webkit Moz O ms Khtml'.split(' '),
            memory = {};

        return function ( prop ) {
            if ( typeof memory[ prop ] === "undefined" ) {

                var ucProp  = prop.charAt(0).toUpperCase() + prop.substr(1),
                    props   = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');

                memory[ prop ] = null;
                for ( var i in props ) {
                    if ( style[ props[i] ] !== undefined ) {
                        memory[ prop ] = props[i];
                        break;
                    }
                }

            }

            return memory[ prop ];
        }

    })();

    var arrayify = function ( a ) {
        return [].slice.call( a );
    };

    var css = function ( el, props ) {
        var key, pkey;
        for ( key in props ) {
            if ( props.hasOwnProperty(key) ) {
                pkey = pfx(key);
                if ( pkey != null ) {
                    el.style[pkey] = props[key];
                }
            }
        }
        return el;
    }

    var byId = function ( id ) {
        return document.getElementById(id);
    }

    var $ = function ( selector, context ) {
        context = context || document;
        return context.querySelector(selector);
    };

    var $$ = function ( selector, context ) {
        context = context || document;
        return arrayify( context.querySelectorAll(selector) );
    };

    var translate = function ( t ) {
        return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) ";
    };

    var rotate = function ( r, revert ) {
        var rX = " rotateX(" + r.x + "deg) ",
            rY = " rotateY(" + r.y + "deg) ",
            rZ = " rotateZ(" + r.z + "deg) ";

        return revert ? rZ+rY+rX : rX+rY+rZ;
    };

    var scale = function ( s ) {
        return " scale(" + s + ") ";
    };

    var perspective = function ( p ) {
        return " perspective(" + p + "px) ";
    };

    var getElementFromUrl = function () {
        // get id from url # by removing `#` or `#/` from the beginning,
        // so both `#slide-id` and "legacy" `#/slide-id` will work
        return byId( window.location.hash.replace(/^#\/?/,"") );
    };

    // CHECK SUPPORT

    var ua = navigator.userAgent.toLowerCase();
    var impressSupported = ( pfx("perspective") != null ) &&
                           ( document.body.classList ) &&
                           ( document.body.dataset ) &&
                           ( ua.search(/(iphone)|(ipod)|(android)/) == -1 );

    var roots = {};

    var impress = window.impress = function ( rootId ) {

        rootId = rootId || "impress";

        // if already initialized just return the API
        if (roots["impress-root-" + rootId]) {
            return roots["impress-root-" + rootId];
        }

        // DOM ELEMENTS

        var root = byId( rootId );

        if (!impressSupported) {
            root.className = "impress-not-supported";
            return;
        } else {
            root.className = "";
        }

        // viewport updates for iPad
        var meta = $("meta[name='viewport']") || document.createElement("meta");
        // hardcoding these values looks pretty bad, as they kind of depend on the content
        // so they should be at least configurable
        meta.content = "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no";
        if (meta.parentNode != document.head) {
            meta.name = 'viewport';
            document.head.appendChild(meta);
        }

        // configuration object
        // probably will get extended (and configurable) later
        var config = {
            width: 1024,
            height: 768
        }

        var canvas = document.createElement("div");
        canvas.className = "canvas";

        arrayify( root.childNodes ).forEach(function ( el ) {
            canvas.appendChild( el );
        });
        root.appendChild(canvas);

        var steps = $$(".step", root);

        // SETUP
        // set initial values and defaults

        document.documentElement.style.height = "100%";

        css(document.body, {
            height: "100%",
            overflow: "hidden"
        });

        var props = {
            position: "absolute",
            transformOrigin: "top left",
            transition: "all 0s ease-in-out",
            transformStyle: "preserve-3d"
        }

        css(root, props);
        css(root, {
            top: "50%",
            left: "50%",
            transform: perspective(1000)
        });
        css(canvas, props);

        var current = {
            translate: { x: 0, y: 0, z: 0 },
            rotate:    { x: 0, y: 0, z: 0 },
            scale:     1
        };

        var stepData = {};

        var isStep = function ( el ) {
            return !!(el && el.id && stepData["impress-" + el.id]);
        }

        var computeWindowScale = function () {
            var hScale = window.innerHeight / config.height;
            var wScale = window.innerWidth / config.width;
            return hScale > wScale ? wScale : hScale;
        }

        steps.forEach(function ( el, idx ) {
            var data = el.dataset,
                step = {
                    translate: {
                        x: data.x || 0,
                        y: data.y || 0,
                        z: data.z || 0
                    },
                    rotate: {
                        x: data.rotateX || 0,
                        y: data.rotateY || 0,
                        z: data.rotateZ || data.rotate || 0
                    },
                    scale: data.scale || 1,
                    el: el
                };

            if ( !el.id ) {
                el.id = "step-" + (idx + 1);
            }

            stepData["impress-" + el.id] = step;

            css(el, {
                position: "absolute",
                transform: "translate(-50%,-50%)" +
                           translate(step.translate) +
                           rotate(step.rotate) +
                           scale(step.scale),
                transformStyle: "preserve-3d"
            });

        });

        // making given step active

        var active = null;
        var hashTimeout = null;

        var windowScale = computeWindowScale();

        var goto = function ( el, force ) {
            if ( !isStep(el) || (el == active && !force) ) {
                // selected element is not defined as step or is already active
                return false;
            }

            // Sometimes it's possible to trigger focus on first link with some keyboard action.
            // Browser in such a case tries to scroll the page to make this element visible
            // (even that body overflow is set to hidden) and it breaks our careful positioning.
            //
            // So, as a lousy (and lazy) workaround we will make the page scroll back to the top
            // whenever slide is selected
            //
            // If you are reading this and know any better way to handle it, I'll be glad to hear about it!
            window.scrollTo(0, 0);

            var step = stepData["impress-" + el.id];

            if ( active ) {
                active.classList.remove("active");
            }
            el.classList.add("active");

            root.className = "step-" + el.id;

            // Setting fragment URL with `history.pushState`
            // and it has to be set after animation finishes, because in Chrome it
            // causes transtion being laggy
            // BUG: http://code.google.com/p/chromium/issues/detail?id=62820
            window.clearTimeout( hashTimeout );
            hashTimeout = window.setTimeout(function () {
                window.location.hash = "#/" + el.id;
            }, 1000);

            var target = {
                rotate: {
                    x: -parseInt(step.rotate.x, 10),
                    y: -parseInt(step.rotate.y, 10),
                    z: -parseInt(step.rotate.z, 10)
                },
                translate: {
                    x: -step.translate.x,
                    y: -step.translate.y,
                    z: -step.translate.z
                },
                scale: 1 / parseFloat(step.scale)
            };

            // check if the transition is zooming in or not
            var zoomin = target.scale >= current.scale;

            // if presentation starts (nothing is active yet)
            // don't animate (set duration to 0)
            var duration = (active) ? "1s" : "0";

            if (force) {
                windowScale = computeWindowScale();
            }

            css(root, {
                // to keep the perspective look similar for different scales
                // we need to 'scale' the perspective, too
                transform: perspective( 1000 / (target.scale * windowScale) ) + scale(target.scale * windowScale),
                transitionDuration: duration,
                transitionDelay: (zoomin ? "500ms" : "0ms")
            });

            css(canvas, {
                transform: rotate(target.rotate, true) + translate(target.translate),
                transitionDuration: duration,
                transitionDelay: (zoomin ? "0ms" : "500ms")
            });

            current = target;
            active = el;

            return el;
        };

        var prev = function () {
            var prev = steps.indexOf( active ) - 1;
            prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ];

            return goto(prev);
        };

        var next = function () {
            var next = steps.indexOf( active ) + 1;
            next = next < steps.length ? steps[ next ] : steps[ 0 ];

            return goto(next);
        };

        window.addEventListener("hashchange", function () {
            goto( getElementFromUrl() );
        }, false);

        window.addEventListener("orientationchange", function () {
            window.scrollTo(0, 0);
        }, false);

        // START
        // by selecting step defined in url or first step of the presentation
        goto(getElementFromUrl() || steps[0]);

        return (roots[ "impress-root-" + rootId ] = {
            goto: goto,
            next: next,
            prev: prev
        });

    }
})(document, window);

// EVENTS

(function ( document, window ) {
    'use strict';

    // throttling function calls, by Remy Sharp
    // http://remysharp.com/2010/07/21/throttling-function-calls/
    var throttle = function (fn, delay) {
        var timer = null;
        return function () {
            var context = this, args = arguments;
            clearTimeout(timer);
            timer = setTimeout(function () {
                fn.apply(context, args);
            }, delay);
        };
    };

    // keyboard navigation handler
    document.addEventListener("keydown", function ( event ) {
        if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
            switch( event.keyCode ) {
                case 33: ; // pg up
                case 37: ; // left
                case 38:   // up
                         impress().prev();
                         break;
                case 9:  ; // tab
                case 32: ; // space
                case 34: ; // pg down
                case 39: ; // right
                case 40:   // down
                         impress().next();
                         break;
            }

            event.preventDefault();
        }
    }, false);

    // delegated handler for clicking on the links to presentation steps
    document.addEventListener("click", function ( event ) {
        // event delegation with "bubbling"
        // check if event target (or any of its parents is a link)
        var target = event.target;
        while ( (target.tagName != "A") &&
                (target != document.documentElement) ) {
            target = target.parentNode;
        }

        if ( target.tagName == "A" ) {
            var href = target.getAttribute("href");

            // if it's a link to presentation step, target this step
            if ( href && href[0] == '#' ) {
                target = document.getElementById( href.slice(1) );
            }
        }

        if ( impress().goto(target) ) {
            event.stopImmediatePropagation();
            event.preventDefault();
        }
    }, false);

    // delegated handler for clicking on step elements
    document.addEventListener("click", function ( event ) {
        var target = event.target;
        // find closest step element
        while ( !target.classList.contains("step") &&
                (target != document.documentElement) ) {
            target = target.parentNode;
        }

        if ( impress().goto(target) ) {
            event.preventDefault();
        }
    }, false);

    // touch handler to detect taps on the left and right side of the screen
    document.addEventListener("touchstart", function ( event ) {
        if (event.touches.length === 1) {
            var x = event.touches[0].clientX,
                width = window.innerWidth * 0.3,
                result = null;

            if ( x < width ) {
                result = impress().prev();
            } else if ( x > window.innerWidth - width ) {
                result = impress().next();
            }

            if (result) {
                event.preventDefault();
            }
        }
    }, false);

    // rescale presentation when window is resized
    window.addEventListener("resize", throttle(function (event) {
        // force going to active step again, to trigger rescaling
        impress().goto( document.querySelector(".active"), true );
    }, 250), false);
})(document, window);

<commit_msg>keyboard handler updated - now triggering actions on keyup<commit_after>/**
 * impress.js
 *
 * impress.js is a presentation tool based on the power of CSS3 transforms and transitions
 * in modern browsers and inspired by the idea behind prezi.com.
 *
 *
 * Copyright 2011-2012 Bartek Szopka (@bartaz)
 *
 * Released under the MIT and GPL Licenses.
 *
 * ------------------------------------------------
 *  author:  Bartek Szopka
 *  version: 0.4pre (in development)
 *  url:     http://bartaz.github.com/impress.js/
 *  source:  http://github.com/bartaz/impress.js/
 */

(function ( document, window ) {
    'use strict';

    // HELPER FUNCTIONS

    var pfx = (function () {

        var style = document.createElement('dummy').style,
            prefixes = 'Webkit Moz O ms Khtml'.split(' '),
            memory = {};

        return function ( prop ) {
            if ( typeof memory[ prop ] === "undefined" ) {

                var ucProp  = prop.charAt(0).toUpperCase() + prop.substr(1),
                    props   = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');

                memory[ prop ] = null;
                for ( var i in props ) {
                    if ( style[ props[i] ] !== undefined ) {
                        memory[ prop ] = props[i];
                        break;
                    }
                }

            }

            return memory[ prop ];
        }

    })();

    var arrayify = function ( a ) {
        return [].slice.call( a );
    };

    var css = function ( el, props ) {
        var key, pkey;
        for ( key in props ) {
            if ( props.hasOwnProperty(key) ) {
                pkey = pfx(key);
                if ( pkey != null ) {
                    el.style[pkey] = props[key];
                }
            }
        }
        return el;
    }

    var byId = function ( id ) {
        return document.getElementById(id);
    }

    var $ = function ( selector, context ) {
        context = context || document;
        return context.querySelector(selector);
    };

    var $$ = function ( selector, context ) {
        context = context || document;
        return arrayify( context.querySelectorAll(selector) );
    };

    var translate = function ( t ) {
        return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) ";
    };

    var rotate = function ( r, revert ) {
        var rX = " rotateX(" + r.x + "deg) ",
            rY = " rotateY(" + r.y + "deg) ",
            rZ = " rotateZ(" + r.z + "deg) ";

        return revert ? rZ+rY+rX : rX+rY+rZ;
    };

    var scale = function ( s ) {
        return " scale(" + s + ") ";
    };

    var perspective = function ( p ) {
        return " perspective(" + p + "px) ";
    };

    var getElementFromUrl = function () {
        // get id from url # by removing `#` or `#/` from the beginning,
        // so both `#slide-id` and "legacy" `#/slide-id` will work
        return byId( window.location.hash.replace(/^#\/?/,"") );
    };

    // CHECK SUPPORT

    var ua = navigator.userAgent.toLowerCase();
    var impressSupported = ( pfx("perspective") != null ) &&
                           ( document.body.classList ) &&
                           ( document.body.dataset ) &&
                           ( ua.search(/(iphone)|(ipod)|(android)/) == -1 );

    var roots = {};

    var impress = window.impress = function ( rootId ) {

        rootId = rootId || "impress";

        // if already initialized just return the API
        if (roots["impress-root-" + rootId]) {
            return roots["impress-root-" + rootId];
        }

        // DOM ELEMENTS

        var root = byId( rootId );

        if (!impressSupported) {
            root.className = "impress-not-supported";
            return;
        } else {
            root.className = "";
        }

        // viewport updates for iPad
        var meta = $("meta[name='viewport']") || document.createElement("meta");
        // hardcoding these values looks pretty bad, as they kind of depend on the content
        // so they should be at least configurable
        meta.content = "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no";
        if (meta.parentNode != document.head) {
            meta.name = 'viewport';
            document.head.appendChild(meta);
        }

        // configuration object
        // probably will get extended (and configurable) later
        var config = {
            width: 1024,
            height: 768
        }

        var canvas = document.createElement("div");
        canvas.className = "canvas";

        arrayify( root.childNodes ).forEach(function ( el ) {
            canvas.appendChild( el );
        });
        root.appendChild(canvas);

        var steps = $$(".step", root);

        // SETUP
        // set initial values and defaults

        document.documentElement.style.height = "100%";

        css(document.body, {
            height: "100%",
            overflow: "hidden"
        });

        var props = {
            position: "absolute",
            transformOrigin: "top left",
            transition: "all 0s ease-in-out",
            transformStyle: "preserve-3d"
        }

        css(root, props);
        css(root, {
            top: "50%",
            left: "50%",
            transform: perspective(1000)
        });
        css(canvas, props);

        var current = {
            translate: { x: 0, y: 0, z: 0 },
            rotate:    { x: 0, y: 0, z: 0 },
            scale:     1
        };

        var stepData = {};

        var isStep = function ( el ) {
            return !!(el && el.id && stepData["impress-" + el.id]);
        }

        var computeWindowScale = function () {
            var hScale = window.innerHeight / config.height;
            var wScale = window.innerWidth / config.width;
            return hScale > wScale ? wScale : hScale;
        }

        steps.forEach(function ( el, idx ) {
            var data = el.dataset,
                step = {
                    translate: {
                        x: data.x || 0,
                        y: data.y || 0,
                        z: data.z || 0
                    },
                    rotate: {
                        x: data.rotateX || 0,
                        y: data.rotateY || 0,
                        z: data.rotateZ || data.rotate || 0
                    },
                    scale: data.scale || 1,
                    el: el
                };

            if ( !el.id ) {
                el.id = "step-" + (idx + 1);
            }

            stepData["impress-" + el.id] = step;

            css(el, {
                position: "absolute",
                transform: "translate(-50%,-50%)" +
                           translate(step.translate) +
                           rotate(step.rotate) +
                           scale(step.scale),
                transformStyle: "preserve-3d"
            });

        });

        // making given step active

        var active = null;
        var hashTimeout = null;

        var windowScale = computeWindowScale();

        var goto = function ( el, force ) {
            if ( !isStep(el) || (el == active && !force) ) {
                // selected element is not defined as step or is already active
                return false;
            }

            // Sometimes it's possible to trigger focus on first link with some keyboard action.
            // Browser in such a case tries to scroll the page to make this element visible
            // (even that body overflow is set to hidden) and it breaks our careful positioning.
            //
            // So, as a lousy (and lazy) workaround we will make the page scroll back to the top
            // whenever slide is selected
            //
            // If you are reading this and know any better way to handle it, I'll be glad to hear about it!
            window.scrollTo(0, 0);

            var step = stepData["impress-" + el.id];

            if ( active ) {
                active.classList.remove("active");
            }
            el.classList.add("active");

            root.className = "step-" + el.id;

            // Setting fragment URL with `history.pushState`
            // and it has to be set after animation finishes, because in Chrome it
            // causes transtion being laggy
            // BUG: http://code.google.com/p/chromium/issues/detail?id=62820
            window.clearTimeout( hashTimeout );
            hashTimeout = window.setTimeout(function () {
                window.location.hash = "#/" + el.id;
            }, 1000);

            var target = {
                rotate: {
                    x: -parseInt(step.rotate.x, 10),
                    y: -parseInt(step.rotate.y, 10),
                    z: -parseInt(step.rotate.z, 10)
                },
                translate: {
                    x: -step.translate.x,
                    y: -step.translate.y,
                    z: -step.translate.z
                },
                scale: 1 / parseFloat(step.scale)
            };

            // check if the transition is zooming in or not
            var zoomin = target.scale >= current.scale;

            // if presentation starts (nothing is active yet)
            // don't animate (set duration to 0)
            var duration = (active) ? "1s" : "0";

            if (force) {
                windowScale = computeWindowScale();
            }

            css(root, {
                // to keep the perspective look similar for different scales
                // we need to 'scale' the perspective, too
                transform: perspective( 1000 / (target.scale * windowScale) ) + scale(target.scale * windowScale),
                transitionDuration: duration,
                transitionDelay: (zoomin ? "500ms" : "0ms")
            });

            css(canvas, {
                transform: rotate(target.rotate, true) + translate(target.translate),
                transitionDuration: duration,
                transitionDelay: (zoomin ? "0ms" : "500ms")
            });

            current = target;
            active = el;

            return el;
        };

        var prev = function () {
            var prev = steps.indexOf( active ) - 1;
            prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ];

            return goto(prev);
        };

        var next = function () {
            var next = steps.indexOf( active ) + 1;
            next = next < steps.length ? steps[ next ] : steps[ 0 ];

            return goto(next);
        };

        window.addEventListener("hashchange", function () {
            goto( getElementFromUrl() );
        }, false);

        window.addEventListener("orientationchange", function () {
            window.scrollTo(0, 0);
        }, false);

        // START
        // by selecting step defined in url or first step of the presentation
        goto(getElementFromUrl() || steps[0]);

        return (roots[ "impress-root-" + rootId ] = {
            goto: goto,
            next: next,
            prev: prev
        });

    }
})(document, window);

// EVENTS

(function ( document, window ) {
    'use strict';

    // throttling function calls, by Remy Sharp
    // http://remysharp.com/2010/07/21/throttling-function-calls/
    var throttle = function (fn, delay) {
        var timer = null;
        return function () {
            var context = this, args = arguments;
            clearTimeout(timer);
            timer = setTimeout(function () {
                fn.apply(context, args);
            }, delay);
        };
    };

    // keyboard navigation handlers

    // prevent default keydown action when one of supported key is pressed
    document.addEventListener("keydown", function ( event ) {
        if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
            event.preventDefault();
        }
    }, false);

    // trigger impress action on keyup
    document.addEventListener("keyup", function ( event ) {
        if ( event.keyCode == 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
            switch( event.keyCode ) {
                case 33: ; // pg up
                case 37: ; // left
                case 38:   // up
                         impress().prev();
                         break;
                case 9:  ; // tab
                case 32: ; // space
                case 34: ; // pg down
                case 39: ; // right
                case 40:   // down
                         impress().next();
                         break;
            }

            event.preventDefault();
        }
    }, false);

    // delegated handler for clicking on the links to presentation steps
    document.addEventListener("click", function ( event ) {
        // event delegation with "bubbling"
        // check if event target (or any of its parents is a link)
        var target = event.target;
        while ( (target.tagName != "A") &&
                (target != document.documentElement) ) {
            target = target.parentNode;
        }

        if ( target.tagName == "A" ) {
            var href = target.getAttribute("href");

            // if it's a link to presentation step, target this step
            if ( href && href[0] == '#' ) {
                target = document.getElementById( href.slice(1) );
            }
        }

        if ( impress().goto(target) ) {
            event.stopImmediatePropagation();
            event.preventDefault();
        }
    }, false);

    // delegated handler for clicking on step elements
    document.addEventListener("click", function ( event ) {
        var target = event.target;
        // find closest step element
        while ( !target.classList.contains("step") &&
                (target != document.documentElement) ) {
            target = target.parentNode;
        }

        if ( impress().goto(target) ) {
            event.preventDefault();
        }
    }, false);

    // touch handler to detect taps on the left and right side of the screen
    document.addEventListener("touchstart", function ( event ) {
        if (event.touches.length === 1) {
            var x = event.touches[0].clientX,
                width = window.innerWidth * 0.3,
                result = null;

            if ( x < width ) {
                result = impress().prev();
            } else if ( x > window.innerWidth - width ) {
                result = impress().next();
            }

            if (result) {
                event.preventDefault();
            }
        }
    }, false);

    // rescale presentation when window is resized
    window.addEventListener("resize", throttle(function (event) {
        // force going to active step again, to trigger rescaling
        impress().goto( document.querySelector(".active"), true );
    }, 250), false);
})(document, window);

<|endoftext|>


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

module.exports = {
    entry: './src/index.js',
    hot: false,
    output: {
        libraryTarget: 'umd',
        library: 'mobservable-devtools',
        path: __dirname,
        filename: 'index.js'
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style-loader!css-loader" }
        ]
    },
    externals: {
        "mobservable-react": "mobservable-react",
        "mobservable": "mobservable"
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compressor: {
              screw_ie8: true,
              warnings: false
            }
        })
    ]
}
<commit_msg>changed lib-name for easier include without commonjs/amd<commit_after>var webpack = require('webpack');

module.exports = {
    entry: './src/index.js',
    hot: false,
    output: {
        libraryTarget: 'umd',
        library: 'mobservableDevtools',
        path: __dirname,
        filename: 'index.js'
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style-loader!css-loader" }
        ]
    },
    externals: {
        "mobservable-react": "mobservable-react",
        "mobservable": "mobservable"
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compressor: {
              screw_ie8: true,
              warnings: false
            }
        })
    ]
}
<|endoftext|>


<commit_before>var webpack = require('webpack');
var config = require('./config');
module.exports = {
    entry:
    {
        'yasp': './public/js/yasp.js',
        'yaspv2': './public/js/yaspv2.js'
    },
    output:
    {
        filename: '[name].min.js',
        path: './public/build/',
        publicPath: "/public/build/"
    },
    module:
    {
        loaders: [
            {
                test: /\.css$/,
                loader: "style-loader!css-loader"
            },
            {
                test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "url-loader?limit=10000&minetype=application/font-woff&name=[hash].[ext]"
            },
            {
                test: /\.(ttf|eot|svg|jpg|gif|png)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "file-loader?name=[hash].[ext]"
                },
            {
                test: /\.(json)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "json-loader"
                },
            {
                test: /jquery\.js$/,
                loader: 'expose?$'
            },
            {
                test: /jquery\.js$/,
                loader: 'expose?jQuery'
            },
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel', // 'babel-loader' is also a legal name to reference
                query:
                {
                    presets: ['react', 'es2015']
                }
            }
        ]
    },
    devServer:
    {
        contentBase: 'public/build',
        progress: true,
        host: "0.0.0.0",
        proxy:
        {
            '/api/*':
            {
                target: config.ROOT_URL,
                secure: false,
            },
            '/apps/*':
            {
                target: config.ROOT_URL,
                secure: false,
            }
        }
    }
};<commit_msg>set historyapifallback<commit_after>var webpack = require('webpack');
var config = require('./config');
module.exports = {
    entry:
    {
        'yasp': './public/js/yasp.js',
        'yaspv2': './public/js/yaspv2.js'
    },
    output:
    {
        filename: '[name].min.js',
        path: './public/build/',
        publicPath: "/public/build/"
    },
    module:
    {
        loaders: [
            {
                test: /\.css$/,
                loader: "style-loader!css-loader"
            },
            {
                test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "url-loader?limit=10000&minetype=application/font-woff&name=[hash].[ext]"
            },
            {
                test: /\.(ttf|eot|svg|jpg|gif|png)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "file-loader?name=[hash].[ext]"
                },
            {
                test: /\.(json)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "json-loader"
                },
            {
                test: /jquery\.js$/,
                loader: 'expose?$'
            },
            {
                test: /jquery\.js$/,
                loader: 'expose?jQuery'
            },
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel', // 'babel-loader' is also a legal name to reference
                query:
                {
                    presets: ['react', 'es2015']
                }
            }
        ]
    },
    devServer:
    {
        contentBase: 'public/build',
        progress: true,
        host: "0.0.0.0",
        proxy:
        {
            '/api/*':
            {
                target: config.ROOT_URL,
                secure: false,
            },
            '/apps/*':
            {
                target: config.ROOT_URL,
                secure: false,
            }
        },
        historyApiFallback: true
    }
};<|endoftext|>


<commit_before>const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const {version} = require('./package.json')

// NODE_ENV is not set for webpack config
// https://github.com/webpack/webpack/issues/2537#issuecomment-250950677
const isProd = process.argv.includes('-p')

const plugins = [
	new webpack.DefinePlugin({
		__VERSION__: JSON.stringify(version)
	}),
	new webpack.ProvidePlugin({
		i18n: 'i18next',
		Promise: 'bluebird',
		React: 'react'
	}),

	// Remove unnecessary moment.js locales
	// http://stackoverflow.com/a/25426019
	new webpack.ContextReplacementPlugin(/moment\/locale/, /ru/),

	// Create vendor.js bundle from node_modules imports
	// https://github.com/webpack/webpack/issues/2372#issuecomment-213149173
	new webpack.optimize.CommonsChunkPlugin({
		minChunks: ({resource}) => /node_modules/.test(resource),
		name: 'vendor'
	})
]

if (isProd) {
	plugins.push(new ExtractTextPlugin('[name].css'))
} else {
	plugins.push(new webpack.NamedModulesPlugin())
}

module.exports = {
	entry: path.resolve('src'),
	output: {
		filename: '[name].js',
		path: path.resolve('public')
	},
	devServer: {
		historyApiFallback: true,
		contentBase: path.resolve('public'),
		proxy: {
			'/ycm': {
				target: 'http://youcomedy.me',
				changeOrigin: true,
				pathRewrite: {'^/ycm' : ''}
			}
		}
	},
	resolve: {
		alias: {
			react: 'preact-compat',
			'react-dom': 'preact-compat'
		},
		modules: [
			path.resolve('src'),
			path.resolve('node_modules')
		]
	},
	plugins,
	module: {
		loaders: [{
			test: /\.js$/,
			include: [
				path.resolve('src'),

				// preact-compat needs to be transpiled
				// https://github.com/developit/preact-compat/issues/155#issuecomment-242905949
				path.resolve('node_modules/preact-compat')
			],
			loader: 'babel',
			query: {
				stage: 0,
				cacheDirectory: true
			}
		}, {
			test: /\.css$/,
			loader: !isProd
				? 'style!css'
				: ExtractTextPlugin.extract({
					fallbackLoader: 'style',
					loader: 'css'
				})
		}]
	}
}<commit_msg>Add source-maps<commit_after>const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const {version} = require('./package.json')

// NODE_ENV is not set for webpack config
// https://github.com/webpack/webpack/issues/2537#issuecomment-250950677
const isProd = process.argv.includes('-p')

const plugins = [
	new webpack.DefinePlugin({
		__VERSION__: JSON.stringify(version)
	}),
	new webpack.ProvidePlugin({
		i18n: 'i18next',
		Promise: 'bluebird',
		React: 'react'
	}),

	// Remove unnecessary moment.js locales
	// http://stackoverflow.com/a/25426019
	new webpack.ContextReplacementPlugin(/moment\/locale/, /ru/),

	// Create vendor.js bundle from node_modules imports
	// https://github.com/webpack/webpack/issues/2372#issuecomment-213149173
	new webpack.optimize.CommonsChunkPlugin({
		minChunks: ({resource}) => /node_modules/.test(resource),
		name: 'vendor'
	})
]

if (isProd) {
	plugins.push(new ExtractTextPlugin('[name].css'))
} else {
	plugins.push(new webpack.NamedModulesPlugin())
}

module.exports = {
	entry: path.resolve('src'),
	output: {
		filename: '[name].js',
		path: path.resolve('public')
	},

	// Enable source-maps
	// http://cheng.logdown.com/posts/2016/03/25/679045
	devtool: isProd
		? 'cheap-module-source-map'
		: 'cheap-module-eval-source-map',
	devServer: {
		historyApiFallback: true,
		contentBase: path.resolve('public'),
		proxy: {
			'/ycm': {
				target: 'http://youcomedy.me',
				changeOrigin: true,
				pathRewrite: {'^/ycm' : ''}
			}
		}
	},
	resolve: {
		alias: {
			react: 'preact-compat',
			'react-dom': 'preact-compat'
		},
		modules: [
			path.resolve('src'),
			path.resolve('node_modules')
		]
	},
	plugins,
	module: {
		loaders: [{
			test: /\.js$/,
			include: [
				path.resolve('src'),

				// preact-compat needs to be transpiled
				// https://github.com/developit/preact-compat/issues/155#issuecomment-242905949
				path.resolve('node_modules/preact-compat')
			],
			loader: 'babel',
			query: {
				stage: 0,
				cacheDirectory: true
			}
		}, {
			test: /\.css$/,
			loader: !isProd
				? 'style!css'
				: ExtractTextPlugin.extract({
					fallbackLoader: 'style',
					loader: 'css'
				})
		}]
	}
}<|endoftext|>


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

module.exports = {
  entry: './src',
  output: {
    path: path.join(__dirname, 'public'),
    filename: 'app.js'
  },
  resolve: {
    root: [
      path.join(__dirname, './src')
    ]
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  }
};
<commit_msg>add css modules loader<commit_after>var path = require('path');

module.exports = {
  entry: './src',
  output: {
    path: path.join(__dirname, 'public'),
    filename: 'app.js'
  },
  resolve: {
    root: [
      path.join(__dirname, './src')
    ]
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.css/,
        loader: 'style-loader!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader'
      }
    ]
  }
};
<|endoftext|>


<commit_before>/* eslint-disable */

var webpack = require('webpack');

module.exports = {
	output: {
		filename: 'index.js',
		libraryTarget: 'umd',
		library: 'ReactCheckboxTree',
	},
	externals: {
		react: 'React',
	},
	module: {
		loaders: [
			{
				test: /\.js?$/,
				exclude: /(node_modules|bower_components|vender_modules)/,
				loader: 'babel',
				query: {
					presets: ['react', 'es2015', 'stage-0']
				},
			},
		],
	},
};
<commit_msg>Fix some build issues when React is not included<commit_after>/* eslint-disable */

module.exports = {
	output: {
		filename: 'index.js',
		libraryTarget: 'umd',
		library: 'ReactCheckboxTree',
	},
	module: {
		loaders: [
			{
				test: /\.js?$/,
				exclude: /(node_modules|bower_components|vender_modules)/,
				loader: 'babel',
				query: {
					presets: ['react', 'es2015', 'stage-0']
				},
			},
		],
	},
};
<|endoftext|>


<commit_before>  /********************************************/
 /**				MARKERS					**/
/********************************************/

// Define marker icons
// For each region add an image to 'img/marker/'
var SL = L.icon({iconUrl: 'img/marker/SL.png',iconSize: [32, 74]})
var SLcapitol = L.icon({iconUrl: 'img/marker/SLcapitol.png',iconSize: [32, 74]})
var SLfort = L.icon({iconUrl: 'img/marker/SLfort.png',iconSize: [32, 74]})
var SLtown = L.icon({iconUrl: 'img/marker/SLtown.png',iconSize: [32, 74]})
var CL = L.icon({iconUrl: 'img/marker/CL.png',iconSize: [32, 74]})
var Dorne = L.icon({iconUrl: 'img/marker/Dorne.png',iconSize: [32, 74]})
var II = L.icon({iconUrl: 'img/marker/II.png',iconSize: [32, 74]})
var North = L.icon({iconUrl: 'img/marker/North.png',iconSize: [32, 74]})
var NotWesteros = L.icon({iconUrl: 'img/marker/NotWesteros.png',iconSize: [32, 74]})
var Reach = L.icon({iconUrl: 'img/marker/Reach.png',iconSize: [32, 74]})
var RL = L.icon({iconUrl: 'img/marker/RL.png',iconSize: [32, 74]})
var TrueNorth = L.icon({iconUrl: 'img/marker/TrueNorth.png',iconSize: [32, 74]})
var Vale = L.icon({iconUrl: 'img/marker/Vale.png',iconSize: [32, 74]})
var Valecapitol = L.icon({iconUrl: 'img/marker/Valecapitol.png',iconSize: [32, 74]})
var Valecity = L.icon({iconUrl: 'img/marker/Valecity.png',iconSize: [32, 74]})
var Valetown = L.icon({iconUrl: 'img/marker/Valetown.png',iconSize: [32, 74]})
var Valefort = L.icon({iconUrl: 'img/marker/Valefort.png',iconSize: [32, 74]})
var Wall = L.icon({iconUrl: 'img/marker/Wall.png',iconSize: [32, 74]})
var West = L.icon({iconUrl: 'img/marker/West.png',iconSize: [32, 74]})

// Define the markers
var markers = [
	// Each marker will be a line with the following format:
	//		[Lat, Long, icon, 'popup']
	// "Lat" and "Long" are the two numbers obtained by clicking on the map.
	// icon is one of the names defined above
	// popup is the text that will display on screen
//Stormlands
[-31.428663117358596,-114.697265625,SL,"Lover's Hill"],
[-32.76880048488168,-116.27929687499999,SL,"Nightsong"],
[-29.228890030194215,-107.841796875,SL,"Harvest Hall"],
[-30.524413269923986,-101.6015625,SL,"Blackhaven"],
[-25.562265014427492,-96.328125,SL,"Summerhall"],
[-21.37124437061831,-98.525390625,SL,"Broad Arch"],
[-25.720735134412095,-89.912109375,SL,"Grandview"],
[-31.503629305773018,-90.87890625,SL,"Stonehelm"],
[-29.305561325527712,-87.5390625,SL,"Crow's Nest"],
[-25.40358497318669,-82.96875,SL,"Griffin's Roost"],
[-28.613459424004414,-71.015625,SL,"Rain House"],
[-32.175612478499325,-73.740234375,SL,"Holywater"],
[-33.28461996888768,-77.6953125,SL,"Mistwood"],
[-36.17335693522159,-78.134765625,SLtown,"Weeping Town"],
[-35.02999636902566,-71.103515625,SL,"Greenstone"],
[-20.961439614096825,-69.78515625,SL,"Evenfall Hall"],
[-22.187404991398775,-78.22265625,SLcapitol,"Storm's End"],
[-15.876809064146757,-74.091796875,SL,"Parchments"],
[-12.811801316582606,-80.068359375,SL,"Haystack Hall"],
[-17.056784609942554,-82.44140625,SL,"Bronzegate"],
[-18.062312304546726,-92.10937499999999,SL,"Felwood"],
[-13.838079936422462,-93.955078125,SL,"Fawnton"],
[-33.06392419812064,-100.8984375,SLfort,"Caelen's Reach"],
[-11.350796722383672,-76.552734375,SLfort,"Durran's Grief"],
[-11.95334939364343,-86.923828125,SLfort,"Forrestwatch"],
[-29.228890030194215,-97.646484375,SL,"Gallowsgrey"],
//Vale
[27.21555620902969,-88.06640625,Vale,"Gates of the Moon"],
[28.844673680771795,-87.71484375,Valecapitol,"The Eyrie"],
[25.085598897064777,-92.197265625,Vale,"The Bloody Gate"],
[15.623036831528264,-79.453125,Valetown,"Wickendon"],
[25.085598897064777,-67.67578124999999,Valecity,"Gulltown"],
[26.980828590472107,-61.52343749999999,Vale,"Witch Isle"],
[27.761329874505233,-66.181640625,Vale,"Runestone"],
[29.611670115197406,-71.982421875,Vale,"Old Anchor"],
[33.211116472416855,-71.89453125,Vale,"Longbow Hall"],
[38.548165423046584,-66.09375,Vale,"Champion's Hall"],
[34.016241889667015,-83.75976562499999,Vale,"Heart's Home"],
[37.85750715625203,-80.15625,Vale,"Snakewood"],
[41.77131167976407,-77.431640625,Vale,"Coldwater Burn"],
[46.37725420510028,-69.60937499999999,Vale,"The Paps"],
[45.767522962149904,-78.134765625,Vale,"Pebble"],
[45.02695045318546,-83.84765625,Vale,"The Fingers"],
[47.754097979680026,-90,Valetown,"Three Sisters"],
[41.83682786072714,-88.59374999999999,Vale,"Ninestars"],
[41.64007838467894,-94.833984375,Valefort,"The Bite's Teeth"],
[34.66935854524545,-94.130859375,Vale,"Strongsong"],
[38.61687046392973,-85.60546875,Vale,"Newkeep"],
[31.728167146023935,-76.904296875,Vale,"Cloudspire"],
[28.14950321154457,-79.89257812499999,Vale,"Ironoaks"],
[25.878994400196202,-77.6953125,Vale,"Grey Glen"],
[24.367113562651276,-81.474609375,Vale,"Redfort"],
[21.94304553343818,-78.046875,Valefort,"Little Redfort"],
[27.371767300523047,-83.583984375,Vale,"Hardhold"]

]<commit_msg>North<commit_after>  /********************************************/
 /**				MARKERS					**/
/********************************************/

// Define marker icons
// For each region add an image to 'img/marker/'
var SL = L.icon({iconUrl: 'img/marker/SL.png',iconSize: [32, 74]})
var SLcapitol = L.icon({iconUrl: 'img/marker/SLcapitol.png',iconSize: [32, 74]})
var SLfort = L.icon({iconUrl: 'img/marker/SLfort.png',iconSize: [32, 74]})
var SLtown = L.icon({iconUrl: 'img/marker/SLtown.png',iconSize: [32, 74]})
var CL = L.icon({iconUrl: 'img/marker/CL.png',iconSize: [32, 74]})
var Dorne = L.icon({iconUrl: 'img/marker/Dorne.png',iconSize: [32, 74]})
var II = L.icon({iconUrl: 'img/marker/II.png',iconSize: [32, 74]})
var North = L.icon({iconUrl: 'img/marker/North.png',iconSize: [32, 74]})
var NotWesteros = L.icon({iconUrl: 'img/marker/NotWesteros.png',iconSize: [32, 74]})
var Reach = L.icon({iconUrl: 'img/marker/Reach.png',iconSize: [32, 74]})
var RL = L.icon({iconUrl: 'img/marker/RL.png',iconSize: [32, 74]})
var TrueNorth = L.icon({iconUrl: 'img/marker/TrueNorth.png',iconSize: [32, 74]})
var Vale = L.icon({iconUrl: 'img/marker/Vale.png',iconSize: [32, 74]})
var Valecapitol = L.icon({iconUrl: 'img/marker/Valecapitol.png',iconSize: [32, 74]})
var Valecity = L.icon({iconUrl: 'img/marker/Valecity.png',iconSize: [32, 74]})
var Valetown = L.icon({iconUrl: 'img/marker/Valetown.png',iconSize: [32, 74]})
var Valefort = L.icon({iconUrl: 'img/marker/Valefort.png',iconSize: [32, 74]})
var Wall = L.icon({iconUrl: 'img/marker/Wall.png',iconSize: [32, 74]})
var West = L.icon({iconUrl: 'img/marker/West.png',iconSize: [32, 74]})

// Define the markers
var markers = [
	// Each marker will be a line with the following format:
	//		[Lat, Long, icon, 'popup']
	// "Lat" and "Long" are the two numbers obtained by clicking on the map.
	// icon is one of the names defined above
	// popup is the text that will display on screen
//Stormlands
[-31.428663117358596,-114.697265625,SL,"Lover's Hill"],
[-32.76880048488168,-116.27929687499999,SL,"Nightsong"],
[-29.228890030194215,-107.841796875,SL,"Harvest Hall"],
[-30.524413269923986,-101.6015625,SL,"Blackhaven"],
[-25.562265014427492,-96.328125,SL,"Summerhall"],
[-21.37124437061831,-98.525390625,SL,"Broad Arch"],
[-25.720735134412095,-89.912109375,SL,"Grandview"],
[-31.503629305773018,-90.87890625,SL,"Stonehelm"],
[-29.305561325527712,-87.5390625,SL,"Crow's Nest"],
[-25.40358497318669,-82.96875,SL,"Griffin's Roost"],
[-28.613459424004414,-71.015625,SL,"Rain House"],
[-32.175612478499325,-73.740234375,SL,"Holywater"],
[-33.28461996888768,-77.6953125,SL,"Mistwood"],
[-36.17335693522159,-78.134765625,SLtown,"Weeping Town"],
[-35.02999636902566,-71.103515625,SL,"Greenstone"],
[-20.961439614096825,-69.78515625,SL,"Evenfall Hall"],
[-22.187404991398775,-78.22265625,SLcapitol,"Storm's End"],
[-15.876809064146757,-74.091796875,SL,"Parchments"],
[-12.811801316582606,-80.068359375,SL,"Haystack Hall"],
[-17.056784609942554,-82.44140625,SL,"Bronzegate"],
[-18.062312304546726,-92.10937499999999,SL,"Felwood"],
[-13.838079936422462,-93.955078125,SL,"Fawnton"],
[-33.06392419812064,-100.8984375,SLfort,"Caelen's Reach"],
[-11.350796722383672,-76.552734375,SLfort,"Durran's Grief"],
[-11.95334939364343,-86.923828125,SLfort,"Forrestwatch"],
[-29.228890030194215,-97.646484375,SL,"Gallowsgrey"],
//Vale
[27.21555620902969,-88.06640625,Vale,"Gates of the Moon"],
[28.844673680771795,-87.71484375,Valecapitol,"The Eyrie"],
[25.085598897064777,-92.197265625,Vale,"The Bloody Gate"],
[15.623036831528264,-79.453125,Valetown,"Wickendon"],
[25.085598897064777,-67.67578124999999,Valecity,"Gulltown"],
[26.980828590472107,-61.52343749999999,Vale,"Witch Isle"],
[27.761329874505233,-66.181640625,Vale,"Runestone"],
[29.611670115197406,-71.982421875,Vale,"Old Anchor"],
[33.211116472416855,-71.89453125,Vale,"Longbow Hall"],
[38.548165423046584,-66.09375,Vale,"Champion's Hall"],
[34.016241889667015,-83.75976562499999,Vale,"Heart's Home"],
[37.85750715625203,-80.15625,Vale,"Snakewood"],
[41.77131167976407,-77.431640625,Vale,"Coldwater Burn"],
[46.37725420510028,-69.60937499999999,Vale,"The Paps"],
[45.767522962149904,-78.134765625,Vale,"Pebble"],
[45.02695045318546,-83.84765625,Vale,"The Fingers"],
[47.754097979680026,-90,Valetown,"Three Sisters"],
[41.83682786072714,-88.59374999999999,Vale,"Ninestars"],
[41.64007838467894,-94.833984375,Valefort,"The Bite's Teeth"],
[34.66935854524545,-94.130859375,Vale,"Strongsong"],
[38.61687046392973,-85.60546875,Vale,"Newkeep"],
[31.728167146023935,-76.904296875,Vale,"Cloudspire"],
[28.14950321154457,-79.89257812499999,Vale,"Ironoaks"],
[25.878994400196202,-77.6953125,Vale,"Grey Glen"],
[24.367113562651276,-81.474609375,Vale,"Redfort"],
[21.94304553343818,-78.046875,Valefort,"Little Redfort"],
[27.371767300523047,-83.583984375,Vale,"Hardhold"]
//North
[47.040182144806664,-112.763671875,North,"Greywater Watch"],
[51.45400691005982,-107.40234375,North,"Moat Cailin"],
[50.56928286558243,-94.39453125,North,"Oldcastle"],
[56.12106042504407,-98.525390625,North,"White Harbor"],
[58.44773280389084,-80.947265625,North,"Ramsgate"],
[57.27904276497778,-67.8515625,North,"Widow's Watch"]
]<|endoftext|>


<commit_before>const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const tsLoader = nextLoader => ({
  test: /\.(ts|tsx|js|)$/,
  use: [
    {
      loader: 'ts-loader',
      options: {
        onlyCompileBundledFiles: true,
      },
    },
    nextLoader,
  ].filter(Boolean),
  exclude: [/node_modules/, /\.ejs$/],
});

module.exports = (env) => {
  const isProd = env.prod === true;
  const isExample = env.example === true;
  const type = isExample ? 'example' : 'lib';

  // eslint-disable-next-line no-console
  console.log(`Compiling: ${type} in mode: ${isProd ? 'production' : 'dev'}`);

  const entries = {
    example: './example/src/index.tsx',
    lib: './src/index.ts',
  };

  const outputPaths = {
    example: path.resolve(__dirname, 'example/dist'),
    lib: path.resolve(__dirname, 'dist'),
  };

  const config = {
    entry: entries[type],
    resolve: {
      extensions: ['.tsx', '.ts', '.js'],
    },
    output: {
      path: outputPaths[type],
      filename: 'index.js',
    },
  };

  if (isProd) {
    return webpackMerge(config, {
      module: {
        rules: [tsLoader()],
      },
      mode: 'production',
      optimization: {
        minimize: false,
      },
      output: {
        library: 'ReactRouterLastLocation',
        libraryTarget: 'umd',
      },
      // @see https://github.com/webpack/webpack/issues/603#issuecomment-215547651
      externals: /^[^.]/,
      plugins: [
        new webpack.DefinePlugin({
          'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV) },
        }),
      ],
    });
  }

  return webpackMerge(config, {
    module: {
      rules: [
        tsLoader({
          loader: 'linaria/loader',
          options: {
            sourceMap: true,
          },
        }),
        {
          test: /\.css$/,
          use: [
            'css-hot-loader',
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                modules: 'global',
                sourceMap: true,
              },
            },
          ],
        },
      ],
    },
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    devServer: {
      contentBase: outputPaths.example,
      compress: true,
      hot: true,
      port: 8080,
      historyApiFallback: { disableDotRule: true },
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './example/src/index.ejs',
      }),
      new MiniCssExtractPlugin({
        filename: 'styles.css',
      }),
      new webpack.HotModuleReplacementPlugin(),
    ],
  });
};
<commit_msg>Fix(webpack): #21 Add output.globalObject prop to fix umd build for node<commit_after>const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const tsLoader = nextLoader => ({
  test: /\.(ts|tsx|js|)$/,
  use: [
    {
      loader: 'ts-loader',
      options: {
        onlyCompileBundledFiles: true,
      },
    },
    nextLoader,
  ].filter(Boolean),
  exclude: [/node_modules/, /\.ejs$/],
});

module.exports = (env) => {
  const isProd = env.prod === true;
  const isExample = env.example === true;
  const type = isExample ? 'example' : 'lib';

  // eslint-disable-next-line no-console
  console.log(`Compiling: ${type} in mode: ${isProd ? 'production' : 'dev'}`);

  const entries = {
    example: './example/src/index.tsx',
    lib: './src/index.ts',
  };

  const outputPaths = {
    example: path.resolve(__dirname, 'example/dist'),
    lib: path.resolve(__dirname, 'dist'),
  };

  const config = {
    entry: entries[type],
    resolve: {
      extensions: ['.tsx', '.ts', '.js'],
    },
    output: {
      path: outputPaths[type],
      filename: 'index.js',
    },
  };

  if (isProd) {
    return webpackMerge(config, {
      module: {
        rules: [tsLoader()],
      },
      mode: 'production',
      optimization: {
        minimize: false,
      },
      output: {
        library: 'ReactRouterLastLocation',
        libraryTarget: 'umd',
        /**
         * When targeting a library, especially the libraryTarget is 'umd',
         * this option indicates what global object will be used to mount the library.
         * To make UMD build available on both browsers and Node.js,
         * set output.globalObject option to 'this'.
         * @see https://webpack.js.org/configuration/output/#outputglobalobject
         */
        globalObject: 'this',
      },
      // @see https://github.com/webpack/webpack/issues/603#issuecomment-215547651
      externals: /^[^.]/,
      plugins: [
        new webpack.DefinePlugin({
          'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV) },
        }),
      ],
    });
  }

  return webpackMerge(config, {
    module: {
      rules: [
        tsLoader({
          loader: 'linaria/loader',
          options: {
            sourceMap: true,
          },
        }),
        {
          test: /\.css$/,
          use: [
            'css-hot-loader',
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                modules: 'global',
                sourceMap: true,
              },
            },
          ],
        },
      ],
    },
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    devServer: {
      contentBase: outputPaths.example,
      compress: true,
      hot: true,
      port: 8080,
      historyApiFallback: { disableDotRule: true },
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './example/src/index.ejs',
      }),
      new MiniCssExtractPlugin({
        filename: 'styles.css',
      }),
      new webpack.HotModuleReplacementPlugin(),
    ],
  });
};
<|endoftext|>