{"version":3,"file":"TrackServiceImpl.mjs","sources":["../../../../../../packages/sdk/plugins/Trackplayer/TrackServiceImpl.ts"],"sourcesContent":["import L from 'leaflet'\nimport { clone } from 'lodash-unified'\n\nimport dayjs from 'dayjs'\nimport { CanvasShipUtils } from '@map-sdk/sdk/utils/CanvasShipUtils'\nimport { CommUtils } from '@map-sdk/sdk/utils/CommUtils'\nimport { result } from '@map-sdk/sdk/plugins/Trackplayer/data'\nimport { trackPlayServiceImpl } from '@map-sdk/sdk/plugins/Trackplayer/TrackPlayServiceImpl'\nimport { trackSymbol } from '@map-sdk/sdk/plugins/Trackplayer/TrackSymbolImpl'\nimport type { LatLngExpression } from 'leaflet'\nimport type { CanvasShip } from '@map-sdk/sdk/model/CanvasShip'\n/**\n * 轨迹\n */\nexport class Track {\n  from: string | number = 0\n  lng: string | number = 0\n  lat: string | number = 0\n  utc: string | number = 0\n  mmsi: string | number = 0\n  sog: string | number = 0\n  hdg: string | number = 0\n  cog: string | number = 0\n  draught?: string\n  dest: undefined\n  eta: undefined\n  serverTime: undefined\n  shipName?: string\n  MMSI?: string\n  rot?: string\n  navistatus: any\n}\ninterface EmissionDataItem {\n  [key: string]: any\n  time: number\n  co2: number\n}\n\ninterface EmissionConfig {\n  datas: EmissionDataItem[]\n  fieldsMap: {\n    time: string\n    co2: string\n  }\n  scalesMap: {\n    co2: number\n  }\n  colorsMap: {\n    co2: any[] // Assuming this is an array of color objects or values\n  }\n}\n\ninterface TrackEmission {\n  utc: number\n  emissionCo2: number | null\n  emissionCo2Color: string | null\n  emissionCo2Count?: number\n}\nexport interface TrackItem {\n  trackId: string\n  data: any[]\n  trackLang: number | string\n  symbol: any\n  options: any\n  ship: any\n}\n\ninterface TrackServiceOptions {\n  from180: any\n  minStopTime: number\n  minSlowTime: number\n  minSuspectStopSpeed: number\n  maxStopSpeed: number\n  maxSlowSpeed: number\n  playSpeed: number\n  beginTime: number\n  playCallBack?: () => void\n  playGPSCallBack?: () => void\n  isVisiableWithNoSignal: boolean\n  showPlayObjLable: boolean\n}\n\nexport interface TrackPolyLineOptions {\n  maxStopSpeed: number\n  lableMap: Record<string, any>\n  showTimeType: string[]\n  notDiluteZoom: number[]\n  lineColor: string // 轨迹线颜色\n  lineWeight: number // 线粗细，默认：1\n  circleOverColor: string // 拐点，鼠标滑过时的颜色\n  dash: boolean // 是否为虚线，true：虚线，false：实线，默认：false\n  dashArray: number[] // 虚线参数，默认：[5,5]\n  startShow: boolean // 是否显示“起点”图标，默认值：true\n  endShow: boolean // 是否显示“终点”图标，默认值：true\n  directionShow: boolean // 轨迹方向三角是否展示，默认值：false\n  isEnablePlayer: boolean // 是否需要播放轨迹，默认值：false\n  isShowLable: boolean // 是否显示lable，默认值：true\n  lableFields: string[] // 轨迹点信息显示，默认值：[\"name\", \"mmsi\", \"sog\", \"cog\", \"utc\", \"kn\"]\n  shipColor?: string\n  shipLineColor?: string\n  from180?: number\n\n  tipHideTimeOut: number // 轨迹/航线，tip 超时关闭时间设置，默认：8000\n  startCircleType: number // 起始圆圈样式类型，0：不显示，1:同心圆，2：普通圆圈，与拐点相同，默认：1\n  endCircleType: number // 结束圆圈样式类型，0：不显示，1:同心圆，2：普通圆圈，与拐点相同，默认：1\n  startCircleColor: string // 起始圆圈填充色，默认：'#06c84a'\n  endCircleColor: string // 结束圆圈填充色，默认：'#f70006'\n  isAppend: boolean // 是否追加\n}\n\nexport class TrackServiceImpl {\n  private _map: any\n  private options: TrackServiceOptions\n  private items: { [key: string]: TrackItem }\n  private trackPlayService: any\n  mmCount = 0\n\n  constructor(map: any, options?: Partial<TrackServiceOptions>) {\n    this.options = {\n      minStopTime: 300,\n      minSlowTime: 300,\n      minSuspectStopSpeed: 3,\n      maxStopSpeed: 0.5,\n      maxSlowSpeed: 5,\n      from180: true,\n      playSpeed: 1,\n      beginTime: 0,\n      isVisiableWithNoSignal: true,\n      showPlayObjLable: true,\n    }\n\n    this.items = {}\n    this._map = map\n    this.options = { ...this.options, ...options }\n    this.trackPlayService = trackPlayServiceImpl(this._map, this.options)\n    this.trackPlayService.maxSupplementPointInterval = 0\n  }\n\n  /**\n   * 增加轨迹\n   * @params trackId String\t轨迹ID\n   * @params tracks Array\tTrack对象集合\n   * @params options Object\t设置信息\n   * @params ship CanvasShip\t船舶静态数据{name:船名,mmsi:MMSI,from:数据来源,navistatus:航行状态,draught:吃水}\n   */\n  add(\n    trackId: string,\n    trackData: any[],\n    options: Partial<TrackPolyLineOptions>,\n    shipInfo: Partial<CanvasShip>\n  ) {\n    // 处理from180参数\n    let from180 = this.options.from180\n    if (!options || CommUtils.isEmpty(options.from180)) {\n      from180 = options.from180\n    }\n\n    // 如果已经存在该轨迹ID，则先移除\n    if (this.has(trackId) && !options.isAppend) {\n      this.remove(trackId)\n    }\n\n    // 转换经纬度数据，如果from180标志为真\n    if (from180 === 1) {\n      trackData = CanvasShipUtils.objFrom180(trackData, '', 0)\n    }\n\n    // 自动设置视图边界\n    trackData = this.autoSetViewBounds(trackData)\n\n    // 合并选项参数\n    const finalOptions = Object.assign(\n      {},\n      {\n        addAndShowPlayer: true,\n      },\n      options\n    )\n\n    // 如果没有提供shipInfo，则初始化为空对象\n    if (!shipInfo) {\n      shipInfo = {}\n    }\n\n    // 计算轨迹语言\n    const trackLang = this.calculationTracklang(trackData)\n\n    // 添加到轨迹列表中\n    if (!this.items[trackId]) {\n      this.items[trackId] = {\n        trackId,\n        data: trackData,\n        trackLang,\n        symbol: null,\n        options: finalOptions,\n        ship: shipInfo,\n      }\n    } else {\n      this.items[trackId].data = [...this.items[trackId].data, ...trackData]\n    }\n\n    // 返回添加的轨迹项\n    return this.items[trackId]\n  }\n\n  autoSetViewBounds(trackData: any[]) {\n    // 如果轨迹列表为空，则直接返回原始数据\n    if (!this.items) {\n      return trackData\n    }\n\n    // 获取现有轨迹ID列表\n    const trackIds = Object.keys(this.items)\n\n    // 如果轨迹ID列表为空，则直接返回原始数据\n    if (!trackIds || trackIds.length === 0) {\n      return trackData\n    }\n\n    // 获取当前轨迹的中心点\n    const currentCenter = this.getCenterByTracks(trackData)\n\n    // 遍历现有轨迹，寻找中心点\n    let referenceCenter: L.LatLng = new L.LatLng(0, 0)\n    trackIds.forEach((trackId) => {\n      const item = this.items[trackId]\n      referenceCenter = this.getCenterByTracks(item.data)\n    })\n\n    // 如果没有找到参考中心点，则直接返回原始数据\n    if (!referenceCenter) {\n      return trackData\n    }\n\n    // 计算当前轨迹中心点与参考中心点的经度差\n    const lngDiff = Math.abs(referenceCenter.lng - currentCenter.lng)\n    const lngDiffPlus180 = Math.abs(\n      referenceCenter.lng - (currentCenter.lng + 180)\n    )\n    const lngDiffMinus180 = Math.abs(\n      referenceCenter.lng - (currentCenter.lng - 180)\n    )\n    const minLngDiff = Math.min(lngDiff, lngDiffPlus180, lngDiffMinus180)\n    let offset = 0\n\n    // 根据最小经度差确定偏移量\n    switch (minLngDiff) {\n      case lngDiff:\n        offset = 0\n        break\n      case lngDiffPlus180:\n        offset = 180\n        break\n      case lngDiffMinus180:\n        offset = -180\n    }\n\n    // 如果偏移量为0，则直接返回原始数据\n    if (offset === 0) {\n      return trackData\n    }\n\n    // 应用偏移量到所有点\n    const offsetData: any[] = []\n    trackData.forEach((point) => {\n      point.lng += offset\n      offsetData.push(point)\n    })\n\n    // 返回调整后的轨迹数据\n    return offsetData\n  }\n\n  getCenterByTracks(trackPoints: any[]) {\n    // 使用Leaflet的polyline方法根据轨迹点创建一个虚拟的线\n    // 然后获取这个线的边界（Bounds）并计算中心点\n    const bounds = L.polyline(trackPoints).getBounds()\n    return bounds.getCenter()\n  }\n  formateTrack(tracks: any[], shipname: string, mmsi: string) {\n    const formateTracks = []\n    for (const track of tracks) {\n      const point = new Track()\n      point.shipName = shipname\n      point.MMSI = mmsi\n      point.from = track.from\n      point.utc = track.utc\n      point.hdg = (track.hdg / 100).toFixed(1)\n      point.sog = (track.sog / 514).toFixed(1)\n      point.cog = (track.cog / 100).toFixed(1)\n      point.rot = (track.rot / 100).toFixed(1)\n      point.lng = (track.lon || track.lng) / 1000000\n      point.lat = track.lat / 1000000\n      point.navistatus = track.navistatus\n      formateTracks.push(point)\n    }\n    return formateTracks\n  }\n\n  /**\n   * 增加轨迹并展示\n   * @params trackId\tString\t轨迹ID\n   * @params tracks\tArray\tTrack对象集合\n   * @params options\tTrackPolyLineOptions\t设置信息\n   * @params ship\tCanvasShip\t船舶静态数据{name:船名,mmsi:MMSI,from:数据来源,navistatus:航行状态,draught:吃水}\n   * @params autoViewzoom\tboolea\t是否自适应展示,默认:true\n   * @return trackItem\n   */\n  addAndShow(\n    trackId: string,\n    tracks: any[],\n    options: Partial<TrackPolyLineOptions>,\n    ship: any,\n    autoViewzoom = true\n  ): TrackItem {\n    tracks = this.formateTrack(\n      tracks.length ? tracks : result,\n      ship.name || '测试数据',\n      ship.mmis || '123123'\n    )\n    this.add(trackId, tracks, options, ship)\n    return this.show(trackId, autoViewzoom)\n  }\n  /**\n   * 添加轨迹（根据参数自动获取轨迹数据）\n   * @params mmsi\tstring\tmmsi\n   * @params btime\tnumber\t起始时间戳，秒\n   * @params etime\tnumber\t结束时间戳，秒\n   * @params options\tObject\t设置信息\n   * @params callBack\tfunction\t回调方法\n   * @params tp\tnumber\t轨迹数据类型，0：普通,1：抽稀,2：完整，默认：0\n   * @params vy\tnumber\t航程，0：无,1：有，默认：0\n   * @params autoViewzoom\tboolea\t是否自适应展示,默认:true\n   */\n  addAndShowByUrl(\n    mmsi: string,\n    btime: string,\n    etime: string,\n    options: Partial<TrackPolyLineOptions>,\n    callBack: (arg0: any) => void,\n    tp: string | number | string[] | null | undefined,\n    vy: string | number | string[] | null | undefined,\n    autoViewzoom: boolean\n  ) {\n    let trackItem: TrackItem | undefined\n    const key = `${mmsi}_${btime}_${etime}`\n    try {\n      if (\n        (CommUtils.isEmpty(tp) && (tp = 0),\n        CommUtils.isEmpty(vy) && (vy = 0),\n        this.has(key))\n      )\n        trackItem = this.show(key)\n      else {\n        // mmsi, btime, etime, false, tp, vy\n        const trackInfo = this.getTrackInfoByUrl()\n        if (!trackInfo || 0 == trackInfo.length) return null\n        let shipByMmsi = {} as any\n        !this._map.shipsService &&\n          this._map.shipsService(this._map, {\n            enableAreaShip: false,\n            enableFleetShip: false,\n          })\n        this._map.shipsService &&\n          (shipByMmsi = this._map.shipsService.getShipByMmsi(mmsi, true))\n        !shipByMmsi && (shipByMmsi = {})\n        shipByMmsi.mmsi = mmsi\n        if (options) {\n          if (options.shipColor) {\n            shipByMmsi.color = options.shipColor\n          }\n          options.shipLineColor &&\n            (shipByMmsi.lineColor = options.shipLineColor)\n        }\n        trackItem = this.addAndShow(\n          key,\n          trackInfo,\n          options,\n          shipByMmsi,\n          autoViewzoom\n        )\n      }\n    } catch (e) {\n      console.error(e)\n    } finally {\n      callBack &&\n        setTimeout(() => {\n          callBack(trackItem)\n        }, 1),\n        CanvasShipUtils.closeLoadingPopup()\n    }\n    return trackItem\n  }\n\n  appendTracks(trackId: string, tracks: any[], aiDetectionList?: any[]) {\n    const item = this.items[trackId]\n    if (!item) {\n      console.error(\n        '未找到航线信息请先调用addAndShow进行展示首段信息后再调用该方法'\n      )\n      return\n    }\n    tracks = this.formateTrack(tracks, item.ship.name, item.ship.MMSI)\n    const lastPoint = item.data[item.data.length - 1]\n    lastPoint.isShowMarker = false\n    tracks = [lastPoint, ...tracks]\n    // tracks = [item.data[item.data.length - 1], ...tracks]\n    const mergeOptions = { ...item.options, isAppend: true }\n    this.add(trackId, tracks, mergeOptions, item.ship)\n    this._analysisTrack(trackId)\n    this._analysisEmission(tracks, this.getEmissionOptions(mergeOptions))\n    this.show(trackId, false, true)\n    item.symbol.appendLine(tracks, aiDetectionList)\n  }\n  appendFinish(trackId: string) {\n    const item = this.items[trackId]\n    item.symbol.resetCache()\n  }\n  getEmissionOptions(options: any) {\n    // 处理排放数据选项\n    const emissionOptions = options.emission\n      ? Object.assign(\n          true,\n          {\n            overlayMinStopTime: 1,\n            weight: 20,\n            colorsMap: {\n              default: 'rgba(0,0,0,0)',\n              co2: [\n                { value: 5, color: 'rgba(217,245,214,0.6)' },\n                { value: 10, color: 'rgba(98,210,86,0.8)' },\n                { value: 20, color: 'rgba(255,246,122,0.8)' },\n                { value: 30, color: 'rgba(255,233,40,0.8)' },\n                { value: 50, color: 'rgba(251,191,188,0.8)' },\n                { value: 3600, color: 'rgba(247,105,100,0.8)' },\n              ],\n            },\n            scalesMap: {\n              co2: 1000,\n            },\n            fieldsMap: {\n              time: 'datekey_rt',\n              co2: 'vessel_co2_day_atom_v2',\n            },\n            datas: [],\n          },\n          options.emission\n        )\n      : null\n    options.emission = emissionOptions\n    return emissionOptions\n  }\n\n  /**\n   * 显示指定轨迹\n   * @params trackId\tString\t轨迹ID\n   * @params autoViewzoom\tboolea\t是否自适应展示,默认:true\n   */\n  show(trackId: string, autoViewzoom = true, append = false) {\n    // 检查是否有该轨迹\n    if (this.has(trackId)) {\n      const item = this.items[trackId]\n\n      // 如果轨迹没有符号化，进行符号化处理\n      const options = item.options\n      if (!item.symbol) {\n        const trackLang = item.trackLang\n\n        // 处理排放数据选项\n        const emissionOptions = this.getEmissionOptions(options)\n\n        // 分析轨迹和排放数据\n        this._analysisTrack(trackId)\n        this._analysisEmission(item.data, emissionOptions)\n\n        // 创建轨迹符号\n        const trackOptions = L.extend(\n          this.options,\n          {\n            trackid: trackId,\n            trackLangCount: trackLang,\n          },\n          options\n        )\n        item.symbol = trackSymbol(this._map, item.data, item.ship, trackOptions)\n      }\n\n      // 定位缩放到合适位置\n      autoViewzoom && this._viewAllTrackInMap(trackId)\n\n      // 设置轨迹为新状态并显示\n      if (!append) {\n        item.symbol.trackNew = true\n        item.symbol.show()\n      }\n      // 更新船舶服务的z-index\n      if (this._map.shipsService) {\n        this._map.shipsService.setZIndex()\n      }\n\n      // 检查是否启用播放器并根据需要添加和显示\n      let isEnablePlayer = options.isEnablePlayer\n      isEnablePlayer = isEnablePlayer === null ? false : !!isEnablePlayer\n      const addAndShowPlayer = options.addAndShowPlayer\n\n      if (isEnablePlayer && addAndShowPlayer !== 1) {\n        this.trackPlayService.addPlayTrack(trackId, false, options.isAutoPlay)\n      }\n    }\n\n    // 刷新地图视图\n    // this._map.refreshView()\n\n    // 返回当前项\n    return this.items[trackId]\n  }\n\n  calculationTracklang(data: string | any[]) {\n    let md = 0\n    const dataLength = data.length\n    for (let i = 0; i < dataLength; i++) {\n      data[i].index = i\n      CommUtils.isEmpty(data[i].lng) && (data[i].lng = data[i].lon)\n      i + 1 < dataLength\n        ? ((data[i].md = CanvasShipUtils.getDistance(\n            data[i],\n            data[i + 1],\n            'nm'\n          )),\n          (data[i].cog = CanvasShipUtils.getAngleByLatLngToBigCircle(\n            data[i],\n            data[i + 1]\n          )))\n        : ((data[i].md = 0), (data[i].cog = 0))\n      md += data[i].md\n      data[i].kn = md - data[i].md\n    }\n\n    let countMd = 0\n    for (let i = dataLength - 1; i >= 0; i--)\n      i < dataLength - 1 && (countMd += data[i].md), (data[i].ed = countMd)\n    return md.toFixed(2)\n  }\n  _analysisTrack(trackIndex: string) {\n    const minStopTime = this.options.minStopTime // 最小停靠时间\n    const minSlowTime = this.options.minSlowTime // 最小慢行时间\n    const maxStopSpeed = this.options.maxStopSpeed // 最大停止速度\n    const maxSlowSpeed = this.options.maxSlowSpeed // 最大慢行速度\n    const minSuspectStopSpeed = this.options.minSuspectStopSpeed // 疑似停止的最小速度\n    const tracksData = this.items[trackIndex].data // 轨迹数据\n    const trackAnalysis = {\n      startTime: null,\n      endTime: null,\n      time: 0,\n      _time: '',\n      isShow: false,\n      tracks: [],\n      tracksHash: {},\n      type: null,\n    }\n    let currentTrack, nextTrack, prevTrack\n    let analysisInfo: any = null,\n      suspectStopInfo = null\n\n    for (let i = 0; i < tracksData.length; i++) {\n      currentTrack = tracksData[i]\n      nextTrack = tracksData[i + 1]\n      prevTrack = tracksData[i - 1]\n\n      const speed = currentTrack.sog\n      // 判断航速状态\n      const type =\n        speed <= maxStopSpeed ? 'stop' : speed < maxSlowSpeed ? 'slow' : 'none'\n      if (analysisInfo && analysisInfo.type === type && type !== 'none') {\n        analysisInfo.endTrackIndex = i\n        analysisInfo.count =\n          analysisInfo.endTrackIndex - analysisInfo.startTrackIndex + 1\n        analysisInfo.endTime = currentTrack.utc\n        analysisInfo.time = analysisInfo.endTime - analysisInfo.startTime\n        // console.log(CommUtils.dataFormat(1717455009000),analysisInfo.time*1000);\n        // 创建两个时间戳对象\n        const time1 = dayjs(analysisInfo.endTime)\n        const time2 = dayjs(analysisInfo.startTime)\n\n        // 计算时间差\n        const duration = time1.diff(time2)\n\n        // 获取时间差相差的天数、小时数、分钟数和秒数\n        const days = duration / 1000 / 60 / 60 / 24\n        const hours = (duration / 1000 / 60 / 60) % 24\n        const minutes = (duration / 1000 / 60) % 60\n        const seconds = (duration / 1000) % 60\n        analysisInfo._time = {\n          days,\n          hours,\n          minutes,\n          seconds,\n        } //CommUtils.dataFormat(analysisInfo.time, 'HH:mm:ss')\n      } else if (\n        (analysisInfo &&\n          analysisInfo.type === 'slow' &&\n          analysisInfo.time >= minSlowTime) ||\n        (analysisInfo &&\n          analysisInfo.type === 'stop' &&\n          analysisInfo.time >= minStopTime)\n      ) {\n        this._reSetTrackByAnalysisInfo(tracksData, analysisInfo)\n        analysisInfo = null\n      } else if (type !== 'none') {\n        analysisInfo = clone(trackAnalysis)\n        analysisInfo.trackId = trackIndex\n        analysisInfo.type = type\n        analysisInfo.startTrackIndex = i\n        analysisInfo.startTime = currentTrack.utc\n      }\n\n      if (\n        nextTrack &&\n        prevTrack &&\n        speed >= minSuspectStopSpeed &&\n        nextTrack.sog >= minSuspectStopSpeed\n      ) {\n        const avgSpeed = (speed + nextTrack.sog) / 2\n        const timeDiff = nextTrack.utc - currentTrack.utc\n        const timeInSeconds = timeDiff / 1000\n        const distanceCovered = currentTrack.md / timeInSeconds\n\n        if (timeInSeconds >= 0.5 && 0.6 * avgSpeed > distanceCovered) {\n          const stopMightSeconds = timeInSeconds - currentTrack.md / avgSpeed\n          suspectStopInfo = {\n            type: 'suspectStop',\n            startTrackIndex: i,\n            endTrackIndex: i + 1,\n            md: currentTrack.md,\n            time: timeInSeconds.toFixed(2),\n            _time: CommUtils.dataFormat(timeDiff),\n            sogAvg: distanceCovered.toFixed(1),\n            sogMight: avgSpeed.toFixed(1),\n            stopMight: stopMightSeconds.toFixed(2),\n            _stopMight: CommUtils.dataFormat(1000 * stopMightSeconds),\n          }\n          currentTrack.analysisInfo = clone(suspectStopInfo)\n        }\n      }\n    }\n\n    if (\n      (analysisInfo &&\n        analysisInfo.type === 'slow' &&\n        analysisInfo.time >= minSlowTime) ||\n      (analysisInfo &&\n        analysisInfo.type === 'stop' &&\n        analysisInfo.time >= minStopTime)\n    ) {\n      this._reSetTrackByAnalysisInfo(tracksData, analysisInfo)\n    }\n  }\n\n  _reSetTrackByAnalysisInfo(\n    tracks: any[],\n    analysisInfo: {\n      startTime?: null\n      endTime?: null\n      time?: number\n      _time?: string\n      isShow?: boolean\n      tracks?: never[]\n      tracksHash?: Record<string, any>\n      type?: null\n      startTrackIndex?: any\n      endTrackIndex?: any\n    }\n  ) {\n    // 检查分析信息和轨迹数据是否有效且轨迹数据不为空\n    if (analysisInfo && tracks && tracks.length > 0) {\n      // 遍历分析信息指示的轨迹索引范围\n      for (\n        let startIndex = analysisInfo.startTrackIndex;\n        startIndex <= analysisInfo.endTrackIndex;\n        startIndex++\n      ) {\n        tracks[startIndex].analysisInfo = { ...analysisInfo, index: startIndex }\n\n        // 如果这是第一次处理，则初始化mmCount\n        if (this.mmCount === null || typeof this.mmCount === 'undefined') {\n          this.mmCount = 0\n        }\n        // 增加处理计数\n        this.mmCount++\n      }\n    }\n  }\n  _analysisEmission(\n    tracks: TrackEmission[],\n    emissionConfig?: EmissionConfig\n  ): TrackEmission[] {\n    if (emissionConfig) {\n      const emissionData: {\n        [key: number]: {\n          time: number\n          _time: number\n          co2h: number\n          co2s: number\n        }\n      } = {}\n      emissionConfig.datas.forEach((dataItem) => {\n        const time = dataItem[emissionConfig.fieldsMap.time]\n        const dailyCo2 =\n          dataItem[emissionConfig.fieldsMap.co2] /\n          emissionConfig.scalesMap.co2 /\n          24\n        const hourlyCo2 = dailyCo2 / 3600\n        emissionData[time] = {\n          time,\n          _time: new Date(time).getTime() / 1000,\n          co2h: dailyCo2,\n          co2s: hourlyCo2,\n        }\n      })\n\n      let previousTimestamp = null\n      let accumulatedEmission = 0\n      for (const track of tracks) {\n        const dateStr = CommUtils.dataFormat(\n          new Date(1000 * track.utc),\n          'YYYY-MM-DD'\n        )\n        const emissionForDay = emissionData[dateStr]\n\n        if (emissionForDay) {\n          track.emissionCo2 = emissionForDay.co2h\n          track.emissionCo2Color = this._getTrackEmissionColor(\n            track.emissionCo2,\n            emissionConfig.colorsMap.co2\n          )\n          if (previousTimestamp !== null) {\n            accumulatedEmission +=\n              (track.utc - previousTimestamp) * emissionForDay.co2s\n          }\n        } else {\n          track.emissionCo2 = null\n          track.emissionCo2Color = null\n        }\n        track.emissionCo2Count = accumulatedEmission\n        previousTimestamp = track.utc\n      }\n    } else {\n      tracks.forEach((track) => {\n        Object.assign(track, {\n          emissionCo2: null,\n          emissionCo2Color: null,\n          emissionCo2Count: null,\n        })\n      })\n    }\n\n    return tracks\n  }\n  _getTrackEmissionColor(\n    emissionValue: number | null,\n    segments: string | any[]\n  ) {\n    if (!emissionValue) return\n    for (let index = 0; index < segments.length; index++) {\n      if (\n        index === segments.length - 1 ||\n        emissionValue < segments[index].value\n      ) {\n        return segments[index].color\n      }\n    }\n    return null\n  }\n  _getTrackEmissionCount(\n    startTimeInSeconds: number,\n    endTimeInSeconds: number,\n    co2EmissionData: { [x: string]: { co2s: any } }\n  ) {\n    const startDate = new Date(startTimeInSeconds * 1000)\n    const endDate = new Date(endTimeInSeconds * 1000)\n    const currentDateStr = CommUtils.dataFormat(startDate, 'yyyy-MM-dd')\n    let totalEmission = 0\n\n    if (currentDateStr === CommUtils.dataFormat(endDate, 'yyyy-MM-dd')) {\n      totalEmission =\n        (endTimeInSeconds - startTimeInSeconds) *\n        ((co2EmissionData[currentDateStr] &&\n          co2EmissionData[currentDateStr].co2s) ||\n          0)\n    } else {\n      let currentTimeInSeconds = startTimeInSeconds,\n        nextDayStartTimeInSeconds =\n          new Date(currentDateStr).getTime() / 1000 + 50400,\n        nextDayStr = CommUtils.dataFormat(\n          nextDayStartTimeInSeconds * 1000,\n          'yyyy-MM-dd'\n        ),\n        lastDateKey = nextDayStr\n\n      if (currentTimeInSeconds < endTimeInSeconds) {\n        totalEmission +=\n          (nextDayStartTimeInSeconds - currentTimeInSeconds) *\n          ((co2EmissionData[nextDayStr] && co2EmissionData[nextDayStr].co2s) ||\n            0)\n\n        currentTimeInSeconds = nextDayStartTimeInSeconds\n        lastDateKey = nextDayStr\n        nextDayStartTimeInSeconds += 50400\n        nextDayStr = CommUtils.dataFormat(\n          nextDayStartTimeInSeconds * 1000,\n          'yyyy-MM-dd'\n        )\n      }\n      totalEmission +=\n        (endTimeInSeconds - currentTimeInSeconds) *\n        ((co2EmissionData[lastDateKey] && co2EmissionData[lastDateKey].co2s) ||\n          0)\n    }\n    return totalEmission\n  }\n\n  /**\n   * 可视范围同时显示所有轨迹\n   * @params trackId\tstring\t轨迹ID，可为空，为空则适应所有轨迹\n   */\n  _viewAllTrackInMap(trackId: string, options?: undefined) {\n    const latlngs: LatLngExpression[] = []\n    let item = {}\n    CanvasShipUtils.isEmpty(trackId)\n      ? (item = this.items)\n      : (item[trackId] = this.items[trackId])\n    for (const key in item)\n      if (item[key] && item[key].symbol) {\n        const data = item[key].data\n        if (data && data.length) {\n          let lng = data[0].lng\n          latlngs.push([data[0].lat, lng])\n          lng = data[data.length - 1].lng\n          latlngs.push([data[data.length - 1].lat, lng])\n          for (let i = 1; i < data.length - 2; i++) {\n            latlngs.push([data[i].lat, data[i].lng])\n          }\n        }\n      }\n    if (latlngs.length > 0) {\n      this._map.fitBounds(\n        CanvasShipUtils.getLatLngBoundsBoxArea(latlngs, this._map),\n        options\n      )\n    }\n  }\n  /**\n   * 隐藏指定轨迹\n   * @params trackId\tString\t轨迹ID\n   */\n  _hide(trackId: string) {\n    if (this.has(trackId)) {\n      const item = this.items[trackId].symbol\n      item && (item.hide(), (this.items[trackId].symbol = null))\n    }\n    this.trackPlayService.removeTracks([trackId])\n  }\n  /**\n   * 隐藏指定轨迹\n   * @params trackId\tString\t轨迹ID\n   */\n  hide(trackId: string) {\n    this._hide(trackId)\n    this.refreshView()\n  }\n  /**\n   * 隐藏全部轨迹\n   */\n  hideAll() {\n    for (const item in this.items) this.hide(item)\n    this.refreshView()\n  }\n  _remove(trackId: string) {\n    this.hide(trackId)\n    delete this.items[trackId]\n  }\n  /**\n   * 删除指定轨迹\n   * @params  trackId\tString\t轨迹ID\n   */\n  remove(trackId: any) {\n    this._remove(trackId)\n    this.refreshView()\n  }\n  /**\n   * 删除所有轨迹\n   */\n  removeAll() {\n    for (const item in this.items) this._remove(item)\n  }\n  refreshView() {\n    this._map.refreshView && this._map.refreshView()\n    this._map.shipsService &&\n      (!this.hasTrackIsShow()\n        ? this._map.shipsService.restoreZIndex()\n        : this._map.shipsService.setZIndex(90))\n  }\n  /**\n   * 获取轨迹对象集合\n   */\n  getItems() {\n    return this.items\n  }\n  /**\n   * 获取轨迹数量\n   */\n  getLength() {\n    return Object.keys(this.items).length\n  }\n  /**\n   * 获取所有轨迹集合\n   */\n  getValues() {\n    const tracks = []\n    for (const key in this.items) tracks.push(this.items[key])\n    return tracks\n  }\n  /**\n   * 获取所有轨迹ID集合\n   */\n  getKeys() {\n    return Object.keys(this.items)\n  }\n  /**\n   * 查询轨迹数据\n   * @params mmsi\tstring\tmmsi\n   * @params btime\tnumber\t起始时间戳，秒\n   * @params etime\tnumber\t结束时间戳，秒\n   * @params going\tboolean\t是否为连续查询，默认：false\n   * @params tp\tnumber\t轨迹数据类型，0：普通,1：抽稀,2：完整，默认：0\n   * @params vy\tnumber\t航程，0：无,1：有，默认：0\n   * mmsi, btime, etime, going, tp, vy\n   */\n  getTrackInfoByUrl() {\n    const tracks: any[] = result\n    // if (CommUtils.isEmpty(mmsi) || CommUtils.isEmpty(btime) || CommUtils.isEmpty(etime) || btime > etime)\n    //   return [];\n    // CommUtils.isEmpty(going) && (going = false)\n    // CommUtils.isEmpty(tp) && (tp = 0)\n    // CommUtils.isEmpty(vy) && (vy = 0)\n    // let url = ShipxyOptions.shipDataServer.getShipTrackUrl;\n    // url = url.replace('{1}', mmsi).replace('{2}', btime).replace('{3}', etime).replace('{4}', tp).replace('{5}', vy),\n    //   this._map.options.ak && (url = url.replace('{k}', this._map.options.ak)),\n    //   jQuery.ajaxSettings.async = false,\n    //   jQuery.get(url, function (resData) {\n    //     let parseData = L.ParseUtils.parseTrackAPI(resData, tp, vy);\n    //     if (parseData && 0 == parseData.status && parseData.data) {\n    //       tracks = tracks.concat(parseData.data)\n    //       if (parseData.continue) {\n    //         let utc = parseData.data[parseData.data.length - 1].utc\n    //         let currentSegment = this.getTrackInfoByUrl(mmsi, utc, etime, true, tp, vy);\n    //         tracks = tracks.concat(currentSegment);\n    //       }\n    //     }\n\n    //   })\n    return tracks\n  }\n  /**\n   * 是否包含指定轨迹\n   * @params trackId\tString\t轨迹ID\n   */\n  has(trackId: string) {\n    return trackId in this.items\n  }\n  /**\n   * 是否有轨迹显示\n   */\n  hasTrackIsShow() {\n    let IsShow = false\n    for (const key in this.items)\n      if (this.items[key].symbol) {\n        IsShow = true\n        break\n      }\n    return IsShow\n  }\n  /**\n   * 获取指定轨迹\n   * @params trackId\tString\t轨迹ID\n   */\n  get(trackId: string) {\n    return this.has(trackId) ? this.items[trackId] : undefined\n  }\n  setZIndex(zIndex = 160) {\n    this._map.canvas_track && this._map.canvas_track._container\n      ? (this._map.canvas_track._container.style.zIndex = zIndex)\n      : console.error('canvas_track is null')\n  }\n}\n\n// 确保引入或定义任何在原始JavaScript代码中使用的外部API或类型\n"],"names":["Track","constructor","this","from","lng","lat","utc","mmsi","sog","hdg","cog","TrackServiceImpl","e","t","mmCount","options","minStopTime","minSlowTime","minSuspectStopSpeed","maxStopSpeed","maxSlowSpeed","from180","playSpeed","beginTime","isVisiableWithNoSignal","showPlayObjLable","items","_map","trackPlayService","E","maxSupplementPointInterval","add","o","n","s","p","isEmpty","has","isAppend","remove","d","objFrom180","autoSetViewBounds","i","Object","assign","addAndShowPlayer","a","calculationTracklang","data","trackId","trackLang","symbol","ship","keys","length","getCenterByTracks","k","LatLng","forEach","h","r","Math","abs","m","min","l","c","push","polyline","getBounds","getCenter","formateTrack","shipName","MMSI","toFixed","rot","lon","navistatus","addAndShow","x","name","mmis","show","addAndShowByUrl","getTrackInfoByUrl","shipsService","enableAreaShip","enableFleetShip","getShipByMmsi","shipColor","color","shipLineColor","lineColor","setTimeout","closeLoadingPopup","appendTracks","isShowMarker","_analysisTrack","_analysisEmission","getEmissionOptions","appendLine","appendFinish","resetCache","emission","overlayMinStopTime","weight","colorsMap","default","co2","value","scalesMap","fieldsMap","time","datas","extend","trackid","trackLangCount","O","_viewAllTrackInMap","trackNew","setZIndex","isEnablePlayer","addPlayTrack","isAutoPlay","index","md","getDistance","getAngleByLatLngToBigCircle","kn","ed","startTime","endTime","_time","isShow","tracks","tracksHash","type","_","u","f","b","endTrackIndex","count","startTrackIndex","y","w","S","g","diff","T","v","L","P","days","hours","minutes","seconds","_reSetTrackByAnalysisInfo","C","dataFormat","sogAvg","sogMight","stopMight","_stopMight","analysisInfo","Date","getTime","co2h","co2s","emissionCo2","emissionCo2Color","_getTrackEmissionColor","emissionCo2Count","_getTrackEmissionCount","fitBounds","getLatLngBoundsBoxArea","_hide","hide","removeTracks","refreshView","hideAll","_remove","removeAll","hasTrackIsShow","restoreZIndex","getItems","getLength","getValues","getKeys","get","canvas_track","_container","style","zIndex"],"mappings":"qWAAmc,MAAMA,EAAM,WAAAC,GAAcC,KAAKC,KAAK,EAAED,KAAKE,IAAI,EAAEF,KAAKG,IAAI,EAAEH,KAAKI,IAAI,EAAEJ,KAAKK,KAAK,EAAEL,KAAKM,IAAI,EAAEN,KAAKO,IAAI,EAAEP,KAAKQ,IAAI,CAAC,EAAS,MAAMC,EAAiB,WAAAV,CAAYW,EAAEC,GAAGX,KAAKY,QAAQ,EAAEZ,KAAKa,QAAQ,CAACC,YAAY,IAAIC,YAAY,IAAIC,oBAAoB,EAAEC,aAAa,GAAGC,aAAa,EAAEC,SAAQ,EAAGC,UAAU,EAAEC,UAAU,EAAEC,wBAAuB,EAAGC,kBAAiB,GAAIvB,KAAKwB,MAAM,CAAE,EAACxB,KAAKyB,KAAKf,EAAEV,KAAKa,QAAQ,IAAIb,KAAKa,WAAWF,GAAGX,KAAK0B,iBAAiBC,EAAE3B,KAAKyB,KAAKzB,KAAKa,SAASb,KAAK0B,iBAAiBE,2BAA2B,CAAC,CAAC,GAAAC,CAAInB,EAAEC,EAAEmB,EAAEC,GAAG,IAAIC,EAAEhC,KAAKa,QAAQM,UAAUW,GAAGG,EAAEC,QAAQJ,EAAEX,YAAYa,EAAEF,EAAEX,SAASnB,KAAKmC,IAAIzB,KAAKoB,EAAEM,UAAUpC,KAAKqC,OAAO3B,GAAO,IAAJsB,IAAQrB,EAAE2B,EAAEC,WAAW5B,EAAE,GAAG,IAAIA,EAAEX,KAAKwC,kBAAkB7B,GAAG,MAAM8B,EAAEC,OAAOC,OAAO,CAAE,EAAC,CAACC,kBAAiB,GAAId,GAAGC,IAAIA,EAAE,CAAA,GAAI,MAAMc,EAAE7C,KAAK8C,qBAAqBnC,GAAG,OAAOX,KAAKwB,MAAMd,GAAGV,KAAKwB,MAAMd,GAAGqC,KAAK,IAAI/C,KAAKwB,MAAMd,GAAGqC,QAAQpC,GAAGX,KAAKwB,MAAMd,GAAG,CAACsC,QAAQtC,EAAEqC,KAAKpC,EAAEsC,UAAUJ,EAAEK,OAAO,KAAKrC,QAAQ4B,EAAEU,KAAKpB,GAAG/B,KAAKwB,MAAMd,EAAE,CAAC,iBAAA8B,CAAkB9B,GAAG,IAAIV,KAAKwB,MAAM,OAAOd,EAAE,MAAMC,EAAE+B,OAAOU,KAAKpD,KAAKwB,OAAO,IAAIb,GAAc,IAAXA,EAAE0C,OAAW,OAAO3C,EAAE,MAAMoB,EAAE9B,KAAKsD,kBAAkB5C,GAAG,IAAIqB,EAAE,IAAIwB,EAAEC,OAAO,EAAE,GAAG,GAAG7C,EAAE8C,SAAQC,IAAI,MAAMC,EAAE3D,KAAKwB,MAAMkC,GAAG3B,EAAE/B,KAAKsD,kBAAkBK,EAAEZ,UAAShB,EAAE,OAAOrB,EAAE,MAAMsB,EAAE4B,KAAKC,IAAI9B,EAAE7B,IAAI4B,EAAE5B,KAAKuC,EAAEmB,KAAKC,IAAI9B,EAAE7B,KAAK4B,EAAE5B,IAAI,MAAM2C,EAAEe,KAAKC,IAAI9B,EAAE7B,KAAK4B,EAAE5B,IAAI,MAAM4D,EAAEF,KAAKG,IAAI/B,EAAES,EAAEI,GAAG,IAAImB,EAAE,EAAE,OAAOF,GAAG,KAAK9B,EAAEgC,EAAE,EAAE,MAAM,KAAKvB,EAAEuB,EAAE,IAAI,MAAM,KAAKnB,EAAEmB,GAAG,IAAI,GAAO,IAAJA,EAAM,OAAOtD,EAAE,MAAMuD,EAAE,GAAG,OAAOvD,EAAE+C,SAAQC,IAAIA,EAAExD,KAAK8D,EAAEC,EAAEC,KAAKR,MAAKO,CAAC,CAAC,iBAAAX,CAAkB5C,GAAG,OAAO6C,EAAEY,SAASzD,GAAG0D,YAAYC,WAAW,CAAC,YAAAC,CAAa5D,EAAEC,EAAEmB,GAAG,MAAMC,EAAE,GAAG,IAAI,MAAMC,KAAKtB,EAAE,CAAC,MAAM+B,EAAE,IAAI3C,EAAM2C,EAAE8B,SAAS5D,EAAE8B,EAAE+B,KAAK1C,EAAEW,EAAExC,KAAK+B,EAAE/B,KAAKwC,EAAErC,IAAI4B,EAAE5B,IAAIqC,EAAElC,KAAKyB,EAAEzB,IAAI,KAAKkE,QAAQ,GAAGhC,EAAEnC,KAAK0B,EAAE1B,IAAI,KAAKmE,QAAQ,GAAGhC,EAAEjC,KAAKwB,EAAExB,IAAI,KAAKiE,QAAQ,GAAGhC,EAAEiC,KAAK1C,EAAE0C,IAAI,KAAKD,QAAQ,GAAGhC,EAAEvC,KAAK8B,EAAE2C,KAAK3C,EAAE9B,KAAK,IAAIuC,EAAEtC,IAAI6B,EAAE7B,IAAI,IAAIsC,EAAEmC,WAAW5C,EAAE4C,WAAW7C,EAAEmC,KAAKzB,EAAE,CAAC,OAAOV,CAAC,CAAC,UAAA8C,CAAWnE,EAAEC,EAAEmB,EAAEC,EAAEC,GAAE,GAAI,OAAOrB,EAAEX,KAAKsE,aAAa3D,EAAE0C,OAAO1C,EAAEmE,EAAE/C,EAAEgD,MAAM,OAA2BhD,EAAEiD,MAAM,UAAUhF,KAAK6B,IAAInB,EAAEC,EAAEmB,EAAEC,GAAG/B,KAAKiF,KAAKvE,EAAEsB,EAAE,CAAC,eAAAkD,CAAgBxE,EAAEC,EAAEmB,EAAEC,EAAEC,EAAES,EAAEI,EAAEiB,GAAG,IAAIE,EAAE,MAAMC,EAAE,GAAGvD,KAAKC,KAAKmB,IAAI,IAAI,GAAGG,EAAEC,QAAQO,KAAKA,EAAE,GAAGR,EAAEC,QAAQW,KAAKA,EAAE,GAAG7C,KAAKmC,IAAI8B,GAAGD,EAAEhE,KAAKiF,KAAKhB,OAAO,CAAC,MAAMP,EAAE1D,KAAKmF,oBAAoB,IAAIzB,GAAa,GAAVA,EAAEL,OAAU,OAAO,KAAK,IAAIM,EAAE,CAAE,GAAE3D,KAAKyB,KAAK2D,cAAcpF,KAAKyB,KAAK2D,aAAapF,KAAKyB,KAAK,CAAC4D,gBAAe,EAAGC,iBAAgB,IAAKtF,KAAKyB,KAAK2D,eAAezB,EAAE3D,KAAKyB,KAAK2D,aAAaG,cAAc7E,GAAE,KAAMiD,IAAIA,EAAE,CAAE,GAAEA,EAAEtD,KAAKK,EAAEqB,IAAIA,EAAEyD,YAAY7B,EAAE8B,MAAM1D,EAAEyD,WAAWzD,EAAE2D,gBAAgB/B,EAAEgC,UAAU5D,EAAE2D,gBAAgB1B,EAAEhE,KAAK6E,WAAWZ,EAAEP,EAAE3B,EAAE4B,EAAEG,EAAE,CAAC,CAAC,MAAMJ,GAAmB,CAAC,QAAQ1B,GAAG4D,YAAW,KAAK5D,EAAEgC,KAAI,GAAG1B,EAAEuD,mBAAmB,CAAC,OAAO7B,CAAC,CAAC,YAAA8B,CAAapF,EAAEC,EAAEmB,GAAG,MAAMC,EAAE/B,KAAKwB,MAAMd,GAAG,IAAIqB,EAA2L,OAAOpB,EAAEX,KAAKsE,aAAa3D,EAAEoB,EAAEoB,KAAK4B,KAAKhD,EAAEoB,KAAKqB,MAAM,MAAMxC,EAAED,EAAEgB,KAAKhB,EAAEgB,KAAKM,OAAO,GAAGrB,EAAE+D,cAAa,EAAGpF,EAAE,CAACqB,KAAKrB,GAAG,MAAM8B,EAAE,IAAIV,EAAElB,QAAQuB,UAAS,GAAIpC,KAAK6B,IAAInB,EAAEC,EAAE8B,EAAEV,EAAEoB,MAAMnD,KAAKgG,eAAetF,GAAGV,KAAKiG,kBAAkBtF,EAAEX,KAAKkG,mBAAmBzD,IAAIzC,KAAKiF,KAAKvE,GAAE,GAAG,GAAIqB,EAAEmB,OAAOiD,WAAWxF,EAAEmB,EAAE,CAAC,YAAAsE,CAAa1F,GAAGV,KAAKwB,MAAMd,GAAGwC,OAAOmD,YAAY,CAAC,kBAAAH,CAAmBxF,GAAG,MAAMC,EAAED,EAAE4F,SAAS5D,OAAOC,QAAO,EAAG,CAAC4D,mBAAmB,EAAEC,OAAO,GAAGC,UAAU,CAACC,QAAQ,gBAAgBC,IAAI,CAAC,CAACC,MAAM,EAAEnB,MAAM,yBAAyB,CAACmB,MAAM,GAAGnB,MAAM,uBAAuB,CAACmB,MAAM,GAAGnB,MAAM,yBAAyB,CAACmB,MAAM,GAAGnB,MAAM,wBAAwB,CAACmB,MAAM,GAAGnB,MAAM,yBAAyB,CAACmB,MAAM,KAAKnB,MAAM,2BAA2BoB,UAAU,CAACF,IAAI,KAAKG,UAAU,CAACC,KAAK,aAAaJ,IAAI,0BAA0BK,MAAM,IAAItG,EAAE4F,UAAU,KAAK,OAAO5F,EAAE4F,SAAS3F,EAAEA,CAAC,CAAC,IAAAsE,CAAKvE,EAAEC,GAAE,EAAGmB,GAAE,GAAI,GAAG9B,KAAKmC,IAAIzB,GAAG,CAAC,MAAMqB,EAAE/B,KAAKwB,MAAMd,GAAGsB,EAAED,EAAElB,QAAQ,IAAIkB,EAAEmB,OAAO,CAAC,MAAMY,EAAE/B,EAAEkB,UAAUe,EAAEhE,KAAKkG,mBAAmBlE,GAAGhC,KAAKgG,eAAetF,GAAGV,KAAKiG,kBAAkBlE,EAAEgB,KAAKiB,GAAG,MAAMC,EAAEV,EAAE0D,OAAOjH,KAAKa,QAAQ,CAACqG,QAAQxG,EAAEyG,eAAerD,GAAG9B,GAAGD,EAAEmB,OAAOkE,EAAEpH,KAAKyB,KAAKM,EAAEgB,KAAKhB,EAAEoB,KAAKc,EAAE,CAACtD,GAAGX,KAAKqH,mBAAmB3G,GAAGoB,IAAIC,EAAEmB,OAAOoE,UAAS,EAAGvF,EAAEmB,OAAO+B,QAAQjF,KAAKyB,KAAK2D,cAAcpF,KAAKyB,KAAK2D,aAAamC,YAAY,IAAI9E,EAAET,EAAEwF,eAAe/E,EAAM,OAAJA,KAAcA,EAAE,MAAMI,EAAEb,EAAEY,iBAAiBH,GAAO,IAAJI,GAAO7C,KAAK0B,iBAAiB+F,aAAa/G,GAAE,EAAGsB,EAAE0F,WAAW,CAAC,OAAO1H,KAAKwB,MAAMd,EAAE,CAAC,oBAAAoC,CAAqBpC,GAAG,IAAIC,EAAE,EAAE,MAAMmB,EAAEpB,EAAE2C,OAAO,IAAI,IAAIrB,EAAE,EAAEA,EAAEF,EAAEE,IAAItB,EAAEsB,GAAG2F,MAAM3F,EAAEC,EAAEC,QAAQxB,EAAEsB,GAAG9B,OAAOQ,EAAEsB,GAAG9B,IAAIQ,EAAEsB,GAAG2C,KAAK3C,EAAE,EAAEF,GAAGpB,EAAEsB,GAAG4F,GAAGtF,EAAEuF,YAAYnH,EAAEsB,GAAGtB,EAAEsB,EAAE,GAAG,MAAMtB,EAAEsB,GAAGxB,IAAI8B,EAAEwF,4BAA4BpH,EAAEsB,GAAGtB,EAAEsB,EAAE,MAAMtB,EAAEsB,GAAG4F,GAAG,EAAElH,EAAEsB,GAAGxB,IAAI,GAAGG,GAAGD,EAAEsB,GAAG4F,GAAGlH,EAAEsB,GAAG+F,GAAGpH,EAAED,EAAEsB,GAAG4F,GAAG,IAAI7F,EAAE,EAAE,IAAI,IAAIC,EAAEF,EAAE,EAAEE,GAAG,EAAEA,IAAIA,EAAEF,EAAE,IAAIC,GAAGrB,EAAEsB,GAAG4F,IAAIlH,EAAEsB,GAAGgG,GAAGjG,EAAE,OAAOpB,EAAE8D,QAAQ,EAAE,CAAC,cAAAuB,CAAetF,GAAG,MAAMC,EAAEX,KAAKa,QAAQC,YAAYgB,EAAE9B,KAAKa,QAAQE,YAAYgB,EAAE/B,KAAKa,QAAQI,aAAae,EAAEhC,KAAKa,QAAQK,aAAauB,EAAEzC,KAAKa,QAAQG,oBAAoB6B,EAAE7C,KAAKwB,MAAMd,GAAGqC,KAAKe,EAAE,CAACmE,UAAU,KAAKC,QAAQ,KAAKnB,KAAK,EAAEoB,MAAM,GAAGC,QAAO,EAAGC,OAAO,GAAGC,WAAW,CAAA,EAAGC,KAAK,MAAM,IAAIvE,EAAEC,EAAEP,EAAEC,EAAE,KAAK6E,EAAE,KAAK,IAAI,IAAIC,EAAE,EAAEA,EAAE5F,EAAEQ,OAAOoF,IAAI,CAACzE,EAAEnB,EAAE4F,GAAGxE,EAAEpB,EAAE4F,EAAE,GAAG/E,EAAEb,EAAE4F,EAAE,GAAG,MAAMC,EAAE1E,EAAE1D,IAAIqI,EAAED,GAAG3G,EAAE,OAAO2G,EAAE1G,EAAE,OAAO,OAAO,GAAG2B,GAAGA,EAAE4E,OAAOI,GAAO,SAAJA,EAAW,CAAChF,EAAEiF,cAAcH,EAAE9E,EAAEkF,MAAMlF,EAAEiF,cAAcjF,EAAEmF,gBAAgB,EAAEnF,EAAEuE,QAAQlE,EAAE5D,IAAIuD,EAAEoD,KAAKpD,EAAEuE,QAAQvE,EAAEsE,UAAU,MAAMc,EAAEC,EAAErF,EAAEuE,SAASe,EAAED,EAAErF,EAAEsE,WAAWiB,EAAEH,EAAEI,KAAKF,GAAGG,EAAEF,EAAE,IAAI,GAAG,GAAG,GAAGG,EAAEH,EAAE,IAAI,GAAG,GAAG,GAAGI,EAAEJ,EAAE,IAAI,GAAG,GAAGK,EAAEL,EAAE,IAAI,GAAGvF,EAAEwE,MAAM,CAACqB,KAAKJ,EAAEK,MAAMJ,EAAEK,QAAQJ,EAAEK,QAAQJ,EAAE,MAAM5F,GAAY,SAATA,EAAE4E,MAAe5E,EAAEoD,MAAMjF,GAAG6B,GAAY,SAATA,EAAE4E,MAAe5E,EAAEoD,MAAMpG,GAAGX,KAAK4J,0BAA0B/G,EAAEc,GAAGA,EAAE,MAAU,SAAJgF,IAAahF,EAAEkG,EAAE/F,GAAGH,EAAEX,QAAQtC,EAAEiD,EAAE4E,KAAKI,EAAEhF,EAAEmF,gBAAgBL,EAAE9E,EAAEsE,UAAUjE,EAAE5D,KAAK,GAAG6D,GAAGP,GAAGgF,GAAGjG,GAAGwB,EAAE3D,KAAKmC,EAAE,CAAC,MAAMsG,GAAGL,EAAEzE,EAAE3D,KAAK,EAAE2I,EAAEhF,EAAE7D,IAAI4D,EAAE5D,IAAI8I,EAAED,EAAE,IAAIG,EAAEpF,EAAE4D,GAAGsB,EAAE,GAAGA,GAAG,IAAI,GAAGH,EAAEK,EAAE,CAAC,MAAMC,EAAEH,EAAElF,EAAE4D,GAAGmB,EAAEP,EAAE,CAACD,KAAK,cAAcO,gBAAgBL,EAAEG,cAAcH,EAAE,EAAEb,GAAG5D,EAAE4D,GAAGb,KAAKmC,EAAEzE,QAAQ,GAAG0D,MAAMlG,EAAE6H,WAAWb,GAAGc,OAAOX,EAAE3E,QAAQ,GAAGuF,SAASjB,EAAEtE,QAAQ,GAAGwF,UAAUZ,EAAE5E,QAAQ,GAAGyF,WAAWjI,EAAE6H,WAAW,IAAIT,IAAIrF,EAAEmG,aAAaN,EAAErB,EAAE,CAAC,CAAC,EAAE7E,GAAY,SAATA,EAAE4E,MAAe5E,EAAEoD,MAAMjF,GAAG6B,GAAY,SAATA,EAAE4E,MAAe5E,EAAEoD,MAAMpG,IAAIX,KAAK4J,0BAA0B/G,EAAEc,EAAE,CAAC,yBAAAiG,CAA0BlJ,EAAEC,GAAG,GAAGA,GAAGD,GAAGA,EAAE2C,OAAO,EAAE,IAAI,IAAIvB,EAAEnB,EAAEmI,gBAAgBhH,GAAGnB,EAAEiI,cAAc9G,IAAIpB,EAAEoB,GAAGqI,aAAa,IAAIxJ,EAAEgH,MAAM7F,IAAmB,OAAf9B,KAAKY,cAAqC,IAAdZ,KAAKY,WAAwBZ,KAAKY,QAAQ,GAAGZ,KAAKY,SAAS,CAAC,iBAAAqF,CAAkBvF,EAAEC,GAAG,GAAGA,EAAE,CAAC,MAAMmB,EAAE,CAAA,EAAGnB,EAAEqG,MAAMvD,SAAQhB,IAAI,MAAMI,EAAEJ,EAAE9B,EAAEmG,UAAUC,MAAMjD,EAAErB,EAAE9B,EAAEmG,UAAUH,KAAKhG,EAAEkG,UAAUF,IAAI,GAAG3C,EAAEF,EAAE,KAAKhC,EAAEe,GAAG,CAACkE,KAAKlE,EAAEsF,MAAM,IAAIiC,KAAKvH,GAAGwH,UAAU,IAAIC,KAAKxG,EAAEyG,KAAKvG,MAAK,IAAIjC,EAAE,KAAKC,EAAE,EAAE,IAAI,MAAMS,KAAK/B,EAAE,CAAC,MAAMmC,EAAEZ,EAAE6H,WAAW,IAAIM,KAAK,IAAI3H,EAAErC,KAAK,cAAc0D,EAAEhC,EAAEe,GAAGiB,GAAGrB,EAAE+H,YAAY1G,EAAEwG,KAAK7H,EAAEgI,iBAAiBzK,KAAK0K,uBAAuBjI,EAAE+H,YAAY7J,EAAE8F,UAAUE,KAAS,OAAJ5E,IAAWC,IAAIS,EAAErC,IAAI2B,GAAG+B,EAAEyG,QAAQ9H,EAAE+H,YAAY,KAAK/H,EAAEgI,iBAAiB,MAAMhI,EAAEkI,iBAAiB3I,EAAED,EAAEU,EAAErC,GAAG,CAAC,MAAMM,EAAE+C,SAAQ3B,IAAIY,OAAOC,OAAOb,EAAE,CAAC0I,YAAY,KAAKC,iBAAiB,KAAKE,iBAAiB,UAAS,OAAOjK,CAAC,CAAC,sBAAAgK,CAAuBhK,EAAEC,GAAG,GAAKD,EAAE,CAAC,IAAI,IAAIoB,EAAE,EAAEA,EAAEnB,EAAE0C,OAAOvB,IAAI,GAAGA,IAAInB,EAAE0C,OAAO,GAAG3C,EAAEC,EAAEmB,GAAG8E,MAAM,OAAOjG,EAAEmB,GAAG2D,MAAM,OAAO,IAAI,CAAC,CAAC,sBAAAmF,CAAuBlK,EAAEC,EAAEmB,GAAG,MAAMC,EAAE,IAAIqI,KAAO,IAAF1J,GAAOsB,EAAE,IAAIoI,KAAO,IAAFzJ,GAAO8B,EAAER,EAAE6H,WAAW/H,EAAE,cAAc,IAAIc,EAAE,EAAE,GAAGJ,IAAIR,EAAE6H,WAAW9H,EAAE,cAAca,GAAGlC,EAAED,IAAIoB,EAAEW,IAAIX,EAAEW,GAAG8H,MAAM,OAAO,CAAC,IAAIzG,EAAEpD,EAAEsD,EAAE,IAAIoG,KAAK3H,GAAG4H,UAAU,IAAI,MAAMpG,EAAEhC,EAAE6H,WAAa,IAAF9F,EAAM,cAAcN,EAAEO,EAAEH,EAAEnD,IAAIkC,IAAImB,EAAEF,IAAIhC,EAAEmC,IAAInC,EAAEmC,GAAGsG,MAAM,GAAGzG,EAAEE,EAAEN,EAAEO,EAAED,GAAG,MAAMC,EAAEhC,EAAE6H,WAAa,IAAF9F,EAAM,eAAenB,IAAIlC,EAAEmD,IAAIhC,EAAE4B,IAAI5B,EAAE4B,GAAG6G,MAAM,EAAE,CAAC,OAAO1H,CAAC,CAAC,kBAAAwE,CAAmB3G,EAAEC,GAAG,MAAMmB,EAAE,GAAG,IAAIC,EAAE,CAAA,EAAGO,EAAEJ,QAAQxB,GAAGqB,EAAE/B,KAAKwB,MAAMO,EAAErB,GAAGV,KAAKwB,MAAMd,GAAG,IAAI,MAAMsB,KAAKD,EAAE,GAAGA,EAAEC,IAAID,EAAEC,GAAGkB,OAAO,CAAC,MAAMT,EAAEV,EAAEC,GAAGe,KAAK,GAAGN,GAAGA,EAAEY,OAAO,CAAC,IAAIR,EAAEJ,EAAE,GAAGvC,IAAI4B,EAAEoC,KAAK,CAACzB,EAAE,GAAGtC,IAAI0C,IAAIA,EAAEJ,EAAEA,EAAEY,OAAO,GAAGnD,IAAI4B,EAAEoC,KAAK,CAACzB,EAAEA,EAAEY,OAAO,GAAGlD,IAAI0C,IAAI,IAAI,IAAIiB,EAAE,EAAEA,EAAErB,EAAEY,OAAO,EAAES,IAAIhC,EAAEoC,KAAK,CAACzB,EAAEqB,GAAG3D,IAAIsC,EAAEqB,GAAG5D,KAAK,CAAC,CAAC4B,EAAEuB,OAAO,GAAGrD,KAAKyB,KAAKoJ,UAAUvI,EAAEwI,uBAAuBhJ,EAAE9B,KAAKyB,MAAMd,EAAE,CAAC,KAAAoK,CAAMrK,GAAG,GAAGV,KAAKmC,IAAIzB,GAAG,CAAC,MAAMC,EAAEX,KAAKwB,MAAMd,GAAGwC,OAAOvC,IAAIA,EAAEqK,OAAOhL,KAAKwB,MAAMd,GAAGwC,OAAO,KAAK,CAAClD,KAAK0B,iBAAiBuJ,aAAa,CAACvK,GAAG,CAAC,IAAAsK,CAAKtK,GAAGV,KAAK+K,MAAMrK,GAAGV,KAAKkL,aAAa,CAAC,OAAAC,GAAU,IAAI,MAAMzK,KAAKV,KAAKwB,MAAMxB,KAAKgL,KAAKtK,GAAGV,KAAKkL,aAAa,CAAC,OAAAE,CAAQ1K,GAAGV,KAAKgL,KAAKtK,UAAUV,KAAKwB,MAAMd,EAAE,CAAC,MAAA2B,CAAO3B,GAAGV,KAAKoL,QAAQ1K,GAAGV,KAAKkL,aAAa,CAAC,SAAAG,GAAY,IAAI,MAAM3K,KAAKV,KAAKwB,MAAMxB,KAAKoL,QAAQ1K,EAAE,CAAC,WAAAwK,GAAclL,KAAKyB,KAAKyJ,aAAalL,KAAKyB,KAAKyJ,cAAclL,KAAKyB,KAAK2D,eAAepF,KAAKsL,iBAAiBtL,KAAKyB,KAAK2D,aAAamC,UAAU,IAAIvH,KAAKyB,KAAK2D,aAAamG,gBAAgB,CAAC,QAAAC,GAAW,OAAOxL,KAAKwB,KAAK,CAAC,SAAAiK,GAAY,OAAO/I,OAAOU,KAAKpD,KAAKwB,OAAO6B,MAAM,CAAC,SAAAqI,GAAY,MAAMhL,EAAE,GAAG,IAAI,MAAMC,KAAKX,KAAKwB,MAAMd,EAAEwD,KAAKlE,KAAKwB,MAAMb,IAAI,OAAOD,CAAC,CAAC,OAAAiL,GAAU,OAAOjJ,OAAOU,KAAKpD,KAAKwB,MAAM,CAAC,iBAAA2D,GAAoB,OAAOL,CAAC,CAAC,GAAA3C,CAAIzB,GAAG,OAAOA,KAAKV,KAAKwB,KAAK,CAAC,cAAA8J,GAAiB,IAAI5K,GAAE,EAAG,IAAI,MAAMC,KAAKX,KAAKwB,MAAM,GAAGxB,KAAKwB,MAAMb,GAAGuC,OAAO,CAACxC,GAAE,EAAG,KAAK,CAAC,OAAOA,CAAC,CAAC,GAAAkL,CAAIlL,GAAG,OAAOV,KAAKmC,IAAIzB,GAAGV,KAAKwB,MAAMd,QAAG,CAAM,CAAC,SAAA6G,CAAU7G,EAAE,KAAKV,KAAKyB,KAAKoK,cAAc7L,KAAKyB,KAAKoK,aAAaC,aAAW9L,KAAKyB,KAAKoK,aAAaC,WAAWC,MAAMC,OAAOtL,EAAuC"}