<commit_before>/*****************************************************************************/
/* Reports Scheme */
/*****************************************************************************/

var textAreaRegEx = /^[a-z0-9A-z .,!;\n\r&:%"?æøåÆØÅèÈéÉ\/()<>-]*$/;
var textFieldRegEx = /^[a-z0-9A-z .,æøåÆØÅèÈéÉ()-]{2,100}$/;

ReportScheme = new SimpleSchema({
    project: {
        type: Object,
        optional: false
    },
    "project.name": {
    	type: String,
    	label: "Prosjektnavn",
    	optional: false,
    	regEx: textFieldRegEx
    },
    "project.projectNumber": {
    	type: Number,
    	label: "Prosjektnummer (Trailbase)",
    	optional: false,
    	regEx: /^[0-9 ]{1,10}$/
    },
    "project.sector": {
    	type: String,
    	label: "Sektor",
    	optional: false,
        regEx: textFieldRegEx
    },
    "project.location": {
        type: Object,
        optional: false
    },
    "project.location.name": {
        type: String,
        label: "Lokasjonsbeskrivelse for evalueringsobjektet",
        optional: true,
        regEx: textFieldRegEx
    },
    "project.location.coordinates": {
        type: Object,
        optional: true
    },
    "project.location.coordinates.lat": {
        type: String,
        optional: true
    },
    "project.location.coordinates.lng": {
        type: String,
        optional: true
    },
    "project.successCategory": {
        type: Number,
        optional: false,
        regEx: /^[1-3]$/
    },
    "project.projectDescription": {
        type: Object,
        optional: false
    },
    "project.projectDescription.short": {
        type: String,
        label: "Kort prosjektbeskrivelse",
        optional: false,
        regEx: textAreaRegEx
    },
    "project.projectDescription.long": {
        type: String,
        label: "Utdypende prosjektbeskrivelse og mål/bakgrunn for prosjektet",
        optional: false,
        regEx: textAreaRegEx
    },
    "project.finishingYear": {
        type: Number,
        label: "Årstall for ferdigstilling av prosjekt",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.evaluationYear": {
        type: Number,
        label: "Årstall for utført evaluering",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.decisionYear": {
        type: Number,
        label: "Årstall for vedtak",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.managementBudget": {
        type: Object,
        optional: false
    },
    "project.managementBudget.year": {
        type: Number,
        label: "Årstall (Styringsramme)",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.managementBudget.amount": {
        type: Number,
        label: "Styringsramme (i millioner NOK)",
        optional: false,
        regEx: /^[0-9]{1-10}$/
    },
    "project.costBudget": {
        type: Object,
        optional: false
    },
    "project.costBudget.year": {
        type: Number,
        label: "Årstall (Kostnadsramme)",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.costBudget.amount": {
        type: Number,
        label: "Kostnadsramme (i millioner NOK)",
        optional: false,
        regEx: /^[0-9]{1-10}$/
    },
    "project.costFinal": {
        type: Object,
        optional: false
    },
    "project.costFinal.year": {
        type: Number,
        label: "Årstall (Sluttkostnad)",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.costFinal.amount": {
        type: Number,
        label: "Sluttkostnad (i millioner NOK)",
        optional: false,
        regEx: /^[0-9]{1-10}$/
    },
    "evaluation": {
        type: Object,
        optional: false
    },
    "evaluation.overall": {
        type: Object,
        optional: false
    },
    "evaluation.overall.short": {
        type: String,
        label: "Kort samlet vurdering",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.overall.long": {
        type: String,
        label: "Utdypende samlet vurdering",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.productivity": {
        type: Object,
        optional: false
    },
    "evaluation.productivity.short": {
        type: String,
        label: "Kort vurdering av produktivitet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.productivity.long": {
        type: String,
        label: "Utdypende vurdering av produktivitet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.productivity.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.achievement": {
        type: Object,
        optional: false
    },
    "evaluation.achievement.short": {
        type: String,
        label: "Kort vurdering av måloppnåelse",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.achievement.long": {
        type: String,
        label: "Utdypende vurdering av måloppnåelse",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.achievement.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.effects": {
        type: Object,
        optional: false
    },
    "evaluation.effects.short": {
        type: String,
        label: "Kort vurdering av virkninger",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.effects.long": {
        type: String,
        label: "Utdypende vurdering av virkninger",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.effects.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.relevance": {
        type: Object,
        optional: false
    },
    "evaluation.relevance.short": {
        type: String,
        label: "Kort vurdering av relevans",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.relevance.long": {
        type: String,
        label: "Utdypende vurdering av relevans",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.relevance.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.viability": {
        type: Object,
        optional: false
    },
    "evaluation.viability.short": {
        type: String,
        label: "Kort vurdering av levedyktighet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.viability.long": {
        type: String,
        label: "Utdypende vurdering av levedyktighet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.viability.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.profitability": {
        type: Object,
        optional: false
    },
    "evaluation.profitability.short": {
        type: String,
        label: "Kort vurdering av samfunnsøkonomisk lønnsomhet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.profitability.long": {
        type: String,
        label: "Utdypende vurdering av samfunnsøkonomisk lønnsomhet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.profitability.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "responsible": {
        type: Object,
        optional: false
    },
    "responsible.organization": {
        type: String,
        label: "Evalueringsansvarlig instans",
        optional: false,
        regEx: textFieldRegEx
    },
    "responsible.person": {
        type: String,
        label: "Evalueringsansvarlig person",
        optional: true,
        regEx: textFieldRegEx
    },
    "images": {
        type: [Object],
        optional: false
    },
    "images.$.fileId": {
        type: String,
        optional: true,
        regEx: SimpleSchema.RegEx.Id
    },
    "images.$.title": {
        type: String,
        label: "Tittel",
        optional: true,
        regEx: textFieldRegEx
    },
    "images.$.copyright": {
        type: String,
        label: "Kilde",
        optional: true,
        regEx: textFieldRegEx
    },
    "images.$.link": {
        type: String,
        label: "Kilde-URL",
        optional: true,
        regEx: SimpleSchema.RegEx.Url
    },
    "references": {
        type: [Object],
        optional: false
    },
    "references.$.fileId": {
        type: String,
        optional: true,
        regEx: SimpleSchema.RegEx.Id
    },
    "references.$.title": {
        type: String,
        label: "Tittel",
        optional: true,
        regEx: textFieldRegEx
    },
    "references.$.typedoc": {
        type: String,
        label: "Dokumenttype",
        optional: true,
        regEx: textFieldRegEx
    },
    "references.$.date": {
        type: String,
        label: "Dato",
        optional: true,
        regEx: /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
    },
    "_id": {
        type: String,
        denyInsert: true,
        optional: true,
        regEx: SimpleSchema.RegEx.Id
    },
    "_public": {
        type: Boolean,
        optional: false
    }
});

ReportScheme.messages({
    required: "[label] må fylles ut",
    minString: "[label] må inneholde minimum [min] tegn",
    maxString: "[label] må ikke overskride [max] tegn",
    minNumber: "[label] må minst være [min]",
    maxNumber: "[label] må ikke overskride [max]",
    minDate: "[label] må være enten på eller før [min]",
    maxDate: "[label] kan ikke være etter [max]",
    minCount: "Du må spesifisere minst [minCount] verdier",
    maxCount: "Du kan ikke spesifisere mer enn [maxCount] verdier",
    noDecimal: "[label] må inneholde et heltall",
    notAllowed: "[value] er ikke en gyldig verdi",
    expectedString: "[label] må inneholde en streng",
    expectedNumber: "[label] må inneholde et tall",
    expectedBoolean: "[label] må være en bolsk verdi",
    expectedArray: "[label] må være en liste",
    expectedObject: "[label] må være et objekt",
    expectedConstructor: "[label] må være av type [type]",
    regEx: "[label] feilet ved regulær sjekk av innholdet"
});

Reports.attachSchema(ReportScheme);<commit_msg>Comments in both/schemas/reports.js<commit_after>/**
 * Reports Scheme
 */

var textAreaRegEx = /^[a-z0-9A-z .,!;\n\r&:%"?æøåÆØÅèÈéÉ\/()<>-]*$/;
var textFieldRegEx = /^[a-z0-9A-z .,æøåÆØÅèÈéÉ()-]{2,100}$/;

ReportScheme = new SimpleSchema({
    project: {
        type: Object,
        optional: false
    },
    "project.name": {
    	type: String,
    	label: "Prosjektnavn",
    	optional: false,
    	regEx: textFieldRegEx
    },
    "project.projectNumber": {
    	type: Number,
    	label: "Prosjektnummer (Trailbase)",
    	optional: false,
    	regEx: /^[0-9 ]{1,10}$/
    },
    "project.sector": {
    	type: String,
    	label: "Sektor",
    	optional: false,
        regEx: textFieldRegEx
    },
    "project.location": {
        type: Object,
        optional: false
    },
    "project.location.name": {
        type: String,
        label: "Lokasjonsbeskrivelse for evalueringsobjektet",
        optional: true,
        regEx: textFieldRegEx
    },
    "project.location.coordinates": {
        type: Object,
        optional: true
    },
    "project.location.coordinates.lat": {
        type: String,
        optional: true
    },
    "project.location.coordinates.lng": {
        type: String,
        optional: true
    },
    "project.successCategory": {
        type: Number,
        optional: false,
        regEx: /^[1-3]$/
    },
    "project.projectDescription": {
        type: Object,
        optional: false
    },
    "project.projectDescription.short": {
        type: String,
        label: "Kort prosjektbeskrivelse",
        optional: false,
        regEx: textAreaRegEx
    },
    "project.projectDescription.long": {
        type: String,
        label: "Utdypende prosjektbeskrivelse og mål/bakgrunn for prosjektet",
        optional: false,
        regEx: textAreaRegEx
    },
    "project.finishingYear": {
        type: Number,
        label: "Årstall for ferdigstilling av prosjekt",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.evaluationYear": {
        type: Number,
        label: "Årstall for utført evaluering",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.decisionYear": {
        type: Number,
        label: "Årstall for vedtak",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.managementBudget": {
        type: Object,
        optional: false
    },
    "project.managementBudget.year": {
        type: Number,
        label: "Årstall (Styringsramme)",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.managementBudget.amount": {
        type: Number,
        label: "Styringsramme (i millioner NOK)",
        optional: false,
        regEx: /^[0-9]{1-10}$/
    },
    "project.costBudget": {
        type: Object,
        optional: false
    },
    "project.costBudget.year": {
        type: Number,
        label: "Årstall (Kostnadsramme)",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.costBudget.amount": {
        type: Number,
        label: "Kostnadsramme (i millioner NOK)",
        optional: false,
        regEx: /^[0-9]{1-10}$/
    },
    "project.costFinal": {
        type: Object,
        optional: false
    },
    "project.costFinal.year": {
        type: Number,
        label: "Årstall (Sluttkostnad)",
        optional: false,
        max:9999,
        min:1900,
        regEx: /^[0-9]{4}$/
    },
    "project.costFinal.amount": {
        type: Number,
        label: "Sluttkostnad (i millioner NOK)",
        optional: false,
        regEx: /^[0-9]{1-10}$/
    },
    "evaluation": {
        type: Object,
        optional: false
    },
    "evaluation.overall": {
        type: Object,
        optional: false
    },
    "evaluation.overall.short": {
        type: String,
        label: "Kort samlet vurdering",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.overall.long": {
        type: String,
        label: "Utdypende samlet vurdering",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.productivity": {
        type: Object,
        optional: false
    },
    "evaluation.productivity.short": {
        type: String,
        label: "Kort vurdering av produktivitet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.productivity.long": {
        type: String,
        label: "Utdypende vurdering av produktivitet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.productivity.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.achievement": {
        type: Object,
        optional: false
    },
    "evaluation.achievement.short": {
        type: String,
        label: "Kort vurdering av måloppnåelse",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.achievement.long": {
        type: String,
        label: "Utdypende vurdering av måloppnåelse",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.achievement.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.effects": {
        type: Object,
        optional: false
    },
    "evaluation.effects.short": {
        type: String,
        label: "Kort vurdering av virkninger",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.effects.long": {
        type: String,
        label: "Utdypende vurdering av virkninger",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.effects.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.relevance": {
        type: Object,
        optional: false
    },
    "evaluation.relevance.short": {
        type: String,
        label: "Kort vurdering av relevans",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.relevance.long": {
        type: String,
        label: "Utdypende vurdering av relevans",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.relevance.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.viability": {
        type: Object,
        optional: false
    },
    "evaluation.viability.short": {
        type: String,
        label: "Kort vurdering av levedyktighet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.viability.long": {
        type: String,
        label: "Utdypende vurdering av levedyktighet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.viability.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "evaluation.profitability": {
        type: Object,
        optional: false
    },
    "evaluation.profitability.short": {
        type: String,
        label: "Kort vurdering av samfunnsøkonomisk lønnsomhet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.profitability.long": {
        type: String,
        label: "Utdypende vurdering av samfunnsøkonomisk lønnsomhet",
        optional: true,
        regEx: textAreaRegEx
    },
    "evaluation.profitability.value": {
        type: Number,
        optional: false,
        regEx: /^[1-6]$/
    },
    "responsible": {
        type: Object,
        optional: false
    },
    "responsible.organization": {
        type: String,
        label: "Evalueringsansvarlig instans",
        optional: false,
        regEx: textFieldRegEx
    },
    "responsible.person": {
        type: String,
        label: "Evalueringsansvarlig person",
        optional: true,
        regEx: textFieldRegEx
    },
    "images": {
        type: [Object],
        optional: false
    },
    "images.$.fileId": {
        type: String,
        optional: true,
        regEx: SimpleSchema.RegEx.Id
    },
    "images.$.title": {
        type: String,
        label: "Tittel",
        optional: true,
        regEx: textFieldRegEx
    },
    "images.$.copyright": {
        type: String,
        label: "Kilde",
        optional: true,
        regEx: textFieldRegEx
    },
    "images.$.link": {
        type: String,
        label: "Kilde-URL",
        optional: true,
        regEx: SimpleSchema.RegEx.Url
    },
    "references": {
        type: [Object],
        optional: false
    },
    "references.$.fileId": {
        type: String,
        optional: true,
        regEx: SimpleSchema.RegEx.Id
    },
    "references.$.title": {
        type: String,
        label: "Tittel",
        optional: true,
        regEx: textFieldRegEx
    },
    "references.$.typedoc": {
        type: String,
        label: "Dokumenttype",
        optional: true,
        regEx: textFieldRegEx
    },
    "references.$.date": {
        type: String,
        label: "Dato",
        optional: true,
        regEx: /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
    },
    "_id": {
        type: String,
        denyInsert: true,
        optional: true,
        regEx: SimpleSchema.RegEx.Id
    },
    "_public": {
        type: Boolean,
        optional: false
    }
});

/**
 * Translation of the schema messages
 */

ReportScheme.messages({
    required: "[label] må fylles ut",
    minString: "[label] må inneholde minimum [min] tegn",
    maxString: "[label] må ikke overskride [max] tegn",
    minNumber: "[label] må minst være [min]",
    maxNumber: "[label] må ikke overskride [max]",
    minDate: "[label] må være enten på eller før [min]",
    maxDate: "[label] kan ikke være etter [max]",
    minCount: "Du må spesifisere minst [minCount] verdier",
    maxCount: "Du kan ikke spesifisere mer enn [maxCount] verdier",
    noDecimal: "[label] må inneholde et heltall",
    notAllowed: "[value] er ikke en gyldig verdi",
    expectedString: "[label] må inneholde en streng",
    expectedNumber: "[label] må inneholde et tall",
    expectedBoolean: "[label] må være en bolsk verdi",
    expectedArray: "[label] må være en liste",
    expectedObject: "[label] må være et objekt",
    expectedConstructor: "[label] må være av type [type]",
    regEx: "[label] feilet ved regulær sjekk av innholdet"
});

// Attach the schema to the collection
Reports.attachSchema(ReportScheme);
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

// Node.js core.
const path = require('path');

// Local dependencies.
const packageJSON = require('../json/package.json.js');
const database = require('../json/database.json.js');

/**
 * Copy required files for the generated application
 */

module.exports = {
  moduleDir: path.resolve(__dirname, '..'),
  templatesDirectory: path.resolve(__dirname, '..', 'templates'),
  before: require('./before'),
  after: require('./after'),
  targets: {

    // Call the `admin` generator.
    '.': ['admin'],

    // Main package.
    'package.json': {
      jsonfile: packageJSON
    },

    'config/environments/development/database.json': {
      jsonfile: database
    },

    // Copy dot files.
    '.editorconfig': {
      copy: 'editorconfig'
    },
    '.npmignore': {
      copy: 'npmignore'
    },
    '.gitignore': {
      copy: 'gitignore'
    },

    // Copy Markdown files with some information.
    'README.md': {
      template: 'README.md'
    },

    // Empty API directory.
    'api': {
      folder: {}
    },

    // Empty plugins directory.
    'plugins': {
      folder: {}
    },

    // Empty public directory.
    'public': {
      folder: {}
    },

    // Empty node_modules directory.
    'node_modules': {
      folder: {}
    }
  }
};
<commit_msg>Remove node_modules folder for alpha.10.3<commit_after>'use strict';

/**
 * Module dependencies
 */

// Node.js core.
const path = require('path');

// Local dependencies.
const packageJSON = require('../json/package.json.js');
const database = require('../json/database.json.js');

/**
 * Copy required files for the generated application
 */

module.exports = {
  moduleDir: path.resolve(__dirname, '..'),
  templatesDirectory: path.resolve(__dirname, '..', 'templates'),
  before: require('./before'),
  after: require('./after'),
  targets: {

    // Call the `admin` generator.
    '.': ['admin'],

    // Main package.
    'package.json': {
      jsonfile: packageJSON
    },

    'config/environments/development/database.json': {
      jsonfile: database
    },

    // Copy dot files.
    '.editorconfig': {
      copy: 'editorconfig'
    },
    '.npmignore': {
      copy: 'npmignore'
    },
    '.gitignore': {
      copy: 'gitignore'
    },

    // Copy Markdown files with some information.
    'README.md': {
      template: 'README.md'
    },

    // Empty API directory.
    'api': {
      folder: {}
    },

    // Empty plugins directory.
    'plugins': {
      folder: {}
    },

    // Empty public directory.
    'public': {
      folder: {}
    }
  }
};
<|endoftext|>


<commit_before>const $ = window.jQuery
const resolve = require('resolve-pathname')
const fetch = window.fetch

const htmlWithLink = require('../helpers').htmlWithLink
const bloburl = require('../helpers').bloburl

module.exports.process = function process () {
  var importing = false
  var from_import = false
  var hasImported = false

  $('.blob-code-inner').each((_, elem) => {
    let line = elem.innerText.trim()

    if (line.match(/^import\b/) || line.match(/^include\b/)) {
      importing = true
      hasImported = false
    }

    if (line.match(/^from /)) {
      importing = true
      from_import = true
      hasImported = false
    }

    if (importing) {
      var matches = []

      if (from_import) {
        let m = line.match(/from +([\w\/_]+) +import/)
        if (m) {
          matches = [m[1]]
        }
      } else {
        let m = line.match(/([\w\/_]+)( *,| *$)/g)
        if (m) {
          matches = m
            .map(n => n.match(/[\w\/_]+/)[0] /* remove comma and spaces */)
            .filter(n => n !== 'import')
            .filter(n => n !== 'include')
        }
      }

      if (!matches.length) return

      hasImported = true
      Promise.all(matches.map(moduleName => {
        let [moduleFirstName] = moduleName.split('/')

        // first try the stdlib
        if (moduleFirstName in stdlib) {
          return [
            moduleFirstName,
            {
              url: `https://nim-lang.org/docs/${moduleFirstName}.html`,
              kind: 'stdlib'
            }
          ]
        }

        // then try the nimble package list
        return externalurl(moduleFirstName)
        .then(info => {
          if (info) return [moduleFirstName, info]

          // if none found, assume it is a local path
          let {user, repo, ref, current} = window.pathdata
          let relative = resolve(moduleName, current.join('/'))
          return [moduleName, bloburl(user, repo, ref, relative) + '.nim']
        })
      }))
      .then(results => {
        // results is an array of [moduleName, url] for all modules in this line, in order
        // since we may have multiple modules in the same line we must use extra-caution when
        // replacing so one module name don't try to overwrite underlying HTML tags or other
        // module names.

        var baseIndex = 0
        var resultingHTML = ''
        results.forEach(([moduleName, url]) => {
          let index = elem.innerHTML.slice(baseIndex).search(moduleName)
          if (index === -1) return // should never happen.
          let endIndex = baseIndex + index + moduleName.length
          let html = elem.innerHTML.slice(baseIndex, endIndex)
          let withLink = htmlWithLink(html, moduleName, url)

          resultingHTML += withLink
          baseIndex = endIndex
        })

        elem.innerHTML = resultingHTML + elem.innerHTML.slice(baseIndex)
      })
    }

    if (importing && hasImported && line.match(/\w$/) /* line ending without a comma */) {
      importing = false
      from_import = false
    }
  })
}

module.exports.externalurl = externalurl
function externalurl (moduleName) {
  return waitForNimbleList()
    .then(packages => {
      for (let i = 0; i < packages.length; i++) {
        let pack = packages[i]
        if (pack.name === moduleName) {
          return {
            url: pack.url,
            desc: pack.description,
            kind: 'external'
          }
        }
      }
    })
    .catch(() => null)
}

const stdlib = {'apis': 1, 'system': 1, 'threads': 1, 'channels': 1, 'locks': 1, 'rlocks': 1, 'macros': 1, 'typeinfo': 1, 'typetraits': 1, 'threadpool': 1, 'cpuinfo': 1, 'algorithm': 1, 'tables': 1, 'sets': 1, 'lists': 1, 'deques': 1, 'intsets': 1, 'critbits': 1, 'sequtils': 1, 'strutils': 1, 'strmisc': 1, 'parseutils': 1, 'strscans': 1, 'strtabs': 1, 'unicode': 1, 'encodings': 1, 'pegs': 1, 'ropes': 1, 'matchers': 1, 'subexes': 1, 'os': 1, 'osproc': 1, 'times': 1, 'dynlib': 1, 'streams': 1, 'marshal': 1, 'terminal': 1, 'memfiles': 1, 'fsmonitor': 1, 'asyncfile': 1, 'math': 1, 'complex': 1, 'rationals': 1, 'fenv': 1, 'basic2d': 1, 'basic3d': 1, 'mersenne': 1, 'random': 1, 'stats': 1, 'cgi': 1, 'scgi': 1, 'browsers': 1, 'httpserver': 1, 'httpcore': 1, 'posix': 1, 'httpclient': 1, 'smtp': 1, 'cookies': 1, 'mimetypes': 1, 'uri': 1, 'asyncdispatch': 1, 'asyncnet': 1, 'asynchttpserver': 1, 'asyncftpclient': 1, 'net': 1, 'nativesockets': 1, 'selectors': 1, 'parseopt': 1, 'parseopt2': 1, 'parsecfg': 1, 'parsexml': 1, 'parsecsv': 1, 'parsesql': 1, 'json': 1, 'lexbase': 1, 'highlite': 1, 'rst': 1, 'rstast': 1, 'rstgen': 1, 'sexp': 1, 'xmldom': 1, 'xmldomparser': 1, 'xmltree': 1, 'xmlparser': 1, 'htmlparser': 1, 'htmlgen': 1, 'hashes': 1, 'md5': 1, 'base64': 1, 'securehash': 1, 'colors': 1, 'events': 1, 'oids': 1, 'endians': 1, 'logging': 1, 'options': 1, 'future': 1, 'coro': 1, 'unittest': 1, 'dom': 1, 'asyncio': 1, 'ftpclient': 1, 'sockets': 1, 'rawsockets': 1, 're': 1, 'nre': 1, 'db_postgres': 1, 'db_mysql': 1, 'db_sqlite': 1, 'ssl': 1, 'winlean': 1, 'pcre': 1, 'iup': 1, 'postgres': 1, 'mysql': 1, 'sqlite3': 1, 'odbcsql': 1, 'libuv': 1, 'joyent_http_parser': 1, 'libcurl': 1, 'openssl': 1, 'libsvm': 1}

var requested = false
var packagesPromise
function waitForNimbleList () {
  if (requested) {
    return packagesPromise
  } else {
    requested = true
    packagesPromise =
      fetch('https://rawgit.com/nim-lang/packages/master/packages.json')
        .then(r => r.json())
    return packagesPromise
  }
}
<commit_msg>nim better matching and path resolving with treePromise.<commit_after>const $ = window.jQuery
const resolve = require('resolve-pathname')
const endswith = require('lodash.endswith')
const fetch = window.fetch

const htmlWithLink = require('../helpers').htmlWithLink
const treePromise = require('../helpers').treePromise
const treeurl = require('../helpers').treeurl
const bloburl = require('../helpers').bloburl

module.exports.process = function process () {
  var importing = false
  var from_import = false
  var hasImported = false

  $('.blob-code-inner').each((_, elem) => {
    let line = elem.innerText.trim()

    if (line.match(/^import\b/) || line.match(/^include\b/)) {
      importing = true
      hasImported = false

      if (line.match(/^from /)) {
        importing = true
        from_import = true
        hasImported = false
      }
    }

    if (importing) {
      var matches = []

      if (from_import) {
        let m = line.match(/from +([\w\/_]+) +import/)
        if (m) {
          matches = [m[1]]
        }
      } else {
        let m = line.match(/("?[\w\/._]+"?)( +as +[\w_]+| *,| *$)/g)
        if (m) {
          matches = m
            .map(n => n.match(/"?[\w\/._]+"?/)[0] /* remove comma and spaces */)
            .filter(n => n !== 'import')
            .filter(n => n !== 'include')
        }
      }

      if (!matches.length) return

      hasImported = true
      Promise.all(matches.map(moduleName => {
        var names
        if (moduleName[0] === '"') {
          // name has quotes, like "src/path/template.tmpl" or "src/handle"
          names = moduleName.slice(1, -1).split('/')
        } else {
          // name has no quotes, so its parts can be separated by '.' or '/'
          names = moduleName.indexOf('/') !== -1 ? moduleName.split('/') : moduleName.split('.')
        }
        let firstName = names[0]

        // first try the stdlib
        if (firstName in stdlib) {
          return [
            firstName,
            {
              url: `https://nim-lang.org/docs/${firstName}.html`,
              kind: 'stdlib'
            }
          ]
        }

        // then try a relative path
        return treePromise()
          .then(paths => {
            let {user, repo, ref, current} = window.pathdata
            let moduleAsPath = names.join('/')
            let extension = moduleAsPath.indexOf('.') !== -1 ? '' : '.nim'

            var idx

            // trey relative to local module
            let relative = resolve(moduleAsPath, current.join('/')) + extension
            idx = paths.indexOf(relative)
            if (idx !== -1) {
              return [moduleName, bloburl(user, repo, ref, paths[idx])]
            }

            // try relative to root
            idx = paths.indexOf(moduleAsPath + extension)
            if (idx !== -1) {
              return [moduleName, bloburl(user, repo, ref, paths[idx])]
            }

            // fallback to search anywhere
            for (let i = 0; i < paths.length; i++) {
              let path = paths[i]
              let modulepattern = new RegExp(`\b${moduleAsPath.replace('/', '\\/')}\b`)
              if (modulepattern.exec(path)) {
                // found something
                if (endswith(path, moduleAsPath + extension)) {
                  // it is a file
                  return [moduleName, bloburl(user, repo, ref, path)]
                } else {
                  // it is probably a directory
                  return [moduleName, treeurl(user, repo, ref, path.split('/').slice(0, -1).join('/'))]
                }
              }
            }

            // found nothing, let's try the nimble package list
            return externalurl(firstName)
            .then(info => {
              if (info) return [firstName, info]
            })
          })
      }))
      .then(results => results.filter(x => x))
      .then(results => {
        // results is an array of [moduleName, url] for all modules in this line, in order
        // since we may have multiple modules in the same line we must use extra-caution when
        // replacing so one module name don't try to overwrite underlying HTML tags or other
        // module names.

        var baseIndex = 0
        var resultingHTML = ''
        results.forEach(([moduleName, url]) => {
          let index = elem.innerHTML.slice(baseIndex).search(moduleName)
          if (index === -1) return // should never happen.
          let endIndex = baseIndex + index + moduleName.length
          let html = elem.innerHTML.slice(baseIndex, endIndex)
          let withLink = htmlWithLink(html, moduleName, url)

          resultingHTML += withLink
          baseIndex = endIndex
        })

        elem.innerHTML = resultingHTML + elem.innerHTML.slice(baseIndex)
      })
      .catch(() => null)
    }

    if (importing && hasImported && line.match(/[^,]$/) /* line ending without a comma */) {
      importing = false
      from_import = false
    }
  })
}

module.exports.externalurl = externalurl
function externalurl (moduleName) {
  return waitForNimbleList()
    .then(packages => {
      for (let i = 0; i < packages.length; i++) {
        let pack = packages[i]
        if (pack.name === moduleName) {
          return {
            url: pack.url,
            desc: pack.description,
            kind: 'external'
          }
        }
      }
    })
    .catch(() => null)
}

const stdlib = {'apis': 1, 'system': 1, 'threads': 1, 'channels': 1, 'locks': 1, 'rlocks': 1, 'macros': 1, 'typeinfo': 1, 'typetraits': 1, 'threadpool': 1, 'cpuinfo': 1, 'algorithm': 1, 'tables': 1, 'sets': 1, 'lists': 1, 'deques': 1, 'intsets': 1, 'critbits': 1, 'sequtils': 1, 'strutils': 1, 'strmisc': 1, 'parseutils': 1, 'strscans': 1, 'strtabs': 1, 'unicode': 1, 'encodings': 1, 'pegs': 1, 'ropes': 1, 'matchers': 1, 'subexes': 1, 'os': 1, 'osproc': 1, 'times': 1, 'dynlib': 1, 'streams': 1, 'marshal': 1, 'terminal': 1, 'memfiles': 1, 'fsmonitor': 1, 'asyncfile': 1, 'math': 1, 'complex': 1, 'rationals': 1, 'fenv': 1, 'basic2d': 1, 'basic3d': 1, 'mersenne': 1, 'random': 1, 'stats': 1, 'cgi': 1, 'scgi': 1, 'browsers': 1, 'httpserver': 1, 'httpcore': 1, 'posix': 1, 'httpclient': 1, 'smtp': 1, 'cookies': 1, 'mimetypes': 1, 'uri': 1, 'asyncdispatch': 1, 'asyncnet': 1, 'asynchttpserver': 1, 'asyncftpclient': 1, 'net': 1, 'nativesockets': 1, 'selectors': 1, 'parseopt': 1, 'parseopt2': 1, 'parsecfg': 1, 'parsexml': 1, 'parsecsv': 1, 'parsesql': 1, 'json': 1, 'lexbase': 1, 'highlite': 1, 'rst': 1, 'rstast': 1, 'rstgen': 1, 'sexp': 1, 'xmldom': 1, 'xmldomparser': 1, 'xmltree': 1, 'xmlparser': 1, 'htmlparser': 1, 'htmlgen': 1, 'hashes': 1, 'md5': 1, 'base64': 1, 'securehash': 1, 'colors': 1, 'events': 1, 'oids': 1, 'endians': 1, 'logging': 1, 'options': 1, 'future': 1, 'coro': 1, 'unittest': 1, 'dom': 1, 'asyncio': 1, 'ftpclient': 1, 'sockets': 1, 'rawsockets': 1, 're': 1, 'nre': 1, 'db_postgres': 1, 'db_mysql': 1, 'db_sqlite': 1, 'ssl': 1, 'winlean': 1, 'pcre': 1, 'iup': 1, 'postgres': 1, 'mysql': 1, 'sqlite3': 1, 'odbcsql': 1, 'libuv': 1, 'joyent_http_parser': 1, 'libcurl': 1, 'openssl': 1, 'libsvm': 1}

var requested = false
var packagesPromise
function waitForNimbleList () {
  if (requested) {
    return packagesPromise
  } else {
    requested = true
    packagesPromise =
      fetch('https://rawgit.com/nim-lang/packages/master/packages.json')
        .then(r => r.json())
    return packagesPromise
  }
}
<|endoftext|>


<commit_before>var fileUpload = require('./fileUpload')
var request = require('./request')
var modulePath = null;
var DEFAULT_OPTIONS = {
  method: 'get',
  baseUrl: '',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json;charset=UTF-8'
  },
  onRequest: function (xhr, options) {
    xhr.send(JSON.stringify(options.body))
  },
  onResponse: function (response, resolve, reject) {
    if (response.status >= 200 && response.status < 300) {
      resolve({
        status: response.status,
        result: JSON.parse(response.responseText || '""')
      })
    } else {
      reject({
        status: response.status,
        result: response.responseText
      })
    }
  }
}

function mergeWith(optionsA, optionsB) {
  return Object.keys(optionsB).reduce(function (newOptions, key) {
    if (!newOptions[key]) {
      newOptions[key] = optionsB[key]
    } else if (key === 'headers') {
      newOptions[key] = mergeWith(newOptions[key], optionsB[key] || {})
    }
    return newOptions
  }, optionsA)
}

function HttpModule (moduleOptions) {
  if (typeof moduleOptions === 'function') {
    var defaultOptions = mergeWith({}, DEFAULT_OPTIONS);
    moduleOptions = moduleOptions(defaultOptions)
  } else {
    moduleOptions = mergeWith(moduleOptions || {}, DEFAULT_OPTIONS)
  }

  return function (module, controller) {
    var requests = {}
    function createAbortablePromise(url, cb) {
      return new Promise(function (resolve, reject) {
        requests[url] = {
          resolve: resolve,
          reject: reject,
          xhr: cb(function (payload) {
            delete requests[url]
            resolve(payload)
          }, function (error) {
            delete requests[url]
            reject(error)
          })
        }
      })
    }

    function createResponse(options, resolve, reject) {
      return function (event) {
        switch (event.type) {
          case 'load':
            return options.onResponse(event.currentTarget, resolve, reject)
            break
          case 'progress':
            if (options.onProgress && event.lengthComputable) {
              if (typeof options.onProgress === 'string') {
                controller.getSignals(options.onProgress)({
                  progress: (event.loaded / event.total).toFixed(0)
                })
              } else if (options.onProgress) {
                options.onProgress({
                  progress: (event.loaded / event.total).toFixed(0)
                })
              }
            }
            break
          case 'error':
            reject({
              status: event.currentTarget.status,
              result: 'Request error'
            })
            break
          case 'abort':
            reject({
              isAborted: true
            })
            break
        }
      }
    }

    function requestService (options) {
      options = mergeWith(options, moduleOptions)

      return createAbortablePromise(options.url, function (resolve, reject) {
        return request(options, createResponse(options, resolve, reject))
      })
    }

    module.addServices({
      request: requestService,
      get: function (url, options) {
        options = options || {}
        options.url = url
        options.method = 'GET'
        return requestService(options)
      },
      post: function (url, body, options) {
        options = options || {}
        options.url = url
        options.method = 'POST'
        options.body = body
        return requestService(options)
      },
      put: function (url, body, options) {
        options = options || {}
        options.url = url
        options.method = 'PUT'
        options.body = body
        return requestService(options)
      },
      patch: function (url, body, options) {
        options = options || {}
        options.url = url
        options.method = 'PATCH'
        options.body = body
        return requestService(options)
      },
      delete: function (url, options) {
        options = options || {}
        options.url = url
        options.method = 'DELETE'
        return requestService(options)
      },
      updateOptions: function (newOptions) {
        moduleOptions = mergeWith(newOptions, moduleOptions)
      },
      abort: function (regexp) {
        var matchingUrls = Object.keys(requests).filter(function (url) {
          return Boolean(url.match(new RegExp(regexp)))
        })
        matchingUrls.forEach(function (url) {
          requests[url].xhr.abort()
        })
      }
    })
  };
};

module.exports = HttpModule;

module.exports.httpGet = function httpGet(url) {
  function action(context) {
    var services = context.services;
    var service = modulePath.reduce(function (currentService, key) {
      return currentService[key];
    }, services);

    service.get(url)
      .then(context.output.success)
      .catch(context.output.error);
  }
  action.displayName = 'httpGet (' + url + ')';
  action.async = true;
  action.outputs = ['success', 'error'];

  return action;
}

module.exports.fileUpload = fileUpload
<commit_msg>Fixed defining modulePath<commit_after>var fileUpload = require('./fileUpload')
var request = require('./request')
var modulePath = null;
var DEFAULT_OPTIONS = {
  method: 'get',
  baseUrl: '',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json;charset=UTF-8'
  },
  onRequest: function (xhr, options) {
    xhr.send(JSON.stringify(options.body))
  },
  onResponse: function (response, resolve, reject) {
    if (response.status >= 200 && response.status < 300) {
      resolve({
        status: response.status,
        result: JSON.parse(response.responseText || '""')
      })
    } else {
      reject({
        status: response.status,
        result: response.responseText
      })
    }
  }
}

function mergeWith(optionsA, optionsB) {
  return Object.keys(optionsB).reduce(function (newOptions, key) {
    if (!newOptions[key]) {
      newOptions[key] = optionsB[key]
    } else if (key === 'headers') {
      newOptions[key] = mergeWith(newOptions[key], optionsB[key] || {})
    }
    return newOptions
  }, optionsA)
}

function HttpModule (moduleOptions) {
  if (typeof moduleOptions === 'function') {
    var defaultOptions = mergeWith({}, DEFAULT_OPTIONS);
    moduleOptions = moduleOptions(defaultOptions)
  } else {
    moduleOptions = mergeWith(moduleOptions || {}, DEFAULT_OPTIONS)
  }

  return function (module, controller) {
    var requests = {}
    modulePath = module.path
    function createAbortablePromise(url, cb) {
      return new Promise(function (resolve, reject) {
        requests[url] = {
          resolve: resolve,
          reject: reject,
          xhr: cb(function (payload) {
            delete requests[url]
            resolve(payload)
          }, function (error) {
            delete requests[url]
            reject(error)
          })
        }
      })
    }

    function createResponse(options, resolve, reject) {
      return function (event) {
        switch (event.type) {
          case 'load':
            return options.onResponse(event.currentTarget, resolve, reject)
            break
          case 'progress':
            if (options.onProgress && event.lengthComputable) {
              if (typeof options.onProgress === 'string') {
                controller.getSignals(options.onProgress)({
                  progress: (event.loaded / event.total).toFixed(0)
                })
              } else if (options.onProgress) {
                options.onProgress({
                  progress: (event.loaded / event.total).toFixed(0)
                })
              }
            }
            break
          case 'error':
            reject({
              status: event.currentTarget.status,
              result: 'Request error'
            })
            break
          case 'abort':
            reject({
              isAborted: true
            })
            break
        }
      }
    }

    function requestService (options) {
      options = mergeWith(options, moduleOptions)

      return createAbortablePromise(options.url, function (resolve, reject) {
        return request(options, createResponse(options, resolve, reject))
      })
    }

    module.addServices({
      request: requestService,
      get: function (url, options) {
        options = options || {}
        options.url = url
        options.method = 'GET'
        return requestService(options)
      },
      post: function (url, body, options) {
        options = options || {}
        options.url = url
        options.method = 'POST'
        options.body = body
        return requestService(options)
      },
      put: function (url, body, options) {
        options = options || {}
        options.url = url
        options.method = 'PUT'
        options.body = body
        return requestService(options)
      },
      patch: function (url, body, options) {
        options = options || {}
        options.url = url
        options.method = 'PATCH'
        options.body = body
        return requestService(options)
      },
      delete: function (url, options) {
        options = options || {}
        options.url = url
        options.method = 'DELETE'
        return requestService(options)
      },
      updateOptions: function (newOptions) {
        moduleOptions = mergeWith(newOptions, moduleOptions)
      },
      abort: function (regexp) {
        var matchingUrls = Object.keys(requests).filter(function (url) {
          return Boolean(url.match(new RegExp(regexp)))
        })
        matchingUrls.forEach(function (url) {
          requests[url].xhr.abort()
        })
      }
    })
  };
};

module.exports = HttpModule;

module.exports.httpGet = function httpGet(url) {
  function action(context) {
    var services = context.services;
    var service = modulePath.reduce(function (currentService, key) {
      return currentService[key];
    }, services);

    service.get(url)
      .then(context.output.success)
      .catch(context.output.error);
  }
  action.displayName = 'httpGet (' + url + ')';
  action.async = true;
  action.outputs = ['success', 'error'];

  return action;
}

module.exports.fileUpload = fileUpload
<|endoftext|>


<commit_before>/**
 * Worker scanning the Steam sequential match API (GetMatchHistoryBySequenceNum) for latest matches.
 **/
var utility = require('../util/utility');
var config = require('../config');
var buildSets = require('../store/buildSets');
var db = require('../store/db');
var cassandra = config.ENABLE_CASSANDRA_MATCH_STORE_WRITE ? require('../store/cassandra') : undefined;
var redis = require('../store/redis');
var queries = require('../store/queries');
var insertMatch = queries.insertMatch;
var getData = utility.getData;
var generateJob = utility.generateJob;
var async = require('async');
var trackedPlayers;
var userPlayers;
var parallelism = config.SCANNER_PARALLELISM;
var PAGE_SIZE = 100;
buildSets(db, redis, function(err)
{
    if (err)
    {
        throw err;
    }
    start();
});

function start()
{
    if (config.START_SEQ_NUM)
    {
        redis.get("match_seq_num", function(err, result)
        {
            if (err || !result)
            {
                console.log('failed to get match_seq_num from redis, waiting to retry');
                return setTimeout(start, 10000);
            }
            //stagger
            result = Number(result);
            scanApi(result);
        });
    }
    else if (config.NODE_ENV !== "production")
    {
        //never do this in production to avoid skipping sequence number if we didn't pull .env properly
        var container = generateJob("api_history",
        {});
        getData(container.url, function(err, data)
        {
            if (err)
            {
                console.log("failed to get sequence number from webapi");
                return start();
            }
            scanApi(data.result.matches[0].match_seq_num);
        });
    }
    else
    {
        throw "failed to initialize sequence number";
    }

    function scanApi(seq_num)
    {
        queries.getSets(redis, function(err, result)
        {
            if (err)
            {
                console.log("failed to getSets from redis");
                return scanApi(seq_num);
            }
            //set local vars
            trackedPlayers = result.trackedPlayers;
            userPlayers = result.userPlayers;
            var arr = [];
            var matchBuffer = {};
            var completePages = {};
            for (var i = 0; i < parallelism; i++)
            {
                arr.push(seq_num + i * PAGE_SIZE);
            }
            var next_seq_num = seq_num;
            //async parallel calls
            async.each(arr, function(match_seq_num, cb)
            {
                var container = generateJob("api_sequence",
                {
                    start_at_match_seq_num: match_seq_num
                });
                getData(
                {
                    url: container.url,
                    delay: Number(config.SCANNER_DELAY),
                    proxyAffinityRange: parallelism,
                }, function(err, data)
                {
                    if (err)
                    {
                        return cb(err);
                    }
                    var resp = data.result && data.result.matches ? data.result.matches : [];
                    if (resp.length >= PAGE_SIZE)
                    {
                        completePages[arr.indexOf(match_seq_num)] = Math.max(next_seq_num, resp[PAGE_SIZE - 1].match_seq_num + 1);
                    }
                    console.log("[API] match_seq_num:%s, matches:%s", match_seq_num, resp.length);
                    resp.forEach(function(m)
                    {
                        matchBuffer[m.match_id] = m;
                    });
                    cb(err);
                });
            }, function(err)
            {
                if (err)
                {
                    return scanApi(seq_num);
                }
                console.log('%s distinct matches found in %s pages', Object.keys(matchBuffer).length, parallelism);
                async.each(Object.keys(matchBuffer), function(k, cb)
                {
                    var match = matchBuffer[k];
                    if (config.ENABLE_PRO_PARSING && match.leagueid)
                    {
                        //parse tournament games
                        match.parse_status = 0;
                    }
                    else if (match.players.some(function(p)
                        {
                            return (p.account_id in trackedPlayers);
                        }))
                    {
                        //queued
                        match.parse_status = 0;
                    }
                    else if (match.players.some(function(p)
                        {
                            return (config.ENABLE_INSERT_ALL_MATCHES || p.account_id in userPlayers);
                        }))
                    {
                        //skipped
                        match.parse_status = 3;
                    }
                    //check if match was previously processed
                    redis.get('scanner_insert:' + match.match_id, function(err, result)
                    {
                        //don't insert this match if we already processed it recently
                        if (match.parse_status === 0 || match.parse_status === 3 && !result)
                        {
                            insertMatch(db, redis, match,
                            {
                                type: "api",
                                origin: "scanner",
                                cassandra: cassandra,
                                userPlayers: userPlayers,
                            }, function(err)
                            {
                                if (!err)
                                {
                                    //mark with long-lived key to indicate complete (persist between restarts)
                                    redis.setex('scanner_insert:' + match.match_id, 3600 * 8, 1);
                                }
                                close(err);
                            });
                        }
                        else
                        {
                            close(err);
                        }
                    });

                    function close(err)
                    {
                        if (err)
                        {
                            console.error("failed to insert match from scanApi %s", match.match_id);
                            console.error(err);
                        }
                        return cb(err);
                    }
                }, function(err)
                {
                    if (err)
                    {
                        //something bad happened, retry this page
                        console.error(err);
                        return scanApi(seq_num);
                    }
                    else
                    {
                        //find next seq num by last contiguous seq num (completed page)
                        var next_seq_num = seq_num;
                        for (var i = 0; i < parallelism; i++)
                        {
                            if (!completePages[i])
                            {
                                break;
                            }
                            next_seq_num = completePages[i];
                        }
                        console.log("next_seq_num: %s", next_seq_num);
                        redis.set("match_seq_num", next_seq_num);
                        //completed inserting matches on this page
                        return scanApi(next_seq_num);
                    }
                });
            });
        });
    }
}
<commit_msg>refactor scanner<commit_after>/**
 * Worker scanning the Steam sequential match API (GetMatchHistoryBySequenceNum) for latest matches.
 **/
var utility = require('../util/utility');
var config = require('../config');
var buildSets = require('../store/buildSets');
var db = require('../store/db');
var cassandra = config.ENABLE_CASSANDRA_MATCH_STORE_WRITE ? require('../store/cassandra') : undefined;
var redis = require('../store/redis');
var queries = require('../store/queries');
var insertMatch = queries.insertMatch;
var getData = utility.getData;
var generateJob = utility.generateJob;
var async = require('async');
var trackedPlayers;
var userPlayers;
var parallelism = config.SCANNER_PARALLELISM;
var PAGE_SIZE = 100;
buildSets(db, redis, function(err)
{
    if (err)
    {
        throw err;
    }
    start();
});

function start()
{
    if (config.START_SEQ_NUM)
    {
        redis.get("match_seq_num", function(err, result)
        {
            if (err || !result)
            {
                console.log('failed to get match_seq_num from redis, waiting to retry');
                return setTimeout(start, 10000);
            }
            //stagger
            result = Number(result);
            scanApi(result);
        });
    }
    else if (config.NODE_ENV !== "production")
    {
        //never do this in production to avoid skipping sequence number if we didn't pull .env properly
        var container = generateJob("api_history",
        {});
        getData(container.url, function(err, data)
        {
            if (err)
            {
                console.log("failed to get sequence number from webapi");
                return start();
            }
            scanApi(data.result.matches[0].match_seq_num);
        });
    }
    else
    {
        throw "failed to initialize sequence number";
    }

    function scanApi(seq_num)
    {
        queries.getSets(redis, function(err, result)
        {
            if (err)
            {
                console.log("failed to getSets from redis");
                return scanApi(seq_num);
            }
            //set local vars
            trackedPlayers = result.trackedPlayers;
            userPlayers = result.userPlayers;
            var arr = [];
            var matchBuffer = {};
            var completePages = {};
            for (var i = 0; i < parallelism; i++)
            {
                arr.push(seq_num + i * PAGE_SIZE);
            }
            var next_seq_num = seq_num;
            //async parallel calls
            async.each(arr, processPage, finishPageSet);

            function processPage(match_seq_num, cb)
            {
                var container = generateJob("api_sequence",
                {
                    start_at_match_seq_num: match_seq_num
                });
                getData(
                {
                    url: container.url,
                    delay: Number(config.SCANNER_DELAY),
                    proxyAffinityRange: parallelism,
                }, function(err, data)
                {
                    if (err)
                    {
                        return cb(err);
                    }
                    var resp = data.result && data.result.matches ? data.result.matches : [];
                    if (resp.length >= PAGE_SIZE)
                    {
                        completePages[arr.indexOf(match_seq_num)] = Math.max(next_seq_num, resp[PAGE_SIZE - 1].match_seq_num + 1);
                    }
                    console.log("[API] match_seq_num:%s, matches:%s", match_seq_num, resp.length);
                    async.each(resp, processMatch, cb);
                });
            }

            function processMatch(match, cb)
            {
                if (config.ENABLE_PRO_PARSING && match.leagueid)
                {
                    //parse tournament games
                    match.parse_status = 0;
                }
                else if (match.players.some(function(p)
                    {
                        return (p.account_id in trackedPlayers);
                    }))
                {
                    //queued
                    match.parse_status = 0;
                }
                else if (match.players.some(function(p)
                    {
                        return (config.ENABLE_INSERT_ALL_MATCHES || p.account_id in userPlayers);
                    }))
                {
                    //skipped
                    match.parse_status = 3;
                }
                //check if match was previously processed
                redis.get('scanner_insert:' + match.match_id, function(err, result)
                {
                    if (err)
                    {
                        return finishMatch(err);
                    }
                    //don't insert this match if we already processed it recently
                    //deduplicate matches in this page set
                    if (match.parse_status === 0 || match.parse_status === 3 && !result && !matchBuffer[match.match_id])
                    {
                        matchBuffer[match.match_id] = 1;
                        insertMatch(db, redis, match,
                        {
                            type: "api",
                            origin: "scanner",
                            cassandra: cassandra,
                            userPlayers: userPlayers,
                        }, function(err)
                        {
                            if (!err)
                            {
                                //mark with long-lived key to indicate complete (persist between restarts)
                                redis.setex('scanner_insert:' + match.match_id, 3600 * 8, 1);
                            }
                            finishMatch(err);
                        });
                    }
                    else
                    {
                        finishMatch(err);
                    }
                });

                function finishMatch(err)
                {
                    if (err)
                    {
                        console.error("failed to insert match from scanApi %s", match.match_id);
                        console.error(err);
                    }
                    return cb(err);
                }
            }

            function finishPageSet(err)
            {
                if (err)
                {
                    //something bad happened, retry this page
                    console.error(err);
                    return scanApi(seq_num);
                }
                else
                {
                    //find next seq num by last contiguous seq num (completed page)
                    var next_seq_num = seq_num;
                    for (var i = 0; i < parallelism; i++)
                    {
                        if (!completePages[i])
                        {
                            break;
                        }
                        next_seq_num = completePages[i];
                    }
                    console.log("next_seq_num: %s", next_seq_num);
                    redis.set("match_seq_num", next_seq_num);
                    //completed inserting matches on this page
                    return scanApi(next_seq_num);
                }
            }
        });
    }
}
<|endoftext|>


<commit_before>/**
 * Pattern for Redactor
 * Copyright 2013-2014 Simplon B.V. - Wichert Akkerman
 */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define([
            "jquery",
            "underscore",
            "pat-registry",
            "pat-utils",
            "pat-parser",
            "pat-pluggable",
            "redactor",
            ], function ($, _, registry, utils, Parser, pluggablePattern, Redactor) {
                return factory.apply(this, arguments);
        });
    } else {
        factory(root.jQuery, _, root.patterns, utils, root.patterns.Parser, pluggablePattern, Redactor);
    }
}(this, function($, _, registry, utils, Parser, pluggablePattern, Redactor) {
    var parser = new Parser('redactor');

    parser.add_argument('toolbar-type', 'standard', ['standard', 'fixed', 'air']);
    parser.add_argument('toolbar-external', null);
    parser.add_argument('toolbar-fixed-target', null);
    parser.add_argument('buttons',
        ['html', 'formatting', 'bold', 'italic', 'unordered-list', 'ordered-list', 'outdent', 'indent', 'alignment', 'image', 'video', 'link', 'horizontal-rule', 'table'],
        ['html', 'formatting', 'bold', 'italic', 'unordered-list', 'ordered-list', 'outdent', 'indent', 'alignment', 'image', 'video', 'link', 'horizontal-rule', 'table'],
        true);
    parser.add_argument('air-buttons', [],
        ['formatting', 'bold', 'italic', 'unordered-list', 'ordered-list', 'image', 'video', 'link', 'horizontal-rule'],
        true);
    parser.add_argument('formatting',
        ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5'],
        ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5'],
        true);
    parser.add_argument('allowed-tags', [], [], true);
    parser.add_argument('denied-tags', [], [], true);
    parser.add_argument('min-height', 0);
    parser.add_argument('file-upload', undefined);
    parser.add_argument('image-upload', undefined);
    parser.add_argument('image-get-json', undefined);
    parser.add_argument('buttonSource', false);

    // XXX: Deprecated
    parser.add_argument('fileupload', undefined);
    parser.add_argument('imageupload', undefined);
    parser.add_argument('imagegetjson', undefined);

    var redactor = pluggablePattern.extend({
        name: 'redactor',
        trigger: '.pat-redactor',
        plugins: {},

        init: function($el, opts) {
            var i, poptions = parser.parse($el, opts), options = {};
            if ($.browser.msie && parseInt($.browser.version, 10) === 8) {
                options.rangy = true;
            }

            switch (poptions.toolbar.type) {
                case 'air':
                    options.air = true;
                    if (poptions.airButtons.length !==0) {
                        options.airButtons = poptions.airButtons;
                    }
                    break;
                case 'fixed':
                    options.toolbarFixed = true;
                    if (poptions.toolbar['fixed-target']) {
                        options.toolbarFixedTarget = poptions.toolbar['fixed-target'];
                    }
                    break;
                default:
                    break;
            }
            if (poptions.toolbar.external) {
                options.toolbarExternal = poptions.toolbar.external;
            }
            // Remove dashes from button names, per redactor convention
            for (i=0; i< poptions.buttons.length; i++) {
                poptions.buttons[i] = poptions.buttons[i].replace('-', '');
            }
            options.buttons = poptions.buttons;

            _.extend(options,
                _.pick(poptions,
                    ['minHeight', 'fileUpload', 'imageGetJson', 'deniedTags', 'allowedTags', 'formatting', 'buttonSource']
                )
            );
            // XXX Deprecated (see above where parser's arguments are added)
            if (poptions.imageupload) {
                options.imageUpload = poptions.imageupload;
            }
            if (poptions.imagegetjson) {
                options.imageGetJson = poptions.imagegetjson;
            }
            // Until here
            $el.redactor(this.initializePlugins(options)[0]);
        }
    });
    registry.register(redactor);
    return redactor;
}));
<commit_msg>Add image-resize boolean and merge.<commit_after>/**
 * Pattern for Redactor
 * Copyright 2013-2014 Simplon B.V. - Wichert Akkerman
 */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define([
            "jquery",
            "underscore",
            "pat-registry",
            "pat-utils",
            "pat-parser",
            "pat-pluggable",
            "redactor",
            ], function ($, _, registry, utils, Parser, pluggablePattern, Redactor) {
                return factory.apply(this, arguments);
        });
    } else {
        factory(root.jQuery, _, root.patterns, utils, root.patterns.Parser, pluggablePattern, Redactor);
    }
}(this, function($, _, registry, utils, Parser, pluggablePattern, Redactor) {
    var parser = new Parser('redactor');

    parser.add_argument('toolbar-type', 'standard', ['standard', 'fixed', 'air']);
    parser.add_argument('toolbar-external', null);
    parser.add_argument('toolbar-fixed-target', null);
    parser.add_argument('buttons',
        ['html', 'formatting', 'bold', 'italic', 'unordered-list', 'ordered-list', 'outdent', 'indent', 'alignment', 'image', 'video', 'link', 'horizontal-rule', 'table'],
        ['html', 'formatting', 'bold', 'italic', 'unordered-list', 'ordered-list', 'outdent', 'indent', 'alignment', 'image', 'video', 'link', 'horizontal-rule', 'table'],
        true);
    parser.add_argument('air-buttons',
        [],
        ['formatting', 'bold', 'italic', 'unordered-list', 'ordered-list', 'image', 'video', 'link', 'horizontal-rule'],
        true);
    parser.add_argument('formatting',
        ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5'],
        ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5'],
        true);
    parser.add_argument('allowed-tags', [], [], true);
    parser.add_argument('denied-tags', [], [], true);
    parser.add_argument('min-height', 0);
    parser.add_argument('file-upload', undefined);
    parser.add_argument('image-upload', undefined);
    parser.add_argument('image-resizable', true);
    parser.add_argument('image-get-json', undefined);
    parser.add_argument('show-source-button', false);

    // XXX: Deprecated
    parser.add_argument('fileupload', undefined);
    parser.add_argument('imageupload', undefined);
    parser.add_argument('imagegetjson', undefined);

    var redactor = pluggablePattern.extend({
        name: 'redactor',
        trigger: '.pat-redactor',
        plugins: {},

        init: function($el, opts) {
            var i, poptions = parser.parse($el, opts), options = {};
            if ($.browser.msie && parseInt($.browser.version, 10) === 8) {
                options.rangy = true;
            }

            switch (poptions.toolbar.type) {
                case 'air':
                    options.air = true;
                    if (poptions.airButtons.length !==0) {
                        options.airButtons = poptions.airButtons;
                    }
                    break;
                case 'fixed':
                    options.toolbarFixed = true;
                    if (poptions.toolbar['fixed-target']) {
                        options.toolbarFixedTarget = poptions.toolbar['fixed-target'];
                    }
                    break;
                default:
                    break;
            }
            if (poptions.toolbar.external) {
                options.toolbarExternal = poptions.toolbar.external;
            }
            // Remove dashes from button names, per redactor convention
            for (i=0; i< poptions.buttons.length; i++) {
                poptions.buttons[i] = poptions.buttons[i].replace('-', '');
            }
            options.buttons = poptions.buttons;
            options.imageResizable = poptions.image.resizable;
            options.buttonsSource = poptions.showSourceButton;
            _.extend(options,
                _.pick(poptions, [
                    'minHeight',
                    'fileUpload',
                    'imageGetJson',
                    'deniedTags',
                    'allowedTags',
                    'formatting',
                ])
            );
            // XXX Deprecated (see above where parser's arguments are added)
            if (poptions.imageupload) {
                options.imageUpload = poptions.imageupload;
            }
            if (poptions.imagegetjson) {
                options.imageGetJson = poptions.imagegetjson;
            }
            // Until here
            $el.redactor(this.initializePlugins(options)[0]);
        }
    });
    registry.register(redactor);
    return redactor;
}));
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');

function guardedRequire(fileName) {
    try {
        return require(fileName);
    } catch (e) {
        if (e.code === 'MODULE_NOT_FOUND') {
            return false;
        }

        throw e;
    }
}

function getModule(name, obj, err) {
    let mod;

    for (const path in obj) {
        if (fs.existsSync(path)) {
            mod = guardedRequire(path);
            if (!mod) continue;
        }
    }

    // check if its a node module
    if (!mod) {
        mod = guardedRequire(name);
    }

    // Still not found check for a connector.
    if (!mod) {
        mod = guardedRequire(`terafoundation_${name}_connector`);
    }

    if (!mod) {
        throw new Error(err);
    }

    return mod;
}

module.exports = {
    getModule
};
<commit_msg>Support connectors with dashes and namespaces, resolves #960<commit_after>'use strict';

const fs = require('fs');

function guardedRequire(fileName) {
    try {
        return require(fileName);
    } catch (e) {
        if (e.code === 'MODULE_NOT_FOUND') {
            return false;
        }

        throw e;
    }
}

function getModule(name, obj, err) {
    let mod;

    for (const path in obj) {
        if (fs.existsSync(path)) {
            mod = guardedRequire(path);
            if (!mod) continue;
        }
    }

    // check if its a node module
    if (!mod) {
        mod = guardedRequire(name);
    }

    // Still not found check for a connector with underscores
    if (!mod) {
        mod = guardedRequire(`terafoundation_${name}_connector`);
    }

    // Still not found check for a connector with dashes
    if (!mod) {
        mod = guardedRequire(`terafoundation-${name}-connector`);
    }

    // Stil not found check for the @terascope namespace
    if (!mod) {
        mod = guardedRequire(`@terascope/${name}`);
    }

    if (!mod) {
        throw new Error(err);
    }

    return mod;
}

module.exports = {
    getModule
};
<|endoftext|>


<commit_before>(function() {
  var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';

  window.URL = (window.URL || window.webkitURL);

  var body = document.body,
      emptySvg;

  var prefix = {
    xmlns: "http://www.w3.org/2000/xmlns/",
    xlink: "http://www.w3.org/1999/xlink",
    svg: "http://www.w3.org/2000/svg"
  };

  initialize();

  function initialize() {
    var documents = [window.document],
        SVGSources = [];
        iframes = document.querySelectorAll("iframe");

    // add empty svg element
    var emptySvg = window.document.createElementNS(prefix.svg, 'svg');
    window.document.body.appendChild(emptySvg);
    var emptySvgDeclarationComputed = getComputedStyle(emptySvg);

    [].forEach.call(iframes, function(el) {
      try {
        if (el.contentDocument) {
          documents.push(el.contentDocument);
        }
      } catch(err) {
        console.log(err);
      }
    });

    documents.forEach(function(doc) {
      var newSources = getSources(doc, emptySvgDeclarationComputed);
      // because of prototype on NYT pages
      for (var i = 0; i < newSources.length; i++) {
        SVGSources.push(newSources[i]);
      }
    });
    if (SVGSources.length > 1) {
      createPopover(SVGSources);
    } else if (SVGSources.length > 0) {
      download(SVGSources[0]);
    } else {
      alert("The Crowbar couldn’t find any SVG nodes.");
    }

  }

  function createPopover(sources) {
    cleanup();

    sources.forEach(function(s1) {
      sources.forEach(function(s2) {
        if (s1 !== s2) {
          if ((Math.abs(s1.top - s2.top) < 38) && (Math.abs(s1.left - s2.left) < 38)) {
            s2.top += 38;
            s2.left += 38;
          }
        }
      });
    });

    var buttonsContainer = document.createElement("div");
    body.appendChild(buttonsContainer);

    buttonsContainer.setAttribute("class", "svg-crowbar");
    buttonsContainer.style["z-index"] = 1e7;
    buttonsContainer.style["position"] = "absolute";
    buttonsContainer.style["top"] = 0;
    buttonsContainer.style["left"] = 0;

    var background = document.createElement("div");
    body.appendChild(background);

    background.setAttribute("class", "svg-crowbar");
    background.style["background"] = "rgba(255, 255, 255, 0.7)";
    background.style["position"] = "fixed";
    background.style["left"] = 0;
    background.style["top"] = 0;
    background.style["width"] = "100%";
    background.style["height"] = "100%";

    sources.forEach(function(d, i) {
      var buttonWrapper = document.createElement("div");
      buttonsContainer.appendChild(buttonWrapper);
      buttonWrapper.setAttribute("class", "svg-crowbar");
      buttonWrapper.style["position"] = "absolute";
      buttonWrapper.style["top"] = (d.top + document.body.scrollTop) + "px";
      buttonWrapper.style["left"] = (document.body.scrollLeft + d.left) + "px";
      buttonWrapper.style["padding"] = "4px";
      buttonWrapper.style["border-radius"] = "3px";
      buttonWrapper.style["color"] = "white";
      buttonWrapper.style["text-align"] = "center";
      buttonWrapper.style["font-family"] = "'Helvetica Neue'";
      buttonWrapper.style["background"] = "rgba(0, 0, 0, 0.8)";
      buttonWrapper.style["box-shadow"] = "0px 4px 18px rgba(0, 0, 0, 0.4)";
      buttonWrapper.style["cursor"] = "move";
      buttonWrapper.textContent =  "SVG #" + i + ": " + (d.id ? "#" + d.id : "") + (d.class ? "." + d.class : "");

      var button = document.createElement("button");
      buttonWrapper.appendChild(button);
      button.setAttribute("data-source-id", i);
      button.style["width"] = "150px";
      button.style["font-size"] = "12px";
      button.style["line-height"] = "1.4em";
      button.style["margin"] = "5px 0 0 0";
      button.textContent = "Download";

      button.onclick = function(el) {
        // console.log(el, d, i, sources)
        download(d);
      };

    });

  }

  function cleanup() {
    var crowbarElements = document.querySelectorAll(".svg-crowbar");

    [].forEach.call(crowbarElements, function(el) {
      el.parentNode.removeChild(el);
    });
  }

  function getSources(doc, emptySvgDeclarationComputed) {
    var svgInfo = [],
        svgs = doc.querySelectorAll("svg");

    [].forEach.call(svgs, function (svg) {

      svg.setAttribute("version", "1.1");

      // removing attributes so they aren't doubled up
      svg.removeAttribute("xmlns");
      svg.removeAttribute("xlink");

      // These are needed for the svg
      if (!svg.hasAttributeNS(prefix.xmlns, "xmlns")) {
        svg.setAttributeNS(prefix.xmlns, "xmlns", prefix.svg);
      }

      if (!svg.hasAttributeNS(prefix.xmlns, "xmlns:xlink")) {
        svg.setAttributeNS(prefix.xmlns, "xmlns:xlink", prefix.xlink);
      }

      setInlineStyles(svg, emptySvgDeclarationComputed);

      var source = (new XMLSerializer()).serializeToString(svg);
      var rect = svg.getBoundingClientRect();
      svgInfo.push({
        top: rect.top,
        left: rect.left,
        width: rect.width,
        height: rect.height,
        class: svg.getAttribute("class"),
        id: svg.getAttribute("id"),
        childElementCount: svg.childElementCount,
        source: [doctype + source]
      });
    });
    return svgInfo;
  }

  function download(source) {
    var filename = "untitled";

    if (source.id) {
      filename = source.id;
    } else if (source.class) {
      filename = source.class;
    } else if (window.document.title) {
      filename = window.document.title.replace(/[^a-z0-9]/gi, '-').toLowerCase();
    }

    var url = window.URL.createObjectURL(new Blob(source.source, { "type" : "text\/xml" }));

    var a = document.createElement("a");
    body.appendChild(a);
    a.setAttribute("class", "svg-crowbar");
    a.setAttribute("download", filename + ".svg");
    a.setAttribute("href", url);
    a.style["display"] = "none";
    a.click();

    setTimeout(function() {
      window.URL.revokeObjectURL(url);
    }, 10);
  }

  function setInlineStyles(svg, emptySvgDeclarationComputed) {

    function explicitlySetStyle (element) {
      var cSSStyleDeclarationComputed = getComputedStyle(element);
      var i, len, key, value;
      var computedStyleStr = "";
      for (i=0, len=cSSStyleDeclarationComputed.length; i<len; i++) {
        key=cSSStyleDeclarationComputed[i];
        value=cSSStyleDeclarationComputed.getPropertyValue(key);
        if (value!==emptySvgDeclarationComputed.getPropertyValue(key) && key != 'font-family') {
          computedStyleStr+=key+":"+value+";";
        }
      }
      if (element.tagName == 'text' || element.tagName == 'tspan') {
        computedStyleStr += 'font-size:'+cSSStyleDeclarationComputed.fontSize+';';
        var fw = cSSStyleDeclarationComputed.fontWeight,
            ff = 'NYTFranklin' + (fw == 300 || fw == 'light' ? 'Light' : fw > 400 || fw == 'bold' ? 'Bold' : 'Medium');
        computedStyleStr += 'font-family:'+ff+';';
      }
      element.setAttribute('style', computedStyleStr);
    }
    function traverse(obj){
      var tree = [];
      tree.push(obj);
      visit(obj);
      function visit(node) {
        if (node && node.hasChildNodes()) {
          var child = node.firstChild;
          while (child) {
            if (child.nodeType === 1 && child.nodeName != 'SCRIPT'){
              tree.push(child);
              visit(child);
            }
            child = child.nextSibling;
          }
        }
      }
      return tree;
    }
    // hardcode computed css styles inside svg
    var allElements = traverse(svg);
    var i = allElements.length;
    while (i--){
      explicitlySetStyle(allElements[i]);
    }
  }

})();
<commit_msg>restored old version<commit_after>(function() {
  var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';

  window.URL = (window.URL || window.webkitURL);

  var body = document.body;

  var prefix = {
    xmlns: "http://www.w3.org/2000/xmlns/",
    xlink: "http://www.w3.org/1999/xlink",
    svg: "http://www.w3.org/2000/svg"
  }

  initialize();

  function initialize() {
    var documents = [window.document],
        SVGSources = [];
        iframes = document.querySelectorAll("iframe");

    [].forEach.call(iframes, function(el) {
      try {
        if (el.contentDocument) {
          documents.push(el.contentDocument);
        }
      } catch(err) {
        console.log(err)
      }
    });

    documents.forEach(function(doc) {
      var styles = getStyles(doc);
      var newSources = getSources(doc, styles);
      // because of prototype on NYT pages
      for (var i = 0; i < newSources.length; i++) {
        SVGSources.push(newSources[i]);
      };
    })
    if (SVGSources.length > 1) {
      createPopover(SVGSources);
    } else if (SVGSources.length > 0) {
      download(SVGSources[0]);
    } else {
      alert("The Crowbar couldn’t find any SVG nodes.");
    }
  }

  function createPopover(sources) {
    cleanup();

    sources.forEach(function(s1) {
      sources.forEach(function(s2) {
        if (s1 !== s2) {
          if ((Math.abs(s1.top - s2.top) < 38) && (Math.abs(s1.left - s2.left) < 38)) {
            s2.top += 38;
            s2.left += 38;
          }
        }
      })
    });

    var buttonsContainer = document.createElement("div");
    body.appendChild(buttonsContainer);

    buttonsContainer.setAttribute("class", "svg-crowbar");
    buttonsContainer.style["z-index"] = 1e7;
    buttonsContainer.style["position"] = "absolute";
    buttonsContainer.style["top"] = 0;
    buttonsContainer.style["left"] = 0;

    var background = document.createElement("div");
    body.appendChild(background);

    background.setAttribute("class", "svg-crowbar");
    background.style["background"] = "rgba(255, 255, 255, 0.7)";
    background.style["position"] = "fixed";
    background.style["left"] = 0;
    background.style["top"] = 0;
    background.style["width"] = "100%";
    background.style["height"] = "100%";

    sources.forEach(function(d, i) {
      var buttonWrapper = document.createElement("div");
      buttonsContainer.appendChild(buttonWrapper);
      buttonWrapper.setAttribute("class", "svg-crowbar");
      buttonWrapper.style["position"] = "absolute";
      buttonWrapper.style["top"] = (d.top + document.body.scrollTop) + "px";
      buttonWrapper.style["left"] = (document.body.scrollLeft + d.left) + "px";
      buttonWrapper.style["padding"] = "4px";
      buttonWrapper.style["border-radius"] = "3px";
      buttonWrapper.style["color"] = "white";
      buttonWrapper.style["text-align"] = "center";
      buttonWrapper.style["font-family"] = "'Helvetica Neue'";
      buttonWrapper.style["background"] = "rgba(0, 0, 0, 0.8)";
      buttonWrapper.style["box-shadow"] = "0px 4px 18px rgba(0, 0, 0, 0.4)";
      buttonWrapper.style["cursor"] = "move";
      buttonWrapper.textContent =  "SVG #" + i + ": " + (d.id ? "#" + d.id : "") + (d.class ? "." + d.class : "");

      var button = document.createElement("button");
      buttonWrapper.appendChild(button);
      button.setAttribute("data-source-id", i)
      button.style["width"] = "150px";
      button.style["font-size"] = "12px";
      button.style["line-height"] = "1.4em";
      button.style["margin"] = "5px 0 0 0";
      button.textContent = "Download";

      button.onclick = function(el) {
        // console.log(el, d, i, sources)
        download(d);
      };

    });

  }

  function cleanup() {
    var crowbarElements = document.querySelectorAll(".svg-crowbar");

    [].forEach.call(crowbarElements, function(el) {
      el.parentNode.removeChild(el);
    });
  }

  function getSources(doc, styles) {
    var svgInfo = [],
        svgs = doc.querySelectorAll("svg");

    styles = (styles === undefined) ? "" : styles;

    [].forEach.call(svgs, function (svg) {

      svg.setAttribute("version", "1.1");

      var defsEl = document.createElement("defs");
      svg.insertBefore(defsEl, svg.firstChild); //TODO   .insert("defs", ":first-child")
      // defsEl.setAttribute("class", "svg-crowbar");

      var styleEl = document.createElement("style")
      defsEl.appendChild(styleEl);
      styleEl.setAttribute("type", "text/css");

      // removing attributes so they aren't doubled up
      svg.removeAttribute("xmlns");
      svg.removeAttribute("xlink");

      // These are needed for the svg
      if (!svg.hasAttributeNS(prefix.xmlns, "xmlns")) {
        svg.setAttributeNS(prefix.xmlns, "xmlns", prefix.svg);
      }

      if (!svg.hasAttributeNS(prefix.xmlns, "xmlns:xlink")) {
        svg.setAttributeNS(prefix.xmlns, "xmlns:xlink", prefix.xlink);
      }

      var source = (new XMLSerializer()).serializeToString(svg).replace('</style>', '<![CDATA[' + styles + ']]></style>');
      var rect = svg.getBoundingClientRect();
      svgInfo.push({
        top: rect.top,
        left: rect.left,
        width: rect.width,
        height: rect.height,
        class: svg.getAttribute("class"),
        id: svg.getAttribute("id"),
        childElementCount: svg.childElementCount,
        source: [doctype + source]
      });
    });
    return svgInfo;
  }

  function download(source) {
    var filename = "untitled";

    if (source.id) {
      filename = source.id;
    } else if (source.class) {
      filename = source.class;
    } else if (window.document.title) {
      filename = window.document.title.replace(/[^a-z0-9]/gi, '-').toLowerCase();
    }

    var url = window.URL.createObjectURL(new Blob(source.source, { "type" : "text\/xml" }));

    var a = document.createElement("a");
    body.appendChild(a);
    a.setAttribute("class", "svg-crowbar");
    a.setAttribute("download", filename + ".svg");
    a.setAttribute("href", url);
    a.style["display"] = "none";
    a.click();

    setTimeout(function() {
      window.URL.revokeObjectURL(url);
    }, 10);
  }

  function getStyles(doc) {
    var styles = "",
        styleSheets = doc.styleSheets;

    if (styleSheets) {
      for (var i = 0; i < styleSheets.length; i++) {
        processStyleSheet(styleSheets[i]);
      }
    }

    function processStyleSheet(ss) {
      if (ss.cssRules) {
        for (var i = 0; i < ss.cssRules.length; i++) {
          var rule = ss.cssRules[i];
          if (rule.type === 3) {
            // Import Rule
            processStyleSheet(rule.styleSheet);
          } else {
            // hack for illustrator crashing on descendent selectors
            if (rule.selectorText) {
              if (rule.selectorText.indexOf(">") === -1) {
                styles += "\n" + rule.cssText;
              }
            }
          }
        }
      }
    }
    return styles;
  }

})();<|endoftext|>


<commit_before>(function() {
  "use strict";

  App.register('component').enter(function() {

    var template = '
<slot></slot>
';

    Vue.component('vue-transition', {
      props: {
        transitionName: {
          type: String,
          default: "v-fade-up"
        }
      },
      template: template,
      data: function() {
        return {
          pageTransitionFinished: false
        }
      },
      ready: function() {
        var self = this;
        this.$nextTick(function() {
          self.pageTransitionFinished = true;
        });
      }
    });
  });
})();
<commit_msg>Update transition.js<commit_after>(function() {
  "use strict";

  var template = '
<slot></slot>
';

  App.vue.components.vueTransition = Vue.extend({
    props: {
      transitionName: {
        type: String,
        default: "v-fade-up"
      }
    },
    template: template,
    data: function() {
      return {
        pageTransitionFinished: false
      }
    },
    ready: function() {
      var self = this;
      this.$nextTick(function() {
        self.pageTransitionFinished = true;
      });
    }
  });
})();
<|endoftext|>


<commit_before>import piwikTracker from '../../shared/services/piwik-tracker/piwik-tracker';

/** Set Piwik variable */
const actionsToPiwik = {
  TOGGLE_MAP_OVERLAY: (tracking) => [
    'trackEvent',
    'kaartlaag',
    tracking.category.toLowerCase().replace(/[: ][ ]*/g, '_'),
    tracking.title
  ],
  SET_MAP_BASE_LAYER: (tracking) => [
    'trackEvent',
    'achtergrond',
    (tracking.startsWith('lf') ? 'luchtfoto' : 'topografie'),
    tracking
  ]
};

/** Execute Piwik actions */
const piwikMiddleware = () => (next) => (action) => {
  const nextAction = action;

  const actionMap = actionsToPiwik[action.type];

  if (actionMap) {
    const { tracking } = action.meta;
    piwikTracker(actionMap(tracking));
  }

  next(nextAction);
};

export default piwikMiddleware;
<commit_msg>Fix case where mapOverlay is toggled by panorama images<commit_after>import piwikTracker from '../../shared/services/piwik-tracker/piwik-tracker';

/** Set Piwik variable */
const actionsToPiwik = {
  TOGGLE_MAP_OVERLAY: (tracking) => [
    'trackEvent',
    'kaartlaag',
    (tracking.category) ? tracking.category.toLowerCase().replace(/[: ][ ]*/g, '_') : 'panorama',
    tracking.title
  ],
  SET_MAP_BASE_LAYER: (tracking) => [
    'trackEvent',
    'achtergrond',
    (tracking.startsWith('lf') ? 'luchtfoto' : 'topografie'),
    tracking
  ]
};

/** Execute Piwik actions */
const piwikMiddleware = () => (next) => (action) => {
  const nextAction = action;

  const actionMap = actionsToPiwik[action.type];

  if (actionMap) {
    const { tracking } = action.meta;

    if (tracking) {
      piwikTracker(actionMap(tracking));
    }
  }

  next(nextAction);
};

export default piwikMiddleware;
<|endoftext|>