!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.tcx=e():"undefined"!=typeof global?global.tcx=e():"undefined"!=typeof self&&(self.tcx=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
    var process=require("__browserify_process");// all Y children of X
    function get(x, y) { return x.getElementsByTagName(y); }
    function attr(x, y) { return x.getAttribute(y); }
    function attrf(x, y) { return parseFloat(attr(x, y)); }
    // one Y child of X, if any, otherwise null
    function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
    // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
    function norm(el) { if (el.normalize) { el.normalize(); } return el; }
    // cast array x into numbers
    function numarray(x) {
        for (var j = 0, o = []; j < x.length; j++) o[j] = parseFloat(x[j]);
        return o;
    }
    function clean(x) {
        var o = {};
        for (var i in x) if (x[i]) o[i] = x[i];
        return o;
    }
    // get the content of a text node, if any
    function nodeVal(x) { if (x) {norm(x);} return x && x.firstChild && x.firstChild.nodeValue; }
    function coordPair(x) {
        return numarray([
            nodeVal(get1(x, 'LongitudeDegrees')),
            nodeVal(get1(x, 'LatitudeDegrees')),
        ]);
    }
    function time(x) {
        return nodeVal(get1(x, 'Time'));
    }
    
    // create a new feature collection parent object
    function fc() {
        return {
            type: 'FeatureCollection',
            features: []
        };
    }
    
    var serializer;
    if (typeof XMLSerializer !== 'undefined') {
        serializer = new XMLSerializer();
    // only require xmldom in a node environment
    } else if (typeof exports === 'object' && typeof process === 'object' && !process.browser) {
        serializer = new (require('xmldom').XMLSerializer)();
    }
    
    module.exports = function(doc) {
        var i,
            laps = get(doc, 'Lap'),
            // a feature collection
            gj = fc(),
            totalMeters = 0,
            startTime = '',
            totalSeconds = 0;
    
        gj.properties = {
            totalMeters: 0,
            totalSeconds: 0,
            startTime: ''
        };
    
        for (i = 0; i < laps.length; i++) {
            gj.features.push(getLinestring(laps[i]));
            gj.properties.totalMeters += parseFloat(nodeVal(get1(laps[i], 'DistanceMeters')));
            gj.properties.totalSeconds += parseFloat(nodeVal(get1(laps[i], 'TotalTimeSeconds')));
            gj.properties.startTime += attr(laps[i], 'StartTime');
        }
    
        function getLinestring(node) {
            var j, pts = get(node, 'Trackpoint'), line = [], coordTimes = [], props = getProperties(node);
            for (j = 0; j < pts.length; j++) {
                line.push(coordPair(pts[j]));
                coordTimes.push(time(pts[j]));
                collectProperties(props, pts[j])
            }
            props.coordTimes = coordTimes
            return {
                type: 'Feature',
                properties: props,
                geometry: {
                    type: 'LineString',
                    coordinates: line
                }
            };
        }

        function collectProperties(props, node){
            props = props || {}
            var obj = flattenObject(nodeToObj(node))
            for(var p in obj){
                if(obj.hasOwnProperty(p)){
                    if(props[p] instanceof Array){
                        props[p].push(obj[p])
                    }else if(props[p] === undefined){
                        props[p] = obj[p]
                    }else{
                        props[p] = [props[p]]
                        props[p].push(obj[p])
                    }
                }
            }
        }

        function flattenObject(ob) {
            var toReturn = {};
        
            for (var i in ob) {
                if (!ob.hasOwnProperty(i)) continue;
        
                if ((typeof ob[i]) == 'object') {
                    var flatObject = flattenObject(ob[i]);
                    for (var x in flatObject) {
                        if (!flatObject.hasOwnProperty(x)) continue;
                        toReturn[i + '_' + x] = flatObject[x];
                    }
                } else if(ob[i] instanceof Array) {
                    for (var x = 0; x < ob[i].length; x++) {
                        toReturn[i + '_' + x] = flattenObject(ob[i][x])
                    }
                } else {
                    toReturn[i] = ob[i];
                }
            }
            return toReturn;
        };

        function nodeToObj(node, props){
            var obj = props || {}
            function recur(node, obj){
                var nodeValue = nodeVal(node)
                var nodes = node.childNodes
                if(node.tagName){
                    if(nodes && nodes.length && !(nodes.length === 1 && typeof nodeValue === "string")){// is NodeList fehlt
                        obj[node.tagName] = {}
                        for (var n = 0; n < nodes.length; n++){
                            recur(nodes[n], obj[node.tagName])
                        }
                    }else{
                        obj[node.tagName] = nodeVal(node)
                    }
                }
            }
            recur(node, obj)
            return obj
        }
    
        function getProperties(node) {
            var meta = ['TotalTimeSeconds', 'DistanceMeters', 'Calories',
                'MaximumSpeed'],
                prop = {},
                k;
            for (k = 0; k < meta.length; k++) {
                prop[meta[k]] = parseFloat(nodeVal(get1(node, meta[k])));
            }
            prop.starttime = attr(node, 'StartTime');
            return clean(prop);
        }
        return gj;
    };
    
    },{"__browserify_process":3,"xmldom":2}],2:[function(require,module,exports){
    
    },{}],3:[function(require,module,exports){
    // shim for using process in browser
    
    var process = module.exports = {};
    
    process.nextTick = (function () {
        var canSetImmediate = typeof window !== 'undefined'
        && window.setImmediate;
        var canPost = typeof window !== 'undefined'
        && window.postMessage && window.addEventListener
        ;
    
        if (canSetImmediate) {
            return function (f) { return window.setImmediate(f) };
        }
    
        if (canPost) {
            var queue = [];
            window.addEventListener('message', function (ev) {
                if (ev.source === window && ev.data === 'process-tick') {
                    ev.stopPropagation();
                    if (queue.length > 0) {
                        var fn = queue.shift();
                        fn();
                    }
                }
            }, true);
    
            return function nextTick(fn) {
                queue.push(fn);
                window.postMessage('process-tick', '*');
            };
        }
    
        return function nextTick(fn) {
            setTimeout(fn, 0);
        };
    })();
    
    process.title = 'browser';
    process.browser = true;
    process.env = {};
    process.argv = [];
    
    process.binding = function (name) {
        throw new Error('process.binding is not supported');
    }
    
    // TODO(shtylman)
    process.cwd = function () { return '/' };
    process.chdir = function (dir) {
        throw new Error('process.chdir is not supported');
    };
    
    },{}]},{},[1])
    (1)
    });