<commit_before>/**
 * @author <NAME> <<EMAIL>>
 * https://github.com/wenzhixin/bootstrap-show-password
 * version: 1.2.1
 */

let bootstrapVersion = 4
try {
  const rawVersion = $.fn.dropdown.Constructor.VERSION

  // Only try to parse VERSION if it is defined.
  // It is undefined in older versions of Bootstrap (tested with 3.1.1).
  if (rawVersion !== undefined) {
    bootstrapVersion = parseInt(rawVersion, 10)
  } else {
    bootstrapVersion = 3
  }
} catch (e) {
  // ignore
}

const Constants = {
  html: {
    inputGroups: {
      3: [
        '<span tabindex="100" class="add-on input-group-addon %s" title="%s">',
        '</span>'
      ],
      4: [
        '<div class="%s"><button tabindex="100" title="%s" class="btn btn-outline-secondary" type="button">',
        '</button></div>'
      ]
    }[bootstrapVersion]
  }
}

// TOOLS DEFINITION
// ======================

// it only does '%s', and return '' when arguments are undefined
const sprintf = function (str) {
  const args = arguments
  let flag = true
  let i = 1

  str = str.replace(/%s/g, () => {
    const arg = args[i++]

    if (typeof arg === 'undefined') {
      flag = false
      return ''
    }
    return arg
  })
  if (flag) {
    return str
  }
  return ''
}

class Password {
  constructor (element, options) {
    this.options = options
    this.$element = $(element)
    this.isShown = false

    this.init()
  }

  init () {
    let placementFuc
    let inputClass

    if (this.options.placement === 'before') {
      placementFuc = 'insertBefore'
      inputClass = 'input-group-prepend'
    } else {
      this.options.placement = 'after' // default to after
      placementFuc = 'insertAfter'
      inputClass = 'input-group-append'
    }

    // Create the text, icon and assign
    this.$element.wrap(`<div class="input-group${sprintf(' input-group-%s', this.options.size)}" />`)

    this.$text = $('<input type="text" />')[placementFuc](this.$element)
      .attr('class', this.$element.attr('class'))
      .attr('style', this.$element.attr('style'))
      .attr('placeholder', this.$element.attr('placeholder'))
      .attr('maxlength', this.$element.attr('maxlength'))
      .attr('disabled', this.$element.attr('disabled'))
      .css('display', this.$element.css('display'))
      .val(this.$element.val()).hide()

    // Copy readonly attribute if it's set
    if (this.$element.prop('readonly'))
      this.$text.prop('readonly', true)
    this.$icon = $([
      `${sprintf(Constants.html.inputGroups[0], inputClass, this.options.message)}
      <i class="icon-eye-open ${this.options.eyeClass} ${this.options.eyeClassPositionInside ? '' : this.options.eyeOpenClass}">
      ${this.options.eyeClassPositionInside ? this.options.eyeOpenClass : ''}
      </i>`,
      Constants.html.inputGroups[1]
    ].join(''))[placementFuc](this.$text).css('cursor', 'pointer')

    // events
    this.$text.off('keyup').on('keyup', $.proxy(function () {<commit_msg>Supported all attributes without data-*<commit_after>/**
 * @author <NAME> <<EMAIL>>
 * https://github.com/wenzhixin/bootstrap-show-password
 * version: 1.2.1
 */

let bootstrapVersion = 4
try {
  const rawVersion = $.fn.dropdown.Constructor.VERSION

  // Only try to parse VERSION if it is defined.
  // It is undefined in older versions of Bootstrap (tested with 3.1.1).
  if (rawVersion !== undefined) {
    bootstrapVersion = parseInt(rawVersion, 10)
  } else {
    bootstrapVersion = 3
  }
} catch (e) {
  // ignore
}

const Constants = {
  html: {
    inputGroups: {
      3: [
        '<span tabindex="100" class="add-on input-group-addon %s" title="%s">',
        '</span>'
      ],
      4: [
        '<div class="%s"><button tabindex="100" title="%s" class="btn btn-outline-secondary" type="button">',
        '</button></div>'
      ]
    }[bootstrapVersion]
  }
}

// TOOLS DEFINITION
// ======================

// it only does '%s', and return '' when arguments are undefined
const sprintf = function (str) {
  const args = arguments
  let flag = true
  let i = 1

  str = str.replace(/%s/g, () => {
    const arg = args[i++]

    if (typeof arg === 'undefined') {
      flag = false
      return ''
    }
    return arg
  })
  if (flag) {
    return str
  }
  return ''
}

class Password {
  constructor (element, options) {
    this.options = options
    this.$element = $(element)
    this.isShown = false

    this.init()
  }

  init () {
    let placementFuc
    let inputClass

    if (this.options.placement === 'before') {
      placementFuc = 'insertBefore'
      inputClass = 'input-group-prepend'
    } else {
      this.options.placement = 'after' // default to after
      placementFuc = 'insertAfter'
      inputClass = 'input-group-append'
    }

    // Create the text, icon and assign
    this.$element.wrap(`<div class="input-group${sprintf(' input-group-%s', this.options.size)}" />`)

    this.$text = $('<input type="text" />')[placementFuc](this.$element)
      .css('display', this.$element.css('display'))
      .val(this.$element.val()).hide()

    for (const attr of this.$element[0].attributes) {
      if (
        !attr.specified ||
        ['id', 'type'].includes(attr.name) ||
        attr.name.indexOf('data-') === 0
      ) {
        continue
      }

      this.$text.attr(attr.name, attr.value)
    }

    this.$icon = $([
      `${sprintf(Constants.html.inputGroups[0], inputClass, this.options.message)}
      <i class="icon-eye-open ${this.options.eyeClass} ${this.options.eyeClassPositionInside ? '' : this.options.eyeOpenClass}">
      ${this.options.eyeClassPositionInside ? this.options.eyeOpenClass : ''}
      </i>`,
      Constants.html.inputGroups[1]
    ].join(''))[placementFuc](this.$text).css('cursor', 'pointer')

    // events
    this.$text.off('keyup').on('keyup', $.proxy(function () {
{'fraction_non_alphanumeric': 0.18117687543014452, 'fraction_numerical': 0.007570543702684102, 'mean_word_length': 2.782042940793754, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '793656', 'n_tokens_mistral': 1903, 'n_tokens_neox': 1836, 'n_words': 400}