trackswap 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +328 -281
  2. package/dist/FIT/base.d.ts +0 -30
  3. package/dist/FIT/decoder.d.ts +0 -48
  4. package/dist/FIT/encoder.d.ts +0 -97
  5. package/dist/FIT/mesg.d.ts +0 -3
  6. package/dist/FIT/middleware.d.ts +0 -15
  7. package/dist/FIT/plugins.d.ts +0 -9
  8. package/dist/FIT/processor.d.ts +0 -24
  9. package/dist/FIT/types/mesg_num.d.ts +102 -102
  10. package/dist/FIT/types/sport.d.ts +44 -44
  11. package/dist/FIT/types.d.ts +0 -35
  12. package/dist/GPX/base.d.ts +6 -50
  13. package/dist/GPX/converters.d.ts +0 -30
  14. package/dist/GPX/decoder.d.ts +0 -66
  15. package/dist/GPX/encoder.d.ts +0 -109
  16. package/dist/GPX/middleware.d.ts +0 -9
  17. package/dist/GPX/processor.d.ts +0 -18
  18. package/dist/GPX/types.d.ts +0 -108
  19. package/dist/TCX/base.d.ts +0 -33
  20. package/dist/TCX/converters.d.ts +0 -24
  21. package/dist/TCX/decoder.d.ts +0 -54
  22. package/dist/TCX/encoder.d.ts +0 -109
  23. package/dist/TCX/index.d.ts +4 -2
  24. package/dist/TCX/middleware.d.ts +11 -13
  25. package/dist/TCX/processor.d.ts +13 -21
  26. package/dist/TCX/types.d.ts +1 -13
  27. package/dist/TrackSwap.d.ts +37 -33
  28. package/dist/core/base.d.ts +0 -46
  29. package/dist/core/xml-utils.d.ts +0 -24
  30. package/dist/index.cjs +26 -0
  31. package/dist/index.js +26 -5
  32. package/dist/sport/base.d.ts +64 -0
  33. package/dist/sport/converters.d.ts +33 -0
  34. package/dist/sport/encoders.d.ts +34 -0
  35. package/dist/sport/index.d.ts +17 -0
  36. package/dist/sport/processor.d.ts +19 -0
  37. package/dist/types.d.ts +91 -13
  38. package/package.json +23 -5
  39. package/dist/FIT/base.js +0 -101
  40. package/dist/FIT/crc.js +0 -16
  41. package/dist/FIT/decoder.js +0 -323
  42. package/dist/FIT/encoder.js +0 -445
  43. package/dist/FIT/index.js +0 -13
  44. package/dist/FIT/mesg.js +0 -208
  45. package/dist/FIT/middleware.js +0 -206
  46. package/dist/FIT/plugins.js +0 -104
  47. package/dist/FIT/processor.js +0 -170
  48. package/dist/FIT/types/course_point.js +0 -58
  49. package/dist/FIT/types/event.js +0 -50
  50. package/dist/FIT/types/event_type.js +0 -19
  51. package/dist/FIT/types/file.js +0 -24
  52. package/dist/FIT/types/index.js +0 -297
  53. package/dist/FIT/types/mesg_num.js +0 -106
  54. package/dist/FIT/types/sport.js +0 -48
  55. package/dist/FIT/types.js +0 -1
  56. package/dist/FIT/util.js +0 -7
  57. package/dist/GPX/base.js +0 -56
  58. package/dist/GPX/converters.js +0 -352
  59. package/dist/GPX/decoder.js +0 -409
  60. package/dist/GPX/encoder.js +0 -513
  61. package/dist/GPX/extensions/index.js +0 -14
  62. package/dist/GPX/index.js +0 -11
  63. package/dist/GPX/middleware.js +0 -93
  64. package/dist/GPX/processor.js +0 -188
  65. package/dist/GPX/types.js +0 -1
  66. package/dist/GPX/util.js +0 -18
  67. package/dist/TCX/base.js +0 -62
  68. package/dist/TCX/converters.js +0 -333
  69. package/dist/TCX/decoder.js +0 -350
  70. package/dist/TCX/encoder.js +0 -513
  71. package/dist/TCX/index.js +0 -9
  72. package/dist/TCX/middleware.js +0 -93
  73. package/dist/TCX/processor.js +0 -197
  74. package/dist/TCX/types.js +0 -1
  75. package/dist/TrackSwap.js +0 -84
  76. package/dist/core/base.js +0 -138
  77. package/dist/core/decoder.d.ts +0 -66
  78. package/dist/core/decoder.js +0 -90
  79. package/dist/core/index.js +0 -4
  80. package/dist/core/processor.d.ts +0 -69
  81. package/dist/core/processor.js +0 -265
  82. package/dist/core/xml-utils.js +0 -140
  83. package/dist/types.js +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,26 @@
1
- import { TrackSwap } from "./TrackSwap.js";
2
- import GPXManager from "./GPX/index.js";
3
- export { TrackSwap, };
4
- export { GPXManager };
5
- export default TrackSwap;
1
+ var h=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){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 i;return(i=e.attributes)==null?void 0:i[r]})}extractAttributes(e,t,r){e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{let o=r[i];o&&o in t&&(t[o]=String(n||""))})}processChildren(e,t,r){var i;(i=e.children)==null||i.forEach(n=>{let o=r[n.tag];o&&o(n,t)})}getChildValue(e,t){var i;let r=(i=e.children)==null?void 0:i.find(n=>n.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(i=>i.tag===t)}getChildrenByTag(e,t){var r;return((r=e.children)==null?void 0:r.filter(i=>i.tag===t))||[]}convertExtensions(e){var r;let t={};return(r=e.children)==null||r.forEach(i=>{t[i.tag]=this.convertExtensionContent(i)}),t}convertExtensionContent(e){var t;if((t=e.children)!=null&&t.length){let r={};return e.children.forEach(i=>{r[i.tag]=this.convertExtensionContent(i)}),r}else return e.value}},x=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 u=class extends h{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(([i,n])=>{let o=r[i];o&&o in t&&typeof n<"u"&&(t[o]=this.parseFloat(n))})}},A=class extends x{async onError(e,t){t.warnings.push(`Middleware ${this.name} error: ${e.message}`)}};var O=class extends u{constructor(){super(...arguments);this.name="wpt-converter";this.supportedTags=["wpt","trkpt","rtept"];this.version="1.0.0"}convert(t,r){if(!this.hasRequiredAttributes(t,["lat","lon"]))return;let i={lat:this.parseFloat(t.attributes.lat),lon:this.parseFloat(t.attributes.lon)};return this.extractAttributes(t,i,{lat:"lat",lon:"lon"}),this.processChildren(t,i,{ele:(n,o)=>o.ele=this.parseFloat(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),speed:(n,o)=>o.speed=this.parseFloat(n.value),course:(n,o)=>o.course=this.parseFloat(n.value),name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),sym:(n,o)=>o.sym=this.parseString(n.value),type:(n,o)=>o.type=this.parseString(n.value),fix:(n,o)=>o.fix=this.parseString(n.value),sat:(n,o)=>o.sat=this.parseString(n.value),hdop:(n,o)=>o.hdop=this.parseFloat(n.value),vdop:(n,o)=>o.vdop=this.parseFloat(n.value),pdop:(n,o)=>o.pdop=this.parseFloat(n.value),ageofdgpsdata:(n,o)=>o.ageofdgpsdata=this.parseFloat(n.value),geoidheight:(n,o)=>o.geoidheight=this.parseFloat(n.value),magvar:(n,o)=>o.magvar=this.parseFloat(n.value),dgpsid:(n,o)=>o.dgpsid=this.parseFloat(n.value),extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},$=class extends u{constructor(){super(...arguments);this.name="rte-converter";this.supportedTags=["rte"]}convert(t,r){let i={rtept:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),rtept:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.rtept&&o.rtept.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},G=class extends u{constructor(){super(...arguments);this.name="trk-converter";this.supportedTags=["trk"]}convert(t,r){let i={trkseg:[]};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),cmt:(n,o)=>o.cmt=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),src:(n,o)=>o.src=this.parseString(n.value),number:(n,o)=>o.number=this.parseFloat(n.value),type:(n,o)=>o.type=this.parseString(n.value),trkseg:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("trkseg"))==null?void 0:c.convert(n,r);a&&o.trkseg&&o.trkseg.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var a;o.link||(o.link=[]);let s=r.metadata.get("decoder");(a=n.children)==null||a.forEach(c=>{var l;let d=(l=s==null?void 0:s.getConverter("link"))==null?void 0:l.convert(c,r);d&&o.link&&o.link.push(d)})}}),i}},B=class extends u{constructor(){super(...arguments);this.name="trkseg-converter";this.supportedTags=["trkseg"]}convert(t,r){let i={trkpt:[]};return this.processChildren(t,i,{trkpt:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("wpt"))==null?void 0:c.convert(n,r);a&&o.trkpt&&o.trkpt.push(a)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))}}),i}},H=class extends u{constructor(){super(...arguments);this.name="link-converter";this.supportedTags=["link"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.href&&(i.href=t.attributes.href),this.processChildren(t,i,{text:(o,s)=>s.text=this.parseString(o.value),type:(o,s)=>s.type=this.parseString(o.value)}),i}},z=class extends u{constructor(){super(...arguments);this.name="metadata-converter";this.supportedTags=["metadata"]}convert(t,r){let i={};return this.processChildren(t,i,{name:(n,o)=>o.name=this.parseString(n.value),desc:(n,o)=>o.desc=this.parseString(n.value),keywords:(n,o)=>o.keywords=this.parseString(n.value),time:(n,o)=>o.time=new Date(this.parseString(n.value)),author:(n,o)=>{var a;let s=r.metadata.get("decoder");o.author=(a=s==null?void 0:s.getConverter("author"))==null?void 0:a.convert(n,r)},copyright:(n,o)=>{var a;let s=r.metadata.get("decoder");o.copyright=(a=s==null?void 0:s.getConverter("copyright"))==null?void 0:a.convert(n,r)},bounds:(n,o)=>{var a;let s=r.metadata.get("decoder");o.bounds=(a=s==null?void 0:s.getConverter("bounds"))==null?void 0:a.convert(n,r)},extensions:(n,o)=>{let s=r.metadata.get("decoder");s&&(o.extensions=s.convertExtensions(n))},link:(n,o)=>{var c;o.link||(o.link=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("link"))==null?void 0:c.convert(n,r);a&&o.link&&o.link.push(a)}}),i}},V=class extends u{constructor(){super(...arguments);this.name="person-converter";this.supportedTags=["author"]}convert(t,r){var n;let i={};return t.value&&!((n=t.children)!=null&&n.length)?(i.name=this.parseString(t.value),i):(this.processChildren(t,i,{name:(o,s)=>s.name=this.parseString(o.value),email:(o,s)=>{var c;let a=r.metadata.get("decoder");s.email=(c=a==null?void 0:a.getConverter("email"))==null?void 0:c.convert(o,r)},link:(o,s)=>{var c;let a=r.metadata.get("decoder");s.link=(c=a==null?void 0:a.getConverter("link"))==null?void 0:c.convert(o,r)}}),i)}},U=class extends u{constructor(){super(...arguments);this.name="email-converter";this.supportedTags=["email"]}convert(t,r){let i={};return this.processChildren(t,i,{id:(n,o)=>o.id=this.parseString(n.value),domain:(n,o)=>o.domain=this.parseString(n.value)}),i}},W=class extends u{constructor(){super(...arguments);this.name="copyright-converter";this.supportedTags=["copyright"]}convert(t,r){var n;let i={};return(n=t.attributes)!=null&&n.author&&(i.author=t.attributes.author),this.processChildren(t,i,{year:(o,s)=>s.year=this.parseString(o.value),license:(o,s)=>s.license=this.parseString(o.value)}),i}},j=class extends u{constructor(){super(...arguments);this.name="bounds-converter";this.supportedTags=["bounds"]}convert(t,r){let i={};return this.extractAttributes(t,i,{minlat:"minlat",minlon:"minlon",maxlat:"maxlat",maxlon:"maxlon"}),i}};import{Parser as Ue}from"htmlparser2";var N=(i=>(i.TOKENIZE="tokenize",i.AST_GENERATE="ast_generate",i.CONVERT="convert",i.COMPLETE="complete",i))(N||{}),K=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=[],i=new Ue({onopentag(n,o){r.push({type:"open",tag:n,attributes:o})},ontext(n){let o=n.replace(/\n/g,"").trim();o&&r.push({type:"text",tag:"text",value:o})},onclosetag(n){r.push({type:"close",tag:n})}},{xmlMode:!0});return i.write(e.xmlContent),i.end(),e.tokens=r,e.performance.tokenizeTime=Date.now()-t,e}},Y=class{constructor(){this.stage="ast_generate"}async process(e){var o;let t=Date.now();if(!e.tokens)throw new Error("Tokens cannot be empty");let r=[],i,n=null;for(let s of e.tokens)if(s.type==="open"){let a={tag:s.tag,attributes:s.attributes||{},children:[]};i?n&&((o=n.children)==null||o.push(a)):i=a,r.push(a),n=a}else s.type==="text"&&n?n.value=s.value:s.type==="close"&&(r.pop(),n=r[r.length-1]||null);return e.ast=i,e.performance.astTime=Date.now()-t,e}},Z=class{constructor(e){this.getConverter=e;this.stage="convert"}async process(e){var i;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(([n,o])=>{n.startsWith("xmlns:")?r[n]=o.replace(/&#39;/g,"'"):n==="xsi:schemaLocation"?r[n]=o.replace(/&#39;/g,"'"):r[n]=o}),(i=e.ast.children)==null||i.forEach(n=>{let o=this.getConverter(n.tag);try{let s=o.convert(n,e);s&&this.assignResult(r,n.tag,s)}catch(s){e.errors.push(s)}}),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}}},q=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 C=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 K,new Y,new Z(e=>this.getConverter(e)),new q]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new O,new $,new G,new B,new H,new z,new V,new U,new W,new j];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,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((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.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,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.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(i=>({name:i.name,priority:i.priority||100})))}else for(let[r,i]of this.converterPlugins)t[r]=i.map(n=>({name:n.name,priority:n.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 i of t)try{await((r=i.initialize)==null?void 0:r.call(i,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 i of t)try{await((r=i.destroy)==null?void 0:r.call(i,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 n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}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 i of this.processors)try{switch(t=await i.process(t),i.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(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}};import _e from"dayjs";import We from"dayjs/plugin/utc.js";var we={temperature:"atemp",wtemp:"wtemp",heartRate:"hr",cadence:"cad"};var Se={temperature:"Temperature",Depth:"Depth"};_e.extend(We);var P=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),n=`${t}${r}
2
+ </gpx>`;return this.compact?this.compressXML(n):n}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(`
3
+ `)}buildGPXContent(e){let{metadata:t,wpt:r=[],rte:i=[],trk:n=[]}=e,o=[];return t&&o.push(this.buildMetadata(t)),r.forEach(s=>{o.push(this.buildWaypoint(s,"wpt"))}),i.forEach(s=>{o.push(this.buildRoute(s))}),n.forEach(s=>{o.push(this.buildTrack(s))}),o.join(`
4
+ `)}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(`
5
+ `)}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(`
6
+ `)}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(`
7
+ `)}buildBounds(e){let t=this.escapeXMLAttribute((e.minlat||0).toString()),r=this.escapeXMLAttribute((e.minlon||0).toString()),i=this.escapeXMLAttribute((e.maxlat||0).toString()),n=this.escapeXMLAttribute((e.maxlon||0).toString());return`<bounds minlat="${t}" minlon="${r}" maxlat="${i}" maxlon="${n}"/>`}buildWaypoint(e,t){var i,n,o;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",(i=e.ele)==null?void 0:i.toString(),this.formatElevation),e.time&&r.push(this.buildTimeElement(e.time)),this.addOptionalElement(r,"speed",(n=e.speed)==null?void 0:n.toString()),this.addOptionalElement(r,"course",(o=e.course)==null?void 0:o.toString()),this.addStandardWaypointElements(r,e),e.extensions){let s=this.processPointExtensions(e,e.extensions);Object.keys(s).length>0&&r.push(this.buildExtensions(s))}return r.push(`</${t}>`),r.join(`
8
+ `)}addStandardWaypointElements(e,t){var r,i,n,o,s,a,c;this.addOptionalElement(e,"magvar",(r=t.magvar)==null?void 0:r.toString()),this.addOptionalElement(e,"geoidheight",(i=t.geoidheight)==null?void 0:i.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",(n=t.hdop)==null?void 0:n.toString()),this.addOptionalElement(e,"vdop",(o=t.vdop)==null?void 0:o.toString()),this.addOptionalElement(e,"pdop",(s=t.pdop)==null?void 0:s.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(i=>{t.push(this.buildWaypoint(i,"rtept"))})),e.extensions&&t.push(this.buildExtensions(e.extensions)),t.push("</rte>"),t.join(`
9
+ `)}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(`
10
+ `)}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(`
11
+ `)}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=this.deepClone(t),i=this.buildTrackPointExtension(e,t);Object.keys(i).length>0&&(r["gpxtpx:TrackPointExtension"]=i);let n=this.buildPowerExtension(e,t);Object.keys(n).length>0&&(r["gpxpx:PowerExtension"]=n);let o=this.buildGpxExtensions(e,t);return Object.keys(o).length>0&&(r["gpxx:GpxExtensions"]=o),r}buildTrackPointExtension(e,t){let r=this.deepClone(t["gpxtpx:TrackPointExtension"]||{}),i=Object.keys(we);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=we[n];o&&e[n]!==void 0&&(r[`gpxtpx:${o}`]=e[n])}),r}buildPowerExtension(e,t){return this.deepClone(t["gpxpx:PowerExtension"]||{})}buildGpxExtensions(e,t){let r=this.deepClone(t["gpxx:GpxExtensions"]||{}),i=Object.keys(Se);return Object.keys(e).filter(n=>i.includes(n)).forEach(n=>{let o=Se[n];o&&e[n]!==void 0&&(r[`gpxx:${o}`]=e[n])}),r}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<extensions>${t}</extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}buildLink(e){let t=[`<link href="${this.escapeXMLAttribute(e.href||"")}">`];return this.addOptionalElement(t,"text",e.text),this.addOptionalElement(t,"type",e.type),t.push("</link>"),t.join("")}addLinks(e,t){(Array.isArray(t)?t:[t]).forEach(i=>{e.push(this.buildLink(i))})}buildTimeElement(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?$/.test(e)?`<time>${e}</time>`:`<time>${_e(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}</time>`}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var be=class extends A{constructor(){super(...arguments);this.name="performance-middleware";this.description="Monitor parsing performance"}async onTokenize(t,r){return t}async onAstGenerate(t,r){let i=this.countNodes(t);return t}async onComplete(t,r){let i=r.metadata.get("performance");return t}countNodes(t){let r=1;if(t.children)for(let i of t.children)r+=this.countNodes(i);return r}},Ie=class extends A{constructor(){super(...arguments);this.name="validation-middleware";this.description="Validate GPX data integrity"}async onComplete(t,r){let i=this.validateGPX(t);return i.length>0&&r.metadata.set("validation-errors",i),t}validateGPX(t){let r=[];if(t.version||r.push("Missing GPX version information"),t.creator||r.push("Missing GPX creator information"),t.trk){for(let i of t.trk)if(i.trkseg){for(let n of i.trkseg)if(n.trkpt)for(let o of n.trkpt)(typeof o.lat!="number"||typeof o.lon!="number")&&r.push("Invalid track point coordinates")}}return r}};async function Xe(p){let e=[new be,new Ie];for(let t of e)await p.registerMiddleware(t)}var je={GPXDecoder:C,GPXEncoder:P,registerDefaultMiddlewares:Xe,PipelineStage:N};var J=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"),i=r.fromBuffer(e);if(!t.isFIT(i))throw new Error("Not a valid FIT file");let n=new t(i),{messages:o,errors:s}=n.read();return s&&s.length>0,o}},Q=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[i,n]of Object.entries(e.rawMessages)){if(!Array.isArray(n)||n.length===0){r[i]=n;continue}let o=this.getConverters(i);if(o.length===0)r[i]=n;else{let s=o[0];try{let a=s.convertMessages(n,e);r[i]=a}catch(a){e.errors.push(a),r[i]=n}}}return e.rawMessages=r,e.performance.extractTime=Date.now()-t,e}},ee=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={},i=this.getStructurePlugins();for(let n of i)try{let o=n.structureData(e.rawMessages,e);r={...r,...o}}catch(o){e.errors.push(o)}return e.result=r,e.performance.structureTime=Date.now()-t,e}},te=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}};import T from"dayjs";var y=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}};var D=class extends y{constructor(){super(...arguments);this.name="SessionStructurePlugin";this.priority=10}structureData(t,r){let{sessionMesgs:i,lapMesgs:n,recordMesgs:o}=t;return i!=null&&i.length?{sessionMesgs:i.map(a=>{let c=T(a.startTime).valueOf(),d=T(a.timestamp).valueOf(),f=((n==null?void 0:n.filter(g=>{let k=T(g.startTime).valueOf(),F=T(g.timestamp).valueOf();return k>=c&&F<=d}))||[]).map(g=>{let k=T(g.startTime).valueOf(),F=T(g.timestamp).valueOf(),L=(o==null?void 0:o.filter(Ve=>{let De=T(Ve.timestamp).valueOf();return De>=k&&De<=F}))||[];return{...g,recordMesgs:L}});return{...a,lapMesgs:f}})}:{}}},_=class extends y{constructor(){super(...arguments);this.name="CourseStructurePlugin";this.priority=10}structureData(t,r){let{courseMesgs:i,lapMesgs:n,recordMesgs:o}=t;if(!(i!=null&&i.length))return{};let s=2e3;return{courseMesgs:i.map(c=>{let d=(n==null?void 0:n.map(l=>{let f=T(l.startTime).valueOf(),g=T(l.timestamp).valueOf(),k=(o==null?void 0:o.filter(F=>{let L=T(F.timestamp).valueOf();return L>=f-s&&L<=g+s}))||[];return{...l,recordMesgs:k}}))||[];return{...c,lapMesgs:d}})}}},X=class extends y{constructor(){super(...arguments);this.name="FileHeaderPlugin";this.priority=1}structureData(t,r){let{fileIdMesgs:i}=t;if(i!=null&&i.length&&i[0]){let n=i[0];r.fileHeader={type:n.type,manufacturer:n.manufacturer,product:n.product}}return{}}};var E=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 J,new Q(e=>this.getConverters(e)),new ee(()=>this.structurePlugins),new te]}async registerDefaultPlugins(){if(this.defaultPluginsRegistered)return;let e=[new X,new D,new _];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((i,n)=>(i.priority||100)-(n.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 n=(this.converterPlugins.get(r)||[]).map(o=>`${o.name}(${o.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(i=>i.name===e.name);t!==-1?this.middlewarePlugins[t]=e:(this.middlewarePlugins.push(e),this.middlewarePlugins.sort((i,n)=>(i.priority||100)-(n.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[i,n]of this.converterPlugins){let o=n.findIndex(s=>s.name===e);o!==-1&&(n.splice(o,1),n.length===0&&this.converterPlugins.delete(i))}let t=this.structurePlugins.findIndex(i=>i.name===e);t!==-1&&this.structurePlugins.splice(t,1);let r=this.middlewarePlugins.findIndex(i=>i.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 i of t)try{await((r=i.initialize)==null?void 0:r.call(i,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 i of t)try{await((r=i.destroy)==null?void 0:r.call(i,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 n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(e,t={}){var i;await this.initialize();let r=this.createContext();r.rawData=e,r.userData=t.userData,r.metadata.set("decoder",this);try{for(let n of this.processors)try{switch(r=await n.process(r),n.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(o){r.errors.push(o);for(let s of this.middlewarePlugins)await((i=s.onError)==null?void 0:i.call(s,o,r))}return r.result||{}}catch(n){throw n}}};var Ke={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}},v=p=>{let e=Ke[p];return{size:1,baseType:0,mapValue:t=>typeof t=="string"?e[t]??255:t,setValue:function(t,r){this.setUint8(t,r)}}},ke={enum_file:v("file"),enum_activity:v("sport"),enum_sport:v("sport"),enum_sub_sport:v("sport"),enum_event:v("event"),enum_event_type:v("event_type"),enum_course_point:v("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(Me(p)),setValue:Ze},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 Re(p){return Array.from(Me(p)).length+1}function*Me(p){for(let e of Ye(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*Ye(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 Ze(p,e){for(let t=0;t<e.length;t++)this.setUint8(p+t,e[t])}var qe={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"}]}},Ne=(p,e)=>p.map(t=>({...t,value:e[t.name]})).filter(({value:t})=>t!==void 0),re=class p{static check(e,t,r,i){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 n=r.map(s=>s.name),o=Object.keys(i).filter(s=>!n.includes(s));if(o.length)throw new Error(`Message '${e}' has no field definitions named '${o}'`)}constructor(e,t,r){let i=qe[t];if(!i)throw new Error(`Unknown message type: ${t}`);let{mesgNum:n,fieldDefns:o}=i;p.check(t,n,o,r),this.localNum=e,this.mesgNum=n,this.fields=Ne(o,r)}get mesgDefn(){let e=this.fields.map(({number:t,type:r,value:i})=>{let n=ke[r];if(!n)throw new Error(`Unknown type: ${r}`);let{size:o,baseType:s}=n;return r==="string"?{number:t,size:Re(i),baseType:s}:{number:t,size:o,baseType:s}});return{localNum:this.localNum,mesgNum:this.mesgNum,fieldDefns:e}}isSameDefn(e){let t=(s,a)=>s.number===a.number&&s.size===a.size&&s.baseType===a.baseType,r=(s,a)=>s.length===a.length&&s.every((c,d)=>t(c,a[d])),{localNum:i,mesgNum:n,fieldDefns:o}=this.mesgDefn;return n===e.mesgNum&&i===e.localNum&&r(o,e.fieldDefns)}get defnRecord(){let{localNum:e,mesgNum:t,fieldDefns:r}=this.mesgDefn,i=6+3*r.length,n=new DataView(new ArrayBuffer(i));n.setUint8(0,64|e),n.setUint8(2,1),n.setUint16(3,t),n.setUint8(5,r.length);let o=6;for(let s of r)n.setUint8(o++,s.number),n.setUint8(o++,s.size),n.setUint8(o++,s.baseType);return n.buffer}get dataRecord(){let{fieldDefns:e}=this.mesgDefn,t=1+e.reduce((n,{size:o})=>n+o,0),r=new DataView(new ArrayBuffer(t));r.setUint8(0,this.localNum);let i=1;for(let{number:n,type:o,value:s}of this.fields){let a=ke[o];if(!a)throw new Error(`Unknown type: ${o}`);let{size:c,setValue:d}=a,l;"mapValue"in a?l=a.mapValue(s):l=s,d&&d.call(r,i,l),i+=c}return r.buffer}};var Je=[0,52225,55297,5120,61441,15360,10240,58369,40961,27648,30720,46081,20480,39937,34817,17408],Le=(p,e)=>(p>>>4^Je[p&15^e])&65535,Qe=(p,e,t)=>Le(Le(p,e),t),et=(p,e)=>Qe(p,e&15,e>>>4);function Fe(p,e=0){let t=e,r=p instanceof ArrayBuffer?new Uint8Array(p):p;for(let i=0;i<r.length;i++)t=et(t,r[i]);return t}import tt from"dayjs";var Oe=14,rt=16,nt=2078,it=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,i=[],n=[];for(let o of t){if(o.lapMesgs&&this.buildEventsFromLaps(o.lapMesgs,i),o.lapMesgs)for(let s of o.lapMesgs)s.recordMesgs&&this.buildRecords(s.recordMesgs);o.lapMesgs&&this.buildLaps(o.lapMesgs),this.buildSession(o),r++,this.buildActivityFromSession(o,n)}i.forEach(o=>this.buildEvent(o)),n.forEach(o=>this.buildActivity(o))}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 i=[];for(let s of r.lapMesgs)s.recordMesgs&&i.push(...s.recordMesgs);i.sort((s,a)=>s.timestamp&&a.timestamp?new Date(s.timestamp).getTime()-new Date(a.timestamp).getTime():(s.distance||0)-(a.distance||0));let n=i[0],o=i[i.length-1];n.timestamp&&this.buildEvent({timestamp:n.timestamp,event:"timer",eventType:"start",eventGroup:0}),i.forEach(s=>this.buildRecord(s)),o.timestamp&&this.buildEvent({timestamp:o.timestamp,event:"timer",eventType:"stop_all",eventGroup:0}),r.lapMesgs[0]&&this.buildLap(r.lapMesgs[0])}}buildFileId(e,t){var i;let r=((i=e.fileIdMesgs)==null?void 0:i[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,i)=>{r.startTime&&t.push({timestamp:r.startTime,event:"timer",eventType:"start",eventGroup:i}),r.timestamp&&t.push({timestamp:r.timestamp,event:"timer",eventType:i===e.length-1?"stop_all":"stop",eventGroup:i})})}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:tt(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(([s,a])=>a!==void 0));if(Object.keys(r).length===0)return;let i=this.localNum[e];i===void 0&&(i=this.localNum[e]=Object.keys(this.localNum).length);let n=new re(i,e,r),o=this.mesgDefn[i];(!o||!n.isSameDefn(o))&&(this.messages.push(n.defnRecord),this.mesgDefn[i]=n.mesgDefn),this.messages.push(n.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)=>Fe(t,e),0)}get header(){let e=new DataView(new ArrayBuffer(Oe));return e.setUint8(0,Oe),e.setUint8(1,rt),e.setUint16(2,nt,!0),e.setUint32(4,this.dataLen,!0),e.setUint32(8,it),e.setUint16(12,Fe(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 m=class extends h{parseHeartRate(e){let t=this.parseFloat(e);return t>0&&t<300?t:void 0}parseTCXTime(e){if(!e)return;let t=new Date(e);return isNaN(t.getTime())?void 0:t}parseDistance(e){let t=this.parseFloat(e);return t>=0?t:void 0}parseSpeed(e){let t=this.parseFloat(e);return t>=0?t:void 0}parseAltitude(e){return this.parseFloat(e)}parseCoordinate(e){let t=this.parseFloat(e);return t!==0?t:void 0}};var ne=class extends m{constructor(){super(...arguments);this.name="PositionConverter";this.supportedTags=["Position"]}convert(t,r){let i={};return this.processChildren(t,i,{LatitudeDegrees:(n,o)=>o.LatitudeDegrees=this.parseString(n.value),LongitudeDegrees:(n,o)=>o.LongitudeDegrees=this.parseString(n.value)}),i}},ie=class extends m{constructor(){super(...arguments);this.name="TrackpointConverter";this.supportedTags=["Trackpoint"]}convert(t,r){let i={};return this.processChildren(t,i,{Time:(n,o)=>o.Time=this.parseString(n.value),Position:(n,o)=>{var a;let s=r.metadata.get("decoder");o.Position=(a=s==null?void 0:s.getConverter("Position"))==null?void 0:a.convert(n,r)},AltitudeMeters:(n,o)=>o.AltitudeMeters=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),HeartRateBpm:(n,o)=>{if(n.value)o.HeartRateBpm=this.parseFloat(n.value);else{let s=this.getChildByTag(n,"Value");s!=null&&s.value&&(o.HeartRateBpm=this.parseFloat(s.value))}},Cadence:(n,o)=>{let s={Low:0,High:0};this.processChildren(n,s,{Low:(a,c)=>c.Low=this.parseFloat(a.value),High:(a,c)=>c.High=this.parseFloat(a.value)}),o.Cadence=s},SensorState:(n,o)=>o.SensorState=n.value,Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},oe=class extends m{constructor(){super(...arguments);this.name="TrackConverter";this.supportedTags=["Track"]}convert(t,r){let i={Trackpoint:[]};return this.processChildren(t,i,{Trackpoint:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Trackpoint"))==null?void 0:c.convert(n,r);a&&o.Trackpoint&&o.Trackpoint.push(a)}}),i}},se=class extends m{constructor(){super(...arguments);this.name="ActivityLapConverter";this.supportedTags=["Lap"]}convert(t,r){let i={};return this.extractAttributes(t,i,{StartTime:"Id"}),this.processChildren(t,i,{TotalTimeSeconds:(n,o)=>o.TotalTimeSeconds=this.parseFloat(n.value),DistanceMeters:(n,o)=>o.DistanceMeters=this.parseFloat(n.value),MaximumSpeed:(n,o)=>o.MaximumSpeed=this.parseFloat(n.value),Calories:(n,o)=>o.Calories=this.parseFloat(n.value),AverageHeartRateBpm:(n,o)=>o.AverageHeartRateBpm=this.parseFloat(n.value),MaximumHeartRateBpm:(n,o)=>o.MaximumHeartRateBpm=this.parseFloat(n.value),Intensity:(n,o)=>o.Intensity=n.value,TriggerMethod:(n,o)=>o.TriggerMethod=n.value,Track:(n,o)=>{var c;o.Track||(o.Track=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Track"))==null?void 0:c.convert(n,r);a&&o.Track.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},ae=class extends m{constructor(){super(...arguments);this.name="ActivityConverter";this.supportedTags=["Activity"]}convert(t,r){let i={Id:"",Lap:[]};return this.extractAttributes(t,i,{Sport:"Sport"}),this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),Lap:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Lap"))==null?void 0:c.convert(n,r);a&&o.Lap.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value),Training:(n,o)=>o.Training=this.convertTraining(n),Creator:(n,o)=>o.Creator=this.convertCreator(n),Extensions:(n,o)=>o.Extensions=this.convertExtensions(n)}),i}convertTraining(t){var i;let r={};return t.attributes&&Object.entries(t.attributes).forEach(([n,o])=>{r[n]=o}),(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertCreator(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensions(t){var i;let r={};return(i=t.children)==null||i.forEach(n=>{r[n.tag]=this.convertExtensionContent(n)}),r}convertExtensionContent(t){var r;if((r=t.children)!=null&&r.length){let i={};return t.children.forEach(n=>{i[n.tag]=this.convertExtensionContent(n)}),i}else return t.value}},pe=class extends m{constructor(){super(...arguments);this.name="ActivityListConverter";this.supportedTags=["Activities"]}convert(t,r){let i={Activity:[],MultiSportSession:[]};return this.processChildren(t,i,{Activity:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("Activity"))==null?void 0:c.convert(n,r);a&&o.Activity&&o.Activity.push(a)},MultiSportSession:(n,o)=>{var c;let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("MultiSportSession"))==null?void 0:c.convert(n,r);a&&o.MultiSportSession&&o.MultiSportSession.push(a)}}),i}},ce=class extends m{constructor(){super(...arguments);this.name="MultiSportSessionConverter";this.supportedTags=["MultiSportSession"]}convert(t,r){let i={};return this.processChildren(t,i,{Id:(n,o)=>o.Id=this.parseString(n.value),FirstSport:(n,o)=>{var a;let s=r.metadata.get("decoder");o.FirstSport=(a=s==null?void 0:s.getConverter("FirstSport"))==null?void 0:a.convert(n,r)},NextSport:(n,o)=>{var c;o.NextSport||(o.NextSport=[]);let s=r.metadata.get("decoder"),a=(c=s==null?void 0:s.getConverter("NextSport"))==null?void 0:c.convert(n,r);a&&o.NextSport.push(a)},Notes:(n,o)=>o.Notes=this.parseString(n.value)}),i}},de=class extends m{constructor(){super(...arguments);this.name="AbstractSourceConverter";this.supportedTags=["Author","Creator"]}convert(t,r){let i={};return this.processChildren(t,i,{Name:(n,o)=>o.Name=this.parseString(n.value)}),i}};import{Parser as $e}from"htmlparser2";var le=class{static tokenizeXML(e){let t=[],r=new $e({onopentag(i,n){t.push({type:"open",tag:i,attributes:n})},ontext(i){let n=i.replace(/\n/g,"").trim();n&&t.push({type:"text",tag:"text",value:n})},onclosetag(i){t.push({type:"close",tag:i})}},{xmlMode:!0});return r.write(e),r.end(),t}static compressXML(e){return e.replace(/>\s+</g,"><").replace(/\s+/g," ").trim()}static formatXML(e,t=2){let r=" ".repeat(t),i="",n=0,o=!1;for(let s=0;s<e.length;s++){let a=e[s],c=e[s+1];a==="<"?(c==="/"?(n--,o||(i+=`
12
+ `+r.repeat(n))):c!=="?"&&c!=="!"&&(o||(i+=`
13
+ `+r.repeat(n)),n++),o=!0):a===">"&&(o=!1,c==="<"&&e[s+2]==="/"&&n--),i+=a}return i.trim()}static validateXML(e){try{let t=new $e({},{xmlMode:!0});return t.write(e),t.end(),{isValid:!0}}catch(t){return{isValid:!1,error:t.message}}}static extractXMLDeclaration(e){let t=e.match(/<\?xml\s+([^>]+)\?>/);if(!t)return{};let r=t[1],i={},n=r.match(/version=["']([^"']+)["']/);n&&(i.version=n[1]);let o=r.match(/encoding=["']([^"']+)["']/);o&&(i.encoding=o[1]);let s=r.match(/standalone=["']([^"']+)["']/);return s&&(i.standalone=s[1]),i}static escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}static unescapeXML(e){return e.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&")}};var ue=class{constructor(){this.stage="tokenize";this.name="tokenize-processor"}async process(e){if(!e.xmlContent)throw new Error("TCX data cannot be empty");let t=le.tokenizeXML(e.xmlContent);if(t.length===0)throw new Error("Not a valid TCX file");return e.tokens=t,e.stats.processedTokens=t.length,e}},me=class{constructor(){this.stage="ast-generate";this.name="ast-generate-processor"}async process(e){if(!e.tokens||e.tokens.length===0)throw new Error("Tokens are empty, cannot generate AST");let t=this.buildAST(e.tokens);if(!t)throw new Error("Failed to generate AST");return e.ast=t,e}buildAST(e){if(e.length===0)return;let t=[],r;for(let i of e)if(i.type==="open"){let n={tag:i.tag,attributes:i.attributes,children:[]};r&&(r.children=r.children||[],r.children.push(n)),t.push(n),r=n,t.length||r||(r=n)}else i.type==="close"?(t.pop(),r=t[t.length-1]):i.type==="text"&&r&&i.value&&typeof i.value=="string"&&i.value.trim()&&(r.value=i.value.trim());return r}},Te=class{constructor(e){this.getConverter=e;this.stage="convert";this.name="convert-processor"}async process(e){if(!e.ast)throw new Error("AST is empty, cannot convert");let t=this.findTCXRoot(e.ast);if(!t)throw new Error("Not a valid TCX file: TrainingCenterDatabase element not found");let r=this.convertAST(t,e);return e.result=r,e.stats.convertedElements=this.countElements(e.ast),e}findTCXRoot(e){if(e.tag==="TrainingCenterDatabase")return e;if(e.children)for(let t of e.children){let r=this.findTCXRoot(t);if(r)return r}}convertAST(e,t){let r=this.getConverter(e.tag);return r?r.convert(e,t):this.genericConvert(e,t)}genericConvert(e,t){let r={};if(e.attributes&&Object.entries(e.attributes).forEach(([i,n])=>{r[i]=n}),e.value!==void 0)if(e.children&&e.children.length>0)r._value=e.value;else return e.value;return e.children&&e.children.forEach(i=>{let n=this.convertAST(i,t);r[i.tag]?(Array.isArray(r[i.tag])||(r[i.tag]=[r[i.tag]]),r[i.tag].push(n)):r[i.tag]=n}),r}countElements(e){let t=1;if(e.children)for(let r of e.children)t+=this.countElements(r);return t}},fe=class{constructor(){this.stage="complete";this.name="complete-processor"}async process(e){if(!e.result)throw new Error("No conversion result found");let t=Date.now(),r=t-e.performance.startTime;return e.performance.endTime=t,e.performance.processingTime=r,e.metadata.set("performance",{processingTime:r,processedTokens:e.stats.processedTokens,convertedElements:e.stats.convertedElements}),e}};var S=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 ue,new me,new Te(e=>this.getConverter(e)),new fe]}async registerDefaultConverters(){var t;if(this.defaultConvertersRegistered)return;let e=[new ne,new ie,new oe,new se,new ae,new pe,new ce,new de];for(let r of e)(t=r.supportedTags)==null||t.forEach(i=>{this.addConverterForTag(i,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((i,n)=>(i.priority||100)-(n.priority||100))}async registerConverter(e){var r,n;if(this.registeredPlugins.has(e.name))throw new Error(`Converter plugin ${e.name} already exists`);(r=e.supportedTags)==null||r.forEach(o=>{this.addConverterForTag(o,e)}),this.registeredPlugins.add(e.name);let t=e.priority!==void 0?` (priority: ${e.priority})`:"";(n=e.supportedTags)==null||n.forEach(o=>{let a=(this.converterPlugins.get(o)||[]).map(c=>`${c.name}(${c.priority||100})`)})}async registerMiddleware(e){let t=this.middlewarePlugins.findIndex(i=>i.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,i]of this.converterPlugins){let n=i.findIndex(o=>o.name===e);n!==-1&&(t=i[n],i.splice(n,1),i.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)}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 i of t)try{await((r=i.initialize)==null?void 0:r.call(i,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 i of t)try{await((r=i.destroy)==null?void 0:r.call(i,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 n;let i=t;for(let o of this.middlewarePlugins){let s=o[e];if(s)try{i=await s.call(o,i,r)||i}catch(a){r.errors.push(a),await((n=o.onError)==null?void 0:n.call(o,a,r))}}return i}async parseByBuffer(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 i of this.processors)try{switch(t=await i.process(t),i.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(n){t.errors.push(n);for(let o of this.middlewarePlugins)await((r=o.onError)==null?void 0:r.call(o,n,t))}return t.result}catch(i){throw i}}convertExtensions(e){var o,s;let t={},{attributes:r,tag:i,value:n}=e;if(r&&Object.entries(r).forEach(([a,c])=>{t[a]=c}),(o=e==null?void 0:e.children)!=null&&o.length)(s=e.children)==null||s.forEach(a=>{t[a.tag]=this.convertExtensions(a)});else if(n!==void 0)return n;return t}async parserByBuffer(e){return this.parseByBuffer(e)}async parseByString(e){let t=Buffer.from(e,"utf-8");return this.parseByBuffer(t)}};import Ge from"dayjs";import ot from"dayjs/plugin/utc.js";Ge.extend(ot);var R=class{constructor(e={}){this.compact=e.compact??!0}async encode(e){let t=this.buildTCXXML(e);return Buffer.from(t,"utf-8")}encodeToString(e){return this.buildTCXXML(e)}buildTCXXML(e){let t=this.buildXMLHeader(e),r=this.buildTCXContent(e),n=`${t}${r}
14
+ </TrainingCenterDatabase>`;return this.compact?this.compressXML(n):n}compressXML(e){return e.replace(/>\s+</g,"><").replace(/^\s+|\s+$/gm,"").replace(/\s+/g," ").trim()}buildXMLHeader(e){let t=e.version||"1.0",r=e.creator||"trackswap",i=e.xmlns||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",n=e["xmlns:xsi"]||"http://www.w3.org/2001/XMLSchema-instance",o=e["xsi:schemaLocation"]||"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd";return['<?xml version="1.0" encoding="UTF-8"?>',`<TrainingCenterDatabase version="${this.escapeXMLAttribute(t)}"`,` creator="${this.escapeXMLAttribute(r)}"`,` xmlns="${this.escapeXMLAttribute(i)}"`,` xmlns:xsi="${this.escapeXMLAttribute(n)}"`,` xsi:schemaLocation="${this.escapeXMLAttribute(o)}">`].join(`
15
+ `)}buildTCXContent(e){let t=[];return e.Folders&&t.push(this.buildFolders(e.Folders)),e.Activities&&t.push(this.buildActivities(e.Activities)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses&&t.push(this.buildCourses(e.Courses)),e.Author&&t.push(this.buildAuthor(e.Author)),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.join(`
16
+ `)}buildFolders(e){let t=["<Folders>"];return e.History&&t.push(this.buildHistory(e.History)),e.Workouts&&t.push(this.buildWorkouts(e.Workouts)),e.Courses,t.push("</Folders>"),t.join(`
17
+ `)}buildHistory(e){let t=["<History>"];return e.Running&&t.push(`<Running>${this.buildHistoryFolder(e.Running)}</Running>`),e.Biking&&t.push(`<Biking>${this.buildHistoryFolder(e.Biking)}</Biking>`),e.Other&&t.push(`<Other>${this.buildHistoryFolder(e.Other)}</Other>`),e.MultiSport&&t.push(`<MultiSport>${this.buildHistoryFolder(e.MultiSport)}</MultiSport>`),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</History>"),t.join(`
18
+ `)}buildHistoryFolder(e){return""}buildActivities(e){let t=["<Activities>"];return e.Activity&&e.Activity.forEach(r=>{t.push(this.buildActivity(r))}),e.MultiSportSession&&e.MultiSportSession.forEach(r=>{t.push(this.buildMultiSportSession(r))}),t.push("</Activities>"),t.join(`
19
+ `)}buildActivity(e){let r=[`<Activity Sport="${e.Sport||"Other"}">`];return r.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.Lap&&e.Lap.length>0&&e.Lap.forEach(i=>{r.push(this.buildActivityLap(i))}),this.addOptionalElement(r,"Notes",e.Notes),e.Training,e.Creator,e.Extensions&&r.push(this.buildExtensions(e.Extensions)),r.push("</Activity>"),r.join(`
20
+ `)}buildActivityLap(e){let t=["<Lap>"];return this.addOptionalNumericElement(t,"TotalTimeSeconds",e.TotalTimeSeconds),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),this.addOptionalNumericElement(t,"MaximumSpeed",e.MaximumSpeed),this.addOptionalNumericElement(t,"Calories",e.Calories),e.AverageHeartRateBpm&&t.push(`<AverageHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.AverageHeartRateBpm}</Value></AverageHeartRateBpm>`),e.MaximumHeartRateBpm&&t.push(`<MaximumHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.MaximumHeartRateBpm}</Value></MaximumHeartRateBpm>`),this.addOptionalElement(t,"Intensity",e.Intensity),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"TriggerMethod",e.TriggerMethod),e.Track&&e.Track.forEach(r=>{t.push(this.buildTrack(r))}),this.addOptionalElement(t,"Notes",e.Notes),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Lap>"),t.join(`
21
+ `)}buildTrack(e){let t=["<Track>"];return e.Trackpoint&&e.Trackpoint.forEach(r=>{t.push(this.buildTrackpoint(r))}),t.push("</Track>"),t.join(`
22
+ `)}buildTrackpoint(e){let t=["<Trackpoint>"];return e.Time&&t.push(`<Time>${this.formatTime(e.Time)}</Time>`),e.Position&&t.push(this.buildPosition(e.Position)),this.addOptionalNumericElement(t,"AltitudeMeters",e.AltitudeMeters),this.addOptionalNumericElement(t,"DistanceMeters",e.DistanceMeters),e.HeartRateBpm&&t.push(`<HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t"><Value>${e.HeartRateBpm}</Value></HeartRateBpm>`),e.Cadence&&t.push(this.buildCadence(e.Cadence)),this.addOptionalElement(t,"SensorState",e.SensorState),e.Extensions&&t.push(this.buildExtensions(e.Extensions)),t.push("</Trackpoint>"),t.join(`
23
+ `)}buildPosition(e){let t=["<Position>"];return e.LatitudeDegrees&&t.push(`<LatitudeDegrees>${this.formatCoordinate(parseFloat(e.LatitudeDegrees))}</LatitudeDegrees>`),e.LongitudeDegrees&&t.push(`<LongitudeDegrees>${this.formatCoordinate(parseFloat(e.LongitudeDegrees))}</LongitudeDegrees>`),t.push("</Position>"),t.join("")}buildCadence(e){return`<Cadence><Low>${e.Low}</Low><High>${e.High}</High></Cadence>`}buildMultiSportSession(e){let t=["<MultiSportSession>"];return e.Id&&t.push(`<Id>${this.formatTime(e.Id)}</Id>`),e.FirstSport&&t.push(this.buildFirstSport(e.FirstSport)),e.NextSport&&e.NextSport.forEach(r=>{t.push(this.buildNextSport(r))}),this.addOptionalElement(t,"Notes",e.Notes),t.push("</MultiSportSession>"),t.join(`
24
+ `)}buildFirstSport(e){let t=["<FirstSport>"];return e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</FirstSport>"),t.join(`
25
+ `)}buildNextSport(e){let t=["<NextSport>"];return e.Transition&&t.push(`<Transition>${this.buildActivityLap(e.Transition)}</Transition>`),e.Activity&&t.push(this.buildActivity(e.Activity)),t.push("</NextSport>"),t.join(`
26
+ `)}buildWorkouts(e){return"<Workouts></Workouts>"}buildCourses(e){return"<Courses></Courses>"}buildAuthor(e){let t=["<Author>"];return this.addOptionalElement(t,"Name",e.Name),t.push("</Author>"),t.join("")}buildExtensions(e){let t=this.buildExtensionContent(e);return t?`<Extensions>${t}</Extensions>`:""}buildExtensionContent(e){return Object.entries(e).filter(([t])=>!t.startsWith("xmlns")).map(([t,r])=>{if(r&&typeof r=="object"){let i=this.buildExtensionContent(r);return`<${t}>${i}</${t}>`}else if(r!=null)return`<${t}>${this.escapeXML(String(r))}</${t}>`;return""}).filter(t=>t).join("")}formatTime(e){return typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e)?e:Ge(e).utc().format("YYYY-MM-DDTHH:mm:ss[Z]")}addOptionalElement(e,t,r,i){if(r!=null&&r!==""){let n=i?i(r):this.escapeXML(r);e.push(`<${t}>${n}</${t}>`)}}addOptionalNumericElement(e,t,r){r!=null&&!isNaN(r)&&e.push(`<${t}>${r}</${t}>`)}isValidCoordinate(e,t){return e!=null&&t!==void 0&&t!==null&&!isNaN(e)&&!isNaN(t)}formatCoordinate(e){return this.roundTo(e,6).toString()}roundTo(e,t){let r=Math.pow(10,t);return Math.round(e*r)/r}escapeXML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}escapeXMLAttribute(e){return typeof e!="string"?String(e||""):e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\r/g,"&#13;").replace(/\n/g,"&#10;").replace(/\t/g,"&#9;")}deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(r=>this.deepClone(r));let t={};for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=this.deepClone(e[r]));return t}encoder(e){return this.encode(e)}};var b=class extends h{convertPoints(e){return e.map(t=>this.convertPoint(t)).filter(t=>t!==void 0)}convertTime(e){if(e){if(typeof e=="number")return e;if(e instanceof Date)return e.getTime();if(typeof e=="string"){let t=new Date(e);return isNaN(t.getTime())?void 0:t.getTime()}}}calculateDistance(e){if(e.length<2)return;let t=0;for(let r=1;r<e.length;r++){let i=e[r-1],n=e[r],o=6371e3,s=i.lat*Math.PI/180,a=n.lat*Math.PI/180,c=(n.lat-i.lat)*Math.PI/180,d=(n.lon-i.lon)*Math.PI/180,l=Math.sin(c/2)*Math.sin(c/2)+Math.cos(s)*Math.cos(a)*Math.sin(d/2)*Math.sin(d/2),f=2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l));t+=o*f}return t}calculateDuration(e){var i,n;if(e.length<2)return;let t=(i=e[0])==null?void 0:i.time,r=(n=e[e.length-1])==null?void 0:n.time;if(!(!t||!r))return Math.round((r-t)/1e3)}},I=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}convertTimeToDate(e){return e?new Date(e):new Date}convertTimeToString(e){return this.convertTimeToDate(e).toISOString()}ensureValidCoordinates(e,t){return e>=-90&&e<=90&&t>=-180&&t<=180}round(e,t=6){let r=Math.pow(10,t);return Math.round(e*r)/r}};var Be={"gpxtpx:cad":"cadence","gpxtpx:hr":"heartRate","gpxtpx:temp":"temperature","gpxtpx:wtemp":"wtemp","gpxtpx:atemp":"atemp","gpxx:Temperature":"temperature","gpxx:Depth":"depth"},Ae=p=>p*(180/Math.pow(2,31));import M from"dayjs";function He(p,e=0){let t=Math.pow(10,e);return Math.round(p*t)/t}var ge=class extends b{constructor(){super(...arguments);this.name="gpx-to-sport-converter";this.supportedTags=["gpx"];this.convertGPXExtensions=t=>{let r={};return Object.entries(t).forEach(([i,n])=>{if(typeof n!="string"&&typeof n!="number")r={...r,...this.convertGPXExtensions(n)};else if(typeof n<"u"&&n!=="undefined"){let o=Be[i]||i;r[o]=n}}),r}}convert(t,r){if(r.sourceFormat!=="gpx")return;let i=r.sourceData;return this.convertGPX(i)}convertGPX(t){let r={metadata:{originType:"GPX",creator:t.creator,fileType:"gpx"}};return t.wpt&&(r.points=this.convertWpts2Points(t.wpt)),t.trk&&(r.tracks=t.trk.map(i=>{var n;return{name:i.name,trackseg:((n=i.trkseg)==null?void 0:n.map(o=>({name:i.name,points:o.trkpt?this.convertWpts2Points(o.trkpt):[]})))||[]}})),t.rte&&(r.routes=t.rte.map(i=>({name:i.name,points:i.rtept?this.convertWpts2Points(i.rtept):[]}))),r}convertPoint(t){if(!t.lat||!t.lon)return;let{extensions:r}=t,i=r?this.convertGPXExtensions(r):{};return{lat:t.lat,lon:t.lon,ele:t.ele,time:this.convertTime(t.time),...i}}convertWpts2Points(t){let r=[];for(let i=0;i<t.length;i++){let n=t[i];if(n.lat&&n.lon){let o=this.convertPoint(n);o&&r.push(o)}}return r}},he=class extends b{constructor(){super(...arguments);this.name="fit-to-sport-converter";this.supportedTags=["fit"]}convert(t,r){if(r.sourceFormat!=="fit")return;let i=r.sourceData;return this.convertFIT(i)}convertFIT(t){var i,n;let r={metadata:{originType:"FIT",fileType:"fit"}};if((i=t.sessionMesgs)!=null&&i.length){r.tracks=[];for(let o of t.sessionMesgs)r.tracks.push({name:o.event,startTime:o.startTime?M(o.startTime).valueOf():void 0,distance:o.totalDistance,duration:o.totalElapsedTime,sport:o.sport,trackseg:this.convertFITLap2Trackseg(o==null?void 0:o.lapMesgs),__fit__sessionMesgType:o})}else if((n=t.courseMesgs)!=null&&n.length){r.routes=[];for(let o of t.courseMesgs)r.routes.push({name:o.event,points:this.convertLap2Points(o==null?void 0:o.lapMesgs)})}return r}convertPoint(t){let{positionLong:r,positionLat:i,altitude:n,timestamp:o,...s}=t;if(!(!r||!i))return{lat:He(Ae(Number(i)),6),lon:He(Ae(Number(r)),6),ele:n,time:o?M(o).valueOf():void 0,...s}}convertFITLap2Trackseg(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let o=((i=n==null?void 0:n.recordMesgs)==null?void 0:i.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];r.push({points:o,duration:n.totalElapsedTime,distance:n.totalDistance,startTime:n.startTime?M(n.startTime).valueOf():void 0,endTime:n.startTime&&n.totalElapsedTime?M(n.startTime).add(n.totalElapsedTime,"second").valueOf():void 0,avgSpeed:n.avgSpeed,maxSpeed:n.maxSpeed,avgCadenceBpm:n.avgCadence,maxCadenceBpm:n.maxCadence,avgPower:n.avgPower,maxPower:n.maxPower,totalAscent:n.totalAscent,totalDescent:n.totalDescent,calories:n.totalCalories,__fit__lapMesgType:n})}return r}convertLap2Points(t){var i;let r=[];if(!(t!=null&&t.length))return[];for(let n of t){let o=((i=n.recordMesgs)==null?void 0:i.map(s=>this.convertPoint(s)).filter(s=>s!==void 0))||[];o.length&&(r=[...r,...o])}return r}},ye=class extends b{constructor(){super(...arguments);this.name="tcx-to-sport-converter";this.supportedTags=["tcx"]}convert(t,r){if(r.sourceFormat!=="tcx")return;let i=r.sourceData;return this.convertTCX(i)}convertTCX(t){var i,n,o,s;let r={metadata:{originType:"TCX",fileType:"tcx"}};if((n=(i=t.Activities)==null?void 0:i.Activity)!=null&&n.length){r.tracks=[];for(let a of t.Activities.Activity)r.tracks.push({name:a.Id,sport:a.Sport,trackseg:this.convertLap2Trackseg(a.Lap)})}if((s=(o=t.Courses)==null?void 0:o.Course)!=null&&s.length){r.routes=[];for(let a of t.Courses.Course){let c=a.Track||[];for(let d of c)r.routes.push({name:a.Name||"",points:this.convertTCXTrack(d)})}}return r}convertPoint(t){let{Position:r,Time:i,DistanceMeters:n,AltitudeMeters:o}=t;if(!(!(r!=null&&r.LatitudeDegrees)||!(r!=null&&r.LongitudeDegrees)))return{lat:Number(r.LatitudeDegrees),lon:Number(r.LongitudeDegrees),time:i?M(i).valueOf():void 0,distance:n,ele:o}}convertLap2Trackseg(t){var i,n,o,s;let r=[];for(let a of t)if(a.Track){for(let c of a.Track)if(c.Trackpoint){let d=c.Trackpoint.map(f=>this.convertPoint(f)).filter(f=>f!==void 0),l={duration:a.TotalTimeSeconds,distance:a.DistanceMeters,startTime:(i=d==null?void 0:d[0])==null?void 0:i.time,endTime:(n=d==null?void 0:d[d.length-1])==null?void 0:n.time,avgHeartRateBpm:a==null?void 0:a.AverageHeartRateBpm,maxHeartRateBpm:a==null?void 0:a.MaximumHeartRateBpm,maxSpeed:a.MaximumSpeed,calories:a.Calories,__tcx__Intensity:a==null?void 0:a.Intensity,__tcx__TriggerMethod:a==null?void 0:a.TriggerMethod,avgCadenceBpm:(o=a==null?void 0:a.Cadence)==null?void 0:o.Low,maxCadenceBpm:(s=a==null?void 0:a.Cadence)==null?void 0:s.High,points:d};r.push(l)}}return r}convertTCXTrack(t){return t.Trackpoint?t.Trackpoint.map(r=>this.convertPoint(r)).filter(r=>r!==void 0):[]}};function ze(p){return Math.round(p*(Math.pow(2,31)/180))}var ve=class extends I{constructor(){super(...arguments);this.name="sport-to-gpx-encoder";this.supportedTags=["gpx"]}encode(t,r){var n,o,s,a;if(r.targetFormat!=="gpx")return;let i={version:"1.1",creator:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"};return(o=t.points)!=null&&o.length&&(i.wpt=this.convertPoints2Wpts(t.points)),(s=t.routes)!=null&&s.length&&(i.rte=t.routes.map(c=>this.convertRoute2GPXRoute(c))),(a=t.tracks)!=null&&a.length&&(i.trk=t.tracks.map(c=>this.convertTrack2GPXTrack(c))),i}convertPoints2Wpts(t){return t.map(r=>({lat:r.lat,lon:r.lon,ele:r.ele,time:r.time?this.convertTimeToDate(r.time):void 0,speed:r.speed,magvar:r.magvar,extensions:this.extractGPXExtensions(r)}))}convertRoute2GPXRoute(t){return{name:t.name,rtept:t.points?this.convertPoints2Wpts(t.points):[]}}convertTrack2GPXTrack(t){var r;return{name:t.name,trkseg:((r=t.trackseg)==null?void 0:r.map(i=>({trkpt:i.points?this.convertPoints2Wpts(i.points):[]})))||[]}}extractGPXExtensions(t){let r={};return t.heart&&(r["gpxtpx:hr"]=t.heart),t.cadence&&(r["gpxtpx:cad"]=t.cadence),t.temperature&&(r["gpxtpx:atemp"]=t.temperature),Object.keys(r).length>0?r:void 0}},xe=class extends I{constructor(){super(...arguments);this.name="sport-to-fit-encoder";this.supportedTags=["fit"]}encode(t,r){var n,o;if(r.targetFormat!=="fit")return;let i={};return(n=t.tracks)!=null&&n.length&&(i.sessionMesgs=t.tracks.map(s=>this.convertTrack2FITSession(s))),(o=t.routes)!=null&&o.length&&(i.courseMesgs=t.routes.map(s=>this.convertRoute2FITCourse(s))),i}convertTrack2FITSession(t){var i;return{event:t.name||"session",sport:t.sport||"generic",startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalDistance:t.distance,totalElapsedTime:t.duration,lapMesgs:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2FITLap(n)))||[]}}convertSeg2FITLap(t){var i;return{startTime:t.startTime?this.convertTimeToString(t.startTime):this.convertTimeToString(void 0),totalElapsedTime:t.duration,totalDistance:t.distance,avgSpeed:t.avgSpeed,maxSpeed:t.maxSpeed,avgCadence:t.avgCadenceBpm,maxCadence:t.maxCadenceBpm,avgPower:t.avgPower,maxPower:t.maxPower,totalAscent:t.totalAscent,totalDescent:t.totalDescent,totalCalories:t.calories,recordMesgs:((i=t.points)==null?void 0:i.map(n=>this.convertPoint2FITRecord(n)))||[]}}convertPoint2FITRecord(t){return{timestamp:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),positionLat:ze(t.lat),positionLong:ze(t.lon),altitude:t.ele,speed:t.speed,power:t.power,heartRate:t.heart,cadence:t.cadence,temperature:t.temperature,distance:t.distance,enhancedSpeed:t.enhancedSpeed,enhancedAltitude:t.enhancedAltitude,accumulatedPower:t.accumulatedPower}}convertRoute2FITCourse(t){return{event:t.name||"course",lapMesgs:t.points?[this.convertPoints2FITLap(t.points)]:[]}}convertPoints2FITLap(t){let r=t[0],i=t[t.length-1],n=r!=null&&r.time?this.convertTimeToString(r.time):this.convertTimeToString(void 0),o=r!=null&&r.time&&(i!=null&&i.time)?Math.round((i.time-r.time)/1e3):0,s=(i==null?void 0:i.distance)||0;return{startTime:n,totalElapsedTime:o,totalDistance:s,recordMesgs:t.map(a=>this.convertPoint2FITRecord(a))}}},Ce=class extends I{constructor(){super(...arguments);this.name="sport-to-tcx-encoder";this.supportedTags=["tcx"]}encode(t,r){var n,o,s;if(r.targetFormat!=="tcx")return;let i={Author:{Name:((n=t.metadata)==null?void 0:n.creator)||"TrackSwap"}};return(o=t.tracks)!=null&&o.length&&(i.Activities={Activity:t.tracks.map(a=>this.convertTrack2TCXActivity(a))}),(s=t.routes)!=null&&s.length&&(i.Courses={Course:t.routes.map(a=>this.convertRoute2TCXCourse(a))}),i}convertTrack2TCXActivity(t){var i;let r="Other";return(t.sport==="Running"||t.sport==="Biking")&&(r=t.sport),{Id:t.name||`Activity_${Date.now()}`,Sport:r,Lap:((i=t.trackseg)==null?void 0:i.map(n=>this.convertSeg2TCXLap(n)))||[]}}convertSeg2TCXLap(t){let r={TotalTimeSeconds:t.duration,DistanceMeters:t.distance,MaximumSpeed:t.maxSpeed,Calories:t.calories,AverageHeartRateBpm:t.avgHeartRateBpm,MaximumHeartRateBpm:t.maxHeartRateBpm,Intensity:t.__tcx__Intensity||"Active",TriggerMethod:t.__tcx__TriggerMethod||"Manual",Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]};return(t.avgCadenceBpm!==void 0||t.maxCadenceBpm!==void 0)&&(r.Cadence={Low:t.avgCadenceBpm||0,High:t.maxCadenceBpm||0}),r}convertPoints2TCXTrack(t){return{Trackpoint:t.map(r=>this.convertPoint2TCXTrackpoint(r))}}convertPoint2TCXTrackpoint(t){let r={Time:t.time?this.convertTimeToString(t.time):this.convertTimeToString(void 0),Position:{LatitudeDegrees:t.lat.toString(),LongitudeDegrees:t.lon.toString()},AltitudeMeters:t.ele,DistanceMeters:t.distance};return t.heart&&(r.HeartRateBpm=t.heart),r}convertRoute2TCXCourse(t){return{Name:t.name||`Course_${Date.now()}`,Track:t.points?[this.convertPoints2TCXTrack(t.points)]:[]}}};var Pe=class{constructor(){this.converters=new Map;this.encoders=new Map;this.registerDefaultConverters(),this.registerDefaultEncoders()}registerDefaultConverters(){this.registerConverter(new ge),this.registerConverter(new he),this.registerConverter(new ye)}registerDefaultEncoders(){this.registerEncoder(new ve),this.registerEncoder(new xe),this.registerEncoder(new Ce)}registerConverter(e){this.converters.set(e.name,e)}registerEncoder(e){this.encoders.set(e.name,e)}async convertToSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},sourceFormat:t,sourceData:e,performance:{startTime:Date.now()}};try{let i=this.findConverter(t);if(!i)throw new Error(`No converter found for format "${t}"`);let n=Date.now(),o=i.convert({},r);if(r.performance.convertTime=Date.now()-n,!o)throw new Error(`Converter "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}async encodeSport(e,t){let r={metadata:new Map,errors:[],warnings:[],stats:{startTime:Date.now(),processedTokens:0,convertedElements:0},targetFormat:t,performance:{startTime:Date.now()}};try{let i=this.findEncoder(t);if(!i)throw new Error(`No encoder found for format "${t}"`);let n=Date.now(),o=i.encode(e,r);if(r.performance.encodeTime=Date.now()-n,!o)throw new Error(`Encoder "${i.name}" returned empty result`);return r.result=o,r.performance.endTime=Date.now(),r.stats.endTime=Date.now(),o}catch(i){throw r.errors.push(i),i}}findConverter(e){return Array.from(this.converters.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}findEncoder(e){return Array.from(this.encoders.values()).find(t=>{var r;return(r=t.supportedTags)==null?void 0:r.includes(e)})}async destroy(){this.converters.clear(),this.encoders.clear()}};var Ee=class{constructor(){this.gpxDecoder=new C,this.gpxEncoder=new P,this.fitDecoder=new E,this.fitEncoder=new w,this.tcxDecoder=new S,this.tcxEncoder=new R,this.sportProcessor=new Pe}async parseGPX(e){try{return await this.gpxDecoder.parserByBuffer(e)}catch(t){throw new Error(`GPX parsing failed: ${t.message}`)}}async parseGPXString(e){let t=Buffer.from(e,"utf-8");return this.parseGPX(t)}async encodeGPX(e){try{return await this.gpxEncoder.encode(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}encodeGPXString(e){try{return this.gpxEncoder.encodeToString(e)}catch(t){throw new Error(`GPX encoding failed: ${t.message}`)}}async parseFIT(e){try{return await this.fitDecoder.parseByBuffer(e)}catch(t){throw new Error(`FIT parsing failed: ${t.message}`)}}async encodeFIT(e){try{return await this.fitEncoder.encode(e)}catch(t){throw new Error(`FIT encoding failed: ${t.message}`)}}async encodeFITCourse(e){try{return await this.fitEncoder.encodeCourse(e)}catch(t){throw new Error(`FIT Course encoding failed: ${t.message}`)}}async parseTCX(e){try{let t=await this.tcxDecoder.parseByBuffer(e);if(!t)throw new Error("TCX parsing result is empty");return t}catch(t){throw new Error(`TCX parsing failed: ${t.message}`)}}async parseTCXString(e){let t=Buffer.from(e,"utf-8");return this.parseTCX(t)}async encodeTCX(e){try{return await this.tcxEncoder.encode(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async encodeTCXString(e){try{return await this.tcxEncoder.encodeToString(e)}catch(t){throw new Error(`TCX encoding failed: ${t.message}`)}}async convertGPXToSport(e){return await this.sportProcessor.convertToSport(e,"gpx")}async convertFITToSport(e){return await this.sportProcessor.convertToSport(e,"fit")}async convertTCXToSport(e){return await this.sportProcessor.convertToSport(e,"tcx")}async convertSportToGPX(e){return await this.sportProcessor.encodeSport(e,"gpx")}async convertSportToFIT(e){return await this.sportProcessor.encodeSport(e,"fit")}async convertSportToTCX(e){return await this.sportProcessor.encodeSport(e,"tcx")}async convertFile(e,t,r){try{let i=r||this.detectFormat(e);if(i==="unknown")throw new Error("Unable to recognize source file format, please specify sourceType parameter");if(i===t)return e;let n;switch(i){case"gpx":let s=await this.parseGPX(e);if(!s)throw new Error("GPX file parsing failed");n=s;break;case"fit":n=await this.parseFIT(e);break;case"tcx":n=await this.parseTCX(e);break;default:throw new Error(`Unsupported source file format: ${i}`)}let o;switch(i){case"gpx":o=await this.convertGPXToSport(n);break;case"fit":o=await this.convertFITToSport(n);break;case"tcx":o=await this.convertTCXToSport(n);break;default:throw new Error(`Unsupported source file format conversion: ${i}`)}switch(t){case"gpx":let s=await this.convertSportToGPX(o);return await this.encodeGPX(s);case"fit":let a=await this.convertSportToFIT(o);return await this.encodeFIT(a);case"tcx":let c=await this.convertSportToTCX(o);return await this.encodeTCX(c);default:throw new Error(`Unsupported target file format: ${t}`)}}catch(i){let n=r||"auto-detect";throw new Error(`${n} to ${t.toUpperCase()} failed: ${i.message}`)}}detectFormat(e){let t=e.toString("utf-8",0,Math.min(1024,e.length));if(e.length>=12&&e.toString("ascii",8,12)===".FIT")return"fit";if(t.includes("<?xml")){if(t.includes("<gpx")||t.includes("http://www.topografix.com/GPX/"))return"gpx";if(t.includes("<TrainingCenterDatabase")||t.includes("http://www.garmin.com/xmlschemas/TrainingCenterDatabase/"))return"tcx"}return"unknown"}async parseFile(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return i;case"fit":return await this.parseFIT(e);case"tcx":return await this.parseTCX(e);default:throw new Error(`Unsupported file format: ${r}`)}}async parseToSport(e,t){let r=t||this.detectFormat(e);if(r==="unknown")throw new Error("Unable to recognize file format, please specify sourceType parameter");switch(r){case"gpx":let i=await this.parseGPX(e);if(!i)throw new Error("GPX parsing failed");return this.convertGPXToSport(i);case"fit":let n=await this.parseFIT(e);return this.convertFITToSport(n);case"tcx":let o=await this.parseTCX(e);return this.convertTCXToSport(o);default:throw new Error(`Unsupported file format: ${r}`)}}getSportProcessor(){return this.sportProcessor}getGPXDecoder(){return this.gpxDecoder}getGPXEncoder(){return this.gpxEncoder}getFITDecoder(){return this.fitDecoder}getFITEncoder(){return this.fitEncoder}getTCXDecoder(){return this.tcxDecoder}getTCXEncoder(){return this.tcxEncoder}async destroy(){await this.gpxDecoder.destroy(),await this.fitDecoder.destroy(),await this.tcxDecoder.destroy(),await this.sportProcessor.destroy()}};var gn=Ee;export{je as GPXManager,Ee as TrackSwap,gn as default};
@@ -0,0 +1,64 @@
1
+ import { IPlugin, IConverterPlugin, IMiddlewarePlugin, BaseConverter, BaseMiddleware, IProcessingContext } from "../core/base.js";
2
+ import { SportFileType, SportPointType, SportRouteSegType, SportTrackType, TokenAST } from "../types.js";
3
+ export interface SportContext extends IProcessingContext {
4
+ sourceFormat: string;
5
+ sourceData: any;
6
+ result?: SportFileType;
7
+ performance: {
8
+ startTime: number;
9
+ convertTime?: number;
10
+ endTime?: number;
11
+ };
12
+ }
13
+ export interface SportEncodingContext extends IProcessingContext {
14
+ targetFormat: string;
15
+ result?: any;
16
+ performance: {
17
+ startTime: number;
18
+ encodeTime?: number;
19
+ endTime?: number;
20
+ };
21
+ }
22
+ export interface ISportPlugin extends IPlugin {
23
+ }
24
+ export interface ISportConverterPlugin extends IConverterPlugin {
25
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
26
+ }
27
+ export interface ISportMiddlewarePlugin extends IMiddlewarePlugin {
28
+ process(context: SportContext): Promise<void>;
29
+ }
30
+ export interface ISportEncoderPlugin extends IPlugin<SportEncodingContext> {
31
+ encode(sportData: SportFileType, context: SportEncodingContext): any | undefined;
32
+ supports(format: string): boolean;
33
+ priority?: number;
34
+ }
35
+ export declare abstract class BaseSportConverter extends BaseConverter<SportContext> implements ISportConverterPlugin {
36
+ protected convertPoints(points: any[]): SportPointType[];
37
+ protected abstract convertPoint(point: any): SportPointType | undefined;
38
+ protected convertTime(time: Date | string | number | undefined): number | undefined;
39
+ protected calculateDistance(points: SportPointType[]): number | undefined;
40
+ protected calculateDuration(points: SportPointType[]): number | undefined;
41
+ }
42
+ export declare abstract class BaseSportEncoder implements ISportEncoderPlugin {
43
+ abstract name: string;
44
+ abstract supportedTags: string[];
45
+ version: string;
46
+ priority: number;
47
+ abstract encode(sportData: SportFileType, context: SportEncodingContext): any | undefined;
48
+ supports(format: string): boolean;
49
+ initialize(context: SportEncodingContext): Promise<void>;
50
+ destroy(context: SportEncodingContext): Promise<void>;
51
+ validate(context: SportEncodingContext): Promise<boolean>;
52
+ protected convertTimeToDate(time: number | undefined): Date;
53
+ protected convertTimeToString(time: number | undefined): string;
54
+ protected ensureValidCoordinates(lat: number, lon: number): boolean;
55
+ protected round(value: number, precision?: number): number;
56
+ }
57
+ export declare abstract class BaseSportMiddleware extends BaseMiddleware<SportContext, SportFileType> implements ISportMiddlewarePlugin {
58
+ abstract process(context: SportContext): Promise<void>;
59
+ onError(error: Error, context: SportContext): Promise<void>;
60
+ protected validateSportFile(sportFile: SportFileType): boolean;
61
+ protected validateTrack(track: SportTrackType): boolean;
62
+ protected validateRoute(route: SportRouteSegType): boolean;
63
+ protected validatePoint(point: SportPointType): boolean;
64
+ }
@@ -0,0 +1,33 @@
1
+ import { BaseSportConverter, SportContext } from "./base.js";
2
+ import { TokenAST } from "../types.js";
3
+ import { SportFileType, SportPointType } from "../types.js";
4
+ import { WptType } from "../GPX/types.js";
5
+ import { RecordMesgType } from "../FIT/types.js";
6
+ import { TrackpointType } from "../TCX/types.js";
7
+ export declare class GPXToSportConverter extends BaseSportConverter {
8
+ name: string;
9
+ supportedTags: string[];
10
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
11
+ private convertGPX;
12
+ protected convertPoint(point: WptType): SportPointType | undefined;
13
+ private convertWpts2Points;
14
+ private convertGPXExtensions;
15
+ }
16
+ export declare class FITToSportConverter extends BaseSportConverter {
17
+ name: string;
18
+ supportedTags: string[];
19
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
20
+ private convertFIT;
21
+ protected convertPoint(point: RecordMesgType): SportPointType | undefined;
22
+ private convertFITLap2Trackseg;
23
+ private convertLap2Points;
24
+ }
25
+ export declare class TCXToSportConverter extends BaseSportConverter {
26
+ name: string;
27
+ supportedTags: string[];
28
+ convert(ast: TokenAST, context: SportContext): SportFileType | undefined;
29
+ private convertTCX;
30
+ protected convertPoint(point: TrackpointType): SportPointType | undefined;
31
+ private convertLap2Trackseg;
32
+ private convertTCXTrack;
33
+ }
@@ -0,0 +1,34 @@
1
+ import { BaseSportEncoder, SportEncodingContext } from "./base.js";
2
+ import { SportFileType } from "../types.js";
3
+ import { GPX11Type } from "../GPX/types.js";
4
+ import { FITFileType } from "../FIT/types.js";
5
+ import { TCXFileType } from "../TCX/types.js";
6
+ export declare class SportToGPXEncoder extends BaseSportEncoder {
7
+ name: string;
8
+ supportedTags: string[];
9
+ encode(sportData: SportFileType, context: SportEncodingContext): GPX11Type | undefined;
10
+ private convertPoints2Wpts;
11
+ private convertRoute2GPXRoute;
12
+ private convertTrack2GPXTrack;
13
+ private extractGPXExtensions;
14
+ }
15
+ export declare class SportToFITEncoder extends BaseSportEncoder {
16
+ name: string;
17
+ supportedTags: string[];
18
+ encode(sportData: SportFileType, context: SportEncodingContext): FITFileType | undefined;
19
+ private convertTrack2FITSession;
20
+ private convertSeg2FITLap;
21
+ private convertPoint2FITRecord;
22
+ private convertRoute2FITCourse;
23
+ private convertPoints2FITLap;
24
+ }
25
+ export declare class SportToTCXEncoder extends BaseSportEncoder {
26
+ name: string;
27
+ supportedTags: string[];
28
+ encode(sportData: SportFileType, context: SportEncodingContext): TCXFileType | undefined;
29
+ private convertTrack2TCXActivity;
30
+ private convertSeg2TCXLap;
31
+ private convertPoints2TCXTrack;
32
+ private convertPoint2TCXTrackpoint;
33
+ private convertRoute2TCXCourse;
34
+ }
@@ -0,0 +1,17 @@
1
+ export * from "./base.js";
2
+ export * from "./converters.js";
3
+ export * from "./encoders.js";
4
+ export * from "./processor.js";
5
+ import { GPXToSportConverter, FITToSportConverter, TCXToSportConverter } from "./converters.js";
6
+ import { SportToGPXEncoder, SportToFITEncoder, SportToTCXEncoder } from "./encoders.js";
7
+ import { SportProcessor } from "./processor.js";
8
+ declare const _default: {
9
+ GPXToSportConverter: typeof GPXToSportConverter;
10
+ FITToSportConverter: typeof FITToSportConverter;
11
+ TCXToSportConverter: typeof TCXToSportConverter;
12
+ SportToGPXEncoder: typeof SportToGPXEncoder;
13
+ SportToFITEncoder: typeof SportToFITEncoder;
14
+ SportToTCXEncoder: typeof SportToTCXEncoder;
15
+ SportProcessor: typeof SportProcessor;
16
+ };
17
+ export default _default;
@@ -0,0 +1,19 @@
1
+ import { ISportConverterPlugin, ISportEncoderPlugin } from "./base.js";
2
+ import { SportFileType } from "../types.js";
3
+ import { GPX11Type } from "../GPX/types.js";
4
+ import { FITFileType } from "../FIT/types.js";
5
+ import { TCXFileType } from "../TCX/types.js";
6
+ export declare class SportProcessor {
7
+ private converters;
8
+ private encoders;
9
+ constructor();
10
+ private registerDefaultConverters;
11
+ private registerDefaultEncoders;
12
+ registerConverter(converter: ISportConverterPlugin): void;
13
+ registerEncoder(encoder: ISportEncoderPlugin): void;
14
+ convertToSport(sourceData: GPX11Type | FITFileType | TCXFileType, sourceFormat: "gpx" | "fit" | "tcx"): Promise<SportFileType>;
15
+ encodeSport(sportData: SportFileType, targetFormat: "gpx" | "fit" | "tcx"): Promise<GPX11Type | FITFileType | TCXFileType>;
16
+ private findConverter;
17
+ private findEncoder;
18
+ destroy(): Promise<void>;
19
+ }
package/dist/types.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { LapMesgType, RecordMesgType, SessionMesgType, UserProfileMesgType } from "./FIT/types.js";
2
+ import { IntensityType, TriggerMethodType } from "./TCX/types.js";
1
3
  export interface Token {
2
4
  type: "open" | "close" | "text";
3
5
  tag: string;
@@ -13,22 +15,98 @@ export interface TokenAST {
13
15
  export interface AttributeType {
14
16
  [key: string]: string;
15
17
  }
16
- /**
17
- * The latitude of the point. Decimal degrees, WGS84 datum.
18
- * @type {number} -90.0 <= value <= 90.0
19
- */
20
18
  export type LatitudeType = number;
21
- /**
22
- * The longitude of the point. Decimal degrees, WGS84 datum.
23
- * @type {number} -180.0 <= value < 180.0
24
- */
25
19
  export type LongitudeType = number;
26
- /**
27
- * Used for bearing, heading, course. Units are decimal degrees, true (not magnetic).
28
- * @type {number} 0.0 <= value < 360.0
29
-
30
- */
31
20
  export type DegreesType = number;
32
21
  export interface ExtensionsType {
33
22
  [key: string]: string | number | undefined | ExtensionsType;
34
23
  }
24
+ export interface SportFileType {
25
+ metadata?: {
26
+ originType: "GPX" | "FIT" | "TCX" | "HIJSON";
27
+ fileName?: string;
28
+ fileType?: string;
29
+ creator?: string;
30
+ date?: string;
31
+ };
32
+ points?: SportPointType[];
33
+ routes?: SportRouteSegType[];
34
+ tracks?: SportTrackType[];
35
+ __fit__UserProfileMesgs?: UserProfileMesgType[];
36
+ }
37
+ export interface SportPointType {
38
+ lat: LatitudeType;
39
+ lon: LongitudeType;
40
+ ele?: number;
41
+ time?: number;
42
+ heart?: number;
43
+ distance?: number;
44
+ accumulatedPower?: number;
45
+ speed?: number;
46
+ power?: number;
47
+ cadence?: number;
48
+ temperature?: number;
49
+ enhancedAltitude?: number;
50
+ enhancedSpeed?: number;
51
+ __fit__RecordMesgType?: RecordMesgType;
52
+ magvar?: DegreesType;
53
+ geoidheight?: number;
54
+ name?: string;
55
+ cmt?: string;
56
+ desc?: string;
57
+ src?: string;
58
+ sym?: string;
59
+ type?: string;
60
+ sat?: string;
61
+ hdop?: number;
62
+ vdop?: number;
63
+ pdop?: number;
64
+ ageofdgpsdata?: number;
65
+ dgpsid?: DegreesType;
66
+ turn?: number;
67
+ extensions?: ExtensionsType;
68
+ }
69
+ export interface SportTrackType {
70
+ name?: string;
71
+ sport?: string;
72
+ trackseg?: SportRouteSegType[];
73
+ extensions?: ExtensionsType;
74
+ startTime?: number;
75
+ startLat?: LatitudeType;
76
+ startLon?: LongitudeType;
77
+ duration?: number;
78
+ distance?: number;
79
+ endTime?: number;
80
+ endLat?: LatitudeType;
81
+ endLon?: LongitudeType;
82
+ __fit__sessionMesgType?: SessionMesgType;
83
+ }
84
+ export interface SportRouteSegType {
85
+ name?: string;
86
+ sport?: string;
87
+ points?: SportPointType[];
88
+ duration?: number;
89
+ distance?: number;
90
+ startTime?: number;
91
+ endTime?: number;
92
+ avgHeartRateBpm?: number;
93
+ maxHeartRateBpm?: number;
94
+ avgSpeed?: number;
95
+ maxSpeed?: number;
96
+ avgCadenceBpm?: number;
97
+ maxCadenceBpm?: number;
98
+ avgPower?: number;
99
+ maxPower?: number;
100
+ avgTemperature?: number;
101
+ maxTemperature?: number;
102
+ avgAltitude?: number;
103
+ maxEnhancedAltitude?: number;
104
+ totalAscent?: number;
105
+ totalDescent?: number;
106
+ calories?: number;
107
+ __tcx__Intensity?: IntensityType;
108
+ __tcx__TriggerMethod?: TriggerMethodType;
109
+ __tcx__Notes?: string;
110
+ __tcx__Extensions?: any;
111
+ __fit__lapMesgType?: LapMesgType;
112
+ }
package/package.json CHANGED
@@ -1,23 +1,40 @@
1
1
  {
2
2
  "name": "trackswap",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "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.",
5
- "main": "dist/index.js",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
8
  "exports": {
8
9
  ".": {
9
10
  "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs",
10
12
  "types": "./dist/index.d.ts"
11
13
  }
12
14
  },
13
15
  "files": [
14
- "dist/**/*",
16
+ "dist/index.js",
17
+ "dist/index.cjs",
18
+ "dist/index.d.ts",
19
+ "dist/TrackSwap.d.ts",
20
+ "dist/types.d.ts",
21
+ "dist/**/*.d.ts",
15
22
  "README.md",
16
23
  "LICENSE"
17
24
  ],
18
25
  "scripts": {
19
26
  "dev": "ts-node src/index.ts",
20
- "build": "tsc",
27
+ "clean": "rm -rf dist",
28
+ "build": "npm run clean && npm run build:types && npm run build:esm && npm run build:cjs && npm run build:optimize",
29
+ "build:types": "tsc --emitDeclarationOnly",
30
+ "build:esm": "NODE_ENV=production node build.config.js",
31
+ "build:cjs": "NODE_ENV=production FORMAT=cjs node build.config.js",
32
+ "build:dev": "npm run clean && npm run build:types && NODE_ENV=development node build.config.js",
33
+ "build:optimize": "node scripts/optimize-dist.js",
34
+ "build:js": "esbuild src/index.ts --bundle --platform=node --target=node14 --format=esm --outfile=dist/index.js --minify --sourcemap",
35
+ "build:tsc": "tsc && npm run minify",
36
+ "minify": "terser dist/**/*.js --compress --mangle --output dist/index.min.js --source-map",
37
+ "analyze": "NODE_ENV=production ANALYZE=true node build.config.js",
21
38
  "start": "node dist/index.js",
22
39
  "test:gpx": "cd example/gpx && rm -f output* test_*.json *_report.json *_encoded.xml && node test.js",
23
40
  "test:fit": "cd example/FIT && rm -rf output && node test.js",
@@ -40,7 +57,6 @@
40
57
  ],
41
58
  "author": "berber1016",
42
59
  "license": "MIT",
43
- "type": "module",
44
60
  "repository": {
45
61
  "type": "git",
46
62
  "url": "https://github.com/berber1016/trackswap.git"
@@ -54,6 +70,8 @@
54
70
  },
55
71
  "devDependencies": {
56
72
  "@types/node": "^22.15.24",
73
+ "esbuild": "^0.19.12",
74
+ "terser": "^5.27.0",
57
75
  "ts-node": "^10.9.2",
58
76
  "typescript": "^5.8.3"
59
77
  },