{"version":3,"file":"index.mjs","sources":[""],"sourcesContent":["import { getLastFromIterable, isNonEmptyArr } from \"@web3r/flowerkit/arr\";\r\nimport { getCSSValue, removeCSSVar, setCSSVar } from \"@web3r/flowerkit/css\";\r\nimport { getDebouncedFn, wait } from \"@web3r/flowerkit/fn\";\nimport { getStrWithCapitalized } from \"@web3r/flowerkit/str\";\r\nimport type {\r\n  Placemark,\r\n  Clusterer,\r\n  map,\r\n  IOverlay,\r\n  IMapPanOptions,\r\n  IProjection,\r\n  IMapBoundsOptions,\r\n  IMapState, IEvent, geoObject,\r\n} from \"yandex-maps\";\r\nimport type ymaps from \"yandex-maps\";\r\nimport { getElRefHelper } from \"../../../utils/react/getElRefHelper\";\r\nimport { mapDefaults, optionsDefaults, userPropsDefaults } from \"../config\";\r\nimport type {\r\n  TCoords,\r\n  TZoom,\r\n  TConstructorInstance,\r\n  TObjectUserProp,\r\n  TFactoryCallback,\r\n  TMapInstance,\r\n  TAPI,\r\n  TClusterOptions,\r\n  TMapContext,\r\n  TCluster,\r\n} from \"../config/types\";\r\n\r\ninterface IFixedOverlay extends IOverlay {\r\n  getLayout: () => map.Container;\r\n}\r\n\r\ntype TMapEventHandler = {\r\n  bivarianceHack: (event: IEvent<object, object>) => void | Promise<void>;\r\n}[\"bivarianceHack\"];\r\n\r\n/**\r\n * Проверяет валидность массива координат\r\n * @returns {boolean}\r\n */\r\nconst isCoordsValid = (coords?: number[]): boolean => {\r\n  const items = coords || [];\r\n  return isNonEmptyArr(items) && items.length === 2 && items.every((item: number | unknown) => typeof item === \"number\" && Number.isFinite(item));\r\n};\r\n\r\n/**\r\n * Проверяет валидность полей\r\n * @returns {boolean}\r\n */\r\nconst isMarginValid = (margin?: number[] | number[][]): boolean => {\r\n  if (Array.isArray(margin)) {\r\n    return margin.length === 2 && margin.every((value) => typeof value === \"number\" && Number.isFinite(value) && value > 0);\r\n  } else {\r\n    return false;\r\n  }\r\n};\r\n\r\n/**\r\n * Проверяет валидность зума\r\n * @param zoom{TZoom}\r\n * @returns {boolean}\r\n */\r\nconst isZoomValid = (zoom: TZoom | undefined): boolean => {\r\n  if (typeof zoom === \"number\" && Number.isFinite(zoom) && zoom > -1 && zoom < 24) {\r\n    return true;\r\n  } else {\r\n    console.error(`[Map] Zoom must be number in range of 0 to 23`, zoom);\r\n    return false;\r\n  }\r\n};\r\n\r\n/**\r\n * Проверяет валидность верстки элементов\r\n * @param layout{*}\r\n * @returns {boolean}\r\n */\r\nconst isValidLayout = (layout: unknown) => typeof layout === \"string\" && !!layout.length;\r\n\r\n/**\r\n * Получает экземляр вызова `ymaps.templateLayoutFactory`\r\n * @returns {TConstructorInstance}\r\n */\r\nconst getLayoutConstructor: <T, CB = T>(instance: TAPI, html?: string, callback?: TFactoryCallback<CB>, props?: Record<string, unknown> | null, methods?: {\r\n  [key: string]: Function;\r\n}) => TConstructorInstance<T> = function(instance, html, callback, props, methods) {\r\n  const Layout = instance?.templateLayoutFactory.createClass(html, {\r\n    build: function() {\r\n      Layout.superclass.build.call(this);\r\n      if (typeof callback === \"function\") {\r\n        callback(\"build\", this);\r\n      }\r\n    },\r\n    rebuild: function() {\r\n      Layout.superclass.rebuild.call(this);\r\n      if (typeof callback === \"function\") {\r\n        callback(\"rebuild\", this);\r\n      }\r\n    },\r\n    clear: function() {\r\n      Layout.superclass.clear.call(this);\r\n      if (typeof callback === \"function\") {\r\n        callback(\"clear\", this);\r\n      }\r\n    },\r\n    destroy: function() {\r\n      Layout.superclass.destroy.call(this);\r\n      if (typeof callback === \"function\") {\r\n        callback(\"destroy\", this);\r\n      }\r\n    },\r\n    ...(methods || {}),\r\n  }, {\r\n    getProps: (name: string) => {\r\n      const propMap = props || {};\r\n      return !!name ? propMap[name] : propMap;\r\n    },\r\n  });\r\n  return Layout;\r\n};\r\n\r\n/**\r\n * Получает значение пользовательского поля, которое может быть функцией\r\n * @returns {Promise<string|null>}\r\n */\r\nconst getUserField = async <TArg extends object>(prop: TObjectUserProp<TArg>, userFnArg: TArg): Promise<string> => {\n  const result = typeof prop === \"function\" ? await prop(userFnArg) : prop;\n  if (typeof result !== \"string\") {\n    throw new TypeError(\"[Map] User field must resolve to a string\");\n  }\n  return result;\n};\n\r\n\r\n/**\r\n * Добавляет или удаляет обработчик события на экземпляр вызова элемента карты\r\n * @param instance\r\n * @param events\r\n * @param isBind\r\n */\r\nconst bindEvents = (\r\n  instance: Placemark | TMapInstance | Clusterer,\r\n  events: { event: string; handler: TMapEventHandler; }[],\r\n  isBind: boolean\r\n) => {\r\n  if (instance) {\r\n    events.forEach(({ handler, event }) => {\r\n      instance.events[isBind ? \"add\" : \"remove\"](\r\n        event, handler as (event: object | IEvent<object, object>) => void\r\n      );\r\n    });\r\n  }\r\n};\r\n\r\n/**\r\n * Добавляет или удаляет классы у экземпляра вызова GeoObject\r\n * @param node{HTMLElement|null}\r\n * @param className{String}\r\n * @param isAdd{Boolean=}\r\n * @param callback{Function=}\r\n * @returns void;\r\n */\r\nconst manageGeoObjectClass: ((node: HTMLElement | null, className?: string, isAdd?: boolean, callback?: Function) => void) = (node: HTMLElement | null, className: string = \"\", isAdd: boolean | undefined = true, callback: Function | undefined) => {\r\n  if (node && className) {\r\n    const wrapper = getLastFromIterable(node.children);\r\n    if (wrapper) {\r\n      return wait(50)\r\n        .then(() => {\r\n          wrapper.classList[isAdd ? \"add\" : \"remove\"](className);\r\n          if (typeof callback === \"function\") {\r\n            callback();\r\n          }\r\n          return Promise.resolve();\r\n        });\r\n    }\r\n  }\r\n};\r\n\r\n/**\r\n * Получает DOM-элемент из дочернего элемента экземпляра вызова Placemark\r\n * @returns {Promise<HTMLElement>}\r\n */\r\nconst getNodeFromElementInstance: ((instance: ymaps.IGeoObject<ymaps.IPointGeometry> & {\r\n  options: TClusterOptions & { _name: string; };\r\n} | geoObject.Hint | geoObject.Balloon) => Promise<HTMLElement | null>) = async (instance): Promise<HTMLElement | null> => {\r\n  if (instance) {\r\n    return instance.getOverlay()\r\n      .then((overlay) => (overlay as IFixedOverlay)?.getLayout())\r\n      .then((layout: map.Container) => layout?.getElement());\r\n  } else {\r\n    return Promise.resolve(null);\r\n  }\r\n};\r\n\r\n/**\r\n * Получает результат сдвига карты на заданное число пикселей\r\n * @returns {Promise}\r\n */\r\nconst getMapMoveWithPx: (map: TMapInstance, coords: TCoords, xPx: number, yPx: number, options?: IMapPanOptions) => Promise<void> = async (map, coords, xPx, yPx, options = {\r\n  flying: true,\r\n  useMapMargin: true,\r\n}): Promise<void> => {\r\n  if (map) {\r\n    // Zoom\r\n    const zoom = map.getZoom();\r\n\r\n    // Преобразуем координаты в глобальные пиксели\r\n    const projection = map.options.get(\"projection\", []) as IProjection;\r\n    const [ currentXPx, currentYPx ] = projection.toGlobalPixels(coords, zoom);\r\n\r\n    // Преобразуем обратно в координаты\r\n    const newCoordinates = projection.fromGlobalPixels([\r\n      currentXPx + xPx,\r\n      currentYPx + yPx,\r\n    ], zoom);\r\n\r\n    await map.panTo(newCoordinates, options);\r\n    return;\r\n  } else {\r\n    return Promise.reject(new Error(\"Map instance is undefined\"));\r\n  }\r\n};\r\n\r\n/**\r\n * Получает результат обновления границ карты\r\n * @param instance{TMapInstance}\r\n * @param options{IMapBoundsOptions}\r\n * @returns {Promise<TMapInstance>}\r\n */\r\nconst getUpdateBounds = (instance: TMapInstance, options?: IMapBoundsOptions): Promise<TMapInstance> => {\r\n  return new Promise<TMapInstance>((resolve, reject) => {\n    if (instance) {\r\n      const userZoom = instance.getZoom();\r\n      const GeoObjects = instance.geoObjects;\r\n      const zoomOptions = {\r\n        duration: 0,\r\n        useMapMargin: true,\r\n        checkZoomRange: true,\r\n      };\r\n\r\n      function isAllGeoObjectsVisible(): boolean {\r\n        const objectsBounds = instance!.geoObjects.getBounds() as number[][];\r\n        const mapBounds = instance!.getBounds() as number[][];\r\n        return objectsBounds && (\r\n          objectsBounds[0][0] >= mapBounds[0][0] &&\r\n            objectsBounds[1][0] <= mapBounds[1][0] &&\r\n            objectsBounds[0][1] >= mapBounds[0][1] &&\r\n            objectsBounds[1][1] <= mapBounds[1][1]\r\n        );\r\n      }\r\n\r\n      const getCorrectViewport = async (bounds: number[][]) => {\r\n        return await instance.setBounds(bounds, {\r\n          preciseZoom: false,\r\n          checkZoomRange: true,\r\n          useMapMargin: true,\r\n          duration: 0,\r\n          ...(options || {}),\r\n        }).then(async () => {\r\n          const state = {\r\n            minZoom: instance.options.get(\"minZoom\", optionsDefaults.minZoom as unknown as object) as unknown as number,\r\n            maxZoom: instance.options.get(\"maxZoom\", optionsDefaults.maxZoom as unknown as object) as unknown as number,\r\n            zoom: instance.getZoom(),\r\n            margin: instance.margin.getMargin(),\r\n            center: instance.getCenter({\r\n              useMapMargin: true,\r\n            }),\r\n          };\r\n          if (state.maxZoom && state.zoom > state.maxZoom) {\r\n            return await instance.setZoom(state.maxZoom, zoomOptions)\r\n              .then(() => {\r\n                console.debug(\"[Map] Set zoom to max: \", state.maxZoom);\r\n                return Promise.resolve();\r\n              });\r\n          } else if (state.minZoom && state.zoom < state.minZoom) {\r\n            return await instance.setZoom(state.minZoom, zoomOptions)\r\n              .then(() => {\r\n                console.debug(\"[Map] Set zoom to min: \", state.minZoom);\r\n                return Promise.resolve();\r\n              });\r\n          } else {\r\n            const userOptions = instance.options.get(\"customProps\", userPropsDefaults);\r\n            const isPointsVisible = isAllGeoObjectsVisible() && (userOptions as typeof userPropsDefaults).isAllPointsVisible;\r\n            if (isPointsVisible) {\r\n              return Promise.resolve();\r\n            } else {\r\n              const geoBounds = instance.geoObjects.getBounds() || instance.getBounds({\r\n                useMapMargin: true,\r\n              });\r\n              return instance.setBounds(geoBounds, {\r\n                useMapMargin: true,\r\n                checkZoomRange: true,\r\n                duration: 0,\r\n              }).then(() => {\r\n                console.debug(`[Map] Zoom level of \"${userZoom}\" within current map bounds can't show all points, switched to \"${instance.getZoom()}\". Auto zoom can be disabled via \"isAllPointsVisible\" prop`);\r\n                return Promise.resolve();\r\n              });\r\n            }\r\n          }\r\n        });\r\n      };\r\n\r\n      if (GeoObjects && GeoObjects.getLength()) {\r\n        const bounds = GeoObjects.getBounds();\r\n        if (bounds) {\r\n          void getCorrectViewport(bounds)\n            .then(() => {\n              return resolve(instance);\n            })\n            .catch((err) => {\n              return reject(err);\n            });\n          return;\n        } else {\r\n          const boundsFound = getDebouncedFn(async () => {\r\n            const bounds = GeoObjects.getBounds();\r\n            if (bounds) {\r\n              await getCorrectViewport(bounds)\r\n                .then(() => {\r\n                  return resolve(instance);\r\n                })\r\n                .catch((err) => {\r\n                  return reject(err);\r\n                })\r\n                .finally(() => {\r\n                  GeoObjects.events.remove(\"add\", onAdd);\r\n                  GeoObjects.events.remove(\"boundschange\", onBoundsChange);\r\n                });\r\n            }\r\n          }, 500);\r\n          function onAdd() {\r\n            boundsFound();\r\n          }\r\n          function onBoundsChange() {\r\n            boundsFound();\r\n          }\r\n          GeoObjects.events.add(\"boundschange\", onBoundsChange);\r\n          GeoObjects.events.add(\"add\", onAdd);\r\n        }\r\n      } else {\r\n        return reject(new Error(`Geo objects not found`));\r\n      }\r\n    } else {\r\n      return reject(new Error(`Map instance not provided`));\r\n    }\r\n  });\r\n};\r\n\r\n/**\r\n * Получает начальное состояние карты\r\n * @param props{IMapState}\r\n * @returns {IMapState}\r\n */\r\nconst getDefaultState = (props: IMapState) => {\r\n  const { zoom, center, margin } = props || {};\r\n  return {\r\n    zoom: isZoomValid(zoom) ? zoom : mapDefaults.zoom,\r\n    center: isCoordsValid(center) ? center : mapDefaults.center,\r\n    margin: isMarginValid(margin) ? margin : mapDefaults.margin,\r\n  };\r\n};\r\n\r\n/**\r\n * Обновляет CSS-переменную вычисляемого размера карты\r\n * @param container{HTMLElement | null}\r\n */\r\nconst setComputedWidth = (container: HTMLElement | null) => {\r\n  if (container) {\r\n    setCSSVar(container, \"--yaMapComputedWidth\", `${container.clientWidth}px`);\r\n    setCSSVar(container, \"--yaMapComputedHeight\", `${container.clientHeight}px`);\r\n  }\r\n};\r\n\r\n/**\r\n * Обновляет CSS-переменные для слоя балунов.\r\n */\r\nconst managePaneVariables = (containerRef: TMapContext[\"containerRef\"], isAdd: boolean, paneNode: HTMLElement | null) => {\r\n  const container = getElRefHelper(containerRef);\r\n  const props = [ \"width\", \"height\", \"top\", \"left\", \"right\", \"bottom\" ];\r\n  if (container) {\r\n    props.forEach((prop) => {\r\n      const cssVar = `--yaMapBalloons${getStrWithCapitalized(prop)}Computed`;\r\n      if (isAdd) { // add vars\r\n        if (paneNode) {\r\n          const computedValue = getCSSValue(paneNode, prop);\r\n          setCSSVar(container, cssVar, computedValue);\r\n          paneNode.style.removeProperty(prop);\r\n        }\r\n      } else { // remove vars\r\n        removeCSSVar(container, cssVar);\r\n      }\r\n    });\r\n  }\r\n};\r\n\r\n/**\r\n * Проверяет, обновились ли кластеры (по ID или по составу точек, исключая поле state)\r\n * @returns {Boolean} true если кластеры изменились, false если изменился только state точек\r\n */\r\nconst isClustersUpdated = (current: TCluster[], prev: TCluster[]): boolean => {\r\n\r\n  // Если длины различаются - кластеры обновились\r\n  if (current.length !== prev.length) {\r\n    return true;\r\n  }\r\n\r\n  // Проверяем каждый кластер\r\n  for (let i = 0; i < current.length; i++) {\r\n    const currentCluster = current[i];\r\n    const prevCluster = prev[i];\r\n\r\n    // Если ID кластера изменился - обновление произошло\r\n    if (currentCluster.id !== prevCluster.id) {\r\n      return true;\r\n    }\r\n\r\n    // Если количество точек в кластере изменилось - обновление произошло\r\n    if (currentCluster.points.length !== prevCluster.points.length) {\r\n      return true;\r\n    }\r\n\r\n    // Проверяем каждую точку в кластере (исключая поле state)\r\n    for (let j = 0; j < currentCluster.points.length; j++) {\r\n      const currentPoint = currentCluster.points[j];\r\n      const prevPoint = prevCluster.points[j];\r\n\r\n      // Сравниваем значимые поля, исключая state\r\n      if (\r\n        currentPoint.id !== prevPoint.id ||\r\n        currentPoint.coords[0] !== prevPoint.coords[0] ||\r\n        currentPoint.coords[1] !== prevPoint.coords[1]\r\n      ) {\r\n        return true;\r\n      }\r\n    }\r\n  }\r\n\r\n  // Если ничего не изменилось (только state) - обновления нет\r\n  return false;\r\n};\r\n\r\nexport {\r\n  bindEvents,\r\n  getDefaultState,\r\n  getLayoutConstructor,\r\n  getMapMoveWithPx,\r\n  getNodeFromElementInstance,\r\n  getUpdateBounds,\r\n  getUserField,\r\n  isClustersUpdated,\r\n  isCoordsValid,\r\n  isMarginValid,\r\n  isValidLayout,\r\n  isZoomValid,\r\n  manageGeoObjectClass,\r\n  managePaneVariables,\r\n  setComputedWidth,\r\n};\r\n"],"names":["isCoordsValid","coords","items","isNonEmptyArr","length","every","item","Number","isFinite","isMarginValid","margin","Array","isArray","value","isZoomValid","zoom","console","error","isValidLayout","layout","getLayoutConstructor","instance","html","callback","props","methods","Layout","templateLayoutFactory","createClass","build","superclass","call","this","rebuild","clear","destroy","getProps","name","propMap","getUserField","async","prop","userFnArg","result","TypeError","bindEvents","events","isBind","forEach","handler","event","manageGeoObjectClass","node","className","isAdd","wrapper","getLastFromIterable","children","wait","then","classList","Promise","resolve","getNodeFromElementInstance","getOverlay","overlay","getLayout","getElement","getMapMoveWithPx","map","xPx","yPx","options","flying","useMapMargin","getZoom","projection","get","currentXPx","currentYPx","toGlobalPixels","newCoordinates","fromGlobalPixels","panTo","reject","Error","getUpdateBounds","userZoom","GeoObjects","geoObjects","zoomOptions","duration","checkZoomRange","isAllGeoObjectsVisible","objectsBounds","getBounds","mapBounds","getCorrectViewport","setBounds","bounds","preciseZoom","state","minZoom","optionsDefaults","maxZoom","getMargin","center","getCenter","setZoom","debug","userOptions","userPropsDefaults","isPointsVisible","isAllPointsVisible","geoBounds","getLength","catch","err","boundsFound","getDebouncedFn","finally","remove","onAdd","onBoundsChange","add","getDefaultState","mapDefaults","setComputedWidth","container","setCSSVar","clientWidth","clientHeight","managePaneVariables","containerRef","paneNode","getElRefHelper","cssVar","getStrWithCapitalized","computedValue","getCSSValue","style","removeProperty","removeCSSVar","isClustersUpdated","current","prev","i","currentCluster","prevCluster","id","points","j","currentPoint","prevPoint"],"mappings":"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"}