<commit_before>// extractWebVTT will receive a video file and use mplayer to retrieve
// chaper information. It then converts the output from mplayer into a
// valid WebVTT format and saves it as a file with same name/path with
// extension .webvtt!

// Dependencies
const fs=require("fs");
const moment=require("moment");
require("moment-duration-format");
const exec=require('child_process').exec;

// Time/Chapter Stuff
const re=/^ID_CHAPTER_(\d{1,5})_(start|end|name)=(.*)$/gim;
const TIMEFMT="HH:mm:ss.SSS";
const TIMEOPTS={forceLength:true, trim:false};
function timeFormat(dur){return moment.duration(parseInt(dur)).format(TIMEFMT,TIMEOPTS)}

// Variables
var match, data={}, webvtt="WEBVTT FILE", ch, chdata;
var videoFilePath=process.argv[2];

// Run then process the mplayer results
var mplayerOutput=exec(`mplayer -vo null -ao null -identify -frames 0 ${videoFilePath}`,(err,stdout,stderr)=>{
    if( err ) {
        console.error(stderr);
    } else {
        // Build a map by finding all matches in mplayer's info output
        while( match=re.exec(mplayerOutput) ) {
            if( !data[match[1]] ) data[match[1]]={};
            data[match[1]][match[2].toLowerCase()]=match[3];
        }
        // Loop through the chapters and builds the WebVTT
        for( ch in data ) {
            chdata=data[ch];
            webvtt+=`\n\n${ch}`;
            webvtt+=`\n${moment.duration(parseInt(chdata.start)).format(TIMEFMT,TIMEOPTS)} --> `;
            webvtt+=`${moment.duration(parseInt(chdata.end)).format(TIMEFMT,TIMEOPTS)}`;
            webvtt+=`\n${chdata.name}`;
        }
        // Save the WebVTT file.
        var webvttpath=videoFilePath+".webvtt";
        fs.writeFileSync(webvttpath, webvtt);
    }
})
<commit_msg>Fixed to properly process mplayer output. The extractWebVTT script just uses output from mplayer to output content in webvtt format.<commit_after>// extractWebVTT will receive a video file and use mplayer to retrieve
// chaper information. It then converts the output from mplayer into a
// valid WebVTT format and saves it as a file with same name/path with
// extension .webvtt!

// Dependencies
const fs=require("fs");
const moment=require("moment");
require("moment-duration-format");
const exec=require('child_process').exec;

// Time/Chapter Stuff
const re=/^ID_CHAPTER_(\d{1,5})_(start|end|name)=(.*)$/gim;
const TIMEFMT="HH:mm:ss.SSS";
const TIMEOPTS={forceLength:true, trim:false};
function timeFormat(dur){return moment.duration(parseInt(dur)).format(TIMEFMT,TIMEOPTS)}

// Variables
var match, data={}, webvtt="WEBVTT FILE", ch, chdata;
var videoFilePath=process.argv[2];

// Run then process the mplayer results
exec(`mplayer -vo null -ao null -identify -frames 0 ${videoFilePath}`,(err,stdout,stderr)=>{
    if( err ) {
        console.error(stderr);
    } else {
        // Build a map by finding all matches in mplayer's info output
        while( match=re.exec(stdout) ) {
            if( !data[match[1]] ) data[match[1]]={};
            data[match[1]][match[2].toLowerCase()]=match[3];
        }
        // Loop through the chapters and builds the WebVTT
        for( ch in data ) {
            chdata=data[ch];
            webvtt+=`\n\n${ch}`;
            webvtt+=`\n${moment.duration(parseInt(chdata.start)).format(TIMEFMT,TIMEOPTS)} --> `;
            webvtt+=`${moment.duration(parseInt(chdata.end)).format(TIMEFMT,TIMEOPTS)}`;
            webvtt+=`\n${chdata.name}`;
        }
        // Save the WebVTT file.
        var webvttpath=videoFilePath+".webvtt";
        fs.writeFileSync(webvttpath, webvtt);
        console.log(webvtt);
    }
})
<|endoftext|>


<commit_before>import { map } from 'lodash';
import {
  join,
  truncate,
} from '../../lib/helpers';
import { getDefault } from '../image';
import { setVersion } from '../image/normalize';
import {
  GraphQLInt,
  GraphQLString,
  GraphQLObjectType,
} from 'graphql';

const titleWithDate = ({ title, date }) => join(' ', [
  title,
  date ? `(${date})` : undefined,
]);

const artistNames = artwork =>
  map(artwork.artists, 'name').join(', ');

const forSaleIndication = artwork =>
  artwork.forsale ? 'Available for Sale' : undefined;

const dimensions = artwork =>
  artwork.dimensions[artwork.metric];

const partnerDescription = ({ partner: { name }, forsale }) => {
  if (!name) return undefined;
  return forsale ? `Available for sale from ${name}` : `From ${name}`;
};

const ArtworkMetaType = new GraphQLObjectType({
  name: 'ArtworkMeta',
  fields: {
    title: {
      type: GraphQLString,
      resolve: artwork => join(' | ', [
        artistNames(artwork),
        titleWithDate(artwork),
        forSaleIndication(artwork),
        'Artsy',
      ]),
    },
    description: {
      type: GraphQLString,
      args: {
        limit: {
          type: GraphQLInt,
          defaultValue: 155,
        },
      },
      resolve: (artwork, { limit }) => truncate(join(', ', [
        partnerDescription(artwork),
        artistNames(artwork),
        titleWithDate(artwork),
        artwork.medium,
        dimensions(artwork),
      ]), limit),
    },
    image: {
      type: GraphQLString,
      resolve: ({ images }) =>
        setVersion(getDefault(images), [
          'large',
          'medium',
          'tall',
        ]),
    },
  },
});

export default {
  type: ArtworkMetaType,
  resolve: x => x,
};
<commit_msg>Support cultural_maker for artwork meta titles<commit_after>import { map } from 'lodash';
import {
  join,
  truncate,
} from '../../lib/helpers';
import { getDefault } from '../image';
import { setVersion } from '../image/normalize';
import {
  GraphQLInt,
  GraphQLString,
  GraphQLObjectType,
} from 'graphql';

const titleWithDate = ({ title, date }) => join(' ', [
  title,
  date ? `(${date})` : undefined,
]);

const artistNames = artwork =>
  artwork.cultural_maker || map(artwork.artists, 'name').join(', ');

const forSaleIndication = artwork =>
  artwork.forsale ? 'Available for Sale' : undefined;

const dimensions = artwork =>
  artwork.dimensions[artwork.metric];

const partnerDescription = ({ partner: { name }, forsale }) => {
  if (!name) return undefined;
  return forsale ? `Available for sale from ${name}` : `From ${name}`;
};

const ArtworkMetaType = new GraphQLObjectType({
  name: 'ArtworkMeta',
  fields: {
    title: {
      type: GraphQLString,
      resolve: artwork => join(' | ', [
        artistNames(artwork),
        titleWithDate(artwork),
        forSaleIndication(artwork),
        'Artsy',
      ]),
    },
    description: {
      type: GraphQLString,
      args: {
        limit: {
          type: GraphQLInt,
          defaultValue: 155,
        },
      },
      resolve: (artwork, { limit }) => truncate(join(', ', [
        partnerDescription(artwork),
        artistNames(artwork),
        titleWithDate(artwork),
        artwork.medium,
        dimensions(artwork),
      ]), limit),
    },
    image: {
      type: GraphQLString,
      resolve: ({ images }) =>
        setVersion(getDefault(images), [
          'large',
          'medium',
          'tall',
        ]),
    },
  },
});

export default {
  type: ArtworkMetaType,
  resolve: x => x,
};
<|endoftext|>


<commit_before>import _ from 'lodash';
import qs from 'qs';
import cached from './fields/cached';
import date from './fields/date';
import Image from './image';
import Artist from './artist';
import Artwork from './artwork';
import gravity from '../lib/loaders/gravity';
import {
  GraphQLObjectType,
  GraphQLBoolean,
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
  GraphQLInt
} from 'graphql';

let SaleArtworkType = new GraphQLObjectType({
  name: 'SaleArtwork',
  fields: () => {
    return {
      cached: cached,
      _id: {
        type: GraphQLString
      },
      id: {
        type: GraphQLString
      },
      sale_id: {
        type: GraphQLString
      },
      position: {
        type: GraphQLInt
      },
      lot_number: {
        type: GraphQLString
      },
      bidder_positions_count: {
        type: GraphQLInt
      },
      reserve_status: {
        type: GraphQLString
      },
      opening_bid_cents: {
        type: GraphQLString
      },
      minimum_next_bid_cents: {
        type: GraphQLString
      },
      highest_bid: {
        type: new GraphQLObjectType({
          name: 'highest_bid',
          fields: {
            created_at: date,
            amount_cents: {
              type: GraphQLString
            }
          }
        })
      },
      artwork: {
        type: Artwork.type,
        resolve: ({ artwork }) => artwork
      }
    }
  }
});

let SaleArtwork = {
  type: SaleArtworkType,
  description: 'A Sale Artwork',
  args: {
    sale_id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The slug or ID of the Sale'
    },
    id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The slug or ID of the SaleArtwork'
    }
  },
  resolve: (root, { sale_id, id }) => {
    return gravity(`sale/${sale_id}/sale_artwork/${id}`)
  }
};

export default SaleArtwork;
<commit_msg>adds a few more fields to SaleArtwork<commit_after>import _ from 'lodash';
import qs from 'qs';
import cached from './fields/cached';
import date from './fields/date';
import Image from './image';
import Artist from './artist';
import Artwork from './artwork';
import gravity from '../lib/loaders/gravity';
import {
  GraphQLObjectType,
  GraphQLBoolean,
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
  GraphQLInt
} from 'graphql';

let SaleArtworkType = new GraphQLObjectType({
  name: 'SaleArtwork',
  fields: () => {
    return {
      cached: cached,
      _id: {
        type: GraphQLString
      },
      id: {
        type: GraphQLString
      },
      sale_id: {
        type: GraphQLString
      },
      position: {
        type: GraphQLInt
      },
      lot_number: {
        type: GraphQLString
      },
      bidder_positions_count: {
        type: GraphQLInt
      },
      reserve_status: {
        type: GraphQLString
      },
      low_estimate_cents: {
        type: GraphQLString
      },
      high_estimate_cents: {
        type: GraphQLString
      },
      opening_bid_cents: {
        type: GraphQLString
      },
      currency: {
        type: GraphQLString
      },
      symbol: {
        type: GraphQLString
      },
      minimum_next_bid_cents: {
        type: GraphQLString
      },
      highest_bid: {
        type: new GraphQLObjectType({
          name: 'highest_bid',
          fields: {
            created_at: date,
            amount_cents: {
              type: GraphQLString
            }
          }
        })
      },
      artwork: {
        type: Artwork.type,
        resolve: ({ artwork }) => artwork
      }
    }
  }
});

let SaleArtwork = {
  type: SaleArtworkType,
  description: 'A Sale Artwork',
  args: {
    sale_id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The slug or ID of the Sale'
    },
    id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The slug or ID of the SaleArtwork'
    }
  },
  resolve: (root, { sale_id, id }) => {
    return gravity(`sale/${sale_id}/sale_artwork/${id}`)
  }
};

export default SaleArtwork;
<|endoftext|>


<commit_before>import Parser from 'src/external/bibtexParse.js';
import Morph from 'src/components/widgets/lively-morph.js';
import ContextMenu from 'src/client/contextmenu.js'
import {Paper} from 'src/client/literature.js'
import Bibliography from "src/client/bibliography.js"

/*MD
# Lively Bibtex

![](lively-bibtex.png){style="width:350px"}

MD*/

export default class LivelyBibtex extends Morph {
  async initialize() {

    this.setAttribute("tabindex", 0) // just ensure focusabiltity
    this.windowTitle = "LivelyBibtex";
    this.addEventListener('contextmenu', evt => this.onContextMenu(evt), false);
    this.addEventListener("click", evt => this.onClick(evt))
    this.addEventListener("drop", this.onDrop);
    this.addEventListener("copy", (evt) => this.onCopy(evt))
    this.addEventListener("cut", (evt) => this.onCut(evt))
    this.addEventListener("paste", (evt) => this.onPaste(evt))
    this.updateView()
    this.registerButtons()
  }

  selectedEntries() {
    return Array.from(this.querySelectorAll("lively-bibtex-entry.selected"))
  }

  async importEntries(entries) {

    var source = entries.map(ea => ea.textContent).join("\n")

    return Paper.importBibtexSource(source)
  }

  onContextMenu(evt) {
    if (!evt.shiftKey) {
      var entries = this.selectedEntries()
      if (entries.length == 0) {
        entries = evt.composedPath().filter(ea => ea.localName == "lively-bibtex-entry")
      }
      if (entries.length == 0) return // nothing selected or clicked on

      evt.stopPropagation();
      evt.preventDefault();
      var menu = new ContextMenu(this, [
        ["generate key", () => {
          entries.forEach(ea => {
            var entry = ea.value
            var key = Bibliography.generateCitationKey(entry)
            if (key) {
              entry.citationKey = Bibliography.generateCitationKey(entry)
              ea.value = entry
            } else {
              lively.warn("Bibtex: Could net gernerate key for", ea.toBibtex())
            }
          })
        }],
        ["generate key and replace all occurences", () => {
          entries.forEach(ea => {
            var entry = ea.value
            var oldkey = ea.value.citationKey
            var key = Bibliography.generateCitationKey(entry)
            if (key) {
              entry.citationKey = Bibliography.generateCitationKey(entry)
              ea.value = entry

             lively.openComponentInWindow("lively-index-search").then(comp => {
              comp.searchAndReplace(oldkey, key)
              lively.setExtent(comp.parentElement, lively.pt(1000, 700));
              comp.focus();
            });

            } else {
              lively.warn("Bibtex: Could net gernerate key for", ea.toBibtex())
            }
          })
        }],
        ["import", () => {
            this.importEntries(entries)
        }],
        ["remove", () => {
            entries.forEach(ea => {
              ea.remove()
            })
        }]
      ]);
      menu.openIn(document.body, evt, this);
      return
    }
  }

  onCopy(evt) {
    if (this.isEditing()) return;
    var data = this.selectedEntries().map(ea => ea.textContent).join("")
    evt.clipboardData.setData('text/plain', data);
    evt.stopPropagation()
    evt.preventDefault()
  }

  onCut(evt) {
    if (this.isEditing()) return;
    this.onCopy(evt)
    this.selectedEntries().forEach(ea => ea.remove())
  }

  async onPaste(evt) {
    if (this.isEditing()) return;
    var scroll = this.scrollTop
    var data = evt.clipboardData.getData('text');
    var entries = this.parseEntries(data)
    this.selectedEntries().forEach(ea => ea.classList.remove("selected"))

    if (entries) {
     for (var ea of entries) {
      var entryElement = await this.appendBibtexEntry(ea)
      entryElement.classList.add("selected")
      if (this.currentEntry) this.insertBefore(entryElement, this.currentEntry)
     }
    }
    await lively.sleep(0)
    this.scrollTop = scroll
  }

  parseEntries(source) {
    try {
      return Parser.toJSON(source);
    } catch(e) {
      lively.notify("Bibtex could not parse: " + source)
    }
  }

  isEditing() {
    return this.currentEntry && (this.currentEntry.getAttribute("mode") == "edit")
  }

  async onDrop(evt) {
    evt.preventDefault();
    evt.stopPropagation();

    var source = evt.dataTransfer.getData("text");
    var value = this.parseEntries(source)
    if (value) {
      value = value[0]
      var beforeEntry = this.findEntryInPath(evt.composedPath())
      var newEntry = await this.appendBibtexEntry(value)
      if (beforeEntry) this.insertBefore(newEntry, beforeEntry)
    }

  }

  get src() {
    return this.getAttribute("src")
  }

  set src(url) {
    this.setAttribute("src", url)
    this.updateView()
  }

  findEntryInPath(path) {
    return path.find(ea => ea.tagName == "lively-bibtex-entry".toUpperCase())
  }

  onClick(evt) {
    // don't interfere with selection
    if (window.getSelection().toString().length > 0) return
    if (this.isEditing()) return;
    // var oldScroll
    var entry = this.findEntryInPath(evt.composedPath())
    if (!entry) return;
    this.select(entry, evt.shiftKey)

    if (entry.getAttribute("mode") != "edit") {
      lively.focusWithoutScroll(this.get("#copyHack"))
    }
  }

  select(entry, keepSelection) {
    if (this.currentEntry && !keepSelection) {
      this.currentEntry.classList.remove("selected")
    }
    if (this.currentEntry === entry) {
      this.currentEntry = null
    } else {
      entry.classList.add("selected")
      this.currentEntry = entry
    }
  }

  async appendBibtexEntry(value) {
    var entry = await (<lively-bibtex-entry></lively-bibtex-entry>)
    entry.value = value
    this.appendChild(entry)
    return entry
  }

  async updateView() {
    if (!this.src) {
      var source = this.textContent
      this.innerHTML = ""
      return this.setBibtex(source)
    }
    this.innerHTML = ""
    source = await fetch(this.src).then(res => res.text());
    return this.setBibtex(source)
  }

  async setBibtex(source) {
    try {
      var json= Parser.toJSON(source);
    } catch(e) {
      this.innerHTML = "" + e
    }
    for(var ea of json) {
      await this.appendBibtexEntry(ea)
    }
  }

  toBibtex() {
    var bibtex = ""
    for(var ea of this.querySelectorAll("lively-bibtex-entry")) {
      bibtex += ea.innerHTML
    }
    return bibtex
  }

  async onSaveButton() {
    var bibtex = this.toBibtex()
    if (!this.src) throw new Error("BibtexEditor src missing" )
    lively.files.saveFile(this.src, bibtex)
      .then(() => lively.success("saved bibtex", this.src, 5,
                                  () => lively.openBrowser(this.src)))
  }

  async onEditButton(evt) {

    if (this.style.position) {
      var pos = lively.getPosition(this)
      var extent = lively.getExtent(this)
    }
    var editor = await (<lively-bibtex-editor></lively-bibtex-editor>)
    if (this.src) {
      editor.setAttribute("src", this.src)
    } else {
      editor.textContent = this.textContent
    }
    if (evt.shiftKey) {
      var win = await (<lively-window>{editor}</lively-window>)
      document.body.appendChild(win)
      editor.updateView()
      this.remove()
      if (pos) {
        lively.setPosition(win, pos)
        // lively.setExtent(win, extent)
      }
    } else {
     this.parentElement.insertBefore(editor, this)
      editor.updateView()
      this.remove()
      if (pos) {
        lively.setPosition(editor, pos)
        lively.setExtent(editor, extent)
      }
    }

  }

  livelySource() {
    return Array.from(this.querySelectorAll("lively-bibtex-entry")).map(ea => ea.textContent).join("")
  }

  async livelyExample() {
    // this customizes a default instance to a pretty example
    // this is used by the
    this.src = lively4url + "/demos/bibliographie/_incoming.bib"
    this.style.overflow = "scroll"
  }

}<commit_msg>[bibtex] allow to copy selected text<commit_after>import Parser from 'src/external/bibtexParse.js';
import Morph from 'src/components/widgets/lively-morph.js';
import ContextMenu from 'src/client/contextmenu.js'
import {Paper} from 'src/client/literature.js'
import Bibliography from "src/client/bibliography.js"

/*MD
# Lively Bibtex

![](lively-bibtex.png){style="width:350px"}

MD*/

export default class LivelyBibtex extends Morph {
  async initialize() {

    this.setAttribute("tabindex", 0) // just ensure focusabiltity
    this.windowTitle = "LivelyBibtex";
    this.addEventListener('contextmenu', evt => this.onContextMenu(evt), false);
    this.addEventListener("click", evt => this.onClick(evt))
    this.addEventListener("drop", this.onDrop);
    this.addEventListener("copy", (evt) => this.onCopy(evt))
    this.addEventListener("cut", (evt) => this.onCut(evt))
    this.addEventListener("paste", (evt) => this.onPaste(evt))
    this.updateView()
    this.registerButtons()
  }

  selectedEntries() {
    return Array.from(this.querySelectorAll("lively-bibtex-entry.selected"))
  }

  async importEntries(entries) {

    var source = entries.map(ea => ea.textContent).join("\n")

    return Paper.importBibtexSource(source)
  }

  onContextMenu(evt) {
    if (!evt.shiftKey) {
      var entries = this.selectedEntries()
      if (entries.length == 0) {
        entries = evt.composedPath().filter(ea => ea.localName == "lively-bibtex-entry")
      }
      if (entries.length == 0) return // nothing selected or clicked on

      evt.stopPropagation();
      evt.preventDefault();
      var menu = new ContextMenu(this, [
        ["generate key", () => {
          entries.forEach(ea => {
            var entry = ea.value
            var key = Bibliography.generateCitationKey(entry)
            if (key) {
              entry.citationKey = Bibliography.generateCitationKey(entry)
              ea.value = entry
            } else {
              lively.warn("Bibtex: Could net gernerate key for", ea.toBibtex())
            }
          })
        }],
        ["generate key and replace all occurences", () => {
          entries.forEach(ea => {
            var entry = ea.value
            var oldkey = ea.value.citationKey
            var key = Bibliography.generateCitationKey(entry)
            if (key) {
              entry.citationKey = Bibliography.generateCitationKey(entry)
              ea.value = entry

             lively.openComponentInWindow("lively-index-search").then(comp => {
              comp.searchAndReplace(oldkey, key)
              lively.setExtent(comp.parentElement, lively.pt(1000, 700));
              comp.focus();
            });

            } else {
              lively.warn("Bibtex: Could net gernerate key for", ea.toBibtex())
            }
          })
        }],
        ["import", () => {
            this.importEntries(entries)
        }],
        ["remove", () => {
            entries.forEach(ea => {
              ea.remove()
            })
        }]
      ]);
      menu.openIn(document.body, evt, this);
      return
    }
  }

  onCopy(evt) {
    if (this.isEditing()) return;
    if (window.getSelection().toString().length > 0) return
    var data = this.selectedEntries().map(ea => ea.textContent).join("")
    evt.clipboardData.setData('text/plain', data);
    evt.stopPropagation()
    evt.preventDefault()
  }

  onCut(evt) {
    if (this.isEditing()) return;
    if (window.getSelection().toString().length > 0) return
    this.onCopy(evt)
    this.selectedEntries().forEach(ea => ea.remove())
  }

  async onPaste(evt) {
    if (this.isEditing()) return;
    var scroll = this.scrollTop
    var data = evt.clipboardData.getData('text');
    var entries = this.parseEntries(data)
    this.selectedEntries().forEach(ea => ea.classList.remove("selected"))

    if (entries) {
     for (var ea of entries) {
      var entryElement = await this.appendBibtexEntry(ea)
      entryElement.classList.add("selected")
      if (this.currentEntry) this.insertBefore(entryElement, this.currentEntry)
     }
    }
    await lively.sleep(0)
    this.scrollTop = scroll
  }

  parseEntries(source) {
    try {
      return Parser.toJSON(source);
    } catch(e) {
      lively.notify("Bibtex could not parse: " + source)
    }
  }

  isEditing() {
    return this.currentEntry && (this.currentEntry.getAttribute("mode") == "edit")
  }

  async onDrop(evt) {
    evt.preventDefault();
    evt.stopPropagation();

    var source = evt.dataTransfer.getData("text");
    var value = this.parseEntries(source)
    if (value) {
      value = value[0]
      var beforeEntry = this.findEntryInPath(evt.composedPath())
      var newEntry = await this.appendBibtexEntry(value)
      if (beforeEntry) this.insertBefore(newEntry, beforeEntry)
    }

  }

  get src() {
    return this.getAttribute("src")
  }

  set src(url) {
    this.setAttribute("src", url)
    this.updateView()
  }

  findEntryInPath(path) {
    return path.find(ea => ea.tagName == "lively-bibtex-entry".toUpperCase())
  }

  onClick(evt) {
    // don't interfere with selection
    if (window.getSelection().toString().length > 0) return
    if (this.isEditing()) return;
    // var oldScroll
    var entry = this.findEntryInPath(evt.composedPath())
    if (!entry) return;
    this.select(entry, evt.shiftKey)

    if (entry.getAttribute("mode") != "edit") {
      lively.focusWithoutScroll(this.get("#copyHack"))
    }
  }

  select(entry, keepSelection) {
    if (this.currentEntry && !keepSelection) {
      this.currentEntry.classList.remove("selected")
    }
    if (this.currentEntry === entry) {
      this.currentEntry = null
    } else {
      entry.classList.add("selected")
      this.currentEntry = entry
    }
  }

  async appendBibtexEntry(value) {
    var entry = await (<lively-bibtex-entry></lively-bibtex-entry>)
    entry.value = value
    this.appendChild(entry)
    return entry
  }

  async updateView() {
    if (!this.src) {
      var source = this.textContent
      this.innerHTML = ""
      return this.setBibtex(source)
    }
    this.innerHTML = ""
    source = await fetch(this.src).then(res => res.text());
    return this.setBibtex(source)
  }

  async setBibtex(source) {
    try {
      var json= Parser.toJSON(source);
    } catch(e) {
      this.innerHTML = "" + e
    }
    for(var ea of json) {
      await this.appendBibtexEntry(ea)
    }
  }

  toBibtex() {
    var bibtex = ""
    for(var ea of this.querySelectorAll("lively-bibtex-entry")) {
      bibtex += ea.innerHTML
    }
    return bibtex
  }

  async onSaveButton() {
    var bibtex = this.toBibtex()
    if (!this.src) throw new Error("BibtexEditor src missing" )
    lively.files.saveFile(this.src, bibtex)
      .then(() => lively.success("saved bibtex", this.src, 5,
                                  () => lively.openBrowser(this.src)))
  }

  async onEditButton(evt) {

    if (this.style.position) {
      var pos = lively.getPosition(this)
      var extent = lively.getExtent(this)
    }
    var editor = await (<lively-bibtex-editor></lively-bibtex-editor>)
    if (this.src) {
      editor.setAttribute("src", this.src)
    } else {
      editor.textContent = this.textContent
    }
    if (evt.shiftKey) {
      var win = await (<lively-window>{editor}</lively-window>)
      document.body.appendChild(win)
      editor.updateView()
      this.remove()
      if (pos) {
        lively.setPosition(win, pos)
        // lively.setExtent(win, extent)
      }
    } else {
     this.parentElement.insertBefore(editor, this)
      editor.updateView()
      this.remove()
      if (pos) {
        lively.setPosition(editor, pos)
        lively.setExtent(editor, extent)
      }
    }

  }

  livelySource() {
    return Array.from(this.querySelectorAll("lively-bibtex-entry")).map(ea => ea.textContent).join("")
  }

  async livelyExample() {
    // this customizes a default instance to a pretty example
    // this is used by the
    this.src = lively4url + "/demos/bibliographie/_incoming.bib"
    this.style.overflow = "scroll"
  }

}<|endoftext|>


<commit_before>new function () {

	base2.package(this, {
		name:    'sampleApp',
		imports: 'miruken.mvc,sampleApp.domain',
		exports: 'ModalsController'
	});

	eval(this.imports);

	var ModalsController = Controller.extend(MasterDetail, {
        getSelectedDetail: function(target){
            if (target === Person) {
                return new Person({
                    firstName: 'Dalinar',
                    lastName:  'Kholin'
                });
            }
        },
		showWrappedModal: function () {
            ViewRegion(this.context.modal({
            	title: 'Hooray!',
        		footer: true })
            ).present({
                templateUrl: 'app/modals/wrappedModal.html',
                controller:  'WrappedModalController as vm'
            });
		},
		showWrappedModalWithHeader: function () {
            ViewRegion(this.context.modal({
                title: 'Just a Header',
        		header: true })
            ).present({
                templateUrl: 'app/modals/wrappedModal.html',
                controller:  'WrappedModalController as vm'
            });
		},
		showWrappedModalWithFooter: function () {
            ViewRegion(this.context.modal({ footer: true }))
                .present({
                    templateUrl: 'app/modals/wrappedModal.html',
                    controller:  'WrappedModalController as vm'
                });
		},
		showFullModal: function () {
            ViewRegion(this.context.modal({ chrome: false }))
            	.present({
	                templateUrl: 'app/modals/fullModal.html',
	                controller:  'FullModalController as vm'
	            });
		},
		showSelfClosingModal: function () {
            ViewRegion(this.context.modal({ forceClose: true }))
            	.present({
	                templateUrl: 'app/modals/selfClosingModal.html',
	                controller:  'SelfClosingModalController as vm'
	            });
		},
        showModalWithButtons: function () {
            ViewRegion(this.context.modal({
                title: 'Buttons',
                buttons: [
                    { text: 'Primary', css: 'btn-primary btn-xs' },
                    { text: 'Default', css: 'btn-default btn-sm' },
                    { text: 'Success', css: 'btn-success' },
                    { text: 'Warning', css: 'btn-warning' },
                    { text: 'Danger',  css: 'btn-danger btn-lg' },
                ]})
            ).present({ template: '
Demo adding buttons with classes.
' })
                .then(function (context) {
                    context.modalResult.then(function (result) {
                        if (result)
                            alert(format('Button %1 - %2', result.buttonIndex, result.button.text));
                    });
                });
        },
        showConfirmModal: function () {
            ViewRegion(this.context.modal({
                forceClose: true,
                title: 'Confirm',
                buttons: [
                    'Yes',
                    'No'
                ]})
            ).present({ template: '
Are you sure you want to...?
' })
                .then(function (context) {
                    context.modalResult.then(function (result) {
                        alert(format('Result: %1', result.button));
                    });
                });
        },
        showModalReturningInput: function () {
            ViewRegion(this.context.modal({
                title: 'Input',
                buttons: [
                    { text: 'Ok', css: 'btn-sm btn-primary' },
                    'Cancel'
                ]})
            ).present({
                templateUrl: 'app/modals/modalReturningInput.html',
                controller:  'ModalReturningInputController as vm' })
                .then(function (context) {
                    context.modalResult.then(function (result) {
                        if (result && result.button != 'Cancel') {
                            var controller = context.resolve(sampleApp.ModalReturningInputController);
                            alert(format('Hello, %1!', controller.name));
                        }
                    });
                });
        },
        showModalUsingMasterDetail: function () {
            ViewRegion(this.context.modal({
                title: 'Person'
            })).present({
                templateUrl: 'app/modals/modalUsingMasterDetail.html',
                controller:  'ModalUsingMasterDetailController as vm'
            });
        }
	});

	eval(this.exports);

}
<commit_msg>updating modal example to a better more prefered way to get the controller<commit_after>new function () {

	base2.package(this, {
		name:    'sampleApp',
		imports: 'miruken.mvc,sampleApp.domain',
		exports: 'ModalsController'
	});

	eval(this.imports);

	var ModalsController = Controller.extend(MasterDetail, {
        getSelectedDetail: function(target){
            if (target === Person) {
                return new Person({
                    firstName: 'Dalinar',
                    lastName:  'Kholin'
                });
            }
        },
		showWrappedModal: function () {
            ViewRegion(this.context.modal({
            	title: 'Hooray!',
        		footer: true })
            ).present({
                templateUrl: 'app/modals/wrappedModal.html',
                controller:  'WrappedModalController as vm'
            });
		},
		showWrappedModalWithHeader: function () {
            ViewRegion(this.context.modal({
                title: 'Just a Header',
        		header: true })
            ).present({
                templateUrl: 'app/modals/wrappedModal.html',
                controller:  'WrappedModalController as vm'
            });
		},
		showWrappedModalWithFooter: function () {
            ViewRegion(this.context.modal({ footer: true }))
                .present({
                    templateUrl: 'app/modals/wrappedModal.html',
                    controller:  'WrappedModalController as vm'
                });
		},
		showFullModal: function () {
            ViewRegion(this.context.modal({ chrome: false }))
            	.present({
	                templateUrl: 'app/modals/fullModal.html',
	                controller:  'FullModalController as vm'
	            });
		},
		showSelfClosingModal: function () {
            ViewRegion(this.context.modal({ forceClose: true }))
            	.present({
	                templateUrl: 'app/modals/selfClosingModal.html',
	                controller:  'SelfClosingModalController as vm'
	            });
		},
        showModalWithButtons: function () {
            ViewRegion(this.context.modal({
                title: 'Buttons',
                buttons: [
                    { text: 'Primary', css: 'btn-primary btn-xs' },
                    { text: 'Default', css: 'btn-default btn-sm' },
                    { text: 'Success', css: 'btn-success' },
                    { text: 'Warning', css: 'btn-warning' },
                    { text: 'Danger',  css: 'btn-danger btn-lg' },
                ]})
            ).present({ template: '
Demo adding buttons with classes.
' })
                .then(function (context) {
                    context.modalResult.then(function (result) {
                        if (result)
                            alert(format('Button %1 - %2', result.buttonIndex, result.button.text));
                    });
                });
        },
        showConfirmModal: function () {
            ViewRegion(this.context.modal({
                forceClose: true,
                title: 'Confirm',
                buttons: [
                    'Yes',
                    'No'
                ]})
            ).present({ template: '
Are you sure you want to...?
' })
                .then(function (context) {
                    context.modalResult.then(function (result) {
                        alert(format('Result: %1', result.button));
                    });
                });
        },
        showModalReturningInput: function () {
            ViewRegion(this.context.modal({
                title: 'Input',
                buttons: [
                    { text: 'Ok', css: 'btn-sm btn-primary' },
                    'Cancel'
                ]})
            ).present({
                templateUrl: 'app/modals/modalReturningInput.html',
                controller:  'ModalReturningInputController as vm' })
                .then(function (context) {
                    context.modalResult.then(function (result) {
                        if (result && result.button != 'Cancel') {
                            var controller = ViewRegion(context).controller;
                            alert(format('Hello, %1!', controller.name));
                        }
                    });
                });
        },
        showModalUsingMasterDetail: function () {
            ViewRegion(this.context.modal({
                title: 'Person'
            })).present({
                templateUrl: 'app/modals/modalUsingMasterDetail.html',
                controller:  'ModalUsingMasterDetailController as vm'
            });
        }
	});

	eval(this.exports);

}
<|endoftext|>


<commit_before>/*
 * Configuration file for setting global variables
 *
 * @author: Dejan Dežman <dejan.dezman@cosylab.com>
 */

/**
 * Variables that can be and should be configured by user
 */

// Version number
var version = "0.4";

// For accessing the REST service
var serviceurl = window.location.protocol + "//localhost:8080/Olog/resources/";

// For all the dates shown in client
// Format docs can be found at http://momentjs.com/docs/#/displaying/format/
var dateFormat = "M/D/YY, h:mm a";

// jQuery datepicker plugin has its onw date format so it is defined separately.
// Format switches can be found at http://api.jqueryui.com/datepicker/
var datePickerDateFormat = "mm/dd/yy";

// jQuery timepicker plugin has its onw date format so it is defined separately.
// Format switches can be found at http://trentrichardson.com/examples/timepicker/
var datePickerTimeFormat = "hh:mm";

// Date from the datepicker is put in the search input but need to be parsed
// to build a REST service query. Format documentation can be found at
// http://momentjs.com/docs/#/parsing/
var datePickerDateFormatMometParseString = "MM/DD/YYYY hh:mm";

// Start of the week in the jQuery datepicker: 0: Sunday, 1: Monday, ...
var datePickerFirstName = 1;

// How many logs do you want to load per request?
var numberOfLogsPerLoad = 20;

// Set the name of the cookie that holds selected filters
var filtersCookieName = "filters";

// Set the name of the cookie that holds the user data
var sessionCookieName = "SESSION";

// Write logs to console
var writeLogs = true;

// First page name
var firstPageName = "index.html";

// Search key map. Function will extract value from search input, try to find
// keyMap keys in it and it will generate search query by replacing keyMap keys
// with keyMap values.
var keyMap = {
	'tag:': 'tag=',
	'logbook:': 'logbook=',
	'from:': 'start=',
	'start:': 'start=',
	'end:': 'end=',
	'to:': 'end=',
	'search:': 'search='
};

// Convert time filters to seconds. Forulas are evaluated and added or substracted from
// current time.
var timeFilter = {
	'min': '60',
	'mins': '60',
	'hour': '60*60',
	'hours': '60*60',
	'day': '24*60*60',
	'days': '24*60*60',
	'week': '7*24*60*60',
	'weeks': '7*24*60*60'
};

// Create From filter definition array. Other values can be added in this array to
// extend the functionality.
// @param name name of the filter which will be visibla by the user
// @param value value of the filter that can be parsed with the regular expression
var createdFromFilterDefinition = [
	{name:"Last min", value:"last 1 min"},
	{name:"Last hour", value:"last 1 hour"},
	{name:"Last day", value:"last 1 day"},
	{name:"Last week", value:"last 1 week"}
];

// Available sizes for Log attachments. These sites will be displayed in the
// Image size dropdown list.
// list:
// @param name is the name of the size that will be displayed as a list item
// @param scale is a scale, attachment will be resized to
// @param correction is a parameter that can be set to correct image sizes so they
// fit in the right pane in all browsers
// selected:
// represents the default selected size
// current:
// represents the current selected size
var imageSizes = {
	list:[
		{name:'small', scale:'0.25', correction:'15'},
		{name:'medium', scale:'0.5', correction:'25'},
		{name:'large', scale:'1', correction:'0'}
	],
	defaultSize:1,
	current:-1
};

// Map size names to list item array position
var backwardImageSizesMap = {
	small:0,
	medium:1,
	large:2
};

// Update interval in seconds. After this time has elapsed system will check if
// new Log entries were created. If updateInterval is set to -1, checking will
// be disabled.
var updateInterval = 60;

// Settings cookie name
var settingsCookieName = "olog";

// Maximum width of small resolution. If Olog will be displayed in smaller
// width, panes will be stacked one upon each other and filters will be closed.
// If this constant is changes, constant should also be changed in style.css
// file.
var smallScreenResolutionWidth = 1024;

// Available Levels
var levels = ["Info", "Problem", "Request", "Suggestion", "Urgent"];

/**
 * Global variables needed by more than one page. SHOULD NOT BE CONFIGURED BY THE USER!
 */

// Current Log search url
var searchURL = "";

// Current Log displayed
var selectedLog = "";

// Html file that contain modal windows
var modalWindows = "static/html/modal_windows.html";

// Html file that contain templates
var templates = "static/html/templates.html";

// Selected filter elements are saved into an object
var selectedElements = {};

// Olog settings that are saved in Olog settings cookie
var ologSettings = {};

// Should history be included by default
var includeHistory = true;

// URL parameter for displaying log's history
var historyParameter = "history";

// URL parameter for displaying particular version of log entry
var versionParameter = "version";

// Default version order
var logVersionOrder = true;<commit_msg>Restored configuration to compute server url for remote client<commit_after>/*
 * Configuration file for setting global variables
 *
 * @author: Dejan Dežman <dejan.dezman@cosylab.com>
 */

/**
 * Variables that can be and should be configured by user
 */

// Version number
var version = "0.4";

// For accessing the REST service
var serviceurl = window.location.protocol + "//" + window.location.host + "/Olog/resources/";

// For all the dates shown in client
// Format docs can be found at http://momentjs.com/docs/#/displaying/format/
var dateFormat = "M/D/YY, h:mm a";

// jQuery datepicker plugin has its onw date format so it is defined separately.
// Format switches can be found at http://api.jqueryui.com/datepicker/
var datePickerDateFormat = "mm/dd/yy";

// jQuery timepicker plugin has its onw date format so it is defined separately.
// Format switches can be found at http://trentrichardson.com/examples/timepicker/
var datePickerTimeFormat = "hh:mm";

// Date from the datepicker is put in the search input but need to be parsed
// to build a REST service query. Format documentation can be found at
// http://momentjs.com/docs/#/parsing/
var datePickerDateFormatMometParseString = "MM/DD/YYYY hh:mm";

// Start of the week in the jQuery datepicker: 0: Sunday, 1: Monday, ...
var datePickerFirstName = 1;

// How many logs do you want to load per request?
var numberOfLogsPerLoad = 20;

// Set the name of the cookie that holds selected filters
var filtersCookieName = "filters";

// Set the name of the cookie that holds the user data
var sessionCookieName = "SESSION";

// Write logs to console
var writeLogs = true;

// First page name
var firstPageName = "index.html";

// Search key map. Function will extract value from search input, try to find
// keyMap keys in it and it will generate search query by replacing keyMap keys
// with keyMap values.
var keyMap = {
	'tag:': 'tag=',
	'logbook:': 'logbook=',
	'from:': 'start=',
	'start:': 'start=',
	'end:': 'end=',
	'to:': 'end=',
	'search:': 'search='
};

// Convert time filters to seconds. Forulas are evaluated and added or substracted from
// current time.
var timeFilter = {
	'min': '60',
	'mins': '60',
	'hour': '60*60',
	'hours': '60*60',
	'day': '24*60*60',
	'days': '24*60*60',
	'week': '7*24*60*60',
	'weeks': '7*24*60*60'
};

// Create From filter definition array. Other values can be added in this array to
// extend the functionality.
// @param name name of the filter which will be visibla by the user
// @param value value of the filter that can be parsed with the regular expression
var createdFromFilterDefinition = [
	{name:"Last min", value:"last 1 min"},
	{name:"Last hour", value:"last 1 hour"},
	{name:"Last day", value:"last 1 day"},
	{name:"Last week", value:"last 1 week"}
];

// Available sizes for Log attachments. These sites will be displayed in the
// Image size dropdown list.
// list:
// @param name is the name of the size that will be displayed as a list item
// @param scale is a scale, attachment will be resized to
// @param correction is a parameter that can be set to correct image sizes so they
// fit in the right pane in all browsers
// selected:
// represents the default selected size
// current:
// represents the current selected size
var imageSizes = {
	list:[
		{name:'small', scale:'0.25', correction:'15'},
		{name:'medium', scale:'0.5', correction:'25'},
		{name:'large', scale:'1', correction:'0'}
	],
	defaultSize:1,
	current:-1
};

// Map size names to list item array position
var backwardImageSizesMap = {
	small:0,
	medium:1,
	large:2
};

// Update interval in seconds. After this time has elapsed system will check if
// new Log entries were created. If updateInterval is set to -1, checking will
// be disabled.
var updateInterval = 60;

// Settings cookie name
var settingsCookieName = "olog";

// Maximum width of small resolution. If Olog will be displayed in smaller
// width, panes will be stacked one upon each other and filters will be closed.
// If this constant is changes, constant should also be changed in style.css
// file.
var smallScreenResolutionWidth = 1024;

// Available Levels
var levels = ["Info", "Problem", "Request", "Suggestion", "Urgent"];

/**
 * Global variables needed by more than one page. SHOULD NOT BE CONFIGURED BY THE USER!
 */

// Current Log search url
var searchURL = "";

// Current Log displayed
var selectedLog = "";

// Html file that contain modal windows
var modalWindows = "static/html/modal_windows.html";

// Html file that contain templates
var templates = "static/html/templates.html";

// Selected filter elements are saved into an object
var selectedElements = {};

// Olog settings that are saved in Olog settings cookie
var ologSettings = {};

// Should history be included by default
var includeHistory = true;

// URL parameter for displaying log's history
var historyParameter = "history";

// URL parameter for displaying particular version of log entry
var versionParameter = "version";

// Default version order
var logVersionOrder = true;
<|endoftext|>


<commit_before>/**
 * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config ) {
	// Define changes to default configuration here. For example:
	// config.language = 'fr';
	// config.uiColor = '#AADC6E';

	config.removePlugins 				=	"newpage,save,templates,about,liststyle,tabletools,scayt,menubutton,contextmenu"; //remove some icons

    config.filebrowserUploadUrl 		=  	"/OpenNote/modules/core/upload.php";
	config.filebrowserImageUploadUrl 	=  	"/OpenNote/modules/core/upload.php";

	config.extraPlugins					=	"imagepaste";
	config.height 						= 	"500px";
	config.disableNativeSpellChecker 	= 	false;

};
<commit_msg>Update config.js<commit_after>/**
 * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config ) {
	// Define changes to default configuration here. For example:
	// config.language = 'fr';
	// config.uiColor = '#AADC6E';

	config.removePlugins 				=	"newpage,save,templates,about,liststyle,tabletools,scayt,menubutton,contextmenu"; //remove some icons

    config.filebrowserUploadUrl 		=  	"/OpenNote/modules/core/upload.php";
	config.filebrowserImageUploadUrl 	=  	"/OpenNote/modules/core/upload.php";

	config.height 						= 	"500px";
	config.disableNativeSpellChecker 	= 	false;

};
<|endoftext|>


<commit_before>import Asana from 'asana';

let authCreds = {};
const access_token = localStorage.getItem('access_token') || false;

if (access_token) {
  authCreds = {
    credentials: access_token
  }
}

export default Asana.Client.create({
  clientId: process.env.CLIENT_ID,
  redirectUri: document.location['href']
}).useOauth(authCreds);
<commit_msg>Removed url from asana client creation<commit_after>import Asana from 'asana';

let authCreds = {};
const access_token = localStorage.getItem('access_token') || false;

if (access_token) {
  authCreds = {
    credentials: access_token
  }
}

export default Asana.Client.create({
  clientId: process.env.CLIENT_ID
}).useOauth(authCreds);
<|endoftext|>


<commit_before>{
  "bogus": {
    "type": "bogus",
    "label": "bogus"
  },
  "button": {
    "type": "button",
    "label": "button"
  },
  "checkbox": {
    "type": "checkbox",
    "label": "checkbox"
  },
  "checklist": {
    "type": "checklist",
    "label": "checklist",
    "options": {
      "first": {
        "label": "first option"
      },
      "second": {
        "label": "second option",
        "isOn": "on",
        "isOff": "off"
      }
    }
  },
  "color": {
    "type": "color",
    "label": "color"
  },
  "date": {
    "type": "date",
    "label": "date",
    "placeholder": "date"
  },
  "datetime": {
    "type": "datetime",
    "label": "datetime",
    "placeholder": "datetime"
  },
  "datetime-local": {
    "type": "datetime-local",
    "label": "datetime-local",
    "placeholder": "datetime-local"
  },
  "email": {
    "type": "email",
    "label": "email",
    "placeholder": "email"
  },
  "file": {
    "type": "file",
    "label": "file",
    "multiple": true
  },
  "fieldset": {
    "type": "fieldset",
    "label": "fieldset",
    "fields": {
      "hidden": {
        "type": "hidden",
        "label": "hidden",
        "val": "hidden"
      },
      "image": {
        "type": "image",
        "label": "image",
        "source": "http://angularjs.org/img/AngularJS-large.png"
      },
      "legend": {
        "type": "legend",
        "label": "legend"
      },
      "month": {
        "type": "month",
        "label": "month",
        "placeholder": "month"
      },
      "number": {
        "type": "number",
        "label": "number",
        "placeholder": "number"
      },
      "password": {
        "type": "password",
        "label": "password",
        "placeholder": "password"
      },
      "radio": {
        "type": "radio",
        "label": "radio",
        "values": {
          "first": "first option",
          "second": "second option",
          "third": "third option",
          "fourth": "fourth option",
          "fifth": "fifth option"
        }
      },
      "range": {
        "type": "range",
        "label": "range",
        "model": "number",
        "val": 42,
        "minValue": -42,
        "maxValue": 84
      }
    }
  },
  "reset": {
    "type": "reset",
    "label": "reset"
  },
  "search": {
    "type": "search",
    "label": "search",
    "placeholder": "search"
  },
  "select": {
    "type": "select",
    "label": "select",
    "empty": "nothing selected",
    "options": {
      "first": {
        "label": "first option"
      },
      "second": {
        "label": "second option",
        "group": "first group"
      },
      "third": {
        "label": "third option",
        "group": "second group"
      },
      "fourth": {
        "label": "fourth option",
        "group": "first group"
      },
      "fifth": {
        "label": "fifth option"
      },
      "sixth": {
        "label": "sixth option",
        "group": "second group"
      },
      "seventh": {
        "label": "seventh option"
      },
      "eighth": {
        "label": "eighth option",
        "group": "first group"
      },
      "ninth": {
        "label": "ninth option",
        "group": "second group"
      },
      "tenth": {
        "label": "tenth option"
      }
    }
  },
  "submit": {
    "type": "submit",
    "label": "submit"
  },
  "tel": {
    "type": "tel",
    "label": "tel",
    "placeholder": "tel"
  },
  "text": {
    "type": "text",
    "label": "text",
    "placeholder": "text"
  },
  "textarea": {
    "type": "textarea",
    "label": "textarea",
    "placeholder": "textarea",
    "splitBy": "\n",
    "val": ["This array should be","separated by new lines"]
  },
  "time": {
    "type": "time",
    "label": "time",
    "placeholder": "time"
  },
  "url": {
    "type": "url",
    "label": "url",
    "placeholder": "url"
  },
  "week": {
    "type": "week",
    "label": "week",
    "placeholder": "week"
  }
}<commit_msg>Updated demo to showcase using an array-based template via `model`<commit_after>[
  {
    "type": "bogus",
    "model": "bogus",
    "label": "bogus"
  },
  {
    "type": "button",
    "model": "button",
    "label": "button"
  },
  {
    "type": "checkbox",
    "model": "checkbox",
    "label": "checkbox"
  },
  {
    "type": "checklist",
    "model": "checklist",
    "label": "checklist",
    "options": {
      "first": {
        "label": "first option"
      },
      "second": {
        "label": "second option",
        "isOn": "on",
        "isOff": "off"
      }
    }
  },
  {
    "type": "color",
    "model": "color",
    "label": "color"
  },
  {
    "type": "date",
    "model": "date",
    "label": "date",
    "placeholder": "date"
  },
  {
    "type": "datetime",
    "model": "datetime",
    "label": "datetime",
    "placeholder": "datetime"
  },
  {
    "type": "datetime-local",
    "model": "datetime-local",
    "label": "datetime-local",
    "placeholder": "datetime-local"
  },
  {
    "type": "email",
    "model": "email",
    "label": "email",
    "placeholder": "email"
  },
  {
    "type": "file",
    "model": "file",
    "label": "file",
    "multiple": true
  },
  {
    "type": "fieldset",
    "model": "fieldset",
    "label": "fieldset",
    "fields": [
      {
        "type": "hidden",
        "model": "hidden",
        "label": "hidden",
        "val": "hidden"
      },
      {
        "type": "image",
        "model": "image",
        "label": "image",
        "source": "http://angularjs.org/img/AngularJS-large.png"
      },
      {
        "type": "legend",
        "model": "legend",
        "label": "legend"
      },
      {
        "type": "month",
        "model": "month",
        "label": "month",
        "placeholder": "month"
      },
      {
        "type": "number",
        "model": "number",
        "label": "number",
        "placeholder": "number"
      },
      {
        "type": "password",
        "model": "password",
        "label": "password",
        "placeholder": "password"
      },
      {
        "type": "radio",
        "model": "radio",
        "label": "radio",
        "values": {
          "first": "first option",
          "second": "second option",
          "third": "third option",
          "fourth": "fourth option",
          "fifth": "fifth option"
        }
      },
      {
        "type": "range",
        "model": "number",
        "label": "range",
        "val": 42,
        "minValue": -42,
        "maxValue": 84
      }
    ]
  },
  {
    "type": "reset",
    "model": "reset",
    "label": "reset"
  },
  {
    "type": "search",
    "model": "search",
    "label": "search",
    "placeholder": "search"
  },
  {
    "type": "select",
    "model": "select",
    "label": "select",
    "empty": "nothing selected",
    "options": {
      "first": {
        "label": "first option"
      },
      "second": {
        "label": "second option",
        "group": "first group"
      },
      "third": {
        "label": "third option",
        "group": "second group"
      },
      "fourth": {
        "label": "fourth option",
        "group": "first group"
      },
      "fifth": {
        "label": "fifth option"
      },
      "sixth": {
        "label": "sixth option",
        "group": "second group"
      },
      "seventh": {
        "label": "seventh option"
      },
      "eighth": {
        "label": "eighth option",
        "group": "first group"
      },
      "ninth": {
        "label": "ninth option",
        "group": "second group"
      },
      "tenth": {
        "label": "tenth option"
      }
    }
  },
  {
    "type": "submit",
    "model": "submit",
    "label": "submit"
  },
  {
    "type": "tel",
    "model": "tel",
    "label": "tel",
    "placeholder": "tel"
  },
  {
    "type": "text",
    "model": "text",
    "label": "text",
    "placeholder": "text"
  },
  {
    "type": "textarea",
    "model": "textarea",
    "label": "textarea",
    "placeholder": "textarea",
    "splitBy": "\n",
    "val": ["This array should be","separated by new lines"]
  },
  {
    "type": "time",
    "model": "time",
    "label": "time",
    "placeholder": "time"
  },
  {
    "type": "url",
    "model": "url",
    "label": "url",
    "placeholder": "url"
  },
  {
    "type": "week",
    "model": "week",
    "label": "week",
    "placeholder": "week"
  }
]<|endoftext|>


<commit_before>"use strict";

var PouchDB = require('pouchdb');

var db = new PouchDB('http://localhost:5984/map-reduce');

exports.getAllBooks = function getAllBooks() {

};

exports.getAllBookTitles = function getAllBookTitles() {

};

exports.getExpensiveBooks = function getExpensiveBooks() {

};

exports.getPriceForOneOfEverything = function getPriceForOneOfEverything() {

};
<commit_msg>implement getAllBooks<commit_after>"use strict";

var PouchDB = require('pouchdb');

var db = new PouchDB('http://localhost:5984/map-reduce');

exports.getAllBooks = function getAllBooks() {
  return db.query(function (doc) {
    emit(doc._id, doc);
  });
};

exports.getAllBookTitles = function getAllBookTitles() {

};

exports.getExpensiveBooks = function getExpensiveBooks() {

};

exports.getPriceForOneOfEverything = function getPriceForOneOfEverything() {

};
<|endoftext|>


<commit_before>"use strict";

angular.module('fileUpload', [ 'angularFileUpload' ]);

var uploadUrl = 'http://angular-file-upload-cors-srv.appspot.com/upload';
window.uploadUrl = window.uploadUrl || 'upload';

var MyCtrl = [ '$scope', '$http', '$timeout', '$upload', function($scope, $http, $timeout, $upload) {
	$scope.usingFlash = FileAPI && FileAPI.upload != null;
	$scope.fileReaderSupported = window.FileReader != null && (window.FileAPI == null || FileAPI.html5 != false);
	$scope.uploadRightAway = true;
	$scope.changeAngularVersion = function() {
		window.location.hash = $scope.angularVersion;
		window.location.reload(true);
	};
	$scope.hasUploader = function(index) {
		return $scope.upload[index] != null;
	};
	$scope.abort = function(index) {
		$scope.upload[index].abort();
		$scope.upload[index] = null;
	};
	$scope.angularVersion = window.location.hash.length > 1 ? (window.location.hash.indexOf('/') === 1 ?
			window.location.hash.substring(2): window.location.hash.substring(1)) : '1.2.20';
	$scope.onFileSelect = function($files) {
		$scope.selectedFiles = [];
		$scope.progress = [];
		if ($scope.upload && $scope.upload.length > 0) {
			for (var i = 0; i < $scope.upload.length; i++) {
				if ($scope.upload[i] != null) {
					$scope.upload[i].abort();
				}
			}
		}
		$scope.upload = [];
		$scope.uploadResult = [];
		$scope.selectedFiles = $files;
		$scope.dataUrls = [];
		for ( var i = 0; i < $files.length; i++) {
			var $file = $files[i];
			if ($scope.fileReaderSupported && $file.type.indexOf('image') > -1) {
				var fileReader = new FileReader();
				fileReader.readAsDataURL($files[i]);
				var loadFile = function(fileReader, index) {
					fileReader.onload = function(e) {
						$timeout(function() {
							$scope.dataUrls[index] = e.target.result;
						});
					}
				}(fileReader, i);
			}
			$scope.progress[i] = -1;
			if ($scope.uploadRightAway) {
				$scope.start(i);
			}
		}
	};

	$scope.start = function(index) {
		$scope.progress[index] = 0;
		$scope.errorMsg = null;
		if ($scope.howToSend == 1) {
			//$upload.upload()
			$scope.upload[index] = $upload.upload({
				url: uploadUrl,
				method: $scope.httpMethod,
				headers: {'my-header': 'my-header-value'},
				data : {
					myModel : $scope.myModel,
					errorCode: $scope.generateErrorOnServer && $scope.serverErrorCode,
					errorMessage: $scope.generateErrorOnServer && $scope.serverErrorMsg
				},
				/* formDataAppender: function(fd, key, val) {
					if (angular.isArray(val)) {
                        angular.forEach(val, function(v) {
                          fd.append(key, v);
                        });
                      } else {
                        fd.append(key, val);
                      }
				}, */
				/* transformRequest: [function(val, h) {
					console.log(val, h('my-header')); return val + '-modified';
				}], */
				file: $scope.selectedFiles[index],
				fileFormDataName: 'myFile'
			});
			$scope.upload[index].then(function(response) {
				$timeout(function() {
					$scope.uploadResult.push(response.data);
				});
			}, function(response) {
				if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
			}, function(evt) {
				// Math.min is to fix IE which reports 200% sometimes
				$scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
			});
			$scope.upload[index].xhr(function(xhr){
//				xhr.upload.addEventListener('abort', function() {console.log('abort complete')}, false);
			});
		} else if ($scope.howToSend == 2) {
			//$upload.http()
			var fileReader = new FileReader();
            fileReader.onload = function(e) {
            	console.log('file is loaded in filereader');
		        $scope.upload[index] = $upload.http({
		        	url: uploadUrl,
					headers: {'Content-Type': $scope.selectedFiles[index].type},
					data: e.target.result
		        });
		        $scope.upload[index].then(function(response) {
					$scope.uploadResult.push(response.data);
				}, function(response) {
					if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
				}, function(evt) {
					// Math.min is to fix IE which reports 200% sometimes
					$scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
					console.log('progres', Math.min(100, parseInt(100.0 * evt.loaded / evt.total)))
				});
				$scope.upload[index].xhr(function(xhr){
					xhr.upload.addEventListener('progress', function(evt) {
						console.log('progres2', Math.min(100, parseInt(100.0 * evt.loaded / evt.total)))
					}, false);
					xhr.addEventListener('progress', function(evt) {
						console.log('progres3', Math.min(100, parseInt(100.0 * evt.loaded / evt.total)))
					}, false);
				});
            }
	        fileReader.readAsArrayBuffer($scope.selectedFiles[index]);
		} else {
			//s3 upload
			$scope.upload[index] = $upload.upload({
				url: $scope.s3url,
				method: 'POST',
				data : {
					key: $scope.selectedFiles[index].name,
					AWSAccessKeyId: $scope.AWSAccessKeyId,
					acl: $scope.acl,
					policy: $scope.policy,
					signature: $scope.signature,
					"Content-Type": $scope.selectedFiles[index].type === null || $scope.selectedFiles[index].type === '' ?
										'application/octet-stream' : $scope.selectedFiles[index].type,
					filename: $scope.selectedFiles[index].name
				},
				file: $scope.selectedFiles[index],
			});
			$scope.upload[index].then(function(response) {
				$timeout(function() {
					$scope.uploadResult.push(response.data);
				});
			}, function(response) {
				if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
			}, function(evt) {
				// Math.min is to fix IE which reports 200% sometimes
				$scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
			});
			if (localStorage) {
				localStorage.setItem("s3url", $scope.s3url);
				localStorage.setItem("AWSAccessKeyId", $scope.AWSAccessKeyId);
				localStorage.setItem("acl", $scope.acl);
				localStorage.setItem("success_action_redirect", $scope.success_action_redirect);
				localStorage.setItem("policy", $scope.policy);
				localStorage.setItem("signature", $scope.signature);
			}
		}
	};

	$scope.dragOverClass = function($event) {
		var items = $event.dataTransfer.items;
		var hasFile = false;
		if (items != null) {
			for (var i = 0 ; i < items.length; i++) {
				if (items[i].kind == 'file') {
					hasFile = true;
					break;
				}
			}
		} else {
			hasFile = true;
		}
		return hasFile ? "dragover" : "dragover-err";
	};

	$scope.generateSignature = function() {
		$http.post('/s3sign?aws-secret-key=' + encodeURIComponent($scope.AWSSecretKey), $scope.jsonPolicy).
			success(function(data) {
				$scope.policy = data.policy;
				$scope.signature = data.signature;
			});
	}
	if (localStorage) {
		$scope.s3url = localStorage.getItem("s3url");
		$scope.AWSAccessKeyId = localStorage.getItem("AWSAccessKeyId");
		$scope.acl = localStorage.getItem("acl");
		$scope.success_action_redirect = localStorage.getItem("success_action_redirect");
		$scope.policy = localStorage.getItem("policy");
		$scope.signature = localStorage.getItem("signature");
	}
	$scope.success_action_redirect = $scope.success_action_redirect || window.location.protocol + "//" + window.location.host;
	$scope.jsonPolicy = $scope.jsonPolicy || '{\n  "expiration": "2020-01-01T00:00:00Z",\n  "conditions": [\n    {"bucket": "angular-file-upload"},\n    ["starts-with", "$key", ""],\n    {"acl": "private"},\n    ["starts-with", "$Content-Type", ""],\n    ["starts-with", "$filename", ""],\n    ["content-length-range", 0, 524288000]\n  ]\n}';
	$scope.acl = $scope.acl || 'private';
} ];
<commit_msg>Update upload.js<commit_after>"use strict";

angular.module('fileUpload', [ 'angularFileUpload' ]);

var uploadUrl = (window.location.protocol || 'http:') + '//angular-file-upload-cors-srv.appspot.com/upload';
window.uploadUrl = window.uploadUrl || 'upload';

var MyCtrl = [ '$scope', '$http', '$timeout', '$upload', function($scope, $http, $timeout, $upload) {
	$scope.usingFlash = FileAPI && FileAPI.upload != null;
	$scope.fileReaderSupported = window.FileReader != null && (window.FileAPI == null || FileAPI.html5 != false);
	$scope.uploadRightAway = true;
	$scope.changeAngularVersion = function() {
		window.location.hash = $scope.angularVersion;
		window.location.reload(true);
	};
	$scope.hasUploader = function(index) {
		return $scope.upload[index] != null;
	};
	$scope.abort = function(index) {
		$scope.upload[index].abort();
		$scope.upload[index] = null;
	};
	$scope.angularVersion = window.location.hash.length > 1 ? (window.location.hash.indexOf('/') === 1 ?
			window.location.hash.substring(2): window.location.hash.substring(1)) : '1.2.20';
	$scope.onFileSelect = function($files) {
		$scope.selectedFiles = [];
		$scope.progress = [];
		if ($scope.upload && $scope.upload.length > 0) {
			for (var i = 0; i < $scope.upload.length; i++) {
				if ($scope.upload[i] != null) {
					$scope.upload[i].abort();
				}
			}
		}
		$scope.upload = [];
		$scope.uploadResult = [];
		$scope.selectedFiles = $files;
		$scope.dataUrls = [];
		for ( var i = 0; i < $files.length; i++) {
			var $file = $files[i];
			if ($scope.fileReaderSupported && $file.type.indexOf('image') > -1) {
				var fileReader = new FileReader();
				fileReader.readAsDataURL($files[i]);
				var loadFile = function(fileReader, index) {
					fileReader.onload = function(e) {
						$timeout(function() {
							$scope.dataUrls[index] = e.target.result;
						});
					}
				}(fileReader, i);
			}
			$scope.progress[i] = -1;
			if ($scope.uploadRightAway) {
				$scope.start(i);
			}
		}
	};

	$scope.start = function(index) {
		$scope.progress[index] = 0;
		$scope.errorMsg = null;
		if ($scope.howToSend == 1) {
			//$upload.upload()
			$scope.upload[index] = $upload.upload({
				url: uploadUrl,
				method: $scope.httpMethod,
				headers: {'my-header': 'my-header-value'},
				data : {
					myModel : $scope.myModel,
					errorCode: $scope.generateErrorOnServer && $scope.serverErrorCode,
					errorMessage: $scope.generateErrorOnServer && $scope.serverErrorMsg
				},
				/* formDataAppender: function(fd, key, val) {
					if (angular.isArray(val)) {
                        angular.forEach(val, function(v) {
                          fd.append(key, v);
                        });
                      } else {
                        fd.append(key, val);
                      }
				}, */
				/* transformRequest: [function(val, h) {
					console.log(val, h('my-header')); return val + '-modified';
				}], */
				file: $scope.selectedFiles[index],
				fileFormDataName: 'myFile'
			});
			$scope.upload[index].then(function(response) {
				$timeout(function() {
					$scope.uploadResult.push(response.data);
				});
			}, function(response) {
				if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
			}, function(evt) {
				// Math.min is to fix IE which reports 200% sometimes
				$scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
			});
			$scope.upload[index].xhr(function(xhr){
//				xhr.upload.addEventListener('abort', function() {console.log('abort complete')}, false);
			});
		} else if ($scope.howToSend == 2) {
			//$upload.http()
			var fileReader = new FileReader();
            fileReader.onload = function(e) {
            	console.log('file is loaded in filereader');
		        $scope.upload[index] = $upload.http({
		        	url: uploadUrl,
					headers: {'Content-Type': $scope.selectedFiles[index].type},
					data: e.target.result
		        });
		        $scope.upload[index].then(function(response) {
					$scope.uploadResult.push(response.data);
				}, function(response) {
					if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
				}, function(evt) {
					// Math.min is to fix IE which reports 200% sometimes
					$scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
					console.log('progres', Math.min(100, parseInt(100.0 * evt.loaded / evt.total)))
				});
				$scope.upload[index].xhr(function(xhr){
					xhr.upload.addEventListener('progress', function(evt) {
						console.log('progres2', Math.min(100, parseInt(100.0 * evt.loaded / evt.total)))
					}, false);
					xhr.addEventListener('progress', function(evt) {
						console.log('progres3', Math.min(100, parseInt(100.0 * evt.loaded / evt.total)))
					}, false);
				});
            }
	        fileReader.readAsArrayBuffer($scope.selectedFiles[index]);
		} else {
			//s3 upload
			$scope.upload[index] = $upload.upload({
				url: $scope.s3url,
				method: 'POST',
				data : {
					key: $scope.selectedFiles[index].name,
					AWSAccessKeyId: $scope.AWSAccessKeyId,
					acl: $scope.acl,
					policy: $scope.policy,
					signature: $scope.signature,
					"Content-Type": $scope.selectedFiles[index].type === null || $scope.selectedFiles[index].type === '' ?
										'application/octet-stream' : $scope.selectedFiles[index].type,
					filename: $scope.selectedFiles[index].name
				},
				file: $scope.selectedFiles[index],
			});
			$scope.upload[index].then(function(response) {
				$timeout(function() {
					$scope.uploadResult.push(response.data);
				});
			}, function(response) {
				if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
			}, function(evt) {
				// Math.min is to fix IE which reports 200% sometimes
				$scope.progress[index] = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
			});
			if (localStorage) {
				localStorage.setItem("s3url", $scope.s3url);
				localStorage.setItem("AWSAccessKeyId", $scope.AWSAccessKeyId);
				localStorage.setItem("acl", $scope.acl);
				localStorage.setItem("success_action_redirect", $scope.success_action_redirect);
				localStorage.setItem("policy", $scope.policy);
				localStorage.setItem("signature", $scope.signature);
			}
		}
	};

	$scope.dragOverClass = function($event) {
		var items = $event.dataTransfer.items;
		var hasFile = false;
		if (items != null) {
			for (var i = 0 ; i < items.length; i++) {
				if (items[i].kind == 'file') {
					hasFile = true;
					break;
				}
			}
		} else {
			hasFile = true;
		}
		return hasFile ? "dragover" : "dragover-err";
	};

	$scope.generateSignature = function() {
		$http.post('/s3sign?aws-secret-key=' + encodeURIComponent($scope.AWSSecretKey), $scope.jsonPolicy).
			success(function(data) {
				$scope.policy = data.policy;
				$scope.signature = data.signature;
			});
	}
	if (localStorage) {
		$scope.s3url = localStorage.getItem("s3url");
		$scope.AWSAccessKeyId = localStorage.getItem("AWSAccessKeyId");
		$scope.acl = localStorage.getItem("acl");
		$scope.success_action_redirect = localStorage.getItem("success_action_redirect");
		$scope.policy = localStorage.getItem("policy");
		$scope.signature = localStorage.getItem("signature");
	}
	$scope.success_action_redirect = $scope.success_action_redirect || window.location.protocol + "//" + window.location.host;
	$scope.jsonPolicy = $scope.jsonPolicy || '{\n  "expiration": "2020-01-01T00:00:00Z",\n  "conditions": [\n    {"bucket": "angular-file-upload"},\n    ["starts-with", "$key", ""],\n    {"acl": "private"},\n    ["starts-with", "$Content-Type", ""],\n    ["starts-with", "$filename", ""],\n    ["content-length-range", 0, 524288000]\n  ]\n}';
	$scope.acl = $scope.acl || 'private';
} ];
<|endoftext|>


<commit_before>'use strict';
//  Summary:
//    Get webpack config for different target

const path = require('path');
const _ = require('lodash');
const webpack = require('webpack');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');

const pkgJson = require('./package.json');

module.exports = (type) => { // eslint-disable-line
  // type is one of [dev, dll, test, dist]

  const isDev = type === 'dev';
  const isDist = type === 'dist';

  return {
    devtool: {
      dev: 'eval',
      dll: false,
      test: false,
      dist: false,
    }[type],
    cache: true,
    context: path.join(__dirname, 'src'),

    entry: {
      dev: {
        main: [
          'react-hot-loader/patch',
          `webpack-hot-middleware/client?http://0.0.0.0:${pkgJson.rekit.devPort}`,
          './styles/index.less',
          './index',
        ],
      },
      dll: {
        // Here dll is only used for dev.
        'dev-vendors': [
          'react-hot-loader',
          'react-proxy',
          'babel-polyfill',
          'lodash',
          'react',
          'react-dom',
          'react-router',
          'react-redux',
          'react-router-redux',
          'redux',
          'redux-logger',
          'redux-thunk',
        ],
      },
      dist: {
        main: [
          'babel-polyfill',
          './styles/index.less',
          './index'
        ],
      },
    }[type],

    output: {
      // Js bundle name, [name] will be replaced by which is in entry
      filename: '[name].bundle.js',

      // Where to save your build result
      path: path.join(__dirname, 'build/static'),

      // Exposed asset path
      publicPath: '/static'
    },

    plugins: _.compact([
      isDev && new webpack.HotModuleReplacementPlugin(),
      new webpack.NoErrorsPlugin(),
      isDist && new LodashModuleReplacementPlugin(),
      isDist && new webpack.optimize.DedupePlugin(),
      isDist && new webpack.optimize.UglifyJsPlugin(),
      isDist && new webpack.optimize.AggressiveMergingPlugin(),
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(type === 'dist' ? 'production' : type),
        }
      })
    ]),

    module: {
      rules: [
        {
          test: /\.jsx?$/,
          exclude: /node_modules|build/,
          loader: 'babel-loader?cacheDirectory=true'
        }, {
          test: /\.(ttf|eot|svg|woff)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          loader: 'file-loader'
        }, {
          test: /\.less$/,
          loader: isDev ? 'style-loader!css-loader?sourceMap!less-loader?sourceMap'
            : 'style-loader!css-loader!less-loader'
        }, {
          test: /\.css$/,
          loader: 'style-loader!css-loader'
        }, {
          test: /\.json$/,
          loader: 'json-loader'
        }, {
          test: /\.(png|jpe?g|gif)$/,
          loader: 'url-loader?limit=8192'
        }
      ]
    }
  };
};
<commit_msg>Fix publicPath.<commit_after>'use strict';
//  Summary:
//    Get webpack config for different target

const path = require('path');
const _ = require('lodash');
const webpack = require('webpack');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');

const pkgJson = require('./package.json');

module.exports = (type) => { // eslint-disable-line
  // type is one of [dev, dll, test, dist]

  const isDev = type === 'dev';
  const isDist = type === 'dist';

  return {
    devtool: {
      dev: 'eval',
      dll: false,
      test: false,
      dist: false,
    }[type],
    cache: true,
    context: path.join(__dirname, 'src'),

    entry: {
      dev: {
        main: [
          'react-hot-loader/patch',
          `webpack-hot-middleware/client?http://0.0.0.0:${pkgJson.rekit.devPort}`,
          './styles/index.less',
          './index',
        ],
      },
      dll: {
        // Here dll is only used for dev.
        'dev-vendors': [
          'react-hot-loader',
          'react-proxy',
          'babel-polyfill',
          'lodash',
          'react',
          'react-dom',
          'react-router',
          'react-redux',
          'react-router-redux',
          'redux',
          'redux-logger',
          'redux-thunk',
        ],
      },
      dist: {
        main: [
          'babel-polyfill',
          './styles/index.less',
          './index'
        ],
      },
    }[type],

    output: {
      // Js bundle name, [name] will be replaced by which is in entry
      filename: '[name].bundle.js',

      // Where to save your build result
      path: path.join(__dirname, 'build/static'),

      // Exposed asset path. NOTE: the end '/' is necessary
      publicPath: '/static/'
    },

    plugins: _.compact([
      isDev && new webpack.HotModuleReplacementPlugin(),
      new webpack.NoErrorsPlugin(),
      isDist && new LodashModuleReplacementPlugin(),
      isDist && new webpack.optimize.DedupePlugin(),
      isDist && new webpack.optimize.UglifyJsPlugin(),
      isDist && new webpack.optimize.AggressiveMergingPlugin(),
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(type === 'dist' ? 'production' : type),
        }
      })
    ]),

    module: {
      rules: [
        {
          test: /\.jsx?$/,
          exclude: /node_modules|build/,
          loader: 'babel-loader?cacheDirectory=true'
        }, {
          test: /\.(ttf|eot|svg|woff)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          loader: 'file-loader'
        }, {
          test: /\.less$/,
          loader: isDev ? 'style-loader!css-loader?sourceMap!less-loader?sourceMap'
            : 'style-loader!css-loader!less-loader'
        }, {
          test: /\.css$/,
          loader: 'style-loader!css-loader'
        }, {
          test: /\.json$/,
          loader: 'json-loader'
        }, {
          test: /\.(png|jpe?g|gif)$/,
          loader: 'url-loader?limit=8192'
        }
      ]
    }
  };
};
<|endoftext|>


<commit_before>const webpack = require('webpack');
const path = require('path');
const extractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');

const noErrorsPlugin = new webpack.NoEmitOnErrorsPlugin();
const extractCss = new extractTextPlugin({filename: '../css/[name].css', allChunks: true});

module.exports = [{
  name: 'browser',
  cache: true,
  entry: ['babel-polyfill', './src/client/index.js'],
  output: {
    path: path.join(__dirname, 'public/js'),
    filename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react'],
          plugins: ['transform-async-to-generator', 'transform-class-properties', 'transform-es2015-modules-commonjs', 'transform-object-rest-spread']
        }
      },
      {
        test: /\.(scss|css)$/,
        loader: extractTextPlugin.extract(['css-loader', 'postcss-loader', 'sass-loader']) /* Checkout postcss.config.js for details */
      }
    ]
  },
  plugins: [
    extractCss,
    noErrorsPlugin
  ],
  resolve: {
    alias: {
      'react': 'preact-compat',
      'react-dom': 'preact-compat',
      'react-enroute': 'preact-enroute'
    }
  }
}];
<commit_msg>Added sourcemaps<commit_after>const webpack = require('webpack');
const path = require('path');
const extractTextPlugin = require('extract-text-webpack-plugin');

const noErrorsPlugin = new webpack.NoEmitOnErrorsPlugin();
const extractCss = new extractTextPlugin({filename: '../css/[name].css', allChunks: true});

module.exports = [{
  name: 'browser',
  cache: true,
  entry: ['babel-polyfill', './src/client/index.js'],
  output: {
    path: path.join(__dirname, 'public/js'),
    filename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react'],
          plugins: ['transform-async-to-generator', 'transform-class-properties', 'transform-es2015-modules-commonjs', 'transform-object-rest-spread']
        }
      },
      {
        test: /\.(scss|css)$/,
        loader: extractTextPlugin.extract(['css-loader?importLoaders=1', 'postcss-loader?sourceMap=inline', 'sass-loader?sourceMap=true']) /* Checkout postcss.config.js for details */
      }
    ]
  },
  plugins: [
    extractCss,
    noErrorsPlugin
  ],
  resolve: {
    alias: {
      react: 'preact-compat',
      'react-dom': 'preact-compat',
      'react-enroute': 'preact-enroute'
    }
  }
}];
<|endoftext|>


<commit_before>var dnss = {
  skills: {},
  types: null,
  queue: [],
  messages: {},
  max_levels: null,
  max_sp: null,
  build: Array(72 + 1 + 1).join('-').split(''),
  positions: [],
  current: {},
  total_skills: $('.skill[data-id]').length,
  parsed_total: 0,
  jobs: [],

  init: function(jobIdentifiers, max_levels, max_sp, start_build) {
    this.jobs = jobIdentifiers;
    this.max_levels = max_levels;
    this.max_sp = max_sp;

    // sets the starting build
    if (start_build) {
      var m = start_build.match(/^[0-9a-zA-Z-]+/g);
      var build = m.shift();
      if (build && build.length > 72) {
        build = build.split('');
        for (var i = 0; i < build.length - 1; i++) {
          this.build[i] = build[i];
        }
        this.build[this.build.length - 1] = build[build.length - 1];
      }
    }

    // gives position to every container
    $('.container').each(function(i) {
      var element = $(this).find('.skill');
      if (element.length) {
        element.data('position', i);
      }
    });

    // types
    $.getJSON('/json/types.min.json', function(json) {
      dnss.types = json;
      while (dnss.queue.length) {
        dnss.add_skills(dnss.queue.shift());
      }
    });

    // get json
    for (var i in jobIdentifiers) {
      $.getJSON(fmt('/json/$0.min.json', jobIdentifiers[i]), function(json) {
        for (var j in json.messages) { // I don't trust async $.extends()
          dnss.messages[j] = json.messages[j];
        }

        if (dnss.types) {
          dnss.add_skills(json);
        } else {
          dnss.queue.push(json);
        }
      });
    }

    // mode bind
    $('#mode').bind('click', function() {
      switch($(this).val()) {
        case 'pve': $(this).val('pvp'); break;
        case 'pvp': $(this).val('pve'); break;
      }
     description.flip();
    });

    // job list bind
    $('#job-list-sp li[data-job]').each(function() {
      var idx = $(this).data('job');
      $(this).click(function() {
        $('#job-list-sp li[data-job][class="active"]').removeClass('active');
        $(this).addClass('active');
        $('.skill-tree').hide();
        $('#skill-tree-' + idx).show();
      })
    });
  },

  add_skills: function(job) {
    var skills = job.skills, default_skills = job.default_skills, adv = job.advancement;
    delete job.advancement;
    for (i in skills) {
      var skill = skills[i];
      var levels = skill.levels;
      delete skill.levels; // don't want this lingering

      var l = 0, is_default = false;
      if (default_skills) {
        for (var j = 0; j < default_skills.length; j++) {
          if (default_skills[j] == i) {
            is_default = true;
            break;
          }
        }
      }

      if (is_default) {
        this.skills[i] = new Skill($.extend({}, skill, levels[0], {level: 1, advancement: adv, id: i}));
        l++;
      } else {
        this.skills[i] = new Skill($.extend({}, skill, {image: skill.image+'_b', required_level: 0, level: 0, advancement: adv, id: i}));
      }

      var curr = this.skills[i], max = curr, end, sp_sum = 0;
      max = curr;

      for (; l < levels.length; l++) {
        curr.next = new Skill($.extend({}, skill, levels[l], {level: l+1, advancement: adv, id: i}));
        curr.next.prev = curr;
        curr = curr.next;

        sp_sum += curr.get_spcost();
        curr.total_sp_cost = sp_sum;

        if (curr.required_level <= this.max_levels[adv] ) {
          max = curr;
        }
      }
      end = curr;

      curr = this.skills[i];
      while (curr) {
        curr.start = this.skills[i];
        curr.max = max;
        curr.end = end;
        curr = curr.next;
      }

      this.parsed_total++;
      this.set_starting_skill(i);
    }
  },

  get_skill: function(id, lvl) {
    var skill = this.skills[id];
    if (skill.level == 1 && lvl == 0) {
      return skill;
    }

    while (skill.level != lvl) {
      skill = skill.next;
    }

    return skill;
  },

  $: function(id) {
    return $('.skill[data-id=' + id + ']');
  },

  set_starting_skill: function(id) {
    var $skill = this.$(id), position = $skill.data('position');
    var skill = this.get_skill(id, inv_build_map[this.build[position]]);
    skill.bind($skill);

    $skill.bind({
      mousedown: function(e) {
        var skill = $(this).data('skill'), change;
        var extreme = e.shiftKey || e.ctrlKey;
        if (e.button == 0) { // left click
          if (extreme) {
            if (skill.level < skill.max.level) {
              change = skill.max;
            }
          } else {
            if (skill.next) {
              change = skill.next;
            }
          }
        } else if(e.button == 2) { // right click
          if (extreme) {
            if (skill.level != skill.start.level) {
              change = skill.start;
            }
          } else {
            if (skill.prev) {
              change = skill.prev;
            }
          }
        }

        if (change) {
            description.use(change);
            change.bind($(this));
            dnss.update();
            requirements.check();
        }
      },
      mouseenter: function() {
        description.use($(this).data('skill'));
      }
    });

    $skill.on('contextmenu', function(){ // disable menu
      return false;
    });

    if (this.parsed_total == this.total_skills) {
      this.update();
      if (inv_build_map[this.build[this.build.length - 1]] & 1) {
        description.flip();
      }
    }
  },

  get_all_sp: function() {
    var sp = [0,0,0];
    for (var i = 0; i < 72; i++) {
      if (this.positions[i]) {
        sp[Math.floor(i/24)] += this.positions[i].total_sp_cost;
      }
    }

    return sp;
  },

  update: function() {
    var sp = this.get_all_sp();
    for (i in sp) {
      $('#job-list-sp li[data-job=' + i + '] .sp').html(sp[i] + '/' + this.max_sp[i]);
    }

    $('#job-list-sp li:last .sp').html(sp[0]+sp[1]+sp[2] + '/' + this.max_sp[3]);
    this.update_build();
  },

  update_build: function() {
    var $build = $('#build');
    $build.val(fmt($build.data('base'), window.location) + '/?' + this.build.join(''));
  }
};<commit_msg>Need to check<commit_after>var dnss = {
  skills: {},
  types: null,
  queue: [],
  messages: {},
  max_levels: null,
  max_sp: null,
  build: Array(72 + 1 + 1).join('-').split(''),
  positions: [],
  current: {},
  total_skills: $('.skill[data-id]').length,
  parsed_total: 0,
  jobs: [],

  init: function(jobIdentifiers, max_levels, max_sp, start_build) {
    this.jobs = jobIdentifiers;
    this.max_levels = max_levels;
    this.max_sp = max_sp;

    // sets the starting build
    if (start_build) {
      var m = start_build.match(/^[0-9a-zA-Z-]+/g);
      var build = m.shift();
      if (build && build.length > 72) {
        build = build.split('');
        for (var i = 0; i < build.length - 1; i++) {
          this.build[i] = build[i];
        }
        this.build[this.build.length - 1] = build[build.length - 1];
      }
    }

    // gives position to every container
    $('.container').each(function(i) {
      var element = $(this).find('.skill');
      if (element.length) {
        element.data('position', i);
      }
    });

    // types
    $.getJSON('/json/types.min.json', function(json) {
      dnss.types = json;
      while (dnss.queue.length) {
        dnss.add_skills(dnss.queue.shift());
      }
    });

    // get json
    for (var i in jobIdentifiers) {
      $.getJSON(fmt('/json/$0.min.json', jobIdentifiers[i]), function(json) {
        for (var j in json.messages) { // I don't trust async $.extends()
          dnss.messages[j] = json.messages[j];
        }

        if (dnss.types) {
          dnss.add_skills(json);
        } else {
          dnss.queue.push(json);
        }
      });
    }

    // mode bind
    $('#mode').bind('click', function() {
      switch($(this).val()) {
        case 'pve': $(this).val('pvp'); break;
        case 'pvp': $(this).val('pve'); break;
      }
     description.flip();
    });

    // job list bind
    $('#job-list-sp li[data-job]').each(function() {
      var idx = $(this).data('job');
      $(this).click(function() {
        $('#job-list-sp li[data-job][class="active"]').removeClass('active');
        $(this).addClass('active');
        $('.skill-tree').hide();
        $('#skill-tree-' + idx).show();
      })
    });
  },

  add_skills: function(job) {
    var skills = job.skills, default_skills = job.default_skills, adv = job.advancement;
    delete job.advancement;
    for (i in skills) {
      var skill = skills[i];
      var levels = skill.levels;
      delete skill.levels; // don't want this lingering

      var l = 0, is_default = false;
      if (default_skills) {
        for (var j = 0; j < default_skills.length; j++) {
          if (default_skills[j] == i) {
            is_default = true;
            break;
          }
        }
      }

      if (is_default) {
        this.skills[i] = new Skill($.extend({}, skill, levels[0], {level: 1, advancement: adv, id: i}));
        l++;
      } else {
        this.skills[i] = new Skill($.extend({}, skill, {image: skill.image+'_b', required_level: 0, level: 0, advancement: adv, id: i}));
      }

      var curr = this.skills[i], max = curr, end, sp_sum = 0;
      max = curr;

      for (; l < levels.length; l++) {
        curr.next = new Skill($.extend({}, skill, levels[l], {level: l+1, advancement: adv, id: i}));
        curr.next.prev = curr;
        curr = curr.next;

        sp_sum += curr.get_spcost();
        curr.total_sp_cost = sp_sum;

        if (curr.required_level <= this.max_levels[adv] ) {
          max = curr;
        }
      }
      end = curr;

      curr = this.skills[i];
      while (curr) {
        curr.start = this.skills[i];
        curr.max = max;
        curr.end = end;
        curr = curr.next;
      }

      this.parsed_total++;
      this.set_starting_skill(i);
    }
  },

  get_skill: function(id, lvl) {
    var skill = this.skills[id];
    if (skill.level == 1 && lvl == 0) {
      return skill;
    }

    while (skill.level != lvl) {
      skill = skill.next;
    }

    return skill;
  },

  $: function(id) {
    return $('.skill[data-id=' + id + ']');
  },

  set_starting_skill: function(id) {
    var $skill = this.$(id), position = $skill.data('position');
    var skill = this.get_skill(id, inv_build_map[this.build[position]]);
    skill.bind($skill);

    $skill.bind({
      mousedown: function(e) {
        var skill = $(this).data('skill'), change;
        var extreme = e.shiftKey || e.ctrlKey;
        if (e.button == 0) { // left click
          if (extreme) {
            if (skill.level < skill.max.level) {
              change = skill.max;
            }
          } else {
            if (skill.next) {
              change = skill.next;
            }
          }
        } else if(e.button == 2) { // right click
          if (extreme) {
            if (skill.level != skill.start.level) {
              change = skill.start;
            }
          } else {
            if (skill.prev) {
              change = skill.prev;
            }
          }
        }

        if (change) {
            description.use(change);
            change.bind($(this));
            dnss.update();
            requirements.check();
        }
      },
      mouseenter: function() {
        description.use($(this).data('skill'));
      }
    });

    $skill.on('contextmenu', function(){ // disable menu
      return false;
    });

    if (this.parsed_total == this.total_skills) {
      this.update();
      if (inv_build_map[this.build[this.build.length - 1]] & 1) {
        description.flip();
      }

      requirements.check();
    }
  },

  get_all_sp: function() {
    var sp = [0,0,0];
    for (var i = 0; i < 72; i++) {
      if (this.positions[i]) {
        sp[Math.floor(i/24)] += this.positions[i].total_sp_cost;
      }
    }

    return sp;
  },

  update: function() {
    var sp = this.get_all_sp();
    for (i in sp) {
      $('#job-list-sp li[data-job=' + i + '] .sp').html(sp[i] + '/' + this.max_sp[i]);
    }

    $('#job-list-sp li:last .sp').html(sp[0]+sp[1]+sp[2] + '/' + this.max_sp[3]);
    this.update_build();
  },

  update_build: function() {
    var $build = $('#build');
    $build.val(fmt($build.data('base'), window.location) + '/?' + this.build.join(''));
  }
};<|endoftext|>


<commit_before>/* eslint-env node */

const webpack = require('webpack');
const debug = require('debug')('app:webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const isDev = process.env.NODE_ENV !== 'production';
debug(`Running in ${isDev ? 'development' : 'production'} mode`);

module.exports = {
  entry: {
    main: './src/browser/main',
    'service-worker': './src/browser/service-worker.js',
  },
  output: {
    path: `${__dirname}/dist`,
    filename: 'scripts/[name].js',
  },
  module: {
    rules: [{test: /\.js$/, exclude: /node_modules/, use: ['babel-loader']}],
  },
  plugins: [].concat(
    new CleanWebpackPlugin('dist'),
    new CopyWebpackPlugin([{from: 'static'}]),
    isDev ? [] : new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
    new webpack.DefinePlugin({BUILD_ID: Date.now()}),
    new webpack.BannerPlugin({banner: `Build date: ${new Date()}`}),
    new HtmlWebpackPlugin({
      template: 'html/index.ejs',
      filename: 'index.html',
      chunks: ['main'],
      minify: {
        collapseWhitespace: true,
        collapseInlineTagWhitespace: true,
        conservativeCollapse: true,
        removeAttributeQuotes: true,
        removeComments: true,
        minifyJS: true,
        minifyCSS: true,
      },
    })
  ),
  devtool: 'source-map',
};
<commit_msg>Ensure a fresh main.js is served every time<commit_after>/* eslint-env node */

const webpack = require('webpack');
const debug = require('debug')('app:webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const isDev = process.env.NODE_ENV !== 'production';
debug(`Running in ${isDev ? 'development' : 'production'} mode`);

module.exports = {
  entry: {
    main: './src/browser/main',
    'service-worker': './src/browser/service-worker.js',
  },
  output: {
    path: `${__dirname}/dist`,
    filename: 'scripts/[name].js',
  },
  module: {
    rules: [{test: /\.js$/, exclude: /node_modules/, use: ['babel-loader']}],
  },
  plugins: [].concat(
    new CleanWebpackPlugin('dist'),
    new CopyWebpackPlugin([{from: 'static'}]),
    isDev ? [] : new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
    new webpack.DefinePlugin({BUILD_ID: Date.now()}),
    new webpack.BannerPlugin({banner: `Build date: ${new Date()}`}),
    new HtmlWebpackPlugin({
      template: 'html/index.ejs',
      filename: 'index.html',
      chunks: ['main'],
      hash: true,
      minify: {
        collapseWhitespace: true,
        collapseInlineTagWhitespace: true,
        conservativeCollapse: true,
        removeAttributeQuotes: true,
        removeComments: true,
        minifyJS: true,
        minifyCSS: true,
      },
    })
  ),
  devtool: 'source-map',
};
<|endoftext|>