if ( !("thrive_pv" in window) ) {
  window.thrive = {}

  window.thrive.i_to_b64 = function(i) {
    var b64 = ''
    while (i>0) {
      b64 = window.thrive.b64_digits[i%64]+b64
      i = Math.floor(i/64)
    }
    return b64
  }

  window.thrive.b64_to_i = function(b64) {
    var i = 0
    for (var j=0; j<b64.length; j++) {
      i = i * 64 + window.thrive.b64_digits.indexOf( b64[j] )
    }
    return i
  }

  window.thrive.urlsafe_b64_encode = function(object) {
    return btoa( unescape( encodeURIComponent( JSON.stringify(object) ) ) ).replace(/\+/g,'-').replace(/\//g,'_').replace(/\=+$/,'')
  }

  window.thrive.trim_attributes = function(object) {
    Object.keys(object).forEach( function(a) { if ( typeof( object[a] ) == "string") { object[a] = object[a].substring(0, 255) } } )
    return object
  }

  window.thrive.generate_uuid = function(msec) {
    var b = ''
    for (var i=0; i<44; i++) { b += window.thrive.b64_digits[Math.floor( ( Math.random() ) * 64)] }
    return ( 'AAAAAAAAAAAA'+window.thrive.i_to_b64(msec) ).slice(-12) +
      ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'+b).slice(-44)
  }

  window.thrive.get_ls = function() {
    return JSON.parse( localStorage.getItem('thrive_anon_data') ) || {}
  }

  window.thrive.set_ls = function(key, value) {
    localStorage.setItem( 'thrive_anon_data', JSON.stringify( { ...window.thrive.get_ls(), ...{ [key] : value } } ) )
  }

  window.thrive.append_ls_session = function(new_sess_msec) {
    var sessions = JSON.parse( localStorage.getItem('thrive_anon_sessions') ) || {}
    if ( Object.keys( sessions ).length >= 100 ) delete sessions[Math.min(...Object.keys( sessions ))]
    sessions[new_sess_msec] = {}
    localStorage.setItem( 'thrive_anon_sessions', JSON.stringify( sessions ) )
  }

  window.thrive.get_cookie = function(key) {
    var match
    if ( match = ( new RegExp('(?:^|; )'+encodeURIComponent(key)+'=([^;]*)') ).exec(document.cookie) ) {
      return decodeURIComponent( match[1] )
    }
  }

  window.thrive.set_cookie = function(key, value, domain, expiration) {
    document.cookie = encodeURIComponent(key)+'='+encodeURIComponent(value)+'; path=/;' +
      ( domain ? ( ' domain='+encodeURIComponent(domain)+';' ) : '' ) +
      ( expiration ? (' expires='+expiration+';') : '' ) +
      'Secure; SameSite=Lax;'
    return window.thrive.get_cookie(key)
  }

  window.thrive.get_top_cookieable_domain = function () {
    var key = [ ...Array(8) ].map( () => Math.floor( Math.random() * 16 ).toString(16) ).join('')
    var top_cookieable_domain = null
    var try_domain = '..' + document.domain
    while ( try_domain.match(/^\.[^\.]*\./) ) {
      try_domain = try_domain.replace(/^\.[^\.]*/, '')
      if ( window.thrive.set_cookie(key, '1', try_domain) ) {
        top_cookieable_domain = try_domain
      }
      document.cookie = encodeURIComponent(key)+'=; path=/;'+
        ' domain='+encodeURIComponent(try_domain)+';'+
        ' expires=Thu, 01 Jan 1970 00:00:00 GMT;' +
        'Secure; SameSite=Lax;'
    }
    return top_cookieable_domain
  }

  window.thrive.add_script = function(src, async) {
    var new_node = document.createElement('script')
    new_node.src = src
    new_node.async = async
    document.querySelector('head').appendChild(new_node)
  }

  window.thrive.ga4_send = function(name, attributes) {
    window.thrive.ga4_ids.forEach( t => {
      var attributes_with_send_to = attributes
      attributes_with_send_to["send_to"] = t
      window.gtag('event', name, attributes_with_send_to)
    } )
  }

  window.thrive.ga4 = function(name, attributes) {
    if (window.thrive.ga4_ids.length > 0) {
      window.thrive.ga4_send(name, attributes)
    } else {
      window.thrive.ga4_queue.push( { name: name, attributes: attributes } )
    }
  }

  window.thrive.periodic_check_ga4_ready = function(next_wait) {
    window.thrive.ga4_waiter_id = null
    window.thrive.ga4_ids = Object.keys( window.google_tag_manager || [] ).filter( e => { return e.substring(0,2) == 'G-' } )
    if (window.thrive.ga4_ids.length > 0) {
      if (typeof window.gtag != 'function') {
        window.gtag = function() { dataLayer.push(arguments) }
      }
      while ( window.thrive.ga4_queue.length > 0 ) {
        e = window.thrive.ga4_queue.shift()
        window.thrive.ga4_send( e['name'], e['attributes'] )
      }
    } else if (next_wait < 20000) {
      window.thrive.ga4_waiter_id = setTimeout( function() { window.thrive.periodic_check_ga4_ready(next_wait*1.5) }, next_wait )
    }
  }

  window.thrive.trigger_ga4 = function(gte_object) {
    var attributes = {
      'thrive_uuid':  gte_object['uuid'],
      'thrive_token': gte_object[ gte_object['gte_class_name'] == 'pageview' ? 'tsc_available' : 'token' ]
    }
    switch ( gte_object['tsckind'] ) {
      case 'dbtsc': attributes['thrive_promotions_center_type'] = 'Smart Bar';    break
      case 'cctsc': attributes['thrive_promotions_center_type'] = 'Smart Button'; break
      case 'tsc':   attributes['thrive_promotions_center_type'] = 'Smart Pages';  break
    }

    if ( gte_object["gte_class_name"]=='pageview' && gte_object['ab'] != '' ) {
      window.thrive.ga4( 'thrive_experiment_view', { 'thrive_uuid': gte_object['uuid'], 'thrive_variant': gte_object['ab'] } )
    }

    if ( gte_object["gte_class_name"]=='pageview' && ( /^(db|cc)tsc$/.exec( gte_object["tsckind"] ) ) ) {
      window.thrive.ga4('thrive_available', attributes)

    } else if ( gte_object["gte_class_name"]=='tsc' ) {
      attributes['thrive_category'       ] = gte_object['category']
      attributes['thrive_engagement_type'] = ( gte_object['caveat'] == 'auto' ? 'Auto' : 'Manual' )
      window.thrive.ga4( 'thrive_view_offers', attributes )

    } else if ( gte_object["gte_class_name"]=='offer_engagement' && ( !/_(engage|pass)$/.exec(gte_object["kind"]) ) ) {
      attributes['thrive_offer_title'    ] = gte_object['name'    ]
      attributes['thrive_offer_id'       ] = gte_object['offer_id']
      if ( /_code$/.exec( gte_object["kind"] ) ) { attributes['thrive_code'] = gte_object['code'] }

      switch ( gte_object["kind"] ) {
          case 'apply_code':   attributes['thrive_engagement_type'] = 'Apply Code';       break
          case 'copy_code':    attributes['thrive_engagement_type'] = 'Copy Code';        break
          case 'click_code':   attributes['thrive_engagement_type'] = 'Manual Code Copy'; break
          case 'navigate':     attributes['thrive_engagement_type'] = 'CTA Click';        break
          case 'details':      attributes['thrive_engagement_type'] = 'Details Click';    break
      }
      if ( gte_object["kind"] == 'instore_execute' ) {
        switch ( gte_object['instore_type'] ) {
          case 'apple_wallet': attributes['thrive_engagement_type'] = 'Save to Apple Wallet';      break
          case 'email':        attributes['thrive_engagement_type'] = 'Email Share';               break
          case 'sms':          attributes['thrive_engagement_type'] = 'SMS Share';                 break
          case 'print':        attributes['thrive_engagement_type'] = 'In-Store Print Click';      break
          case 'view':         attributes['thrive_engagement_type'] = 'In-Store View Offer Click'; break
        }
      }
      if ( gte_object["kind"] == 'social_execute' ) {
        switch ( gte_object['social_type'] ) {
          case 'apple_wallet': attributes['thrive_engagement_type'] = 'Save to Apple Wallet'; break
          case 'email':        attributes['thrive_engagement_type'] = 'Email Share';          break
          case 'sms':          attributes['thrive_engagement_type'] = 'SMS Share';            break
        }
      }

      if ( gte_object['in_store'] == '1' ) {
        attributes['thrive_offer_type'] = 'In-Store'
      } else {
        switch ( gte_object['offer_type'] ) {
          case 'rebate': attributes['thrive_offer_type'] = 'Rebate';         break
          case 'coupon': attributes['thrive_offer_type'] = 'Code-Based';     break
          case 'other':  attributes['thrive_offer_type'] = 'Non-Code Based'; break
        }
      }

      window.thrive.ga4('thrive_select_offer', attributes)
    }
  }

  window.thrive.gte = function(gte_class_name, gte_object) {
    gte_object = window.thrive.trim_attributes(gte_object)
    if (gte_class_name != 'pageview') {
      gte_object["uuid"]                   = window.thrive.generate_uuid( gte_object["msec"] = (new Date).getTime() )
      gte_object["pv_uuid"]                = window.thrive.pv_uuid
    }

    gte_object["fp_uuid"]                  = window.thrive.get_cookie('thrive_fp_uuid')

    if ( ["txn", "checkout", "cart"].indexOf(gte_class_name) >= 0 ) { //superclass
      gte_object["gte_class_name"]         = "cart"
      gte_object["status"]                 = gte_class_name
      gte_object["txn_id"]                 = gte_object["id"]
    } else if (gte_class_name == 'product') {
      gte_object["gte_class_name"]         = gte_class_name
      gte_object["txn_id"]                 = gte_object["id"]
    } else {
      gte_object["gte_class_name"]         = gte_class_name
    }
    delete gte_object["id"]
    window.thrive.gte_queue.push(gte_object)
    if (gte_class_name == 'tsc') {
      window.thrive.tsc_uuid = gte_object["uuid"]
    }
  }
  
  window.thrive.gte_send = function() {
    if ('site' in window.thrive) {
      window.thrive.gte_queue.forEach( function(gte_object) {
        gte_object["site"] = window.thrive.site
        window.thrive.add_script( ( "//gte.thrive.today/" + window.thrive.urlsafe_b64_encode(gte_object) + '/gte.js' ), 1 )
        window.thrive.trigger_ga4(gte_object)
      } )
      window.thrive.gte_queue = []
    }
  }



  window.thrive_pv = function() {
    // clean up for SPA frontend pageview
    document.querySelectorAll("[data-mod-by=\"thrive\"]").forEach( e => e.parentNode.removeChild(e) )
    if ('observers'             in window.thrive) { Object.keys(window.thrive.observers).forEach( o => window.thrive.observers[o].disconnect()                                                    ) }
    if ('listeners'             in window.thrive) { Object.keys(window.thrive.listeners).forEach( l => window.removeEventListener( window.thrive.listeners[l][0], window.thrive.listeners[l][1] ) ) }
    if ('dbtsc_esc_listener'    in window.thrive) { window.removeEventListener('keydown', window.thrive.dbtsc_esc_listener) }
    if ('cctsc_esc_listener'    in window.thrive) { window.removeEventListener('keydown', window.thrive.cctsc_esc_listener) }
    if (window.thrive.ga4_waiter_id             ) { clearTimeout(window.thrive.ga4_waiter_id) }

    // init vars
    window.thrive.new_nodes     = {}
    window.thrive.observers     = {}
    window.thrive.listeners     = {}
    window.thrive.functions     = {}
    window.thrive.gte_queue     = []
    window.thrive.ga4_ids       = []
    window.thrive.ga4_queue     = []
    window.thrive.ga4_waiter_id = null
    window.thrive.b64_digits    = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'

    // kick off gte->ga4 event proxy
    window.thrive.periodic_check_ga4_ready(100)

    // pageview fundamentals
    window.thrive.effective_url_b64 = window.thrive.urlsafe_b64_encode( window.thrive.effective_url     = window.location.href )
    window.thrive.pv_uuid           = window.thrive.generate_uuid(      window.thrive.frontend_pv_msec  = (new Date).getTime() )

    // if no valid fp_uuid, generate & set a new one
    if ( !window.thrive.get_cookie('thrive_fp_uuid'   ) || window.thrive.get_cookie('thrive_fp_uuid').length != 56 ) {
      window.thrive.set_cookie( 'thrive_fp_uuid' , window.thrive.generate_uuid(window.thrive.frontend_pv_msec), window.thrive.get_top_cookieable_domain(), 'Wed, 01 Jan 2070 00:00:00 GMT' )
    }

    // thrive 30-minute session mechanics & anonymous data
    if ( !window.thrive.get_ls()['cur_sess_msec' ] || window.thrive.get_ls()['cur_sess_msec'] < window.thrive.frontend_pv_msec - 30*60*1000 ) {
      window.thrive.set_ls( 'cur_sess_msec'       , window.thrive.frontend_pv_msec                      )
      window.thrive.set_ls( 'cur_sess_lp'         , window.thrive.effective_url                         )
      window.thrive.set_ls( 'cur_sess_pv'         , 0                                                   )
      window.thrive.set_ls( 'cur_sess_auto_opened', false                                               )
      window.thrive.set_ls( 'alltime_sess'        , ( window.thrive.get_ls()['alltime_sess'] || 0 ) + 1 )
      window.thrive.append_ls_session( window.thrive.frontend_pv_msec                                   )
    }

    //increment pv counts
    window.thrive.set_ls( 'cur_sess_pv', ( window.thrive.get_ls()['cur_sess_pv'] || 0 ) + 1 )
    window.thrive.set_ls( 'alltime_pv' , ( window.thrive.get_ls()['alltime_pv' ] || 0 ) + 1 )

    // thrive 60-min blackout period
    if ( !window.thrive.get_ls()['bo_msec'] || window.thrive.get_ls()['bo_msec'] < window.thrive.frontend_pv_msec - 60*60*1000 ) {
      window.thrive.set_ls( 'bo_msec'   , window.thrive.frontend_pv_msec )
    }

    // dtam.js
    if ( !['shop.advanceautoparts.com','www.autozone.com'].includes(document.domain) ) {
      window.thrive.add_script(
        "//dtam.thrive.today/" + window.thrive.pv_uuid + '/' + window.thrive.effective_url_b64 + '/dtam.js?' +
        'fp_uuid=' + encodeURIComponent( window.thrive.get_cookie('thrive_fp_uuid') ) +
        '&lp='     + encodeURIComponent( window.thrive.get_ls()  ['cur_sess_lp'   ] ) +
        '&mbo='    + encodeURIComponent( window.thrive.get_ls()  ['bo_msec'       ] )
      , 0 )
    }
  }

  window.thrive_pv()
}
