UNPKG

trackswap

Version:

A powerful and flexible GPX parser and encoder library for Node.js and TypeScript. TrackSwap provides comprehensive support for GPX 1.1 format with advanced features like plugin system, middleware support, and optimized performance.

11 lines 97.3 kB
"use strict";var at=Object.create;var Q=Object.defineProperty;var pt=Object.getOwnPropertyDescriptor;var ct=Object.getOwnPropertyNames;var dt=Object.getPrototypeOf,lt=Object.prototype.hasOwnProperty;var ut=(p,e)=>{for(var t in e)Q(p,t,{get:e[t],enumerable:!0})},je=(p,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ct(e))!lt.call(p,n)&&n!==t&&Q(p,n,{get:()=>e[n],enumerable:!(r=pt(e,n))||r.enumerable});return p};var y=(p,e,t)=>(t=p!=null?at(dt(p)):{},je(e||!p||!p.__esModule?Q(t,"default",{value:p,enumerable:!0}):t,p)),mt=p=>je(Q({},"__esModule",{value:!0}),p);var It={};ut(It,{AbstractSourceConverter:()=>j,ActivityConverter:()=>z,ActivityLapConverter:()=>V,ActivityListConverter:()=>U,AstGenerateProcessor:()=>N,BaseFITMessageConverter:()=>ie,BaseFITMiddleware:()=>se,BaseFITStructurePlugin:()=>v,BaseTCXConverter:()=>T,BaseTCXMiddleware:()=>S,CompleteProcessor:()=>q,ConvertProcessor:()=>Z,CourseStructurePlugin:()=>I,ExtensionsConverter:()=>K,FITDecoder:()=>C,FITEncoder:()=>w,FileHeaderPlugin:()=>F,GPXDecoder:()=>k,GPXEncoder:()=>A,MultiSportSessionConverter:()=>W,PipelineStage:()=>Pe,PositionConverter:()=>G,SessionStructurePlugin:()=>b,TCXDecoder:()=>_,TCXEncoder:()=>D,TCXEnhancementMiddleware:()=>be,TCXPerformanceMiddleware:()=>Ee,TCXPipelineStage:()=>Ve,TCXValidationMiddleware:()=>Se,TokenizeProcessor:()=>Y,TrackConverter:()=>H,TrackSwap:()=>L,TrackpointConverter:()=>B,default:()=>bt,registerDefaultMiddlewares:()=>et,registerDefaultTCXMiddlewares:()=>St});module.exports=mt(It);var ee=class{constructor(){this.stage="parse"}async process(e){let t=Date.now();if(!e.rawData)throw new Error("FIT data cannot be empty");try{let r=await this.parseWithFitSDK(e.rawData);return e.rawMessages=r,e.performance.parseTime=Date.now()-t,e}catch(r){throw new Error(`FIT parsing failed: ${r.message}`)}}async parseWithFitSDK(e){let{Decoder:t,Stream:r}=await import("@garmin/fitsdk"),n=r.fromBuffer(e);if(!t.isFIT(n))throw new Error("Not a valid FIT file");let i=new t(n),{messages:s,errors:o}=i.read();return o&&o.length>0,s}},te=class{constructor(e){this.getConverters=e;this.stage="extract"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Raw messages cannot be empty");let r={};for(let[n,i]of Object.entries(e.rawMessages)){if(!Array.isArray(i)||i.length===0){r[n]=i;continue}let s=this.getConverters(n);if(s.length===0)r[n]=i;else{let o=s[0];try{let a=o.convertMessages(i,e);r[n]=a}catch(a){e.errors.push(a),r[n]=i}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},re=class{constructor(e){this.getStructurePlugins=e;this.stage="structure"}async process(e){let t=Date.now();if(!e.rawMessages)throw new Error("Message data cannot be empty");let r={},n=this.getStructurePlugins();for(let i of n)try{let s=i.structureData(e.rawMessages,e);r={...r,...s}}catch(s){e.errors.push(s)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},ne=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,parseTime:e.performance.parseTime,extractTime:e.performance.extractTime,structureTime:e.performance.structureTime}),e.stats&&(e.stats.endTime=Date.now(),e.rawMessages&&(e.stats.processedTokens=this.countTotalMessages(e.rawMessages))),e}countTotalMessages(e){let t=0;return Object.values(e).forEach(r=>{Array.isArray(r)&&(t+=r.length)}),t}};var g=y(require("dayjs"));var ie=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedMessageTypes.includes(e)}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}parseTimestamp(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}calculateDuration(e,t){if(!e||!t)return 0;let r=new Date(e).getTime(),n=new Date(t).getTime();return Math.max(0,(n-r)/1e3)}filterMessagesByTimeRange(e,t,r,n=2e3){let i=new Date(t).getTime(),s=new Date(r).getTime();return e.filter(o=>{if(!o.timestamp)return!1;let a=new Date(o.timestamp).getTime();return a>=i-n&&a<=s+n})}groupMessagesByLap(e,t){return t.map(r=>{let n=this.filterMessagesByTimeRange(e,r.startTime,r.timestamp);return{lap:r,records:n}})}},v=class{constructor(){this.version="1.0.0";this.priority=100}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}},se=class{constructor(){this.version="1.0.0";this.description="";this.priority=100}async initialize(e){}async destroy(e){}async validate(e){return!0}async onParse(e,t){return e}async onExtractMessages(e,t){return e}async onStructure(e,t){return e}async onComplete(e,t){return e}async onError(e,t){}};var b=class extends v{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:n,lapMesgs:i,recordMesgs:s}=t;return n!=null&&n.length?{sessionMesgs:n.map(a=>{let c=(0,g.default)(a.startTime).valueOf(),d=(0,g.default)(a.timestamp).valueOf(),u=((i==null?void 0:i.filter(f=>{let h=(0,g.default)(f.startTime).valueOf(),O=(0,g.default)(f.timestamp).valueOf();return h>=c&&O<=d}))||[]).map(f=>{let h=(0,g.default)(f.startTime).valueOf(),O=(0,g.default)(f.timestamp).valueOf(),J=(s==null?void 0:s.filter(ot=>{let We=(0,g.default)(ot.timestamp).valueOf();return We>=h&&We<=O}))||[];return{...f,recordMesgs:J}});return{...a,lapMesgs:u}})}:{}}},I=class extends v{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:n,lapMesgs:i,recordMesgs:s}=t;if(!(n!=null&&n.length))return{};let o=2e3;return{courseMesgs:n.map(c=>{let d=(i==null?void 0:i.map(l=>{let u=(0,g.default)(l.startTime).valueOf(),f=(0,g.default)(l.timestamp).valueOf(),h=(s==null?void 0:s.filter(O=>{let J=(0,g.default)(O.timestamp).valueOf();return J>=u-o&&J<=f+o}))||[];return{...l,recordMesgs:h}}))||[];return{...c,lapMesgs:d}})}}},F=class extends v{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:n}=t;if(n!=null&&n.length&&n[0]){let i=n[0];r.fileHeader={type:i.type,manufacturer:i.manufacturer,product:i.product}}return{}}};var C=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.structurePlugins=[];this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultPluginsRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new ee,new te(e=>this.getConverters(e)),new re(()=>this.structurePlugins),new ne]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new F,new b,new I];for(let t of e)this.addStructurePlugin(t),this.registeredPlugins.add(t.name);this.defaultPluginsRegistered=!0}addConverterForMessageType(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((n,i)=>(n.priority||100)-(i.priority||100))}addStructurePlugin(e){this.structurePlugins.push(e),this.structurePlugins.sort((t,r)=>(t.priority||100)-(r.priority||100))}async registerMessageConverter(e){if(this.registeredPlugins.has(e.name))throw new Error(`Message converter plugin ${e.name} already exists`);e.supportedMessageTypes.forEach(r=>{this.addConverterForMessageType(r,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";e.supportedMessageTypes.forEach(r=>{let i=(this.converterPlugins.get(r)||[]).map(s=>`${s.name}(${s.priority||100})`)})}async registerStructurePlugin(e){if(this.registeredPlugins.has(e.name))throw new Error(`Structure plugin ${e.name} already exists`);this.addStructurePlugin(e),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:""}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(n=>n.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((n,i)=>(n.priority||100)-(i.priority||100)));let r=[];e.onParse&&r.push("onParse"),e.onExtractMessages&&r.push("onExtractMessages"),e.onStructure&&r.push("onStructure"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getConverters(e){return this.converterPlugins.get(e)||[]}unregisterPlugin(e){if(!this.registeredPlugins.has(e))return!1;for(let[n,i]of this.converterPlugins){let s=i.findIndex(o=>o.name===e);s!==-1&&(i.splice(s,1),i.length===0&&this.converterPlugins.delete(n))}let t=this.structurePlugins.findIndex(n=>n.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(n=>n.name===e);return r!==-1&&this.middlewarePlugins.splice(r,1),this.registeredPlugins.delete(e),!0}async initialize(){var r;if(this.initialized)return;await this.registerDefaultPlugins();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let n of t)try{await((r=n.initialize)==null?void 0:r.call(n,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.structurePlugins,...this.middlewarePlugins];for(let n of t)try{await((r=n.destroy)==null?void 0:r.call(n,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var i;let n=t;for(let s of this.middlewarePlugins){let o=s[e];if(o)try{n=await o.call(s,n,r)||n}catch(a){r.errors.push(a),await((i=s.onError)==null?void 0:i.call(s,a,r))}}return n}async parseByBuffer(e,t={}){var n;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let i of this.processors)try{switch(r=await i.process(r),i.stage){case"parse":r.rawData&&(r.rawData=await this.executeMiddlewareHook("onParse",r.rawData,r));break;case"extract":r.rawMessages&&(r.rawMessages=await this.executeMiddlewareHook("onExtractMessages",r.rawMessages,r));break;case"structure":r.result&&(r.result=await this.executeMiddlewareHook("onStructure",r.result,r));break;case"complete":r.result&&(r.result=await this.executeMiddlewareHook("onComplete",r.result,r));break}}catch(s){r.errors.push(s);for(let o of this.middlewarePlugins)await((n=o.onError)==null?void 0:n.call(o,s,r))}return r.result||{}}catch(i){throw i}}};var Tt={file:{course:6,device:1,settings:2,sport:3,activity:4,workout:5,schedules:7,weight:9,totals:10,goals:11,blood_pressure:14,monitoring_a:15,activity_summary:20,monitoring_daily:28,monitoring_b:32,segment_list:35,exd_configuration:40,invalid:0},sport:{generic:0,running:1,cycling:2,transition:3,fitness_equipment:4,swimming:5,basketball:6,soccer:7,tennis:8,american_football:9,training:10,walking:11,cross_country_skiing:12,alpine_skiing:13,snowboarding:14,rowing:15,mountaineering:16,hiking:17,multisport:18,paddling:19,invalid:254},event:{timer:0,workout:3,workout_step:4,power_down:5,power_up:6,off_course:7,session:8,lap:9,course_point:10,battery:11,virtual_partner_pace:12,hr_high_alert:13,hr_low_alert:14,speed_high_alert:15,speed_low_alert:16,cad_high_alert:17,cad_low_alert:18,power_high_alert:19,power_low_alert:20,recovery_hr:21,battery_low:22,time_duration_alert:23,distance_duration_alert:24,calorie_duration_alert:25,activity:26,fitness_equipment:27,length:28,user_marker:32,sport_point:33,calibration:36,front_gear_change:42,rear_gear_change:43,rider_position_change:44,elev_high_alert:45,elev_low_alert:46,comm_timeout:47,invalid:255},event_type:{start:0,stop:1,consecutive_depreciated:2,marker:3,stop_all:4,begin_depreciated:5,end_depreciated:6,end_all_depreciated:7,stop_disable:8,stop_disable_all:9,invalid:255},course_point:{generic:0,summit:1,valley:2,water:3,food:4,danger:5,left:6,right:7,straight:8,first_aid:9,fourth_category:10,third_category:11,second_category:12,first_category:13,hors_category:14,sprint:15,left_fork:16,right_fork:17,middle_fork:18,slight_left:19,sharp_left:20,slight_right:21,sharp_right:22,u_turn:23,segment_start:24,segment_end:25,invalid:255}},P=p=>{let e=Tt[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},Re={enum_file:P("file"),enum_activity:P("sport"),enum_sport:P("sport"),enum_sub_sport:P("sport"),enum_event:P("event"),enum_event_type:P("event_type"),enum_course_point:P("course_point"),uint8:{size:1,baseType:2,setValue:DataView.prototype.setUint8},sint8:{size:1,baseType:1,setValue:DataView.prototype.setInt8},uint16:{size:2,baseType:132,setValue:DataView.prototype.setUint16},sint16:{size:2,baseType:131,setValue:DataView.prototype.setInt16},uint32:{size:4,baseType:134,setValue:DataView.prototype.setUint32},sint32:{size:4,baseType:133,setValue:DataView.prototype.setInt32},string:{size:0,baseType:7,mapValue:p=>Array.from(Ye(p)),setValue:gt},distance:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>Math.round(p*1e3)},speed:{size:2,baseType:132,setValue:DataView.prototype.setUint16,mapValue:p=>Math.round(p*100)},altitude:{size:2,baseType:132,setValue:DataView.prototype.setUint16,mapValue:p=>Math.round((p+500)*5)},seconds:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>Math.round(p*1e3)},date_time:{size:4,baseType:134,setValue:DataView.prototype.setUint32,mapValue:p=>{let e;return p instanceof Date?(e=Math.floor(p.getTime()/1e3),e-631065600):typeof p=="string"?(e=Math.floor(new Date(p).getTime()/1e3),e-631065600):p<631065600?Math.floor(p):(p>9999999999?e=Math.floor(p/1e3):e=Math.floor(p),e-631065600)}},semicircles:{size:4,baseType:133,setValue:DataView.prototype.setInt32,mapValue:p=>Math.round(p/180*2147483648)}};function Ke(p){return Array.from(Ye(p)).length+1}function*Ye(p){for(let e of ft(p))e<128?yield e:e<2048?(yield 192|e>>6,yield 128|e&63):e<65536?(yield 224|e>>12,yield 128|e>>6&63,yield 128|e&63):(yield 240|e>>18,yield 128|e>>12&63,yield 128|e>>6&63,yield 128|e&63);yield 0}function*ft(p){for(let e=0;e<p.length;){let t=p.codePointAt(e);if(t===void 0)break;yield t,e+=t>65535?2:1}}function gt(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var ht={file_id:{mesgNum:0,fieldDefns:[{name:"type",number:0,type:"enum_file"},{name:"time_created",number:4,type:"date_time"}]},session:{mesgNum:18,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"start_time",number:2,type:"date_time"},{name:"total_elapsed_time",number:7,type:"seconds"},{name:"total_timer_time",number:8,type:"seconds"},{name:"start_position_lat",number:3,type:"semicircles"},{name:"start_position_long",number:4,type:"semicircles"},{name:"total_distance",number:9,type:"distance"},{name:"total_ascent",number:21,type:"uint16"},{name:"total_descent",number:22,type:"uint16"},{name:"sport",number:5,type:"enum_sport"},{name:"sub_sport",number:6,type:"enum_sub_sport"},{name:"first_lap_index",number:11,type:"uint16"},{name:"num_laps",number:26,type:"uint16"}]},lap:{mesgNum:19,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"start_time",number:2,type:"date_time"},{name:"start_position_lat",number:3,type:"semicircles"},{name:"start_position_long",number:4,type:"semicircles"},{name:"end_position_lat",number:5,type:"semicircles"},{name:"end_position_long",number:6,type:"semicircles"},{name:"total_elapsed_time",number:7,type:"seconds"},{name:"total_timer_time",number:8,type:"seconds"},{name:"total_distance",number:9,type:"distance"},{name:"total_ascent",number:21,type:"uint16"},{name:"total_descent",number:22,type:"uint16"}]},record:{mesgNum:20,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"position_lat",number:0,type:"semicircles"},{name:"position_long",number:1,type:"semicircles"},{name:"altitude",number:2,type:"altitude"},{name:"distance",number:5,type:"distance"},{name:"heart_rate",number:3,type:"uint8"},{name:"cadence",number:4,type:"uint8"},{name:"speed",number:6,type:"speed"},{name:"power",number:7,type:"uint16"}]},event:{mesgNum:21,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"event",number:0,type:"enum_event"},{name:"event_type",number:1,type:"enum_event_type"},{name:"event_group",number:4,type:"uint8"}]},course:{mesgNum:31,fieldDefns:[{name:"name",number:5,type:"string"},{name:"sport",number:4,type:"enum_sport"},{name:"sub_sport",number:7,type:"enum_sub_sport"}]},activity:{mesgNum:34,fieldDefns:[{name:"timestamp",number:253,type:"date_time"},{name:"total_timer_time",number:0,type:"seconds"},{name:"num_sessions",number:1,type:"uint16"},{name:"type",number:2,type:"enum_activity"},{name:"event",number:3,type:"enum_event"},{name:"event_type",number:4,type:"enum_event_type"},{name:"local_timestamp",number:5,type:"date_time"},{name:"event_group",number:6,type:"uint8"}]},course_point:{mesgNum:32,fieldDefns:[{name:"timestamp",number:1,type:"date_time"},{name:"position_lat",number:2,type:"semicircles"},{name:"position_long",number:3,type:"semicircles"},{name:"distance",number:4,type:"distance"},{name:"type",number:5,type:"enum_course_point"}]}},yt=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),oe=class p{static check(e,t,r,n){if(t===void 0)throw new Error(`Message '${e}' not known`);if(r===void 0)throw new Error(`Message '${e}' has no field definitions`);let i=r.map(o=>o.name),s=Object.keys(n).filter(o=>!i.includes(o));if(s.length)throw new Error(`Message '${e}' has no field definitions named '${s}'`)}constructor(e,t,r){let n=ht[t];if(!n)throw new Error(`Unknown message type: ${t}`);let{mesgNum:i,fieldDefns:s}=n;p.check(t,i,s,r),this.localNum=e,this.mesgNum=i,this.fields=yt(s,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:n})=>{let i=Re[r];if(!i)throw new Error(`Unknown type: ${r}`);let{size:s,baseType:o}=i;return r==="string"?{number:t,size:Ke(n),baseType:o}:{number:t,size:s,baseType:o}});return{localNum:this.localNum,mesgNum:this.mesgNum,fieldDefns:e}}isSameDefn(e){let t=(o,a)=>o.number===a.number&&o.size===a.size&&o.baseType===a.baseType,r=(o,a)=>o.length===a.length&&o.every((c,d)=>t(c,a[d])),{localNum:n,mesgNum:i,fieldDefns:s}=this.mesgDefn;return i===e.mesgNum&&n===e.localNum&&r(s,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,n=6+3*r.length,i=new DataView(new ArrayBuffer(n));i.setUint8(0,64|e),i.setUint8(2,1),i.setUint16(3,t),i.setUint8(5,r.length);let s=6;for(let o of r)i.setUint8(s++,o.number),i.setUint8(s++,o.size),i.setUint8(s++,o.baseType);return i.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((i,{size:s})=>i+s,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let n=1;for(let{number:i,type:s,value:o}of this.fields){let a=Re[s];if(!a)throw new Error(`Unknown type: ${s}`);let{size:c,setValue:d}=a,l;"mapValue"in a?l=a.mapValue(o):l=o,d&&d.call(r,n,l),n+=c}return r.buffer}};var vt=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Ne=(p,e)=>(p>>>4^vt[p&15^e])&65535,xt=(p,e,t)=>Ne(Ne(p,e),t),Ct=(p,e)=>xt(p,e&15,e>>>4);function Me(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let n=0;n<r.length;n++)t=Ct(t,r[n]);return t}var qe=y(require("dayjs")),Ze=14,Pt=16,wt=2078,Et=776358228,w=class{constructor(e={}){this.localNum={};this.mesgDefn=[];this.messages=[];this.options={compact:e.compact??!0,defaultSport:e.defaultSport??"cycling",defaultSubSport:e.defaultSubSport??"generic"}}async encode(e){return this.reset(),this.buildFITContent(e,"activity"),Buffer.from(await this.blob.arrayBuffer())}async encodeCourse(e){return this.reset(),this.buildFITContent(e,"course"),Buffer.from(await this.blob.arrayBuffer())}async encodeToBlob(e,t="activity"){return this.reset(),this.buildFITContent(e,t),this.blob}reset(){this.localNum={},this.mesgDefn=[],this.messages=[]}buildFITContent(e,t){this.buildFileId(e,t),t==="course"?this.buildCourseContent(e):this.buildActivityContent(e)}buildActivityContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Activity file must contain at least one Session");let r=0,n=[],i=[];for(let s of t){if(s.lapMesgs&&this.buildEventsFromLaps(s.lapMesgs,n),s.lapMesgs)for(let o of s.lapMesgs)o.recordMesgs&&this.buildRecords(o.recordMesgs);s.lapMesgs&&this.buildLaps(s.lapMesgs),this.buildSession(s),r++,this.buildActivityFromSession(s,i)}n.forEach(s=>this.buildEvent(s)),i.forEach(s=>this.buildActivity(s))}buildCourseContent(e){let t=e.sessionMesgs||[];if(t.length===0)throw new Error("Course file must contain track data");let r=t[0];if(this.buildCourse({name:"course",sport:this.options.defaultSport}),r.lapMesgs){let n=[];for(let o of r.lapMesgs)o.recordMesgs&&n.push(...o.recordMesgs);n.sort((o,a)=>o.timestamp&&a.timestamp?new Date(o.timestamp).getTime()-new Date(a.timestamp).getTime():(o.distance||0)-(a.distance||0));let i=n[0],s=n[n.length-1];i.timestamp&&this.buildEvent({timestamp:i.timestamp,event:"timer",eventType:"start",eventGroup:0}),n.forEach(o=>this.buildRecord(o)),s.timestamp&&this.buildEvent({timestamp:s.timestamp,event:"timer",eventType:"stop_all",eventGroup:0}),r.lapMesgs[0]&&this.buildLap(r.lapMesgs[0])}}buildFileId(e,t){var n;let r=((n=e.fileIdMesgs)==null?void 0:n[0])||{};this.writeMesg("file_id",{type:t,time_created:r.timeCreated?this.parseTimestamp(r.timeCreated):Date.now(),manufacturer:r.manufacturer,product:r.product,serial_number:r.serialNumber})}buildSession(e){var t;this.writeMesg("session",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent,sport:e.sport||this.options.defaultSport,sub_sport:e.subSport||this.options.defaultSubSport,first_lap_index:e.firstLapIndex||0,num_laps:e.numLaps||((t=e.lapMesgs)==null?void 0:t.length)||1})}buildLaps(e){e.forEach(t=>this.buildLap(t))}buildLap(e){this.writeMesg("lap",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,start_time:e.startTime?this.parseTimestamp(e.startTime):void 0,start_position_lat:this.convertToSemicircles(e.startPositionLat),start_position_long:this.convertToSemicircles(e.startPositionLong),end_position_lat:this.convertToSemicircles(e.endPositionLat),end_position_long:this.convertToSemicircles(e.endPositionLong),total_elapsed_time:e.totalElapsedTime,total_timer_time:e.totalTimerTime,total_distance:e.totalDistance,total_ascent:e.totalAscent,total_descent:e.totalDescent})}buildRecords(e){e.forEach(t=>this.buildRecord(t))}buildRecord(e){this.writeMesg("record",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,position_lat:this.convertToSemicircles(e.positionLat),position_long:this.convertToSemicircles(e.positionLong),altitude:e.enhancedAltitude||e.altitude,distance:e.distance,heart_rate:e.heartRate,cadence:e.cadence,speed:e.enhancedSpeed||e.speed,power:e.power})}buildEvent(e){this.writeMesg("event",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,event:e.event,event_type:e.eventType,event_group:e.eventGroup})}buildActivity(e){this.writeMesg("activity",{timestamp:e.timestamp?this.parseTimestamp(e.timestamp):void 0,total_timer_time:e.totalTimerTime,num_sessions:e.numSessions,type:e.type,event:e.event,event_type:e.eventType,local_timestamp:e.localTimestamp?this.parseTimestamp(e.localTimestamp):void 0,event_group:e.eventGroup})}buildCourse(e){this.writeMesg("course",{name:e.name,sport:e.sport})}buildEventsFromLaps(e,t){e.forEach((r,n)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:n}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:n===e.length-1?"stop_all":"stop",eventGroup:n})})}buildActivityFromSession(e,t){t.push({timestamp:e.timestamp,totalTimerTime:e.totalTimerTime,numSessions:1,type:e.sport||this.options.defaultSport,event:"activity",eventType:"stop",eventGroup:0})}parseTimestamp(e){return typeof e=="number"?e:(0,qe.default)(e).valueOf()}convertToSemicircles(e){if(e!=null)return Math.round(e*2**31/180)}validateRequiredFields(e){if(!e.sessionMesgs||e.sessionMesgs.length===0)throw new Error("FIT file must contain at least one Session")}writeMesg(e,t){let r=Object.fromEntries(Object.entries(t).filter(([o,a])=>a!==void 0));if(Object.keys(r).length===0)return;let n=this.localNum[e];n===void 0&&(n=this.localNum[e]=Object.keys(this.localNum).length);let i=new oe(n,e,r),s=this.mesgDefn[n];(!s||!i.isSameDefn(s))&&(this.messages.push(i.defnRecord),this.mesgDefn[n]=i.mesgDefn),this.messages.push(i.dataRecord)}get blob(){let e=[this.header,...this.messages,this.trailer];return new Blob(e,{type:"application/octet-stream"})}get dataLen(){return this.messages.reduce((e,t)=>e+t.byteLength,0)}get dataCrc(){return this.messages.reduce((e,t)=>Me(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(Ze));return e.setUint8(0,Ze),e.setUint8(1,Pt),e.setUint16(2,wt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,Et),e.setUint16(12,Me(e.buffer.slice(0,12)),!0),e.buffer}get trailer(){let e=new DataView(new ArrayBuffer(2));return e.setUint16(0,this.dataCrc,!0),e.buffer}async encoder(e){return this.encode(e)}};var x=class{constructor(){this.version="1.0.0";this.priority=100}supports(e){return this.supportedTags.includes(e)}async initialize(e){e.metadata.set(`plugin:${this.name}:initialized`,!0)}async destroy(e){e.metadata.delete(`plugin:${this.name}:initialized`)}async validate(e){return!0}parseFloat(e){if(!(typeof e>"u"))return typeof e=="number"?e:typeof e=="string"&&parseFloat(e)||0}parseInt(e){return typeof e=="number"?Math.floor(e):typeof e=="string"&&parseInt(e,10)||0}parseString(e){return String(e||"")}parseBoolean(e){return typeof e=="boolean"?e:typeof e=="string"?e.toLowerCase()==="true":!1}parseDate(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}hasRequiredAttributes(e,t){return t.every(r=>{var n;return(n=e.attributes)==null?void 0:n[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([n,i])=>{let s=r[n];s&&s in t&&(t[s]=String(i||""))})}processChildren(e,t,r){var n;(n=e.children)==null||n.forEach(i=>{let s=r[i.tag];s&&s(i,t)})}getChildValue(e,t){var n;let r=(n=e.children)==null?void 0:n.find(i=>i.tag===t);return r!=null&&r.value?String(r.value):void 0}getChildByTag(e,t){var r;return(r=e.children)==null?void 0:r.find(n=>n.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(n=>n.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(n=>{t[n.tag]=this.convertExtensionContent(n)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}else return e.value}},E=class{constructor(){this.version="1.0.0";this.description=""}async initialize(e){}async destroy(e){}async validate(e){return!0}async onTokenize(e,t){return e}async onAstGenerate(e,t){return e}async onConvert(e,t){return e}async onComplete(e,t){return e}async onError(e,t){}};var m=class extends x{parseCoordinate(e){let t=this.parseFloat(e);return t===0?void 0:t}parseGPXTime(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}extractNumericAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([n,i])=>{let s=r[n];s&&s in t&&typeof i<"u"&&(t[s]=this.parseFloat(i))})}},$=class extends E{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var ae=class extends m{constructor(){super(...arguments);this.name="wpt-converter";this.supportedTags=["wpt","trkpt","rtept"];this.version="1.0.0"}convert(t,r){var i,s;if(!this.hasRequiredAttributes(t,["lat","lon"]))return;let n={lat:this.parseFloat((i=t.attributes)==null?void 0:i.lat),lon:this.parseFloat((s=t.attributes)==null?void 0:s.lon)};return this.processChildren(t,n,{ele:(o,a)=>a.ele=this.parseFloat(o.value),time:(o,a)=>a.time=new Date(this.parseString(o.value)),speed:(o,a)=>a.speed=this.parseFloat(o.value),power:(o,a)=>a.power=this.parseFloat(o.value),cadence:(o,a)=>a.cadence=this.parseFloat(o.value),heartRate:(o,a)=>a.heartRate=this.parseFloat(o.value),course:(o,a)=>a.course=this.parseFloat(o.value),name:(o,a)=>a.name=this.parseString(o.value),cmt:(o,a)=>a.cmt=this.parseString(o.value),desc:(o,a)=>a.desc=this.parseString(o.value),src:(o,a)=>a.src=this.parseString(o.value),sym:(o,a)=>a.sym=this.parseString(o.value),type:(o,a)=>a.type=this.parseString(o.value),fix:(o,a)=>a.fix=this.parseString(o.value),sat:(o,a)=>a.sat=this.parseString(o.value),hdop:(o,a)=>a.hdop=this.parseFloat(o.value),vdop:(o,a)=>a.vdop=this.parseFloat(o.value),pdop:(o,a)=>a.pdop=this.parseFloat(o.value),ageofdgpsdata:(o,a)=>a.ageofdgpsdata=this.parseFloat(o.value),geoidheight:(o,a)=>a.geoidheight=this.parseFloat(o.value),magvar:(o,a)=>a.magvar=this.parseFloat(o.value),dgpsid:(o,a)=>a.dgpsid=this.parseFloat(o.value),extensions:(o,a)=>{let c=r.metadata.get("decoder"),d=c==null?void 0:c.getConverter("extensions");if(d){let l=d.convert(o,r);l&&(this.mapExtensionsToPoint(l,a),a.extensions=l)}},link:(o,a)=>{var l;a.link||(a.link=[]);let c=r.metadata.get("decoder"),d=(l=c==null?void 0:c.getConverter("link"))==null?void 0:l.convert(o,r);d&&a.link&&a.link.push(d)}}),n}mapExtensionsToPoint(t,r){Object.entries(t).forEach(([n,i])=>{if(i!==void 0&&(typeof i=="string"||typeof i=="number")){let s=o=>(Array.isArray(o)?o:[o]).some(c=>{let d=n.toLowerCase(),l=c.toLowerCase();return d===l||d.endsWith(`:${l}`)});s("speed")?r.speed=this.parseFloat(i):s("hr")?r.heartRate=this.parseFloat(i):s(["cad","cadence"])?r.cadence=this.parseFloat(i):s(["PowerInWatts","power"])&&(r.power=this.parseFloat(i))}})}},pe=class extends m{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let n={rtept:[]};return this.processChildren(t,n,{name:(i,s)=>s.name=this.parseString(i.value),cmt:(i,s)=>s.cmt=this.parseString(i.value),desc:(i,s)=>s.desc=this.parseString(i.value),src:(i,s)=>s.src=this.parseString(i.value),number:(i,s)=>s.number=this.parseFloat(i.value),type:(i,s)=>s.type=this.parseString(i.value),rtept:(i,s)=>{var c;let o=r.metadata.get("decoder"),a=(c=o==null?void 0:o.getConverter("wpt"))==null?void 0:c.convert(i,r);a&&s.rtept&&s.rtept.push(a)},extensions:(i,s)=>{let o=r.metadata.get("decoder"),a=o==null?void 0:o.getConverter("extensions");a&&(s.extensions=a.convert(i,r))},link:(i,s)=>{var a;s.link||(s.link=[]);let o=r.metadata.get("decoder");(a=i.children)==null||a.forEach(c=>{var l;let d=(l=o==null?void 0:o.getConverter("link"))==null?void 0:l.convert(c,r);d&&s.link&&s.link.push(d)})}}),n}},ce=class extends m{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let n={trkseg:[]};return this.processChildren(t,n,{name:(i,s)=>s.name=this.parseString(i.value),cmt:(i,s)=>s.cmt=this.parseString(i.value),desc:(i,s)=>s.desc=this.parseString(i.value),src:(i,s)=>s.src=this.parseString(i.value),number:(i,s)=>s.number=this.parseFloat(i.value),type:(i,s)=>s.type=this.parseString(i.value),trkseg:(i,s)=>{var c;let o=r.metadata.get("decoder"),a=(c=o==null?void 0:o.getConverter("trkseg"))==null?void 0:c.convert(i,r);a&&s.trkseg&&s.trkseg.push(a)},extensions:(i,s)=>{let o=r.metadata.get("decoder"),a=o==null?void 0:o.getConverter("extensions");a&&(s.extensions=a.convert(i,r))},link:(i,s)=>{var a;s.link||(s.link=[]);let o=r.metadata.get("decoder");(a=i.children)==null||a.forEach(c=>{var l;let d=(l=o==null?void 0:o.getConverter("link"))==null?void 0:l.convert(c,r);d&&s.link&&s.link.push(d)})}}),n}},de=class extends m{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let n={trkpt:[]};return this.processChildren(t,n,{trkpt:(i,s)=>{var c;let o=r.metadata.get("decoder"),a=(c=o==null?void 0:o.getConverter("wpt"))==null?void 0:c.convert(i,r);a&&s.trkpt&&s.trkpt.push(a)},extensions:(i,s)=>{let o=r.metadata.get("decoder"),a=o==null?void 0:o.getConverter("extensions");a&&(s.extensions=a.convert(i,r))}}),n}},le=class extends m{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var i;let n={};return(i=t.attributes)!=null&&i.href&&(n.href=t.attributes.href),this.processChildren(t,n,{text:(s,o)=>o.text=this.parseString(s.value),type:(s,o)=>o.type=this.parseString(s.value)}),n}},ue=class extends m{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let n={};return this.processChildren(t,n,{name:(i,s)=>s.name=this.parseString(i.value),desc:(i,s)=>s.desc=this.parseString(i.value),keywords:(i,s)=>s.keywords=this.parseString(i.value),time:(i,s)=>s.time=new Date(this.parseString(i.value)),author:(i,s)=>{var a;let o=r.metadata.get("decoder");s.author=(a=o==null?void 0:o.getConverter("author"))==null?void 0:a.convert(i,r)},copyright:(i,s)=>{var a;let o=r.metadata.get("decoder");s.copyright=(a=o==null?void 0:o.getConverter("copyright"))==null?void 0:a.convert(i,r)},bounds:(i,s)=>{var a;let o=r.metadata.get("decoder");s.bounds=(a=o==null?void 0:o.getConverter("bounds"))==null?void 0:a.convert(i,r)},extensions:(i,s)=>{let o=r.metadata.get("decoder"),a=o==null?void 0:o.getConverter("extensions");a&&(s.extensions=a.convert(i,r))},link:(i,s)=>{var c;s.link||(s.link=[]);let o=r.metadata.get("decoder"),a=(c=o==null?void 0:o.getConverter("link"))==null?void 0:c.convert(i,r);a&&s.link&&s.link.push(a)}}),n}},me=class extends m{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var i;let n={};return t.value&&!((i=t.children)!=null&&i.length)?(n.name=this.parseString(t.value),n):(this.processChildren(t,n,{name:(s,o)=>o.name=this.parseString(s.value),email:(s,o)=>{var c;let a=r.metadata.get("decoder");o.email=(c=a==null?void 0:a.getConverter("email"))==null?void 0:c.convert(s,r)},link:(s,o)=>{var c;let a=r.metadata.get("decoder");o.link=(c=a==null?void 0:a.getConverter("link"))==null?void 0:c.convert(s,r)}}),n)}},Te=class extends m{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let n={};return this.processChildren(t,n,{id:(i,s)=>s.id=this.parseString(i.value),domain:(i,s)=>s.domain=this.parseString(i.value)}),n}},fe=class extends m{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var i;let n={};return(i=t.attributes)!=null&&i.author&&(n.author=t.attributes.author),this.processChildren(t,n,{year:(s,o)=>o.year=this.parseString(s.value),license:(s,o)=>o.license=this.parseString(s.value)}),n}},ge=class extends m{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let n={};return this.extractAttributes(t,n,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),n}},he=class extends m{constructor(){super(...arguments);this.name="extensions-converter";this.supportedTags=["extensions"]}convert(t,r){var i;let n={};return(i=t.children)==null||i.forEach(s=>{this.flattenExtensionElement(s,n)}),n}flattenExtensionElement(t,r){var n,i;if(!((n=t.children)!=null&&n.length)&&t.value!==void 0){r[t.tag]=this.parseExtensionValue(t.value);return}(i=t.children)!=null&&i.length&&t.children.forEach(s=>{this.flattenExtensionElement(s,r)})}parseExtensionValue(t){if(t===void 0)return;let r=String(t),n=parseFloat(r);return!isNaN(n)&&isFinite(n)?n:r}};var Je=require("htmlparser2"),Pe=(n=>(n.TOKENIZE="tokenize",n.AST_GENERATE="ast_generate",n.CONVERT="convert",n.COMPLETE="complete",n))(Pe||{}),ye=class{constructor(){this.stage="tokenize"}async process(e){let t=Date.now();if(!e.xmlContent)throw new Error("XML content cannot be empty");let r=[],n=new Je.Parser({onopentag(i,s){r.push({type:"open",tag:i,attributes:s})},ontext(i){let s=i.replace(/\n/g,"").trim();s&&r.push({type:"text",tag:"text",value:s})},onclosetag(i){r.push({type:"close",tag:i})}},{xmlMode:!0});return n.write(e.xmlContent),n.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},ve=class{constructor(){this.stage="ast_generate"}async process(e){var s;let t=Date.now();if(!e.tokens)throw new Error("Tokens cannot be empty");let r=[],n,i=null;for(let o of e.tokens)if(o.type==="open"){let a={tag:o.tag,attributes:o.attributes||{},children:[]};n?i&&((s=i.children)==null||s.push(a)):n=a,r.push(a),i=a}else o.type==="text"&&i?i.value=o.value:o.type==="close"&&(r.pop(),i=r[r.length-1]||null);return e.ast=n,e.performance.astTime=Date.now()-t,e}},xe=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var n;let t=Date.now();if(!e.ast)throw new Error("AST cannot be empty");let r={};return e.ast.attributes&&Object.entries(e.ast.attributes).forEach(([i,s])=>{i.startsWith("xmlns:")?r[i]=s.replace(/&#39;/g,"'"):i==="xsi:schemaLocation"?r[i]=s.replace(/&#39;/g,"'"):r[i]=s}),(n=e.ast.children)==null||n.forEach(i=>{let s=this.getConverter(i.tag);try{let o=s.convert(i,e);o&&this.assignResult(r,i.tag,o)}catch(o){e.errors.push(o)}}),e.result=r,e.performance.convertTime=Date.now()-t,e}assignResult(e,t,r){switch(t){case"metadata":e.metadata=r;break;case"wpt":e.wpt||(e.wpt=[]),e.wpt.push(r);break;case"rte":e.rte||(e.rte=[]),e.rte.push(r);break;case"trk":e.trk||(e.trk=[]),e.trk.push(r);break;case"extensions":e.extensions=r;break}}},Ce=class{constructor(){this.stage="complete"}async process(e){e.performance.endTime=Date.now();let t=e.performance.endTime-e.performance.startTime;return e.metadata.set("performance",{totalTime:t,tokenizeTime:e.performance.tokenizeTime,astTime:e.performance.astTime,convertTime:e.performance.convertTime}),e}};var k=class{constructor(){this.converterPlugins=new Map;this.registeredPlugins=new Set;this.middlewarePlugins=[];this.processors=[];this.initialized=!1;this.defaultConvertersRegistered=!1;this.initializePipeline()}initializePipeline(){this.processors=[new ye,new ve,new xe(e=>this.getConverter(e)),new Ce]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new ae,new pe,new ce,new de,new le,new ue,new me,new Te,new fe,new ge,new he];for(let r of e)(t=r.supportedTags)==null||t.forEach(n=>{this.addConverterForTag(n,r)}),this.registeredPlugins.add(r.name);this.defaultConvertersRegistered=!0}addConverterForTag(e,t){this.converterPlugins.has(e)||this.converterPlugins.set(e,[]);let r=this.converterPlugins.get(e);r.push(t),r.sort((n,i)=>(n.priority||100)-(i.priority||100))}async registerConverter(e){var r,i;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(s=>{this.addConverterForTag(s,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(i=e.supportedTags)==null||i.forEach(s=>{let a=(this.converterPlugins.get(s)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(n=>n.name===e.name);t!==-1?this.middlewarePlugins[t]=e:this.middlewarePlugins.push(e);let r=[];e.onTokenize&&r.push("onTokenize"),e.onAstGenerate&&r.push("onAstGenerate"),e.onConvert&&r.push("onConvert"),e.onComplete&&r.push("onComplete"),e.onError&&r.push("onError"),r.length>0}getConverter(e){let t=this.converterPlugins.get(e);return t&&t.length>0?t[0]:void 0}getAllConverters(e){return this.converterPlugins.get(e)||[]}unregisterConverter(e){let t;for(let[r,n]of this.converterPlugins){let i=n.findIndex(s=>s.name===e);i!==-1&&(t=n[i],n.splice(i,1),n.length===0&&this.converterPlugins.delete(r))}t&&this.registeredPlugins.delete(e)}unregisterMiddleware(e){let t=this.middlewarePlugins.findIndex(r=>r.name===e);t!==-1&&this.middlewarePlugins.splice(t,1)}listConverters(){return Array.from(this.converterPlugins.keys())}listConverterPlugins(){return Array.from(this.registeredPlugins)}listMiddlewares(){return this.middlewarePlugins.map(e=>e.name)}listProcessors(){return this.processors.map(e=>e.constructor.name)}getConverterDetails(e){let t={};if(e){let r=this.converterPlugins.get(e);r&&(t[e]=r.map(n=>({name:n.name,priority:n.priority||100})))}else for(let[r,n]of this.converterPlugins)t[r]=n.map(i=>({name:i.name,priority:i.priority||100}));return t}getMiddlewareDetails(){return this.middlewarePlugins.map(e=>{let t=[];return e.onTokenize&&t.push("onTokenize"),e.onAstGenerate&&t.push("onAstGenerate"),e.onConvert&&t.push("onConvert"),e.onComplete&&t.push("onComplete"),e.onError&&t.push("onError"),{name:e.name,hooks:t}})}async initialize(){var r;if(this.initialized)return;await this.registerDefaultConverters();let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let n of t)try{await((r=n.initialize)==null?void 0:r.call(n,e))}catch{}this.initialized=!0}async destroy(){var r;if(!this.initialized)return;let e=this.createContext(),t=[...Array.from(this.converterPlugins.values()).flat(),...this.middlewarePlugins];for(let n of t)try{await((r=n.destroy)==null?void 0:r.call(n,e))}catch{}this.initialized=!1}createContext(){return{metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},performance:{startTime:Date.now()}}}async executeMiddlewareHook(e,t,r){var i;let n=t;for(let s of this.middlewarePlugins){let o=s[e];if(o)try{n=await o.call(s,n,r)||n}catch(a){r.errors.push(a),await((i=s.onError)==null?void 0:i.call(s,a,r))}}return n}async parserByBuffer(e){var r;await this.initialize();let t=this.createContext();t.rawData=e,t.xmlContent=e.toString("utf-8"),t.metadata.set("decoder",this);try{for(let n of this.processors)try{switch(t=await n.process(t),n.stage){case"tokenize":t.tokens&&(t.tokens=await this.executeMiddlewareHook("onTokenize",t.tokens,t));break;case"ast_generate":t.ast&&(t.ast=await this.executeMiddlewareHook("onAstGenerate",t.ast,t));break;case"convert":t.result&&(t.result=await this.executeMiddlewareHook("onConvert",t.result,t));break;case"complete":t.result&&(t.result=await this.executeMiddlewareHook("onComplete",t.result,t));break}}catch(i){t.errors.push(i);for(let s of this.middlewarePlugins)await((r=s.onError)==null?void 0:r.call(s,i,t))}return t.result}catch(n){throw n}}convertExtensions(e){var s,o;let t={},{attributes:r,tag:n,value:i}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(s=e==null?void 0:e.children)!=null&&s.length)(o=e.children)==null||o.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(i!==void 0)return i;return t}};var $e=y(require("dayjs")),Qe=y(require("dayjs/plugin/utc.js"));var Le={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Oe={temperature:"Temperature",Depth:"Depth"};$e.default.extend(Qe.default);var A=class{constructor(e={}){this.formatElevation=e=>{let t=parseFloat(e);return isNaN(t)?e:this.roundTo(t,2).toString()};this.compact=e.compact??!0}async encode(e){let t=this.buildGPXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildGPXXML(e)}buildGPXXML(e){let t=this.buildXMLHeader(),r=this.buildGPXContent(e),i=`${t}${r} </gpx>`;return this.compact?this.compressXML(i):i}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(){return['<?xml version="1.0" encoding="UTF-8"?>','<gpx creator="https://gpxonline.net" version="1.1"',' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'," http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd"," http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"," http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd",' http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd"',' xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"',' xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"',' xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1"',' xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2"',' xmlns="http://www.topografix.com/GPX/1/1">'].join(` `)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:n=[],trk:i=[]}=e,s=[];return t&&s.push(this.buildMetadata(t)),r.forEach(o=>{s.push(this.buildWaypoint(o,"wpt"))}),n.forEach(o=>{s.push(this.buildRoute(o))}),i.forEach(o=>{s.push(this.buildTrack(o))}),s.join(` `)}buildMetadata(e){let t=["<metadata>"];return this.addOptionalElement(t,"name",e.name),this.addOptionalElement(t,"desc",e.desc),e.author&&t.push(this.buildAuthor(e.author)),e.copyright&&t.push(this.buildCopyright(e.copyright)),e.link&&this.addLinks(t,e.link),e.time&&t.push(this.buildTimeElement(e.time)),this.addOptionalElement(t,"keywords",e.keywords),e.bounds&&t.push(this.buildBounds(e.bounds)),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</metadata>"),t.join(` `)}buildAuthor(e){let t=["<author>"];return this.addOptionalElement(t,"name",e.name),e.email&&t.push(`<email id="${this.escapeXML(e.email.id||"")}" domain="${this.escapeXML(e.email.domain||"")}"/>`),e.link&&t.push(this.buildLink(e.link)),t.push("</author>"),t.join(` `)}buildCopyright(e){let t=[`<copyright author="${this.escapeXML(e.author||"")}">`];return this.addOptionalElement(t,"year",e.year),this.addOptionalElement(t,"license",e.license),t.push("</copyright>"),t.join(` `)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),n=this.escapeXMLAttribute((e.maxlat||0).toString()),i=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${n}" maxlon="${i}"/>`}buildWaypoint(e,t){var n,i,s;if(!this.isValidCoordinate(e.lat,e.lon))return"";let r=[`<${t} lat="${this.escapeXMLAttribute(this.formatCoordinate(e.lat))}" lon="${this.escapeXMLAttribute(this.formatCoordinate(e.lon))}">`];if(this.addOptionalElement(r,"ele",(n=e.ele)==null?void 0:n.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(i=e.speed)==null?void 0:i.toString()),this.addOptionalElement(r,"course",(s=e.course)==null?void 0:s.toString()),this.addStandardWaypointElements(r,e),e.extensions){let o=this.processPointExtensions(e,e.extensions);Object.keys(o).length>0&&r.push(this.buildExtensions(o))}return r.push(`</${t}>`),r.join(` `)}addStandardWaypointElements(e,t){var r,n,i,s,o,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(n=t.geoidheight)==null?void 0:n.toString()),this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"sym",t.sym),this.addOptionalElement(e,"type",t.type),this.addOptionalElement(e,"fix",t.fix),this.addOptionalElement(e,"sat",t.sat),this.addOptionalElement(e,"hdop",(i=t.hdop)==null?void 0:i.toString()),this.addOptionalElement(e,"vdop",(s=t.vdop)==null?void 0:s.toString()),this.addOptionalElement(e,"pdop",(o=t.pdop)==null?void 0:o.toString()),this.addOptionalElement(e,"ageofdgpsdata",(a=t.ageofdgpsdata)==null?void 0:a.toString()),this.addOptionalElement(e,"dgpsid",(c=t.dgpsid)==null?void 0:c.toString())}buildRoute(e){var r;let t=["<rte>"];return this.addRouteTrackCommonElements(t,e),e.rtept&&((r=e.rtept)==null||r.forEach(n=>{t.push(this.buildWaypoint(n,"rtept"))})),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</rte>"),t.join(` `)}buildTrack(e){let t=["<trk>"];return this.addRouteTrackCommonElements(t,e),e.trkseg&&e.trkseg.forEach(r=>{t.push(this.buildTrackSegment(r))}),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</trk>"),t.join(` `)}buildTrackSegment(e){let t=["<trkseg>"];return e.trkpt&&e.trkpt.forEach(r=>{t.push(this.buildWaypoint(r,"trkpt"))}),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</trkseg>"),t.join(` `)}addRouteTrackCommonElements(e,t){var r;this.addOptionalElement(e,"name",t.name),this.addOptionalElement(e,"cmt",t.cmt),this.addOptionalElement(e,"desc",t.desc),this.addOptionalElement(e,"src",t.src),t.link&&this.addLinks(e,t.link),this.addOptionalElement(e,"number",(r=t.number)==null?void 0:r.toString()),this.addOptionalElement(e,"type",t.type)}processPointExtensions(e,t){let r={};return Object.entries({"gpxtpx:TrackPointExtension":{"gpxtpx:hr":"heartRate","gpxtpx:cad":"cadence","gpxtpx:speed":"speed","gpxtpx:atemp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:temp":"temperature"},"gpxpx:PowerExtension":{"gpxpx:PowerInWatts":"power"},"gpxx:GpxExtensions":{"gpxx:Temperature":"temperature","gpxx:Depth":"depth"}}).forEach(([i,s])=>{let o={},a=!1;Object.entries(s).forEach(([c,d])=>{let l;if(e[d]!==void 0)l=e[d];else if(t)if(t[c]!==void 0)l=t[c];else{let u=c.split(":").pop();Object.entries(t).forEach(([f,h])=>{f.endsWith(`:${u}`)&&h!==void 0&&(l=h)})}l!==void 0&&(o[c]=l,a=!0)}),a&&(r[i]=o)}),r}buildTrackPointExtension(e,t){let r=this.deepClone(t["gpxtpx:TrackPointExtension"]||{}),n=Object.keys(Le);return Object.keys(e).filter(i=>n.includes(i)).forEach(i=>{let s=Le[i];s&&e[i]!==void 0&&(r[`gpxtpx:${s}`]=e[i])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),n=Object.keys(Oe);return Object.keys(e).filter(i=>n.includes(i)).forEach(i=>{let s=Oe[i];s&&e[i]!==void 0