<commit_before>var stephanie=[]
var xander = []
var jesse = []
var dataObj = {}
var fullClient = retinaSDK.FullClient("9d562520-d285-11e5-8378-4dad29be0fab")
var liteClient = retinaSDK.LiteClient("9d562520-d285-11e5-8378-4dad29be0fab")
$(document).ready(function(){
  getInfo()
  window.setTimeout(compare, 1000)

})

var reallyGetInfo = getInfo()

function getInfo(){
    getStephanieFacebook()
    getXanderFacebook()
    getXanderLinkedIn()
    getStephanieLinkedIn()
    getSMHTwitter()
    getXTwitter()
    getJFB()
    getJLN()
  }

function getJFB(){
 $.get("scraped/jcfb.json", function(response){
    addFBData(response, jesse)
    return true
  })
}

function getJLN(){
   $.get("scraped/jcln.json", function(response){
    addLNData(response, jesse)
    return true
  })
}

function appendImg(location,img){
  $('\#'+location).append( "")
}

function getSMHTwitter(){
  $.get("scraped/amuttican.json", function(response){
    response["results"]["collection1"].map( tweet => stephanie.push(tweet["twitter"]))
    return true
  })
}

function getXTwitter(){
  $.get("scraped/XPSON.json", function(response){
    response["results"]["collection1"].map( tweet => xander.push(tweet["twitter"]) )
    return true
  })
}

function compare(){
  getXPmap()
  getSMHmap()
  compareBulk()
  // $.get("scraped/XPSON.json", function(response){
    // response["results"]["collection1"].map( tweet => xander.push(tweet["twitter"]))
    fullClient.compareImage({expressions: [{"text": stephanie.join(" ")}, {"text": xander.join(" ")}]}, function(img){
      dataObj.comparison = img
    })
  // })
}

function getStephanieFacebook(){
  $.get("scraped/smhfb.json", function(response){
    addFBData(response, stephanie)
    return true
  })

}
function getXanderFacebook(){
  $.ajax({url: "scraped/xpFB.json"})
  .done(function(response){addFBData(response, xander)})
    return true
}
function getXanderLinkedIn(){
  $.ajax({url: "scraped/xpLN.json"})
  .done(function(response){
    addLNData(response, xander)
    return true
  })
}
function getStephanieLinkedIn(){
  $.ajax({url: "scraped/smhLN.json"})
  .done(function(response){
    addLNData(response, stephanie)
    return true
  })
}

function log(response){
  console.log(response)

}
function addLNData(lndata, person) {
  person.push(lndata.summary)
  // console.log(lndata.threeCurrentPositions.values)
  lndata.threePastPositions.values.map(job => person.push(job.summary))

  try {lndata.volunteer.volunteerExperiences.values.map(job => person.push(job.role))}
  catch (e){}
  try {lndata.threeCurrentPositions.values.map(job => person.push(job.summary))}
  catch (e){}
  // console.log(person)
}

function addFBData(fbdata, person) {
  // console.log(fbdata)
  var person = person
  fbdata.likes.data.map( like => person.push(like.name))
  person.push(fbdata.about)
  fbdata.feed.data.map( post => post.message ? person.push(post.message) : person )
  fbdata.books.data.map( book => person.push(book.name))

  fbdata.music.data.map( artist => person.push( artist.name ))

}

function getXPmap(){
  fullClient.getImage({expression: {"text": xander.join()}}, addToMapsX)
}

function getSMHmap(){
  fullClient.getImage({expression: {"text": stephanie.join()}}, addToMapsS)
}

function getJCmap(){
  fullClient.getInfo({expression: {"text": jesse.join()}}, addToMapsJ)
}

function addToMapsX(img){
    dataObj.xander = img
}
function addToMapsS(img){
    dataObj.stephanie = img
}

function addToMapsJ(img){
  dataObj.jesse = img
}

function compareBulk(){
  c1=[]
  c2=[]
  c3=[]

  fullClient.getKeywordsForText({"text": xander.join(" ")}, function(response){
    response.map( term => term != "https" && term != "http" && term != "com" ? c1.push(term) : term )
    fullClient.getKeywordsForText({"text": stephanie.join(" ")}, function(response){
      response.map( term => term != "https" && term != "http" && term != "com" ? c2.push(term) : term )
      dataObj.xanTerms= c1
      dataObj.stephTerms= c2
      fullClient.getKeywordsForText({"text": jesse.join(" ")}, function(response){
        response.map( term => term != "https" && term != "http" && term != "com" ? c3.push(term) : term )
        dataObj.jesseTerms = c3
      })
    })
  })
}

function addAllImgs(){
  appendImg(my_fingerprint, dataObj.xander)
  appendImg(my_fingerprint, dataObj.stephanie)
  appendImg(my_fingerprint, dataObj.comparison)
}

<commit_msg>add vars<commit_after>var stephanie=[]
var xander = []
var jesse = []
var dataObj = {}
var fullClient = retinaSDK.FullClient("9d562520-d285-11e5-8378-4dad29be0fab")
var liteClient = retinaSDK.LiteClient("9d562520-d285-11e5-8378-4dad29be0fab")
$(document).ready(function(){
  getInfo()
  window.setTimeout(compare, 1000)

})

var reallyGetInfo = getInfo()

function getInfo(){
    getStephanieFacebook()
    getXanderFacebook()
    getXanderLinkedIn()
    getStephanieLinkedIn()
    getSMHTwitter()
    getXTwitter()
    getJFB()
    getJLN()
  }

function getJFB(){
 $.get("scraped/jcfb.json", function(response){
    addFBData(response, jesse)
    return true
  })
}

function getJLN(){
   $.get("scraped/jcln.json", function(response){
    addLNData(response, jesse)
    return true
  })
}

function appendImg(location,img){
  $('\#'+location).append( "")
}

function getSMHTwitter(){
  $.get("scraped/amuttican.json", function(response){
    response["results"]["collection1"].map( tweet => stephanie.push(tweet["twitter"]))
    return true
  })
}

function getXTwitter(){
  $.get("scraped/XPSON.json", function(response){
    response["results"]["collection1"].map( tweet => xander.push(tweet["twitter"]) )
    return true
  })
}

function compare(){
  getXPmap()
  getSMHmap()
  compareBulk()
  // $.get("scraped/XPSON.json", function(response){
    // response["results"]["collection1"].map( tweet => xander.push(tweet["twitter"]))
    fullClient.compareImage({expressions: [{"text": stephanie.join(" ")}, {"text": xander.join(" ")}]}, function(img){
      dataObj.comparison = img
    })
  // })
}

function getStephanieFacebook(){
  $.get("scraped/smhfb.json", function(response){
    addFBData(response, stephanie)
    return true
  })

}
function getXanderFacebook(){
  $.ajax({url: "scraped/xpFB.json"})
  .done(function(response){addFBData(response, xander)})
    return true
}
function getXanderLinkedIn(){
  $.ajax({url: "scraped/xpLN.json"})
  .done(function(response){
    addLNData(response, xander)
    return true
  })
}
function getStephanieLinkedIn(){
  $.ajax({url: "scraped/smhLN.json"})
  .done(function(response){
    addLNData(response, stephanie)
    return true
  })
}

function log(response){
  console.log(response)

}
function addLNData(lndata, person) {
  person.push(lndata.summary)
  // console.log(lndata.threeCurrentPositions.values)
  lndata.threePastPositions.values.map(job => person.push(job.summary))

  try {lndata.volunteer.volunteerExperiences.values.map(job => person.push(job.role))}
  catch (e){}
  try {lndata.threeCurrentPositions.values.map(job => person.push(job.summary))}
  catch (e){}
  // console.log(person)
}

function addFBData(fbdata, person) {
  // console.log(fbdata)
  var person = person
  fbdata.likes.data.map( like => person.push(like.name))
  person.push(fbdata.about)
  fbdata.feed.data.map( post => post.message ? person.push(post.message) : person )
  fbdata.books.data.map( book => person.push(book.name))

  fbdata.music.data.map( artist => person.push( artist.name ))

}

function getXPmap(){
  fullClient.getImage({expression: {"text": xander.join()}}, addToMapsX)
}

function getSMHmap(){
  fullClient.getImage({expression: {"text": stephanie.join()}}, addToMapsS)
}

function getJCmap(){
  fullClient.getInfo({expression: {"text": jesse.join()}}, addToMapsJ)
}

function addToMapsX(img){
    dataObj.xander = img
}
function addToMapsS(img){
    dataObj.stephanie = img
}

function addToMapsJ(img){
  dataObj.jesse = img
}

function compareBulk(){
  var c1=[]
  var c2=[]
  var c3=[]

  fullClient.getKeywordsForText({"text": xander.join(" ")}, function(response){
    response.map( term => term != "https" && term != "http" && term != "com" ? c1.push(term) : term )
    fullClient.getKeywordsForText({"text": stephanie.join(" ")}, function(response){
      response.map( term => term != "https" && term != "http" && term != "com" ? c2.push(term) : term )
      dataObj.xanTerms= c1
      dataObj.stephTerms= c2
      fullClient.getKeywordsForText({"text": jesse.join(" ")}, function(response){
        response.map( term => term != "https" && term != "http" && term != "com" ? c3.push(term) : term )
        dataObj.jesseTerms = c3
      })
    })
  })
}

function addAllImgs(){
  appendImg(my_fingerprint, dataObj.xander)
  appendImg(my_fingerprint, dataObj.stephanie)
  appendImg(my_fingerprint, dataObj.comparison)
}

<|endoftext|>


<commit_before>class JSRange {
  constructor (el, options) {
    this._updateObject = this._update
    this._eventsObject = this._events

    this.options = options
    this.selected = {
      min: this.options.min,
      max: this.options.max
    }

    this._createBody(el)
    this._bindEvents()
    this.update()
  }

  // Propably we want to update everything
  update () {
    this._update.all()
  }

  set (hash = {}) {
    if (hash.min) {
      this.selected.min = hash.min
    }

    if (hash.max) {
      this.selected.max = hash.max
    }

    this.update()
  }

  _createBody (el) {
    this.body = {}

    this.body.parent = document.querySelector(el)
    this.body.parent.classList.add('jsr')

    this.body.rail = document.createElement('div')
    this.body.rail.classList.add('jsr_rail')

    this.body.sliders = {}
    this.body.sliders.min = document.createElement('div')
    this.body.sliders.min.classList.add('jsr_slider', 'jsr_slider--min')
    this.body.sliders.min.dataset.jsrType = 'min'
    this.body.sliders.max = document.createElement('div')
    this.body.sliders.max.classList.add('jsr_slider', 'jsr_slider--max')
    this.body.sliders.max.dataset.jsrType = 'max'

    this.body.info = {}
    this.body.info.min = document.createElement('span')
    this.body.info.min.classList.add('jsr_info', 'jsr_info--min')
    this.body.info.max = document.createElement('span')
    this.body.info.max.classList.add('jsr_info', 'jsr_info--max')
    this.body.info.actualMin = document.createElement('span')
    this.body.info.actualMin.classList.add('jsr_info', 'jsr_info--actualMin')
    this.body.info.actualMax = document.createElement('span')
    this.body.info.actualMax.classList.add('jsr_info', 'jsr_info--actualMax')

    let elements = [
      this.body.rail,
      this.body.sliders.min,
      this.body.sliders.max,
      this.body.info.min,
      this.body.info.max,
      this.body.info.actualMin,
      this.body.info.actualMax
    ]

    elements.forEach((element) => {
      this.body.parent.appendChild(element)
    })
  }

  _validateAndSave (type, value) {
    if (type === 'min') {
      if (value < this.options.min) {
        value = this.options.min
      }

      if (value > this.selected.max) {
        value = this.selected.max
      }
    }

    if (type === 'max') {
      if (value > this.options.max) {
        value = this.options.max
      }

      if (value < this.selected.min) {
        value = this.selected.min
      }
    }

    this.selected[type] = value
  }

  _bindEvents () {
    this.body.sliders.min.addEventListener('mousedown', this._events.sliderMouseDown)
    this.body.sliders.max.addEventListener('mousedown', this._events.sliderMouseDown)
    document.addEventListener('mousemove', this._events.sliderMouseMove)
    document.addEventListener('mouseup', this._events.sliderMouseUp)

    this.body.rail.addEventListener('click', this._events.railClick)
  }

  // _update returns all events available to use
  // it tries to use the buffering-variable (_eventsObject) to not recreate this big object every time
  get _events () {
    var _this = this;
    return _this._eventsObject || {
      sliderMouseDown: function (event) {
        event.preventDefault() // prevents selecting text
        window.jsrMoveObject = event.target
      },
      sliderMouseUp: function (event) {
        window.jsrMoveObject = null
      },
      sliderMouseMove: function (event) {
        if (window.jsrMoveObject) {
          let type = window.jsrMoveObject.dataset.jsrType
          let mouseX = event.clientX
          let railLeft = _this.body.rail.getBoundingClientRect().left
          let diff = mouseX - railLeft
          let newSelected = parseInt(diff / _this.body.rail.offsetWidth * _this.options.max)
          _this._validateAndSave(type, newSelected)
          _this.update()
        }
      },
      railClick: function (event) {
        // determine closer to which slider it was closer
        let mouseX = event.clientX
        let railLeft = _this.body.rail.getBoundingClientRect().left
        let diff = mouseX - railLeft
        let clickedValue = parseInt(diff / _this.body.rail.offsetWidth * _this.options.max)

        // compare absolute distance between clickedValue and selected.min/max
        // closer to zero, means closer to min/max
        if (Math.abs(_this.selected.min - clickedValue) < Math.abs(_this.selected.max - clickedValue)) {
          // closer to min
          _this.selected.min = clickedValue
        } else {
          // closer to max
          _this.selected.max = clickedValue
        }

        _this.update()
      }
    }
  }

  // _update returns all methods available to use to update things
  // it tries to use the buffering-variable (_updateObject) to not recreate this big object every time
  get _update () {
    var _this = this;
    return _this._updateObject || {
      // Here goes every function which should be updated via .all()
      // 'info' should be after 'sliders'
      _toUpdate: ['rail', 'sliders', 'info'],
      all: function () {
        this._toUpdate.forEach((item) => {
          this[item]() // Call certain update function
        })
      },

      rail: function (min = _this.selected.min, max = _this.selected.max) {
        // Calc rail color position
        let start = min / _this.options.max
        let end = max / _this.options.max
        // Calc real start (because of weird percentage work)
        let realStart = start / (1 - (end - start))

        // Sets colored part of rail
        // Expects percentages without % sign
        _this.body.rail.style.backgroundPosition = `${realStart * 100}% 0`
        _this.body.rail.style.backgroundSize = `${(end - start) * 100}% 100%`
      },

      info: function () {
        _this.body.info.min.innerHTML = _this.options.min
        _this.body.info.max.innerHTML = _this.options.max
        _this.body.info.actualMin.innerHTML = _this.selected.min
        _this.body.info.actualMax.innerHTML = _this.selected.max

        // minWidth and maxWidth include widths of sliders
        let minWidth = _this.body.info.actualMin.offsetWidth - _this.body.sliders.min.offsetWidth
        let maxWidth = _this.body.info.actualMax.offsetWidth - _this.body.sliders.max.offsetWidth
        _this.body.info.actualMin.style.left = `calc(${_this.body.sliders.min.style.left} - ${minWidth}px / 2)`
        _this.body.info.actualMax.style.left = `calc(${_this.body.sliders.max.style.left} - ${maxWidth}px / 2)`
      },

      sliders: function (min = _this.selected.min, max = _this.selected.max) {
        let startWidthRatio = _this.body.sliders.min.offsetWidth / _this.body.rail.offsetWidth
        let endWidthRatio = _this.body.sliders.max.offsetWidth / _this.body.rail.offsetWidth
        // widthRatio is used to place middle point of slider in the right point
        let start = min / _this.options.max - startWidthRatio / 2
        let end = max / _this.options.max - endWidthRatio / 2

        _this.body.sliders.min.style.left = `${start * 100}%`
        _this.body.sliders.max.style.left = `${end * 100}%`
      }
    }
  }
}<commit_msg>_getValueOfPosition<commit_after>class JSRange {
  constructor (el, options) {
    this._updateObject = this._update
    this._eventsObject = this._events

    this.options = options
    this.selected = {
      min: this.options.min,
      max: this.options.max
    }

    this._createBody(el)
    this._bindEvents()
    this.update()
  }

  // Propably we want to update everything
  update () {
    this._update.all()
  }

  set (hash = {}) {
    if (hash.min) {
      this.selected.min = hash.min
    }

    if (hash.max) {
      this.selected.max = hash.max
    }

    this.update()
  }

  _createBody (el) {
    this.body = {}

    this.body.parent = document.querySelector(el)
    this.body.parent.classList.add('jsr')

    this.body.rail = document.createElement('div')
    this.body.rail.classList.add('jsr_rail')

    this.body.sliders = {}
    this.body.sliders.min = document.createElement('div')
    this.body.sliders.min.classList.add('jsr_slider', 'jsr_slider--min')
    this.body.sliders.min.dataset.jsrType = 'min'
    this.body.sliders.max = document.createElement('div')
    this.body.sliders.max.classList.add('jsr_slider', 'jsr_slider--max')
    this.body.sliders.max.dataset.jsrType = 'max'

    this.body.info = {}
    this.body.info.min = document.createElement('span')
    this.body.info.min.classList.add('jsr_info', 'jsr_info--min')
    this.body.info.max = document.createElement('span')
    this.body.info.max.classList.add('jsr_info', 'jsr_info--max')
    this.body.info.actualMin = document.createElement('span')
    this.body.info.actualMin.classList.add('jsr_info', 'jsr_info--actualMin')
    this.body.info.actualMax = document.createElement('span')
    this.body.info.actualMax.classList.add('jsr_info', 'jsr_info--actualMax')

    let elements = [
      this.body.rail,
      this.body.sliders.min,
      this.body.sliders.max,
      this.body.info.min,
      this.body.info.max,
      this.body.info.actualMin,
      this.body.info.actualMax
    ]

    elements.forEach((element) => {
      this.body.parent.appendChild(element)
    })
  }

  _validateAndSave (type, value) {
    if (type === 'min') {
      if (value < this.options.min) {
        value = this.options.min
      }

      if (value > this.selected.max) {
        value = this.selected.max
      }
    }

    if (type === 'max') {
      if (value > this.options.max) {
        value = this.options.max
      }

      if (value < this.selected.min) {
        value = this.selected.min
      }
    }

    this.selected[type] = value
  }

  _bindEvents () {
    this.body.sliders.min.addEventListener('mousedown', this._events.sliderMouseDown)
    this.body.sliders.max.addEventListener('mousedown', this._events.sliderMouseDown)
    document.addEventListener('mousemove', this._events.sliderMouseMove)
    document.addEventListener('mouseup', this._events.sliderMouseUp)

    this.body.rail.addEventListener('click', this._events.railClick)
  }

  _getValueOfPosition (mouseX) {
    let railLeft = this.body.rail.getBoundingClientRect().left
    let diff = mouseX - railLeft
    return parseInt(diff / this.body.rail.offsetWidth * this.options.max)
  }

  // _update returns all events available to use
  // it tries to use the buffering-variable (_eventsObject) to not recreate this big object every time
  get _events () {
    var _this = this;
    return _this._eventsObject || {
      sliderMouseDown: function (event) {
        event.preventDefault() // prevents selecting text
        window.jsrMoveObject = event.target
      },
      sliderMouseUp: function (event) {
        window.jsrMoveObject = null
      },
      sliderMouseMove: function (event) {
        if (window.jsrMoveObject) {
          let type = window.jsrMoveObject.dataset.jsrType
          let newSelected = _this._getValueOfPosition(event.clientX)
          _this._validateAndSave(type, newSelected)
          _this.update()
        }
      },
      railClick: function (event) {
        // determine closer to which slider it was closer
        let clickedValue = _this._getValueOfPosition(event.clientX)

        // compare absolute distance between clickedValue and selected.min/max
        // closer to zero, means closer to min/max
        if (Math.abs(_this.selected.min - clickedValue) < Math.abs(_this.selected.max - clickedValue)) {
          // closer to min
          _this.selected.min = clickedValue
        } else {
          // closer to max
          _this.selected.max = clickedValue
        }

        _this.update()
      }
    }
  }

  // _update returns all methods available to use to update things
  // it tries to use the buffering-variable (_updateObject) to not recreate this big object every time
  get _update () {
    var _this = this;
    return _this._updateObject || {
      // Here goes every function which should be updated via .all()
      // 'info' should be after 'sliders'
      _toUpdate: ['rail', 'sliders', 'info'],
      all: function () {
        this._toUpdate.forEach((item) => {
          this[item]() // Call certain update function
        })
      },

      rail: function (min = _this.selected.min, max = _this.selected.max) {
        // Calc rail color position
        let start = min / _this.options.max
        let end = max / _this.options.max
        // Calc real start (because of weird percentage work)
        let realStart = start / (1 - (end - start))

        // Sets colored part of rail
        // Expects percentages without % sign
        _this.body.rail.style.backgroundPosition = `${realStart * 100}% 0`
        _this.body.rail.style.backgroundSize = `${(end - start) * 100}% 100%`
      },

      info: function () {
        _this.body.info.min.innerHTML = _this.options.min
        _this.body.info.max.innerHTML = _this.options.max
        _this.body.info.actualMin.innerHTML = _this.selected.min
        _this.body.info.actualMax.innerHTML = _this.selected.max

        // minWidth and maxWidth include widths of sliders
        let minWidth = _this.body.info.actualMin.offsetWidth - _this.body.sliders.min.offsetWidth
        let maxWidth = _this.body.info.actualMax.offsetWidth - _this.body.sliders.max.offsetWidth
        _this.body.info.actualMin.style.left = `calc(${_this.body.sliders.min.style.left} - ${minWidth}px / 2)`
        _this.body.info.actualMax.style.left = `calc(${_this.body.sliders.max.style.left} - ${maxWidth}px / 2)`
      },

      sliders: function (min = _this.selected.min, max = _this.selected.max) {
        let startWidthRatio = _this.body.sliders.min.offsetWidth / _this.body.rail.offsetWidth
        let endWidthRatio = _this.body.sliders.max.offsetWidth / _this.body.rail.offsetWidth
        // widthRatio is used to place middle point of slider in the right point
        let start = min / _this.options.max - startWidthRatio / 2
        let end = max / _this.options.max - endWidthRatio / 2

        _this.body.sliders.min.style.left = `${start * 100}%`
        _this.body.sliders.max.style.left = `${end * 100}%`
      }
    }
  }
}<|endoftext|>


<commit_before>'use strict'

// To be used with cpuprofilify http://npm.im/cpuprofilify

var aedes = require('./aedes')()
var server = require('net').createServer(aedes.handle)
var port = 1883

server.listen(port, function () {
  console.error('server listening on port', port, 'pid', process.pid)
})

aedes.on('clientError', function (client, err) {
  console.error('client error', client.id, err.message)
})

// Cleanly shut down process on SIGTERM to ensure that perf-<pid>.map gets flushed
process.on('SIGINT', onSIGINT)

function onSIGINT () {
  // IMPORTANT to log on stderr, to not clutter stdout which is purely for data, i.e. dtrace stacks
  console.error('Caught SIGTERM, shutting down.')
  server.close()
  process.exit(0)
}
<commit_msg>Fixed benchmark server.<commit_after>'use strict'

// To be used with cpuprofilify http://npm.im/cpuprofilify

var aedes = require('../')()
var server = require('net').createServer(aedes.handle)
var port = 1883

server.listen(port, function () {
  console.error('server listening on port', port, 'pid', process.pid)
})

aedes.on('clientError', function (client, err) {
  console.error('client error', client.id, err.message)
})

// Cleanly shut down process on SIGTERM to ensure that perf-<pid>.map gets flushed
process.on('SIGINT', onSIGINT)

function onSIGINT () {
  // IMPORTANT to log on stderr, to not clutter stdout which is purely for data, i.e. dtrace stacks
  console.error('Caught SIGTERM, shutting down.')
  server.close()
  process.exit(0)
}
<|endoftext|>


<commit_before>/* Copyright 2010 the Melange authors.
 *
 * 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.
 */
/**
 * @author Mario Ferraro
 */
(function () {
  /** @lends melange.autocomplete */

  if (window.melange === undefined) {
    throw new Error("Melange not loaded");
  }

  var melange = window.melange;

  /** Package that handles all tooltips related functions
    * @name melange.autocomplete
    * @namespace melange.autocomplete
    * @borrows melange.logging.debugDecorator.log as log
    */
  melange.autocomplete = window.melange.autocomplete = function () {
    return new melange.autocomplete();
  };

  /** Shortcut to current package.
    * @private
    */
  var $m = melange.logging.debugDecorator(melange.autocomplete);

  melange.error.createErrors([
  ]);

  $m.makeAutoComplete = function (id, url) {
    jQuery.getJSON(url,
      function(data){
        $("#" + id).autocomplete(data.data, {
          matchContains: true,
          formatItem: function(item) {
            return item.link_id+" ("+item.title+")";
          },
          formatResult: function(item) {
            return item.link_id;
          }
        });
      }
    );
  }
}());
<commit_msg>Make the autocomplete script accept additional options.<commit_after>/* Copyright 2010 the Melange authors.
 *
 * 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.
 */
/**
 * @author Mario Ferraro
 */
(function () {
  /** @lends melange.autocomplete */

  if (window.melange === undefined) {
    throw new Error("Melange not loaded");
  }

  var melange = window.melange;

  /** Package that handles all tooltips related functions
    * @name melange.autocomplete
    * @namespace melange.autocomplete
    * @borrows melange.logging.debugDecorator.log as log
    */
  melange.autocomplete = window.melange.autocomplete = function () {
    return new melange.autocomplete();
  };

  /** Shortcut to current package.
    * @private
    */
  var $m = melange.logging.debugDecorator(melange.autocomplete);

  melange.error.createErrors([
  ]);

  $m.makeAutoComplete = function (id, url) {
    jQuery.getJSON(url,
      function(data){
        var default_autocomplete_options = {
          matchContains: true,
          formatItem: function(item) {
            return item.link_id+" ("+item.title+")";
          },
          formatResult: function(item) {
            return item.link_id;
          }
        };
        if (data.autocomplete_options !== undefined) {
          jQuery.extend(
            default_autocomplete_options, data.autocomplete_options
          );
        }
        jQuery("#" + id).autocomplete(data.data, default_autocomplete_options);
      }
    );
  }
}());
<|endoftext|>


<commit_before>// ==UserScript==
// @name            Better TW Friends
// @author          xShteff, Diggo11
// @match           https://*.the-west.net/game.php*
// @match           https://*.the-west.de/game.php*
// @match           https://*.the-west.pl/game.php*
// @match           https://*.the-west.nl/game.php*
// @match           https://*.the-west.se/game.php*
// @match           https://*.the-west.ro/game.php*
// @match           https://*.the-west.com.pt/game.php*
// @match           https://*.the-west.cz/game.php*
// @match           https://*.the-west.es/game.php*
// @match           https://*.the-west.ru/game.php*
// @match           https://*.the-west.com.br/game.php*
// @match           https://*.the-west.org/game.php*
// @match           https://*.the-west.hu/game.php*
// @match           https://*.the-west.gr/game.php*
// @match           https://*.the-west.dk/game.php*
// @match           https://*.the-west.sk/game.php*
// @match           https://*.the-west.fr/game.php*
// @match           https://*.the-west.it/game.php*
// @grant           none
// @run-at          document-end
// ==/UserScript==

/**
 * A map of player ids to Chat.Resource.Client-like (mostly) plain objects
 * @type {Object}
 */
var friends = {};

/**
 * A map of player ids to unix timestamps
 * @type {Object}
 */
var lastSent = {};

/**
 * Records whether an ses:*_received event has been signalled since last downloading logs, assuming true upon login
 * @type {Boolean}
 */
var newLogs = true;

/**
 * Returns a list of keys for active events, eg Hearts. Practically guaranteed to have a length of 0 if no events are
 * running and a length of 1 otherwise (2 or more = internal beta only).
 * @returns {Array}
 */
function getActiveSesKeys() {
	return Object.keys(Game.sesData);
}

/**
 * Returns the number of seconds until you can send ses currency to a friend, or 0 if you can send it immediately.
 * Friends list must be initiated first.
 * @param {Number} friendId
 * @returns {Number}
 */
function timeUntilSesReady(friendId) {
	if (!lastSent.hasOwnProperty(friendId)) {
		return 0;
	}
	var yesterday = Date.now()/1000 - 3600*24;
	return Math.max(0, Math.floor(lastSent[friendId] - yesterday));
}

/**
 * Returns the number of friends you can currently send ses currency to. Friends list must be initiated first.
 * @returns {Number}
 */
function getSesReadyCount() {
	var count = 0;
	$.each(friends, function (playerId, client) {
		if (timeUntilSesReady(playerId) === 0) {
			count++;
		}
	});
	return count;
}

/**
 * Returns the total number of friends you have. Friends list must be initiated first.
 * @returns {Number}
 */
function getFriendCount() {
	return Object.keys(friends).length;
}

/**
 * Initiates the friend list and its twin, the last sent list. Do NOT run before establishing an event is ongoing.
 * Returns a promise with the message from the server, if any, but consider it void if resolved successfully.
 * @returns {Promise}
 */
function getFriendsList() {
	return new Promise(function (resolve, reject) {
		Ajax.remoteCallMode('friendsbar', 'search', {search_type: 'friends'}, function (data) {
			if (data.error) {
				return reject(data.msg);
			}

			$.each(data.players, function (i, client) {
				if (client.player_id !== Character.playerId) {
					friends[client.player_id] = west.storage.FriendsBar.prototype.normalizeAvatars_(client, i);
				}
			});

			var sesKey = getActiveSesKeys()[0];
			$.each(data.eventActivations, function (i, eventActivation) {
				if (eventActivation.event_name === sesKey) {
					lastSent[eventActivation.friend_id] = eventActivation.activation_time;
				}
			});

			return resolve(data.msg);
		});
	});
}

/**
 * Sends ses currency to a friend. Do NOT run before establishing an event is ongoing, even if you somehow obtain a
 * friend id without initiating the friend list first (congratulations). Returns a promise with the response message.
 * @param {Number} friendId
 * @returns {Promise}
 */
function sendSesCurrency(friendId) {
	return new Promise(function (resolve, reject) {
		Ajax.remoteCall('friendsbar', 'event', {player_id: friendId, event: getActiveSesKeys()[0]}, function (data) {
			if (data.error) {
				return reject(data.msg);
			}
			lastSent[friendId] = data.activationTime;
			return resolve(data.msg);
		});
	});
}

// getFriendsList()
// .then(getSesReadyCount)
// .then(x => console.log(x));
//
// sendSesCurrency(1337)
// .then(msg => MessageSuccess(msg).show())
// .catch(msg => MessageError(msg).show());

EventHandler.listen('friend_added', function (client) {
	friends[client.player_id] = client;
});

EventHandler.listen('friend_removed', function (friendId) {
	delete friends[friendId];
});

EventHandler.listen(s('ses:%1_received', 'hearts'), function (amount) {
	newLogs = true;
});
<commit_msg>We need somewhere to store the logs of ses currency received<commit_after>// ==UserScript==
// @name            Better TW Friends
// @author          xShteff, Diggo11
// @match           https://*.the-west.net/game.php*
// @match           https://*.the-west.de/game.php*
// @match           https://*.the-west.pl/game.php*
// @match           https://*.the-west.nl/game.php*
// @match           https://*.the-west.se/game.php*
// @match           https://*.the-west.ro/game.php*
// @match           https://*.the-west.com.pt/game.php*
// @match           https://*.the-west.cz/game.php*
// @match           https://*.the-west.es/game.php*
// @match           https://*.the-west.ru/game.php*
// @match           https://*.the-west.com.br/game.php*
// @match           https://*.the-west.org/game.php*
// @match           https://*.the-west.hu/game.php*
// @match           https://*.the-west.gr/game.php*
// @match           https://*.the-west.dk/game.php*
// @match           https://*.the-west.sk/game.php*
// @match           https://*.the-west.fr/game.php*
// @match           https://*.the-west.it/game.php*
// @grant           none
// @run-at          document-end
// ==/UserScript==

/**
 * A map of player ids to Chat.Resource.Client-like (mostly) plain objects
 * @type {Object}
 */
var friends = {};

/**
 * A map of player ids to unix timestamps
 * @type {Object}
 */
var lastSent = {};

/**
 * Records whether an ses:*_received event has been signalled since last downloading logs, assuming true upon login
 * @type {Boolean}
 */
var newLogs = true;

/**
 * A map containing information such as the most recent log processed, etc
 * @type {Object}
 */
var logsMetadata = JSON.parse(localStorage.getItem('xshteff.betterfriends.logsMetadata')) || {};

/**
 * A map of player ids to ses currency received from this player
 * @type {Object}
 */
var playerLogs = JSON.parse(localStorage.getItem('xshteff.betterfriends.playerLogs')) || {};

/**
 * A map of ses drop types to ses currency received from this drop type
 * @type {Object}
 */
var dropTypeLogs = JSON.parse(localStorage.getItem('xshteff.betterfriends.dropTypeLogs')) || {};

/**
 * Returns a list of keys for active events, eg Hearts. Practically guaranteed to have a length of 0 if no events are
 * running and a length of 1 otherwise (2 or more = internal beta only).
 * @returns {Array}
 */
function getActiveSesKeys() {
	return Object.keys(Game.sesData);
}

/**
 * Returns the number of seconds until you can send ses currency to a friend, or 0 if you can send it immediately.
 * Friends list must be initiated first.
 * @param {Number} friendId
 * @returns {Number}
 */
function timeUntilSesReady(friendId) {
	if (!lastSent.hasOwnProperty(friendId)) {
		return 0;
	}
	var yesterday = Date.now()/1000 - 3600*24;
	return Math.max(0, Math.floor(lastSent[friendId] - yesterday));
}

/**
 * Returns the number of friends you can currently send ses currency to. Friends list must be initiated first.
 * @returns {Number}
 */
function getSesReadyCount() {
	var count = 0;
	$.each(friends, function (playerId, client) {
		if (timeUntilSesReady(playerId) === 0) {
			count++;
		}
	});
	return count;
}

/**
 * Returns the total number of friends you have. Friends list must be initiated first.
 * @returns {Number}
 */
function getFriendCount() {
	return Object.keys(friends).length;
}

/**
 * Initiates the friend list and its twin, the last sent list. Do NOT run before establishing an event is ongoing.
 * Returns a promise with the message from the server, if any, but consider it void if resolved successfully.
 * @returns {Promise}
 */
function getFriendsList() {
	return new Promise(function (resolve, reject) {
		Ajax.remoteCallMode('friendsbar', 'search', {search_type: 'friends'}, function (data) {
			if (data.error) {
				return reject(data.msg);
			}

			$.each(data.players, function (i, client) {
				if (client.player_id !== Character.playerId) {
					friends[client.player_id] = west.storage.FriendsBar.prototype.normalizeAvatars_(client, i);
				}
			});

			var sesKey = getActiveSesKeys()[0];
			$.each(data.eventActivations, function (i, eventActivation) {
				if (eventActivation.event_name === sesKey) {
					lastSent[eventActivation.friend_id] = eventActivation.activation_time;
				}
			});

			return resolve(data.msg);
		});
	});
}

/**
 * Sends ses currency to a friend. Do NOT run before establishing an event is ongoing, even if you somehow obtain a
 * friend id without initiating the friend list first (congratulations). Returns a promise with the response message.
 * @param {Number} friendId
 * @returns {Promise}
 */
function sendSesCurrency(friendId) {
	return new Promise(function (resolve, reject) {
		Ajax.remoteCall('friendsbar', 'event', {player_id: friendId, event: getActiveSesKeys()[0]}, function (data) {
			if (data.error) {
				return reject(data.msg);
			}
			lastSent[friendId] = data.activationTime;
			return resolve(data.msg);
		});
	});
}

/**
 * Save playerLogs and dropTypeLogs into local storage.
 */
function saveLogs() {
	localStorage.setItem(JSON.stringify(logsMetadata));
	localStorage.setItem(JSON.stringify(playerLogs));
	localStorage.setItem(JSON.stringify(dropTypeLogs));
}

// getFriendsList()
// .then(getSesReadyCount)
// .then(x => console.log(x));
//
// sendSesCurrency(1337)
// .then(msg => MessageSuccess(msg).show())
// .catch(msg => MessageError(msg).show());

EventHandler.listen('friend_added', function (client) {
	friends[client.player_id] = client;
});

EventHandler.listen('friend_removed', function (friendId) {
	delete friends[friendId];
});

EventHandler.listen(s('ses:%1_received', 'hearts'), function (amount) {
	newLogs = true;
});
<|endoftext|>


<commit_before>/*

  @author Evgeniy Kuznetsov
  @date 11.05.2015
*/

// @param {Array.<Array>} ins Instance of a problem
// @return {Boolean} true - satisfiable, false otherwise
function solve2Sat(ins) {
  ins = cleanInstance(ins);

  var startOn = Date.now();

  var rulesDict = createRulesDictionary(ins);

  var bits = calculateBits(ins);
  bits = Object.keys(bits);

  var endpoint1 = Math.round(Math.log(bits.length) / Math.LN2);
  var endpoint2 = 2 * Math.pow(bits.length, 2);
  for(var i = 0; i <= endpoint1; i++) {
    var assignment = makeRandomAssignment(ins);

    var previousChanged = undefined,
        previousUnsat = undefined;

    for(var j = 0; j <= endpoint2; j++) {
      var progress = ((j/endpoint2)*100);

      if(Math.random()*10 > 9) console.log("Done", progress, "in", Date.now() - startOn);

      var unsat = checkSat(assignment, ins, previousUnsat, previousChanged, rulesDict);

      if(unsat.length == 0) {
        return true;

      } else {
        var randrule = Math.floor(Math.random() * unsat.length);
        randrule = unsat[randrule];

        var randbit = Math.floor(Math.random() * 2);
        randbit = Math.abs(randrule[randbit]);

        assignment[randbit] = !assignment[randbit];

        previousChanged = randbit;
        previousUnsat = unsat;
      }
    }
  }

  return false;
}

// section: Helpers

// @return {Object}
function calculateBits(ins) {
  var r = {};

  for(var i in ins) {
    r[Math.abs(ins[i][0])] = null;
    r[Math.abs(ins[i][1])] = null;
  }

  return r;
}

// @return {Object}
function makeRandomAssignment(ins) {
  var bits = calculateBits(ins);
  var keys = Object.keys(bits);

  for(var i in keys) {
    bits[keys[i]] = Boolean(Math.floor(Math.random() * 2));
  }

  return bits;
}

// Creates rules dictionary
// @param {Object} ins
// @return {Object}
function createRulesDictionary(ins) {
  var r = {};

  var pushToDict = function(id, rule) {
    if(!r[id]) r[id] = [];
    r[id].push(rule);
  };

  for(var i in ins) {
    var rule = ins[i];

    pushToDict(Math.abs(rule[0]), rule);
    pushToDict(Math.abs(rule[1]), rule);
  }

  return r;
}

// @return {Array.<Array>}
function checkSat(assignment, ins, previousUnsat, changedBit, rulesDict) {

  // @return {Boolean} true - satisfied, otherwise false
  function checkRule(rule) {
    var first = rule[0];
    var second = rule[1];

    var firstShould = first >= 0;
    var secondShould = second >= 0;

    var firstIs = assignment[Math.abs(first)];
    var secondIs = assignment[Math.abs(second)];

    return firstShould == firstIs || secondShould == secondIs;
  }

  function checkFull() {
    var r = [];
    for(var i in ins) {
      var rule = ins[i];
      if(!checkRule(rule)) {
        r.push(rule);
      }
    }

    return r;
  }

  function checkChanged() {
    previousUnsat = previousUnsat.slice(0);

    var currentUnsat = [];
    var unsatRulesIds = previousUnsat.map(function(r){ return cantorPairing(r[0], r[1]); });

    var dictEntry = rulesDict[changedBit];

    var excludedIndices = [];

    for(var i = 0; i < dictEntry.length; i++) {
      var rule = dictEntry[i];
      var ruleId = cantorPairing(rule[0], rule[1]);

      var ruleI = unsatRulesIds.indexOf(ruleId);

      if(checkRule(rule)) {

        if(ruleI != -1) {
          excludedIndices.push(ruleI);
        }

      } else if(ruleI == -1) {
        currentUnsat.push(rule);
      }
    }

    var del = 0;
    for(var z in excludedIndices){
      previousUnsat.splice(excludedIndices[z] - del, 1);
      del++;
    }
    return previousUnsat.concat(currentUnsat);

  }

  var result;
  if(typeof(previousUnsat) != "undefined" && typeof(changedBit) != "undefined") {
    result = checkChanged();
  } else {
    result = checkFull();
  }

  return result;

}

// Clear instance from unnecessary rules
function cleanInstance(ins) {
  ins = ins.slice(0);

  var lookup, constants;

  var checkInstance = function(v) {
    var cv = v * -1;
    var skey = Math.abs(v);

    var notAConstant = lookup[cv] != undefined;

    if(notAConstant) {
      delete constants[skey];
    } else {
      constants[skey] = true;
    }
  };

  while(true) {

    lookup = {};
    constants = {};

    for(var i in ins) {

      console.log("Check i", i);

      var rule = ins[i];
      var f = rule[0], s = rule[1];

      lookup[f] = true;
      lookup[s] = true;

      checkInstance(f);
      checkInstance(s);
    }

    if(Object.keys(constants).length == 0) break;

    ins = ins.filter(function(r, i){
      return constants[Math.abs(r[0])] == undefined && constants[Math.abs(r[1])] == undefined;
    });
  }

  return ins;
}

// Cantor pairing function
// http://en.wikipedia.org/wiki/Pairing_function
// @param {Integer} a
// @param {Integer} b
// @return {Integer}
function cantorPairing(a, b) {
  var ca = a >= 0 ? 2 * a : -2 * a - 1;
  var cb = b >= 0 ? 2 * b : -2 * b - 1;
  return ((ca + cb) * (ca + cb + 1))/2 + ca;
}

// section: Tests
var cleanableSat = [
  [1, 2],
  [-2, 1],
  [2, 3],
  [2, -3]
];

var simple = [
  [1, 2],
  [-1, 3],
  [3, 4],
  [-2, -4]
];

var simpleUnsat = [
  [2, 2],
  [-2, -2]
];

var uncorrectSimpleAssignment = {
  '1': false,
  '2': false,
  '3': false,
  '4': false
};

var correctSimpleAssignment = {
  '1': true,
  '2': false,
  '3': true,
  '4': false
};

console.log("Case 1:", solve2Sat(simple)==true);

console.log("Case 2:", Object.keys(calculateBits(simple)).length == 4, calculateBits(simple));
console.log("Case 3:", makeRandomAssignment(simple));

console.log("Case 4:", checkSat(uncorrectSimpleAssignment, simple).length > 0, checkSat(uncorrectSimpleAssignment, simple));
console.log("Case 5:", checkSat(correctSimpleAssignment, simple).length == 0, checkSat(correctSimpleAssignment, simple));

console.log("Case 6:", solve2Sat(simpleUnsat)==false);

console.log("Case 7a:", cleanInstance(cleanableSat));
console.log("Case 7b:", cleanInstance(simpleUnsat));

console.log("Case 8:", createRulesDictionary(simple));

<commit_msg>Refactoring<commit_after>/*
  Papadimitriou 2-sat alghorithm

  @author Evgeniy Kuznetsov
  @date 11.05.2015
*/

// Papadimitriou 2-sat
// @param {Array.<Array>} ins Instance of a problem
// @return {Boolean} true - satisfiable, false otherwise
function solve2Sat(ins) {
  ins = cleanInstance(ins);

  var rulesDict = createRulesDictionary(ins);
  var bits = Object.keys(rulesDict);

  var endpoint1 = Math.round(Math.log(bits.length) / Math.LN2);
  var endpoint2 = 2 * Math.pow(bits.length, 2);
  for(var i = 0; i <= endpoint1; i++) {
    var assignment = makeRandomAssignment(ins);

    var previousChanged = undefined,
        previousUnsat = undefined;

    for(var j = 0; j <= endpoint2; j++) {
      var unsat = checkSat(assignment, ins, previousUnsat, previousChanged, rulesDict);

      if(unsat.length == 0) {
        return true;

      } else {
        var randrule = Math.floor(Math.random() * unsat.length);
        randrule = unsat[randrule];

        var randbit = Math.floor(Math.random() * 2);
        randbit = Math.abs(randrule[randbit]);

        assignment[randbit] = !assignment[randbit];

        previousChanged = randbit;
        previousUnsat = unsat;
      }
    }
  }

  return ins.length == 0 ? true : false;
}

// section: Helpers

// Calculate all bits of a given instance
// @param {Array} ins
// @return {Object}
function calculateBits(ins) {
  var r = {};

  for(var i in ins) {
    r[Math.abs(ins[i][0])] = null;
    r[Math.abs(ins[i][1])] = null;
  }

  return r;
}

// Makes random assignment to a given instance
// @param {Array} ins
// @return {Object}
function makeRandomAssignment(ins) {
  var bits = calculateBits(ins);
  var keys = Object.keys(bits);

  for(var i in keys) {
    bits[keys[i]] = Boolean(Math.floor(Math.random() * 2));
  }

  return bits;
}

// Creates rules dictionary
// @param {Array} ins
// @return {Object}
function createRulesDictionary(ins) {
  var r = {};

  var pushToDict = function(id, rule) {
    if(!r[id]) r[id] = [];
    r[id].push(rule);
  };

  for(var i in ins) {
    var rule = ins[i];

    pushToDict(Math.abs(rule[0]), rule);
    pushToDict(Math.abs(rule[1]), rule);
  }

  return r;
}

// Check if assignment satisfied
// @param {Object} assignment
// @param {Array} ins
// @param {Array} previousUnsat Previously unsatisfied rules
// @param {Integer} changedBit Currently changed bit
// @param {Object} rulesDict
// @return {Array.<Array>}
function checkSat(assignment, ins, previousUnsat, changedBit, rulesDict) {

  // Check all rules
  // @return {Boolean} true - satisfied, otherwise false
  function checkRule(rule) {
    var first = rule[0];
    var second = rule[1];

    var firstShould = first >= 0;
    var secondShould = second >= 0;

    var firstIs = assignment[Math.abs(first)];
    var secondIs = assignment[Math.abs(second)];

    return firstShould == firstIs || secondShould == secondIs;
  }

  function checkFull() {
    var r = [];
    for(var i in ins) {
      var rule = ins[i];
      if(!checkRule(rule)) {
        r.push(rule);
      }
    }

    return r;
  }

  // Check rules only affected by current change
  function checkChanged() {
    previousUnsat = previousUnsat.slice(0);

    var currentUnsat = [];
    var unsatRulesIds = previousUnsat.map(function(r){ return cantorPairing(r[0], r[1]); });

    var dictEntry = rulesDict[changedBit];

    var excludedIndices = [];

    for(var i = 0; i < dictEntry.length; i++) {
      var rule = dictEntry[i];
      var ruleId = cantorPairing(rule[0], rule[1]);

      var ruleI = unsatRulesIds.indexOf(ruleId);

      if(checkRule(rule)) {

        if(ruleI != -1) {
          excludedIndices.push(ruleI);
        }

      } else if(ruleI == -1) {
        currentUnsat.push(rule);
      }
    }

    var del = 0;
    for(var z in excludedIndices){
      previousUnsat.splice(excludedIndices[z] - del, 1);
      del++;
    }
    return previousUnsat.concat(currentUnsat);

  }

  var result;
  if(typeof(previousUnsat) != "undefined" && typeof(changedBit) != "undefined") {
    result = checkChanged();
  } else {
    result = checkFull();
  }

  return result;

}

// Clear instance from unnecessary rules
// @param {Array} ins
// @return {Array}
function cleanInstance(ins) {
  ins = ins.slice(0);

  var lookup, constants;

  var checkInstance = function(v) {
    var cv = v * -1;
    var skey = Math.abs(v);

    var notAConstant = lookup[cv] != undefined;

    if(notAConstant) {
      delete constants[skey];
    } else {
      constants[skey] = true;
    }
  };

  while(true) {

    lookup = {};
    constants = {};

    for(var i in ins) {
      var rule = ins[i];
      var f = rule[0], s = rule[1];

      lookup[f] = true;
      lookup[s] = true;

      checkInstance(f);
      checkInstance(s);
    }

    if(Object.keys(constants).length == 0) break;

    ins = ins.filter(function(r, i){
      return constants[Math.abs(r[0])] == undefined && constants[Math.abs(r[1])] == undefined;
    });
  }

  return ins;
}

// Cantor pairing function
// http://en.wikipedia.org/wiki/Pairing_function
// @param {Integer} a
// @param {Integer} b
// @return {Integer}
function cantorPairing(a, b) {
  var ca = a >= 0 ? 2 * a : -2 * a - 1;
  var cb = b >= 0 ? 2 * b : -2 * b - 1;
  return ((ca + cb) * (ca + cb + 1))/2 + ca;
}

// section: Tests
var cleanableSat = [
  [1, 2],
  [-2, 1],
  [2, 3],
  [2, -3]
];

var simple = [
  [1, 2],
  [-1, 3],
  [3, 4],
  [-2, -4]
];

var simpleUnsat = [
  [2, 2],
  [-2, -2]
];

var uncorrectSimpleAssignment = {
  '1': false,
  '2': false,
  '3': false,
  '4': false
};

var correctSimpleAssignment = {
  '1': true,
  '2': false,
  '3': true,
  '4': false
};

console.log("Case 1:", solve2Sat(simple)==true);

console.log("Case 2:", Object.keys(calculateBits(simple)).length == 4, calculateBits(simple));
console.log("Case 3:", makeRandomAssignment(simple));

console.log("Case 4:", checkSat(uncorrectSimpleAssignment, simple).length > 0, checkSat(uncorrectSimpleAssignment, simple));
console.log("Case 5:", checkSat(correctSimpleAssignment, simple).length == 0, checkSat(correctSimpleAssignment, simple));

console.log("Case 6:", solve2Sat(simpleUnsat)==false);

console.log("Case 7a:", cleanInstance(cleanableSat));
console.log("Case 7b:", cleanInstance(simpleUnsat));

console.log("Case 8:", createRulesDictionary(simple));

<|endoftext|>


<commit_before>/* https://github.com/DiemenDesign/summernote-cleaner */
/* Version: 1.0.3 */
(function(factory) {
  if (typeof define === 'function' && define.amd) {
    define(['jquery'], factory);
  } else if (typeof module === 'object'&&module.exports) {
    module.exports = factory(require('jquery'));
  } else {
    factory(window.jQuery);
  }
}
(function ($) {
  $.extend(true, $.summernote.lang, {
    'en-US': {
      cleaner: {
        tooltip: 'Cleaner',
        not: 'Text has been cleaned!',
        limitText: 'Text',
        limitHTML: 'HTML'
      }
    },
    'de-DE': {
      cleaner: {
        tooltip: 'Cleaner',
        not: 'Inhalt wurde bereinigt!',
        limitText: 'Text',
        limitHTML: 'HTML'
      }
    },
  });
  $.extend( $.summernote.options, {
    cleaner: {
      action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
      icon: '<svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 0 14 14" width="14" height="14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg>',
      keepHtml: true,
      keepTagContents: ['span'], //Remove tags and keep the contents
      badTags: ['applet', 'col', 'colgroup', 'embed', 'noframes', 'noscript', 'script', 'style', 'title'], //Remove full tags with contents
      badAttributes: ['bgcolor', 'border', 'height', 'cellpadding', 'cellspacing', 'lang', 'start', 'style', 'valign', 'width'], //Remove attributes from remaining tags
      limitChars: 0, // 0|# 0 disables option
      limitDisplay: 'both', // none|text|html|both
      limitStop: false, // true/false
      imagePlaceholder: 'https://via.placeholder.com/200'
    }
  });
  $.extend( $.summernote.plugins, {
    'cleaner': function (context) {
      var self = this,
            ui = $.summernote.ui,
         $note = context.layoutInfo.note,
       $editor = context.layoutInfo.editor,
       options = context.options,
          lang = options.langInfo;
      if (options.cleaner.action == 'both' || options.cleaner.action == 'button') {
        context.memo('button.cleaner', function () {
          var button = ui.button({
            contents: options.cleaner.icon,
            container: options.container,
            tooltip: lang.cleaner.tooltip,
            placement: options.placement,
            click: function () {
              if ($note.summernote('createRange').toString())
                $note.summernote('pasteHTML', $note.summernote('createRange').toString());
              else
                $note.summernote('code', cleanPaste($note.summernote('code'), options.cleaner.badTags, options.cleaner.keepTagContents, options.cleaner.badAttributes, options.cleaner.imagePlaceholder), true);
              if ($editor.find('.note-status-output').length > 0)
                $editor.find('.note-status-output').html(lang.cleaner.not);
            }
          });
          return button.render();
        });
      }
      this.events = {
        'summernote.init': function () {
          if (options.cleaner.limitChars != 0 || options.cleaner.limitDisplay != 'none'){
            var textLength = $editor.find(".note-editable").text().replace(/(<([^>]+)>)/ig, "").replace(/( )/," ");
            var codeLength = $editor.find('.note-editable').html();
            var lengthStatus = '';
            if (textLength.length > options.cleaner.limitChars&&options.cleaner.limitChars > 0)
              lengthStatus += 'note-text-danger">';
            else
              lengthStatus += '">';
            if (options.cleaner.limitDisplay == 'text' || options.cleaner.limitDisplay == 'both')
              lengthStatus += lang.cleaner.limitText + ': ' + textLength.length;
            if (options.cleaner.limitDisplay == 'both')
              lengthStatus += ' / ';
            if (options.cleaner.limitDisplay == 'html' || options.cleaner.limitDisplay == 'both')
              lengthStatus += lang.cleaner.limitHTML + ': ' + codeLength.length;
            $editor.find('.note-status-output').html('<small class="note-pull-right ' + lengthStatus + ' ');
          }
        },
        'summernote.keydown': function (we, event) {
          if (options.cleaner.limitChars != 0 || options.cleaner.limitDisplay != 'none') {
            var textLength = $editor.find(".note-editable").text().replace(/(<([^>]+)>)/ig, "").replace(/( )/, " ");
            var codeLength = $editor.find('.note-editable').html();
            var lengthStatus = '';
            if (options.cleaner.limitStop == true && textLength.length >= options.cleaner.limitChars) {
              var key = event.keyCode;
              allowed_keys = [8, 37, 38, 39, 40, 46];
              if ($.inArray(key,allowed_keys) != -1){
                $editor.find('.cleanerLimit').removeClass('note-text-danger');
                return true;
              } else {
                $editor.find('.cleanerLimit').addClass('note-text-danger');
                event.preventDefault();
                event.stopPropagation();
              }
            } else {
              if (textLength.length > options.cleaner.limitChars && options.cleaner.limitChars > 0)
                lengthStatus += 'note-text-danger">';
              else
                lengthStatus += '">';
              if (options.cleaner.limitDisplay == 'text' || options.cleaner.limitDisplay == 'both')
                lengthStatus += lang.cleaner.limitText + ': '+textLength.length;
              if (options.cleaner.limitDisplay == 'both')
                lengthStatus += ' / ';
              if (options.cleaner.limitDisplay == 'html' || options.cleaner.limitDisplay == 'both')
                lengthStatus += lang.cleaner.limitHTML + ': ' + codeLength.length;
              $editor.find('.note-status-output').html('<small class="cleanerLimit note-pull-right ' + lengthStatus + ' ');
            }
          }
        },
        'summernote.paste': function(we, event) {
          if (options.cleaner.action=='both' || options.cleaner.action == 'paste') {
            event.preventDefault();
            var ua = window.navigator.userAgent;
            var msie = ua.indexOf("MSIE ");
                msie = msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./);
            var ffox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
            var text; var isHtmlData = false;
            if (msie)
              text = window.clipboardData.getData("Text");
            else
            {
              var dataType = 'text/plain';
              /*only get the html data if its avaialble else use plain text*/
              if (options.cleaner.keepHtml && event.originalEvent.clipboardData.types.indexOf('text/html') > -1) {
                  dataType = 'text/html';
                  isHtmlData = true;
              }
              text = event.originalEvent.clipboardData.getData(dataType);
            }
            if (text) {
              if (msie || ffox) {
                setTimeout(function () {
                  $note.summernote('pasteHTML', cleanPaste(text, options.cleaner.badTags, options.cleaner.keepTagContents, options.cleaner.badAttributes, options.cleaner.imagePlaceholder, isHtmlData));
                }, 1);
              } else
                $note.summernote('pasteHTML', cleanPaste(text, options.cleaner.badTags, options.cleaner.keepTagContents, options.cleaner.badAttributes, options.cleaner.imagePlaceholder, isHtmlData));
              if ($editor.find('.note-status-output').length > 0)
                $editor.find('.note-status-output').html(lang.cleaner.not);
            }
          }
        }
      }
      var cleanPaste = function(input, badTags, keepTagContents, badAttributes, imagePlaceholder, isHtmlData) {
        if(isHtmlData) {
          return cleanHtmlPaste(input, badTags, keepTagContents, badAttributes, imagePlaceholder);
        } else {
          return cleanTextPaste(input);
        }
      };

      var cleanTextPaste = function(input) {
        var newLines = /(\r\n|\r|\n)/g;
        var parsedInput = input.split(newLines);
        if(parsedInput.length === 1) { return input; }
        var output = "";
        /*for larger blocks of text (such as multiple paragraphs) match summernote markup */
        for (let contentIndex = 0; contentIndex < parsedInput.length; contentIndex++) {
          const element = parsedInput[contentIndex];
          if(!newLines.test(element)) {
            var line = element == '' ? '
' : element;
            output += '
' + line + '
'
          }
        }
        return output;
      }

      var cleanHtmlPaste = function(input, badTags, keepTagContents, badAttributes, imagePlaceholder) {
        var stringStripper = /(\n|\r| class=(")?Mso[a-zA-Z]+(")? ^p)/g;
        var output = input.replace(stringStripper, '');
        var commentSripper = new RegExp('', 'g');
        var output = output.replace(commentSripper, '');
        var tagStripper = new RegExp('<(/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>', 'gi');
        output = output.replace(/ src="(.*?)"/gi, ' src="' + imagePlaceholder + '"');
        output = output.replace(/ name="(.*?)"/gi, ' data-title="$1" alt="$1"');
        output = output.replace(tagStripper, '');
        for (var i = 0; i < badTags.length; i++) {
          tagStripper = new RegExp('<' + badTags[i] + '.*?' + badTags[i] + '(.*?)>', 'gi');
          output = output.replace(tagStripper, '');
        }
        for (var i = 0; i < keepTagContents.length; i++) {
          tagStripper = new RegExp('</?' + keepTagContents[i] + '.*?>', 'gi');
          output = output.replace(tagStripper, ' ');
        }
        for (var i = 0; i < badAttributes.length; i++) {
          var attributeStripper = new RegExp(badAttributes[i] + '="(.*?)"', 'gi');
          output = output.replace(attributeStripper, '');
        }
        output = output.replace(/ align="(.*?)"/gi, ' class="text-$1"');
        output = output.replace(/ class="western"/gi, '');
        output = output.replace(/ class=""/gi, '');
        output = output.replace(/(.*?)<\/b>/gi, '$1');
        output = output.replace(/(.*?)<\/i>/gi, '$1');
        output = output.replace(/\s{2,}/g, ' ').trim();
        return output;
      }
    }
  });
}));
<commit_msg>updated german translation<commit_after>/* https://github.com/DiemenDesign/summernote-cleaner */
/* Version: 1.0.3 */
(function(factory) {
  if (typeof define === 'function' && define.amd) {
    define(['jquery'], factory);
  } else if (typeof module === 'object'&&module.exports) {
    module.exports = factory(require('jquery'));
  } else {
    factory(window.jQuery);
  }
}
(function ($) {
  $.extend(true, $.summernote.lang, {
    'en-US': {
      cleaner: {
        tooltip: 'Cleaner',
        not: 'Text has been cleaned!',
        limitText: 'Text',
        limitHTML: 'HTML'
      }
    },
    'de-DE': {
      cleaner: {
        tooltip: 'Reinigungskraft',
        not: 'Inhalt wurde bereinigt!',
        limitText: 'Text',
        limitHTML: 'HTML'
      }
    },
  });
  $.extend( $.summernote.options, {
    cleaner: {
      action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
      icon: '<svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 0 14 14" width="14" height="14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg>',
      keepHtml: true,
      keepTagContents: ['span'], //Remove tags and keep the contents
      badTags: ['applet', 'col', 'colgroup', 'embed', 'noframes', 'noscript', 'script', 'style', 'title'], //Remove full tags with contents
      badAttributes: ['bgcolor', 'border', 'height', 'cellpadding', 'cellspacing', 'lang', 'start', 'style', 'valign', 'width'], //Remove attributes from remaining tags
      limitChars: 0, // 0|# 0 disables option
      limitDisplay: 'both', // none|text|html|both
      limitStop: false, // true/false
      imagePlaceholder: 'https://via.placeholder.com/200'
    }
  });
  $.extend( $.summernote.plugins, {
    'cleaner': function (context) {
      var self = this,
            ui = $.summernote.ui,
         $note = context.layoutInfo.note,
       $editor = context.layoutInfo.editor,
       options = context.options,
          lang = options.langInfo;
      if (options.cleaner.action == 'both' || options.cleaner.action == 'button') {
        context.memo('button.cleaner', function () {
          var button = ui.button({
            contents: options.cleaner.icon,
            container: options.container,
            tooltip: lang.cleaner.tooltip,
            placement: options.placement,
            click: function () {
              if ($note.summernote('createRange').toString())
                $note.summernote('pasteHTML', $note.summernote('createRange').toString());
              else
                $note.summernote('code', cleanPaste($note.summernote('code'), options.cleaner.badTags, options.cleaner.keepTagContents, options.cleaner.badAttributes, options.cleaner.imagePlaceholder), true);
              if ($editor.find('.note-status-output').length > 0)
                $editor.find('.note-status-output').html(lang.cleaner.not);
            }
          });
          return button.render();
        });
      }
      this.events = {
        'summernote.init': function () {
          if (options.cleaner.limitChars != 0 || options.cleaner.limitDisplay != 'none'){
            var textLength = $editor.find(".note-editable").text().replace(/(<([^>]+)>)/ig, "").replace(/( )/," ");
            var codeLength = $editor.find('.note-editable').html();
            var lengthStatus = '';
            if (textLength.length > options.cleaner.limitChars&&options.cleaner.limitChars > 0)
              lengthStatus += 'note-text-danger">';
            else
              lengthStatus += '">';
            if (options.cleaner.limitDisplay == 'text' || options.cleaner.limitDisplay == 'both')
              lengthStatus += lang.cleaner.limitText + ': ' + textLength.length;
            if (options.cleaner.limitDisplay == 'both')
              lengthStatus += ' / ';
            if (options.cleaner.limitDisplay == 'html' || options.cleaner.limitDisplay == 'both')
              lengthStatus += lang.cleaner.limitHTML + ': ' + codeLength.length;
            $editor.find('.note-status-output').html('<small class="note-pull-right ' + lengthStatus + ' ');
          }
        },
        'summernote.keydown': function (we, event) {
          if (options.cleaner.limitChars != 0 || options.cleaner.limitDisplay != 'none') {
            var textLength = $editor.find(".note-editable").text().replace(/(<([^>]+)>)/ig, "").replace(/( )/, " ");
            var codeLength = $editor.find('.note-editable').html();
            var lengthStatus = '';
            if (options.cleaner.limitStop == true && textLength.length >= options.cleaner.limitChars) {
              var key = event.keyCode;
              allowed_keys = [8, 37, 38, 39, 40, 46];
              if ($.inArray(key,allowed_keys) != -1){
                $editor.find('.cleanerLimit').removeClass('note-text-danger');
                return true;
              } else {
                $editor.find('.cleanerLimit').addClass('note-text-danger');
                event.preventDefault();
                event.stopPropagation();
              }
            } else {
              if (textLength.length > options.cleaner.limitChars && options.cleaner.limitChars > 0)
                lengthStatus += 'note-text-danger">';
              else
                lengthStatus += '">';
              if (options.cleaner.limitDisplay == 'text' || options.cleaner.limitDisplay == 'both')
                lengthStatus += lang.cleaner.limitText + ': '+textLength.length;
              if (options.cleaner.limitDisplay == 'both')
                lengthStatus += ' / ';
              if (options.cleaner.limitDisplay == 'html' || options.cleaner.limitDisplay == 'both')
                lengthStatus += lang.cleaner.limitHTML + ': ' + codeLength.length;
              $editor.find('.note-status-output').html('<small class="cleanerLimit note-pull-right ' + lengthStatus + ' ');
            }
          }
        },
        'summernote.paste': function(we, event) {
          if (options.cleaner.action=='both' || options.cleaner.action == 'paste') {
            event.preventDefault();
            var ua = window.navigator.userAgent;
            var msie = ua.indexOf("MSIE ");
                msie = msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./);
            var ffox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
            var text; var isHtmlData = false;
            if (msie)
              text = window.clipboardData.getData("Text");
            else
            {
              var dataType = 'text/plain';
              /*only get the html data if its avaialble else use plain text*/
              if (options.cleaner.keepHtml && event.originalEvent.clipboardData.types.indexOf('text/html') > -1) {
                  dataType = 'text/html';
                  isHtmlData = true;
              }
              text = event.originalEvent.clipboardData.getData(dataType);
            }
            if (text) {
              if (msie || ffox) {
                setTimeout(function () {
                  $note.summernote('pasteHTML', cleanPaste(text, options.cleaner.badTags, options.cleaner.keepTagContents, options.cleaner.badAttributes, options.cleaner.imagePlaceholder, isHtmlData));
                }, 1);
              } else
                $note.summernote('pasteHTML', cleanPaste(text, options.cleaner.badTags, options.cleaner.keepTagContents, options.cleaner.badAttributes, options.cleaner.imagePlaceholder, isHtmlData));
              if ($editor.find('.note-status-output').length > 0)
                $editor.find('.note-status-output').html(lang.cleaner.not);
            }
          }
        }
      }
      var cleanPaste = function(input, badTags, keepTagContents, badAttributes, imagePlaceholder, isHtmlData) {
        if(isHtmlData) {
          return cleanHtmlPaste(input, badTags, keepTagContents, badAttributes, imagePlaceholder);
        } else {
          return cleanTextPaste(input);
        }
      };

      var cleanTextPaste = function(input) {
        var newLines = /(\r\n|\r|\n)/g;
        var parsedInput = input.split(newLines);
        if(parsedInput.length === 1) { return input; }
        var output = "";
        /*for larger blocks of text (such as multiple paragraphs) match summernote markup */
        for (let contentIndex = 0; contentIndex < parsedInput.length; contentIndex++) {
          const element = parsedInput[contentIndex];
          if(!newLines.test(element)) {
            var line = element == '' ? '
' : element;
            output += '
' + line + '
'
          }
        }
        return output;
      }

      var cleanHtmlPaste = function(input, badTags, keepTagContents, badAttributes, imagePlaceholder) {
        var stringStripper = /(\n|\r| class=(")?Mso[a-zA-Z]+(")? ^p)/g;
        var output = input.replace(stringStripper, '');
        var commentSripper = new RegExp('', 'g');
        var output = output.replace(commentSripper, '');
        var tagStripper = new RegExp('<(/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>', 'gi');
        output = output.replace(/ src="(.*?)"/gi, ' src="' + imagePlaceholder + '"');
        output = output.replace(/ name="(.*?)"/gi, ' data-title="$1" alt="$1"');
        output = output.replace(tagStripper, '');
        for (var i = 0; i < badTags.length; i++) {
          tagStripper = new RegExp('<' + badTags[i] + '.*?' + badTags[i] + '(.*?)>', 'gi');
          output = output.replace(tagStripper, '');
        }
        for (var i = 0; i < keepTagContents.length; i++) {
          tagStripper = new RegExp('</?' + keepTagContents[i] + '.*?>', 'gi');
          output = output.replace(tagStripper, ' ');
        }
        for (var i = 0; i < badAttributes.length; i++) {
          var attributeStripper = new RegExp(badAttributes[i] + '="(.*?)"', 'gi');
          output = output.replace(attributeStripper, '');
        }
        output = output.replace(/ align="(.*?)"/gi, ' class="text-$1"');
        output = output.replace(/ class="western"/gi, '');
        output = output.replace(/ class=""/gi, '');
        output = output.replace(/(.*?)<\/b>/gi, '$1');
        output = output.replace(/(.*?)<\/i>/gi, '$1');
        output = output.replace(/\s{2,}/g, ' ').trim();
        return output;
      }
    }
  });
}));
<|endoftext|>


<commit_before>(function(factory){
  if(typeof define==='function'&&define.amd){
    define(['jquery'],factory);
  }else if(typeof module==='object'&&module.exports){
    module.exports=factory(require('jquery'));
  }else{
    factory(window.jQuery);
  }
}
(function($){
  $.extend(true,$.summernote.lang,{
    'en-US':{
      cleaner:{
        tooltip:'Cleaner',
        not:'Text has been Cleaned!!!'
      }
    }
  });
  $.extend($.summernote.options,{
    cleaner:{
      notTime:2400, // Time to display Notifications.
      action:'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
      newline:'
', // Summernote's default is to use '

'
      notStyle:'position:absolute;top:0;left:0;right:0',
      icon:'<svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 0 14 14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg>',
      keepHtml:false, //Remove all Html formats
      keepOnlyTags: [], // If keepHtml is true, remove all tags except these
      keepClasses:false, //Remove Classes
      badTags:['style','script','applet','embed','noframes','noscript','html'], //Remove full tags with contents
      badAttributes:['style','start'] //Remove attributes from remaining tags
    }
  });
  $.extend($.summernote.plugins,{
    'cleaner':function(context){
      var self=this;
      var ui=$.summernote.ui;
      var $note=context.layoutInfo.note;
      var $editor=context.layoutInfo.editor;
      var options=context.options;
      var lang=options.langInfo;
      var cleanText=function(txt,nlO){
        if(options.cleaner.keepHtml){
          if(!options.cleaner.keepClasses){
            var sS=/(\n|\r| class=(")?Mso[a-zA-Z]+(")?)/g;
            var out=txt.replace(sS,' ');
          }
          var nL=/(\n)+/g;
          out=out.replace(nL,nlO);
          var cS=new RegExp('','gi');
          out=out.replace(cS,'');
          var tS=new RegExp('<(/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>','gi');
          out=out.replace(tS,'');
          var bT=options.cleaner.badTags;
          for(var i=0;i<bT.length;i++){
            tS=new RegExp('<'+bT[i]+'.*?'+bT[i]+'(.*?)>','gi');
            out=out.replace(tS,'');
          }
          var allowedTags = options.cleaner.keepOnlyTags;
          allowedTags = (((allowedTags || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
          var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi
          out = out.replace(tags, function ($0, $1) {
            return allowedTags.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
          });
          var bA=options.cleaner.badAttributes;
          for(var ii=0;ii<bA.length;ii++){
            //var aS=new RegExp(' ('+bA[ii]+'="(.*?)")|('+bA[ii]+'=\'(.*?)\')','gi');
            var aS=new RegExp(' '+bA[ii]+'=[\'|"](.*?)[\'|"]','gi');
            out=out.replace(aS,'');
          }
        }else{
          if(!options.cleaner.keepClasses){
            var sS=/(\r| class=(")?Mso[a-zA-Z]+(")?)/g;
            var out=txt.replace(sS,' ');
          }
          var nL=/(\n)+/g;
          out=out.replace(nL,nlO);
        }
        return out;
      };
      if(options.cleaner.action=='both'||options.cleaner.action=='button'){
        context.memo('button.cleaner',function(){
          var button=ui.button({
            contents:options.cleaner.icon,
            tooltip:lang.cleaner.tooltip,
            click:function(){
              if($note.summernote('createRange').toString()){
                var text=cleanText($note.summernote('createRange').toString(),options.cleaner.newline);
                $note.summernote('pasteHTML',text);
              }else{
                var text=cleanText($note.summernote().text(),options.cleaner.newline);
                $note.summernote('code',text);
              }
              if(options.cleaner.notTime>0){
                $editor.find('.note-editing-area').append('
'+lang.cleaner.not+'
');
                setTimeout(function(){$editor.find('.summernote-cleanerAlert').remove();},options.cleaner.notTime);
              }
            }
          });
          return button.render();
        });
      }
      this.events={
        'summernote.paste':function(we,e){
          if(options.cleaner.action=='both'||options.cleaner.action=='paste'){
            e.preventDefault();
            var ua=window.navigator.userAgent;
            var msie=ua.indexOf("MSIE ");
            msie=msie>0||!!navigator.userAgent.match(/Trident.*rv\:11\./);
            if(msie){
              var text=window.clipboardData.getData("Text");
            }else{
              var text=e.originalEvent.clipboardData.getData((options.cleaner.keepHtml?'text/html':'text/plain'));
            }
            var text=cleanText(text,options.cleaner.newline);
            var pasteFn=function(){
              $note.summernote('pasteHTML',text);
            }
            if(msie){
              setTimeout(pasteFn,1);
            }else{
              pasteFn();
            }
            if(options.cleaner.notTime>0){
              $editor.find('.note-resizebar').append('
'+lang.cleaner.not+'
');
              setTimeout(function(){$editor.find('.summernote-cleanerAlert').remove();},options.cleaner.notTime);
            }
          }
        }
      }
    }
  });
}));
<commit_msg>Filter tags only if array contain one or more element<commit_after>(function(factory){
  if(typeof define==='function'&&define.amd){
    define(['jquery'],factory);
  }else if(typeof module==='object'&&module.exports){
    module.exports=factory(require('jquery'));
  }else{
    factory(window.jQuery);
  }
}
(function($){
  $.extend(true,$.summernote.lang,{
    'en-US':{
      cleaner:{
        tooltip:'Cleaner',
        not:'Text has been Cleaned!!!'
      }
    }
  });
  $.extend($.summernote.options,{
    cleaner:{
      notTime:2400, // Time to display Notifications.
      action:'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
      newline:'
', // Summernote's default is to use '

'
      notStyle:'position:absolute;top:0;left:0;right:0',
      icon:'<svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 0 14 14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg>',
      keepHtml:false, //Remove all Html formats
      keepOnlyTags: [], // If keepHtml is true, remove all tags except these
      keepClasses:false, //Remove Classes
      badTags:['style','script','applet','embed','noframes','noscript','html'], //Remove full tags with contents
      badAttributes:['style','start'] //Remove attributes from remaining tags
    }
  });
  $.extend($.summernote.plugins,{
    'cleaner':function(context){
      var self=this;
      var ui=$.summernote.ui;
      var $note=context.layoutInfo.note;
      var $editor=context.layoutInfo.editor;
      var options=context.options;
      var lang=options.langInfo;
      var cleanText=function(txt,nlO){
        if(options.cleaner.keepHtml){
          if(!options.cleaner.keepClasses){
            var sS=/(\n|\r| class=(")?Mso[a-zA-Z]+(")?)/g;
            var out=txt.replace(sS,' ');
          }
          var nL=/(\n)+/g;
          out=out.replace(nL,nlO);
          var cS=new RegExp('','gi');
          out=out.replace(cS,'');
          var tS=new RegExp('<(/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>','gi');
          out=out.replace(tS,'');
          var bT=options.cleaner.badTags;
          for(var i=0;i<bT.length;i++){
            tS=new RegExp('<'+bT[i]+'.*?'+bT[i]+'(.*?)>','gi');
            out=out.replace(tS,'');
          }
          var allowedTags = options.cleaner.keepOnlyTags;
          if(allowedTags.length > 0) {
            allowedTags = (((allowedTags || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
            var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi
            out = out.replace(tags, function ($0, $1) {
              return allowedTags.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
            });
          }
          var bA=options.cleaner.badAttributes;
          for(var ii=0;ii<bA.length;ii++){
            //var aS=new RegExp(' ('+bA[ii]+'="(.*?)")|('+bA[ii]+'=\'(.*?)\')','gi');
            var aS=new RegExp(' '+bA[ii]+'=[\'|"](.*?)[\'|"]','gi');
            out=out.replace(aS,'');
          }
        }else{
          if(!options.cleaner.keepClasses){
            var sS=/(\r| class=(")?Mso[a-zA-Z]+(")?)/g;
            var out=txt.replace(sS,' ');
          }
          var nL=/(\n)+/g;
          out=out.replace(nL,nlO);
        }
        return out;
      };
      if(options.cleaner.action=='both'||options.cleaner.action=='button'){
        context.memo('button.cleaner',function(){
          var button=ui.button({
            contents:options.cleaner.icon,
            tooltip:lang.cleaner.tooltip,
            click:function(){
              if($note.summernote('createRange').toString()){
                var text=cleanText($note.summernote('createRange').toString(),options.cleaner.newline);
                $note.summernote('pasteHTML',text);
              }else{
                var text=cleanText($note.summernote().text(),options.cleaner.newline);
                $note.summernote('code',text);
              }
              if(options.cleaner.notTime>0){
                $editor.find('.note-editing-area').append('
'+lang.cleaner.not+'
');
                setTimeout(function(){$editor.find('.summernote-cleanerAlert').remove();},options.cleaner.notTime);
              }
            }
          });
          return button.render();
        });
      }
      this.events={
        'summernote.paste':function(we,e){
          if(options.cleaner.action=='both'||options.cleaner.action=='paste'){
            e.preventDefault();
            var ua=window.navigator.userAgent;
            var msie=ua.indexOf("MSIE ");
            msie=msie>0||!!navigator.userAgent.match(/Trident.*rv\:11\./);
            if(msie){
              var text=window.clipboardData.getData("Text");
            }else{
              var text=e.originalEvent.clipboardData.getData((options.cleaner.keepHtml?'text/html':'text/plain'));
            }
            var text=cleanText(text,options.cleaner.newline);
            var pasteFn=function(){
              $note.summernote('pasteHTML',text);
            }
            if(msie){
              setTimeout(pasteFn,1);
            }else{
              pasteFn();
            }
            if(options.cleaner.notTime>0){
              $editor.find('.note-resizebar').append('
'+lang.cleaner.not+'
');
              setTimeout(function(){$editor.find('.summernote-cleanerAlert').remove();},options.cleaner.notTime);
            }
          }
        }
      }
    }
  });
}));
<|endoftext|>