Index: openacs-4/packages/boomerang/README =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/boomerang/README,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/boomerang/README 3 Jan 2018 19:20:58 -0000 1.1 @@ -0,0 +1,154 @@ + +Integration of the Boomerang Library into OpenACS +================================================= + +Boomerang is a JavaScript library to measure the performance of your +website from your end user’s point of view. It has the ability to send +performance data measured at the client back to the server via a +beacon URL further analysis. The boomerang library implements Real +User Measurement (RUM) to measure the performance experience of real +users by collecting quality indicators from the clients. + +The boomerang library is released under the BSD license. + +Details: + https://soasta.github.io/boomerang/doc/ + +This package integrates boomerang with OpenACS, in particular with +OpenACS subsites. + + +FEATURES: +========= + +- Obtain client site timings to measures the performance of your + website from your end user's point of view. + +- Support sampling (e.g. just obtain metrics from every nth request) + +- Output performance data in a format suitable for feeding into + Elasticsearch/Logstash (see below for a sample config file) + +- Configure the appearance of the boomerang per subsite with + the following parameters: + BoomerangEnabled 0|1 + BoomerangSample 1 + BoomerangBeaconUrl /boomerang_handler + + The parameter BoomerangSample can be used for busy sites + to sample not every request (when the value is 1), but e.g. + every 5th request (setting BoomerangSample to 5). + +- Support for host-node-mapped subsites + +- Performance: include boomerang in the template costs about 0.3ms, + processing of the beacon call takes about 1ms (filter times). + + +INSTALLATON: +============ + 1) Install this package via the OpenACS Package Manager + + 2) Add this package to the templating system + + - OpenACS 5.10.0d2 or newer: + The cookie consent widgets uses the "subsite::page_plugin" + callback, so no changes on templates are necessary. + + Make sure to update as well the acs-bootstrap-installer to + 5.10.0d2 or newer to obtain the updated blank-master. + + - OpenACS 5.9.1: + Add to the top of your blank-master.tcl the following snippet: + + ================================================================ + if {[info commands ::boomerang::initialize_widget] ne ""} { + ::boomerang::initialize_widget + } + ================================================================ + + 3) Configure in the parameters of the subsite (e.g. the main subsite) + the section "Boomerang Plugin" + + +USAGE: +====== + For the explanation of the parameters, see: + https://soasta.github.io/boomerang/doc/howtos/howto-0.html + https://soasta.github.io/boomerang/doc/api/RT.html + https://soasta.github.io/boomerang/doc/api/navtiming.html + + +PREREQUIREMENTS: +================ + +The implementation uses nx from the next-scripting framework. + + https://next-scripting.org/xowiki/ + +which is automatically installed for XOTcl2 via +https://openacs.org/xowiki/naviserver-openacs + +It works best with OpenACS 5.10.0d2 or newer, but works as well +with 5.9.1 (see INSTALLATION section above) or earlier versions +supporting Content Security Policy (CSP), and probably with +earlier versions as well, when CSP code is commented out. + + +OPTIONAL: DEFINE A CUSTOM BOOMERANG PLUGIN +========================================== + + 1) clone boomerang repository + + 2) install npm, grunt if necessary + + 3) Follow step 2 in https://github.com/SOASTA/boomerang + which means + ... configure plugins + ... grunt clean build + + 4) The result is in the build directory. The generated + files have the a build-time stamp in seconds included. + You might which to rename these with a custom name. + + 5) Copy the the *.min.js and *.min.js.gz files to + the boomerang/www/resouces directory, which might be + + cp build/boomerang-1.0.*.min.js build/boomerang-1.0.*.min.js.gz .. + + and adapt the version number in the boomerang parameters + (on /acs-subsite) + + + +OPTIONAL: FEED DATA INTO AN ELASTICSEARCH CLUSTER +================================================= + +When boomerang is enabled, the results of the beacon are placed into +the OpenACS log directory with a name boomerang-*.log (containing the date). + +Below are sample-snippets from OpenACS.org the log-files into elasticsearch, +such that it can be analyzed later with kibana or grafana. + +------------------------------------------------------------ sample filebeat entry + - + paths: + - /var/www/openacs.org/log/boomerang-*.log + input_type: log + fields: + log_type: boomerang-log +------------------------------------------------------------ + + +------------------------------------------------------------matching input filter for logstash + if [fields][log_type] == "boomerang-log" { + json { + source => "message" + remove_field => [ "restiming" ] + } + grok { + match => [ "source", "/var/www/%{GREEDYDATA:server}/log/boomerang-" ] + } + geoip { source => "clientip" } + } +------------------------------------------------------------ Index: openacs-4/packages/boomerang/boomerang.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/boomerang/boomerang.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/boomerang/boomerang.info 3 Jan 2018 19:20:58 -0000 1.1 @@ -0,0 +1,53 @@ + + + + + Boomerang Plugin + Boomerang Plugins + f + t + f + f + + + Gustaf Neumann + + +Boomerang is a JavaScript library to measure the performance of your +website from your end user’s point of view. It has the ability to send +performance data measured at the client back to the server via a +beacon URL further analysis. The boomerang library implements Real +User Measurement (RUM) to measure the performance experience of real +users by collecting quality indicators from the clients. + +The boomerang library is released under the BSD license. + +Details: + https://soasta.github.io/boomerang/doc/ + +This package integrates boomerang with OpenACS, +in particular with OpenACS subsites. + + 2018-01-02 + BSD License + 0 + + + + + + + + + + + + + + + + Index: openacs-4/packages/boomerang/tcl/boomerang-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/boomerang/tcl/boomerang-init.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/boomerang/tcl/boomerang-init.tcl 3 Jan 2018 19:20:58 -0000 1.1 @@ -0,0 +1,34 @@ + + +# +# We should get the URL from the parmeter and register this for every +# toplevel subsite, on which boomerang is enabled +# +foreach url {/} { + + set node_info [site_node::get_from_url -url $url] + set subsite_id [dict get $node_info object_id] + set enabled_p [parameter::get \ + -package_id $subsite_id \ + -parameter BoomerangEnabled \ + -default 0] + if {$enabled_p} { + set beaconURL [parameter::get \ + -package_id $subsite_id \ + -parameter BoomerangBeaconUrl \ + -default /boomerang_handler] + # + # Register the beaconURL only, when it is not a fully qualified URL + # + if {[regexp {^https?://} $beaconURL] == 0} { + foreach httpMethod {GET POST} { + ns_register_proc $httpMethod ${url}[string trimleft $beaconURL /] { + set t0 [clock clicks -microseconds] + boomerang::handler record -ns_set [ns_getform] -peeraddr [ad_conn peeraddr] + ns_log notice "boomerang beacon [expr {[clock clicks -microseconds] - $t0}] microseconds" + ns_return 204 text/plain "" + } + } + } + } +} Index: openacs-4/packages/boomerang/tcl/boomerang-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/boomerang/tcl/boomerang-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/boomerang/tcl/boomerang-procs.tcl 3 Jan 2018 19:20:58 -0000 1.1 @@ -0,0 +1,421 @@ +ad_library { + + Integration of the Boomerang Library into OpenACS + + The Boomerang Library is an open sourced library (BSD licence) + for Real User Measurement (RUM) and measures the performance + experience of real users by collecting quality indicators from the + clients. e.g. based on the W3C Navigation Timing model + + Details: + https://soasta.github.io/boomerang/doc/ + https://www.w3.org/TR/navigation-timing/#processing-model + + This package integrates boomerang as a Plugin in OpenACS. + + @author Gustaf Neumann + @creation-date 2 Jan 2018 + @cvs-id $Id: boomerang-procs.tcl,v 1.1 2018/01/03 19:20:58 gustafn Exp $ +} + +namespace eval ::boomerang { + + set package_id [apm_package_id_from_key "boomerang"] + + # + # It is possible to configure the version of the boomerang + # plugin also via NaviServer config file: + # + # ns_section ns/server/${server}/acs/boomerang + # ns_param version 1.0.1514200883 + # + + set version [parameter::get \ + -package_id $package_id \ + -parameter Version \ + -default 1.0.1514200883] + + # + # Boomerang response handler + # + nx::Object create handler { + + # + # Don't quote the following boomerang attributes when output + # format is JSON. + # + foreach v { + t_done + + rt.cstart xrt.tstart rt.bstart rt.end + + nt_con_end nt_con_st nt_dns_end nt_dns_st nt_domcomp + nt_domcontloaded_end nt_domcontloaded_st nt_domint + nt_domloading nt_fet_st nt_first_paint nt_load_end + nt_load_st nt_nav_st nt_red_cnt nt_red_end nt_red_st nt_req_st + nt_res_end nt_res_st nt_spdy nt_ssl_st nt_unload_end + nt_unload_st + + nt_start_time nt_tcp_time nt_request_time nt_response_time nt_processing_time + + dom.res dom.doms dom.ln dom.sz dom.img dom.script dom.script.ext dom.iframe dom.link + + mem.total mem.limit mem.used + + bat.lvl + cpu.cnc + mob.rtt + scr.dpx + + } {set :json_unquoted($v) 1} + + foreach v { + restiming + } { + set :json_drop($v) 1 + } + + foreach {orig new} { + dom.script.ext dom.script_ext + } { + set :json_map($orig) $new + } + + :object method ms_to_utc {ms} { + set seconds [expr {$ms / 1000}] + set fraction [format %03d [expr {$ms - ($seconds * 1000)}]] + return [clock format $seconds -format "%Y-%m-%dT%H:%M:%S" -gmt 1].${fraction}Z + } + + :object method log_to_file {-content -filename} { + set logdir [file dirname [file rootname [ns_config ns/parameters ServerLog]]] + set F [open $logdir/$filename a] + try { + puts $F $content + } finally { + close $F + } + } + + :object method as_json {dict} { + package require json::write + #::json::write object {*} + set result "" + dict map {k v} $dict { + # + # Some fields (like e.g.restiming) can't be used + # easily for elastic search, since it contains names + # with dots, and keys starting with dots, which are + # interpreted differently in elasticsearch + # + if {[info exists :json_drop($k)]} { + continue + } + # + # We have to map some key containing dots. + # + if {[info exists :json_map($k)]} { + set k [set :json_map($k)] + } + set entry "\"$k\":" + # + # Some fields have to be quoted + # + if {[info exists :json_unquoted($k)]} { + append entry $v + } else { + append entry [::json::write string $v] + } + lappend result $entry + } + return "{[join $result ,]}" + } + + :public object method record {-ns_set:required -peeraddr:required} { + set t0 [clock clicks -microseconds] + #xotcl::Object log "boomerang::record start" + + set entries [ns_set array $ns_set] + dict set entries clientip $peeraddr + + if {![dict exists $entries rt.tstart]} { + ns_log notice "boomerang: no rt.tstart value in $entries" + set record 0 + } else { + dict set entries @timestamp [:ms_to_utc [dict get $entries rt.tstart]] + + # + # Do we have W3C "Navigation Timing" information? + # Just record data containing this information. + # + # Other entries have often strange t_done values: e.g. a + # reload of a page, having an automatic refresh after many + # refreshes will cause such a beacon GET request with a + # t_done time span reaching to the original load of the + # page. + # + if {[dict exists $entries nt_con_st]} { + # + # Add nt_*_time variables according to the "Navigation Timing" W3C recommendation + # up to domComplete (see https://www.w3.org/TR/navigation-timing/#processing-model) + # + dict set entries nt_start_time [expr {[dict get $entries nt_req_st] - [dict get $entries nt_nav_st]}] + dict set entries nt_tcp_time [expr {[dict get $entries nt_con_end] - [dict get $entries nt_con_st]}] + dict set entries nt_request_time [expr {[dict get $entries nt_res_st] - [dict get $entries nt_req_st]}] + dict set entries nt_response_time [expr {[dict get $entries nt_res_end] - [dict get $entries nt_res_st]}] + dict set entries nt_processing_time [expr {[dict get $entries nt_domcomp] - [dict get $entries nt_res_end]}] + + # + # Sanity check for the computed fields: + # - no *_time can be larger than t_done + # - no *_time must be negative + # + set t_done [dict get $entries t_done] + set time_fields { nt_start_time nt_tcp_time nt_request_time nt_response_time nt_processing_time } + foreach time_field $time_fields { + set v [dict get $entries $time_field] + if {$v < 0 || $v > $t_done} { + ns_log Warning "boomerang: strange value for $time_field: <$v> computed from $entries" + dict set entries $time_field 0 + } + } + set record 1 + } else { + ns_log notice "boomerang: no nt_con_st value in $entries" + set record 0 + } + } + # + # Drop most Navigation Timing timestamps, since we have + # the relative times (might require more fine tuning). + # + foreach field { + nt_con_end + nt_con_st + nt_dns_end + nt_dns_st + nt_domcomp + nt_domcontloaded_end + nt_domcontloaded_st + nt_domint + nt_domloading + nt_fet_st + nt_load_end + nt_load_st + nt_res_st + nt_ssl_st + nt_unload_end + nt_unload_st + } { + dict unset entries $field + } + set t1 [clock clicks -microseconds] + + # + # dict is finished, now record the data when requested + # + if {$record} { + + :log_to_file \ + -content [:as_json $entries] \ + -filename boomerang-[clock format [clock seconds] -format %Y-%m-%d].log + + } + + # + # Some common parameters: + # https://docs.soasta.com/whatsinbeacon/#urls + # + # - nu: URL clicked, if this beacon was a result of a click + # - pgu: Page URL if different from u + # - r2: Referrer of current page if different from r + # - r: URL of previous page that Boomerang wrote into a cookie + # - u: URL of Page, XHR or SPA route that caused the beacon + # + if {![dict exists $entries r]} { + ns_log notice "boomerang: no r value in $entries" + dict set entries r "" + } + set r [dict get $entries r] + set u [dict get $entries u] + set pid [dict get $entries pid] + if {$r ne "" && $r ne $u} { + set r " r $r" + } else { + set r "" + } + ns_log notice "boomerang::record done $pid [ns_conn method] u $u$r record $record total [expr {[clock clicks -microseconds] - $t0}] microseconds record [expr {[clock clicks -microseconds] - $t1}] " + } + } + + + ad_proc -private get_relevant_subsite {} { + + Find the best "top" subsite on the instance. The code is + based on the "register subsite", which is in plain sites + (single subsite) the top subsite, or on host-node-mapped + subsites to mapped subsite (when the host-node map points to a + subsite) or the main subsite. This code makes sure, we can + provide a URL on this site. We should distinguish between + cases where we provide an URL (e.g. the beacon) or just + include stuff, in which case it works als well for host-node + entries, which are no subsites..... but these cases are rare + enough, such we don't care so far. + + } { + set dict [security::get_register_subsite] + if {![dict exists $dict subsite_id]} { + set host_node_id [dict get $dict host_node_id] + if {$host_node_id == 0} { + # + # Provide compatibility with older versions of + # get_register_subsite, not returning the + # host_node_id. In such cases, we get the host_node_id + # via the URL + # + set node_info [site_node::get_from_url -url [dict get $dict url]] + set host_node_id [dict get $node_info node_id] + } + set subsite_id [site_node::get_object_id -node_id $host_node_id] + } else { + set subsite_id [dict get $dict subsite_id] + } + return $subsite_id + } + + + ad_proc initialize_widget { + {-subsite_id ""} + {-version ""} + } { + + Initialize an boomerang widget. + + } { + set t0 [clock clicks -microseconds] + if {$subsite_id eq ""} { + set subsite_id [get_relevant_subsite] + } + if {$version eq ""} { + set version ${::boomerang::version} + } + + set enabled_p [parameter::get \ + -package_id $subsite_id \ + -parameter BoomerangEnabled \ + -default 0] + if {$enabled_p} { + # + # Check, if we should sample this request + # + set sample [parameter::get \ + -package_id $subsite_id \ + -parameter BoomerangSample \ + -default 1] + if {$sample < 1} { + set sample 1 + } + + if {[nsv_incr boomerange counter] % $sample == 0} { + # + # Yes, we can! + # + # Get the URL and add JavaScript to the page + # + set beaconURL [parameter::get \ + -package_id $subsite_id \ + -parameter BoomerangBeaconUrl \ + -default /boomerang_handler] + + set version_info [version_info] + set prefix [dict get $version_info prefix] + + template::head::add_javascript -src $prefix/boomerang-${version}.min.js + # + # One could add additional plugins here, but many are + # already included in the provided .min.js file via the + # upstream provided plugins.json + # + # "plugins/auto-xhr.js", + # "plugins/spa.js", + # "plugins/history.js", + # "plugins/rt.js", + # "plugins/bw.js", + # "plugins/navtiming.js", + # "plugins/restiming.js", + # "plugins/mobile.js", + # "plugins/memory.js", + # "plugins/cache-reload.js", + # "plugins/md5.js", + # "plugins/compression.js", + # "plugins/errors.js", + # "plugins/third-party-analytics.js", + # "plugins/usertiming.js", + # "plugins/mq.js" + # + + template::head::add_javascript -order 2 -script [subst { + BOOMR.init({ + beacon_url: "$beaconURL" + }); + }] + } + } + ns_log notice "boomerang::initialize_widget [expr {[clock clicks -microseconds] - $t0}] microseconds" + } + + + ad_proc version_info { + {-version ""} + } { + + Get information about available version(s) of the + boomerang packages, either from the local file system, or + from CDN. + + } { + # + # If no version of the boomerange library was specified, + # use the name-spaced variable as default. + # + if {$version eq ""} { + set version ${::boomerang::version} + } + + # + # Provide paths for loading either via resources or CDN + # + set resource_prefix [acs_package_root_dir boomerang/www/resources] + set cdn "//cdnjs.cloudflare.com/ajax/libs" + + # + # If the resources are not available locally, these will be + # loaded via CDN and the CDN host is set (necessary for CSP). + # The returned "prefix" indicates the place, from where the + # resource will be loaded. + # + if {[file exists $resource_prefix]} { + set prefix /resources/boomerang + } else { + # + # So far there is no CDN form boomerang, we distribute + # boomerang.js via static file. + # + set prefix $cdn/$version/ + lappend result host "cdnjs.cloudflare.com" + } + lappend result \ + cdn $cdn \ + prefix $prefix \ + cssFiles {} \ + jsFiles [list boomerang.js] + + return $result + } +} + +# Local variables: +# mode: tcl +# tcl-indent-level: 4 +# indent-tabs-mode: nil +# End: Index: openacs-4/packages/boomerang/tcl/callback-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/boomerang/tcl/callback-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/boomerang/tcl/callback-procs.tcl 3 Jan 2018 19:20:58 -0000 1.1 @@ -0,0 +1,76 @@ +ad_library { + + Callback procs for Boomerang Library into OpenACS + + @author Gustaf Neumann + @creation-date 2 Jan 2018 + @cvs-id $Id: callback-procs.tcl,v 1.1 2018/01/03 19:20:58 gustafn Exp $ +} + +namespace eval ::boomerang { + + # + # Provide hooks for installing/uninstalling the package + # + ad_proc -private after-install {} { + # + # Add additional parameters to acs-subsite + # + foreach {name description default datatype} { + "Enabled" + "Enable/Disable Boomerang for this Subsite" + "0" "number" + + "BeaconUrl" + "URL for the Beacon. Either a relative URL for the subsite, or and absolute URL pointing to a different Server" + "/boomerang_handler" "string" + + "Sample" + "Integer greater or equal 1, indicating how many requests should be sampled (e.g. 10 means: sample every 10th request)" + "1" "number" + + } { + apm_parameter_register "Boomerang$name" \ + $description "acs-subsite" $default $datatype "Boomerang" + } + } + + ad_proc -private before-uninstall {} { + # + # Remove the package specific parameters from acs-subsite + # + foreach parameter { + Enabled + BeaconUrl + Sample + } { + ns_log notice [list apm_parameter_unregister \ + -parameter "Boomerang$parameter" \ + -package_key "acs-subsite" \ + "" ] + ::try { + apm_parameter_unregister \ + -parameter "Boomerang$parameter" \ + -package_key "acs-subsite" \ + "" + } on error {errMsg} { + ns_log notice "apm_parameter_unregister of parameter Boomerang$parameter lead to: $errMsg" + } + } + } + + + # + # Register a "page_plugin" callback for the subsite. In case, this + # is used with an OpenACS version earlier than 5.10.0d2, this is + # essentially no-op operation; the site admin has to add the + # "::boomerang::initialize_widget" manually to the templates. + # + ad_proc -public -callback subsite::page_plugin -impl boomerang { + } { + Implementation of subsite::page_plugin for boomerang + } { + ::boomerang::initialize_widget + } + +} Index: openacs-4/packages/boomerang/www/resources/boomerang-1.0.1514200883-debug.min.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/boomerang/www/resources/boomerang-1.0.1514200883-debug.min.js,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/boomerang/www/resources/boomerang-1.0.1514200883-debug.min.js 3 Jan 2018 19:20:58 -0000 1.1 @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011, Yahoo! Inc. All rights reserved. + * Copyright (c) 2011-2012, Log-Normal, Inc. All rights reserved. + * Copyright (c) 2012-2016, SOASTA, Inc. All rights reserved. + * Copyrights licensed under the BSD License. See the accompanying LICENSE.txt file for terms. + */ +/* JavaScript MD5 1.0.1 Copyright 2011, Sebastian Tschan. Licensed under the MIT license. */ +/* Boomerang Version: 1.0.1514200883 */ + +function BOOMR_check_doc_domain(a){if(window){if(!a){if(window.parent===window||!document.getElementById("boomr-if-as"))return;if(window.BOOMR&&BOOMR.boomerang_frame&&BOOMR.window)try{BOOMR.boomerang_frame.document.domain!==BOOMR.window.document.domain&&(BOOMR.boomerang_frame.document.domain=BOOMR.window.document.domain)}catch(b){BOOMR.isCrossOriginError(b)||BOOMR.addError(b,"BOOMR_check_doc_domain.domainFix")}a=document.domain}if(-1!==a.indexOf(".")){try{window.parent.document;return}catch(b){document.domain=a}try{window.parent.document;return}catch(b){a=a.replace(/^[\w\-]+\./,"")}BOOMR_check_doc_domain(a)}}}BOOMR_start=(new Date).getTime();BOOMR_check_doc_domain();!function(a){var b,c,d,e,f,g,h,i,j=a;if(a.parent!==a&&document.getElementById("boomr-if-as")&&"script"===document.getElementById("boomr-if-as").nodeName.toLowerCase()){a=a.parent;e=document.getElementById("boomr-if-as").src}d=a.document;a.BOOMR||(a.BOOMR={});BOOMR=a.BOOMR;if(!BOOMR.version){BOOMR.version="1.0.1514200883";BOOMR.window=a;BOOMR.boomerang_frame=j;BOOMR.plugins||(BOOMR.plugins={});!function(){try{void 0!==new a.CustomEvent("CustomEvent")&&(f=function(b,c){return new a.CustomEvent(b,c)})}catch(b){}try{!f&&d.createEvent&&d.createEvent("CustomEvent")&&(f=function(a,b){var c=d.createEvent("CustomEvent");b=b||{cancelable:!1,bubbles:!1};c.initCustomEvent(a,b.bubbles,b.cancelable,b.detail);return c})}catch(b){}!f&&d.createEventObject&&(f=function(a,b){var c=d.createEventObject();c.type=c.propertyName=a;c.detail=b.detail;return c});f||(f=function(){})}();g=function(a,b,c){function e(){try{d.dispatchEvent?d.dispatchEvent(g):d.fireEvent&&d.fireEvent("onpropertychange",g)}catch(b){BOOMR.debug("Error when dispatching "+a)}}var g=f(a,{detail:b});g&&(c?BOOMR.setImmediate(e):e())};if(void 0!==document.hidden){h="visibilityState";i="visibilitychange"}else if(void 0!==document.mozHidden){h="mozVisibilityState";i="mozvisibilitychange"}else if(void 0!==document.msHidden){h="msVisibilityState";i="msvisibilitychange"}else if(void 0!==document.webkitHidden){h="webkitVisibilityState";i="webkitvisibilitychange"}b={beacon_url:"",beacon_type:"AUTO",beacon_auth_key:"Authorization",beacon_auth_token:void 0,site_domain:a.location.hostname.replace(/.*?([^.]+\.[^.]+)\.?$/,"$1").toLowerCase(),user_ip:"",autorun:!0,hasSentPageLoadBeacon:!1,r:void 0,r2:void 0,events:{page_ready:[],page_unload:[],before_unload:[],dom_loaded:[],visibility_changed:[],prerender_to_visible:[],before_beacon:[],onbeacon:[],page_load_beacon:[],xhr_load:[],click:[],form_submit:[],onconfig:[],xhr_init:[],spa_init:[],spa_navigation:[],xhr_send:[]},public_events:{before_beacon:"onBeforeBoomerangBeacon",onbeacon:"onBoomerangBeacon",onboomerangloaded:"onBoomerangLoaded"},listenerCallbacks:{},vars:{},varPriority:{"-1":{},1:{}},errors:{},disabled_plugins:{},xb_handler:function(c){return function(d){var e;d||(d=a.event);d.target?e=d.target:d.srcElement&&(e=d.srcElement);3===e.nodeType&&(e=e.parentNode);e&&"OBJECT"===e.nodeName.toUpperCase()&&"application/x-shockwave-flash"===e.type||b.fireEvent(c,e)}},clearEvents:function(){var a;for(a in this.events)this.events.hasOwnProperty(a)&&(this.events[a]=[])},clearListeners:function(){var a;for(a in b.listenerCallbacks)if(b.listenerCallbacks.hasOwnProperty(a))for(;b.listenerCallbacks[a].length;)BOOMR.utils.removeListener(b.listenerCallbacks[a][0].el,a,b.listenerCallbacks[a][0].fn);b.listenerCallbacks={}},fireEvent:function(a,b){var c,d,e,f;a=a.toLowerCase();if(this.events.hasOwnProperty(a)){this.public_events.hasOwnProperty(a)&&g(this.public_events[a],b);e=this.events[a];"before_beacon"!==a&&"onbeacon"!==a&&BOOMR.real_sendBeacon();f=e.length;for(c=0;c")}for(c=0;c0&&null!==a[d]&&"object"==typeof a[d]?e.push(this.objectToString(a[d],b+("\n\t"===b?"\t":""),c-1)):"&"===b?e.push(encodeURIComponent(a[d])):e.push(a[d]);b=","}else for(d in a)Object.prototype.hasOwnProperty.call(a,d)&&(c>0&&null!==a[d]&&"object"==typeof a[d]?e.push(encodeURIComponent(d)+"="+this.objectToString(a[d],b+("\n\t"===b?"\t":""),c-1)):"&"===b?e.push(encodeURIComponent(d)+"="+encodeURIComponent(a[d])):e.push(d+"="+a[d]));return e.join(b)},getCookie:function(a){if(!a)return null;a=" "+a+"=";var b,c;c=" "+d.cookie+";";if((b=c.indexOf(a))>=0){b+=a.length;c=c.substring(b,c.indexOf(";",b)).replace(/^"/,"").replace(/"$/,"");return c}},setCookie:function(a,c,e){var f,g,h,i,j;if(!a||!b.site_domain){BOOMR.debug("No cookie name or site domain: "+a+"/"+b.site_domain);return!1}f=this.objectToString(c,"&");g=a+'="'+f+'"';i=[g,"path=/","domain="+b.site_domain];if(e){j=new Date;j.setTime(j.getTime()+1e3*e);j=j.toGMTString();i.push("expires="+j)}if(g.length<500){d.cookie=i.join("; ");h=this.getCookie(a);if(f===h)return!0;BOOMR.warn("Saved cookie value doesn't match what we tried to set:\n"+f+"\n"+h)}else BOOMR.warn("Cookie too long: "+g.length+" "+g);return!1},getSubCookies:function(a){var b,c,d,e,f=!1,g={};if(!a)return null;if("string"!=typeof a){BOOMR.debug("TypeError: cookie is not a string: "+typeof a);return null}b=a.split("&");for(c=0,d=b.length;cc){var d=a.indexOf("?");a=-1!==d&&d10?BOOMR.utils.MD5(b):b)}):a},pluginConfig:function(a,b,c,d){var e,f=0;if(!b||!b[c])return!1;for(e=0;e0},arrayFilter:function(a,b){var c=[];if("function"==typeof a.filter)c=a.filter(b);else for(var d,e=-1,f=a.length;++e0&&(h.timer=setTimeout(g,b))}var h={observer:null,timer:null};if(!(BOOMR.window&&BOOMR.window.MutationObserver&&d&&a))return null;h.observer=new BOOMR.window.MutationObserver(g);c&&(h.timer=setTimeout(g,h.timeout));h.observer.observe(a,b);return h},addListener:function(a,c,d){a.addEventListener?a.addEventListener(c,d,!1):a.attachEvent&&a.attachEvent("on"+c,d);b.listenerCallbacks[c]=b.listenerCallbacks[c]||[];b.listenerCallbacks[c].push({el:a,fn:d})},removeListener:function(a,c,d){var e;a.removeEventListener?a.removeEventListener(c,d,!1):a.detachEvent&&a.detachEvent("on"+c,d);if(b.listenerCallbacks.hasOwnProperty(c))for(var e=0;e1?" (*"+b.errors[c]+")":""));i.length>0&&(b.vars.errors=i.join("\n"));b.errors={};b.fireEvent("before_beacon",b.vars);b.beacon_url=b.beacon_url_override||b.beacon_url;BOOMR.debug("Ready to send beacon: "+BOOMR.utils.objectToString(b.vars));if(!b.beacon_url){BOOMR.debug("No beacon URL, so skipping.");return!0}for(c in b.vars)if(b.vars.hasOwnProperty(c)){l[c]=b.vars[c];m[c]=b.vars[c]}n=this.getVarsOfPriority(m,-1);o=this.getVarsOfPriority(m,1);j=n.concat(this.getVarsOfPriority(m,0),o);g=j.join("&");e=b.beacon_url+(b.beacon_url.indexOf("?")>-1?"&":"?")+g;("POST"===b.beacon_type||e.length>BOOMR.constants.MAX_GET_LENGTH)&&(k=!1);BOOMR.removeVar("qt");b.fireEvent("onbeacon",l);if(!b.hasSentPageLoadBeacon&&q){b.hasSentPageLoadBeacon=!0;BOOMR.setImmediate(function(){b.fireEvent("page_load_beacon",l)})}if(0===j.length)return this;BOOMR.orig_XMLHttpRequest||BOOMR.window&&BOOMR.window.XMLHttpRequest||(k=!0);if(k){try{f=new Image}catch(s){BOOMR.debug("Image is not a constructor, not sending a beacon");return!1}f.src=e;if(b.secondary_beacons)for(c=0;c=2)f=!1;else{if(0!==a.responseEnd){d=Math.floor(b+a.responseEnd);if(d<=e.timing.loadEventEnd){e.timing.responseEnd=d;f=!0;e.restiming=a}}if(f){e.timing.requestStart=c;e.timing.fetchStart=c;0!==a.responseStart&&(e.timing.responseStart=Math.floor(b+a.responseStart))}}}e.index>-1?j.load_finished(e.index,e.timing.responseEnd):p?j.sendResource(e):n&&!o||j.addEvent(e)}}function i(b,c){a.addEventListener(b,function(){if("readystatechange"===b){e.timing[q[a.readyState]]=BOOMR.now();if(l.ie1011fix&&m&&4===a.readyState){d.pause();a.responseXML;d.resume()}if(4===a.readyState&&0!==a.status){(a.status<200||a.status>=400)&&(e.status=a.status);e.response={text:""===a.responseType||"text"===a.responseType?a.responseText:null,xml:""===a.responseType||"document"===a.responseType?a.responseXML:null,raw:a.response,json:a.responseJSON};loadFinished()}}else{e.status=void 0===c?a.status:c;loadFinished()}},!1)}k.href=g;if(l.excludeFilter(k)){BOOMR.debug("Exclude found for resource: "+k.href+" Skipping instrumentation!","AutoXHR");return b.apply(a,arguments)}void 0===h&&(h=!0);BOOMR.fireEvent("xhr_init","xhr");if(!f){n&&j.watch&&!p&&j.add_event_resource(e);h&&i("readystatechange");i("load");i("timeout",s);i("error",u);i("abort",t)}e.url=k.href;e.method=c;delete e.status;h||(e.synchronous=!0);f=!0;try{return b.apply(a,arguments)}catch(r){e.status=v;loadFinished()}};a.send=function(b){a.resource.requestPayload=b;BOOMR.fireEvent("xhr_send",a);e.timing.requestStart=BOOMR.now();if(void 0===e.status||e.status!==v)return c.apply(a,arguments)};a.resource=e;return a};BOOMR.proxy_XMLHttpRequest.UNSENT=0;BOOMR.proxy_XMLHttpRequest.OPENED=1;BOOMR.proxy_XMLHttpRequest.HEADERS_RECEIVED=2;BOOMR.proxy_XMLHttpRequest.LOADING=3;BOOMR.proxy_XMLHttpRequest.DONE=4;BOOMR.proxy_XMLHttpRequest.prototype=BOOMR.orig_XMLHttpRequest.prototype;BOOMR.window.XMLHttpRequest=BOOMR.proxy_XMLHttpRequest}}function g(){BOOMR.orig_XMLHttpRequest&&BOOMR.orig_XMLHttpRequest!==BOOMR.window.XMLHttpRequest&&(BOOMR.window.XMLHttpRequest=BOOMR.orig_XMLHttpRequest)}function h(a){a.initiator="xhr";BOOMR.responseEnd(a)}var i,j,k,l,m,n=!1,o=!1,p=!1,q=["uninitialized","open","responseStart","domInteractive","responseEnd"],r=1e3,s=-1001,t=-999,u=-998,v=-997,w=["xmlhttprequest","script"];if(window.XMLHttpRequest&&(new XMLHttpRequest).addEventListener){m=window.navigator&&navigator.appVersion&&-1!==navigator.appVersion.indexOf("MSIE 10")||window.navigator&&navigator.userAgent&&navigator.userAgent.match(/Trident.*rv[ :]*11\./);BOOMR=window.BOOMR||{};if(!BOOMR.plugins.AutoXHR){d.stop=function(){d.pause();d.observer=null};d.pause=function(){if(d.observer&&d.observer.observer&&!d.isPaused){d.isPaused=!0;d.observer.observer.disconnect()}};d.resume=function(){if(d.observer&&d.observer.observer&&d.isPaused){d.isPaused=!1;d.observer.observer.observe(i,d.observer.config)}};d.start=function(){if(!d.observer){var a={childList:!0,attributes:!0,subtree:!0,attributeFilter:["src","href"]};d.observer=BOOMR.utils.addObserver(i,a,null,j.mutation_cb,null,j);if(d.observer){d.observer.config=a;BOOMR.subscribe("page_unload",d.stop,null,d)}}};d.prototype.addEvent=function(a){var b,c,e={type:a.initiator,resource:a,nodes_to_wait:0,resources:[],complete:!1},f=this.pending_events.length;for(b=f-1;b>=0;b--)if(this.pending_events[b]&&!this.pending_events[b].complete){c=this.pending_events[b];break}if(c)if("click"===c.type){if(0===c.nodes_to_wait||!c.resource.url){this.pending_events[b]=void 0;return null}}else if("xhr"===c.type){if("click"===e.type)return null}else if(BOOMR.utils.inArray(c.type,BOOMR.constants.BEACON_TYPE_SPAS)&&"xhr"===e.type)return null;this.watch++;this.pending_events.push(e);if(d.observer){BOOMR.utils.inArray(e.type,BOOMR.constants.BEACON_TYPE_SPAS)?this.setTimeout(r,f):this.setTimeout(50,f);return f}if(BOOMR.utils.inArray(e.type,BOOMR.constants.BEACON_TYPE_SPAS)){d.start();this.setTimeout(r,f);return f}a.url&&a.timing.loadEventEnd&&this.sendEvent(f);return null};d.prototype.sendEvent=function(a){var b=this.pending_events[a],c=this;if(b&&!b.complete){this.clearTimeout();if(BOOMR.readyToSend()){b.complete=!0;this.watch--;b.resource.resources=b.resources;BOOMR.utils.inArray(b.type,BOOMR.constants.BEACON_TYPE_SPAS)&&0===b.resources.length&&(b.resource.timing.loadEventEnd=BOOMR.now()-r);this.sendResource(b.resource,a)}else setTimeout(function(){c.sendEvent(a)},500)}};d.prototype.sendResource=function(a,b){var c=this,d=a.timing?a.timing.requestStart:void 0,e=function(e){e&&(a.timing.loadEventEnd=BOOMR.now());BOOMR.real_sendBeacon();a.onComplete&&a.onComplete(a);if(BOOMR.plugins.ResourceTiming&&BOOMR.plugins.ResourceTiming.is_supported()&&a.timing&&a.timing.requestStart){var f=BOOMR.plugins.ResourceTiming.getCompressedResourceTiming(a.timing.requestStart,a.timing.loadEventEnd);BOOMR.plugins.ResourceTiming.addToBeacon(f)}BOOMR.utils.inArray(a.initiator,BOOMR.constants.BEACON_TYPE_SPAS)&&c.calculateSpaTimings(a);BOOMR.responseEnd(a,d,a);b&&(c.pending_events[b]=void 0)};if(a.wait)a.waitComplete=function(){e(!0)};else{if(BOOMR.utils.inArray(a.initiator,BOOMR.constants.BEACON_TYPE_SPAS)&&i&&i.readyState&&"complete"!==i.readyState){BOOMR.window.addEventListener("load",function(){e(!0)});return}e(!1)}};d.prototype.calculateSpaTimings=function(a){var b=BOOMR.getPerformance();if(b&&b.timing)if("spa_hard"===a.initiator){a.timing.responseEnd=b.timing.responseStart;a.timing.fetchStart=b.timing.navigationStart}else{if(!BOOMR.plugins.ResourceTiming)return;var c=BOOMR.plugins.ResourceTiming.getFilteredResourceTiming(a.timing.requestStart,a.timing.loadEventEnd,l.spaBackEndResources).entries,d=Math.round(a.timing.loadEventEnd-a.timing.requestStart);if(!c||!c.length){BOOMR.plugins.ResourceTiming.is_supported()&&(a.timers={t_resp:0,t_page:d,t_done:d});return}for(var e=a.timing.loadEventEnd-b.timing.navigationStart,f=0;fe){c[f].responseStart=e;c[f].responseEnd=e}else c[f].responseEnd>e&&(c[f].responseEnd=e);var g=Math.round(BOOMR.plugins.ResourceTiming.calculateResourceTimingUnion(c)),h=d-g;if(g<0||d<0||h<0){BOOMR.addError("Incorrect SPA time calculation");return}a.timers={t_resp:g,t_page:h,t_done:d}}};d.prototype.setTimeout=function(a,b){var c=this;if(a){this.clearTimeout();this.timer=setTimeout(function(){c.timedout(b)},a)}};d.prototype.timedout=function(a){var b;this.clearTimeout();b=this.pending_events[a];if(b&&BOOMR.utils.inArray(b.type,BOOMR.constants.BEACON_TYPE_SPAS.concat("xhr")))0===b.nodes_to_wait&&this.sendEvent(a);else{this.watch>0&&this.watch--;this.pending_events[a]=void 0}};d.prototype.clearTimeout=function(){if(this.timer){clearTimeout(this.timer);this.timer=null}};d.prototype.load_cb=function(a,b){var c,d,e=BOOMR.now();c=a.target||a.srcElement;if(c&&c._bmr){d=c._bmr.idx;b=void 0!==b?b:c._bmr.res||0;if(!c._bmr.end[b]){c._bmr.end[b]=e;this.load_finished(d,e)}}};d.prototype.load_finished=function(a,b){var c=this.pending_events[a];if(c){c.nodes_to_wait--;if(0===c.nodes_to_wait){c.resource.timing.loadEventEnd=b||BOOMR.now();BOOMR.utils.inArray(c.type,BOOMR.constants.BEACON_TYPE_SPAS)?this.setTimeout(r,a):this.sendEvent(a)}}};d.prototype.wait_for_node=function(a,b){var c,d,e,f,g,h,i=this,j=!1,m=!1;if(a.nodeName.toUpperCase().match(/^(IMG|SCRIPT|IFRAME|IMAGE)$/)||"LINK"===a.nodeName&&a.rel&&a.rel.match(/\/i)){a._bmr&&a._bmr.res&&a._bmr.end[a._bmr.res]&&(m=!0);g=a.src||a.getAttribute("xlink:href")||a.href;if("IMG"===a.nodeName){if(a.naturalWidth&&!m)return!1;if(""===a.getAttribute("src"))return!1}if(!g||g.match(/^(about:|javascript:|data:)/i))return!1;c=this.pending_events[b];if(!c)return!1;h=c.resources.length;a._bmr||(a._bmr={end:{}});c.urls||(c.urls={});if(c.urls[g])return!1;if("SCRIPT"===a.nodeName&&n)return!1;if(!c.resource.url){k.href=g;if(l.excludeFilter(k)){BOOMR.debug("Exclude for "+k.href+" matched. Excluding","AutoXHR");return!1}c.resource.url=k.href}a._bmr.res=h;a._bmr.idx=b;a.addEventListener("load",function(a){i.load_cb(a,h)});a.addEventListener("error",function(a){i.load_cb(a,h)});c.nodes_to_wait++;c.resources.push(a);c.urls[g]=1;j=!0}else a.nodeType===Node.ELEMENT_NODE&&["IMAGE","IMG"].forEach(function(c){d=a.getElementsByTagName(c);if(d&&d.length)for(e=0,f=d.length;e0)for(e=0;e50){BOOMR.utils.removeCookie(this.cookie);BOOMR.error("took more than 50ms to set cookie... aborting: "+e+" -> "+d,"rt")}return!0},initFromCookie:function(){var a,c;c=BOOMR.utils.getSubCookies(BOOMR.utils.getCookie(this.cookie));if(c){c.s=Math.max(+c.ld||0,Math.max(+c.ul||0,+c.cl||0));BOOMR.debug("Read from cookie "+BOOMR.utils.objectToString(c),"rt");if(c.s&&(c.r||c.nu)){this.r=c.r;a=BOOMR.utils.hashQueryString(b.URL,!0);BOOMR.debug(this.r+" =?= "+this.r2,"rt");BOOMR.debug(c.s+" c.s&&(this.t_fb_approx=parseInt(c.hd,10))}else this.t_start=this.t_fb_approx=void 0}this.updateCookie({s:void 0,r:void 0,nu:void 0,ul:void 0,cl:void 0,hd:void 0,ld:void 0,rl:void 0})}},getBoomerangTimings:function(){function a(a,b){var c=Math.round(a||0),d=Math.round(b||0);c=0===c?0:c-d;return c||""}var b,d,e,f,g;if(BOOMR.t_start){BOOMR.plugins.RT.startTimer("boomerang",BOOMR.t_start);BOOMR.plugins.RT.endTimer("boomerang",BOOMR.t_end);BOOMR.plugins.RT.endTimer("boomr_fb",BOOMR.t_start);if(BOOMR.t_lstart){BOOMR.plugins.RT.endTimer("boomr_ld",BOOMR.t_lstart);BOOMR.plugins.RT.setTimer("boomr_lat",BOOMR.t_start-BOOMR.t_lstart)}}try{if(window&&"performance"in window&&window.performance&&"function"==typeof window.performance.getEntriesByName){d={"rt.bmr":BOOMR.url};for(e in d)if(d.hasOwnProperty(e)&&d[e]){b=window.performance.getEntriesByName(d[e]);if(!b||0===b.length||!b[0])continue;b=b[0];f=a(b.startTime,0);g=[f,a(b.responseEnd,f),a(b.responseStart,f),a(b.requestStart,f),a(b.connectEnd,f),a(b.secureConnectionStart,f),a(b.connectStart,f),a(b.domainLookupEnd,f),a(b.domainLookupStart,f),a(b.redirectEnd,f),a(b.redirectStart,f)].join(",").replace(/,+$/,"");BOOMR.addVar(e,g);c.addedVars.push(e)}}}catch(h){BOOMR.addError(h,"rt.getBoomerangTimings")}},checkPreRender:function(){if("prerender"!==BOOMR.visibilityState())return!1;BOOMR.plugins.RT.startTimer("t_load",this.navigationStart);BOOMR.plugins.RT.endTimer("t_load");BOOMR.plugins.RT.startTimer("t_prerender",this.navigationStart);BOOMR.plugins.RT.startTimer("t_postrender");return!0},initFromNavTiming:function(){var b,c,d;if(!this.navigationStart){c=BOOMR.getPerformance();c&&c.navigation&&(this.navigationType=c.navigation.type);if(c&&c.timing)b=c.timing;else if(a.chrome&&a.chrome.csi&&a.chrome.csi().startE){b={navigationStart:a.chrome.csi().startE};d="csi"}else if(a.gtbExternal&&a.gtbExternal.startE()){b={navigationStart:a.gtbExternal.startE()};d="gtb"}if(b){BOOMR.addVar("rt.start",d||"navigation");this.navigationStart=b.navigationStart||b.fetchStart||void 0;this.responseStart=b.responseStart||void 0;navigator.userAgent.match(/Firefox\/[78]\./)&&(this.navigationStart=b.unloadEventStart||b.fetchStart||void 0)}else BOOMR.warn("This browser doesn't support the WebTiming API","rt")}},validateLoadTimestamp:function(a,b,c){var d;if(b&&b.timing&&b.timing.loadEventEnd)return b.timing.loadEventEnd;if(!("xhr"!==c||b&&BOOMR.utils.inArray(b.initiator,BOOMR.constants.BEACON_TYPE_SPAS)))return a;if(BOOMR.loadedLate){d=BOOMR.getPerformance();if(!d||!d.timing)return BOOMR.t_onload||BOOMR.t_lstart||BOOMR.t_start||a;if(d.timing.loadEventStart&&d.timing.loadEventStart=f)&&(e=d.timing.responseEnd)}}else c.responseStart?c.responseStart>=c.cached_t_start&&(e=c.responseStart):c.timers.hasOwnProperty("t_page")?BOOMR.plugins.RT.endTimer("t_page"):c.t_fb_approx&&(e=c.t_fb_approx);if(e){f?BOOMR.plugins.RT.setTimer("t_resp",f,e):BOOMR.plugins.RT.endTimer("t_resp",e);"load"===a&&c.timers.t_load?BOOMR.plugins.RT.setTimer("t_page",c.timers.t_load.end-e):bc.oboError&&(c.oboError=a.RT.oboError);if(a.RT.loadTime&&!isNaN(a.RT.loadTime)&&a.RT.loadTime>c.loadTime){c.loadTime=a.RT.loadTime;isNaN(c.timers.t_done.delta)||(c.loadTime+=c.timers.t_done.delta)}}},domloaded:function(){BOOMR.plugins.RT.endTimer("t_domloaded")},clear:function(){BOOMR.removeVar("rt.start");if(c.addedVars&&c.addedVars.length>0){BOOMR.removeVar(c.addedVars);c.addedVars=[]}},spaNavigation:function(){c.onloadfired=!0}};BOOMR.plugins.RT={init:function(d){BOOMR.debug("init RT","rt");a!==BOOMR.window&&(a=BOOMR.window);if(a&&a.document){b=a.document;BOOMR.utils.pluginConfig(c,d,"RT",["cookie","cookie_exp","session_exp","strict_referrer"]);d&&void 0!==d.autorun&&(c.autorun=d.autorun);void 0!==b&&(c.r=c.r2=BOOMR.utils.hashQueryString(b.referrer,!0));c.initFromCookie();if(c.initialized)return this;c.complete=!1;c.timers={};c.check_visibility();BOOMR.subscribe("page_ready",c.page_ready,null,c);BOOMR.subscribe("visibility_changed",c.check_visibility,null,c);BOOMR.subscribe("prerender_to_visible",c.prerenderToVisible,null,c);BOOMR.subscribe("page_ready",this.done,"load",this);BOOMR.subscribe("xhr_load",this.done,"xhr",this);BOOMR.subscribe("dom_loaded",c.domloaded,null,c);BOOMR.subscribe("page_unload",c.page_unload,null,c);BOOMR.subscribe("click",c.onclick,null,c);BOOMR.subscribe("form_submit",c.onsubmit,null,c);BOOMR.subscribe("before_beacon",this.addTimersToBeacon,"beacon",this);BOOMR.subscribe("onbeacon",c.clear,null,c);BOOMR.subscribe("onerror",c.onerror,null,c);BOOMR.subscribe("onconfig",c.onconfig,null,c);BOOMR.subscribe("spa_navigation",c.spaNavigation,null,c);BOOMR.getBeaconURL=function(){return c.beacon_url};c.initialized=!0;return this}},startTimer:function(a,b){if(a){"t_page"===a&&this.endTimer("t_resp",b);c.timers[a]={start:"number"==typeof b?b:BOOMR.now()}}return this},endTimer:function(a,b){if(a){c.timers[a]=c.timers[a]||{};void 0===c.timers[a].end&&(c.timers[a].end="number"==typeof b?b:BOOMR.now())}return this},clearTimer:function(a){a&&delete c.timers[a];return this},setTimer:function(a,b,d){a&&(c.timers[a]=void 0!==d?{start:b,end:d,delta:d-b}:{delta:b});return this},addTimersToBeacon:function(a,b){var d,e,f=[];for(d in c.timers)if(c.timers.hasOwnProperty(d)){e=c.timers[d];if("number"!=typeof e.delta){"number"!=typeof e.start&&(e.start="xhr"===b?c.cached_xhr_start:c.cached_t_start);e.delta=e.end-e.start}if(isNaN(e.delta))continue;if(c.basic_timers.hasOwnProperty(d)){BOOMR.addVar(d,e.delta);c.addedVars.push(d)}else f.push(d+"|"+e.delta)}if(f.length){BOOMR.addVar("t_other",f.join(","));c.addedVars.push("t_other")}if("beacon"===b){c.timers={};c.complete=!1}},done:function(a,b){BOOMR.debug("Called done: "+b,"rt");var d,e,f=BOOMR.now(),g=!1;c.complete=!1;e=c.validateLoadTimestamp(f,a,b);if(("load"===b||"visible"===b||"xhr"===b)&&!c.setPageLoadTimers(b,e,a))return this;("load"===b||"visible"===b||"xhr"===b&&a&&"spa_hard"===a.initiator)&&c.getBoomerangTimings();d=c.determineTStart(b,a);this.endTimer("t_done",e);a&&"xhr"===a.initiator&&this.setTimer("t_done",a.timing.requestStart,a.timing.loadEventEnd);BOOMR.removeVar("t_done","t_page","t_resp","t_postrender","t_prerender","t_load","t_other","rt.tstart","rt.nstart","rt.cstart","rt.bstart","rt.end","rt.subres","rt.abld","http.errno","http.method","xhr.sync");c.setSupportingTimestamps(d);this.addTimersToBeacon(null,b);BOOMR.setReferrer(c.r,c.r2);"xhr"===b&&a&&a&&a.data&&(a=a.data);if("xhr"===b&&a){g=a.subresource;if(a.url){BOOMR.addVar("u",BOOMR.utils.cleanupURL(a.url.replace(/#.*/,"")));c.addedVars.push("u")}a.status&&(a.status<-1||a.status>=400)&&BOOMR.addVar("http.errno",a.status);a.method&&"GET"!==a.method&&BOOMR.addVar("http.method",a.method);a.headers&&BOOMR.addVar("http.hdr",a.headers);a.synchronous&&BOOMR.addVar("xhr.sync",1);a.initiator&&BOOMR.addVar("http.initiator",a.initiator);c.addedVars.push("http.errno","http.method","http.hdr","xhr.sync","http.initiator")}if(g&&"passive"!==g){BOOMR.addVar("rt.subres",1);c.addedVars.push("rt.subres")}c.updateCookie();if("unload"===b){BOOMR.addVar("rt.quit","");c.onloadfired||BOOMR.addVar("rt.abld","");c.visiblefired||BOOMR.addVar("rt.ntvu","")}c.complete=!0;BOOMR.sendBeacon(c.beacon_url);return this},is_complete:function(){return c.complete},updateCookie:function(){c.updateCookie()},navigationStart:function(){c.navigationStart||c.initFromNavTiming();return c.navigationStart}}}}(window);!function(){var a,b;if(!BOOMR.plugins.BW){b=[{name:"image-0.png",size:11773,timeout:1400},{name:"image-1.png",size:40836,timeout:1200},{name:"image-2.png",size:165544,timeout:1300},{name:"image-3.png",size:382946,timeout:1500},{name:"image-4.png",size:1236278,timeout:1200},{name:"image-5.png",size:4511798,timeout:1200},{name:"image-6.png",size:9092136,timeout:1200}];b.end=b.length;b.start=0;b.l={name:"image-l.gif",size:35,timeout:1e3};a={base_url:"",timeout:15e3,nruns:5,latency_runs:10,user_ip:"",block_beacon:!1,test_https:!1,cookie_exp:604800,cookie:"BA",results:[],latencies:[],latency:null,runs_left:0,aborted:!1,complete:!0,running:!1,initialized:!1,ncmp:function(a,b){return a-b},iqr:function(a){var b,c,d,e,f=a.length-1,g=[];b=(a[Math.floor(.25*f)]+a[Math.ceil(.25*f)])/2;c=(a[Math.floor(.75*f)]+a[Math.ceil(.75*f)])/2;d=1.5*(c-b);if(0===d)return a;f++;for(e=0;eb-d&&g.push(a[e]);return g},calc_latency:function(){var a,b,c,d,e,f,g,h=0,i=0;this.latencies.shift();g=this.iqr(this.latencies.sort(this.ncmp));b=g.length;BOOMR.debug("latencies: "+this.latencies,"bw");BOOMR.debug("lat_filtered: "+g,"bw");for(a=0;a=0&&m<3&&d[c];c--)if(null!==d[c].t){p++;m++;n=1e3*b[c].size/d[c].t;q.push(n);if(d[c].t>this.latency.mean){o=1e3*b[c].size/(d[c].t-this.latency.mean);r.push(o)}else w.push(c+"_"+d[c].t)}}BOOMR.debug("got "+p+" readings","bw");BOOMR.debug("bandwidths: "+q,"bw");BOOMR.debug("corrected: "+r,"bw");if(q.length>3){q=this.iqr(q.sort(this.ncmp));r=this.iqr(r.sort(this.ncmp))}else{q=q.sort(this.ncmp);r=r.sort(this.ncmp)}BOOMR.debug("after iqr: "+q,"bw");BOOMR.debug("corrected: "+r,"bw");p=Math.max(q.length,r.length);for(a=0;a=b.end-1||void 0!==this.results[this.nruns-d].r[a+1]){BOOMR.debug(BOOMR.utils.objectToString(this.results[this.nruns-d],void 0,2),"bw");d===this.nruns&&(b.start=a);BOOMR.setImmediate(this.iterate,null,null,this)}else this.load_img(a+1,d,this.img_loaded)}else this.results[this.nruns-d].r[a+1]={t:null,state:null,run:d}},finish:function(){this.latency||(this.latency=this.calc_latency());var a=this.calc_bw(),b={bw:a.median_corrected,bw_err:parseFloat(a.stderr_corrected,10),lat:this.latency.mean,lat_err:parseFloat(this.latency.stderr,10),bw_time:Math.round(BOOMR.now()/1e3)};BOOMR.addVar(b);a.debug_info.length>0&&BOOMR.addVar("bw_debug",a.debug_info.join(","));!isNaN(b.bw)&&b.bw>0&&BOOMR.utils.setCookie(this.cookie,{ba:Math.round(b.bw),be:b.bw_err,l:b.lat,le:b.lat_err,ip:this.user_ip,t:b.bw_time},this.user_ip?this.cookie_exp:0);this.complete=!0;!0===this.block_beacon&&BOOMR.sendBeacon();this.running=!1},iterate:function(){if(!this.aborted)if(this.runs_left)if(this.latency_runs)this.load_img("l",this.latency_runs--,this.lat_loaded);else{this.results.push({r:[]});this.load_img(b.start,this.runs_left--,this.img_loaded)}else this.finish()},setVarsFromCookie:function(){var b,c,d,e,f,g,h,i,j;b=BOOMR.utils.getSubCookies(BOOMR.utils.getCookie(a.cookie));if(b&&b.ba){c=parseInt(b.ba,10);d=parseFloat(b.be,10);e=parseInt(b.l,10)||0;f=parseFloat(b.le,10)||0;g=b.ip.replace(/\.\d+$/,"0");h=parseInt(b.t,10);i=this.user_ip.replace(/\.\d+$/,"0");j=Math.round(BOOMR.now()/1e3);if(g===i&&h>=j-this.cookie_exp&&c>0){this.complete=!0;BOOMR.addVar({bw:c,lat:e,bw_err:d,lat_err:f,bw_time:h});return!0}}return!1}};BOOMR.plugins.BW={init:function(c){if(a.initialized)return this;BOOMR.utils.pluginConfig(a,c,"BW",["base_url","timeout","nruns","cookie","cookie_exp","test_https","block_beacon"]);c&&c.user_ip&&(a.user_ip=c.user_ip);if(!a.base_url)return this;b.start=0;a.runs_left=a.nruns;a.latency_runs=10;a.results=[];a.latencies=[];a.latency=null;a.complete=a.aborted=!1;BOOMR.removeVar("ba","ba_err","lat","lat_err");a.setVarsFromCookie()||BOOMR.subscribe("page_ready",this.run,null,this);a.initialized=!0;return this},run:function(){var b;if(a.running||a.complete)return this;b=BOOMR.window.document.createElement("a");b.href=a.base_url;if(!a.test_https&&"https:"===b.protocol){BOOMR.info("HTTPS detected, skipping bandwidth test","bw");a.complete=!0;!0===a.block_beacon&&BOOMR.sendBeacon();return this}a.base_url=b.href;a.running=!0;setTimeout(this.abort,a.timeout);a.iterate();return this},abort:function(){a.aborted=!0;a.running&&a.finish()},is_complete:function(){return!0!==a.block_beacon||a.complete}}}}();!function(){if(!BOOMR.plugins.NavigationTiming){var a={complete:!1,sendBeacon:function(){this.complete=!0;BOOMR.sendBeacon()},xhr_done:function(b){var c;if(b&&"spa_hard"===b.initiator)a.done(b);else if(b&&"spa"===b.initiator)a.sendBeacon();else{var d,e,f=(BOOMR.window,{});if(b){b.data&&(b=b.data);c=BOOMR.getPerformance();if(c&&b.restiming){f={nt_red_st:b.restiming.redirectStart,nt_red_end:b.restiming.redirectEnd,nt_fet_st:b.restiming.fetchStart,nt_dns_st:b.restiming.domainLookupStart,nt_dns_end:b.restiming.domainLookupEnd,nt_con_st:b.restiming.connectStart,nt_con_end:b.restiming.connectEnd,nt_req_st:b.restiming.requestStart,nt_res_st:b.restiming.responseStart,nt_res_end:b.restiming.responseEnd};b.restiming.secureConnectionStart&&(f.nt_ssl_st=b.restiming.secureConnectionStart);for(e in f)if(f.hasOwnProperty(e)&&f[e]){f[e]+=c.timing.navigationStart;f[e]=Math.floor(f[e])}}if(b.timing){d=b.timing;f.nt_req_st||(f.nt_req_st=d.requestStart);f.nt_res_st||(f.nt_res_st=d.responseStart);f.nt_res_end||(f.nt_res_end=d.responseEnd);f.nt_domint=d.domInteractive;f.nt_domcomp=d.domComplete;f.nt_load_st=d.loadEventEnd;f.nt_load_end=d.loadEventEnd}for(e in f)f.hasOwnProperty(e)&&!f[e]&&delete f[e];BOOMR.addVar(f);try{a.addedVars.push.apply(a.addedVars,Object.keys(f))}catch(g){}a.sendBeacon()}}},done:function(){var b,c,d,e,f=BOOMR.window;if(this.complete)return this;a.addedVars=[];b=BOOMR.getPerformance();if(b&&b.timing&&b.navigation){BOOMR.info("This user agent supports NavigationTiming.","nt");c=b.navigation;d=b.timing;e={nt_red_cnt:c.redirectCount,nt_nav_type:c.type,nt_nav_st:d.navigationStart,nt_red_st:d.redirectStart,nt_red_end:d.redirectEnd,nt_fet_st:d.fetchStart,nt_dns_st:d.domainLookupStart,nt_dns_end:d.domainLookupEnd,nt_con_st:d.connectStart,nt_con_end:d.connectEnd,nt_req_st:d.requestStart,nt_res_st:d.responseStart,nt_res_end:d.responseEnd,nt_domloading:d.domLoading,nt_domint:d.domInteractive,nt_domcontloaded_st:d.domContentLoadedEventStart,nt_domcontloaded_end:d.domContentLoadedEventEnd,nt_domcomp:d.domComplete,nt_load_st:d.loadEventStart,nt_load_end:d.loadEventEnd,nt_unload_st:d.unloadEventStart,nt_unload_end:d.unloadEventEnd};d.secureConnectionStart&&(e.nt_ssl_st=d.secureConnectionStart);d.msFirstPaint&&(e.nt_first_paint=d.msFirstPaint);BOOMR.addVar(e);if(d.requestStart&&d.navigationStart&&d.requestStartBOOMR.now()+864e5){BOOMR.addVar("nt_bad",1);a.addedVars.push("nt_bad")}try{a.addedVars.push.apply(a.addedVars,Object.keys(e))}catch(g){}}if(f.chrome&&f.chrome.loadTimes){d=f.chrome.loadTimes();if(d){e={nt_spdy:d.wasFetchedViaSpdy?1:0,nt_cinf:d.connectionInfo,nt_first_paint:d.firstPaintTime};BOOMR.addVar(e);try{a.addedVars.push.apply(a.addedVars,Object.keys(e))}catch(g){}}}a.sendBeacon()},clear:function(){if(a.addedVars&&a.addedVars.length>0){BOOMR.removeVar(a.addedVars);a.addedVars=[]}this.complete=!1},prerenderToVisible:function(){this.complete=!1;this.done()}};BOOMR.plugins.NavigationTiming={init:function(){if(!a.initialized){BOOMR.subscribe("page_ready",a.done,null,a);BOOMR.subscribe("prerender_to_visible",a.prerenderToVisible,null,a);BOOMR.subscribe("xhr_load",a.xhr_done,null,a);BOOMR.subscribe("before_unload",a.done,null,a);BOOMR.subscribe("onbeacon",a.clear,null,a);a.initialized=!0}return this},is_complete:function(){return!0}}}}();!function(){function a(a){var b,c,d,e,f,g,h,i,j={};for(b in a){c=b;for(d=0;d10)return w;try{if(!d(a))return w;m=e(a);u=h(a,i);v=a.document.createElement("a");Array.prototype.forEach.call(a.document.getElementsByTagName("script"),function(a){v.href=a.src;v.href.match(/^https?:\/\//)&&(x[v.href]=a)});q=a.document.getElementsByTagName("iframe");if(q&&q.length)for(k=0;km&&(p=c+(o-m));v.href=q[k].src;w=w.concat(f(a.frames[k],!1,p,g+1,u[v.href]))}if("function"!=typeof a.performance.getEntriesByType)return w;if(b){l=a.performance.getEntriesByType("navigation");if(l&&1===l.length){r=l[0];w.push({name:a.location.href,startTime:0,initiatorType:"html",redirectStart:r.redirectStart,redirectEnd:r.redirectEnd,fetchStart:r.fetchStart,domainLookupStart:r.domainLookupStart,domainLookupEnd:r.domainLookupEnd,connectStart:r.connectStart,secureConnectionStart:r.secureConnectionStart,connectEnd:r.connectEnd,requestStart:r.requestStart,responseStart:r.responseStart,responseEnd:r.responseEnd,workerStart:r.workerStart,encodedBodySize:r.encodedBodySize,decodedBodySize:r.decodedBodySize,transferSize:r.transferSize,serverTiming:j(r)})}else if(a.performance.timing){s=a.performance.timing;0!==s.navigationStart&&s.responseEnd<=s.navigationStart+36e5&&w.push({name:a.location.href,startTime:0,initiatorType:"html",redirectStart:s.redirectStart?s.redirectStart-s.navigationStart:0,redirectEnd:s.redirectEnd?s.redirectEnd-s.navigationStart:0,fetchStart:s.fetchStart?s.fetchStart-s.navigationStart:0,domainLookupStart:s.domainLookupStart?s.domainLookupStart-s.navigationStart:0,domainLookupEnd:s.domainLookupEnd?s.domainLookupEnd-s.navigationStart:0,connectStart:s.connectStart?s.connectStart-s.navigationStart:0,secureConnectionStart:s.secureConnectionStart?s.secureConnectionStart-s.navigationStart:0,connectEnd:s.connectEnd?s.connectEnd-s.navigationStart:0,requestStart:s.requestStart?s.requestStart-s.navigationStart:0,responseStart:s.responseStart?s.responseStart-s.navigationStart:0,responseEnd:s.responseEnd?s.responseEnd-s.navigationStart:0})}}var y=a.performance.getEntriesByType("resource"),z=[];for(k=0;y&&k-1||g.name.indexOf(BOOMR.config_url)>-1||"function"==typeof BOOMR.getBeaconURL&&BOOMR.getBeaconURL()&&g.name.indexOf(BOOMR.getBeaconURL())>-1||a&&i+g.startTimeb)break;if(void 0===c||"*"===c||!c.length||g.initiatorType&&BOOMR.utils.inArray(g.initiatorType,c)){v(j,g.serverTiming);k.push(g)}}}var l=w(j);return{entries:k,serverTiming:{lookup:l,indexed:x(l)}}}function j(a){var b,c,d,e;if(a.encodedBodySize||a.decodedBodySize||a.transferSize){b=a.transferSize;c=a.encodedBodySize;d=a.decodedBodySize;e=[c,b?b-c:"_",d?d-c:0];return e.map(g).join(",").replace(/,+$/,"")}return""}function k(a,b){var c,d;void 0===b&&(b={});c=a.split(",");for(d=0;d0&&(c[d]+=c[0])}1===c.length&&c.push(c[0]);2===c.length&&c.push(c[0]);b.encodedBodySize=c[0];b.transferSize=c[1];b.decodedBodySize=c[2];return b}function l(a){var b,c,d,e={},f=[0,0,0];b=a.split("!");for(c=0;c=g||h>=i)return a;for(k=h;kh||k>j){l=(f===1/0?"":g(Math.round(f-e)))+"~"+g(i-h)+"~"+g(i-k);l=l.replace(/~~/,"-").replace(/~$/,"");n.push(l);e=f;h=i;j=k}}return n.join("!").replace(/!+$/,"")}function r(d,e){var f,h,k,l,n,o={},p={},q=i(d,e,B.trackedResourceTypes),r=q.entries,s=q.serverTiming;if(!r||!r.length)return{restiming:{},servertiming:[]};for(f=0;f0?",":"")+d+f;return a},""));l=m(h.name,B.trimUrls);void 0!==o[l]?o[l]+="|"+n:h.visibleDimensions?o[l]=F+G+h.visibleDimensions.map(Math.round).map(g).join(",").replace(/,+$/,"")+"|"+n:o[l]=n;if(h.visibleDimensions){p[h.latestTime]||(p[h.latestTime]=[]);p[h.latestTime].push(h.visibleDimensions)}}return{restiming:b(a(o),!0),servertiming:s.lookup}}function s(a){var b=[];if(!a||!a.length)return b;for(var c=0;c1){var g=c[1].split(".");""!==g[0]&&(e=Number(g[0]));g.length>1&&(f=Number(g[1]))}var h,i="";if(Array.isArray(a[e])){h=a[e][0];i=a[e][1+f]||""}else h=a[e];return{name:h,duration:d,description:i}}var B;if(!BOOMR.plugins.ResourceTiming){var C={other:0,img:1,link:2,script:3,css:4,xmlhttprequest:5,html:6,image:7,beacon:8,fetch:9},D=[/(h)(ref)/gi,/(s)(rc)/gi,/(a)(ction)/gi],E="\n",F="*",G="0",H="1",I="2",J=1,K=2,L=4,M="3";B={complete:!1,sentNavBeacon:!1,initialized:!1,supported:!1,xhr_load:function(){if(!this.complete){this.complete=!0;BOOMR.sendBeacon()}},xssBreakWords:D,urlLimit:500,clearOnBeacon:!1,trimUrls:[],trackedResourceTypes:"*",serverTiming:!0,done:function(){if(!this.sentNavBeacon){u();this.complete=!0;this.sentNavBeacon=!0;BOOMR.sendBeacon()}},onBeacon:function(a){var b=BOOMR.getPerformance();a.hasOwnProperty("restiming")&&BOOMR.removeVar("restiming");a.hasOwnProperty("servertiming")&&BOOMR.removeVar("servertiming");if(B.clearOnBeacon&&b){var c=b.clearResourceTimings||b.webkitClearResourceTimings;c&&"function"==typeof c&&c.call(b)}},prerenderToVisible:function(){this.sentNavBeacon=!1;this.done()}};BOOMR.plugins.ResourceTiming={init:function(a){var b=BOOMR.getPerformance();BOOMR.utils.pluginConfig(B,a,"ResourceTiming",["xssBreakWords","clearOnBeacon","urlLimit","trimUrls","trackedResourceTypes","serverTiming"]);if(B.initialized)return this;if(b&&"function"==typeof b.getEntriesByType){BOOMR.subscribe("page_ready",B.done,null,B);BOOMR.subscribe("prerender_to_visible",B.prerenderToVisible,null,B);BOOMR.subscribe("xhr_load",B.xhr_load,null,B);BOOMR.subscribe("onbeacon",B.onBeacon,null,B);BOOMR.subscribe("before_unload",B.done,null,B);B.supported=!0}else B.complete=!0;B.initialized=!0;return this},is_complete:function(){return!0},is_supported:function(){return B.initialized&&B.supported},getCompressedResourceTiming:r,getFilteredResourceTiming:i,calculateResourceTimingUnion:t,addResourceTimingToBeacon:u,addToBeacon:z,trimTiming:c,convertToTrie:a,optimizeTrie:b,findPerformanceEntriesForFrame:f,toBase36:g,getVisibleEntries:h,reduceFetchStarts:s,compressSize:j,decompressSize:k,trimUrl:m,getResourceLatestTime:n,mergePixels:o,countPixels:p,getOptimizedTimepoints:q,decompressTimePoints:l,accumulateServerTimingEntries:v,compressServerTiming:w,indexServerTiming:x,identifyServerTimingEntry:y,decompressServerTiming:A,SPECIAL_DATA_PREFIX:F,SPECIAL_DATA_DIMENSION_TYPE:G,SPECIAL_DATA_SIZE_TYPE:H,SPECIAL_DATA_SCRIPT_ATTR_TYPE:I,ASYNC_ATTR:J,DEFER_ATTR:K,LOCAT_ATTR:L}}}();!function(){BOOMR=window.BOOMR||{};var a={connection:null,param_map:{type:"ct",bandwidth:"bw",metered:"mt",effectiveType:"etype",downlinkMax:"lm",downlink:"dl",rtt:"rtt",saveData:"sd"},getConnection:function(){if(this.connection)return this.connection;"object"==typeof navigator&&(this.connection=navigator.connection||navigator.mozConnection||navigator.webkitConnection||navigator.msConnection);return this.connection},subscribe:function(){var b=this.getConnection();b.addEventListener&&b.addEventListener("change",function(){a.setConnectionInformation();BOOMR.fireEvent("netinfo",b)})},setConnectionInformation:function(){var a,b,c,d=this.param_map;b=this.getConnection();for(a in d)if(a in b){BOOMR.removeVar("mob."+d[a]);c=typeof b[a];"number"!==c&&"string"!==c&&"boolean"!==c||BOOMR.addVar("mob."+d[a],b[a])}}};BOOMR.plugins.Mobile={init:function(){if(a.getConnection()){a.setConnectionInformation();a.subscribe()}return this},is_complete:function(){return!0}}}();!function(){function a(a,b){var c,e,f,g,h;try{c=d.getElementsByTagName(a);e=c.length;if(b&&b.length){f={};f[b[0]]=e;for(g=2;e>0&&g1&&BOOMR.addVar("scr.dpx",c.devicePixelRatio);if(c.scrollX||c.scrollY){a="function"==typeof c.scrollX?c.scrollX():c.scrollX;b="function"==typeof c.scrollY?c.scrollY():c.scrollY;"number"==typeof a&&"number"==typeof b&&BOOMR.addVar("scr.sxy",a+"x"+b)}},"screen");b(g,function(){g.hardwareConcurrency&&BOOMR.addVar("cpu.cnc",g.hardwareConcurrency);g.maxTouchPoints&&BOOMR.addVar("scr.mtp",g.maxTouchPoints)},"navigator");b(h,function(){BOOMR.addVar("bat.lvl",h.level)},"battery");b(!0,function(){var b;BOOMR.addVar({"dom.ln":a("*"),"dom.sz":d.documentElement.innerHTML.length});b={};BOOMR.addVar(a("img",["dom.img","dom.img.ext","dom.img.uniq"],function(a){return a.src&&!a.src.toLowerCase().match(/^(?:about:|javascript:|data:|#)/)},function(a){return!(b[a.src]=b.hasOwnProperty(a.src))}));b={};BOOMR.addVar(a("script",["dom.script","dom.script.ext","dom.script.uniq"],function(a){return a.src&&!a.src.toLowerCase().match(/^(?:about:|javascript:|#)/)},function(a){return!(b[a.src]=b.hasOwnProperty(a.src))}));b={};BOOMR.addVar(a("iframe",["dom.iframe","dom.iframe.ext","dom.iframe.uniq"],function(a){return a.src&&!a.src.toLowerCase().match(/^(?:about:|javascript:|#)/)},function(a){return!(b[a.src]=b.hasOwnProperty(a.src))}));b={};BOOMR.addVar(a("link",["dom.link","dom.link.css","dom.link.css.uniq"],function(a){return a.rel&&"stylesheet"===a.rel.toLowerCase()&&a.href&&!a.href.toLowerCase().match(/^(?:about:|javascript:|#)/)},function(a){return!(b[a.href]=b.hasOwnProperty(a.href))}))},"dom")}}};BOOMR.plugins.Memory={init:function(){var a;try{c=BOOMR.window;d=c.document;j=BOOMR.getPerformance();a=c.console;f=c.screen;g=c.navigator;if(g&&g.battery)h=g.battery;else if(g&&"function"==typeof g.getBattery){var b=g.getBattery();b&&"function"==typeof b.then?b.then(function(a){h=a}):"object"==typeof b&&b.hasOwnProperty("level")&&(h=b)}}catch(k){BOOMR.addError(k,"Memory.init")}e=j&&j.memory?j.memory:a&&a.memory?a.memory:null;if(i.initialized)return this;i.initialized=!0;BOOMR.subscribe("before_beacon",i.done,null,i);return this},is_complete:function(){return!0}}}}();!function(){if(!BOOMR.plugins.CACHE_RELOAD){var a={url:""};BOOMR.plugins.CACHE_RELOAD={init:function(b){BOOMR.utils.pluginConfig(a,b,"CACHE_RELOAD",["url"]);if(!a.url)return this;var c=document.createElement("iframe");c.style.display="none";c.src=a.url;document.body.appendChild(c);return this},is_complete:function(){return!0}}}}();!function(){"use strict";function a(a,b){var c=(65535&a)+(65535&b);return(a>>16)+(b>>16)+(c>>16)<<16|65535&c}function b(a,b){return a<>>32-b}function c(c,d,e,f,g,h){return a(b(a(a(d,c),a(f,h)),g),e)}function d(a,b,d,e,f,g,h){return c(b&d|~b&e,a,b,f,g,h)}function e(a,b,d,e,f,g,h){return c(b&e|d&~e,a,b,f,g,h)}function f(a,b,d,e,f,g,h){return c(b^d^e,a,b,f,g,h)}function g(a,b,d,e,f,g,h){return c(d^(b|~e),a,b,f,g,h)}function h(b,c){b[c>>5]|=128<>>9<<4)]=c;var h,i,j,k,l,m=1732584193,n=-271733879,o=-1732584194,p=271733878;for(h=0;h>5]>>>b%32&255);return c}function j(a){var b,c=[];c[(a.length>>2)-1]=void 0;for(b=0;b>5]|=(255&a.charCodeAt(b/8))<16&&(e=h(e,8*a.length));for(c=0;c<16;c+=1){f[c]=909522486^e[c];g[c]=1549556828^e[c]}d=h(f.concat(j(b)),512+8*b.length);return i(h(g.concat(d),640))}function m(a){var b,c,d="0123456789abcdef",e="";for(c=0;c>>4&15)+d.charAt(15&b)}return e}function n(a){return unescape(encodeURIComponent(a))}function o(a){return k(n(a))}function p(a){return m(o(a))}function q(a,b){return l(n(a),n(b))}function r(a,b){return m(q(a,b))}function s(a,b,c){return b?c?q(b,a):r(b,a):c?o(a):p(a)}if(!BOOMR.utils||!BOOMR.utils.md5){BOOMR.utils=BOOMR.utils||{};BOOMR.utils.MD5=s}}();!function(){if(!BOOMR.utils||!BOOMR.utils.Compression){var a=BOOMR.utils.Compression={};a.jsUrl=function(b){function c(a){if(!/[^\w-.]/.test(a))return a;a=a.replace(/[^\w-.]/g,function(a){if("$"===a)return"!";a=a.charCodeAt(0);return a<256?"*"+("00"+a.toString(16)).slice(-2):"**"+("0000"+a.toString(16)).slice(-4)});return a}var d=[];switch(typeof b){case"number":return isFinite(b)?"~"+b:"~null";case"string":return"~'"+c(b);case"boolean":return"~"+b;case"object":if(!b)return"~null";if(BOOMR.utils.isArray(b)){for(var e=0;e-1&&(a=a.replace(/eval code/g,"eval").replace(/(\(eval at [^\()]*)|(\)\,.*$)/g,""));var b=a.replace(/^\s+/,"").replace(/\(eval code/g,"(").split(/\s+/).slice(1),c=this.extractLocation(b.pop());return{functionName:b.join(" ")||void 0,fileName:"eval"===c[0]?void 0:c[0],lineNumber:c[1],columnNumber:c[2],source:a}},this)},parseFFOrSafari:function(c){return a(b(c.stack.split("\n"),function(a){return!a.match(e)},this),function(a){a.indexOf(" > eval")>-1&&(a=a.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g,":$1"));if(-1===a.indexOf("@")&&-1===a.indexOf(":"))return{functionName:a};var b=a.split("@"),c=this.extractLocation(b.pop());return{functionName:b.join("@")||void 0,fileName:c[0],lineNumber:c[1],columnNumber:c[2],source:a}},this)},parseOpera:function(a){return!a.stacktrace||a.message.indexOf("\n")>-1&&a.message.split("\n").length>a.stacktrace.split("\n").length?this.parseOpera9(a):a.stack?this.parseOpera11(a):this.parseOpera10(a)},parseOpera9:function(a){for(var b=/Line (\d+).*script (?:in )?(\S+)/i,c=a.message.split("\n"),d=[],e=2,f=c.length;e/,"$2").replace(/\([^\)]*\)/g,"")||void 0;e.match(/\(([^\)]*)\)/)&&(b=e.replace(/^[^\(]+\(([^\)]*)\)$/,"$1"));return{functionName:f,args:void 0===b||"[arguments not available]"===b?void 0:b.split(","),fileName:d[0],lineNumber:d[1],columnNumber:d[2],source:a}},this)}}});!function(){function a(a){a=a||{};"number"==typeof a.count||"string"==typeof a.count?this.count=parseInt(a.count,10):this.count=1;"number"==typeof a.timestamp?this.timestamp=a.timestamp:this.timestamp=BOOMR.now();"number"!=typeof a.code&&"string"!=typeof a.code||(this.code=parseInt(a.code,10));"string"==typeof a.message&&(this.message=a.message);"string"==typeof a.functionName&&(this.functionName=a.functionName);"string"==typeof a.fileName&&(this.fileName=a.fileName);"number"!=typeof a.lineNumber&&"string"!=typeof a.lineNumber||(this.lineNumber=parseInt(a.lineNumber,10));"number"!=typeof a.columnNumber&&"string"!=typeof a.columnNumber||(this.columnNumber=parseInt(a.columnNumber,10));"string"==typeof a.stack&&(this.stack=a.stack);"string"==typeof a.type&&(this.type=a.type);void 0!==a.extra&&(this.extra=a.extra);this.source="number"==typeof a.source||"string"==typeof a.source?parseInt(a.source,10):BOOMR.plugins.Errors.SOURCE_APP;"number"!=typeof a.via&&"string"!=typeof a.via||(this.via=parseInt(a.via,10));BOOMR.utils.isArray(a.frames)?this.frames=a.frames:this.frames=[];BOOMR.utils.isArray(a.events)?this.events=a.events:this.events=[]}var b;if(!BOOMR.plugins.Errors){var c=["BOOMR_addError","createStackForSend","BOOMR.window.console.error","BOOMR.plugins.Errors.init","BOOMR.window.onerror","BOOMR_plugins_errors_"],d=5e3;a.prototype.equals=function(a){return"object"==typeof a&&(this.code===a.code&&(this.message===a.message&&(this.functionName===a.functionName&&(this.fileName===a.fileName&&(this.lineNumber===a.lineNumber&&(this.columnNumber===a.columnNumber&&(this.stack===a.stack&&(this.type===a.type&&this.source===a.source))))))))};a.fromError=function(b,e,f){var g,h,i,j,k=!1,l=BOOMR.now();if(!b)return null;if(b.stack){b.stack.length>d&&(b.stack=b.stack.substr(0,d));h=ErrorStackParser.parse(b);if(h&&h.length){if(b.generatedStack){if(h.length>=4&&h[1].functionName&&-1!==h[1].functionName.indexOf("createStackForSend")){h=h.slice(3);k=!0}if(h.length>=3&&h[0].functionName&&-1!==h[0].functionName.indexOf("createStackForSend")){h=h[1].fileName===h[2].fileName?h.slice(3):h.slice(2);k=!0}if(h.length>=1&&h[0].functionName&&-1!==h[0].functionName.indexOf("BOOMR_plugins_errors")){h=h.slice(1);k=!0}}for(i=0;i=b.maxErrors)){g=a.fromError(c,d,e);h=b.mergeDuplicateErrors(b.errors,g,!1);BOOMR.fireEvent("onerror",h||g);b.mergeDuplicateErrors(b.q,g,!0);if(!b.isDuringLoad&&-1===b.sendIntervalId){if(h)return;b.sendIntervalId=setTimeout(function(){b.sendIntervalId=-1;BOOMR.addVar("http.initiator","error");BOOMR.addVar("api",1);b.addErrorsToBeacon();BOOMR.sendBeacon()},b.sendInterval)}}}},findDuplicateError:function(a,b){if(BOOMR.utils.isArray(a)&&void 0!==b)for(var c=0;c1?arguments[1]:BOOMR.window;var d=Array.prototype.slice.call(arguments,2);return b.wrap(a,c).apply(c,d)}}},normalizeToString:function(a){return void 0===a?"undefined":null===a?"null":"number"==typeof a&&isNaN(a)?"NaN":""===a?"(empty string)":0===a?"0":a?"function"==typeof a?"(function)":a&&"function"==typeof a.toString?a.toString():"(unknown)":"false"},compressErrors:function(a){var b,c,d,e,f,g,h,i,j,k=0;i=BOOMR.window.location.origin;for(b=0;b0&&(g.clientid=f[0].get("clientId"))}}catch(j){BOOMR.addError(j,"TPAnalytics googleAnalytics")}if(!g.clientid){e=BOOMR.utils.getCookie("_ga");if(e){e=e.split(".");e&&4===e.length&&(g.clientid=e[2]+"."+e[3])}else{e=BOOMR.utils.getCookie("__utma");if(e){e=e.split(".");e&&6===e.length&&(g.clientid=e[1]+"."+e[2])}}}}for(b=0;b0?f[1]:""}else b=BOOMR.utils.getCookie("s_fid");b&&(g.aid=b)}}if("object"==typeof h.s){"string"==typeof h.s.campaign&&h.s.campaign&&(g.campaign=h.s.campaign);"string"==typeof h.s.purchaseID&&h.s.purchaseID&&(g.purchaseid=h.s.purchaseID)}}return g},ibmAnalytics:function(){var b,c,d,e,f,g,h={},i=BOOMR.window,j={cm_mmc:[/([^&#]+?)-_-([^&#]+?)-_-([^&#]+?)-_-([^&#]+)/,["mmc_vendor","mmc_category","mmc_placement","mmc_item"]],cm_sp:[/([^&#]+?)-_-([^&#]+?)-_-([^&#]+)/,["sp_type","sp_promotion","sp_link"]],cm_re:[/([^&#]+?)-_-([^&#]+?)-_-([^&#]+)/,["re_version","re_pagearea","re_link"]]};if(a.clientids&&"function"==typeof i.cmRetrieveUserID)try{i.cmRetrieveUserID(function(a){h.coreid=a})}catch(k){BOOMR.addError(k,"TPAnalytics ibmAnalytics")}for(e in j)if(j.hasOwnProperty(e)){b=BOOMR.utils.getQueryParamValue(e);if(b){f=j[e][0];g=j[e][1];c=f.exec(b);if(c&&c.length>g.length)for(d=0;d0&&BOOMR.sendBeacon()},onBeacon:function(){if(this.addedVars&&this.addedVars.length>0){BOOMR.removeVar(this.addedVars);this.addedVars=[]}}};BOOMR.plugins.TPAnalytics={init:function(b){BOOMR.utils.pluginConfig(a,b,"TPAnalytics",["clientids","dropParams"]);if(!a.initialized){BOOMR.utils.isArray(a.dropParams)||(a.dropParams=[]);BOOMR.subscribe("page_ready",a.pageReady,null,a);BOOMR.subscribe("onbeacon",a.onBeacon,null,a);BOOMR.subscribe("prerender_to_visible",a.pageReady,null,a);a.initialized=!0}return this},is_complete:function(){return!0}}}}();!function(){if(!BOOMR.plugins.UserTiming){var a={complete:!1,initialized:!1,supported:!1,options:{from:0,window:BOOMR.window},now:function(){var a,b,c=BOOMR.getPerformance();if(c&&c.now)a=c.now();else{b=BOOMR.plugins.RT&&BOOMR.plugins.RT.navigationStart?BOOMR.plugins.RT.navigationStart():BOOMR.t_lstart||BOOMR.t_start;a=BOOMR.now()-b}return a},getUserTiming:function(){var b,c,d=this.now(),e=window.UserTimingCompression||BOOMR.window.UserTimingCompression;b=e.getCompressedUserTiming(a.options);c=e.compressForUri(b);this.options.from=d;return c},addEntriesToBeacon:function(){var a;if(!this.complete){BOOMR.removeVar("usertiming");a=this.getUserTiming();a&&BOOMR.addVar({usertiming:a});this.complete=!0}},clearMetrics:function(a){a.hasOwnProperty("usertiming")&&BOOMR.removeVar("usertiming");this.complete=!1},subscribe:function(){BOOMR.subscribe("before_beacon",this.addEntriesToBeacon,null,this);BOOMR.subscribe("onbeacon",this.clearMetrics,null,this)},pageReady:function(){this.checkSupport()&&this.subscribe()},checkSupport:function(){if(this.supported)return!0;if(void 0===(window.UserTimingCompression||BOOMR.window.UserTimingCompression)){BOOMR.warn("UserTimingCompression library not found","usertiming");return!1}var a=BOOMR.getPerformance();if(a&&"function"==typeof a.getEntriesByType){var b=a.getEntriesByType("mark"),c=a.getEntriesByType("measure");if(BOOMR.utils.isArray(b)&&BOOMR.utils.isArray(c)){BOOMR.info("Client supports User Timing API","usertiming");this.supported=!0;return!0}}return!1}};BOOMR.plugins.UserTiming={init:function(b){if(a.initialized)return this;a.checkSupport()?a.subscribe():BOOMR.subscribe("page_ready",a.pageReady,null,a);a.initialized=!0;return this},is_complete:function(){return!0},is_supported:function(){return a.initialized&&a.supported}}}}();!function(){function a(a,b,c){var d=a.shift();if("string"==typeof d){var e=d.split("."),f=BOOMR,g=BOOMR;"BOOMR"===e[0]&&e.shift();for(;e.length&&f&&("object"==typeof f||"function"==typeof f);){var h=e.shift();f=f[h];e.length&&(g=g[h])}if(!e.length&&"function"==typeof f){var i=f.apply(g,a);"function"==typeof b&&b.call(c,i)}}}function b(b){for(var c=0;c")}for(c=0;c0&&null!==a[d]&&"object"==typeof a[d]?e.push(this.objectToString(a[d],b+("\n\t"===b?"\t":""),c-1)):"&"===b?e.push(encodeURIComponent(a[d])):e.push(a[d]);b=","}else for(d in a)Object.prototype.hasOwnProperty.call(a,d)&&(c>0&&null!==a[d]&&"object"==typeof a[d]?e.push(encodeURIComponent(d)+"="+this.objectToString(a[d],b+("\n\t"===b?"\t":""),c-1)):"&"===b?e.push(encodeURIComponent(d)+"="+encodeURIComponent(a[d])):e.push(d+"="+a[d]));return e.join(b)},getCookie:function(a){if(!a)return null;a=" "+a+"=";var b,c;c=" "+d.cookie+";";if((b=c.indexOf(a))>=0){b+=a.length;c=c.substring(b,c.indexOf(";",b)).replace(/^"/,"").replace(/"$/,"");return c}},setCookie:function(a,c,e){var f,g,h,i,j;if(!a||!b.site_domain){BOOMR.debug("No cookie name or site domain: "+a+"/"+b.site_domain);return!1}f=this.objectToString(c,"&");g=a+'="'+f+'"';i=[g,"path=/","domain="+b.site_domain];if(e){j=new Date;j.setTime(j.getTime()+1e3*e);j=j.toGMTString();i.push("expires="+j)}if(g.length<500){d.cookie=i.join("; ");h=this.getCookie(a);if(f===h)return!0;BOOMR.warn("Saved cookie value doesn't match what we tried to set:\n"+f+"\n"+h)}else BOOMR.warn("Cookie too long: "+g.length+" "+g);return!1},getSubCookies:function(a){var b,c,d,e,f=!1,g={};if(!a)return null;if("string"!=typeof a){BOOMR.debug("TypeError: cookie is not a string: "+typeof a);return null}b=a.split("&");for(c=0,d=b.length;cc){var d=a.indexOf("?");a=-1!==d&&d10?BOOMR.utils.MD5(b):b)}):a},pluginConfig:function(a,b,c,d){var e,f=0;if(!b||!b[c])return!1;for(e=0;e0},arrayFilter:function(a,b){var c=[];if("function"==typeof a.filter)c=a.filter(b);else for(var d,e=-1,f=a.length;++e0&&(h.timer=setTimeout(g,b))}var h={observer:null,timer:null};if(!(BOOMR.window&&BOOMR.window.MutationObserver&&d&&a))return null;h.observer=new BOOMR.window.MutationObserver(g);c&&(h.timer=setTimeout(g,h.timeout));h.observer.observe(a,b);return h},addListener:function(a,c,d){a.addEventListener?a.addEventListener(c,d,!1):a.attachEvent&&a.attachEvent("on"+c,d);b.listenerCallbacks[c]=b.listenerCallbacks[c]||[];b.listenerCallbacks[c].push({el:a,fn:d})},removeListener:function(a,c,d){var e;a.removeEventListener?a.removeEventListener(c,d,!1):a.detachEvent&&a.detachEvent("on"+c,d);if(b.listenerCallbacks.hasOwnProperty(c))for(var e=0;e1?" (*"+b.errors[c]+")":""));i.length>0&&(b.vars.errors=i.join("\n"));b.errors={};b.fireEvent("before_beacon",b.vars);b.beacon_url=b.beacon_url_override||b.beacon_url;BOOMR.debug("Ready to send beacon: "+BOOMR.utils.objectToString(b.vars));if(!b.beacon_url){BOOMR.debug("No beacon URL, so skipping.");return!0}for(c in b.vars)if(b.vars.hasOwnProperty(c)){l[c]=b.vars[c];m[c]=b.vars[c]}n=this.getVarsOfPriority(m,-1);o=this.getVarsOfPriority(m,1);j=n.concat(this.getVarsOfPriority(m,0),o);g=j.join("&");e=b.beacon_url+(b.beacon_url.indexOf("?")>-1?"&":"?")+g;("POST"===b.beacon_type||e.length>BOOMR.constants.MAX_GET_LENGTH)&&(k=!1);BOOMR.removeVar("qt");b.fireEvent("onbeacon",l);if(!b.hasSentPageLoadBeacon&&q){b.hasSentPageLoadBeacon=!0;BOOMR.setImmediate(function(){b.fireEvent("page_load_beacon",l)})}if(0===j.length)return this;BOOMR.orig_XMLHttpRequest||BOOMR.window&&BOOMR.window.XMLHttpRequest||(k=!0);if(k){try{f=new Image}catch(s){BOOMR.debug("Image is not a constructor, not sending a beacon");return!1}f.src=e;if(b.secondary_beacons)for(c=0;c=2)f=!1;else{if(0!==a.responseEnd){d=Math.floor(b+a.responseEnd);if(d<=e.timing.loadEventEnd){e.timing.responseEnd=d;f=!0;e.restiming=a}}if(f){e.timing.requestStart=c;e.timing.fetchStart=c;0!==a.responseStart&&(e.timing.responseStart=Math.floor(b+a.responseStart))}}}e.index>-1?j.load_finished(e.index,e.timing.responseEnd):p?j.sendResource(e):n&&!o||j.addEvent(e)}}function i(b,c){a.addEventListener(b,function(){if("readystatechange"===b){e.timing[q[a.readyState]]=BOOMR.now();if(l.ie1011fix&&m&&4===a.readyState){d.pause();a.responseXML;d.resume()}if(4===a.readyState&&0!==a.status){(a.status<200||a.status>=400)&&(e.status=a.status);e.response={text:""===a.responseType||"text"===a.responseType?a.responseText:null,xml:""===a.responseType||"document"===a.responseType?a.responseXML:null,raw:a.response,json:a.responseJSON};loadFinished()}}else{e.status=void 0===c?a.status:c;loadFinished()}},!1)}k.href=g;if(l.excludeFilter(k)){BOOMR.debug("Exclude found for resource: "+k.href+" Skipping instrumentation!","AutoXHR");return b.apply(a,arguments)}void 0===h&&(h=!0);BOOMR.fireEvent("xhr_init","xhr");if(!f){n&&j.watch&&!p&&j.add_event_resource(e);h&&i("readystatechange");i("load");i("timeout",s);i("error",u);i("abort",t)}e.url=k.href;e.method=c;delete e.status;h||(e.synchronous=!0);f=!0;try{return b.apply(a,arguments)}catch(r){e.status=v;loadFinished()}};a.send=function(b){a.resource.requestPayload=b;BOOMR.fireEvent("xhr_send",a);e.timing.requestStart=BOOMR.now();if(void 0===e.status||e.status!==v)return c.apply(a,arguments)};a.resource=e;return a};BOOMR.proxy_XMLHttpRequest.UNSENT=0;BOOMR.proxy_XMLHttpRequest.OPENED=1;BOOMR.proxy_XMLHttpRequest.HEADERS_RECEIVED=2;BOOMR.proxy_XMLHttpRequest.LOADING=3;BOOMR.proxy_XMLHttpRequest.DONE=4;BOOMR.proxy_XMLHttpRequest.prototype=BOOMR.orig_XMLHttpRequest.prototype;BOOMR.window.XMLHttpRequest=BOOMR.proxy_XMLHttpRequest}}function g(){BOOMR.orig_XMLHttpRequest&&BOOMR.orig_XMLHttpRequest!==BOOMR.window.XMLHttpRequest&&(BOOMR.window.XMLHttpRequest=BOOMR.orig_XMLHttpRequest)}function h(a){a.initiator="xhr";BOOMR.responseEnd(a)}var i,j,k,l,m,n=!1,o=!1,p=!1,q=["uninitialized","open","responseStart","domInteractive","responseEnd"],r=1e3,s=-1001,t=-999,u=-998,v=-997,w=["xmlhttprequest","script"];if(window.XMLHttpRequest&&(new XMLHttpRequest).addEventListener){m=window.navigator&&navigator.appVersion&&-1!==navigator.appVersion.indexOf("MSIE 10")||window.navigator&&navigator.userAgent&&navigator.userAgent.match(/Trident.*rv[ :]*11\./);BOOMR=window.BOOMR||{};if(!BOOMR.plugins.AutoXHR){d.stop=function(){d.pause();d.observer=null};d.pause=function(){if(d.observer&&d.observer.observer&&!d.isPaused){d.isPaused=!0;d.observer.observer.disconnect()}};d.resume=function(){if(d.observer&&d.observer.observer&&d.isPaused){d.isPaused=!1;d.observer.observer.observe(i,d.observer.config)}};d.start=function(){if(!d.observer){var a={childList:!0,attributes:!0,subtree:!0,attributeFilter:["src","href"]};d.observer=BOOMR.utils.addObserver(i,a,null,j.mutation_cb,null,j);if(d.observer){d.observer.config=a;BOOMR.subscribe("page_unload",d.stop,null,d)}}};d.prototype.addEvent=function(a){var b,c,e={type:a.initiator,resource:a,nodes_to_wait:0,resources:[],complete:!1},f=this.pending_events.length;for(b=f-1;b>=0;b--)if(this.pending_events[b]&&!this.pending_events[b].complete){c=this.pending_events[b];break}if(c)if("click"===c.type){if(0===c.nodes_to_wait||!c.resource.url){this.pending_events[b]=void 0;return null}}else if("xhr"===c.type){if("click"===e.type)return null}else if(BOOMR.utils.inArray(c.type,BOOMR.constants.BEACON_TYPE_SPAS)&&"xhr"===e.type)return null;this.watch++;this.pending_events.push(e);if(d.observer){BOOMR.utils.inArray(e.type,BOOMR.constants.BEACON_TYPE_SPAS)?this.setTimeout(r,f):this.setTimeout(50,f);return f}if(BOOMR.utils.inArray(e.type,BOOMR.constants.BEACON_TYPE_SPAS)){d.start();this.setTimeout(r,f);return f}a.url&&a.timing.loadEventEnd&&this.sendEvent(f);return null};d.prototype.sendEvent=function(a){var b=this.pending_events[a],c=this;if(b&&!b.complete){this.clearTimeout();if(BOOMR.readyToSend()){b.complete=!0;this.watch--;b.resource.resources=b.resources;BOOMR.utils.inArray(b.type,BOOMR.constants.BEACON_TYPE_SPAS)&&0===b.resources.length&&(b.resource.timing.loadEventEnd=BOOMR.now()-r);this.sendResource(b.resource,a)}else setTimeout(function(){c.sendEvent(a)},500)}};d.prototype.sendResource=function(a,b){var c=this,d=a.timing?a.timing.requestStart:void 0,e=function(e){e&&(a.timing.loadEventEnd=BOOMR.now());BOOMR.real_sendBeacon();a.onComplete&&a.onComplete(a);if(BOOMR.plugins.ResourceTiming&&BOOMR.plugins.ResourceTiming.is_supported()&&a.timing&&a.timing.requestStart){var f=BOOMR.plugins.ResourceTiming.getCompressedResourceTiming(a.timing.requestStart,a.timing.loadEventEnd);BOOMR.plugins.ResourceTiming.addToBeacon(f)}BOOMR.utils.inArray(a.initiator,BOOMR.constants.BEACON_TYPE_SPAS)&&c.calculateSpaTimings(a);BOOMR.responseEnd(a,d,a);b&&(c.pending_events[b]=void 0)};if(a.wait)a.waitComplete=function(){e(!0)};else{if(BOOMR.utils.inArray(a.initiator,BOOMR.constants.BEACON_TYPE_SPAS)&&i&&i.readyState&&"complete"!==i.readyState){BOOMR.window.addEventListener("load",function(){e(!0)});return}e(!1)}};d.prototype.calculateSpaTimings=function(a){var b=BOOMR.getPerformance();if(b&&b.timing)if("spa_hard"===a.initiator){a.timing.responseEnd=b.timing.responseStart;a.timing.fetchStart=b.timing.navigationStart}else{if(!BOOMR.plugins.ResourceTiming)return;var c=BOOMR.plugins.ResourceTiming.getFilteredResourceTiming(a.timing.requestStart,a.timing.loadEventEnd,l.spaBackEndResources).entries,d=Math.round(a.timing.loadEventEnd-a.timing.requestStart);if(!c||!c.length){BOOMR.plugins.ResourceTiming.is_supported()&&(a.timers={t_resp:0,t_page:d,t_done:d});return}for(var e=a.timing.loadEventEnd-b.timing.navigationStart,f=0;fe){c[f].responseStart=e;c[f].responseEnd=e}else c[f].responseEnd>e&&(c[f].responseEnd=e);var g=Math.round(BOOMR.plugins.ResourceTiming.calculateResourceTimingUnion(c)),h=d-g;if(g<0||d<0||h<0){BOOMR.addError("Incorrect SPA time calculation");return}a.timers={t_resp:g,t_page:h,t_done:d}}};d.prototype.setTimeout=function(a,b){var c=this;if(a){this.clearTimeout();this.timer=setTimeout(function(){c.timedout(b)},a)}};d.prototype.timedout=function(a){var b;this.clearTimeout();b=this.pending_events[a];if(b&&BOOMR.utils.inArray(b.type,BOOMR.constants.BEACON_TYPE_SPAS.concat("xhr")))0===b.nodes_to_wait&&this.sendEvent(a);else{this.watch>0&&this.watch--;this.pending_events[a]=void 0}};d.prototype.clearTimeout=function(){if(this.timer){clearTimeout(this.timer);this.timer=null}};d.prototype.load_cb=function(a,b){var c,d,e=BOOMR.now();c=a.target||a.srcElement;if(c&&c._bmr){d=c._bmr.idx;b=void 0!==b?b:c._bmr.res||0;if(!c._bmr.end[b]){c._bmr.end[b]=e;this.load_finished(d,e)}}};d.prototype.load_finished=function(a,b){var c=this.pending_events[a];if(c){c.nodes_to_wait--;if(0===c.nodes_to_wait){c.resource.timing.loadEventEnd=b||BOOMR.now();BOOMR.utils.inArray(c.type,BOOMR.constants.BEACON_TYPE_SPAS)?this.setTimeout(r,a):this.sendEvent(a)}}};d.prototype.wait_for_node=function(a,b){var c,d,e,f,g,h,i=this,j=!1,m=!1;if(a.nodeName.toUpperCase().match(/^(IMG|SCRIPT|IFRAME|IMAGE)$/)||"LINK"===a.nodeName&&a.rel&&a.rel.match(/\/i)){a._bmr&&a._bmr.res&&a._bmr.end[a._bmr.res]&&(m=!0);g=a.src||a.getAttribute("xlink:href")||a.href;if("IMG"===a.nodeName){if(a.naturalWidth&&!m)return!1;if(""===a.getAttribute("src"))return!1}if(!g||g.match(/^(about:|javascript:|data:)/i))return!1;c=this.pending_events[b];if(!c)return!1;h=c.resources.length;a._bmr||(a._bmr={end:{}});c.urls||(c.urls={});if(c.urls[g])return!1;if("SCRIPT"===a.nodeName&&n)return!1;if(!c.resource.url){k.href=g;if(l.excludeFilter(k)){BOOMR.debug("Exclude for "+k.href+" matched. Excluding","AutoXHR");return!1}c.resource.url=k.href}a._bmr.res=h;a._bmr.idx=b;a.addEventListener("load",function(a){i.load_cb(a,h)});a.addEventListener("error",function(a){i.load_cb(a,h)});c.nodes_to_wait++;c.resources.push(a);c.urls[g]=1;j=!0}else a.nodeType===Node.ELEMENT_NODE&&["IMAGE","IMG"].forEach(function(c){d=a.getElementsByTagName(c);if(d&&d.length)for(e=0,f=d.length;e0)for(e=0;e50){BOOMR.utils.removeCookie(this.cookie);BOOMR.error("took more than 50ms to set cookie... aborting: "+e+" -> "+d,"rt")}return!0},initFromCookie:function(){var a,c;c=BOOMR.utils.getSubCookies(BOOMR.utils.getCookie(this.cookie));if(c){c.s=Math.max(+c.ld||0,Math.max(+c.ul||0,+c.cl||0));BOOMR.debug("Read from cookie "+BOOMR.utils.objectToString(c),"rt");if(c.s&&(c.r||c.nu)){this.r=c.r;a=BOOMR.utils.hashQueryString(b.URL,!0);BOOMR.debug(this.r+" =?= "+this.r2,"rt");BOOMR.debug(c.s+" c.s&&(this.t_fb_approx=parseInt(c.hd,10))}else this.t_start=this.t_fb_approx=void 0}this.updateCookie({s:void 0,r:void 0,nu:void 0,ul:void 0,cl:void 0,hd:void 0,ld:void 0,rl:void 0})}},getBoomerangTimings:function(){function a(a,b){var c=Math.round(a||0),d=Math.round(b||0);c=0===c?0:c-d;return c||""}var b,d,e,f,g;if(BOOMR.t_start){BOOMR.plugins.RT.startTimer("boomerang",BOOMR.t_start);BOOMR.plugins.RT.endTimer("boomerang",BOOMR.t_end);BOOMR.plugins.RT.endTimer("boomr_fb",BOOMR.t_start);if(BOOMR.t_lstart){BOOMR.plugins.RT.endTimer("boomr_ld",BOOMR.t_lstart);BOOMR.plugins.RT.setTimer("boomr_lat",BOOMR.t_start-BOOMR.t_lstart)}}try{if(window&&"performance"in window&&window.performance&&"function"==typeof window.performance.getEntriesByName){d={"rt.bmr":BOOMR.url};for(e in d)if(d.hasOwnProperty(e)&&d[e]){b=window.performance.getEntriesByName(d[e]);if(!b||0===b.length||!b[0])continue;b=b[0];f=a(b.startTime,0);g=[f,a(b.responseEnd,f),a(b.responseStart,f),a(b.requestStart,f),a(b.connectEnd,f),a(b.secureConnectionStart,f),a(b.connectStart,f),a(b.domainLookupEnd,f),a(b.domainLookupStart,f),a(b.redirectEnd,f),a(b.redirectStart,f)].join(",").replace(/,+$/,"");BOOMR.addVar(e,g);c.addedVars.push(e)}}}catch(h){BOOMR.addError(h,"rt.getBoomerangTimings")}},checkPreRender:function(){if("prerender"!==BOOMR.visibilityState())return!1;BOOMR.plugins.RT.startTimer("t_load",this.navigationStart);BOOMR.plugins.RT.endTimer("t_load");BOOMR.plugins.RT.startTimer("t_prerender",this.navigationStart);BOOMR.plugins.RT.startTimer("t_postrender");return!0},initFromNavTiming:function(){var b,c,d;if(!this.navigationStart){c=BOOMR.getPerformance();c&&c.navigation&&(this.navigationType=c.navigation.type);if(c&&c.timing)b=c.timing;else if(a.chrome&&a.chrome.csi&&a.chrome.csi().startE){b={navigationStart:a.chrome.csi().startE};d="csi"}else if(a.gtbExternal&&a.gtbExternal.startE()){b={navigationStart:a.gtbExternal.startE()};d="gtb"}if(b){BOOMR.addVar("rt.start",d||"navigation");this.navigationStart=b.navigationStart||b.fetchStart||void 0;this.responseStart=b.responseStart||void 0;navigator.userAgent.match(/Firefox\/[78]\./)&&(this.navigationStart=b.unloadEventStart||b.fetchStart||void 0)}else BOOMR.warn("This browser doesn't support the WebTiming API","rt")}},validateLoadTimestamp:function(a,b,c){var d;if(b&&b.timing&&b.timing.loadEventEnd)return b.timing.loadEventEnd;if(!("xhr"!==c||b&&BOOMR.utils.inArray(b.initiator,BOOMR.constants.BEACON_TYPE_SPAS)))return a;if(BOOMR.loadedLate){d=BOOMR.getPerformance();if(!d||!d.timing)return BOOMR.t_onload||BOOMR.t_lstart||BOOMR.t_start||a;if(d.timing.loadEventStart&&d.timing.loadEventStart=f)&&(e=d.timing.responseEnd)}}else c.responseStart?c.responseStart>=c.cached_t_start&&(e=c.responseStart):c.timers.hasOwnProperty("t_page")?BOOMR.plugins.RT.endTimer("t_page"):c.t_fb_approx&&(e=c.t_fb_approx);if(e){f?BOOMR.plugins.RT.setTimer("t_resp",f,e):BOOMR.plugins.RT.endTimer("t_resp",e);"load"===a&&c.timers.t_load?BOOMR.plugins.RT.setTimer("t_page",c.timers.t_load.end-e):bc.oboError&&(c.oboError=a.RT.oboError);if(a.RT.loadTime&&!isNaN(a.RT.loadTime)&&a.RT.loadTime>c.loadTime){c.loadTime=a.RT.loadTime;isNaN(c.timers.t_done.delta)||(c.loadTime+=c.timers.t_done.delta)}}},domloaded:function(){BOOMR.plugins.RT.endTimer("t_domloaded")},clear:function(){BOOMR.removeVar("rt.start");if(c.addedVars&&c.addedVars.length>0){BOOMR.removeVar(c.addedVars);c.addedVars=[]}},spaNavigation:function(){c.onloadfired=!0}};BOOMR.plugins.RT={init:function(d){BOOMR.debug("init RT","rt");a!==BOOMR.window&&(a=BOOMR.window);if(a&&a.document){b=a.document;BOOMR.utils.pluginConfig(c,d,"RT",["cookie","cookie_exp","session_exp","strict_referrer"]);d&&void 0!==d.autorun&&(c.autorun=d.autorun);void 0!==b&&(c.r=c.r2=BOOMR.utils.hashQueryString(b.referrer,!0));c.initFromCookie();if(c.initialized)return this;c.complete=!1;c.timers={};c.check_visibility();BOOMR.subscribe("page_ready",c.page_ready,null,c);BOOMR.subscribe("visibility_changed",c.check_visibility,null,c);BOOMR.subscribe("prerender_to_visible",c.prerenderToVisible,null,c);BOOMR.subscribe("page_ready",this.done,"load",this);BOOMR.subscribe("xhr_load",this.done,"xhr",this);BOOMR.subscribe("dom_loaded",c.domloaded,null,c);BOOMR.subscribe("page_unload",c.page_unload,null,c);BOOMR.subscribe("click",c.onclick,null,c);BOOMR.subscribe("form_submit",c.onsubmit,null,c);BOOMR.subscribe("before_beacon",this.addTimersToBeacon,"beacon",this);BOOMR.subscribe("onbeacon",c.clear,null,c);BOOMR.subscribe("onerror",c.onerror,null,c);BOOMR.subscribe("onconfig",c.onconfig,null,c);BOOMR.subscribe("spa_navigation",c.spaNavigation,null,c);BOOMR.getBeaconURL=function(){return c.beacon_url};c.initialized=!0;return this}},startTimer:function(a,b){if(a){"t_page"===a&&this.endTimer("t_resp",b);c.timers[a]={start:"number"==typeof b?b:BOOMR.now()}}return this},endTimer:function(a,b){if(a){c.timers[a]=c.timers[a]||{};void 0===c.timers[a].end&&(c.timers[a].end="number"==typeof b?b:BOOMR.now())}return this},clearTimer:function(a){a&&delete c.timers[a];return this},setTimer:function(a,b,d){a&&(c.timers[a]=void 0!==d?{start:b,end:d,delta:d-b}:{delta:b});return this},addTimersToBeacon:function(a,b){var d,e,f=[];for(d in c.timers)if(c.timers.hasOwnProperty(d)){e=c.timers[d];if("number"!=typeof e.delta){"number"!=typeof e.start&&(e.start="xhr"===b?c.cached_xhr_start:c.cached_t_start);e.delta=e.end-e.start}if(isNaN(e.delta))continue;if(c.basic_timers.hasOwnProperty(d)){BOOMR.addVar(d,e.delta);c.addedVars.push(d)}else f.push(d+"|"+e.delta)}if(f.length){BOOMR.addVar("t_other",f.join(","));c.addedVars.push("t_other")}if("beacon"===b){c.timers={};c.complete=!1}},done:function(a,b){BOOMR.debug("Called done: "+b,"rt");var d,e,f=BOOMR.now(),g=!1;c.complete=!1;e=c.validateLoadTimestamp(f,a,b);if(("load"===b||"visible"===b||"xhr"===b)&&!c.setPageLoadTimers(b,e,a))return this;("load"===b||"visible"===b||"xhr"===b&&a&&"spa_hard"===a.initiator)&&c.getBoomerangTimings();d=c.determineTStart(b,a);this.endTimer("t_done",e);a&&"xhr"===a.initiator&&this.setTimer("t_done",a.timing.requestStart,a.timing.loadEventEnd);BOOMR.removeVar("t_done","t_page","t_resp","t_postrender","t_prerender","t_load","t_other","rt.tstart","rt.nstart","rt.cstart","rt.bstart","rt.end","rt.subres","rt.abld","http.errno","http.method","xhr.sync");c.setSupportingTimestamps(d);this.addTimersToBeacon(null,b);BOOMR.setReferrer(c.r,c.r2);"xhr"===b&&a&&a&&a.data&&(a=a.data);if("xhr"===b&&a){g=a.subresource;if(a.url){BOOMR.addVar("u",BOOMR.utils.cleanupURL(a.url.replace(/#.*/,"")));c.addedVars.push("u")}a.status&&(a.status<-1||a.status>=400)&&BOOMR.addVar("http.errno",a.status);a.method&&"GET"!==a.method&&BOOMR.addVar("http.method",a.method);a.headers&&BOOMR.addVar("http.hdr",a.headers);a.synchronous&&BOOMR.addVar("xhr.sync",1);a.initiator&&BOOMR.addVar("http.initiator",a.initiator);c.addedVars.push("http.errno","http.method","http.hdr","xhr.sync","http.initiator")}if(g&&"passive"!==g){BOOMR.addVar("rt.subres",1);c.addedVars.push("rt.subres")}c.updateCookie();if("unload"===b){BOOMR.addVar("rt.quit","");c.onloadfired||BOOMR.addVar("rt.abld","");c.visiblefired||BOOMR.addVar("rt.ntvu","")}c.complete=!0;BOOMR.sendBeacon(c.beacon_url);return this},is_complete:function(){return c.complete},updateCookie:function(){c.updateCookie()},navigationStart:function(){c.navigationStart||c.initFromNavTiming();return c.navigationStart}}}}(window);!function(){var a,b;if(!BOOMR.plugins.BW){b=[{name:"image-0.png",size:11773,timeout:1400},{name:"image-1.png",size:40836,timeout:1200},{name:"image-2.png",size:165544,timeout:1300},{name:"image-3.png",size:382946,timeout:1500},{name:"image-4.png",size:1236278,timeout:1200},{name:"image-5.png",size:4511798,timeout:1200},{name:"image-6.png",size:9092136,timeout:1200}];b.end=b.length;b.start=0;b.l={name:"image-l.gif",size:35,timeout:1e3};a={base_url:"",timeout:15e3,nruns:5,latency_runs:10,user_ip:"",block_beacon:!1,test_https:!1,cookie_exp:604800,cookie:"BA",results:[],latencies:[],latency:null,runs_left:0,aborted:!1,complete:!0,running:!1,initialized:!1,ncmp:function(a,b){return a-b},iqr:function(a){var b,c,d,e,f=a.length-1,g=[];b=(a[Math.floor(.25*f)]+a[Math.ceil(.25*f)])/2;c=(a[Math.floor(.75*f)]+a[Math.ceil(.75*f)])/2;d=1.5*(c-b);if(0===d)return a;f++;for(e=0;eb-d&&g.push(a[e]);return g},calc_latency:function(){var a,b,c,d,e,f,g,h=0,i=0;this.latencies.shift();g=this.iqr(this.latencies.sort(this.ncmp));b=g.length;BOOMR.debug("latencies: "+this.latencies,"bw");BOOMR.debug("lat_filtered: "+g,"bw");for(a=0;a=0&&m<3&&d[c];c--)if(null!==d[c].t){p++;m++;n=1e3*b[c].size/d[c].t;q.push(n);if(d[c].t>this.latency.mean){o=1e3*b[c].size/(d[c].t-this.latency.mean);r.push(o)}else w.push(c+"_"+d[c].t)}}BOOMR.debug("got "+p+" readings","bw");BOOMR.debug("bandwidths: "+q,"bw");BOOMR.debug("corrected: "+r,"bw");if(q.length>3){q=this.iqr(q.sort(this.ncmp));r=this.iqr(r.sort(this.ncmp))}else{q=q.sort(this.ncmp);r=r.sort(this.ncmp)}BOOMR.debug("after iqr: "+q,"bw");BOOMR.debug("corrected: "+r,"bw");p=Math.max(q.length,r.length);for(a=0;a=b.end-1||void 0!==this.results[this.nruns-d].r[a+1]){BOOMR.debug(BOOMR.utils.objectToString(this.results[this.nruns-d],void 0,2),"bw");d===this.nruns&&(b.start=a);BOOMR.setImmediate(this.iterate,null,null,this)}else this.load_img(a+1,d,this.img_loaded)}else this.results[this.nruns-d].r[a+1]={t:null,state:null,run:d}},finish:function(){this.latency||(this.latency=this.calc_latency());var a=this.calc_bw(),b={bw:a.median_corrected,bw_err:parseFloat(a.stderr_corrected,10),lat:this.latency.mean,lat_err:parseFloat(this.latency.stderr,10),bw_time:Math.round(BOOMR.now()/1e3)};BOOMR.addVar(b);a.debug_info.length>0&&BOOMR.addVar("bw_debug",a.debug_info.join(","));!isNaN(b.bw)&&b.bw>0&&BOOMR.utils.setCookie(this.cookie,{ba:Math.round(b.bw),be:b.bw_err,l:b.lat,le:b.lat_err,ip:this.user_ip,t:b.bw_time},this.user_ip?this.cookie_exp:0);this.complete=!0;!0===this.block_beacon&&BOOMR.sendBeacon();this.running=!1},iterate:function(){if(!this.aborted)if(this.runs_left)if(this.latency_runs)this.load_img("l",this.latency_runs--,this.lat_loaded);else{this.results.push({r:[]});this.load_img(b.start,this.runs_left--,this.img_loaded)}else this.finish()},setVarsFromCookie:function(){var b,c,d,e,f,g,h,i,j;b=BOOMR.utils.getSubCookies(BOOMR.utils.getCookie(a.cookie));if(b&&b.ba){c=parseInt(b.ba,10);d=parseFloat(b.be,10);e=parseInt(b.l,10)||0;f=parseFloat(b.le,10)||0;g=b.ip.replace(/\.\d+$/,"0");h=parseInt(b.t,10);i=this.user_ip.replace(/\.\d+$/,"0");j=Math.round(BOOMR.now()/1e3);if(g===i&&h>=j-this.cookie_exp&&c>0){this.complete=!0;BOOMR.addVar({bw:c,lat:e,bw_err:d,lat_err:f,bw_time:h});return!0}}return!1}};BOOMR.plugins.BW={init:function(c){if(a.initialized)return this;BOOMR.utils.pluginConfig(a,c,"BW",["base_url","timeout","nruns","cookie","cookie_exp","test_https","block_beacon"]);c&&c.user_ip&&(a.user_ip=c.user_ip);if(!a.base_url)return this;b.start=0;a.runs_left=a.nruns;a.latency_runs=10;a.results=[];a.latencies=[];a.latency=null;a.complete=a.aborted=!1;BOOMR.removeVar("ba","ba_err","lat","lat_err");a.setVarsFromCookie()||BOOMR.subscribe("page_ready",this.run,null,this);a.initialized=!0;return this},run:function(){var b;if(a.running||a.complete)return this;b=BOOMR.window.document.createElement("a");b.href=a.base_url;if(!a.test_https&&"https:"===b.protocol){BOOMR.info("HTTPS detected, skipping bandwidth test","bw");a.complete=!0;!0===a.block_beacon&&BOOMR.sendBeacon();return this}a.base_url=b.href;a.running=!0;setTimeout(this.abort,a.timeout);a.iterate();return this},abort:function(){a.aborted=!0;a.running&&a.finish()},is_complete:function(){return!0!==a.block_beacon||a.complete}}}}();!function(){if(!BOOMR.plugins.NavigationTiming){var a={complete:!1,sendBeacon:function(){this.complete=!0;BOOMR.sendBeacon()},xhr_done:function(b){var c;if(b&&"spa_hard"===b.initiator)a.done(b);else if(b&&"spa"===b.initiator)a.sendBeacon();else{var d,e,f=(BOOMR.window,{});if(b){b.data&&(b=b.data);c=BOOMR.getPerformance();if(c&&b.restiming){f={nt_red_st:b.restiming.redirectStart,nt_red_end:b.restiming.redirectEnd,nt_fet_st:b.restiming.fetchStart,nt_dns_st:b.restiming.domainLookupStart,nt_dns_end:b.restiming.domainLookupEnd,nt_con_st:b.restiming.connectStart,nt_con_end:b.restiming.connectEnd,nt_req_st:b.restiming.requestStart,nt_res_st:b.restiming.responseStart,nt_res_end:b.restiming.responseEnd};b.restiming.secureConnectionStart&&(f.nt_ssl_st=b.restiming.secureConnectionStart);for(e in f)if(f.hasOwnProperty(e)&&f[e]){f[e]+=c.timing.navigationStart;f[e]=Math.floor(f[e])}}if(b.timing){d=b.timing;f.nt_req_st||(f.nt_req_st=d.requestStart);f.nt_res_st||(f.nt_res_st=d.responseStart);f.nt_res_end||(f.nt_res_end=d.responseEnd);f.nt_domint=d.domInteractive;f.nt_domcomp=d.domComplete;f.nt_load_st=d.loadEventEnd;f.nt_load_end=d.loadEventEnd}for(e in f)f.hasOwnProperty(e)&&!f[e]&&delete f[e];BOOMR.addVar(f);try{a.addedVars.push.apply(a.addedVars,Object.keys(f))}catch(g){}a.sendBeacon()}}},done:function(){var b,c,d,e,f=BOOMR.window;if(this.complete)return this;a.addedVars=[];b=BOOMR.getPerformance();if(b&&b.timing&&b.navigation){BOOMR.info("This user agent supports NavigationTiming.","nt");c=b.navigation;d=b.timing;e={nt_red_cnt:c.redirectCount,nt_nav_type:c.type,nt_nav_st:d.navigationStart,nt_red_st:d.redirectStart,nt_red_end:d.redirectEnd,nt_fet_st:d.fetchStart,nt_dns_st:d.domainLookupStart,nt_dns_end:d.domainLookupEnd,nt_con_st:d.connectStart,nt_con_end:d.connectEnd,nt_req_st:d.requestStart,nt_res_st:d.responseStart,nt_res_end:d.responseEnd,nt_domloading:d.domLoading,nt_domint:d.domInteractive,nt_domcontloaded_st:d.domContentLoadedEventStart,nt_domcontloaded_end:d.domContentLoadedEventEnd,nt_domcomp:d.domComplete,nt_load_st:d.loadEventStart,nt_load_end:d.loadEventEnd,nt_unload_st:d.unloadEventStart,nt_unload_end:d.unloadEventEnd};d.secureConnectionStart&&(e.nt_ssl_st=d.secureConnectionStart);d.msFirstPaint&&(e.nt_first_paint=d.msFirstPaint);BOOMR.addVar(e);if(d.requestStart&&d.navigationStart&&d.requestStartBOOMR.now()+864e5){BOOMR.addVar("nt_bad",1);a.addedVars.push("nt_bad")}try{a.addedVars.push.apply(a.addedVars,Object.keys(e))}catch(g){}}if(f.chrome&&f.chrome.loadTimes){d=f.chrome.loadTimes();if(d){e={nt_spdy:d.wasFetchedViaSpdy?1:0,nt_cinf:d.connectionInfo,nt_first_paint:d.firstPaintTime};BOOMR.addVar(e);try{a.addedVars.push.apply(a.addedVars,Object.keys(e))}catch(g){}}}a.sendBeacon()},clear:function(){if(a.addedVars&&a.addedVars.length>0){BOOMR.removeVar(a.addedVars);a.addedVars=[]}this.complete=!1},prerenderToVisible:function(){this.complete=!1;this.done()}};BOOMR.plugins.NavigationTiming={init:function(){if(!a.initialized){BOOMR.subscribe("page_ready",a.done,null,a);BOOMR.subscribe("prerender_to_visible",a.prerenderToVisible,null,a);BOOMR.subscribe("xhr_load",a.xhr_done,null,a);BOOMR.subscribe("before_unload",a.done,null,a);BOOMR.subscribe("onbeacon",a.clear,null,a);a.initialized=!0}return this},is_complete:function(){return!0}}}}();!function(){function a(a){var b,c,d,e,f,g,h,i,j={};for(b in a){c=b;for(d=0;d10)return x;try{if(!d(a))return x;n=e(a);u=h(a,i);w=a.document.createElement("a");Array.prototype.forEach.call(a.document.getElementsByTagName("script"),function(a){w.href=a.src;w.href.match(/^https?:\/\//)&&(y[w.href]=a)});q=a.document.getElementsByTagName("iframe");if(q&&q.length)for(k=0;kn&&(p=c+(o-n));w.href=q[k].src;x=x.concat(f(a.frames[k],!1,p,g+1,u[w.href]))}if("function"!=typeof a.performance.getEntriesByType)return x;if(b){m=a.performance.getEntriesByType("navigation");if(m&&1===m.length){r=m[0];x.push({name:a.location.href,startTime:0,initiatorType:"html",redirectStart:r.redirectStart,redirectEnd:r.redirectEnd,fetchStart:r.fetchStart,domainLookupStart:r.domainLookupStart,domainLookupEnd:r.domainLookupEnd,connectStart:r.connectStart,secureConnectionStart:r.secureConnectionStart,connectEnd:r.connectEnd,requestStart:r.requestStart,responseStart:r.responseStart,responseEnd:r.responseEnd,workerStart:r.workerStart,encodedBodySize:r.encodedBodySize,decodedBodySize:r.decodedBodySize,transferSize:r.transferSize,serverTiming:j(r)})}else if(a.performance.timing){s=a.performance.timing;0!==s.navigationStart&&s.responseEnd<=s.navigationStart+36e5&&x.push({name:a.location.href,startTime:0,initiatorType:"html",redirectStart:s.redirectStart?s.redirectStart-s.navigationStart:0,redirectEnd:s.redirectEnd?s.redirectEnd-s.navigationStart:0,fetchStart:s.fetchStart?s.fetchStart-s.navigationStart:0,domainLookupStart:s.domainLookupStart?s.domainLookupStart-s.navigationStart:0,domainLookupEnd:s.domainLookupEnd?s.domainLookupEnd-s.navigationStart:0,connectStart:s.connectStart?s.connectStart-s.navigationStart:0,secureConnectionStart:s.secureConnectionStart?s.secureConnectionStart-s.navigationStart:0,connectEnd:s.connectEnd?s.connectEnd-s.navigationStart:0,requestStart:s.requestStart?s.requestStart-s.navigationStart:0,responseStart:s.responseStart?s.responseStart-s.navigationStart:0,responseEnd:s.responseEnd?s.responseEnd-s.navigationStart:0})}}var z=a.performance.getEntriesByType("resource"),A=[];for(k=0;z&&k-1||g.name.indexOf(BOOMR.config_url)>-1||"function"==typeof BOOMR.getBeaconURL&&BOOMR.getBeaconURL()&&g.name.indexOf(BOOMR.getBeaconURL())>-1||a&&i+g.startTimeb)break;if(void 0===c||"*"===c||!c.length||g.initiatorType&&BOOMR.utils.inArray(g.initiatorType,c)){q(j,g.serverTiming);k.push(g)}}}var l=r(j);return{entries:k,serverTiming:{lookup:l,indexed:s(l)}}}function j(a){var b,c,d,e;if(a.encodedBodySize||a.decodedBodySize||a.transferSize){b=a.transferSize;c=a.encodedBodySize;d=a.decodedBodySize;e=[c,b?b-c:"_",d?d-c:0];return e.map(g).join(",").replace(/,+$/,"")}return""}function k(a,b){var c,d,e;if(a&&b)for(c=0;c0?",":"")+d+f;return a},""));m=k(h.name,v.trimUrls);void 0!==o[m]?o[m]+="|"+n:h.visibleDimensions?o[m]=z+A+h.visibleDimensions.map(Math.round).map(g).join(",").replace(/,+$/,"")+"|"+n:o[m]=n;if(h.visibleDimensions){p[h.latestTime]||(p[h.latestTime]=[]);p[h.latestTime].push(h.visibleDimensions)}}return{restiming:b(a(o),!0),servertiming:s.lookup}}function n(a){var b=[];if(!a||!a.length)return b;for(var c=0;c0&&g1&&BOOMR.addVar("scr.dpx",c.devicePixelRatio);if(c.scrollX||c.scrollY){a="function"==typeof c.scrollX?c.scrollX():c.scrollX;b="function"==typeof c.scrollY?c.scrollY():c.scrollY;"number"==typeof a&&"number"==typeof b&&BOOMR.addVar("scr.sxy",a+"x"+b)}},"screen");b(g,function(){g.hardwareConcurrency&&BOOMR.addVar("cpu.cnc",g.hardwareConcurrency);g.maxTouchPoints&&BOOMR.addVar("scr.mtp",g.maxTouchPoints)},"navigator");b(h,function(){BOOMR.addVar("bat.lvl",h.level)},"battery");b(!0,function(){var b;BOOMR.addVar({"dom.ln":a("*"),"dom.sz":d.documentElement.innerHTML.length});b={};BOOMR.addVar(a("img",["dom.img","dom.img.ext","dom.img.uniq"],function(a){return a.src&&!a.src.toLowerCase().match(/^(?:about:|javascript:|data:|#)/)},function(a){return!(b[a.src]=b.hasOwnProperty(a.src))}));b={};BOOMR.addVar(a("script",["dom.script","dom.script.ext","dom.script.uniq"],function(a){return a.src&&!a.src.toLowerCase().match(/^(?:about:|javascript:|#)/)},function(a){return!(b[a.src]=b.hasOwnProperty(a.src))}));b={};BOOMR.addVar(a("iframe",["dom.iframe","dom.iframe.ext","dom.iframe.uniq"],function(a){return a.src&&!a.src.toLowerCase().match(/^(?:about:|javascript:|#)/)},function(a){return!(b[a.src]=b.hasOwnProperty(a.src))}));b={};BOOMR.addVar(a("link",["dom.link","dom.link.css","dom.link.css.uniq"],function(a){return a.rel&&"stylesheet"===a.rel.toLowerCase()&&a.href&&!a.href.toLowerCase().match(/^(?:about:|javascript:|#)/)},function(a){return!(b[a.href]=b.hasOwnProperty(a.href))}))},"dom")}}};BOOMR.plugins.Memory={init:function(){var a;try{c=BOOMR.window;d=c.document;j=BOOMR.getPerformance();a=c.console;f=c.screen;g=c.navigator;if(g&&g.battery)h=g.battery;else if(g&&"function"==typeof g.getBattery){var b=g.getBattery();b&&"function"==typeof b.then?b.then(function(a){h=a}):"object"==typeof b&&b.hasOwnProperty("level")&&(h=b)}}catch(k){BOOMR.addError(k,"Memory.init")}e=j&&j.memory?j.memory:a&&a.memory?a.memory:null;if(i.initialized)return this;i.initialized=!0;BOOMR.subscribe("before_beacon",i.done,null,i);return this},is_complete:function(){return!0}}}}();!function(){if(!BOOMR.plugins.CACHE_RELOAD){var a={url:""};BOOMR.plugins.CACHE_RELOAD={init:function(b){BOOMR.utils.pluginConfig(a,b,"CACHE_RELOAD",["url"]);if(!a.url)return this;var c=document.createElement("iframe");c.style.display="none";c.src=a.url;document.body.appendChild(c);return this},is_complete:function(){return!0}}}}();!function(){"use strict";function a(a,b){var c=(65535&a)+(65535&b);return(a>>16)+(b>>16)+(c>>16)<<16|65535&c}function b(a,b){return a<>>32-b}function c(c,d,e,f,g,h){return a(b(a(a(d,c),a(f,h)),g),e)}function d(a,b,d,e,f,g,h){return c(b&d|~b&e,a,b,f,g,h)}function e(a,b,d,e,f,g,h){return c(b&e|d&~e,a,b,f,g,h)}function f(a,b,d,e,f,g,h){return c(b^d^e,a,b,f,g,h)}function g(a,b,d,e,f,g,h){return c(d^(b|~e),a,b,f,g,h)}function h(b,c){b[c>>5]|=128<>>9<<4)]=c;var h,i,j,k,l,m=1732584193,n=-271733879,o=-1732584194,p=271733878;for(h=0;h>5]>>>b%32&255);return c}function j(a){var b,c=[];c[(a.length>>2)-1]=void 0;for(b=0;b>5]|=(255&a.charCodeAt(b/8))<16&&(e=h(e,8*a.length));for(c=0;c<16;c+=1){f[c]=909522486^e[c];g[c]=1549556828^e[c]}d=h(f.concat(j(b)),512+8*b.length);return i(h(g.concat(d),640))}function m(a){var b,c,d="0123456789abcdef",e="";for(c=0;c>>4&15)+d.charAt(15&b)}return e}function n(a){return unescape(encodeURIComponent(a))}function o(a){return k(n(a))}function p(a){return m(o(a))}function q(a,b){return l(n(a),n(b))}function r(a,b){return m(q(a,b))}function s(a,b,c){return b?c?q(b,a):r(b,a):c?o(a):p(a)}if(!BOOMR.utils||!BOOMR.utils.md5){BOOMR.utils=BOOMR.utils||{};BOOMR.utils.MD5=s}}();!function(){if(!BOOMR.utils||!BOOMR.utils.Compression){var a=BOOMR.utils.Compression={};a.jsUrl=function(b){function c(a){if(!/[^\w-.]/.test(a))return a;a=a.replace(/[^\w-.]/g,function(a){if("$"===a)return"!";a=a.charCodeAt(0);return a<256?"*"+("00"+a.toString(16)).slice(-2):"**"+("0000"+a.toString(16)).slice(-4)});return a}var d=[];switch(typeof b){case"number":return isFinite(b)?"~"+b:"~null";case"string":return"~'"+c(b);case"boolean":return"~"+b;case"object":if(!b)return"~null";if(BOOMR.utils.isArray(b)){for(var e=0;e-1&&(a=a.replace(/eval code/g,"eval").replace(/(\(eval at [^\()]*)|(\)\,.*$)/g,""));var b=a.replace(/^\s+/,"").replace(/\(eval code/g,"(").split(/\s+/).slice(1),c=this.extractLocation(b.pop());return{functionName:b.join(" ")||void 0,fileName:"eval"===c[0]?void 0:c[0],lineNumber:c[1],columnNumber:c[2],source:a}},this)},parseFFOrSafari:function(c){return a(b(c.stack.split("\n"),function(a){return!a.match(e)},this),function(a){a.indexOf(" > eval")>-1&&(a=a.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g,":$1"));if(-1===a.indexOf("@")&&-1===a.indexOf(":"))return{functionName:a};var b=a.split("@"),c=this.extractLocation(b.pop());return{functionName:b.join("@")||void 0,fileName:c[0],lineNumber:c[1],columnNumber:c[2],source:a}},this)},parseOpera:function(a){return!a.stacktrace||a.message.indexOf("\n")>-1&&a.message.split("\n").length>a.stacktrace.split("\n").length?this.parseOpera9(a):a.stack?this.parseOpera11(a):this.parseOpera10(a)},parseOpera9:function(a){for(var b=/Line (\d+).*script (?:in )?(\S+)/i,c=a.message.split("\n"),d=[],e=2,f=c.length;e/,"$2").replace(/\([^\)]*\)/g,"")||void 0;e.match(/\(([^\)]*)\)/)&&(b=e.replace(/^[^\(]+\(([^\)]*)\)$/,"$1"));return{functionName:f,args:void 0===b||"[arguments not available]"===b?void 0:b.split(","),fileName:d[0],lineNumber:d[1],columnNumber:d[2],source:a}},this)}}});!function(){function a(a){a=a||{};"number"==typeof a.count||"string"==typeof a.count?this.count=parseInt(a.count,10):this.count=1;"number"==typeof a.timestamp?this.timestamp=a.timestamp:this.timestamp=BOOMR.now();"number"!=typeof a.code&&"string"!=typeof a.code||(this.code=parseInt(a.code,10));"string"==typeof a.message&&(this.message=a.message);"string"==typeof a.functionName&&(this.functionName=a.functionName);"string"==typeof a.fileName&&(this.fileName=a.fileName);"number"!=typeof a.lineNumber&&"string"!=typeof a.lineNumber||(this.lineNumber=parseInt(a.lineNumber,10));"number"!=typeof a.columnNumber&&"string"!=typeof a.columnNumber||(this.columnNumber=parseInt(a.columnNumber,10));"string"==typeof a.stack&&(this.stack=a.stack);"string"==typeof a.type&&(this.type=a.type);void 0!==a.extra&&(this.extra=a.extra);this.source="number"==typeof a.source||"string"==typeof a.source?parseInt(a.source,10):BOOMR.plugins.Errors.SOURCE_APP;"number"!=typeof a.via&&"string"!=typeof a.via||(this.via=parseInt(a.via,10));BOOMR.utils.isArray(a.frames)?this.frames=a.frames:this.frames=[];BOOMR.utils.isArray(a.events)?this.events=a.events:this.events=[]}var b;if(!BOOMR.plugins.Errors){var c=["BOOMR_addError","createStackForSend","BOOMR.window.console.error","BOOMR.plugins.Errors.init","BOOMR.window.onerror","BOOMR_plugins_errors_"],d=5e3;a.prototype.equals=function(a){return"object"==typeof a&&(this.code===a.code&&(this.message===a.message&&(this.functionName===a.functionName&&(this.fileName===a.fileName&&(this.lineNumber===a.lineNumber&&(this.columnNumber===a.columnNumber&&(this.stack===a.stack&&(this.type===a.type&&this.source===a.source))))))))};a.fromError=function(b,e,f){var g,h,i,j,k=!1,l=BOOMR.now();if(!b)return null;if(b.stack){b.stack.length>d&&(b.stack=b.stack.substr(0,d));h=ErrorStackParser.parse(b);if(h&&h.length){if(b.generatedStack){if(h.length>=4&&h[1].functionName&&-1!==h[1].functionName.indexOf("createStackForSend")){h=h.slice(3);k=!0}if(h.length>=3&&h[0].functionName&&-1!==h[0].functionName.indexOf("createStackForSend")){h=h[1].fileName===h[2].fileName?h.slice(3):h.slice(2);k=!0}if(h.length>=1&&h[0].functionName&&-1!==h[0].functionName.indexOf("BOOMR_plugins_errors")){h=h.slice(1);k=!0}}for(i=0;i=b.maxErrors)){g=a.fromError(c,d,e);h=b.mergeDuplicateErrors(b.errors,g,!1);BOOMR.fireEvent("onerror",h||g);b.mergeDuplicateErrors(b.q,g,!0);if(!b.isDuringLoad&&-1===b.sendIntervalId){if(h)return;b.sendIntervalId=setTimeout(function(){b.sendIntervalId=-1;BOOMR.addVar("http.initiator","error");BOOMR.addVar("api",1);b.addErrorsToBeacon();BOOMR.sendBeacon()},b.sendInterval)}}}},findDuplicateError:function(a,b){if(BOOMR.utils.isArray(a)&&void 0!==b)for(var c=0;c1?arguments[1]:BOOMR.window;var d=Array.prototype.slice.call(arguments,2);return b.wrap(a,c).apply(c,d)}}},normalizeToString:function(a){return void 0===a?"undefined":null===a?"null":"number"==typeof a&&isNaN(a)?"NaN":""===a?"(empty string)":0===a?"0":a?"function"==typeof a?"(function)":a&&"function"==typeof a.toString?a.toString():"(unknown)":"false"},compressErrors:function(a){var b,c,d,e,f,g,h,i,j,k=0;i=BOOMR.window.location.origin;for(b=0;b0&&(g.clientid=f[0].get("clientId"))}}catch(j){BOOMR.addError(j,"TPAnalytics googleAnalytics")}if(!g.clientid){e=BOOMR.utils.getCookie("_ga");if(e){e=e.split(".");e&&4===e.length&&(g.clientid=e[2]+"."+e[3])}else{e=BOOMR.utils.getCookie("__utma");if(e){e=e.split(".");e&&6===e.length&&(g.clientid=e[1]+"."+e[2])}}}}for(b=0;b0?f[1]:""}else b=BOOMR.utils.getCookie("s_fid");b&&(g.aid=b)}}if("object"==typeof h.s){"string"==typeof h.s.campaign&&h.s.campaign&&(g.campaign=h.s.campaign);"string"==typeof h.s.purchaseID&&h.s.purchaseID&&(g.purchaseid=h.s.purchaseID)}}return g},ibmAnalytics:function(){var b,c,d,e,f,g,h={},i=BOOMR.window,j={cm_mmc:[/([^&#]+?)-_-([^&#]+?)-_-([^&#]+?)-_-([^&#]+)/,["mmc_vendor","mmc_category","mmc_placement","mmc_item"]],cm_sp:[/([^&#]+?)-_-([^&#]+?)-_-([^&#]+)/,["sp_type","sp_promotion","sp_link"]],cm_re:[/([^&#]+?)-_-([^&#]+?)-_-([^&#]+)/,["re_version","re_pagearea","re_link"]]};if(a.clientids&&"function"==typeof i.cmRetrieveUserID)try{i.cmRetrieveUserID(function(a){h.coreid=a})}catch(k){BOOMR.addError(k,"TPAnalytics ibmAnalytics")}for(e in j)if(j.hasOwnProperty(e)){b=BOOMR.utils.getQueryParamValue(e);if(b){f=j[e][0];g=j[e][1];c=f.exec(b);if(c&&c.length>g.length)for(d=0;d0&&BOOMR.sendBeacon()},onBeacon:function(){if(this.addedVars&&this.addedVars.length>0){BOOMR.removeVar(this.addedVars);this.addedVars=[]}}};BOOMR.plugins.TPAnalytics={init:function(b){BOOMR.utils.pluginConfig(a,b,"TPAnalytics",["clientids","dropParams"]);if(!a.initialized){BOOMR.utils.isArray(a.dropParams)||(a.dropParams=[]);BOOMR.subscribe("page_ready",a.pageReady,null,a);BOOMR.subscribe("onbeacon",a.onBeacon,null,a);BOOMR.subscribe("prerender_to_visible",a.pageReady,null,a);a.initialized=!0}return this},is_complete:function(){return!0}}}}();!function(){if(!BOOMR.plugins.UserTiming){var a={complete:!1,initialized:!1,supported:!1,options:{from:0,window:BOOMR.window},now:function(){var a,b,c=BOOMR.getPerformance();if(c&&c.now)a=c.now();else{b=BOOMR.plugins.RT&&BOOMR.plugins.RT.navigationStart?BOOMR.plugins.RT.navigationStart():BOOMR.t_lstart||BOOMR.t_start;a=BOOMR.now()-b}return a},getUserTiming:function(){var b,c,d=this.now(),e=window.UserTimingCompression||BOOMR.window.UserTimingCompression;b=e.getCompressedUserTiming(a.options);c=e.compressForUri(b);this.options.from=d;return c},addEntriesToBeacon:function(){var a;if(!this.complete){BOOMR.removeVar("usertiming");a=this.getUserTiming();a&&BOOMR.addVar({usertiming:a});this.complete=!0}},clearMetrics:function(a){a.hasOwnProperty("usertiming")&&BOOMR.removeVar("usertiming");this.complete=!1},subscribe:function(){BOOMR.subscribe("before_beacon",this.addEntriesToBeacon,null,this);BOOMR.subscribe("onbeacon",this.clearMetrics,null,this)},pageReady:function(){this.checkSupport()&&this.subscribe()},checkSupport:function(){if(this.supported)return!0;if(void 0===(window.UserTimingCompression||BOOMR.window.UserTimingCompression)){BOOMR.warn("UserTimingCompression library not found","usertiming");return!1}var a=BOOMR.getPerformance();if(a&&"function"==typeof a.getEntriesByType){var b=a.getEntriesByType("mark"),c=a.getEntriesByType("measure");if(BOOMR.utils.isArray(b)&&BOOMR.utils.isArray(c)){BOOMR.info("Client supports User Timing API","usertiming");this.supported=!0;return!0}}return!1}};BOOMR.plugins.UserTiming={init:function(b){if(a.initialized)return this;a.checkSupport()?a.subscribe():BOOMR.subscribe("page_ready",a.pageReady,null,a);a.initialized=!0;return this},is_complete:function(){return!0},is_supported:function(){return a.initialized&&a.supported}}}}();!function(){function a(a,b,c){var d=a.shift();if("string"==typeof d){var e=d.split("."),f=BOOMR,g=BOOMR;"BOOMR"===e[0]&&e.shift();for(;e.length&&f&&("object"==typeof f||"function"==typeof f);){var h=e.shift();f=f[h];e.length&&(g=g[h])}if(!e.length&&"function"==typeof f){var i=f.apply(g,a);"function"==typeof b&&b.call(c,i)}}}function b(b){for(var c=0;c