<commit_before>import generateContentHash from './utils/generateContentHash'
import sortedStringify from './utils/sortedStringify'
import getFontFormat from './utils/getFontFormat'

import cssifyKeyframe from './utils/cssifyKeyframe'
import cssifyObject from './utils/cssifyObject'

export default function Renderer(config = { }) {
  const r = {
    listeners: [],
    keyframePrefixes: config.keyframePrefixes || [ '-webkit-', '-moz-' ],
    plugins: config.plugins || [ ],

    /**
     * clears the sheet's cache but keeps all listeners
     */
    clear() {
      r.fontFaces = ''
      r.keyframes = ''
      r.statics = ''
      r.rules = ''
      r.mediaRules = { }
      r.rendered = { }
      r.base = { }
      r.ids = [ ]

      // emit changes to notify subscribers
      r._emitChange()
    },

    /**
     * renders a new rule variation and caches the result
     *
     * @param {Function} rule - rule which gets rendered
     * @param {Object?} props - properties used to render
     * @return {string} className to reference the rendered rule
     */
    renderRule(rule, props = { }) {
      // rendering a rule for the first time
      // will create an ID reference
      if (r.ids.indexOf(rule) < 0) {
        r.ids.push(rule)

        // directly render the static base style to be able
        // to diff future dynamic style with those
        r.renderRule(rule, { })
      }

      // uses the reference ID and the props to generate an unique className
      const ruleId = r.ids.indexOf(rule)
      const className = 'c' + ruleId + r._generatePropsReference(props)

      // only if the cached rule has not already been rendered
      // with a specific set of properties it actually renders
      if (!r.rendered.hasOwnProperty(className)) {
        const style = r._processStyle(rule(props))
        r._renderStyle(className, style, r.base[ruleId])

        r.rendered[className] = r._didChange

        if (r._didChange) {
          r._didChange = false
          r._emitChange()
        }

        // keep static style to diff dynamic onces later on
        if (className === 'c' + ruleId) {
          r.base[ruleId] = style
        }
      }

      const baseClassName = 'c' + ruleId
      if (!r.rendered[className]) {
        return baseClassName
      }

      // returns either the base className or both the base and the dynamic part
      return className !== baseClassName ? baseClassName + ' ' + className : className
    },

    /**
     * renders a new keyframe variation and caches the result
     *
     * @param {Keyframe} keyframe - Keyframe which gets rendered
     * @param {Object?} props - properties used to render
     * @return {string} animationName to reference the rendered keyframe
     */
    renderKeyframe(keyframe, props = { }) {
      // rendering a Keyframe for the first time
      // will create cache entries and an ID reference
      if (r.ids.indexOf(keyframe) < 0) {
        r.ids.push(keyframe)
      }

      const propsReference = r._generatePropsReference(props)
      const animationName = 'k' + r.ids.indexOf(keyframe) + propsReference

      // only if the cached keyframe has not already been rendered
      // with a specific set of properties it actually renders
      if (!r.rendered.hasOwnProperty(animationName)) {
        const processedKeyframe = r._processStyle(keyframe(props))
        const css = cssifyKeyframe(processedKeyframe, animationName, r.keyframePrefixes)
        r.rendered[animationName] = true
        r.keyframes += css
        r._emitChange()
      }

      return animationName
    },

    /**
     * renders a new font-face and caches it
     *
     * @param {FontFace} fontFace - fontFace which gets rendered
     * @return {string} fontFamily reference
     */
    renderFont(family, files, props = { }) {
      if (!r.rendered.hasOwnProperty(family)) {
        const fontFace = {
          fontFamily: '\'' + family + '\'',
          src: files.map(src => 'url(\'' + src + '\') format(\'' + getFontFormat(src) + '\')').join(',')
        }

        const fontProperties = [ 'fontVariant', 'fontWeight', 'fontStretch', 'fontStyle', 'unicodeRange' ]
        Object.keys(props).filter(prop => fontProperties.indexOf(prop) > -1).forEach(fontProp => fontFace[fontProp] = props[fontProp])

        const css = '@font-face{' + cssifyObject(fontFace) + '}'
        r.rendered[family] = true
        r.fontFaces += css
        r._emitChange()
      }

      return family
    },

    /**
     * renders static style and caches them
     *
     * @param {string|Object} style - static style to be rendered
     * @param {string?} selector - selector used to render the styles
     * @return {string} rendered CSS output
     */
    renderStatic(style, selector) {
      const reference = typeof style === 'string' ? style : selector

      if (!r.rendered.hasOwnProperty(reference)) {
        if (typeof style === 'string') {
          // remove new lines from template strings
          r.statics += style.replace(/\s{2,}/g, '')
        } else {
          r.statics += selector + '{' + cssifyObject(r._processStyle(style)) + '}'
        }

        r.rendered[reference] = true<commit_msg>Revert "`properties` -> `props` for more consistency"<commit_after>import generateContentHash from './utils/generateContentHash'
import sortedStringify from './utils/sortedStringify'
import getFontFormat from './utils/getFontFormat'

import cssifyKeyframe from './utils/cssifyKeyframe'
import cssifyObject from './utils/cssifyObject'

export default function Renderer(config = { }) {
  const r = {
    listeners: [],
    keyframePrefixes: config.keyframePrefixes || [ '-webkit-', '-moz-' ],
    plugins: config.plugins || [ ],

    /**
     * clears the sheet's cache but keeps all listeners
     */
    clear() {
      r.fontFaces = ''
      r.keyframes = ''
      r.statics = ''
      r.rules = ''
      r.mediaRules = { }
      r.rendered = { }
      r.base = { }
      r.ids = [ ]

      // emit changes to notify subscribers
      r._emitChange()
    },

    /**
     * renders a new rule variation and caches the result
     *
     * @param {Function} rule - rule which gets rendered
     * @param {Object?} props - properties used to render
     * @return {string} className to reference the rendered rule
     */
    renderRule(rule, props = { }) {
      // rendering a rule for the first time
      // will create an ID reference
      if (r.ids.indexOf(rule) < 0) {
        r.ids.push(rule)

        // directly render the static base style to be able
        // to diff future dynamic style with those
        r.renderRule(rule, { })
      }

      // uses the reference ID and the props to generate an unique className
      const ruleId = r.ids.indexOf(rule)
      const className = 'c' + ruleId + r._generatePropsReference(props)

      // only if the cached rule has not already been rendered
      // with a specific set of properties it actually renders
      if (!r.rendered.hasOwnProperty(className)) {
        const style = r._processStyle(rule(props))
        r._renderStyle(className, style, r.base[ruleId])

        r.rendered[className] = r._didChange

        if (r._didChange) {
          r._didChange = false
          r._emitChange()
        }

        // keep static style to diff dynamic onces later on
        if (className === 'c' + ruleId) {
          r.base[ruleId] = style
        }
      }

      const baseClassName = 'c' + ruleId
      if (!r.rendered[className]) {
        return baseClassName
      }

      // returns either the base className or both the base and the dynamic part
      return className !== baseClassName ? baseClassName + ' ' + className : className
    },

    /**
     * renders a new keyframe variation and caches the result
     *
     * @param {Keyframe} keyframe - Keyframe which gets rendered
     * @param {Object?} props - properties used to render
     * @return {string} animationName to reference the rendered keyframe
     */
    renderKeyframe(keyframe, props = { }) {
      // rendering a Keyframe for the first time
      // will create cache entries and an ID reference
      if (r.ids.indexOf(keyframe) < 0) {
        r.ids.push(keyframe)
      }

      const propsReference = r._generatePropsReference(props)
      const animationName = 'k' + r.ids.indexOf(keyframe) + propsReference

      // only if the cached keyframe has not already been rendered
      // with a specific set of properties it actually renders
      if (!r.rendered.hasOwnProperty(animationName)) {
        const processedKeyframe = r._processStyle(keyframe(props))
        const css = cssifyKeyframe(processedKeyframe, animationName, r.keyframePrefixes)
        r.rendered[animationName] = true
        r.keyframes += css
        r._emitChange()
      }

      return animationName
    },

    /**
     * renders a new font-face and caches it
     *
     * @param {FontFace} fontFace - fontFace which gets rendered
     * @return {string} fontFamily reference
     */
    renderFont(family, files, properties = { }) {
      if (!r.rendered.hasOwnProperty(family)) {
        const fontFace = {
          fontFamily: '\'' + family + '\'',
          src: files.map(src => 'url(\'' + src + '\') format(\'' + getFontFormat(src) + '\')').join(',')
        }

        const fontProperties = [ 'fontVariant', 'fontWeight', 'fontStretch', 'fontStyle', 'unicodeRange' ]
        Object.keys(properties).filter(prop => fontProperties.indexOf(prop) > -1).forEach(fontProp => fontFace[fontProp] = properties[fontProp])

        const css = '@font-face{' + cssifyObject(fontFace) + '}'
        r.rendered[family] = true
        r.fontFaces += css
        r._emitChange()
      }

      return family
    },

    /**
     * renders static style and caches them
     *
     * @param {string|Object} style - static style to be rendered
     * @param {string?} selector - selector used to render the styles
     * @return {string} rendered CSS output
     */
    renderStatic(style, selector) {
      const reference = typeof style === 'string' ? style : selector

      if (!r.rendered.hasOwnProperty(reference)) {
        if (typeof style === 'string') {
          // remove new lines from template strings
          r.statics += style.replace(/\s{2,}/g, '')
        } else {
          r.statics += selector + '{' + cssifyObject(r._processStyle(style)) + '}'
        }

        r.rendered[reference] = true
{'fraction_non_alphanumeric': 0.11664268585131894, 'fraction_numerical': 0.0007673860911270983, 'mean_word_length': 2.3288633461047255, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 12, 'https://': 0, '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': '4124018', 'n_tokens_mistral': 2937, 'n_tokens_neox': 2851, 'n_words': 860}