<commit_before>HThemeManager = HClass.extend

  allInOneCSS: true # temporary solution until new theme is crafted

  currentTheme: 'default'

  constructor: null

  # Properties by theme name
  currentThemePath: null
  themePaths: {}
  themes: []

  # Set the graphics loading path of the the themeName
  setThemePath: (_clientPrefix)->
    @currentThemePath = _clientPrefix
    for _themeName in @themes
      @setupThemePath( _themeName )

  setupAllInOneCSS: (_themeName)->
    _cssText = ''
    for _componentName of @themeCSSTemplates[_themeName]
      _cssText += @buildCSSTemplate(@, _themeName, _componentName)
    _style = @useCSS( _cssText )
    # Causes issues in Firefox:
    # _cssTitle = 'rsence/'+_themeName
    # _style.title = _cssTitle

  setupThemePath: (_themeName)->
    return unless @currentThemePath?
    return if @themePaths[_themeName]?
    _clientThemePath = [ @currentThemePath, _themeName ].join('/') + '/gfx/'
    @themePaths[_themeName] = _clientThemePath
    @setupAllInOneCSS(_themeName) if @allInOneCSS

  # CSS Templates and CSS Template methods per theme name
  themeCSSTemplates: {}

  # Sets the css template data per theme, all at once
  setThemeCSSTemplates: (_themeName, _themeCSS)->
    @themeCSSTemplates[_themeName] = _themeCSS

  # HTML Templates and HTML Template methods per theme name
  themeHTMLTemplates: {}

  # Sets the css template data per theme, all at once
  setThemeHTMLTemplates: (_themeName, _themeHTML)->
    @themeHTMLTemplates[_themeName] = _themeHTML

  # Set the theme data, this is called by the serverside client_pkg suite
  installThemeData: (_themeName, _themeCSS, _themeHTML)->
    @themes.push(_themeName) unless ~@themes.indexOf(_themeName)
    @setThemeCSSTemplates(_themeName, _themeCSS)
    @setThemeHTMLTemplates(_themeName, _themeHTML)
    @setupThemePath(_themeName)

  # Simple reference counting by theme name and component name, when 0, clear the style sheet
  cssCountUsedBy: {}
  cssByThemeAndComponentName: {}
  incrementCSSUseCount: (_themeName, _componentName)->
    @cssCountUsedBy[_themeName] = {} unless @cssCountUsedBy[_themeName]?
    _themeCollection = @cssCountUsedBy[_themeName]
    if _themeCollection[_componentName]?
      _themeCollection[_componentName] += 1
    else
      _themeCollection[_componentName] = 1

  decrementCSSUseCount: (_themeName, _componentName)->
    unless @cssCountUsedBy[_themeName]?
      console.log("Warning in decrementCSSUseCount; the theme #{_themeName} wasn't initialized (called with componentName: #{_componentName})")
      return
    _themeCollection = @cssCountUsedby[_themeName]
    unless _themeCollection[_componentName]?
      console.log("Warning in decrementCSSUseCount; the componentName #{_componentName} wasn't initialized (called with themeName: #{_themeName})")
      return
    if _themeCollection[_componentName] == 1
      _style = @cssByThemeAndComponentName[_themeName][_componentName]
      _style.parentNode.removeChild( _style )
      delete _themeCollection[_componentName]
    else
      _themeCollection[_componentName] -= 1

  _buildThemePath: (_fileName,_themeName)->
    _fileName = _fileName.substring(1) while _fileName[0] == '/'
    @themePaths[_themeName]+_fileName
  _variableMatch: /#\{([a-z0-9]+?)\}/
  _assignmentMatch: /\$\{([a-z0-9]+?)\}/
  buildHTMLTemplate: ( _view, _themeName, _componentName )->
    unless @themeHTMLTemplates[_themeName]?
      console.log('Theme not installed:',_themeName)
      return ''
    return '' unless @themeHTMLTemplates[_themeName][_componentName]?
    [_tmplJS, _tmplHTML] = @themeHTMLTemplates[_themeName][_componentName]
    _rect   = _view.rect
    _callArgs = [_view.elemId.toString(), _rect.width, _rect.height]
    _tmplHTML = _tmplHTML.replace(/\]I\[/g,_callArgs[0]).replace(/\]W\[/g,_callArgs[1]).replace(/\]H\[/g,_callArgs[2])
    return _tmplHTML if _tmplJS.length == 0
    [_variableMatch, _assignmentMatch] = [@_variableMatch, @_assignmentMatch]
    # _ID     = _view.elemId.toString()
    # _WIDTH  = _rect.width
    # _HEIGHT = _rect.height
    _callValue = (_id,_isAssign)->
      _id = parseInt(_id,36)-10
      try
        _out = _tmplJS[_id].apply(_view,_callArgs)
        return '' if _isAssign
        return _out
      catch e
        console.log "HTML Template error(#{e}) in #{_themeName}/#{_componentName}: #{_tmplJS[_id]}"
        return ''
    while _assignmentMatch.test(_tmplHTML)
      _tmplHTML = _tmplHTML.replace( _assignmentMatch, _callValue( RegExp.$1, true ) )
    while _variableMatch.test(_tmplHTML)
      _tmplHTML = _tmplHTML.replace( _variableMatch, _callValue( RegExp.$1 ) )
    # console.log('tmplHTML:',_tmplHTML) if _componentName == 'tab'
    return _tmplHTML

  gradientCSS: ->
    _colors = []
    _colors.push( _color ) for _color in arguments<commit_msg>Added gradinentStyle method hook to return a style object in similar fashion as gradientCSS does for css strings.<commit_after>HThemeManager = HClass.extend

  allInOneCSS: true # temporary solution until new theme is crafted

  currentTheme: 'default'

  constructor: null

  # Properties by theme name
  currentThemePath: null
  themePaths: {}
  themes: []

  # Set the graphics loading path of the the themeName
  setThemePath: (_clientPrefix)->
    @currentThemePath = _clientPrefix
    for _themeName in @themes
      @setupThemePath( _themeName )

  setupAllInOneCSS: (_themeName)->
    _cssText = ''
    for _componentName of @themeCSSTemplates[_themeName]
      _cssText += @buildCSSTemplate(@, _themeName, _componentName)
    _style = @useCSS( _cssText )
    # Causes issues in Firefox:
    # _cssTitle = 'rsence/'+_themeName
    # _style.title = _cssTitle

  setupThemePath: (_themeName)->
    return unless @currentThemePath?
    return if @themePaths[_themeName]?
    _clientThemePath = [ @currentThemePath, _themeName ].join('/') + '/gfx/'
    @themePaths[_themeName] = _clientThemePath
    @setupAllInOneCSS(_themeName) if @allInOneCSS

  # CSS Templates and CSS Template methods per theme name
  themeCSSTemplates: {}

  # Sets the css template data per theme, all at once
  setThemeCSSTemplates: (_themeName, _themeCSS)->
    @themeCSSTemplates[_themeName] = _themeCSS

  # HTML Templates and HTML Template methods per theme name
  themeHTMLTemplates: {}

  # Sets the css template data per theme, all at once
  setThemeHTMLTemplates: (_themeName, _themeHTML)->
    @themeHTMLTemplates[_themeName] = _themeHTML

  # Set the theme data, this is called by the serverside client_pkg suite
  installThemeData: (_themeName, _themeCSS, _themeHTML)->
    @themes.push(_themeName) unless ~@themes.indexOf(_themeName)
    @setThemeCSSTemplates(_themeName, _themeCSS)
    @setThemeHTMLTemplates(_themeName, _themeHTML)
    @setupThemePath(_themeName)

  # Simple reference counting by theme name and component name, when 0, clear the style sheet
  cssCountUsedBy: {}
  cssByThemeAndComponentName: {}
  incrementCSSUseCount: (_themeName, _componentName)->
    @cssCountUsedBy[_themeName] = {} unless @cssCountUsedBy[_themeName]?
    _themeCollection = @cssCountUsedBy[_themeName]
    if _themeCollection[_componentName]?
      _themeCollection[_componentName] += 1
    else
      _themeCollection[_componentName] = 1

  decrementCSSUseCount: (_themeName, _componentName)->
    unless @cssCountUsedBy[_themeName]?
      console.log("Warning in decrementCSSUseCount; the theme #{_themeName} wasn't initialized (called with componentName: #{_componentName})")
      return
    _themeCollection = @cssCountUsedby[_themeName]
    unless _themeCollection[_componentName]?
      console.log("Warning in decrementCSSUseCount; the componentName #{_componentName} wasn't initialized (called with themeName: #{_themeName})")
      return
    if _themeCollection[_componentName] == 1
      _style = @cssByThemeAndComponentName[_themeName][_componentName]
      _style.parentNode.removeChild( _style )
      delete _themeCollection[_componentName]
    else
      _themeCollection[_componentName] -= 1

  _buildThemePath: (_fileName,_themeName)->
    _fileName = _fileName.substring(1) while _fileName[0] == '/'
    @themePaths[_themeName]+_fileName
  _variableMatch: /#\{([a-z0-9]+?)\}/
  _assignmentMatch: /\$\{([a-z0-9]+?)\}/
  buildHTMLTemplate: ( _view, _themeName, _componentName )->
    unless @themeHTMLTemplates[_themeName]?
      console.log('Theme not installed:',_themeName)
      return ''
    return '' unless @themeHTMLTemplates[_themeName][_componentName]?
    [_tmplJS, _tmplHTML] = @themeHTMLTemplates[_themeName][_componentName]
    _rect   = _view.rect
    _callArgs = [_view.elemId.toString(), _rect.width, _rect.height]
    _tmplHTML = _tmplHTML.replace(/\]I\[/g,_callArgs[0]).replace(/\]W\[/g,_callArgs[1]).replace(/\]H\[/g,_callArgs[2])
    return _tmplHTML if _tmplJS.length == 0
    [_variableMatch, _assignmentMatch] = [@_variableMatch, @_assignmentMatch]
    # _ID     = _view.elemId.toString()
    # _WIDTH  = _rect.width
    # _HEIGHT = _rect.height
    _callValue = (_id,_isAssign)->
      _id = parseInt(_id,36)-10
      try
        _out = _tmplJS[_id].apply(_view,_callArgs)
        return '' if _isAssign
        return _out
      catch e
        console.log "HTML Template error(#{e}) in #{_themeName}/#{_componentName}: #{_tmplJS[_id]}"
        return ''
    while _assignmentMatch.test(_tmplHTML)
      _tmplHTML = _tmplHTML.replace( _assignmentMatch, _callValue( RegExp.$1, true ) )
    while _variableMatch.test(_tmplHTML)
      _tmplHTML = _tmplHTML.replace( _variableMatch, _callValue( RegExp.$1 ) )
    # console.log('tmplHTML:',_tmplHTML) if _componentName == 'tab'
    return _tmplHTML
  gradientStyle: ->
    _colors = []
    _colors.push( _color ) for _color in arguments
    [_key, _value] = ELEM._linearGradientStyle(
      start: _colors.shift()
      end: _colors.pop()
      steps: _colors
    )
    _style = {}
    _style[_key] = _value
    _style
  gradientCSS: ->
    _colors = []
    _colors.push( _color ) for _color in arguments
{'fraction_non_alphanumeric': 0.10798357207252329, 'fraction_numerical': 0.004207152158669738, 'mean_word_length': 4.117375704766786, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 28, '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': '1781106', 'n_tokens_mistral': 3121, 'n_tokens_neox': 3073, 'n_words': 709}