/*
Copyright 2012-2021 VeloViewer. All Rights Reserved
###V134###
*/
var cacheAct = [],
    cacheSeg = [],
    tacts = {},
    tbests = {},
    tmaps = {},
    teffs = {},
    tceffs = {},
    tphotos = {},
    texplorer = {},
    trivals, tsegs, tsegDets, tsegMaps, segCacheReady = true,
    actCacheReady = true,
    actsL = true,
    actsPL = true,
    mapsL = true,
    mapsPL = true,
    bestsL = true,
    bestsPL = true,
    segsL = true,
    segDetsL = true,
    segsMapsL = true,
    photosL = true,
    photosPL = true,
    effsL = true,
    effsPL = true,
    effsCL = true,
    rivalsL = true,
    explorerL = true,
    errorShown = false,
    initLoaded = false,
    pdFiles = ['acts', 'effs', 'bests', 'maps', 'segs', 'segDets', 'segMaps', 'photos', 'acts_p', 'effs_p', 'bests_p', 'maps_p', 'photos_p', 'explorer'];

d3.selectAll('.clearLocalStorageBtn').remove();

function notYetLoaded(e, t) {
    // 0 or 404 does not exist.
    //
    if (t == 'explorer') {
        explorerLoaded(null);
        return;
    }
    if (t == 'photos') {
        photosLoaded([]);
        return;
    }
    if (t == 'photos_p') {
        photos_pLoaded([]);
        return;
    }
    if (typeof(pageName) !== 'undefined' && pageName == 'graphic') {
        return;
    }
    /*if (document.location.pathname == '/infographic') {
        eval(t.replace('_p','P')+'L=true');
        if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL) {
            localInit();
        } else {
            return;
        }
    }*/
    if (typeof(segment) !== 'undefined') {
        if (initLoaded) return;
        actsL = true;
        actsPL = true;
        localInit();
        initLoaded = true;
        return;
    }
    if (t == 'acts' || t == 'acts_p') {
        errorShown = true;
        d3.select('#tourInfo').style('display', 'none');
        contextAthleteId = typeof(contextAthleteId) === 'undefined' ? athleteId : contextAthleteId;
        if (contextAthleteId == athleteId) {

            d3.select('#loadingMsg, .tab-pane.active').html('<h3>Your data isn\'t yet uploaded from Strava. Please visit <a href="/athlete/' + contextAthleteId + '/update">your update page</a> and I\'ll bring it in for you.</h3><br/><br/>');

        } else {
            d3.select('#loadingMsg, .tab-pane.active').html('<h2>This athlete hasn\'t uploaded their data from Strava.</h2><h3>' + (+athleteId > 0 ? '<a href="/summary">View your own data instead</a>.' : '') + '</h3>');
        }
    } else {
        if (hasLocalStorage) {
            var pde = {};
            if (typeof(localStorage['pdDataErrors' + contextAthleteId]) !== 'undefined') {
                pde = localStorage['pdDataErrors' + contextAthleteId].parseJSON();
            }
            pde[t] = e;
            localStorage['pdDataErrors' + contextAthleteId] = JSON.stringify(pde);
        }
        if (!errorShown) {
            errorShown = true;
            d3.select('#tourInfo').style('display', 'none');
            contextAthleteId = typeof(contextAthleteId) === 'undefined' ? athleteId : contextAthleteId;
            if (contextAthleteId == athleteId) {
                d3.select('#loadingMsg, .tab-pane.active').html('<h2>Your data isn\'t yet uploaded from Strava. Please visit <a href="/athlete/' + contextAthleteId + '/update?fix=1">your update page</a> and I\'ll sort it out for you.</h2><h3>If you\'re using NoScript or an Ad Blocker add-on then you may need to disable it to load your data throughout the site.</h3><h3>If you\'re still having trouble then please <a href="mailto:veloviewer@gmail.com?subject=' + encodeURIComponent('Update errors') + '&body=' + encodeURIComponent('athlete id: ' + contextAthleteId + (hasLocalStorage ? ', details:' + localStorage['pdDataErrors' + contextAthleteId] : '')) + '">email me</a>.</h3>');
                d3.selectAll('a[href="/update"]').attr('href', '/athlete/' + contextAthleteId + '/update?fix=1');
            } else {
                d3.select('#loadingMsg, .tab-pane.active').html('<h2>This athlete hasn\'t uploaded their data from Strava.</h2><h3>' + (+athleteId > 0 ? '<a href="/summary">View your own data instead</a>.' : '') + '</h3>');
            }
        }
    }
}

function loadPdDate(src, type) {
    if (errorShown) {
        return;
    }
    var re = new RegExp(type + '\.[0-9]+\.js$');
    if (src.match(re) == null) {
        if (type == 'rivals') {
            rivalsLoaded(null);
        } else {
            notYetLoaded(0, type);
        }
        return;
    }
    $.ajax({
        url: src,
        jsonpCallback: type + 'Loaded',
        contentType: "application/json",
        dataType: 'jsonp',
        callType: type,
        tryCount: 0,
        retryLimit: 3,
        async: true,
        cache: true,
        error: function(xhr, textStatus, errorThrown) {
            if (textStatus == 'timeout' || xhr.status == 0 || xhr.status == 404) {
                this.tryCount++;
                if (this.tryCount == 1) {
                    $.ajax({
                        parentCall: this,
                        parentXhr: xhr,
                        async: true,
                        url: '/api/checkName.php?n=' + this.url.substr(0, this.url.indexOf('?')).substr(this.url.indexOf('athletes2')),
                        success: function(d) {
                            if (d.status == 'success') {
                                var re = new RegExp(this.parentCall.callType + '\.[0-9]+\.js$');
                                if (d.name.match(re) == null) {
                                    if (type == 'rivals') {
                                        rivalsLoaded(null);
                                    } else {
                                        notYetLoaded(0, type);
                                    }
                                    return;
                                }
                                var n = d.name.replace(/^.*\.([0-9]*)\.js$/, '$1')
                                this.parentCall.url = this.parentCall.url.replace(/\.[0-9]*\./, '.' + n + '.');
                                $.ajax(this.parentCall);
                            } else {
                                notYetLoaded(this.parentXhr.status, this.parentCall.callType);
                            }
                        }
                    });
                    return false;
                } else {
                    if (this.tryCount <= this.retryLimit) {
                        window.setTimeout(function() {
                            $.ajax(this);
                        }, 1000);
                        return false;
                    }
                }
            }
            notYetLoaded(xhr.status, this.callType);
        }
    });
}

$(document).ready(function() {
    localStorage.removeItem('pdDataErrors' + athleteId);

    if (typeof(actsSrc) !== 'undefined') {
        actCacheReady = false;
        actsL = false;
        loadPdDate(actsSrc, 'acts');
    }

    if (typeof(actsPSrc) !== 'undefined') {
        actsPL = false;
        loadPdDate(actsPSrc, 'acts_p');
    }

    if (typeof(segsSrc) !== 'undefined') {
        segCacheReady = false;
        segsL = false;
        loadPdDate(segsSrc, 'segs');
    }

    if (typeof(segDetsSrc) !== 'undefined') {
        segDetsL = false;
        loadPdDate(segDetsSrc, 'segDets');
    }

    if (typeof(bestsSrc) !== 'undefined') {
        bestsL = false;
        loadPdDate(bestsSrc, 'bests');
    }

    if (typeof(bestsPSrc) !== 'undefined') {
        bestsPL = false;
        loadPdDate(bestsPSrc, 'bests_p');
    }

    if (typeof(segMapsSrc) !== 'undefined') {
        segsMapsL = false;
        loadPdDate(segMapsSrc, 'segMaps');
    }

    if (typeof(effsSrc) !== 'undefined') {
        effsL = false;
        loadPdDate(effsSrc, 'effs');
    }

    if (typeof(effsPSrc) !== 'undefined') {
        effsPL = false;
        loadPdDate(effsPSrc, 'effs_p');
    }

    if (typeof(mapsSrc) !== 'undefined') {
        mapsL = false;
        loadPdDate(mapsSrc, 'maps');
    }

    if (typeof(mapsPSrc) !== 'undefined') {
        mapsPL = false;
        loadPdDate(mapsPSrc, 'maps_p');
    }

    if (typeof(photosSrc) !== 'undefined') {
        photosL = false;
        loadPdDate(photosSrc, 'photos');
    }

    if (typeof(photosPSrc) !== 'undefined') {
        photosPL = false;
        loadPdDate(photosPSrc, 'photos_p');
    }

    if (typeof(rivalsSrc) !== 'undefined') {
        rivalsL = false;
        loadPdDate(rivalsSrc, 'rivals');
    }

    if (typeof(explorerSrc) !== 'undefined') {
        explorerL = false;
        loadPdDate(explorerSrc, 'explorer');
    }
});

function actsLoaded(obj) {
    actsL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tacts[att] = obj[att];

            if (typeof(tacts[att]['s']) === 'undefined') {
                tacts[att].s = tacts[att]['ls'];
                tacts[att].tz = '+00:00';
            }
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function acts_pLoaded(obj) {
    actsPL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tacts[att] = obj[att];
            if (typeof(tacts[att]['s']) === 'undefined') {
                tacts[att].s = tacts[att]['ls'];
                tacts[att].tz = '+00:00';
            }
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function bestsLoaded(obj) {
    bestsL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tbests[att] = obj[att];
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function bests_pLoaded(obj) {
    bestsPL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tbests[att] = obj[att];
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function mapsLoaded(obj) {
    mapsL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tmaps[att] = obj[att];
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function maps_pLoaded(obj) {
    mapsPL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tmaps[att] = obj[att];
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function photosLoaded(obj) {
    photosL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tphotos[att] = obj[att];
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function photos_pLoaded(obj) {
    photosPL = true;
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            tphotos[att] = obj[att];
        }
    }
    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}


function segsLoaded(obj) {
    segsL = true;
    tsegs = obj;
    if (!s_s) {
        if (contextAthleteId == loggedInAthleteId) {
            var sa = d3.values(tsegs);
            if (sa.length > 0 && sa[0].l) {
                $.ajax({
                    async: true,
                    url: '/api/saveNewRanks.php?c=1',
                    success: function(d) {
                        console.info('Ranks cleared');
                    },
                    error: function(d) {
                        console.info('Ranks clear error');
                    }
                });
            }
        }
        for (var i in tsegs) {
            tsegs[i] = { et: tsegs[i].et };
        }
    }
    if (segsL && segDetsL && segsMapsL & effsL && effsPL && rivalsL) {
        pd_mergeSegArrays();
    }
}

function segDetsLoaded(obj) {
    segDetsL = true;
    tsegDets = obj;
    if (segsL && segDetsL && segsMapsL & effsL && effsPL && rivalsL) {
        pd_mergeSegArrays();
    }
}

function segMapsLoaded(obj) {
    segsMapsL = true;
    tsegMaps = obj;
    if (segsL && segDetsL && segsMapsL & effsL && effsPL && rivalsL) {
        pd_mergeSegArrays();
    }
}

function effsLoaded(obj) {
    if (!effsL) {
        if (typeof(obj.length) !== 'undefined' && obj.length > 0) {
            obj = d3.nest()
                .key(function(d) {
                    return d.ai;
                })
                .rollup(function(d) {
                    return d;
                })
                .map(obj);
        }
        if (typeof(obj.length) === 'undefined') {
            for (var att in obj) {
                teffs[att] = obj[att];
            }
        }
        effsL = true;
        if (segsL && segDetsL && segsMapsL & effsL && effsPL && rivalsL) {
            pd_mergeSegArrays();
        }
    } else {
        effsCL = true;
        tceffs = d3.merge(d3.values(obj));
        d3.nest()
            .key(function(d) {
                return d.si
            })
            .rollup(function(d) {
                return d.sort(function(a, b) {
                    return (a.et == b.et ? a.i - b.i : a.et - b.et)
                }).forEach(function(e, i) {
                    e.pr = i + 1;
                })
            })
            .map(tceffs);

        compLoaded();
    }
}

function effs_pLoaded(obj) {
    if (typeof(obj.length) !== 'undefined' && obj.length > 0) {
        obj = d3.nest()
            .key(function(d) {
                return d.ai;
            })
            .rollup(function(d) {
                return d;
            })
            .map(obj);
    }
    if (typeof(obj.length) === 'undefined') {
        for (var att in obj) {
            teffs[att] = obj[att];
        }
    }
    effsPL = true;
    if (segsL && segDetsL && segsMapsL & effsL && effsPL && rivalsL) {
        pd_mergeSegArrays();
    }
}

function rivalsLoaded(obj) {
    rivalsL = true;
    trivals = (obj == null ? {
        t: {},
        r: {}
    } : obj);
    if (segsL && segDetsL && segsMapsL & effsL && effsPL && rivalsL) {
        pd_mergeSegArrays();
    }
}

function explorerLoaded(obj) {
    explorerL = true;
    texplorer = (obj == null ? {} : obj);

    if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL && explorerL && photosL && photosPL) {
        pd_mergeActArrays()
    }
}

function pd_mergeActArrays() {
    if (!segCacheReady) {
        return;
    }
    for (var att1 in tbests) {
        for (var att in tbests[att1]) {
            if (typeof(tacts[att1]) !== 'undefined') {
                tacts[att1][att] = tbests[att1][att];
            }
        }
    }
    for (var att in tmaps) {
        if (typeof(tacts[att]) !== 'undefined') {
            var lm = (typeof(tmaps[att].m) === 'undefined' ? tmaps[att] : tmaps[att].m);
            tacts[att].map = (lm == null ? null : lm.replace(/\}\,\{/g, '}{'));
        }
    }
    for (var att in tphotos) {
        if (typeof(tacts[att]) !== 'undefined') {
            tacts[att].photos = tphotos[att];
        }
    }
    cacheAct = d3.values(tacts);
    if (typeof(loggedInAthleteId) !== 'undefined' && loggedInAthleteId == contextAthleteId && !isPRO && typeof(freeIds) !== 'undefined' && freeIds.length > 0 && cacheAct.length > 25) {
        var tca = cacheAct.filter(function(d) {
            return freeIds.indexOf(d.i) > -1
        });
        if (tca.length < 25) {
            cacheAct = cacheAct.slice(0, 25);
        } else {
            cacheAct = tca;
            delete tca;
        }
    }
    actCacheReady = true;

    lGear = {};
    gear.forEach(function(d) {
        lGear[d.id] = d;
    });

    /*gear.forEach(function(d) {
        cacheAct.filter(function(e) {
            return e.g == d.id
        }).forEach(function(e) {
            e.gi = d.id;
            e.g = (e.t == 'Ride' || e.t == 'EBikeRide' || e.t == 'VirtualRide' || e.t == 'Run' || e.t == 'Walk' || e.t == 'Hike' || e.t == 'VirtualRun' ? d.name : '');
        })
    })*/
    cacheAct.forEach(function(d) {
        if (typeof(d.g) !== 'undefined' && d.g != null) {
            if (typeof(lGear[d.g]) === 'undefined' && typeof(d.gn) !== 'undefined') {
                lGear[d.g] = { id: d.g, name: d.gn };
            }
            d.gi = d.g;
            d.g = (d.t == 'Ride' || d.t == 'EBikeRide' || d.t == 'VirtualRide' || d.t == 'Velomobile' || d.t == 'Run' || d.t == 'Walk' || d.t == 'Hike' || d.t == 'VirtualRun' ? (typeof(lGear[d.g]) !== 'undefined' ? lGear[d.g].name : d.g + ' (retired)') : '');
            //d.g = (d.g.match(/^[bg][0-9]*$/) != null ? d.g + ' (retired)' : d.g);
        }

        d.dv = (typeof(d.dv) === 'undefined' || d.dv == null ? 'n/a' : d.dv);
        d.aw = (typeof(d.aw) === 'undefined' ? 0 : d.aw);
        d.hr = (typeof(d.hr) === 'undefined' ? 0 : d.hr);
        d.mh = (typeof(d.mh) === 'undefined' ? 0 : d.mh);
        d.ac = (typeof(d.ac) === 'undefined' ? 0 : d.ac);
        d.k = (typeof(d.k) === 'undefined' ? 0 : d.k);
        d.ca = (typeof(d.ca) === 'undefined' ? 0 : d.ca);
        d.tm = (typeof(d.tm) === 'undefined' ? null : (tempUnit == 'C' ? d.tm : convertCtoF(d.tm)));
        d.hp = (typeof(d.hp) === 'undefined' ? 0 : d.hp);
        d.waw = (typeof(d.waw) === 'undefined' ? 0 : d.waw);
        d.sc = (typeof(d.sc) === 'undefined' ? 0 : d.sc);
        d.r = (typeof(d.r) === 'undefined' ? 0 : d.r);
        d.scr = (typeof(d.r) === 'undefined' ? 0 : d.sc - d.r);
        d.prd = (d.sc == 0 ? 0 : 100 * d.r / d.sc);
        d.in = (d.waw == 0 || ftp == null ? null : 100 * d.waw / ftp);
        d.tl = (d.waw == 0 || ftp == null ? null : ((Math.min(d.et, d.mt + 800)) * d.waw * d.in) / (ftp * 3600));
        d.deq = (typeof(d.d) === 'undefined' ? 0 : d.d) + (typeof(d.eg) === 'undefined' ? 0 : d.eg) * 10;
        if (typeof(d.hz) === 'undefined') {
            d.hz1 = 0, d.hz2 = 0, d.hz3 = 0, d.hz4 = 0, d.hz5 = 0;
        } else {
            var hz = d.hz.split(',').map(function(e) {
                return parseInt(e.split('|')[2])
            });
            d.hz1 = hz[0], d.hz2 = hz[1], d.hz3 = hz[2], d.hz4 = hz[3], d.hz5 = hz[4];
        }
        if (typeof(d.pz) === 'undefined') {
            for (var i = 0; i < 11; i++) {
                d['pz' + i] = 0;
            }
        } else {
            var pz = d.pz.split(',').map(function(e) {
                return parseInt(e.split('|')[2])
            });
            for (var i = 0; i < 11; i++) {
                d['pz' + (i + 1)] = pz[i];
            }
        }
        d.pcz1 = 0, d.pcz2 = 0, d.pcz3 = 0, d.pcz4 = 0, d.pcz5 = 0, d.pcz6 = 0;
        if (typeof(d.pcz) !== 'undefined') {
            var pcz = d.pcz.split(',').map(function(e) {
                return parseInt(e.split('|')[2])
            });
            if (pcz[0]) d.pcz1 = pcz[0];
            if (pcz[1]) d.pcz2 = pcz[1];
            if (pcz[2]) d.pcz3 = pcz[2];
            if (pcz[3]) d.pcz4 = pcz[3];
            if (pcz[4]) d.pcz5 = pcz[4]
            if (pcz[5]) d.pcz6 = pcz[5];
        }
        d.trn = d.t == 'VirtualRide' || d.t == 'VirtualRun' ? 1 : d.tr;
        //delete d.tr;

        d.b4 = (typeof(d.b4) === 'undefined' ? null : d.b4);
        d.b1k = (typeof(d.b1k) === 'undefined' ? null : d.b1k);
        d.b5k = (typeof(d.b5k) === 'undefined' ? null : d.b5k);
        d.b10k = (typeof(d.b10k) === 'undefined' ? null : d.b10k);
        d.b15k = (typeof(d.b15k) === 'undefined' ? null : d.b15k);
        d.b20k = (typeof(d.b20k) === 'undefined' ? null : d.b20k);
        d.b30k = (typeof(d.b30k) === 'undefined' ? null : d.b30k);
        d.b50k = (typeof(d.b50k) === 'undefined' ? null : d.b50k);
        d.bh = (typeof(d.bh) === 'undefined' ? null : d.bh);
        d.b1m = (typeof(d.b1m) === 'undefined' ? null : d.b1m);
        d.b2m = (typeof(d.b2m) === 'undefined' ? null : d.b2m);
        d.b10m = (typeof(d.b10m) === 'undefined' ? null : d.b10m);
        d.bhm = (typeof(d.bhm) === 'undefined' ? null : d.bhm);
        d.bmar = (typeof(d.bmar) === 'undefined' ? null : d.bmar);
        if (typeof(d.wt) !== 'undefined' && d.wt != 0 && d.wt != 10) {
            //0 -> ‘default’, 1 -> ‘race’, 2 -> ‘long run’, 3 -> ‘workout’; for rides: 10 -> ‘default’, 11 -> ‘race’, 12 -> ‘workout’
            switch (d.wt) {
                case 1:
                case 11:
                    d.wt = 'Race';
                    break;
                case 2:
                    d.wt = 'Long Run';
                    break;
                case 3:
                case 12:
                    d.wt = 'Workout';
            }
        } else {
            d.wt = '';
        }

        //also do segment defaults fromGAD1

        d.ai = d.i;
        d.as = d.mt == 0 ? 0 : (d.d / d.mt).round(4);
        d.ap = (d.d == 0 || d.mt == 0 ? 0 : (1 / (d.d / d.mt)).round(4));
        d.mp = (d.ms == 0 ? 0 : (1 / d.ms).round(5));
        d.ph = (typeof(d.aw) === 'undefined' || typeof(d.ah) === 'undefined' ? 0 : ((d.waw ? d.waw : d.aw) / d.ah).round(3));
        d.eg = d.t == 'Swim' ? 0 : d.eg;
        d.ed = (d.d == 0 ? 0 : (1000 * d.eg / d.d).round(2));
        d.elt = (d.mt == 0 ? 0 : d.eg / (d.mt * 0.00027778)).round(1);
        d.sh = (d.as == 0 || typeof(d.ah) === 'undefined' ? 0 : (speedMult * d.as / d.ah).round(4));
    });
    cacheAct.filter(function(e) {
        return typeof(e.g) === 'undefined' || e.g == ''
    }).forEach(function(e) {
        e.g = 'n/a'
    });

    gear = d3.values(lGear);

    /*if (typeof(contextAthleteId) !== 'undefined') {
      localStorage['actLength' + contextAthleteId] = cacheAct.length;
    }*/

    if (segCacheReady && actCacheReady) {
        pd_matchActSeg();
        pd_finishUp();
    }
}

function pd_mergeSegArrays() {
    if (tsegDets.length == 0 && typeof(tsegs) !== 'undefined' && ((typeof(tsegs.length) !== 'undefined' && tsegs.filter(function(d) { return d.e != null }).length > 0) || (typeof(tsegs.length) === 'undefined' && d3.values(tsegs).filter(function(d) { return d.e != null }).length > 0))) {
        notYetLoaded('Empty', 'segDets');
        return;
    }
    var l_effs = d3.nest()
        .key(function(d) {
            return d.si;
        })
        .rollup(function(d) {
            return {
                'l': d.length,
                'b': d.sort(function(a, b) {
                    return a.et - b.et
                })[0]
            };
        })
        .map(d3.merge(d3.values(teffs)));

    for (var att in l_effs) {
        if (typeof(tsegs[att]) !== 'undefined') {
            tsegs[att].hr = l_effs[att].b.ah;
            tsegs[att].mh = l_effs[att].b.mh;
            tsegs[att].ac = l_effs[att].b.ac;
            tsegs[att].p = l_effs[att].b.aw;
            tsegs[att].tr = l_effs[att].l;
            tsegs[att].or = l_effs[att].b.or;
            tsegs[att].notPr = 0;
            // also best effort id and time incase PR is private
            if (tsegs[att].e != l_effs[att].b.i) {
                if (tsegs[att].et < l_effs[att].b.et) {
                    // PR has been hidden so remove?
                    //delete tsegs[att];
                } else {
                    if (tsegs[att].et > l_effs[att].b.et) {
                        tsegs[att].notPr = 1;
                        tsegs[att].e = l_effs[att].b.i;
                        tsegs[att].et = l_effs[att].b.et;
                        tsegs[att].ai = l_effs[att].b.ai;
                    }
                }
            }
        }
    }

    // calculate PR placings - this sets the values in teffs :-)
    d3.nest()
        .key(function(d) {
            return d.si
        })
        .rollup(function(d) {
            return d.sort(function(a, b) {
                return (a.et == b.et ? a.i - b.i : a.et - b.et)
            }).forEach(function(e, i) {
                e.pr = i + 1;
                e.prs = (typeof(tsegs[e.si]) === 'undefined' ? null : (tsegs[e.si].tr + 1 - e.pr) * (100 / (tsegs[e.si].tr + 1)));
            })
        })
        .map(d3.merge(d3.values(teffs)));


    for (var att1 in tsegDets) {
        if ((typeof(tsegDets[att1].f) === 'undefined' || tsegDets[att1].f == 2) && typeof(tsegs[att1]) != 'undefined') {
            for (var att in tsegDets[att1]) {
                if (typeof(tsegs[att1]) !== 'undefined') {
                    tsegs[att1][att] = tsegDets[att1][att];
                }
            }
        }
    }

    for (var att in tsegMaps) {
        if (typeof(tsegs[att]) != 'undefined') {
            if (typeof(tsegs[att]) !== 'undefined') {
                tsegs[att].map = tsegMaps[att].map;
            }
        }
    }
    var teffsl = d3.values(teffs).length;
    cacheSeg = d3.values(tsegs).filter(function(d) {
        return typeof(d.t) !== 'undefined' && (teffsl == 0 || typeof(d.tr) !== 'undefined') //&& (d.tac != null || !s_s)
    });
    if (typeof(loggedInAthleteId) !== 'undefined' && loggedInAthleteId == contextAthleteId && !isPRO && typeof(freeIds) !== 'undefined' && freeIds.length > 0) {
        cacheSeg = cacheSeg.slice(0, 250);
    }
    for (var i = 0; i < cacheSeg.length; i++) {
        if (typeof(cacheSeg[i].r) === 'undefined' || cacheSeg[i].r == null) {
            cacheSeg[i].r = -1; //cacheSeg[i].tac;
        }
        if (typeof(cacheSeg[i].ai) === 'undefined' || cacheSeg[i].ai == null) {
            try {
                cacheSeg[i].ai = l_effs[cacheSeg[i].i].b.ai;
                cacheSeg[i].e = l_effs[cacheSeg[i].i].b.i;
                cacheSeg[i].et = l_effs[cacheSeg[i].i].b.et;
            } catch (e) {}
        }
    }

    if (typeof(tsegMaps) !== 'undefined') {
        cacheSeg = cacheSeg.filter(function(d) {
            return typeof(d.map) !== 'undefined'
        });
    }

    if (d3.values(teffs).length > 0) {
        cacheSeg = cacheSeg.filter(function(d) {
            return typeof(d.ai) !== 'undefined' && d.ai != null
        });
    }

    var hasKino = false;
    var kinoSegs = {};
    if (typeof(kino) !== 'undefined' && kino != null) {
        hasKino = true;
        kino.forEach(function(d) {
            kinoSegs[d[1].toString()] = 1;
        });
    }

    cacheSeg.forEach(function(d) {
        d.si = d.i;

        d.sn = d.sn == '' || d.sn == null ? '[no name]' : d.sn;

        d.aw = (typeof(d.aw) === 'undefined' ? 0 : d.aw);
        d.ah = (typeof(d.ar) === 'undefined' ? 0 : d.ar);
        d.mh = (typeof(d.mh) === 'undefined' ? 0 : d.mh);
        d.ac = (typeof(d.ac) === 'undefined' ? 0 : d.ac);
        d.or = s_s ? (typeof(d.or) === 'undefined' ? 0 : d.or) : 0;

        d.if = (starred.indexOf(d.i) > -1 ? 1 : 0);
        d.v = 0;
        d.rp = 0;
        if (d.cc != 'n/a') {
            d.gf = 2 + d.gr / 10;

            d.v = d.ed * 3600 / d.et;
            d.rp = d.v / (d.gf * 100);

            d.bv = d.ed * 3600 / d.bet;
            d.brp = d.bv / (d.gf * 100);
        }
        if (!s_s) {
            d.r = -1;
        }
        if (d.r == 1 && d.et > d.bet) {
            d.r = 2;
        }
        if (d.r == -1 || d.tac == 0) {
            d.r = 0;
            d.s = 0;
        } else {
            d.s = (d.tac + 1 - d.r) * (100 / (d.tac + 1));
        }
        //d.s = 100 * Math.pow(d.s, (Math.pow(0.6 + d.s, 1.5) * 5));
        d.bl = d.et - d.bet;
        d.pbl = Math.min(1000, (d.et * 100 / d.bet) - 100);
        d.as = d.d / d.et;
        d.pa = 1 / d.as;
        d.lc = s_s ? d.r - (typeof(d.lr) === 'undefined' || d.lr <= 0 ? d.r : d.lr) : 0;
        d.drc = s_s ? fDateTime(parseDateTime(typeof(d.drc) !== 'undefined' && d.drc != null ? d.drc * 1000 : (typeof(tacts[d.ai]) !== 'undefined' ? tacts[d.ai].s : new Date()))) : fDateTime(new Date(1970, 0, 1));
        d.gr = +d.gr;
        d.eg = d.eg == 0 && d.gr > 0 ? d.d * d.gr / 100 : d.eg;

        d.k = 0;
        if (hasKino && typeof(kinoSegs[d.i]) !== 'undefined') {
            d.k = 1;
        }
    });
    /*if (typeof(contextAthleteId) !== 'undefined') {
      localStorage['segLength' + contextAthleteId] = cacheSeg.length;
    }*/
    segCacheReady = true;
    if (segCacheReady && actCacheReady) {
        pd_matchActSeg();
        pd_finishUp();
    } else {
        if (actsL && actsPL && bestsL && bestsPL && mapsL && mapsPL & effsL && effsPL && explorerL) {
            pd_mergeActArrays();
        }
    }
}

function pd_matchActSeg() {
    var minStart = d3.min(d3.values(tacts), function(d) {
        return d.s
    });
    if (typeof(minStart) === 'undefined') {
        minStart = '200-01-01 00:00:00';
    }
    cacheSeg.forEach(function(d) {
        if (typeof(tacts[d.ai]) !== 'undefined') {
            d.sd = d3.time.format('%a %b %d %Y %H:%M:%S UTC')(parseDateTime(tacts[d.ai].s));
            d.an = tacts[d.ai].an;
            d.gn = tacts[d.ai].g;
            d.hp = tacts[d.ai].hp;
            d.atc = tacts[d.ai].atc;
            d.apri = tacts[d.ai].p;
            d.co = tacts[d.ai].co;
            d.trn = tacts[d.ai].trn;
            d.tm = tacts[d.ai].tm;
        } else {
            d.sd = d3.time.format('%a %b %d %Y %H:%M:%S UTC')(parseDateTime(minStart)); //d3.time.format('%a %b %d %Y %H:%M:%S UTC')(new Date());
            d.an = 'Go PRO to get PR activity';
            d.gn = 'n/a';
            d.hp = 1;
            d.atc = 1;
            d.apri = 0;
            d.hrftp = 0;
            d.pftp = 0;
            d.co = 0;
            d.trn = 0;
        }
        if (typeof(d.p) !== 'undefined' && /*d.hp == 1 &&*/ d.et >= 60 * 20 && d.p != 0) {
            d.pftp = d.p * Math.min(1, (0.05 / 4) * ((d.et / 60) - 20) / 10 + 0.95);
        } else {
            d.pftp = 0;
        }
        if (typeof(d.hr) !== 'undefined' && d.et >= 60 * 20 && d.hr > 0) {
            d.hrftp = d.hr * Math.min(1, (0.05 / 4) * ((d.et / 60) - 20) / 10 + 0.95);
        } else {
            d.hrftp = 0;
        }
    });
    cacheSeg = cacheSeg.filter(function(d) {
        return typeof(d.sd) !== 'undefined' && (typeof(d.f) === 'undefined' || d.f == 2) //&& d.r > -1
    });

    cacheAct.forEach(function(d) {
        d.segs = (typeof(teffs[d.i]) === 'undefined' ? 0 : teffs[d.i].length);
        d.prs = (typeof(teffs[d.i]) === 'undefined' ? 0 : teffs[d.i].filter(function(e) {
            return e.pr == 1
        }).length);
        d.prs2 = (typeof(teffs[d.i]) === 'undefined' ? 0 : teffs[d.i].filter(function(e) {
            return e.pr == 1
        }).filter(function(e) {
            return typeof(tsegs[e.si]) !== 'undefined' && tsegs[e.si].tr > 1
        }).length);
    })

    if (typeof(cpref) !== 'undefined' && cpref == 'a') {
        cacheAct.forEach(function(d) {
            // segment PRs  3752065|-1|-1,5656919|-1|-1,3522824|-1|-1,1099828|-1|-1
            //d.sp
            if (typeof(teffs[d.i]) !== 'undefined') {
                d.spHtml = teffs[d.i].filter(function(a) {
                    return a.pr == 1 && typeof(tsegs[a.si]) !== 'undefined' && tsegs[a.si].r > 0
                }).sort(function(a, b) {
                    return (tsegs[a.si].r != tsegs[b.si].r ? tsegs[a.si].r - tsegs[b.si].r : tsegs[b.si].tac - tsegs[a.si].tac)
                }).filter(function(e) {
                    return typeof(tsegs[e.si].r) !== 'undefined'
                }).slice(0, 40).map(function(e) {
                    return '<a title="' + suf(tsegs[e.si].r) + ' of ' + tsegs[e.si].tac + ' (Score ' + f2dp(tsegs[e.si].s) + ') - ' + (typeof(tsegs[e.si].sn) === 'undefined' || tsegs[e.si].sn == null ? '' : tsegs[e.si].sn.toString().replace('"', '&quot;')) + '" target="_blank" href="/segments/' + e.si + '"><span class="label" style="background-color:hsla(' + hueScale(100 - tsegs[e.si].s) + ',100%,35%,1)">' + tsegs[e.si].r + '</span></a> '
                }).join('');

                // all segment
                d.sp2Html = teffs[d.i].filter(function(a) {
                    return typeof(tsegs[a.si]) !== 'undefined'
                }).sort(function(a, b) {
                    return (a.pr != b.pr ? a.pr - b.pr : tsegs[b.si].tr - tsegs[a.si].tr)
                }).slice(0, 40).map(function(e) {
                    return '<a title="' + suf(e.pr) + ' of ' + tsegs[e.si].tr + ' (PR Score ' + f2dp(e.prs) + ') - ' + (typeof(tsegs[e.si].sn) === 'undefined' || tsegs[e.si].sn == null ? '' : tsegs[e.si].sn.toString().replace('"', '&quot;')) + '" target="_blank" href="/segments/' + e.si + '"><span class="label" style="background-color:hsla(' + hueScale(100 - e.prs) + ',100%,35%,1)">' + e.pr + '</span></a> '
                    //      return e.si + '|' + e.pr + '|' + tsegs[e.si].tr
                }).join('');
            } else {
                d.spHtml = '';
                d.sp2Html = '';
            }
            if (typeof(teffs[d.i]) === 'undefined') {
                d.prsDist = [];
                d.ksDist = [];
            } else {
                d.prsDist = d3.values(d3.nest().key(function(e) {
                    return Math.floor(e.prs / 10) * 10
                }).rollup(function(e) {
                    return {
                        i: Math.floor(e[0].prs / 10) * 10,
                        l: e.length
                    }
                }).map(teffs[d.i]));

                if (teffs[d.i].length > 0 && s_s) {
                    d.prScoreFull = d3.mean(teffs[d.i], function(d) {
                        return d.prs
                    });
                    d.prScore25 = d3.mean(teffs[d.i].sort(function(a, b) {
                        return b.prs - a.prs
                    }).slice(0, Math.max(1, Math.round(teffs[d.i].length / 4))), function(d) {
                        return d.prs
                    });
                } else {
                    d.prScoreFull = 0;
                    d.prScore25 = 0;
                }

                d.ksDist = d3.values(d3.nest().key(function(e) {
                    return Math.floor(e.prs / 10) * 10
                }).rollup(function(e) {
                    return {
                        i: Math.floor(e[0].prs / 10) * 10,
                        l: e.length
                    }
                }).map(teffs[d.i].filter(function(d) {
                    return d.pr == 1 && typeof(tsegs[d.si]) !== 'undefined'
                }).map(function(d) {
                    return {
                        prs: tsegs[d.si].s
                    }
                }).filter(function(d) {
                    return typeof(d.prs) !== 'undefined'
                })));
            }
        });
    }
}

function pd_finishUp() {
    if (typeof(effsCompSrc) !== 'undefined') {
        effsCL = false;
        var s12 = document.createElement('script');
        s12.src = effsCompSrc;
        s12.async = true;
        s12.onerror = localInit;
        document.getElementsByTagName('head')[0].appendChild(s12);
    } else {
        if (typeof(effsCompData) !== 'undefined') {
            effsCL = false;
            effsLoaded(effsCompData);
        } else {
            localInit();
        }
    }
}
