<commit_before>const {CONTEXT, GRAPH, ID, TYPE, VALUE, LANGUAGE, LIST, VOCAB, BASE} =
  require('../jsonld/keywords')

module.exports = {serialize}

function serialize (data, out = process.stdout, {
  context = null,
  baseIri = null,
  settings = {
    indentChars: '  ',
    upcaseKeywords: false,
    useGraphKeyword: true,
    spaceBeforeSemicolon: true,
    predicateRepeatNewLine: true,
    bracketStartNewLine: false,
    bracketEndNewLine: false,
    listItemNewLine: true,
    prologueEndLine: 1,
    separatorLines: 1
  }
} = {}) {
  let state = new SerializerState(context, out, settings)
  state.serialize(data)
}

class SerializerState {
  constructor (context, outstream, settings, parent = null) {
    this.outstream = outstream || parent.outstream
    this.initContext(context)
    this.parent = parent
    this.settings = parent ? parent.settings : settings
    let kw = it => this.settings.upcaseKeywords ? it.toUpperCase() : it
    this.prefixKeyword = kw('prefix')
    this.baseKeyword = kw('base')
    if (this.settings.useGraphKeyword) {
      this.graphKeyword = kw('graph')
    }
    this.uniqueBNodeSuffix = ''
  }

  initContext (context) {
    this.keys = {
      id: "@id",
      value: '@value',
      type: '@type',
      lang: '@language',
      graph: '@graph',
      list: '@list'
    }
    this.prefixes = {}

    if (context == null) {
      this.context = {}
    }
    else {
      for (let key in this.context) {
        throw 'context already initialized'
      }
    }
    let ctx = {}
    // TODO: merge arrays, deref uri:s ...
    if (Array.isArray(context)) {
      for (let item of context) {
        Object.assign(ctx, item)
      }
    } else if (typeof context === 'object') {
        Object.assign(ctx, context)
    }
    this.context = ctx
    this.prefixes = collectPrefixes(context)
  }

  serialize (data) {
    if (data[CONTEXT]) {
      this.initContext(data[CONTEXT])
    }
    this.prelude()
    let graph = Array.isArray(data) ? data : data[GRAPH]
    if (graph) {
      for (let node of graph) {
        this.objectToTurtle(node)
      }
    } else {
      this.objectToTurtle(data)
    }
  }

  prelude () {
    for (let k in this.prefixes) {
      let v = this.prefixes[k]
      if (k === BASE) {
        this.writeBase(v)
      } else {
        this.writeln(`${this.prefixKeyword} ${k}: <${v}>`)
      }
    }
    if (this.base) {
      this.writeBase(this.base)
    }
    if (this.settings.prologueEndLine > 1) {
      this.writeln()
    }
  }

  writeBase (iri) {
    this.writeln(`${this.baseKeyword} <${iri}>`)
  }

  isListContainer (term) {
    if (this.context == null) return false
    return typeof this.context[term] === 'object' &&
      this.context[term]['@container'] == '@list'
  }

  isLangContainer (term) {
    if (this.context == null) return false
    return typeof this.context[term] === 'object' &&
      this.context[term]['@container'] == '@language'
  }

  objectToTrig (iri, graph) {
    this.writeln()
    if (this.graphKeyword) {
        this.write(`${this.graphKeyword} `)
    }
    this.writeln(`${this.refRepr(iri)} {`)
    if (!Array.isArray(graph)) graph = [graph]
    for (let node of graph) {
      this.objectToTurtle(node, 0, GRAPH)
    }
    this.writeln()
    this.writeln("}")
  }

  objectToTurtle (obj, depth = 0, viaKey = null) {
    if (depth > 0 && obj[CONTEXT]) {
      // TODO: use new SerializerState(node[CONTEXT], null, null, state)
      throw 'Nested context not supported yet'
    }

    if (this.isLangContainer(viaKey) && typeof obj === 'object') {
      let first = true
      for (let lang in obj) {
        let value = obj[lang]
          if (!first) this.write(' , ')
        this.toLiteral(
          { [this.keys.value]: value, [this.keys.lang]: lang },
          viaKey)
        first = false
      }
      return []
    }

    if (!(typeof obj === 'object') || obj[this.keys.value]) {
      this.toLiteral(obj, viaKey)
      return []
    }

    let explicitList = obj[LIST]

    if (this.isListContainer(viaKey)) {
      obj = { [this.keys.list]: obj }
    }

    let s = obj[this.keys.id]

    let isList = obj[LIST]
    let startedList = isList

    if (obj[this.keys.graph]) {
      this.objectToTrig(s, obj[this.keys.graph])
      return []
    }

    if (explicitList) {
      this.write('( ')
    }

    let inGraph = viaKey === GRAPH ? 1 : 0

    if (s != null && this.hasKeys(obj, 2)) {
      if (depth === 0) {
        this.writeln()
      }
      if (inGraph) this.write(this.getIndent(0))
      this.write(this.refRepr(s))
    } else if (depth > 0) {
      if (!isList) {
        depth++
        this.write("[")
      }
    } else {
      if (obj[this.keys.graph]) {
        /* TODO:
        for (let key in obj) {
          if (key[0] != '@') {
            // TODO: this is the default graph, described...
            this.write('[]')
            break
          }
        }
        */
      } else {
        return []
      }
    }

    let indent = this.getIndent(depth + inGraph)

    let topObjects = []

    let first = true
    let endedList = false

    for (let key in obj) {
      let vs = obj[key]
      let term = this.termFor(key)

      let revKey = (term == null)? this.revKeyFor(key) : null
      if (term == null && revKey == null)
        continue

      if (term == this.keys.id || term == "@context")
        continue

      vs = Array.isArray(vs) ? vs : vs != null ? [vs] : []
      if (!vs.length) // TODO: && not @list
        continue

      let inList = isList || this.isListContainer(key)

      if (revKey) {
        for (let it of vs) {
          let node = it.clone()
          node[revKey] = { [this.keys.id]: s }
          topObjects.push(node)
        }
      } else {
        let useIndent = indent
        if (first) {
          useIndent = ' '
          first = false
        } else {
          if (startedList && !inList && !endedList) {
            endedList = true
            this.write(" )")
          }
          this.writeln(" ;")
        }

        if (term == "@type") {
          term = "a"
          this.write(useIndent + term + " " + vs.map(it =>
            this.toValidTerm(this.termFor(it))
          ).join(", "))
          continue
        }

        if (term != '@list') {
          term = this.toValidTerm(term)
          this.write(useIndent + term + " ")
        }

        for (let i = 0; i < vs.length; i++) {
          let v = vs[i]
            if (inList) {
              if (!startedList) {
                this.write("(")
                startedList = true
              }
              this.write(" ")
            } else if (i > 0) {
              if (this.settings.predicateRepeatNewLine) {
                this.writeln(' ,')
                this.write(this.getIndent(depth + 1 + inGraph))
              } else {
                this.write(' , ')
              }
            }
          if (this.bnodeSkolemBase && typeof v === 'object' && !v[this.keys.id]) {
            v[this.keys.id] = s = this.genSkolemId()
          }
          if (typeof v === 'object' && this.keys.id in v) {
            topObjects.push(v)
            this.write(this.refRepr(v[this.keys.id]))
          } else {
            for (let it of this.objectToTurtle(v, depth + 1, key)) {
              topObjects.push(it)
            }
          }
        }
      }
    }

    if (explicitList || (!isList && startedList) && !endedList) {
      this.write(" )")
    }

    if (depth == 0) {
      if (!first) {
        this.writeln(" .")
      }
      //this.writeln()
      for (let it of topObjects) {
        this.objectToTurtle(it)
      }
      return []
    } else {
      indent = this.getIndent(depth - 1 + inGraph)
      if (this.settings.bracketEndNewLine) {
        this.writeln()
        this.write(indent)
      } else {
        this.write(' ')
      }
      if (!isList) {
        // NOTE: hack for e.g. BlazeGraph
        if (!this.hasKeys(obj) && markEmptyBnode) {
          this.writeln("a $emptyMarker")
          this.write(indent)
        }
        this.write("]")
      }
      return topObjects
    }
  }

  toLiteral (obj, viaKey=null) {
    let value = obj
    let lang = this.context["@language"]
    let datatype = null
    if (typeof obj === 'object') {
      value = obj[this.keys.value]
      datatype = obj[this.keys.type]
      lang = obj[this.keys.lang]
    } else {
      let kdef = this.context[viaKey]
      let coerceTo = (typeof kdef === 'object')? kdef["@type"] : null
      if (coerceTo == "@vocab") {
        this.write(typeof value === 'string' ?
          this.refRepr(value, true): value)
        return
      } else if (coerceTo == "@id") {
        this.write(this.refRepr(value))
        return
      } else if (coerceTo) {
        datatype = coerceTo
      } else {
        let termLang = (typeof kdef === 'object')? kdef["@language"] : null
        if (typeof kdef === 'object') {
          lang = termLang
        }
      }
    }
    if (typeof value === 'string') {
      let escaped = value.replace(/"/g, '\\"')
      let quote = '"'
      if (escaped.indexOf('\n') > -1) {
        quote = '"""'
      }
      this.write(quote)
      this.write(escaped)
      this.write(quote)
      if (datatype)
        this.write("^^" + this.termFor(datatype))
      else if (lang)
        this.write("@" + lang)
    } else { // boolean or number
      this.write(value.toString())
    }
  }

  termFor (key) {
    if (key.startsWith("@")) {
      return key
    } else if (key.indexOf(":") > -1) {
      return key
    } else if (this.context[key]) {
      let kdef = this.context[key]
      if (kdef == null)
        return null
      let term = null
      if (typeof kdef === 'object') {
        term = kdef["@id"] || key
      } else {
        term = kdef
      }
      if (term == null)
        return null
      return (term.indexOf(":") == -1)? ":" + term : term
    } else {
      return ":" + key
    }
  }

  revKeyFor (key) {
    let kdef = this.context[key]
    if (!(typeof kdef === 'object'))
      return null
    return kdef["@reverse"]
  }

  refRepr (ref, useVocab = false) {
    if (ref == null) return '[]'

    let cI = ref.indexOf(":")
    if (cI > -1) {
      let pfx = ref.substring(0, cI)
      if (pfx == "_") {
        let nodeId = ref + this.uniqueBNodeSuffix
        if (this.bnodeSkolemBase) {
          ref = this.bnodeSkolemBase + nodeId.substring(2)
        } else {
          return this.toValidTerm(nodeId)
        }
      } else if (this.context[pfx]) {
        return ref
      }
    } else if (useVocab && ref.indexOf("/") == -1) {
      return ":" + ref
    }

    if (ref.startsWith(this.context[VOCAB])) {
      return ":" + ref.substring(this.context[VOCAB].length)
    }

    ref = this.cleanValue(ref)

    return `<${ref}>`
  }

  toValidTerm (term) {
    term = this.cleanValue(term)
    if (term.indexOf('://') > -1) {
      return `<${term}>`
    }
    // TODO: hack to pseudo-fix problematic pnames...
    return term
  }

  hasKeys (obj, atLeast = 1) {
    let seen = 0
    for (let k in obj) if (++seen === atLeast) return true
    return false
  }

  cleanValue (v) {
    return v
  }

  genSkolemId () {
    return this.bnodeSkolemBase + UUID.randomUUID()
  }

  getIndent (depth) {
    let chunks = []
    for (let i = -1; i++ < depth;) {
      chunks.push(this.settings.indentChars)
    }
    return chunks.join('')
  }

  write (s) {
    this.outstream.write(s || '')
  }

  writeln (s) {
    this.outstream.write((s || '') + '\n')
  }
}

function collectPrefixes (context) {
  if (context == null) return

  let prefixes = {}
  for (let key in context) {
    let value = context[key]
    // TODO: verify JSON-LD 1.1 prefix rules
    if (typeof value === 'string' && value.match(/[#\/:]$/)) {
      prefixes[key === VOCAB ? '' : key] = value
    } else if (value && value['@prefix'] === true) {
      prefixes[key] = value[ID]
    }
  }
  return prefixes
}
<commit_msg>Improve handling of multiple graphs and values<commit_after>const {CONTEXT, GRAPH, ID, TYPE, VALUE, LANGUAGE, LIST, VOCAB, BASE} =
  require('../jsonld/keywords')

module.exports = {serialize}

function serialize (data, out = process.stdout, {
  context = null,
  baseIri = null,
  settings = {
    indentChars: '  ',
    upcaseKeywords: false,
    useGraphKeyword: true,
    spaceBeforeSemicolon: true,
    predicateRepeatNewLine: true,
    bracketStartNewLine: false,
    bracketEndNewLine: false,
    listItemNewLine: true,
    prologueEndLine: 1,
    separatorLines: 1
  }
} = {}) {
  let state = new SerializerState(context, out, settings)
  state.serialize(data)
}

class SerializerState {
  constructor (context, outstream, settings, parent = null) {
    this.outstream = outstream || parent.outstream
    this.initContext(context)
    this.parent = parent
    this.settings = parent ? parent.settings : settings
    let kw = it => this.settings.upcaseKeywords ? it.toUpperCase() : it
    this.prefixKeyword = kw('prefix')
    this.baseKeyword = kw('base')
    if (this.settings.useGraphKeyword) {
      this.graphKeyword = kw('graph')
    }
    this.uniqueBNodeSuffix = ''
  }

  initContext (context) {
    this.keys = {
      id: "@id",
      value: '@value',
      type: '@type',
      lang: '@language',
      graph: '@graph',
      list: '@list'
    }
    this.prefixes = {}

    if (context == null) {
      this.context = {}
    }
    else {
      for (let key in this.context) {
        throw 'context already initialized'
      }
    }
    let ctx = {}
    // TODO: merge arrays, deref uri:s ...
    if (Array.isArray(context)) {
      for (let item of context) {
        Object.assign(ctx, item)
      }
    } else if (typeof context === 'object') {
        Object.assign(ctx, context)
    }
    this.context = ctx
    this.prefixes = collectPrefixes(context)
  }

  serialize (data) {
    if (data[CONTEXT]) {
      this.initContext(data[CONTEXT])
    }
    this.prelude()
    let graph = Array.isArray(data) ? data : data[GRAPH]
    if (graph) {
      for (let node of asArray(graph)) {
        this.objectToTurtle(node)
      }
    } else {
      this.objectToTurtle(data)
    }
  }

  prelude () {
    for (let k in this.prefixes) {
      let v = this.prefixes[k]
      if (k === BASE) {
        this.writeBase(v)
      } else {
        this.writeln(`${this.prefixKeyword} ${k}: <${v}>`)
      }
    }
    if (this.base) {
      this.writeBase(this.base)
    }
    if (this.settings.prologueEndLine > 1) {
      this.writeln()
    }
  }

  writeBase (iri) {
    this.writeln(`${this.baseKeyword} <${iri}>`)
  }

  isListContainer (term) {
    if (this.context == null) return false
    return typeof this.context[term] === 'object' &&
      this.context[term]['@container'] == '@list'
  }

  isLangContainer (term) {
    if (this.context == null) return false
    return typeof this.context[term] === 'object' &&
      this.context[term]['@container'] == '@language'
  }

  objectToTrig (iri, graph) {
    this.writeln()
    if (this.graphKeyword) {
        this.write(`${this.graphKeyword} `)
    }
    this.writeln(`${this.refRepr(iri)} {`)
    for (let node of asArray(graph)) {
      this.objectToTurtle(node, 0, GRAPH)
    }
    this.writeln()
    this.writeln("}")
  }

  objectToTurtle (obj, depth = 0, viaKey = null) {
    if (depth > 0 && obj[CONTEXT]) {
      // TODO: use new SerializerState(node[CONTEXT], null, null, state)
      throw 'Nested context not supported yet'
    }

    if (this.isLangContainer(viaKey) && typeof obj === 'object') {
      let first = true
      for (let lang in obj) {
        let value = obj[lang]
          if (!first) this.write(' , ')
        this.toLiteral(
          { [this.keys.value]: value, [this.keys.lang]: lang },
          viaKey)
        first = false
      }
      return []
    }

    if (!(typeof obj === 'object') || obj[this.keys.value]) {
      this.toLiteral(obj, viaKey)
      return []
    }

    let explicitList = obj[LIST]

    if (this.isListContainer(viaKey)) {
      obj = { [this.keys.list]: obj }
    }

    let s = obj[this.keys.id]

    let isList = obj[LIST]
    let startedList = isList

    if (obj[this.keys.graph]) {
      this.objectToTrig(s, obj[this.keys.graph])
      return []
    }

    if (explicitList) {
      this.write('( ')
    }

    let inGraph = viaKey === GRAPH ? 1 : 0

    if (s != null && this.hasKeys(obj, 2)) {
      if (depth === 0) {
        this.writeln()
      }
      if (inGraph) this.write(this.getIndent(0))
      this.write(this.refRepr(s))
    } else if (depth > 0) {
      if (!isList) {
        depth++
        this.write("[")
      }
    } else {
      if (obj[this.keys.graph]) {
        /* TODO:
        for (let key in obj) {
          if (key[0] != '@') {
            // TODO: this is the default graph, described...
            this.write('[]')
            break
          }
        }
        */
      } else {
        return []
      }
    }

    let indent = this.getIndent(depth + inGraph)

    let topObjects = []

    let first = true
    let endedList = false

    for (let key in obj) {
      let vs = obj[key]
      let term = this.termFor(key)

      let revKey = (term == null)? this.revKeyFor(key) : null
      if (term == null && revKey == null)
        continue

      if (term == this.keys.id || term == "@context")
        continue

      vs = Array.isArray(vs) ? vs : vs != null ? [vs] : []
      if (!vs.length) // TODO: && not @list
        continue

      let inList = isList || this.isListContainer(key)

      if (revKey) {
        for (let it of vs) {
          let node = it.clone()
          node[revKey] = { [this.keys.id]: s }
          topObjects.push(node)
        }
      } else {
        let useIndent = indent
        if (first) {
          useIndent = ' '
          first = false
        } else {
          if (startedList && !inList && !endedList) {
            endedList = true
            this.write(" )")
          }
          this.writeln(" ;")
        }

        if (term == "@type") {
          term = "a"
          this.write(useIndent + term + " " + vs.map(it =>
            this.toValidTerm(this.termFor(it))
          ).join(", "))
          continue
        }

        if (term != '@list') {
          term = this.toValidTerm(term)
          this.write(useIndent + term + " ")
        }

        for (let i = 0; i < vs.length; i++) {
          let v = vs[i]
            if (inList) {
              if (!startedList) {
                this.write("(")
                startedList = true
              }
              this.write(" ")
            } else if (i > 0) {
              if (this.settings.predicateRepeatNewLine) {
                this.writeln(' ,')
                this.write(this.getIndent(depth + 1 + inGraph))
              } else {
                this.write(' , ')
              }
            }
          if (this.bnodeSkolemBase && typeof v === 'object' && !v[this.keys.id]) {
            v[this.keys.id] = s = this.genSkolemId()
          }
          if (typeof v === 'object' && this.keys.id in v) {
            topObjects.push(v)
            this.write(this.refRepr(v[this.keys.id]))
          } else {
            for (let it of this.objectToTurtle(v, depth + 1, key)) {
              topObjects.push(it)
            }
          }
        }
      }
    }

    if (explicitList || (!isList && startedList) && !endedList) {
      this.write(" )")
    }

    if (depth == 0) {
      if (!first) {
        this.writeln(" .")
      }
      //this.writeln()
      for (let it of topObjects) {
        this.objectToTurtle(it)
      }
      return []
    } else {
      indent = this.getIndent(depth - 1 + inGraph)
      if (this.settings.bracketEndNewLine) {
        this.writeln()
        this.write(indent)
      } else {
        this.write(' ')
      }
      if (!isList) {
        // NOTE: hack for e.g. BlazeGraph
        if (!this.hasKeys(obj) && markEmptyBnode) {
          this.writeln("a $emptyMarker")
          this.write(indent)
        }
        this.write("]")
      }
      return topObjects
    }
  }

  toLiteral (obj, viaKey=null) {
    let value = obj
    let lang = this.context["@language"]
    let datatype = null
    if (typeof obj === 'object') {
      value = obj[this.keys.value]
      datatype = obj[this.keys.type]
      lang = obj[this.keys.lang]
    } else {
      let kdef = this.context[viaKey]
      let coerceTo = (typeof kdef === 'object')? kdef["@type"] : null
      if (coerceTo == "@vocab") {
        let next = false
        for (let v of asArray(value)) {
          if (next) this.write(' , ')
          else next = true
          this.write(typeof v === 'string'
            ? this.refRepr(v, true)
            : v)
        }
        return
      } else if (coerceTo == "@id") {
        let next = false
        for (let v of asArray(value)) {
          if (next) this.write(' , ')
          else next = true
          this.write(this.refRepr(v))
        }
        return
      } else if (coerceTo) {
        datatype = coerceTo
      } else {
        let termLang = (typeof kdef === 'object')? kdef["@language"] : null
        if (typeof kdef === 'object') {
          lang = termLang
        }
      }
    }

    let next = false
    for (let v of asArray(value)) {
      if (next) this.write(' , ')
      else next = true

      if (typeof v === 'string') {
        let escaped = v.replace(/"/g, '\\"')
        let quote = '"'
        if (escaped.indexOf('\n') > -1) {
          quote = '"""'
        }
        this.write(quote)
        this.write(escaped)
        this.write(quote)
        if (datatype)
          this.write("^^" + this.termFor(datatype))
        else if (lang)
          this.write("@" + lang)
      } else { // boolean or number
        this.write(v.toString())
      }
    }
  }

  termFor (key) {
    if (key.startsWith("@")) {
      return key
    } else if (key.indexOf(":") > -1) {
      return key
    } else if (this.context[key]) {
      let kdef = this.context[key]
      if (kdef == null)
        return null
      let term = null
      if (typeof kdef === 'object') {
        term = kdef["@id"] || key
      } else {
        term = kdef
      }
      if (term == null)
        return null
      return (term.indexOf(":") == -1)? ":" + term : term
    } else {
      return ":" + key
    }
  }

  revKeyFor (key) {
    let kdef = this.context[key]
    if (!(typeof kdef === 'object'))
      return null
    return kdef["@reverse"]
  }

  refRepr (ref, useVocab = false) {
    if (ref == null) return '[]'

    let cI = ref.indexOf(":")
    if (cI > -1) {
      let pfx = ref.substring(0, cI)
      if (pfx == "_") {
        let nodeId = ref + this.uniqueBNodeSuffix
        if (this.bnodeSkolemBase) {
          ref = this.bnodeSkolemBase + nodeId.substring(2)
        } else {
          return this.toValidTerm(nodeId)
        }
      } else if (this.context[pfx]) {
        return ref
      }
    } else if (useVocab && ref.indexOf("/") == -1) {
      return ":" + ref
    }

    if (ref.startsWith(this.context[VOCAB])) {
      return ":" + ref.substring(this.context[VOCAB].length)
    }

    ref = this.cleanValue(ref)

    return `<${ref}>`
  }

  toValidTerm (term) {
    term = this.cleanValue(term)
    if (term.indexOf('://') > -1) {
      return `<${term}>`
    }
    // TODO: hack to pseudo-fix problematic pnames...
    return term
  }

  hasKeys (obj, atLeast = 1) {
    let seen = 0
    for (let k in obj) if (++seen === atLeast) return true
    return false
  }

  cleanValue (v) {
    return v
  }

  genSkolemId () {
    return this.bnodeSkolemBase + UUID.randomUUID()
  }

  getIndent (depth) {
    let chunks = []
    for (let i = -1; i++ < depth;) {
      chunks.push(this.settings.indentChars)
    }
    return chunks.join('')
  }

  write (s) {
    this.outstream.write(s || '')
  }

  writeln (s) {
    this.outstream.write((s || '') + '\n')
  }
}

function collectPrefixes (context) {
  if (context == null) return

  let prefixes = {}
  for (let key in context) {
    let value = context[key]
    // TODO: verify JSON-LD 1.1 prefix rules
    if (typeof value === 'string' && value.match(/[#\/:]$/)) {
      prefixes[key === VOCAB ? '' : key] = value
    } else if (value && value['@prefix'] === true) {
      prefixes[key] = value[ID]
    }
  }
  return prefixes
}

function asArray(value) {
  return Array.isArray(value) ? value : [value]
}
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.gameEditor', ['ngRoute', 'ngMaterial'])

    .config(['$routeProvider', function($routeProvider) {
      $routeProvider.when('/gameEditor', {
        templateUrl: 'views/gameEditor/gameEditor.html',
        controller: 'inputController'
      });
    }])

    /* FORM */
    .controller('inputController', ['$http', function ($http) {
      var self = this;
      //self.game = function(){};

      self.game = {
       title : null,
        id: null,
          punishTime: null
      };
        /**checks if the user input is valid for sending
         *
         * @returns {boolean}
         */
        self.validInput = function(){

            var title = self.game.title;
            var id = self.game.id;
            var punishTime = self.game.punishTime;

            if(title == null || title.length == 0){
                return false;
            }
            if(id == null || id.length == 0){
                return false;
            }
            return !(punishTime == null || punishTime <= 0);

    };

      self.sendGameData = function() {

          var gamesEndpoint = "http://localhost:8888/games"

          //TODO token header, LINK

          $http.post(gamesEndpoint, JSON.stringify(self.game)).
          success(function(data, status, headers, config) {
              window.alert(" SUCCESS "  +data + status)
              self.games = data
          }).
          error(function(data, status, headers, config) {
              window.alert("error posting game " + data + " " + status)
              // log error
          });

      };

      return true;
    }])

    /* TABLE */
    .controller('tableController', ['$http', function ($http) {

        var self = this;
        self.games = function(){};
        self.games = [
            {title: "test", id: "testId", punishTime: 10}
        ];

        // TODO TOKEN HEADER, CORRECT LINK

        var gamesEndpoint = "http://localhost:8888/games"
        $http.get(gamesEndpoint).
        success(function(data, status, headers, config) {
            window.alert(data)
            self.games = data
        }).
        error(function(data, status, headers, config) {
            window.alert("error retrieving games" + data + " " + status)
            // log error
        });

      return true;
    }]);;<commit_msg>updated token, and url cant test, server still not working<commit_after>'use strict';

angular.module('myApp.gameEditor', ['ngRoute', 'ngMaterial'])

    .config(['$routeProvider', function($routeProvider) {
      $routeProvider.when('/gameEditor', {
        templateUrl: 'views/gameEditor/gameEditor.html',
        controller: 'inputController'
      });
    }])

    /* FORM */
    .controller('inputController', ['$http', function ($http) {
      var self = this;
      //self.game = function(){};

      self.game = {
       title : null,
        id: null,
          punishTime: null
      };
        /**checks if the user input is valid for sending
         *
         * @returns {boolean}
         */
        self.validInput = function(){

            var title = self.game.title;
            var id = self.game.id;
            var punishTime = self.game.punishTime;

            if(title == null || title.length == 0){
                return false;
            }
            if(id == null || id.length == 0){
                return false;
            }
            return !(punishTime == null || punishTime <= 0);

    };

      self.sendGameData = function() {

          var config = {
              headers: {
                  "token": sessionStorage.getItem('token')
              }
          }
          var gamesEndpoint = "http://zaxion.nl/api/games"
          var token = sessionStorage.getItem('token').

          $http.post(gamesEndpoint, JSON.stringify(self.game), config).
          success(function(data, status, headers, config) {
              window.alert(" SUCCESS "  +data + status)
              self.games = data
          }).
          error(function(data, status, headers, config) {
              window.alert("error posting game " + data + " " + status)
              // log error
          });

      };

      return true;
    }])

    /* TABLE */
    .controller('tableController', ['$http', function ($http) {

        var self = this;
        self.games = function(){};
        self.games = [
            {title: "test", id: "testId", punishTime: 10}
        ];

        // TODO TOKEN HEADER, CORRECT LINK
        var config = {
            headers: {
                "token": sessionStorage.getItem('token')
            }
        }
        var gamesEndpoint = "http://zaxion.nl/api/games"
        $http.get(gamesEndpoint, config).
        success(function(data, status, headers, config) {
            window.alert(data)
            self.games = data
        }).
        error(function(data, status, headers, config) {
            window.alert("error retrieving games" + data + " " + status)
            // log error
        });

      return true;
    }]);;<|endoftext|>


<commit_before>/**
 * Shopware 5
 * Copyright (c) shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */

/**
 * The cache controller takes care of cache related events and also
 * handles the category fixing
 */

//{namespace name=backend/performance/main}
//{block name="backend/performance/controller/start"}
Ext.define('Shopware.apps.Performance.controller.Start', {
    extend: 'Enlight.app.Controller',

    infoTitle: '{s name=form/message_title}Shop cache{/s}',
    infoMessageSuccess: '{s name=form/message}Shop cache has been cleared.{/s}',
    infoTitlePerformanceMode: '{s name=tabs/start/performance_mode}{/s}',
    infoMessageProductionMode: '{s name=tabs/start/production_mode_active}{/s}',
    infoMessageDevelopmentMode: '{s name=tabs/start/development_mode_active}{/s}',
    errorTitle: '{s name=errorTitle}{/s}',
    httpCacheError: '{s name=tabs/start/errorHttpCache}{/s}',

    running: false,
    state: null,

    /**
     * init events
     */
    init: function () {
        var me = this;

        me.control({
            'performance-tabs-start-main button[action=clear-all]': {
                click: me.clearWholeCache
            },
            'performance-tabs-start-main': {
                'init-toggle-productive': me.getPerformanceMode,
                'toggle-productive': me.toggleProductive
            }
        });

        me.callParent(arguments);
    },

    /**
     * function to set toggle-button-state in the view on startup
     * @param Shopware.apps.Performance.view.tabs.start.Main window
     */
    getPerformanceMode: function (window) {
        var me = this;

        Ext.Ajax.request({
            url: '{url controller=Performance action=getProductiveMode}',
            success: function (operation, opts) {
                var response = Ext.decode(operation.responseText);

                if (response.success == true) {
                    me.state = response.productiveMode;
                    window.setState(me.state);
                }
            }
        });
    },

    /**
     * set productive mode active/unactive
     * @param Shopware.apps.Performance.view.tabs.start.Main window
     */
    toggleProductive: function (window) {
        var me = this;

        if (!window) {
            return;
        }

        if (me.running) {
            return;
        }

        me.running = true;

        Ext.Ajax.request({
            url: '{url controller=Performance action=toggleProductiveMode}',
            success: function (operation, opts) {
                var response = Ext.decode(operation.responseText);
                me.running = false;

                if (response.success == true) {
                    me.toggleProductiveCallback(window);
                } else {
                    if (response.state == 'not_found') {
                        Shopware.Notification.createGrowlMessage(
                            me.errorTitle,
                            me.httpCacheError
                        );
                        window.resetState();
                    }
                }
            }
        });
    },

    /**
     * callback function for toggleProductive
     * @param Shopware.apps.Performance.view.tabs.start.Main window
     */
    toggleProductiveCallback: function (window) {
        var me = this,
            message;

        if (me.state) {
            message = me.infoMessageDevelopmentMode;
        } else {
            message = me.infoMessageProductionMode;
        }

        me.state = !me.state;

        Shopware.Notification.createGrowlMessage(
            me.infoTitlePerformanceMode,
            message,
            me.infoTitlePerformanceMode
        );
    },

    /**
     * clear whole cache
     */
    clearWholeCache: function () {
        var me = this;

        Ext.Ajax.request({
            url: '{url controller=Cache action=clearCache}?cache=Config',
            params:{
              'cache[template]' : 'on',
              'cache[theme]'    : 'on',
              'cache[search]'   : 'on',
              'cache[router]'   : 'on'
            },
            success: function () {
                me.reloadInfoStore();
            }
        });
    },

    /**
     * reload cache-info-store and give success-message
     */
    reloadInfoStore: function () {
        var me = this;

        Ext.getStore('Info').load({
            callback: function (records, operation) {
                Shopware.app.Application.fireEvent('shopware-theme-cache-warm-up-request');
                Shopware.Notification.createGrowlMessage(
                    me.infoTitle,
                    me.infoMessageSuccess,
                    me.infoTitle
                );
            }
        });
    }
});
//{/block}<commit_msg>SW-11456 - Don't display theme compiling window on performance start tab<commit_after>/**
 * Shopware 5
 * Copyright (c) shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */

/**
 * The cache controller takes care of cache related events and also
 * handles the category fixing
 */

//{namespace name=backend/performance/main}
//{block name="backend/performance/controller/start"}
Ext.define('Shopware.apps.Performance.controller.Start', {
    extend: 'Enlight.app.Controller',

    infoTitle: '{s name=form/message_title}Shop cache{/s}',
    infoMessageSuccess: '{s name=form/message}Shop cache has been cleared.{/s}',
    infoTitlePerformanceMode: '{s name=tabs/start/performance_mode}{/s}',
    infoMessageProductionMode: '{s name=tabs/start/production_mode_active}{/s}',
    infoMessageDevelopmentMode: '{s name=tabs/start/development_mode_active}{/s}',
    errorTitle: '{s name=errorTitle}{/s}',
    httpCacheError: '{s name=tabs/start/errorHttpCache}{/s}',

    running: false,
    state: null,

    /**
     * init events
     */
    init: function () {
        var me = this;

        me.control({
            'performance-tabs-start-main button[action=clear-all]': {
                click: me.clearWholeCache
            },
            'performance-tabs-start-main': {
                'init-toggle-productive': me.getPerformanceMode,
                'toggle-productive': me.toggleProductive
            }
        });

        me.callParent(arguments);
    },

    /**
     * function to set toggle-button-state in the view on startup
     * @param Shopware.apps.Performance.view.tabs.start.Main window
     */
    getPerformanceMode: function (window) {
        var me = this;

        Ext.Ajax.request({
            url: '{url controller=Performance action=getProductiveMode}',
            success: function (operation, opts) {
                var response = Ext.decode(operation.responseText);

                if (response.success == true) {
                    me.state = response.productiveMode;
                    window.setState(me.state);
                }
            }
        });
    },

    /**
     * set productive mode active/unactive
     * @param Shopware.apps.Performance.view.tabs.start.Main window
     */
    toggleProductive: function (window) {
        var me = this;

        if (!window) {
            return;
        }

        if (me.running) {
            return;
        }

        me.running = true;

        Ext.Ajax.request({
            url: '{url controller=Performance action=toggleProductiveMode}',
            success: function (operation, opts) {
                var response = Ext.decode(operation.responseText);
                me.running = false;

                if (response.success == true) {
                    me.toggleProductiveCallback(window);
                } else {
                    if (response.state == 'not_found') {
                        Shopware.Notification.createGrowlMessage(
                            me.errorTitle,
                            me.httpCacheError
                        );
                        window.resetState();
                    }
                }
            }
        });
    },

    /**
     * callback function for toggleProductive
     * @param Shopware.apps.Performance.view.tabs.start.Main window
     */
    toggleProductiveCallback: function (window) {
        var me = this,
            message;

        if (me.state) {
            message = me.infoMessageDevelopmentMode;
        } else {
            message = me.infoMessageProductionMode;
        }

        me.state = !me.state;

        Shopware.Notification.createGrowlMessage(
            me.infoTitlePerformanceMode,
            message,
            me.infoTitlePerformanceMode
        );
    },

    /**
     * clear whole cache
     */
    clearWholeCache: function () {
        var me = this;

        Ext.Ajax.request({
            url: '{url controller=Cache action=clearCache}?cache=Config',
            params:{
              'cache[config]'   : 'on',
              'cache[template]' : 'on',
              'cache[search]'   : 'on',
              'cache[router]'   : 'on'
            },
            success: function () {
                me.reloadInfoStore();
            }
        });
    },

    /**
     * reload cache-info-store and give success-message
     */
    reloadInfoStore: function () {
        var me = this;

        Ext.getStore('Info').load({
            callback: function (records, operation) {
                Shopware.Notification.createGrowlMessage(
                    me.infoTitle,
                    me.infoMessageSuccess,
                    me.infoTitle
                );
            }
        });
    }
});
//{/block}<|endoftext|>


<commit_before>import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import pkg from './package.json';

export default [
	// browser-friendly UMD build
	{
		input: 'src/main.js',
		output: {
			file: pkg.browser,
			format: 'umd'
		},
		name: 'howLongUntilLunch',
		plugins: [
			resolve(), // so Rollup can find `ms`
			commonjs() // so Rollup can convert `ms` to an ES module
		]
	},

	// CommonJS (for Node) and ES module (for bundlers) build.
	// (We could have three entries in the configuration array
	// instead of two, but it's quicker to generate multiple
	// builds from a single configuration where possible, using
	// an array for the `output` option, where we can specify
	// `file` and `format` for each target)
	{
		input: 'src/main.js',
		external: ['ms'],
		output: [
			{ file: pkg.main, format: 'cjs' },
			{ file: pkg.module, format: 'es' }
		]
	}
];
<commit_msg>name is now output.name (#10)<commit_after>import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import pkg from './package.json';

export default [
	// browser-friendly UMD build
	{
		input: 'src/main.js',
		output: {
			name: 'howLongUntilLunch',
			file: pkg.browser,
			format: 'umd'
		},
		plugins: [
			resolve(), // so Rollup can find `ms`
			commonjs() // so Rollup can convert `ms` to an ES module
		]
	},

	// CommonJS (for Node) and ES module (for bundlers) build.
	// (We could have three entries in the configuration array
	// instead of two, but it's quicker to generate multiple
	// builds from a single configuration where possible, using
	// an array for the `output` option, where we can specify
	// `file` and `format` for each target)
	{
		input: 'src/main.js',
		external: ['ms'],
		output: [
			{ file: pkg.main, format: 'cjs' },
			{ file: pkg.module, format: 'es' }
		]
	}
];
<|endoftext|>


<commit_before>/**
 * Policy Mappings
 * (sails.config.policies)
 *
 * Policies are simple functions which run **before** your controllers.
 * You can apply one or more policies to a given controller, or protect
 * its actions individually.
 *
 * Any policy file (e.g. `api/policies/authenticated.js`) can be accessed
 * below by its filename, minus the extension, (e.g. "authenticated")
 *
 * For more information on how policies work, see:
 * http://sailsjs.org/#/documentation/concepts/Policies
 *
 * For more information on configuring policies, check out:
 * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.policies.html
 */

var mod = ['passport', 'sessionAuth', 'isMod'];
var user = ['passport', 'sessionAuth'];
var anyone = ['passport'];

module.exports.policies = {

  '*': mod,

  AuthController: {
    '*': anyone
  },

  FlairController: {
    '*': mod,
    apply: user,
    setText: user
  },

  HomeController: {
    '*': mod,
    index: user,
    reference: anyone,
    search: user,
    info: anyone
  },

  ReferenceController: {
    '*': mod,
    get: user,
    add: user,
    edit: user,
    deleteRef: user,
    comment: user,
    delComment: user,
    getFlairs: user
  },

  SearchController: {
    '*': mod,
    ref: user,
    refView: user
  },

  UserController: {
    '*': mod,
    edit: user,
    mine: user,
    get: anyone
  }
};
<commit_msg>Fix #465<commit_after>/**
 * Policy Mappings
 * (sails.config.policies)
 *
 * Policies are simple functions which run **before** your controllers.
 * You can apply one or more policies to a given controller, or protect
 * its actions individually.
 *
 * Any policy file (e.g. `api/policies/authenticated.js`) can be accessed
 * below by its filename, minus the extension, (e.g. "authenticated")
 *
 * For more information on how policies work, see:
 * http://sailsjs.org/#/documentation/concepts/Policies
 *
 * For more information on configuring policies, check out:
 * http://sailsjs.org/#/documentation/reference/sails.config/sails.config.policies.html
 */

var mod = ['passport', 'sessionAuth', 'isMod'];
var user = ['passport', 'sessionAuth'];
var anyone = ['passport'];

module.exports.policies = {

  '*': mod,

  AuthController: {
    '*': anyone
  },

  FlairController: {
    '*': mod,
    apply: user,
    setText: user
  },

  HomeController: {
    '*': mod,
    index: user,
    reference: anyone,
    search: user,
    info: anyone
  },

  ReferenceController: {
    '*': mod,
    get: user,
    add: user,
    edit: user,
    deleteRef: user,
    comment: user,
    delComment: user,
    getFlairs: user
  },

  SearchController: {
    '*': mod,
    ref: user,
    refView: user,
    user: user,
    userView: user
  },

  UserController: {
    '*': mod,
    edit: user,
    mine: user,
    get: anyone
  }
};
<|endoftext|>


<commit_before>import makeDir from 'make-dir'
import fs from 'fs'
import gutil from 'gulp-util'
import modulesList from './modulesList'
import outputFileSync from 'output-file-sync'
import gulp from 'gulp'
import args from './args'
import config from '../../config'
import path from 'path'
import requireDirectory from 'require-directory'
import _ from 'lodash'
import shell from 'gulp-shell'
import os from 'os'

/**
 * 工具类
 */
class Util {
  /**
   * 初始化主题目录
   */
  static initDir () {
    let themeDir = this.themeDir()
    if (!this.isDir(themeDir)) {
      this.initConfigFile(themeDir, this.currentThemeName())
      let totalModules = [...modulesList, ...this.extraModulesList()]
      for (let key in totalModules) {
        let moduleDir = `${themeDir}${this.ds()}Magento_${totalModules[key]}`
        this.initModule(moduleDir)
      }
    } else {
      gutil.log(gutil.colors.red(`主题目录已存在：${themeDir}`))
    }
  }

  /**
   * 检查目录是否存在
   * @param dir
   * @returns true|false
   */
  static isDir (dir) {
    return fs.existsSync(dir)
  }

  /**
   * 创建目录
   * @param dir
   */
  static createDir (dir) {
    makeDir(dir).then(path => {
      gutil.log(gutil.colors.green(`目录创建成功：${dir}`))
    })
  }

  /**
   * 初始化模块目录
   * @param dir
   */
  static initModule (dir) {
    Promise.all([
      makeDir(`${dir}/layout`),
      makeDir(`${dir}/templates`),
      makeDir(`${dir}/web/components`),
      makeDir(`${dir}/web/modules`),
      makeDir(`${dir}/web/lib`)
    ]).then((path) => {
      gutil.log(gutil.colors.green(`模块创建成功：${dir}`))
    })

    gulp.src('./build/static/require-config.js').pipe(gulp.dest(`${dir}`))
  }

  /**
   * 初始化主题配置文件及所需资源
   * @param dir
   * @param themeName
   */
  static initConfigFile (dir, themeName) {
    let registration = fs.readFileSync('./build/static/registration.php', 'utf8')
    let registrationR = registration.replace(/ThemePath/, dir.slice(2, dir.length-1))
    outputFileSync(`${dir}/registration.php`, registrationR)

    let theme = fs.readFileSync('./build/static/theme.xml', 'utf8')
    let themeR = theme.replace(/ThemeName/, themeName)
    outputFileSync(`${dir}/theme.xml`, themeR)

    gulp.src('./build/static/etc/view.xml').pipe(gulp.dest(`${dir}/etc`))
    gulp.src('./build/static/media/preview.jpg').pipe(gulp.dest(`${dir}/media`))

    gulp.src('./build/static/web/**').pipe(gulp.dest(`${dir}/web`))
    gulp.src('./build/static/Magento_Theme/**').pipe(gulp.dest(`${dir}/Magento_Theme`))
  }

  /**
   * 获取当前主题路径
   * @returns {string}
   */
  static themeDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      // return `./frontend/${theme.src}/`
      return path.join(__dirname, `../../frontend/${theme.src}/`)
    } else {
      return ''
    }
  }

  /**
   * 主题输出目录
   * @returns {*}
   */
  static outputDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      return `${path.join(__dirname, '../../../')}app/design/frontend/${theme.src}/`
    } else {
      return ''
    }
  }

  /**
   * 设置需要排除的依赖文件，浅移除加载
   * @returns {Util.excludeShallow|*|Array}
   */
  static excludeShallow () {
    let currentTheme = this.currentTheme()
    return config.themes[currentTheme].excludeShallow ? config.themes[currentTheme].excludeShallow : []
  }

  /**
   * 引入额外的JS库
   */
  static includeJsLib () {
    let currentTheme = this.currentTheme()
    return config.themes[currentTheme].includeJsLib ? config.themes[currentTheme].includeJsLib : []
  }

  /**
   * 指定主题标识
   */
  static currentTheme () {
    return args.theme
  }

  /**
   * 当前主题名
   */
  static currentThemeName () {
    return config.themes[this.currentTheme()].name
  }

  /**
   * 当前模式
   */
  static mode () {
    return args.mode
  }

  /**
   * 合并所有require-config.js配置文件
   */
  static mergeConfig () {
    // let themeDir = path.join(__dirname, `../../${this.themeDir()}`)
    let themeDir = this.themeDir()
    if (this.isDir(themeDir)) {
      let whitelist = /Magento_[\w]+(\/|\\)require-config.js/
      let requireDir = requireDirectory(module, themeDir, {include: whitelist})
      let requireConfigObj = {}
      for (let item of Object.keys(requireDir)) {
        requireConfigObj = _.merge(requireConfigObj, requireDir[item]['require-config'].default)
      }
      let config = String('require.config(' + JSON.stringify(requireConfigObj) + ')')
      outputFileSync(`${themeDir}web${Util.ds()}require-config.js`, config, 'utf-8')
    } else {
      gutil.log(gutil.colors.red(`目录不存在：${themeDir}`))
    }
  }

  /**
   * 是否开启模块压缩
   * @returns {string}
   */
  static isUglify () {
    return args.mode ? 'uglify' : 'none'
  }

  /**
   * 监听的端口
   */
  static port () {
    return args.prot
  }

  /**
   * Cache Clean
   */
  static isCache () {
    return args.cache
  }

  /**
   * 代理URL
   * @returns {*}
   */
  static proxy () {
    if (config.siteConfig.proxy) {
      return config.siteConfig.proxy
    } else {
      gutil.log(gutil.colors.red('请先在配置文件中设置proxy'))
      return false
    }
  }

  /**
   * 获取扩展的模块列表
   * @returns {*}
   */
  static extraModulesList () {
    return config.themes[this.currentTheme()].extraModulesList ? config.themes[this.currentTheme()].extraModulesList : []
  }

  /**
   * 判断主题是否存在
   * @returns {boolean}
   */
  static isThemeDir () {
    if (this.isDir(this.themeDir())) {
      return true
    } else {
      gutil.log(gutil.colors.red(`主题目录不存在：${this.themeDir()}`))
      return false
    }
  }

  /**
   * 传入需要执行的command
   * @param commands
   */
  static shell (commands = []) {
    return shell.task(commands)
  }

  /**
   * 获取magento的bin
   * @returns {*}
   */
  static mageBin () {
    let mageBin = path.join(__dirname, '../../../bin/magento')
    if (this.isDir(mageBin)) {
      return mageBin
    }
    return false
  }

  /**
   * 获取当前系统
   * @returns {*}
   */
  static getOS () {
    return os.platform()
  }

  /**
   * 处理系统路径兼容性
   * @returns {string}
   */
  static ds () {
    return this.getOS() === "win32" ? "\\" : '/'
  }
}

export default Util
<commit_msg>优化util<commit_after>import makeDir from 'make-dir'
import fs from 'fs'
import gutil from 'gulp-util'
import modulesList from './modulesList'
import outputFileSync from 'output-file-sync'
import gulp from 'gulp'
import args from './args'
import config from '../../config'
import path from 'path'
import requireDirectory from 'require-directory'
import _ from 'lodash'
import shell from 'gulp-shell'
import os from 'os'

/**
 * 工具类
 */
class Util {
  /**
   * 初始化主题目录
   */
  static initDir () {
    let themeDir = this.themeDir()
    if (!this.isDir(themeDir)) {
      this.initConfigFile(themeDir, this.currentThemeName())
      let totalModules = [...modulesList, ...this.extraModulesList()]
      for (let key in totalModules) {
        let moduleDir = `${themeDir}${this.ds()}Magento_${totalModules[key]}`
        this.initModule(moduleDir)
      }
    } else {
      gutil.log(gutil.colors.red(`主题目录已存在：${themeDir}`))
    }
  }

  /**
   * 检查目录是否存在
   * @param dir
   * @returns true|false
   */
  static isDir (dir) {
    return fs.existsSync(dir)
  }

  /**
   * 创建目录
   * @param dir
   */
  static createDir (dir) {
    makeDir(dir).then(path => {
      gutil.log(gutil.colors.green(`目录创建成功：${dir}`))
    })
  }

  /**
   * 初始化模块目录
   * @param dir
   */
  static initModule (dir) {
    Promise.all([
      makeDir(`${dir}/layout`),
      makeDir(`${dir}/templates`),
      makeDir(`${dir}/web/components`),
      makeDir(`${dir}/web/modules`),
      makeDir(`${dir}/web/lib`)
    ]).then((path) => {
      gutil.log(gutil.colors.green(`模块创建成功：${dir}`))
    })

    gulp.src('./build/static/require-config.js').pipe(gulp.dest(`${dir}`))
  }

  /**
   * 初始化主题配置文件及所需资源
   * @param dir
   * @param themeName
   */
  static initConfigFile (dir, themeName) {
    let registration = fs.readFileSync('./build/static/registration.php', 'utf8')
    let registrationR = registration.replace(/ThemePath/, dir.slice(2, dir.length-1))
    outputFileSync(`${dir}/registration.php`, registrationR)

    let theme = fs.readFileSync('./build/static/theme.xml', 'utf8')
    let themeR = theme.replace(/ThemeName/, themeName)
    outputFileSync(`${dir}/theme.xml`, themeR)

    gulp.src('./build/static/etc/view.xml').pipe(gulp.dest(`${dir}/etc`))
    gulp.src('./build/static/media/preview.jpg').pipe(gulp.dest(`${dir}/media`))

    gulp.src('./build/static/web/**').pipe(gulp.dest(`${dir}/web`))
    gulp.src('./build/static/Magento_Theme/**').pipe(gulp.dest(`${dir}/Magento_Theme`))
  }

  /**
   * 获取当前主题路径
   * @returns {string}
   */
  static themeDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      // return `./frontend/${theme.src}/`
      return path.join(__dirname, `../../frontend/${theme.src}/`)
    } else {
      return ''
    }
  }

  /**
   * 主题输出目录
   * @returns {*}
   */
  static outputDir () {
    let currentTheme = this.currentTheme()
    if (currentTheme) {
      let theme = config.themes[currentTheme]
      return `${path.join(__dirname, '../../../')}app/design/frontend/${theme.src}/`
    } else {
      return ''
    }
  }

  /**
   * 设置需要排除的依赖文件，浅移除加载
   * @returns {Util.excludeShallow|*|Array}
   */
  static excludeShallow () {
    let currentTheme = this.currentTheme()
    return config.themes[currentTheme].excludeShallow ? config.themes[currentTheme].excludeShallow : []
  }

  /**
   * 引入额外的JS库
   */
  static includeJsLib () {
    let currentTheme = this.currentTheme()
    return config.themes[currentTheme].includeJsLib ? config.themes[currentTheme].includeJsLib : []
  }

  /**
   * 指定主题标识
   */
  static currentTheme () {
    return args.theme
  }

  /**
   * 当前主题名
   */
  static currentThemeName () {
    return config.themes[this.currentTheme()].name
  }

  /**
   * 当前模式
   */
  static mode () {
    return args.mode
  }

  /**
   * 合并所有require-config.js配置文件
   */
  static mergeConfig () {
    // let themeDir = path.join(__dirname, `../../${this.themeDir()}`)
    let themeDir = this.themeDir()
    if (this.isDir(themeDir)) {
      let whitelist = /Magento_[\w]+(\/|\\)require-config.js/
      let requireDir = requireDirectory(module, themeDir, {include: whitelist})
      let requireConfigObj = {}
      for (let item of Object.keys(requireDir)) {
        requireConfigObj = _.merge(requireConfigObj, requireDir[item]['require-config'].default)
      }
      let config = String('require.config(' + JSON.stringify(requireConfigObj) + ')')
      outputFileSync(`${themeDir}web${Util.ds()}require-config.js`, config, 'utf-8')
    } else {
      gutil.log(gutil.colors.red(`目录不存在：${themeDir}`))
    }
  }

  /**
   * 是否开启模块压缩
   * @returns {string}
   */
  static isUglify () {
    return args.mode ? 'uglify' : 'none'
  }

  /**
   * 监听的端口
   */
  static port () {
    return args.prot
  }

  /**
   * Cache Clean
   */
  static isCache () {
    return args.cache
  }

  /**
   * 代理URL
   * @returns {*}
   */
  static proxy () {
    if (config.siteConfig.proxy) {
      return config.siteConfig.proxy
    } else {
      gutil.log(gutil.colors.red('请先在配置文件中设置proxy'))
      return false
    }
  }

  /**
   * 获取扩展的模块列表
   * @returns {*}
   */
  static extraModulesList () {
    return config.themes[this.currentTheme()].extraModulesList ? config.themes[this.currentTheme()].extraModulesList : []
  }

  /**
   * 判断主题是否存在
   * @returns {boolean}
   */
  static isThemeDir () {
    if (this.isDir(this.themeDir())) {
      return true
    } else {
      gutil.log(gutil.colors.red(`主题目录不存在：${this.themeDir()}`))
      return false
    }
  }

  /**
   * 传入需要执行的command
   * @param commands
   */
  static shell (commands = []) {
    return shell.task(commands)
  }

  /**
   * 获取magento的bin
   * @returns {*}
   */
  static mageBin () {
    let mageBin = path.join(__dirname, '../../../bin/magento')
    if (this.isDir(mageBin)) {
      return mageBin
    }
    return false
  }

  /**
   * 获取当前系统
   * @returns {*}
   */
  static getOS () {
    return os.platform()
  }

  /**
   * 处理系统路径兼容性
   * @returns {string}
   */
  static ds () {
    return this.getOS() === "win32" ? "\\" : '/'
  }

  /**
   * 返回指定打开网站浏览器
   * @returns {(string|string)[]}
   */
  static getBrowser () {
    return config.siteConfig.browser
  }
}

export default Util
<|endoftext|>


<commit_before>import sourcemaps from "rollup-plugin-sourcemaps";
import resolve from "rollup-plugin-node-resolve";
import globals from "rollup-plugin-node-globals";
import builtins from "rollup-plugin-node-builtins";
import commonjs from "rollup-plugin-commonjs";
import uglify from "rollup-plugin-uglify";
import pascalCase from "pascal-case";

const pkg = require("./package");

export default {
  moduleName: pascalCase(pkg.name),
  entry: "es/index.js",
  dest: "dist/bundle.js",
  format: "umd",
  exports: "named",
  sourceMap: true,
  plugins: [
    sourcemaps(),
    resolve({
      jsnext: true,
      browser: true
    }),
    commonjs(),
    globals(),
    builtins(),
    uglify()
  ]
};
<commit_msg>Move up commonjs<commit_after>import sourcemaps from "rollup-plugin-sourcemaps";
import resolve from "rollup-plugin-node-resolve";
import globals from "rollup-plugin-node-globals";
import builtins from "rollup-plugin-node-builtins";
import commonjs from "rollup-plugin-commonjs";
import uglify from "rollup-plugin-uglify";
import pascalCase from "pascal-case";

const pkg = require("./package");

export default {
  moduleName: pascalCase(pkg.name),
  entry: "es/index.js",
  dest: "dist/bundle.js",
  format: "umd",
  exports: "named",
  sourceMap: true,
  plugins: [
    sourcemaps(),
    commonjs(),
    resolve({
      jsnext: true,
      browser: true
    }),
    globals(),
    builtins(),
    uglify()
  ]
};
<|endoftext|>


<commit_before>// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
import serve from 'rollup-plugin-serve';
import livereload from "rollup-plugin-livereload"

const pkg = require("./package.json");

export default {
  input: './src/index.ts',
  name: "flatpickr",
  output: {
    file: 'dist/flatpickr.js',
    format: 'umd',
    banner: `/* flatpickr v${pkg.version}, @license MIT */`
  },

  plugins: [
    typescript({
      abortOnError: false,
      cacheRoot: `/tmp/.rpt2_cache`
    }),
    ...process.env.ROLLUP_WATCH ? [serve({
      open: true,
      contentBase: ''
    }),
    livereload()] : []
  ],
  watch: {
    include: 'src/**/*.ts',
  }
}
<commit_msg>rollup: port 8000<commit_after>// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
import serve from 'rollup-plugin-serve';
import livereload from "rollup-plugin-livereload"

const pkg = require("./package.json");

export default {
  input: './src/index.ts',
  name: "flatpickr",
  output: {
    file: 'dist/flatpickr.js',
    format: 'umd',
    banner: `/* flatpickr v${pkg.version}, @license MIT */`
  },

  plugins: [
    typescript({
      abortOnError: false,
      cacheRoot: `/tmp/.rpt2_cache`
    }),
    ...process.env.ROLLUP_WATCH ? [serve({
      open: true,
      contentBase: '',
      host: '0.0.0.0',
      port: 8000,
    }),
    livereload()] : []
  ],
  watch: {
    include: 'src/**/*.ts',
  }
}
<|endoftext|>


<commit_before>Template.courseSelection.helpers({
  courses: function() {
    var school = Schools.findOne(Session.get('schoolId'));
    if (school) {
      return Courses.find({schoolId: school._id});
    }
  }
});

Template.courseSelection.events({
  'change #course-selector': function(event) {
    var value = $(event.target).val();
    Session.set('courseId', value);
  }
});

<commit_msg>Codestyle<commit_after>Template.courseSelection.helpers({
  courses: function() {
    var school = Schools.findOne(Session.get('schoolId'));
    if (school) {
      return Courses.find({schoolId: school._id});
    }
  }
});

Template.courseSelection.events({
  'change #course-selector': function(event) {
    var value = $(event.target).val();
    Session.set('courseId', value);
  }
});

<|endoftext|>


<commit_before>import React from 'react'
import {
	Alert,
	View,
	Text,
	Image,
	ActivityIndicator,
	TextInput,
	TouchableWithoutFeedback
} from 'react-native'
import { connect } from 'react-redux'
import Toast from 'react-native-simple-toast'
import {
	openURL,
	hideKeyboard
} from '../../util/general'
import AppSettings from '../../AppSettings'
import Touchable from '../common/Touchable'
import css from '../../styles/css'
import COLOR from '../../styles/ColorConstants'

const auth = require('../../util/auth')

const campusLogo = require('../../assets/images/UCSanDiegoLogo-White.png')

class OnboardingLogin extends React.Component {
	constructor(props) {
		super(props)
		this.state = {
			credentials: {
				username: '',
				password: ''
			}
		}
	}

	componentDidMount() {
		// if we're mounting and we're somehow still in the
		// process of logging in, check if we've timed out.
		// otherwise, set a timeout
		if (this.props.requestStatus) {
			const now = new Date()
			const lastPostTime = new Date(this.props.requestStatus.timeRequested)
			if (now - lastPostTime >= AppSettings.SSO_TTL) {
				this.props.timeoutLogin()
			} else {
				// timeout after remaining time expires
				setTimeout(this.props.timeoutLogin, now - lastPostTime)
			}
		}
	}

	componentWillReceiveProps(nextProps) {
		if (nextProps.user.isLoggedIn) {
			Toast.showWithGravity(
				'Successfully signed in!',
				Toast.SHORT,
				Toast.BOTTOM
			)

			auth.retrieveAccessToken()
				.then((token) => {
					console.log('User Data: ', this.props.user)
					console.log('Access Token: ', token)
				})

			this.props.setOnboardingViewed(true)
		}
	}

	componentDidUpdate(prevProps, prevState) {
		const oldStatus = prevProps.requestStatus
		const newStatus = this.props.requestStatus

		// Only render alerts if status change is new
		if (oldStatus !== newStatus) {
			// Failed log in
			if (this.props.requestError) {
				Alert.alert(
					'Sign in error',
					this.props.requestError,
					{ cancelable: false }
				)
			}
		}
	}

	onSubmit = (username, password) => {
		this.props.doLogin(username, password)
	}

	handleCredentialInput = fieldName => (e) => {
		const { username, password } = this.state.credentials
		const newCredentials = { username, password }
		newCredentials[fieldName] = e.nativeEvent.text

		this.setState({ credentials: newCredentials })
	}

	skipSSO = () => {
		this.props.setOnboardingViewed(true)
	}

	render() {
		const { username, password } = this.state.credentials

		return (
			<TouchableWithoutFeedback onPress={() => hideKeyboard()}>
				<View style={css.ob_container}>
					<Image style={css.ob_logo} source={campusLogo} />

					<View style={css.ob_logincontainer}>
						{(this.props.requestStatus) ?
							(
								<View style={css.ob_logincontainer}>
									<ActivityIndicator
										size="large"
										color="#fff"
										style={css.ob_loading_icon}
									/>
								</View>
							) : (
								<View style={css.ob_logincontainer}>
									<TextInput
										style={[css.ob_input, css.ob_login]}
										value={username}
										placeholder="User ID"
										placeholderTextColor={COLOR.DGREY}
										underlineColorAndroid={COLOR.TRANSPARENT}
										autoCapitalize="none"
										autoCorrect={false}
										returnKeyType="next"
										autoFocus={true}
										onChange={this.handleCredentialInput('username')}
										onSubmitEditing={(event) => {
											this.passInput.focus()
										}}
									/>
									<TextInput
										style={[css.ob_input, css.ob_pass]}
										value={password}
										ref={(input) => { this.passInput = input }}
										placeholder="Password"
										placeholderTextColor={COLOR.DGREY}
										underlineColorAndroid={COLOR.TRANSPARENT}
										autoCapitalize="none"
										secureTextEntry={true}
										returnKeyType="send"
										onChange={this.handleCredentialInput('password')}
										onSubmitEditing={() => this.onSubmit(username, password)}
									/>

									<Touchable
										onPress={() => this.onSubmit(username, password)}
										style={css.ob_loginButton}
									>
										<Text style={css.ob_loginText}>Sign in</Text>
									</Touchable>

									<View style={css.ob_actionscontainer}>
										<Touchable style={css.ob_help_button} onPress={() => openURL(AppSettings.ACCOUNT_HELP_URL)}>
											<Text style={css.ob_forgotpass}>Need help logging in?</Text>
										</Touchable>
										<Touchable style={css.ob_cancel_button} onPress={() => this.skipSSO()}>
											<Text style={css.ob_cancel}>Cancel</Text>
										</Touchable>
									</View>
								</View>
							)
						}
					</View>
				</View>
			</TouchableWithoutFeedback>
		)
	}
}

const mapStateToProps = (state, props) => (
	{
		user: state.user,
		onBoardingViewed: state.routes.onBoardingViewed,
		requestStatus: state.requestStatuses.LOG_IN,
		requestError: state.requestErrors.LOG_IN
	}
)

const mapDispatchToProps = (dispatch, ownProps) => (
	{
		setOnboardingViewed: (viewed) => {
			dispatch({
				type: 'SET_ONBOARDING_VIEWED',
				viewed
			})
		},
		doLogin: (username, password) => {
			dispatch({ type: 'USER_LOGIN', username, password })
		},
		doLogout: () => {
			dispatch({ type: 'USER_LOGOUT' })
		},
		timeoutLogin: () => {
			dispatch({ type: 'USER_LOGIN_TIMEOUT' })
		}
	}
)

export default connect(mapStateToProps, mapDispatchToProps)(OnboardingLogin)
<commit_msg>Disable autoactive keyboard<commit_after>import React from 'react'
import {
	Alert,
	View,
	Text,
	Image,
	ActivityIndicator,
	TextInput,
	TouchableWithoutFeedback
} from 'react-native'
import { connect } from 'react-redux'
import Toast from 'react-native-simple-toast'
import {
	openURL,
	hideKeyboard
} from '../../util/general'
import AppSettings from '../../AppSettings'
import Touchable from '../common/Touchable'
import css from '../../styles/css'
import COLOR from '../../styles/ColorConstants'

const auth = require('../../util/auth')

const campusLogo = require('../../assets/images/UCSanDiegoLogo-White.png')

class OnboardingLogin extends React.Component {
	constructor(props) {
		super(props)
		this.state = {
			credentials: {
				username: '',
				password: ''
			}
		}
	}

	componentDidMount() {
		// if we're mounting and we're somehow still in the
		// process of logging in, check if we've timed out.
		// otherwise, set a timeout
		if (this.props.requestStatus) {
			const now = new Date()
			const lastPostTime = new Date(this.props.requestStatus.timeRequested)
			if (now - lastPostTime >= AppSettings.SSO_TTL) {
				this.props.timeoutLogin()
			} else {
				// timeout after remaining time expires
				setTimeout(this.props.timeoutLogin, now - lastPostTime)
			}
		}
	}

	componentWillReceiveProps(nextProps) {
		if (nextProps.user.isLoggedIn) {
			Toast.showWithGravity(
				'Successfully signed in!',
				Toast.SHORT,
				Toast.BOTTOM
			)

			auth.retrieveAccessToken()
				.then((token) => {
					console.log('User Data: ', this.props.user)
					console.log('Access Token: ', token)
				})

			this.props.setOnboardingViewed(true)
		}
	}

	componentDidUpdate(prevProps, prevState) {
		const oldStatus = prevProps.requestStatus
		const newStatus = this.props.requestStatus

		// Only render alerts if status change is new
		if (oldStatus !== newStatus) {
			// Failed log in
			if (this.props.requestError) {
				Alert.alert(
					'Sign in error',
					this.props.requestError,
					{ cancelable: false }
				)
			}
		}
	}

	onSubmit = (username, password) => {
		this.props.doLogin(username, password)
	}

	handleCredentialInput = fieldName => (e) => {
		const { username, password } = this.state.credentials
		const newCredentials = { username, password }
		newCredentials[fieldName] = e.nativeEvent.text

		this.setState({ credentials: newCredentials })
	}

	skipSSO = () => {
		this.props.setOnboardingViewed(true)
	}

	render() {
		const { username, password } = this.state.credentials

		return (
			<TouchableWithoutFeedback onPress={() => hideKeyboard()}>
				<View style={css.ob_container}>
					<Image style={css.ob_logo} source={campusLogo} />

					<View style={css.ob_logincontainer}>
						{(this.props.requestStatus) ?
							(
								<View style={css.ob_logincontainer}>
									<ActivityIndicator
										size="large"
										color="#fff"
										style={css.ob_loading_icon}
									/>
								</View>
							) : (
								<View style={css.ob_logincontainer}>
									<TextInput
										style={[css.ob_input, css.ob_login]}
										value={username}
										placeholder="User ID"
										placeholderTextColor={COLOR.DGREY}
										underlineColorAndroid={COLOR.TRANSPARENT}
										autoCapitalize="none"
										autoCorrect={false}
										returnKeyType="next"
										onChange={this.handleCredentialInput('username')}
										onSubmitEditing={(event) => {
											this.passInput.focus()
										}}
									/>
									<TextInput
										style={[css.ob_input, css.ob_pass]}
										value={password}
										ref={(input) => { this.passInput = input }}
										placeholder="Password"
										placeholderTextColor={COLOR.DGREY}
										underlineColorAndroid={COLOR.TRANSPARENT}
										autoCapitalize="none"
										secureTextEntry={true}
										returnKeyType="send"
										onChange={this.handleCredentialInput('password')}
										onSubmitEditing={() => this.onSubmit(username, password)}
									/>

									<Touchable
										onPress={() => this.onSubmit(username, password)}
										style={css.ob_loginButton}
									>
										<Text style={css.ob_loginText}>Sign in</Text>
									</Touchable>

									<View style={css.ob_actionscontainer}>
										<Touchable style={css.ob_help_button} onPress={() => openURL(AppSettings.ACCOUNT_HELP_URL)}>
											<Text style={css.ob_forgotpass}>Need help logging in?</Text>
										</Touchable>
										<Touchable style={css.ob_cancel_button} onPress={() => this.skipSSO()}>
											<Text style={css.ob_cancel}>Cancel</Text>
										</Touchable>
									</View>
								</View>
							)
						}
					</View>
				</View>
			</TouchableWithoutFeedback>
		)
	}
}

const mapStateToProps = (state, props) => (
	{
		user: state.user,
		onBoardingViewed: state.routes.onBoardingViewed,
		requestStatus: state.requestStatuses.LOG_IN,
		requestError: state.requestErrors.LOG_IN
	}
)

const mapDispatchToProps = (dispatch, ownProps) => (
	{
		setOnboardingViewed: (viewed) => {
			dispatch({
				type: 'SET_ONBOARDING_VIEWED',
				viewed
			})
		},
		doLogin: (username, password) => {
			dispatch({ type: 'USER_LOGIN', username, password })
		},
		doLogout: () => {
			dispatch({ type: 'USER_LOGOUT' })
		},
		timeoutLogin: () => {
			dispatch({ type: 'USER_LOGIN_TIMEOUT' })
		}
	}
)

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


<commit_before>var React = require('react/addons'),
	classnames = require('classnames'),
	Tappable = require('react-tappable')

module.exports = React.createClass({
	displayName: 'KeypadButton',
	propTypes: {
		action: React.PropTypes.func,
		aux: React.PropTypes.bool,
		className: React.PropTypes.string,
		disabled: React.PropTypes.bool,
		primaryLabel: React.PropTypes.string,
		secondaryLabel: React.PropTypes.string,
		value: React.PropTypes.string
	},
	getDefaultProps: function() {
		return {
			action: function() {},
			className: '',
			secondaryLabel: ''
		};
	},
	render: function() {

		var className = classnames({
			'Keypad-button': true,
			'is-auxiliary': this.props.aux || this.props.delete,
			'disabled': this.props.disabled
		});

		var primaryLabel = this.props.primaryLabel ?
{this.props.primaryLabel}
 : null;
		var secondaryLabel = this.props.secondaryLabel ?
{this.props.secondaryLabel}
 : null;
		var icon = this.props.icon ?  : null;

		return (

				<Tappable onTap={this.props.action} className={className} component="div">
					{icon}
					{primaryLabel}
					{secondaryLabel}
				</Tappable>

		);
	}
});
<commit_msg>more delete keypad fixes<commit_after>var React = require('react/addons'),
	classnames = require('classnames'),
	Tappable = require('react-tappable')

module.exports = React.createClass({
	displayName: 'KeypadButton',
	propTypes: {
		action: React.PropTypes.func,
		aux: React.PropTypes.bool,
		className: React.PropTypes.string,
		disabled: React.PropTypes.bool,
		primaryLabel: React.PropTypes.string,
		secondaryLabel: React.PropTypes.string,
		value: React.PropTypes.string
	},
	getDefaultProps: function() {
		return {
			action: function() {},
			className: '',
			secondaryLabel: ''
		};
	},
	render: function() {

		var className = classnames({
			'Keypad-button': true,
			'is-auxiliary': this.props.aux || this.props['delete'],
			'disabled': this.props.disabled
		});

		var primaryLabel = this.props.primaryLabel ?
{this.props.primaryLabel}
 : null;
		var secondaryLabel = this.props.secondaryLabel ?
{this.props.secondaryLabel}
 : null;
		var icon = this.props.icon ?  : null;

		return (

				<Tappable onTap={this.props.action} className={className} component="div">
					{icon}
					{primaryLabel}
					{secondaryLabel}
				</Tappable>

		);
	}
});
<|endoftext|>


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

'use strict';

// security.js
var secure     = require('express-secure-only'),
  rateLimit    = require('express-rate-limit'),
  csrf         = require('csurf'),
  cookieParser = require('cookie-parser'),
  helmet       = require('helmet'),
  request      = require('request');

module.exports = function (app) {
  app.enable('trust proxy');

  // 1. redirects http to https
  app.use(secure());

  // 2. helmet with defaults
  app.use(helmet());

  // 3. allow iframes
  app.use(helmet.frameguard('allow-from', 'https://sentiment-and-emotion.mybluemix.net'));

  // 3. setup cookies
  var secret = Math.random().toString(36).substring(7);
  app.use(cookieParser(secret));

  // 4. csrf
  var csrfProtection = csrf({ cookie: true });
  app.get('/', csrfProtection, function(req, res, next) {
    req._csrfToken = req.csrfToken();
    next();
  });

  // 5. rate limiting
  var limiter = rateLimit({
    windowMs: 30 * 1000, // seconds
    delayMs: 0,
    max: 20,
    message: JSON.stringify({
      error:'Too many requests, please try again in 30 seconds.',
      code: 429
    }),
  });

  // 6. captcha
  var captchaKeys = {
    site: process.env.CAPTCHA_SITE || '<captcha-site>',
    secret: process.env.CAPTCHA_SECRET || '<captcha-secret>',
  };

  var checkCaptcha = function(req, res, next) {
    if (req.body && req.body.recaptcha) {
      request({
        url: 'https://www.google.com/recaptcha/api/siteverify',
        method: 'POST',
        form: {
          secret: captchaKeys.secret,
          response: req.body.recaptcha,
          remoteip: req.ip
        },
        json: true
      }, function(error, response, body) {
        if (body.success) {
          limiter.resetIp(req.ip);
          next();
        } else {
          next({
            code: 'EBADCSRFTOKEN',
            error: 'Wrong captcha'
          });
        }
      });
    } else {
      next();
    }
  };

  app.use('/api/', csrfProtection, checkCaptcha, limiter);
};
<commit_msg>Limited requests to alchemy api: 500 request/24hs<commit_after>/**
 * Copyright 2015 IBM Corp. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// security.js
var secure     = require('express-secure-only'),
  rateLimit    = require('express-rate-limit'),
  csrf         = require('csurf'),
  cookieParser = require('cookie-parser'),
  helmet       = require('helmet'),
  request      = require('request');

module.exports = function (app) {
  app.enable('trust proxy');

  // 1. redirects http to https
  app.use(secure());

  // 2. helmet with defaults
  app.use(helmet());

  // 3. allow iframes
  app.use(helmet.frameguard('allow-from', 'https://sentiment-and-emotion.mybluemix.net'));

  // 3. setup cookies
  var secret = Math.random().toString(36).substring(7);
  app.use(cookieParser(secret));

  // 4. csrf
  var csrfProtection = csrf({ cookie: true });
  app.get('/', csrfProtection, function(req, res, next) {
    req._csrfToken = req.csrfToken();
    next();
  });

  // 5. rate limiting
  var limiterError = {
    error : 'Too many requests, please try again in 30 seconds.',
    code  : 429
  };
  var limiter = rateLimit({
    windowMs: 24 * 60 * 60 * 1000, // 24 hours
    delayMs: 0,
    max: 500,
    handler: function (req, res) {
      res.format({
        html: function(){
          res.status(limiterError.code).end(limiterError.error);
        },
        json: function(){
          res.status(limiterError.code).json(limiterError);
        }
      });
    },
  });

  // 6. captcha
  var captchaKeys = {
    site: process.env.CAPTCHA_SITE || '<captcha-site>',
    secret: process.env.CAPTCHA_SECRET || '<captcha-secret>',
  };

  var checkCaptcha = function(req, res, next) {
    if (req.body && req.body.recaptcha) {
      request({
        url: 'https://www.google.com/recaptcha/api/siteverify',
        method: 'POST',
        form: {
          secret: captchaKeys.secret,
          response: req.body.recaptcha,
          remoteip: req.ip
        },
        json: true
      }, function(error, response, body) {
        if (body.success) {
          limiter.resetIp(req.ip);
          next();
        } else {
          next({
            code: 'EBADCSRFTOKEN',
            error: 'Wrong captcha'
          });
        }
      });
    } else {
      next();
    }
  };

  app.use('/api/', csrfProtection, checkCaptcha, limiter);
};
<|endoftext|>


<commit_before>/*
 *  PubNubTransport.js
 *
 *  David Janes
 *  IOTDB.org
 *  2015-04-01
 *  "April Fool's Day"
 *
 *  Copyright [2013-2015] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var iotdb = require('iotdb');
var iotdb_transport = require('iotdb-transport');
var _ = iotdb._;

var path = require('path');
var pubnub = require('pubnub');

var util = require('util');
var url = require('url');

var logger = iotdb.logger({
    name: 'iotdb-transport-proto',
    module: 'PubNubTransport',
});

/* --- constructor --- */

/**
 *  See {iotdb_transport.Transport#Transport} for documentation.
 */
var PubNubTransport = function (initd) {
    var self = this;

    self.initd = _.defaults(
        initd,
        {
            channel: iotdb_transport.channel,
            unchannel: iotdb_transport.unchannel,
            encode: _encode,
            decode: _decode,
            pack: _pack,
            unpack: _unpack,
        },
        iotdb.keystore().get("/transports/PubNubTransport/initd"),
        {
            prefix: ""
        }
    );

    self.native = pubnub({
        ssl: true,
        publish_key: self.initd.publish_key,
        subscribe_key: self.initd.subscribe_key,
    });
};

PubNubTransport.prototype = new iotdb_transport.Transport;
PubNubTransport.prototype._class = "PubNubTransport";

/* --- methods --- */

/**
 *  See {iotdb_transport.Transport#list} for documentation.
 *

 *  PubNub does not support list
 */
PubNubTransport.prototype.list = function(paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_list(paramd, callback);

    callback({
        end: true,
        error: new Error("N/A"),
    });
};

/**
 *  See {iotdb_transport.Transport#added} for documentation.
 */
PubNubTransport.prototype.added = function(paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_added(paramd, callback);

    var channel = self.initd.channel(self.initd);
};

/**
 *  See {iotdb_transport.Transport#get} for documentation.
 */
PubNubTransport.prototype.get = function(paramd, callback) {
    var self = this;

    self._validate_get(paramd, callback);

    var channel = self.initd.channel(self.initd, id, band);

    // callback(id, band, null); does not exist
    // OR
    // callback(id, band, undefined); don't know
    // OR
    // callback(id, band, d); data
};

/**
 *  See {iotdb_transport.Transport#update} for documentation.
 */
PubNubTransport.prototype.put = function(paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_update(paramd, callback);

    var channel = self.initd.channel(id, band);
    var d = _pack(value);

    self.native.publish({
        channel: channel,
        message: d,
        callback: function(e) {
            console.log( "SUCCESS!", e, d );
        },
        error: function(e) {
            console.log( "FAILED! RETRY PUBLISH!", e );
        }
    });
};

/**
 *  See {iotdb_transport.Transport#updated} for documentation.
 */
PubNubTransport.prototype.updated = function(paramd, callback) {
    var self = this;

    self._validate_updated(paramd, callback);

    var channel = self.initd.channel(id, band);

    self.native.subscribe({
        channel: channel,
        callback: function(messaged) {
            callback(id, band, _unpack(messaged));
        }
    });
};

/**
 *  See {iotdb_transport.Transport#remove} for documentation.
 */
PubNubTransport.prototype.remove = function(paramd, callback) {
    var self = this;

    self._validate_remove(paramd, callback);
};

/* -- internals -- */
var _encode = function(s) {
    return s.replace(/[\/$%#.\]\[]/g, function(c) {
        return '%' + c.charCodeAt(0).toString(16);
    });
};

var _decode = function(s) {
    return decodeURIComponent(s);
}

var _unpack = function(d) {
    return _.d.transform(d, {
        pre: _.ld_compact,
    });
};

var _pack = function(d) {
    return _.d.transform(d, {
        pre: _.ld_compact,
    });
};

/**
 *  API
 */
exports.PubNubTransport = PubNubTransport;
<commit_msg>no defaulting arguments<commit_after>/*
 *  PubNubTransport.js
 *
 *  David Janes
 *  IOTDB.org
 *  2015-04-01
 *  "April Fool's Day"
 *
 *  Copyright [2013-2015] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var iotdb = require('iotdb');
var iotdb_transport = require('iotdb-transport');
var _ = iotdb._;

var path = require('path');
var pubnub = require('pubnub');

var util = require('util');
var url = require('url');

var logger = iotdb.logger({
    name: 'iotdb-transport-proto',
    module: 'PubNubTransport',
});

/* --- constructor --- */

/**
 *  See {iotdb_transport.Transport#Transport} for documentation.
 */
var PubNubTransport = function (initd) {
    var self = this;

    self.initd = _.defaults(
        initd,
        {
            channel: iotdb_transport.channel,
            unchannel: iotdb_transport.unchannel,
            encode: _encode,
            decode: _decode,
            pack: _pack,
            unpack: _unpack,
        },
        iotdb.keystore().get("/transports/PubNubTransport/initd"),
        {
            prefix: ""
        }
    );

    self.native = pubnub({
        ssl: true,
        publish_key: self.initd.publish_key,
        subscribe_key: self.initd.subscribe_key,
    });
};

PubNubTransport.prototype = new iotdb_transport.Transport;
PubNubTransport.prototype._class = "PubNubTransport";

/* --- methods --- */

/**
 *  See {iotdb_transport.Transport#list} for documentation.
 *

 *  PubNub does not support list
 */
PubNubTransport.prototype.list = function(paramd, callback) {
    var self = this;

    self._validate_list(paramd, callback);

    callback({
        end: true,
        error: new Error("N/A"),
    });
};

/**
 *  See {iotdb_transport.Transport#added} for documentation.
 */
PubNubTransport.prototype.added = function(paramd, callback) {
    var self = this;

    self._validate_added(paramd, callback);

    var channel = self.initd.channel(self.initd);
};

/**
 *  See {iotdb_transport.Transport#get} for documentation.
 */
PubNubTransport.prototype.get = function(paramd, callback) {
    var self = this;

    self._validate_get(paramd, callback);

    var channel = self.initd.channel(self.initd, id, band);

    // callback(id, band, null); does not exist
    // OR
    // callback(id, band, undefined); don't know
    // OR
    // callback(id, band, d); data
};

/**
 *  See {iotdb_transport.Transport#update} for documentation.
 */
PubNubTransport.prototype.put = function(paramd, callback) {
    var self = this;

    self._validate_update(paramd, callback);

    var channel = self.initd.channel(id, band);
    var d = _pack(value);

    self.native.publish({
        channel: channel,
        message: d,
        callback: function(e) {
            console.log( "SUCCESS!", e, d );
        },
        error: function(e) {
            console.log( "FAILED! RETRY PUBLISH!", e );
        }
    });
};

/**
 *  See {iotdb_transport.Transport#updated} for documentation.
 */
PubNubTransport.prototype.updated = function(paramd, callback) {
    var self = this;

    self._validate_updated(paramd, callback);

    var channel = self.initd.channel(id, band);

    self.native.subscribe({
        channel: channel,
        callback: function(messaged) {
            callback(id, band, _unpack(messaged));
        }
    });
};

/**
 *  See {iotdb_transport.Transport#remove} for documentation.
 */
PubNubTransport.prototype.remove = function(paramd, callback) {
    var self = this;

    self._validate_remove(paramd, callback);
};

/* -- internals -- */
var _encode = function(s) {
    return s.replace(/[\/$%#.\]\[]/g, function(c) {
        return '%' + c.charCodeAt(0).toString(16);
    });
};

var _decode = function(s) {
    return decodeURIComponent(s);
}

var _unpack = function(d) {
    return _.d.transform(d, {
        pre: _.ld_compact,
    });
};

var _pack = function(d) {
    return _.d.transform(d, {
        pre: _.ld_compact,
    });
};

/**
 *  API
 */
exports.PubNubTransport = PubNubTransport;
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tex2svg = require( 'tex-equation-to-svg' );
var mkdirp = require( 'mkdirp' );
var visit = require( 'unist-util-visit' );
var path = require( 'path' );
var fs = require( 'fs' );

// CONSTANTS //

var DIV_EQN = /
/;
var RAW = /data-raw-text="([^"]*)"/;

// TRANSFORMER //

/**
* Transforms a Markdown file.
*
* @private
* @param {Node} ast - root node
* @param {File} file - Virtual file.
*/
function transformer( ast, file ) {
	// Create ./docs/img folder to house SVGs
	mkdirp( path.join( file.directory, '/docs/img' ), onDone );

	/**
	* Callback invoked upon creating the /docs/img directory.
	*
	* @private
	* @param {Error|null} err - error object
	*/
	function onDone( err ) {
		if ( err ) {
			throw err;
		}
		visit( ast, 'html', generateSVGs );
	} // end FUNCTION onDone()

	/**
	* Generate SVGs for DIV equations in the Markdown file.
	*
	* @private
	* @param {Node} node - reference node
	*/
	function generateSVGs( node ) {
		var label;
		var raw;
		if ( DIV_EQN.test( node.value) === true ) {
			label = LABEL.exec( node.value )[ 1 ];
			raw = RAW.exec( node.value )[ 1 ];
			createSVG( raw, label );
		}
	} // end FUNCTION generateSVGs()

	/**
	* Create SVG for the respective equation.
	*
	* @private
	* @param {string} tex - equation LaTeX formula
	* @param {string} label - equation label (used to generate filename)
	* @param {Function} clbk - callback function
	*/
	function createSVG( tex, label, clbk ) {
		tex2svg( tex, saveSVG );
		/**
		* Save created SVG to disk.
		*
		* @private
		* @param {Error|null} err - error object
		* @param {string} svg - SVG code
		*/
		function saveSVG( err, svg ) {
			var outfile;
			if ( err ) {
				throw err;
			}
			outfile = path.join( file.directory, '/docs/img/' + label + '.svg' );
			fs.writeFile( outfile, svg, clbk );
		} // end FUNCTION saveSVG()
	} // end FUNCTION createSVG()

} // end FUNCTION transformer()

// EXPORTS //

module.exports = transformer;
<commit_msg>Add missing space<commit_after>'use strict';

// MODULES //

var tex2svg = require( 'tex-equation-to-svg' );
var mkdirp = require( 'mkdirp' );
var visit = require( 'unist-util-visit' );
var path = require( 'path' );
var fs = require( 'fs' );

// CONSTANTS //

var DIV_EQN = /
/;
var RAW = /data-raw-text="([^"]*)"/;

// TRANSFORMER //

/**
* Transforms a Markdown file.
*
* @private
* @param {Node} ast - root node
* @param {File} file - Virtual file.
*/
function transformer( ast, file ) {
	// Create ./docs/img folder to house SVGs
	mkdirp( path.join( file.directory, '/docs/img' ), onDone );

	/**
	* Callback invoked upon creating the /docs/img directory.
	*
	* @private
	* @param {Error|null} err - error object
	*/
	function onDone( err ) {
		if ( err ) {
			throw err;
		}
		visit( ast, 'html', generateSVGs );
	} // end FUNCTION onDone()

	/**
	* Generate SVGs for DIV equations in the Markdown file.
	*
	* @private
	* @param {Node} node - reference node
	*/
	function generateSVGs( node ) {
		var label;
		var raw;
		if ( DIV_EQN.test( node.value ) === true ) {
			label = LABEL.exec( node.value )[ 1 ];
			raw = RAW.exec( node.value )[ 1 ];
			createSVG( raw, label );
		}
	} // end FUNCTION generateSVGs()

	/**
	* Create SVG for the respective equation.
	*
	* @private
	* @param {string} tex - equation LaTeX formula
	* @param {string} label - equation label (used to generate filename)
	* @param {Function} clbk - callback function
	*/
	function createSVG( tex, label, clbk ) {
		tex2svg( tex, saveSVG );
		/**
		* Save created SVG to disk.
		*
		* @private
		* @param {Error|null} err - error object
		* @param {string} svg - SVG code
		*/
		function saveSVG( err, svg ) {
			var outfile;
			if ( err ) {
				throw err;
			}
			outfile = path.join( file.directory, '/docs/img/' + label + '.svg' );
			fs.writeFile( outfile, svg, clbk );
		} // end FUNCTION saveSVG()
	} // end FUNCTION createSVG()

} // end FUNCTION transformer()

// EXPORTS //

module.exports = transformer;
<|endoftext|>


<commit_before>const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const packageJson = require('./package.json');

const buildUmd = {
  input: 'lib/index.js',
  output: {
    file: packageJson.main,
    format: 'umd',
    name: 'gavel',
    exports: 'named',
    sourcemap: true
  },
  plugins: [
    resolve({
      browser: true,

      // Forbid bundling of NodeJS built-ins (i.e. "fs", "path").
      // Throw when such modules are present in the bundle.
      preferBuiltins: false
    }),
    commonjs()
  ]
};

module.exports = [buildUmd];
<commit_msg>chore: uses "@rollup/plugin-json" to import ".json" modules<commit_after>const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const json = require('@rollup/plugin-json/dist');
const packageJson = require('./package.json');

const buildUmd = {
  input: 'lib/index.js',
  output: {
    file: packageJson.main,
    format: 'umd',
    name: 'gavel',
    exports: 'named',
    sourcemap: true
  },
  plugins: [
    resolve({
      browser: true,

      // Forbid bundling of NodeJS built-ins (i.e. "fs", "path").
      // Throw when such modules are present in the bundle.
      preferBuiltins: false
    }),
    json(),
    commonjs()
  ]
};

module.exports = [buildUmd];
<|endoftext|>


<commit_before>function change_type(event,id){
	$(event.target).parent().html('公益组织
企业
公益人
基金会');
}
function change_event_type(event,id){
    $(event.target).parent().html('公益活动
企业活动
对接案例');
}
function change_type_to(type, id, event){
	$.get(app_path+"/Admin/change_type", {'id': id, 'type': type}, function(result){
		$(event.target).parent().html($(event.target).text()+'切换');
	});
}
function change_event_type_to(type, id, event){
    $.get(app_path+"/Admin/change_event_type", {'id': id, 'type': type}, function(result){
        $(event.target).parent().html($(event.target).text()+'切换');
    });
}

//全选当前页事件
function CheckAll(strSection)
{
    var i;
    var colInputs = $('.'+strSection).find('input');
    for(i=1;i<colInputs.length;i++)
    {
        colInputs[i].checked=colInputs[0].checked;
    }
}

//获取已选事件ids
function getSelectCheckboxValues(){
	var obj = document.getElementsByName('key');
	var result ='';
	for (var i=0;i<obj.length;i++)
	{
		if (obj[i].checked==true)
				result += obj[i].value+",";

	}
	return result.substring(0, result.length-1);
}

//点击批量操作标签响应事件
function batch(item,action,type){
	var keyValue= getSelectCheckboxValues();

	if (!keyValue)
	{
		alert(check_word);
		return false;
	}
    else{
        $(item).fastConfirm({
                position: "right",
                questionText:lock_word,
                onProceed: function(trigger) {
                       window.location.href=app_path+'/Admin/batch/ids/'+keyValue+'/action/'+action+'/type/'+type;
                },
                onCancel: function(trigger) {
                }
        });
         return false;
    }
}

console.log('admin.loaded');<commit_msg>change event type bug<commit_after>function change_type(event,id){
	$(event.target).parent().html('公益组织
企业
公益人
基金会');
}
function change_event_type(event,id){
    $(event.target).parent().html('公益活动
企业活动
对接案例');
}
function change_type_to(type, id, event){
	$.get(app_path+"/Admin/change_type", {'id': id, 'type': type}, function(result){
		$(event.target).parent().html($(event.target).text()+'切换');
	});
}
function change_event_type_to(type, id, event){
    $.get(app_path+"/Admin/change_event_type", {'id': id, 'type': type}, function(result){
        $(event.target).parent().html($(event.target).text()+'切换');
    });
}

//全选当前页事件
function CheckAll(strSection)
{
    var i;
    var colInputs = $('.'+strSection).find('input');
    for(i=1;i<colInputs.length;i++)
    {
        colInputs[i].checked=colInputs[0].checked;
    }
}

//获取已选事件ids
function getSelectCheckboxValues(){
	var obj = document.getElementsByName('key');
	var result ='';
	for (var i=0;i<obj.length;i++)
	{
		if (obj[i].checked==true)
				result += obj[i].value+",";

	}
	return result.substring(0, result.length-1);
}

//点击批量操作标签响应事件
function batch(item,action,type){
	var keyValue= getSelectCheckboxValues();

	if (!keyValue)
	{
		alert(check_word);
		return false;
	}
    else{
        $(item).fastConfirm({
                position: "right",
                questionText:lock_word,
                onProceed: function(trigger) {
                       window.location.href=app_path+'/Admin/batch/ids/'+keyValue+'/action/'+action+'/type/'+type;
                },
                onCancel: function(trigger) {
                }
        });
         return false;
    }
}

console.log('admin.loaded');<|endoftext|>


<commit_before>import babel       from "rollup-plugin-babel"
import nodeResolve from "rollup-plugin-node-resolve"
import replace     from "rollup-plugin-replace"
import uglify      from "rollup-plugin-uglify"

export default {
  external: ["infestines", "partial.lenses", "kefir"],
  globals: {"infestines": "I", "partial.lenses": "L"},
  plugins: [].concat(
    process.env.NODE_ENV
    ? [replace({"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)})]
    : [],
    [nodeResolve()],
    [babel()],
    process.env.NODE_ENV === "production"
    ? [uglify()]
    : []
  )
}
<commit_msg>Refactor<commit_after>import babel       from "rollup-plugin-babel"
import nodeResolve from "rollup-plugin-node-resolve"
import replace     from "rollup-plugin-replace"
import uglify      from "rollup-plugin-uglify"

export default {
  external: ["infestines", "partial.lenses", "kefir"],
  globals: {"infestines": "I", "partial.lenses": "L"},
  plugins: [
    process.env.NODE_ENV &&
      replace({"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)}),
    nodeResolve(),
    babel(),
    process.env.NODE_ENV === "production" &&
      uglify()
  ].filter(x => x)
}
<|endoftext|>