Snippets Collections
import socket
# client code to connect with API bridge
HOST = '127.0.0.1'  # The server's hostname or IP address
PORT = 56789    # The port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    #ID,Type,Symbol,OrderType,TrigPrice,Price,Qty,InstrumentName,StrategyTag"
    # Symbol = Symbol | Expiry | Strike | OptionType
    # TrigPrice = TrigPrice | StopLoss | SquareOff | TrailingTicks
    # StrategyTag = StrategyTag | Port

    #s.sendall(b"8,LE,SBIN,M,1,180,1,EQ,STG11")
    #s.sendall(b"8,SE,RELIANCE,L,1,180,1,EQ,STG11")
   # s.sendall(b"8,SE,HDFC,L,1,1200,100,EQ,STG11")
    #s.sendall(b"8,SE,INFY|30MAY2019|130|PE,L,1,2000,50,OPTSTK,STG11")
    s.sendall(b"8,LE,MARUTI,L,1,180,1,EQ,STG11")

    data = s.recv(1024)

print('Received', repr(data))
'post__in' => array(301, 344, 342, 995, 998, 1001, 1000, 999),
'orderby' => 'post__in', 


=======
$arg = array(
		'post_type' => 'team',
		'posts_per_page' => -1,
		'post__in' => array(301, 344, 342, 995, 998, 1001, 1000, 999),
    	'orderby' => 'post__in', 
);
/* eslint-disable no-promise-executor-return */
import dayjs from 'dayjs';
import _ from 'lodash';
import {
  useEffect, useRef, useState,
} from 'react';
import {
  useRecoilValue, useSetRecoilState,
} from 'recoil';
import { t } from 'ttag';
import {
  beatEventCountState,
  rhythmEventCountState,
  specialEventTypesState, updatedAfibAvgHrState, updatedDailyAfibHrSummariesState,
} from '.';
import { clearApolloCache } from '../../../../../Apollo/apolloClient';
import fetchHolterBeatEventsCount from '../../../../../Apollo/Functions/fetchHolterBeatEventsCount';
import fetchHolterEventIndex from '../../../../../Apollo/Functions/fetchHolterEventIndex';
import fetchHolterEvents from '../../../../../Apollo/Functions/fetchHolterEvents';
import fetchHolterEventsDailyCount from '../../../../../Apollo/Functions/fetchHolterEventsDailyCount';
import fetchHolterRhythmEventsCount from '../../../../../Apollo/Functions/fetchHolterRhythmEventsCount';
import handleCheckSavingAiProcess from '../../../../../Apollo/Functions/handleCheckSavingAiProcess';
import { EMITTER_CONSTANTS } from '../../../../../ConstantsV2';
import {
  AI_COMMAND,
  canShowCountBeatEvents, canShowDurationEvents,
  ECG_EVENT_MENU_OPTIONS, EVENT_COUNT_CONVERT, ID_BOOKMARK_TAB, KEY_CANCEL, KEY_RECOIL, STRIP_EVENT_THUMBNAIL_INFO, TYPE_RHYTHM_EVENT_ENUM,
  typesPersistEventV2,
} from '../../../../../ConstantsV2/aiConstants';
import { convertToDayJS } from '../../../../../UtilsV2/aiUtils';
import { useEmitter, useGetRecoilValue } from '../../../../../UtilsV2/customHooks';
import emitter from '../../../../../UtilsV2/eventEmitter';
import { toastrError } from '../../../../../UtilsV2/toastNotification';
import {
  activeTabState,
  beatChangesState,
  dailyCountState,
  ecgDataMapState,
  eventChangesState,
  eventFilterState,
  eventNewsState,
  eventOptionsState,
  eventOthersState,
  groupEventChangesState,
  isActiveTabState,
  isNotReadyAfterSaveState,
  isRenderViewerEcgState,
  originalDailySummariesState,
  pageIndexState,
  profileAfibAvgHrState,
  reloadEcgViewerState,
  reloadHrChartState,
  reportInfoState,
  selectedDateValueState,
  selectedStripState,
} from '../../Recoil';
import { logError } from '../../handler';
import {
  generateFilterSpecialEventType,
  isAppliedFilterEvent,
} from '../handler';
import { clearCachesBeatHourly } from '../../../../../Store/caches';
import { removeSavingData } from '../../BeatHR/helper';
import { beatOptionsState } from '../../BeatHR/recoil';

const RhythmEventsRecoilDataEffect = (props) => {
  const keyRecoil = KEY_RECOIL.TAB_2;
  const activeButton = useRecoilValue(activeTabState(keyRecoil));
  const getActiveButton = useGetRecoilValue(activeTabState(keyRecoil));
  const getSelectedStrip = useGetRecoilValue(selectedStripState(keyRecoil));
  const getPageIndex = useGetRecoilValue(pageIndexState(keyRecoil));
  const setPageIndex = useSetRecoilState(pageIndexState(keyRecoil));
  const getSelectedDateValue = useGetRecoilValue(selectedDateValueState(keyRecoil));
  const getSpecialEventTypes = useGetRecoilValue(specialEventTypesState);
  const getEventFilter = useGetRecoilValue(eventFilterState(keyRecoil));
  const setDailyCount = useSetRecoilState(dailyCountState(keyRecoil));
  const setUpdatedAfibAvgHr = useSetRecoilState(updatedAfibAvgHrState);
  const setUpdatedDailyAfibHrSummaries = useSetRecoilState(updatedDailyAfibHrSummariesState);
  const setEventChanges = useSetRecoilState(eventChangesState(keyRecoil));
  const setBeatChanges = useSetRecoilState(beatChangesState(keyRecoil));
  const setReloadEcgViewer = useSetRecoilState(reloadEcgViewerState(keyRecoil));
  const setReloadHrChart = useSetRecoilState(reloadHrChartState(keyRecoil));
  const setGroupEventChanges = useSetRecoilState(groupEventChangesState(keyRecoil));
  const isActiveTab = useRecoilValue(isActiveTabState(keyRecoil));
  const setIsNotReadyAfterSaveTab1 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_1));
  const setIsNotReadyAfterSaveTab2 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_2));
  const setIsNotReadyAfterSaveTab3 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_3));
  const getHolterRhythmEventsCount = useGetRecoilValue(rhythmEventCountState);
  const getHolterBeatEventsCount = useGetRecoilValue(beatEventCountState);
  const { studyId, profileId, timezoneOffset } = useRecoilValue(reportInfoState);
  const setEcgDataMap = useSetRecoilState(ecgDataMapState);
  const getEcgDataMap = useGetRecoilValue(ecgDataMapState);
  const setOriginalDailySummaries = useSetRecoilState(originalDailySummariesState);
  const setProfileAfibAvgHr = useSetRecoilState(profileAfibAvgHrState);
  const setEventOthers = useSetRecoilState(eventOthersState(keyRecoil));
  const setEventNews = useSetRecoilState(eventNewsState(keyRecoil));
  const setEventOptions = useSetRecoilState(eventOptionsState(keyRecoil));
  const setIsRenderViewerEcg = useSetRecoilState(isRenderViewerEcgState);
  const setHolterRhythmEventsCount = useSetRecoilState(rhythmEventCountState);
  const setHolterBeatEventsCount = useSetRecoilState(beatEventCountState);
  const setSelectedStrip = useSetRecoilState(selectedStripState(keyRecoil));
  const [doneReset, setDoneReset] = useState(false);
  const setBeatOptions = useSetRecoilState(beatOptionsState(keyRecoil));

  const commandPendingQueue = useRef([]);
  const updateDataMessageQueue = useRef([]);
  const promiseUpdateData = useRef([]);
  const promiseUpdateDataType = useRef([]);
  const isExcutedRef = useRef(false);

  const handleFetchStripEvents = async ({ page, additionalFilter = {} }) => {
    try {
      const type = getActiveButton();
      const validatePage = page <= 0 ? 0 : page;
      const filterHolterEvents = {
        studyId,
        profileId,
        types: [type],
        skip: validatePage * STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit,
        ...additionalFilter,
      };
      const promises = [fetchHolterEvents(
        filterHolterEvents,
        STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit,
        true,
        KEY_CANCEL.API_HOLTER_AI,
      )];
      if (!_.isEmpty(additionalFilter)) {
        const holterEventsCountFilter = {
          studyId,
          profileId,
          types: [type],
          ...additionalFilter,
        };
        promises.push(
          _.find(ECG_EVENT_MENU_OPTIONS, (x) => x.value === type).type === 'beat'
            ? fetchHolterBeatEventsCount(holterEventsCountFilter, true, KEY_CANCEL.API_HOLTER_AI)
            : fetchHolterRhythmEventsCount(holterEventsCountFilter, true, KEY_CANCEL.API_HOLTER_AI),
        );
      }
      const [{ events }, eventsCount] = await Promise.all(promises);
      if (!_.isEmpty(additionalFilter)) {
        return { events, eventsCount };
      }
      return { events, eventsCount: _.find(ECG_EVENT_MENU_OPTIONS, (x) => x.value === type).type === 'beat' ? getHolterBeatEventsCount() : getHolterRhythmEventsCount() };
    } catch (error) {
      return { events: undefined, eventsCount: 0 };
    }
  };

  const handleReloadEventHrChartV2 = async () => {
    try {
      const type = activeButton;
      const selectedDateValue = getSelectedDateValue();
      const startSearchDate = selectedDateValue;
      const stopSearchDate = selectedDateValue ? dayjs(selectedDateValue).add(1, 'days').toISOString() : null;
      const promiseArr = [
        selectedDateValue ? fetchHolterEvents({
          studyId,
          profileId,
          types: typesPersistEventV2,
          startSearchDate,
          stopSearchDate,
        }, 0, true, KEY_CANCEL.API_HOLTER_AI) : undefined,
      ];
      await Promise.allSettled(promiseArr);
      if (!_.includes(promiseUpdateDataType.current, 'setReloadHrChart')) {
        promiseUpdateDataType.current.push('setReloadHrChart');
        promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
      }
    } catch (error) {
      logError('Failed to fetch reload data: ', error);
      toastrError(error.message, t`Error`);
    }
  };

  const handleReloadEventDataV2 = async (needUpdateAfibArtifact) => {
    try {
      if (isActiveTab) {
        setIsRenderViewerEcg(false);
      }
      const type = activeButton;
      const selectedDateValue = getSelectedDateValue();
      const startSearchDate = selectedDateValue;
      const stopSearchDate = selectedDateValue ? dayjs(selectedDateValue).add(1, 'days').toISOString() : null;
      const additionalFilter = generateFilterSpecialEventType(type, getSpecialEventTypes());
      const eventFilter = getEventFilter();
      if (isAppliedFilterEvent(eventFilter, type)) {
        _.assign(additionalFilter, {
          ...(eventFilter.isHideReviewed && { isReviewed: false }),
          ...(eventFilter.isCapture && { isCaptured: true }),
          ...(eventFilter.sortOrder && (canShowCountBeatEvents.includes(type) || canShowDurationEvents.includes(type)) && {
            sortBy: eventFilter.sortBy || 'countBeats',
            sortOrder: eventFilter.sortOrder,
          }),
        });
      }
      const promiseArr = [
        selectedDateValue ? fetchHolterEvents({
          studyId,
          profileId,
          types: typesPersistEventV2,
          startSearchDate,
          stopSearchDate,
        }, 0, true, KEY_CANCEL.API_HOLTER_AI) : undefined,
        fetchHolterEventsDailyCount({
          studyId,
          profileId,
          types: [type],
          ...additionalFilter,
        }, null, false),
      ];
      const selectedStrip = getSelectedStrip();
      if (selectedStrip?.idEvent) {
        const filterHolterEventIndex = {
          studyId,
          profileId,
          types: [type],
          includedEventId: selectedStrip.idEvent,
          ...additionalFilter,
        };
        promiseArr.push(fetchHolterEventIndex(filterHolterEventIndex, false, KEY_CANCEL.API_HOLTER_AI));
      } else {
        promiseArr.push(new Promise((resolve) => resolve(undefined)));
      }
      const [resultHolterEventsPersistAllDay, resultDailyCount, resultEventIndex] = await Promise.allSettled(promiseArr);
      const dailyCount = resultDailyCount?.status === 'rejected' ? undefined : resultDailyCount.value;
      if (resultEventIndex?.status === 'fulfilled') {
        const eventIndex = resultEventIndex.value;
        if (!_.isNil(eventIndex) && eventIndex >= 0) {
          const page = Math.floor(eventIndex / STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit);
          await handleFetchStripEvents({ page, additionalFilter });
          promiseUpdateData.current.push(() => setPageIndex({ index: page < 0 ? 0 : page }));
        } else {
          const pageIndex = getPageIndex();
          const { events, eventsCount } = await handleFetchStripEvents({ page: pageIndex.index, additionalFilter });
          if (_.isEmpty(events)) {
            const totalEvent = eventsCount[EVENT_COUNT_CONVERT[getActiveButton()]]?.count || 0;
            const pageTemp = Math.floor(totalEvent / STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit);
            const page = (totalEvent % STRIP_EVENT_THUMBNAIL_INFO.stripDisplayLimit) === 0 ? pageTemp - 1 : pageTemp;
            promiseUpdateData.current.push(() => setPageIndex({ index: page < 0 ? 0 : page }));
          } else {
            promiseUpdateData.current.push(() => setPageIndex({ index: getPageIndex().index }));
          }
        }
      }
      if (needUpdateAfibArtifact) {
        handleReloadEventHrChartV2();
      }
      if (!_.isEmpty(dailyCount)) {
        promiseUpdateData.current.push(() => setDailyCount(dailyCount));
      }
      if (!_.includes(promiseUpdateDataType.current, 'setReloadHrChart')) {
        promiseUpdateDataType.current.push('setReloadHrChart');
        promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
      }
    } catch (error) {
      logError('Failed to fetch reload data: ', error);
      toastrError(error.message, t`Error`);
    }
  };

  const handleReloadEvent = async (msg) => {
    try {
      if (isActiveTab) {
        setIsRenderViewerEcg(false);
      }
      const {
        newEvents, deletedEvents, updatedEvents, deletedEventTypes,
      } = msg;
      const selectedDateValue = getSelectedDateValue();
      const selectedDateString = selectedDateValue ? convertToDayJS(selectedDateValue, timezoneOffset).format('DD-MM-YYYY') : null;
      const types = [TYPE_RHYTHM_EVENT_ENUM.AFIB, TYPE_RHYTHM_EVENT_ENUM.ARTIFACT];
      let needUpdate;
      let needUpdateAfibArtifact; //* Trường hợp sửa artifact hoặc afib xong qua tab event khác save thì hr chart ko update
      if (deletedEventTypes?.length) {
        deletedEventTypes.forEach((type) => {
          if (type === activeButton || type === TYPE_RHYTHM_EVENT_ENUM.TACHY) {
            needUpdate = true;
          } else if (types.includes(type)) {
            needUpdateAfibArtifact = true;
          }
        });
      }
      if (deletedEvents?.length) {
        deletedEvents.forEach((deletedEvent) => {
          if (deletedEvent.type === activeButton || (deletedEvent.type === TYPE_RHYTHM_EVENT_ENUM.TACHY)) {
            needUpdate = true;
          } else {
            const isSameDate = selectedDateString === convertToDayJS(deletedEvent.start, timezoneOffset).format('DD-MM-YYYY');
            if (types.includes(deletedEvent.type) && isSameDate) {
              needUpdateAfibArtifact = true;
            }
          }
        });
      }
      if (newEvents?.length) {
        newEvents.forEach((newEvent) => {
          if (newEvent.type === activeButton) {
            needUpdate = true;
          } else {
            const isSameDate = selectedDateString === convertToDayJS(newEvent.start, timezoneOffset).format('DD-MM-YYYY');
            if (types.includes(newEvent.type) && isSameDate) {
              needUpdateAfibArtifact = true;
            }
          }
        });
      }
      if (updatedEvents?.length) {
        updatedEvents.forEach((updatedEvent) => {
          if (updatedEvent.type === activeButton) {
            needUpdate = true;
          } else {
            const isSameDate = selectedDateString === convertToDayJS(updatedEvent.start, timezoneOffset).format('DD-MM-YYYY');
            if (types.includes(updatedEvent.type) && isSameDate) {
              needUpdateAfibArtifact = true;
            }
          }
        });
      }
      if (needUpdate) {
        await handleReloadEventDataV2(needUpdateAfibArtifact);
      } else if (needUpdateAfibArtifact || activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
        await handleReloadEventHrChartV2();
      } else if (activeButton === ID_BOOKMARK_TAB) {
        if (!_.includes(promiseUpdateDataType.current, 'setReloadHrChart')) {
          promiseUpdateDataType.current.push('setReloadHrChart');
          promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
        }
      }
      console.log('[rhythmEventsRecoilDataEffect]-RELOAD-EVENT-RHYTHMEVENT', needUpdate, activeButton, needUpdateAfibArtifact);
      if (!_.includes(promiseUpdateDataType.current, 'setReloadEcgViewer')) {
        promiseUpdateDataType.current.push('setReloadEcgViewer');
        promiseUpdateData.current.push(() => setReloadEcgViewer((prev) => prev + _.round(Math.random() * 100)));
      }
      promiseUpdateData.current.push(() => {
        setGroupEventChanges((prev) => {
          if (prev.length === 0) {
            return prev;
          }
          return [];
        });
        let eventChanges = [];
        let eventNews = [];
        let eventOthers = [];

        setEventChanges((prev) => {
          let count = 0;
          const filterResult = prev.filter((x) => {
            if (x.isSaving) {
              count += 1;
              return false;
            }
            return true;
          });
          if (count === 0) {
            return prev;
          }
          eventChanges.push(...filterResult);
          return filterResult;
        });
        setEventOthers((prev) => {
          let count = 0;
          const filterResult = prev.filter((x) => {
            if (x.isSaving) {
              count += 1;
              return false;
            }
            return true;
          });
          if (count === 0) {
            return prev;
          }
          eventOthers.push(...filterResult);
          return filterResult;
        });
        setEventNews((prev) => {
          let count = 0;
          const filterResult = prev.filter((x) => {
            if (x.isSaving) {
              count += 1;
              return false;
            }
            return true;
          });
          if (count === 0) {
            return prev;
          }
          eventNews.push(...filterResult);
          return filterResult;
        });

        // Perform grouping action applicable to undo/redo
        setEventOptions({
          eventNewsState: eventNews,
          eventChangesState: eventChanges,
          eventOthersState: eventOthers,
        });

        eventChanges = [];
        eventNews = [];
        eventOthers = [];
        const selectedStrip = getSelectedStrip();
        if (selectedStrip?.isNew) {
          setSelectedStrip(null);
        }
      });
    } catch (error) {
      logError('Error: ', error);
    }
    return true;
  };

  const handleUpdateBeats = (msg) => {
    const prevEcgDataMap = getEcgDataMap();
    const cloneEcgDataMap = { ...prevEcgDataMap };
    if ((msg.summaries?.length || msg.beatsUpdated?.summaries?.length) && !_.isEmpty(prevEcgDataMap?.data)) {
      _.forEach(msg.summaries || msg.beatsUpdated?.summaries, (summary) => {
        const foundData = _.find(cloneEcgDataMap.data, (x) => x.id === summary.id);
        if (foundData) {
          _.assign(foundData, {
            avgHrs: summary?.avgHrs,
            maxHrs: summary?.maxHrs,
            minHrs: summary?.minHrs,
            beatFinalPath: summary?.beatFinalPath,
            latestBeatPrefix: summary?.latestBeatPrefix,
          });
        }
      });

      const summaryIds = _.map(msg.summaries || msg.beatsUpdated?.summaries, 'id');
      const socketUpdateEcgDataMap = {
        ...cloneEcgDataMap,
        data: _.filter(cloneEcgDataMap.data, (item) => summaryIds.includes(item.id)),
      };
      if (isActiveTab) {
        emitter.emit(EMITTER_CONSTANTS.UPDATE_SOCKET_BEAT_DATA_MAP, socketUpdateEcgDataMap);
      }
    }
    return cloneEcgDataMap;
  };

  const handleReloadBeat = async (msg) => {
    try {
      const cloneEcgDataMap = handleUpdateBeats(msg);
      promiseUpdateData.current.push(() => {
        let beatsChanges = [];

        setBeatChanges((prev) => {
          if (_.isEmpty(prev)) return prev;
          const beats = removeSavingData(prev);
          beatsChanges = beats;
          return beats;
        });
        setBeatOptions((prev) => ({ ...prev, beatChangesState: beatsChanges }));

        setEcgDataMap((prev) => {
          if (_.isEqual(prev, cloneEcgDataMap)) {
            return prev;
          }
          return cloneEcgDataMap;
        });
        setReloadEcgViewer((prev) => prev + _.round(Math.random() * 100));
      });
    } catch (error) {
      logError('Failed to reload beat', error);
    }
    return true;
  };

  const fetchEventsCount = async () => {
    try {
      const eventsCountFilter = {
        studyId,
        profileId,
      };
      const promises = [
        fetchHolterBeatEventsCount(eventsCountFilter, false, null, false),
        fetchHolterRhythmEventsCount(eventsCountFilter, false, null, false),
      ];
      const [holterBeatEventsCount, holterRhythmEventsCount] = await Promise.all(promises);
      setHolterBeatEventsCount(holterBeatEventsCount);
      setHolterRhythmEventsCount(holterRhythmEventsCount);
    } catch (error) {
      logError('Failed to fetch holter rhythm events count: ', error);
    }
  };

  const updateEventOutOfPending = _.debounce(async () => {
    await clearApolloCache();
    setIsRenderViewerEcg(false);
    setTimeout(() => {
      setIsRenderViewerEcg(true);
    }, 500);
  }, 2000);

  const batchUpdateData = async () => {
    try {
      await clearApolloCache();
      await clearCachesBeatHourly();
      if (isActiveTab || props.activeTab !== '1') {
        setIsRenderViewerEcg(false);
      }
      const promise = [];
      updateDataMessageQueue.current.forEach((x) => {
        if (x.type === AI_COMMAND.EVENT) {
          promise.push(handleReloadEvent(x.msg));
          promise.push(fetchEventsCount());
        }
      });
      const beatPromises = [];
      updateDataMessageQueue.current.forEach((x) => {
        if (x.type === AI_COMMAND.BEAT) {
          beatPromises.push(handleReloadBeat(x.msg));
        }
      });
      await Promise.all(beatPromises); // Wait for all beat promises to resolve
      console.log('[rhythmEventsRecoilDataEffect]-COMMANDEXECUTED-1', {
        promise,
        updateDataMessageQueue: updateDataMessageQueue.current,
        promiseUpdateData: promiseUpdateData.current,
      });
      await Promise.all(promise);
      promiseUpdateData.current.forEach((update) => update());
      updateDataMessageQueue.current.length = 0;
    } catch (error) {
      logError('Error: ', error);
    } finally {
      console.log('[rhythmEventsRecoilDataEffect]-COMMANDEXECUTED-2', {
        updateDataMessageQueue: updateDataMessageQueue.current,
        promiseUpdateData: promiseUpdateData.current,
      });
      updateDataMessageQueue.current.length = 0;
      promiseUpdateData.current.length = 0;
      commandPendingQueue.current.length = 0;
      promiseUpdateDataType.current.length = 0;
      emitter.emit(EMITTER_CONSTANTS.RELOAD_EVENT_STRIP);
      if (isActiveTab) {
        setDoneReset(true);
      }
    }
  };

  useEffect(() => {
    if (doneReset) {
      setTimeout(() => {
        emitter.emit(EMITTER_CONSTANTS.AI_LOADING, {
          isLoading: false,
          tab: 'rhythmEvents',
          isExcuted: isExcutedRef.current,
        });
        setDoneReset(false);
        if (isExcutedRef.current) {
          isExcutedRef.current = false;
        }
      }, 2000);
    }
  }, [doneReset]);

  useEmitter(EMITTER_CONSTANTS.EVENTSUPDATED_EVENT, (msg) => {
    const foundMsg = updateDataMessageQueue.current.find((x) => x.type === AI_COMMAND.EVENT);
    if (foundMsg) {
      if (!_.isEmpty(msg)) {
        Object.keys(msg).forEach((key) => {
          if (foundMsg.msg[key]) {
            foundMsg.msg[key] = foundMsg.msg[key].concat(msg[key]);
          } else {
            foundMsg.msg[key] = msg[key];
          }
        });
      }
    } else {
      updateDataMessageQueue.current.push({
        type: AI_COMMAND.EVENT,
        msg: _.cloneDeep(msg),
      });
    }
    if (commandPendingQueue.current.length === 0) { // update out of pending command
      updateEventOutOfPending();
    }
  }, [studyId, profileId]);

  useEmitter(EMITTER_CONSTANTS.BEATSUPDATED_EVENT, async (msg) => {
    const foundMsg = updateDataMessageQueue.current.find((x) => x.type === AI_COMMAND.BEAT);
    if (foundMsg) {
      if (!_.isEmpty(msg)) {
        _.assign(foundMsg, { msg });
      }
    } else {
      updateDataMessageQueue.current.push({
        type: AI_COMMAND.BEAT,
        msg,
      });
    }
  }, []);

  useEmitter(EMITTER_CONSTANTS.DAILY_SUMMARY_UPDATED, (msg) => {
    setOriginalDailySummaries((prev) => {
      if (msg) {
        const cloneDailySummaries = _.cloneDeep(prev);
        _.forEach(msg, (dailySummary) => {
          const foundDailySummary = _.find(cloneDailySummaries, (x) => x.date === dailySummary.date);
          if (foundDailySummary) {
            _.assign(foundDailySummary, dailySummary);
          }
        });
        return cloneDailySummaries;
      }
      return prev;
    });
  }, []);

  useEmitter(EMITTER_CONSTANTS.AFIB_HR_SUMMARY_UPDATED, (msg) => {
    const { afibAvgHr } = msg;
    setProfileAfibAvgHr(afibAvgHr);
    setUpdatedAfibAvgHr(undefined);
    setUpdatedDailyAfibHrSummaries([]);
  }, []);

  useEmitter(EMITTER_CONSTANTS.AI_PROCESS_SAVED, async (msg) => {
    await batchUpdateData();
    setIsNotReadyAfterSaveTab2(false);
  }, [activeButton, studyId, profileId, isActiveTab, props.activeTab]);

  useEmitter(EMITTER_CONSTANTS.COMMAND_PENDING, (msg) => {
    //* Khi 1 user save, BE gửi command pending về tuỳ theo số lượng api gọi lúc save, push command vào mảng và khi
    // có socket command execute thì remove => khi mảng về 0 thì get hết data nhận đc trong mảng updateDataMessage => update UI
    if (msg.messageId !== profileId) return;
    emitter.emit(EMITTER_CONSTANTS.AI_LOADING, { isLoading: true, tab: 'rhythmEvents' });
    commandPendingQueue.current.push(msg.command);
  }, [profileId]);

  useEmitter(EMITTER_CONSTANTS.COMMAND_EXECUTED, async (msg) => {
    // msg.command: update-events, update-beats, updateHolterHrDailySummary
    // updateHolterProfile, generate-report-comments
    if (msg.messageId !== profileId) return;
    if (msg.command === 'updateHolterProfile' || msg.command === 'generate-report-comments') return;
    console.log('[rhythmEventsRecoilDataEffect]-COMMANDEXECUTED-BEFORE', {
      msg,
      commandPendingQueue: commandPendingQueue.current,
      updateDataMessageQueue: updateDataMessageQueue.current,
    });
    const foundIndexCommand = commandPendingQueue.current.findIndex((command) => command === msg.command);
    if (foundIndexCommand !== -1) {
      commandPendingQueue.current.splice(foundIndexCommand, 1);
    }
    //* Finish all command
    if (commandPendingQueue.current.length === 0) {
      isExcutedRef.current = true;
      if (isActiveTab) {
        if (updateDataMessageQueue.current.length !== 0) {
          //* Announce this tab have data to update
          emitter.emit(EMITTER_CONSTANTS.AI_UPDATE_TAB, '2');
          const { beats, events, strips } = await handleCheckSavingAiProcess({
            studyId,
            profileId,
          });
          if (!beats) {
            setIsNotReadyAfterSaveTab1(true);
          }
          if (!strips) {
            setIsNotReadyAfterSaveTab3(true);
          }
          await batchUpdateData();
        } else {
          setDoneReset(true);
        }
      } else {
        await batchUpdateData();
      }
    }
  }, [activeButton, isActiveTab, studyId, profileId, props.activeTab]);

  return null;
};

export default RhythmEventsRecoilDataEffect;
/* eslint-disable no-promise-executor-return */
import dayjs from 'dayjs';
import _ from 'lodash';
import {
  useEffect,
  useRef,
  useState,
} from 'react';
import {
  useRecoilState,
  useRecoilValue,
  useSetRecoilState,
} from 'recoil';
import { t } from 'ttag';
import {
  beatOptionsState,
  dailySummariesCombineState,
  dataHeatmapChartState,
  dataHeatmapChartStatusState,
  generateDefaultHeatmapState,
  listOriginReviewedCellsState,
  listReviewedCellsState,
  listSelectedCellsState,
  listUnReviewedCellsState,
  resetAppliedBulkChangesState,
  rrHeatMapCellChangesState,
  rrOverviewOriginState,
  rrOverviewState,
  totalStripState,
  updatedDailySummariesState,
} from '.';
import fetchHolterBeatEventsCount from '../../../../../Apollo/Functions/fetchHolterBeatEventsCount';
import fetchHolterEventIndex from '../../../../../Apollo/Functions/fetchHolterEventIndex';
import fetchHolterEvents from '../../../../../Apollo/Functions/fetchHolterEvents';
import fetchHolterEventsDailyCount from '../../../../../Apollo/Functions/fetchHolterEventsDailyCount';
import fetchHolterRhythmEventsCount from '../../../../../Apollo/Functions/fetchHolterRhythmEventsCount';
import fetchHolterRrHeatMapCount from '../../../../../Apollo/Functions/fetchHolterRrHeatMapCount';
import fetchHolterRrHeatMapOverview from '../../../../../Apollo/Functions/fetchHolterRrHeatMapOverview';
import handleCheckSavingAiProcess from '../../../../../Apollo/Functions/handleCheckSavingAiProcess';
import { clearApolloCache } from '../../../../../Apollo/apolloClient';
import { EMITTER_CONSTANTS } from '../../../../../ConstantsV2';
import {
  AI_COMMAND,
  EVENT_COUNT_CONVERT,
  KEY_CANCEL,
  KEY_RECOIL,
  STRIP_AFIB_THUMBNAIL_INFO,
  STRIP_ARTIFACT_THUMBNAIL_INFO,
  TYPE_RHYTHM_EVENT_ENUM,
  typesPersistEventV2,
} from '../../../../../ConstantsV2/aiConstants';
import { resetHistoryStateRecoil } from '../../../../../Store/dbHistoryStateRecoil';
import { getDataStateRecoil } from '../../../../../Store/dbStateRecoil';
import { convertToDayJS } from '../../../../../UtilsV2/aiUtils';
import {
  useEmitter,
  useGetRecoilValue,
} from '../../../../../UtilsV2/customHooks';
import emitter from '../../../../../UtilsV2/eventEmitter';
import { toastrError } from '../../../../../UtilsV2/toastNotification';
import {
  activeTabState,
  beatChangesState,
  dailyArtifactCountState,
  dailyCountState,
  ecgDataMapState,
  eventChangesState,
  eventFilterState,
  eventNewsState,
  eventOptionsState,
  eventOthersState,
  groupEventChangesState,
  isActiveTabState,
  isNotReadyAfterSaveState,
  isRenderViewerEcgState,
  originalDailySummariesState,
  pageIndexState,
  profileAfibAvgHrState,
  reloadEcgViewerState,
  reloadHrChartState,
  reportInfoState,
  selectedDateValueState,
  selectedStripState,
} from '../../Recoil';
import { isAppliedFilterEvent } from '../../RhythmEvents/handler';
import { beatEventCountState, rhythmEventCountState } from '../../RhythmEvents/recoil';
import { logError } from '../../handler';
import { formatDataChart } from '../rrInterval/heatMapChart/handler';
import { DATA_HEATMAP_STATUS } from './model';
import { clearCachesBeatHourly } from '../../../../../Store/caches';
import { removeSavingData } from '../helper';

const BeatHrRecoilDataEffect = () => {
  const keyRecoil = KEY_RECOIL.TAB_1;
  const activeButton = useRecoilValue(activeTabState(keyRecoil));
  const getActiveButton = useGetRecoilValue(activeTabState(keyRecoil));
  const getSelectedStrip = useGetRecoilValue(selectedStripState(keyRecoil));
  const selectedDateValue = useRecoilValue(selectedDateValueState(keyRecoil));
  const getSelectedDateValue = useGetRecoilValue(selectedDateValueState(keyRecoil));
  const setBeatChanges = useSetRecoilState(beatChangesState(keyRecoil));
  const setEventChanges = useSetRecoilState(eventChangesState(keyRecoil));
  const setTotalStrip = useSetRecoilState(totalStripState);
  const setDailyCount = useSetRecoilState(dailyCountState(keyRecoil));
  const setArtifactDailyCount = useSetRecoilState(dailyArtifactCountState(keyRecoil));
  const setDailySummariesCombine = useSetRecoilState(dailySummariesCombineState);
  const setRrOverview = useSetRecoilState(rrOverviewState);
  const getRrOverview = useGetRecoilValue(rrOverviewState);
  const setRrOverviewOrigin = useSetRecoilState(rrOverviewOriginState);
  const getPageIndex = useGetRecoilValue(pageIndexState(keyRecoil));
  const setPageIndex = useSetRecoilState(pageIndexState(keyRecoil));
  const [updatedDailySummaries, setUpdatedDailySummaries] = useRecoilState(updatedDailySummariesState);
  const setReloadEcgViewer = useSetRecoilState(reloadEcgViewerState(keyRecoil));
  const setReloadHrChart = useSetRecoilState(reloadHrChartState(keyRecoil));
  const getDataHeatmapChart = useGetRecoilValue(dataHeatmapChartState);
  const getDataHeatmapChartStatus = useGetRecoilValue(dataHeatmapChartStatusState);
  const getListReviewedCells = useGetRecoilValue(listReviewedCellsState);
  const getListUnReviewedCells = useGetRecoilValue(listUnReviewedCellsState);
  const setListReviewedCells = useSetRecoilState(listReviewedCellsState);
  const setListUnReviewedCells = useSetRecoilState(listUnReviewedCellsState);
  const setDataHeatmapChart = useSetRecoilState(dataHeatmapChartState);
  const setDataHeatmapChartStatus = useSetRecoilState(dataHeatmapChartStatusState);
  const setListOriginReviewedCells = useSetRecoilState(listOriginReviewedCellsState);
  const setGroupEventChanges = useSetRecoilState(groupEventChangesState(keyRecoil));
  const getEventFilter = useGetRecoilValue(eventFilterState(keyRecoil));
  const isActiveTab = useRecoilValue(isActiveTabState(keyRecoil));
  const setIsNotReadyAfterSaveTab1 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_1));
  const setIsNotReadyAfterSaveTab2 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_2));
  const setIsNotReadyAfterSaveTab3 = useSetRecoilState(isNotReadyAfterSaveState(KEY_RECOIL.TAB_3));
  const getHolterRhythmEventsCount = useGetRecoilValue(rhythmEventCountState);
  const getListSelectedCells = useGetRecoilValue(listSelectedCellsState);
  const setListSelectedCells = useSetRecoilState(listSelectedCellsState);
  const setEventOthers = useSetRecoilState(eventOthersState(keyRecoil));
  const setEventNews = useSetRecoilState(eventNewsState(keyRecoil));
  const setEventOptions = useSetRecoilState(eventOptionsState(keyRecoil));
  const setHolterRhythmEventsCount = useSetRecoilState(rhythmEventCountState);
  const setHolterBeatEventsCount = useSetRecoilState(beatEventCountState);
  const setSelectedStrip = useSetRecoilState(selectedStripState(keyRecoil));
  const setIsRenderViewerEcg = useSetRecoilState(isRenderViewerEcgState);
  const setRrHeatMapCellChanges = useSetRecoilState(rrHeatMapCellChangesState);
  const setResetAppliedBulkChanges = useSetRecoilState(resetAppliedBulkChangesState);
  const setBeatOptions = useSetRecoilState(beatOptionsState(keyRecoil));

  const {
    studyId,
    profileId,
    timezoneOffset,
  } = useRecoilValue(reportInfoState);
  const [originalDailySummaries, setOriginalDailySummaries] = useRecoilState(originalDailySummariesState);
  const setEcgDataMap = useSetRecoilState(ecgDataMapState);
  const getEcgDataMap = useGetRecoilValue(ecgDataMapState);
  const setProfileAfibAvgHr = useSetRecoilState(profileAfibAvgHrState);

  const commandPendingQueue = useRef([]);
  const updateDataMessageQueue = useRef([]);
  const promiseUpdateData = useRef([]);
  const isExcutedRef = useRef(false);

  const [doneReset, setDoneReset] = useState(false);
  const [doneSetListOriginReviewedCells, setDoneSetListOriginReviewedCells] = useState(true);

  const formatRrOverview = (rrOverview) => {
    const result = generateDefaultHeatmapState({
      reviewed: 1,
      total: 1,
    });
    _.forEach(rrOverview, (x) => {
      result[x.rrHeatMapType] = x.total === 0 ? {
        reviewed: 1,
        total: 1,
      } : {
        reviewed: x.reviewed,
        total: x.total,
      };
    });
    return result;
  };

  const handleFetchRrOverview = async (isFistFetch = false) => {
    // check data from indexdb, if true, no need to fetch data from server
    const rrOver = await getDataStateRecoil('rrOverviewState');
    if (isFistFetch && rrOver) {
      return {};
    }
    try {
      const rrOverview = await fetchHolterRrHeatMapOverview({
        studyId,
        profileId,
      }, null, false);

      const formattedRrOverview = formatRrOverview(rrOverview);
      setRrOverview(formattedRrOverview);
      setRrOverviewOrigin(formattedRrOverview);
    } catch (error) {
      logError('Failed to fetch rr histogram overview', error);
    }
    return {};
  };

  const handleFetchStripEventsArtifact = async (page) => {
    if (!selectedDateValue) {
      return undefined;
    }
    try {
      const validatePage = page <= 0 ? 0 : page;
      const filterHolterEvents = {
        studyId,
        profileId,
        types: [TYPE_RHYTHM_EVENT_ENUM.ARTIFACT],
        startRange: {
          start: selectedDateValue,
          stop: dayjs(selectedDateValue).add(1, 'days').toISOString(),
        },
        skip: validatePage * STRIP_ARTIFACT_THUMBNAIL_INFO.stripDisplayLimit,
      };
      const { events } = await fetchHolterEvents(
        filterHolterEvents,
        STRIP_ARTIFACT_THUMBNAIL_INFO.stripDisplayLimit,
        true,
        KEY_CANCEL.API_HOLTER_AI,
      );
      return events;
    } catch (error) {
      return undefined;
    }
  };

  const handleFetchStripEventsAfib = async ({ page, additionalFilter = {} }) => {
    try {
      const type = getActiveButton();
      const validatePage = page <= 0 ? 0 : page;
      const filterHolterEvents = {
        studyId,
        profileId,
        types: [type],
        skip: validatePage * STRIP_AFIB_THUMBNAIL_INFO.stripDisplayLimit,
        ...additionalFilter,
      };
      const promises = [fetchHolterEvents(
        filterHolterEvents,
        STRIP_AFIB_THUMBNAIL_INFO.stripDisplayLimit,
        true,
        KEY_CANCEL.API_HOLTER_AI,
      )];
      if (!_.isEmpty(additionalFilter)) {
        const holterEventsCountFilter = {
          studyId,
          profileId,
          types: [type],
          ...additionalFilter,
        };
        promises.push(fetchHolterRhythmEventsCount(holterEventsCountFilter, true, KEY_CANCEL.API_HOLTER_AI));
      }
      const [{ events }, eventsCount] = await Promise.all(promises);
      if (!_.isEmpty(additionalFilter)) {
        return { events, eventsCount };
      }
      return { events, eventsCount: getHolterRhythmEventsCount() };
    } catch (error) {
      return { events: undefined, eventsCount: 0 };
    }
  };

  const handleReloadAfibV2 = async () => {
    try {
      const type = getActiveButton();
      const selectedDateValue = getSelectedDateValue();
      const startSearchDate = selectedDateValue;
      const stopSearchDate = selectedDateValue ? dayjs(selectedDateValue).add(1, 'days').toISOString() : null;
      const additionalFilter = {};
      const eventFilter = getEventFilter();
      if (isAppliedFilterEvent(eventFilter, type)) {
        _.assign(additionalFilter, {
          ...(eventFilter.isHideReviewed && { isReviewed: false }),
          ...(eventFilter.isCapture && { isCaptured: true }),
        });
      }
      const promiseArr = [
        selectedDateValue ? fetchHolterEvents({
          studyId,
          profileId,
          types: typesPersistEventV2,
          startSearchDate,
          stopSearchDate,
        }, 0, true, KEY_CANCEL.API_HOLTER_AI) : undefined,
        fetchHolterEventsDailyCount({
          studyId,
          profileId,
          types: [type],
          ...additionalFilter,
        }, null, false),
      ];
      const selectedStrip = getSelectedStrip();
      if (selectedStrip?.idEvent) {
        const filterHolterEventIndex = {
          studyId,
          profileId,
          types: [type],
          includedEventId: selectedStrip.idEvent,
          ...additionalFilter,
        };
        promiseArr.push(fetchHolterEventIndex(filterHolterEventIndex, false, KEY_CANCEL.API_HOLTER_AI));
      } else {
        promiseArr.push(new Promise((resolve) => resolve(undefined)));
      }
      const [resultHolterEventsPersistAllDay, resultDailyCount, resultEventIndex] = await Promise.allSettled(promiseArr);
      const dailyCount = resultDailyCount?.status === 'rejected' ? undefined : resultDailyCount.value;
      if (resultEventIndex?.status === 'fulfilled') {
        const eventIndex = resultEventIndex.value;
        if (!_.isNil(eventIndex) && eventIndex >= 0) {
          const page = Math.floor(eventIndex / STRIP_AFIB_THUMBNAIL_INFO.stripDisplayLimit);
          await handleFetchStripEventsAfib({ page, additionalFilter });
          promiseUpdateData.current.push(() => setPageIndex({ index: page < 0 ? 0 : page }));
        } else {
          const pageIndex = getPageIndex();
          const { events, eventsCount } = await handleFetchStripEventsAfib({ page: pageIndex.index, additionalFilter });
          if (_.isEmpty(events)) {
            const totalEvent = eventsCount[EVENT_COUNT_CONVERT[getActiveButton()]]?.count || 0;
            const pageTemp = Math.floor(totalEvent / STRIP_AFIB_THUMBNAIL_INFO.stripDisplayLimit);
            const page = (totalEvent % STRIP_AFIB_THUMBNAIL_INFO.stripDisplayLimit) === 0 ? pageTemp - 1 : pageTemp;
            promiseUpdateData.current.push(() => setPageIndex({ index: page < 0 ? 0 : page }));
          } else {
            promiseUpdateData.current.push(() => setPageIndex({ index: getPageIndex().index }));
          }
        }
      }
      if (!_.isEmpty(dailyCount)) {
        if (getActiveButton() === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
          promiseUpdateData.current.push(() => setArtifactDailyCount(dailyCount));
        } else {
          promiseUpdateData.current.push(() => setDailyCount(dailyCount));
        }
      }
      promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
    } catch (error) {
      logError('Failed to fetch reload data: ', error);
      toastrError(error.message, t`Error`);
    }
  };

  const handleReloadAfibHrChartV2 = async () => {
    try {
      const selectedDateValue = getSelectedDateValue();
      const startSearchDate = selectedDateValue;
      const stopSearchDate = selectedDateValue ? dayjs(selectedDateValue).add(1, 'days').toISOString() : null;
      const promiseArr = [
        selectedDateValue ? fetchHolterEvents({
          studyId,
          profileId,
          types: typesPersistEventV2,
          startSearchDate,
          stopSearchDate,
        }, 0, true, KEY_CANCEL.API_HOLTER_AI) : undefined,
      ];
      await Promise.allSettled(promiseArr);
      promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
    } catch (error) {
      logError('Failed to fetch reload data: ', error);
      toastrError(error.message, t`Error`);
    }
  };

  const handleReloadArtifact = async (reloadAll = false) => {
    try {
      // Thumbnail
      const filterDailyCount = {
        studyId,
        profileId,
        types: [TYPE_RHYTHM_EVENT_ENUM.ARTIFACT],
      };
      const promiseArr = [
        fetchHolterEventsDailyCount(filterDailyCount, null, false),
      ];
      const selectedDateValue = getSelectedDateValue();
      if (reloadAll) {
        // Strip event
        const selectedStrip = getSelectedStrip();
        if (selectedStrip?.idEvent && selectedDateValue) {
          const filterHolterEventIndex = {
            studyId,
            profileId,
            types: [TYPE_RHYTHM_EVENT_ENUM.ARTIFACT],
            startRange: {
              start: selectedDateValue,
              stop: dayjs(selectedDateValue).add(1, 'days').toISOString(),
            },
            includedEventId: selectedStrip.idEvent,
          };
          promiseArr.push(fetchHolterEventIndex(filterHolterEventIndex, false, KEY_CANCEL.API_HOLTER_AI));
        } else {
          promiseArr.push(new Promise((resolve) => resolve(undefined)));
        }
        if (selectedDateValue) {
          // Hr chart: fetch to cache only
          const filterHolterEvents = {
            studyId,
            profileId,
            types: [TYPE_RHYTHM_EVENT_ENUM.ARTIFACT],
            startSearchDate: selectedDateValue,
            stopSearchDate: dayjs(selectedDateValue).add(1, 'days').toISOString(),
          };
          promiseArr.push(fetchHolterEvents(filterHolterEvents, 0, true, KEY_CANCEL.API_HOLTER_AI));
        }
      }
      const [resultDailyCount, resultEventIndex, resultHolterEventsAllDay] = await Promise.allSettled(promiseArr);
      const dailyCount = resultDailyCount?.status === 'rejected' ? undefined : resultDailyCount.value;
      if (resultEventIndex?.status === 'fulfilled' && reloadAll) {
        const eventIndex = resultEventIndex.value;
        if (!_.isNil(eventIndex) && eventIndex >= 0) {
          const page = Math.floor(eventIndex / STRIP_ARTIFACT_THUMBNAIL_INFO.stripDisplayLimit);
          await handleFetchStripEventsArtifact(page);
          promiseUpdateData.current.push(() => {
            if (getActiveButton() === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
              setPageIndex({ index: page < 0 ? 0 : page });
            }
          });
        } else {
          const pageIndex = getPageIndex();
          const events = await handleFetchStripEventsArtifact(pageIndex.index);
          if (_.isEmpty(events)) {
            const currentSelectedDateValue = getSelectedDateValue();
            const totalEvent = _.find(dailyCount, (x) => x.date === currentSelectedDateValue)?.count || 0;
            const pageTemp = Math.floor(totalEvent / STRIP_ARTIFACT_THUMBNAIL_INFO.stripDisplayLimit);
            const page = (totalEvent % STRIP_ARTIFACT_THUMBNAIL_INFO.stripDisplayLimit) === 0 ? pageTemp - 1 : pageTemp;
            promiseUpdateData.current.push(() => {
              if (getActiveButton() === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
                setPageIndex({ index: page < 0 ? 0 : page });
              }
            });
          } else {
            promiseUpdateData.current.push(() => {
              if (getActiveButton() === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
                setPageIndex({ index: getPageIndex().index });
              }
            });
          }
        }
      }
      if (!_.isEmpty(dailyCount)) {
        const currentSelectedDateValue = getSelectedDateValue();
        const foundDailyCount = _.find(dailyCount, (x) => x.date === currentSelectedDateValue)?.count;
        promiseUpdateData.current.push(() => {
          if (getActiveButton() === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
            setTotalStrip(foundDailyCount ?? 0);
            setArtifactDailyCount(dailyCount);
          } else {
            setDailyCount(dailyCount);
          }
        });
      }
      promiseUpdateData.current.push(() => setReloadHrChart((prev) => prev + _.round(Math.random() * 100)));
    } catch (error) {
      logError('Error: ', error);
      toastrError(error.message, t`Error`);
    }
    return true;
  };

  const handleReloadEvent = async (msg) => {
    if (isActiveTab) {
      setIsRenderViewerEcg(false);
    }
    try {
      const {
        newEvents, updatedEvents, deletedEvents, deletedEventTypes,
      } = msg;
      // Reload if user in artifact areas and event updated is in selected date
      const selectedDateValue = getSelectedDateValue();
      const selectedDateString = selectedDateValue ? convertToDayJS(selectedDateValue, timezoneOffset).format('DD-MM-YYYY') : null;
      const types = [TYPE_RHYTHM_EVENT_ENUM.AFIB, TYPE_RHYTHM_EVENT_ENUM.ARTIFACT];
      let needUpdateArtifact;
      let needUpdateAfib;
      if (deletedEventTypes?.length && !(needUpdateArtifact || needUpdateAfib)) {
        deletedEventTypes.forEach((type) => {
          if (types.includes(type) && activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
            needUpdateAfib = true;
          } else if (type === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT && activeButton === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
            needUpdateArtifact = true;
          }
        });
      }
      if (deletedEvents?.length && !(needUpdateArtifact || needUpdateAfib)) {
        deletedEvents.forEach((deletedEvent) => {
          if (deletedEvent.type === activeButton && activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
            needUpdateAfib = true;
          } else {
            const isSameDate = selectedDateString === convertToDayJS(deletedEvent.start, timezoneOffset).format('DD-MM-YYYY');
            if (deletedEvent.type === activeButton && isSameDate) {
              needUpdateArtifact = true;
            }
          }
        });
      }
      if (updatedEvents?.length && !(needUpdateArtifact || needUpdateAfib)) {
        updatedEvents.forEach((updatedEvent) => {
          if (updatedEvent.type === activeButton && activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
            needUpdateAfib = true;
          } else {
            const isSameDate = selectedDateString === convertToDayJS(updatedEvent.start, timezoneOffset).format('DD-MM-YYYY');
            if (updatedEvent.type === activeButton && isSameDate) {
              needUpdateArtifact = true;
            }
          }
        });
      }
      if (newEvents?.length && !(needUpdateArtifact || needUpdateAfib)) {
        newEvents.forEach((newEvent) => {
          if (newEvent.type === activeButton && activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
            needUpdateAfib = true;
          } else {
            const isSameDate = selectedDateString === convertToDayJS(newEvent.start, timezoneOffset).format('DD-MM-YYYY');
            if (newEvent.type === activeButton && isSameDate) {
              needUpdateArtifact = true;
            }
          }
        });
      }
      if (needUpdateArtifact) {
        await handleReloadArtifact(true);
      } else if (needUpdateAfib) {
        await handleReloadAfibV2();
      } else if (activeButton === TYPE_RHYTHM_EVENT_ENUM.ARTIFACT) {
        await handleReloadArtifact();
      } else if (activeButton === TYPE_RHYTHM_EVENT_ENUM.AFIB) {
        await handleReloadAfibHrChartV2();
      }
      console.log('[beatHrRecoilDataEffect]-RELOAD-EVENT-BEATHR', needUpdateArtifact, activeButton);
      promiseUpdateData.current.push(() => {
        setGroupEventChanges((prev) => {
          if (prev.length === 0) {
            return prev;
          }
          return [];
        });

        let eventChanges = [];
        let eventNews = [];
        let eventOthers = [];

        setEventChanges((prev) => {
          let count = 0;
          const filterResult = prev.filter((x) => {
            if (x.isSaving) {
              count += 1;
              return false;
            }
            return true;
          });
          if (count === 0) {
            return prev;
          }
          eventChanges.push(...filterResult);
          return filterResult;
        });
        setEventOthers((prev) => {
          let count = 0;
          const filterResult = prev.filter((x) => {
            if (x.isSaving) {
              count += 1;
              return false;
            }
            return true;
          });
          if (count === 0) {
            return prev;
          }
          eventOthers.push(...filterResult);
          return filterResult;
        });
        setEventNews((prev) => {
          let count = 0;
          const filterResult = prev.filter((x) => {
            if (x.isSaving) {
              count += 1;
              return false;
            }
            return true;
          });
          if (count === 0) {
            return prev;
          }
          eventNews.push(...filterResult);
          return filterResult;
        });
        setEventOptions({
          eventNewsState: eventNews,
          eventChangesState: eventChanges,
          eventOthersState: eventOthers,
        });
        setTimeout(() => {
          resetHistoryStateRecoil();
        }, 200);
        const selectedStrip = getSelectedStrip();
        if (selectedStrip?.isNew) {
          setSelectedStrip(null);
        }
        eventChanges = [];
        eventNews = [];
        eventOthers = [];
      });
      promiseUpdateData.current.push(() => setReloadEcgViewer((prev) => prev + _.round(Math.random() * 100)));
    } catch (error) {
      logError('Error: ', error);
    }
  };

  const updateCellsStatus = async (listDataHeatmapChart) => {
    const resultListReviewedCells = {};
    const resultListUnReviewedCells = {};
    const resultListOriginReviewedCells = {};

    const listUnReviewedCells = getListUnReviewedCells();

    const dataHeatmapChart = getDataHeatmapChart();
    const listReviewedCells = getListReviewedCells();

    const listSelectedCells = _.filter(getListSelectedCells(), (x) => !_.isNaN(Number(x.id)));
    const newListSelectedCells = [];
    let isSetListSelectedCells = false;
    const activeButton = getActiveButton();

    _.forEach(listDataHeatmapChart, (newDataHeatmapChart, key) => {
      const {
        listReviewedCells: currentListReviewedCells,
        listOriginReviewedCells,
      } = formatDataChart({
        currentDataHeatmapChart: newDataHeatmapChart,
        type: key,
      });
      resultListOriginReviewedCells[key] = listOriginReviewedCells;
      const oldDataHeatmapChart = dataHeatmapChart[key];

      const oldListReviewedCells = listReviewedCells[key];

      const studyId2 = window.location.pathname.split('/')[2];
      const defaultHeatmapState = JSON.parse(localStorage.getItem(`defaultValueHeatmap-${Number(studyId2)}`));

      if (defaultHeatmapState) {
        const resultRrOverviewCells = getRrOverview();
        defaultHeatmapState[key] = {
          newValue: {
            listReviewedCells: listReviewedCells[key],
            listUnReviewedCells: [],
            listSelectedCells: [],
            activeButton: key,
            markCells: 'initialize',
            resetData: true,
            rrOverview: resultRrOverviewCells,
          },
        };
        localStorage.setItem(`defaultValueHeatmap-${Number(studyId2)}`, JSON.stringify(defaultHeatmapState));
      }

      const newListReviewedCells = [];
      /* Điều kiện của list review mới:
        - Có trong list review hiện tại (list review được update trong thời gian saving) và không bị mất đi trong list data mới
        - Không nằm trong list data hiện tại nhưng có trong list data mới và có cờ isRevewed = true
      */
      let isSetListReviewedCells = false;

      _.forEach(currentListReviewedCells, (cells) => {
        // check trong list review
        const isInListOldReviewed = _.some(oldListReviewedCells, { id: cells.id });
        if (isInListOldReviewed) {
          // Có trong list review hiện tại (list review được update trong thời gian saving) và không bị mất đi trong list data mới
          newListReviewedCells.push(cells);
          return;
        }
        // check trong list data heatmap
        const isInListOldData = _.some(oldDataHeatmapChart, { id: cells.id });
        if (!isInListOldData) {
          // Không nằm trong list data hiện tại nhưng có trong list data mới và có cờ isRevewed = true
          isSetListReviewedCells = true;
          newListReviewedCells.push(cells);
        }
      });

      _.forEach(oldListReviewedCells, (cells) => {
        const isInListNewData = _.some(newDataHeatmapChart, { id: cells.id });

        if (!isInListNewData) {
          isSetListReviewedCells = true;
          return;
        }

        const isInCurrentList = _.some(newListReviewedCells, { id: cells.id });
        if (!isInCurrentList) {
          // Có trong list review hiện tại (list review được update trong thời gian saving) và không bị mất đi trong list data mới
          newListReviewedCells.push(cells);
        }
      });

      if (isSetListReviewedCells) {
        resultListReviewedCells[key] = newListReviewedCells;
      }
      // reset list unreview
      if (listUnReviewedCells[key]?.length > 0) {
        resultListUnReviewedCells[key] = [];
      }

      if (key === activeButton) {
        // Nếu có item không nằm trong list hiện tại (sau khi save bị xoá cell) hoặc nằm trong nhưng value thay đổi thì set reload
        _.forEach(listSelectedCells, (cell) => {
          let newDataValue;
          const isInNewData = _.some(newDataHeatmapChart, (item) => {
            if (item.id === cell.id) {
              newDataValue = item.count;
              return true;
            }
            return false;
          });
          if (isInNewData) {
            const newCell = { ...cell, value: newDataValue };
            if (cell.value !== newDataValue) {
              isSetListSelectedCells = true;
            }
            newListSelectedCells.push(newCell);
            return;
          }
          isSetListSelectedCells = true;
        });
      }
    });

    if (!_.isEmpty(resultListReviewedCells)) {
      setListReviewedCells((prev) => ({
        ...prev,
        ...resultListReviewedCells,
      }));
    }

    if (!_.isEmpty(resultListUnReviewedCells)) {
      setListUnReviewedCells((prev) => ({
        ...prev,
        ...resultListUnReviewedCells,
      }));
    }

    setListOriginReviewedCells(resultListOriginReviewedCells);
    if (isSetListSelectedCells) {
      emitter.emit(EMITTER_CONSTANTS.UPDATE_RELOAD_BEAT, newListSelectedCells);
      setListSelectedCells(newListSelectedCells);
    } else {
      emitter.emit(EMITTER_CONSTANTS.UPDATE_RELOAD_BEAT);
    }
  };

  const fetchDataHeatmapChart = async (key) => {
    try {
      const filter = {
        studyId,
        profileId,
        rrHeatMapType: key,
      };
      const newDataHeatmapChart = await fetchHolterRrHeatMapCount(filter, null, false);
      return {
        [key]: newDataHeatmapChart,
      };
    } catch (error) {
      logError('Failed to fetch rr heatmap data', error);
      toastrError(error.message);
      return {};
    }
  };

  const handleReloadRrHeatMap = async () => {
    await clearApolloCache();
    const promiseArr = [handleFetchRrOverview()];

    _.forEach(getDataHeatmapChartStatus(), (value, key) => {
      if (value === DATA_HEATMAP_STATUS.SUCCESS || value === DATA_HEATMAP_STATUS.EMPTY) {
        promiseArr.push(fetchDataHeatmapChart(key));
      }
    });

    const data = await Promise.all(promiseArr);
    const newDataHeatmapChart = {};
    const newDataHeatMapChartStatus = {};
    _.forEach(data, (value) => {
      if (!_.isEmpty(value)) {
        _.assign(newDataHeatmapChart, value);
      }
    });

    Object.keys(newDataHeatmapChart).forEach((key) => {
      if (_.isEmpty(newDataHeatmapChart[key])) {
        newDataHeatMapChartStatus[key] = DATA_HEATMAP_STATUS.EMPTY;
      } else {
        newDataHeatMapChartStatus[key] = DATA_HEATMAP_STATUS.SUCCESS;
      }
    });
    setDataHeatmapChart((prev) => ({
      ...prev,
      ...newDataHeatmapChart,
    }));
    setDataHeatmapChartStatus((prev) => ({
      ...prev,
      ...newDataHeatMapChartStatus,
    }));
    // use setTimeOut in order to waiting all setState in recoil
    updateCellsStatus(newDataHeatmapChart);

    setTimeout(() => {
      emitter.emit(EMITTER_CONSTANTS.UPDATE_HEATMAP_CHART_DATA);
    }, 0);
  };

  const handleUpdateBeats = (msg) => {
    const prevEcgDataMap = getEcgDataMap();
    const cloneEcgDataMap = { ...prevEcgDataMap };
    if ((msg.summaries?.length || msg.beatsUpdated?.summaries?.length) && !_.isEmpty(prevEcgDataMap?.data)) {
      _.forEach(msg.summaries || msg.beatsUpdated?.summaries, (summary) => {
        const foundData = _.find(cloneEcgDataMap.data, (x) => x.id === summary.id);
        if (foundData) {
          _.assign(foundData, {
            avgHrs: summary?.avgHrs,
            maxHrs: summary?.maxHrs,
            minHrs: summary?.minHrs,
            beatFinalPath: summary?.beatFinalPath,
            latestBeatPrefix: summary?.latestBeatPrefix,
          });
        }
      });
      const summaryIds = _.map(msg.summaries || msg.beatsUpdated?.summaries, 'id');
      const socketUpdateEcgDataMap = {
        ...cloneEcgDataMap,
        data: _.filter(cloneEcgDataMap.data, (item) => summaryIds.includes(item.id)),
      };
      if (isActiveTab) {
        emitter.emit(EMITTER_CONSTANTS.UPDATE_SOCKET_BEAT_DATA_MAP, socketUpdateEcgDataMap);
      }
    }
    return cloneEcgDataMap;
  };

  const handleReloadBeat = async (msg) => {
    try {
      const cloneEcgDataMap = handleUpdateBeats(msg);
      promiseUpdateData.current.push(() => {
        let rrHeatMapCellChanges = [];
        const resetAppliedBulkChanges = [];
        let beatsChanges = [];
        setRrHeatMapCellChanges((prev) => {
          if (_.isEmpty(prev)) return prev;
          rrHeatMapCellChanges = removeSavingData(prev);
          return rrHeatMapCellChanges;
        });
        setResetAppliedBulkChanges((prev) => {
          if (_.isEmpty(prev)) return prev;
          resetAppliedBulkChanges.push(...removeSavingData(prev));
          return resetAppliedBulkChanges;
        });
        setBeatChanges((prev) => {
          if (_.isEmpty(prev)) return prev;
          const beats = removeSavingData(prev);
          beatsChanges = beats;
          return beats;
        });
        setBeatOptions((prev) => ({
          ...prev,
          rrHeatMapCellChangesState: rrHeatMapCellChanges,
          resetAppliedBulkChangesState: resetAppliedBulkChanges,
          beatChangesState: beatsChanges,
        }));
        setEcgDataMap((prev) => {
          if (_.isEqual(prev, cloneEcgDataMap)) {
            return prev;
          }
          return cloneEcgDataMap;
        });
        setReloadEcgViewer((prev) => prev + _.round(Math.random() * 100));
      });
    } catch (error) {
      logError('Failed to reload beat', error);
    }
  };

  const fetchEventsCount = async () => {
    try {
      const eventsCountFilter = {
        studyId,
        profileId,
      };
      const promises = [
        fetchHolterBeatEventsCount(eventsCountFilter, false, null, false),
        fetchHolterRhythmEventsCount(eventsCountFilter, false, null, false),
      ];
      const [holterBeatEventsCount, holterRhythmEventsCount] = await Promise.all(promises);
      setHolterBeatEventsCount(holterBeatEventsCount);
      setHolterRhythmEventsCount(holterRhythmEventsCount);
    } catch (error) {
      logError('Failed to fetch holter rhythm events count: ', error);
    }
  };

  const batchUpdateData = async () => {
    try {
      await clearApolloCache();
      await clearCachesBeatHourly();
      if (isActiveTab) {
        setIsRenderViewerEcg(false);
      }
      const promise = [];
      updateDataMessageQueue.current.forEach((x) => {
        if (x.type === AI_COMMAND.EVENT) {
          promise.push(handleReloadEvent(x.msg));
          promise.push(fetchEventsCount());
        }
      });
      const beatPromises = [];
      updateDataMessageQueue.current.forEach((x) => {
        if (x.type === AI_COMMAND.BEAT) {
          beatPromises.push(handleReloadBeat(x.msg));
        }
      });
      await Promise.all(beatPromises); // Wait for all beat promises to resolve
      await Promise.all(promise); // Wait for all promises to resolve
      promiseUpdateData.current.forEach((update) => update());
    } catch (error) {
      logError('Error: ', error);
    } finally {
      console.log('[beatHrRecoilDataEffect]-COMMANDEXECUTED-2', {
        updateDataMessageQueue: updateDataMessageQueue.current,
        promiseUpdateData: promiseUpdateData.current,
      });
      updateDataMessageQueue.current.length = 0;
      promiseUpdateData.current.length = 0;
      commandPendingQueue.current.length = 0;
      emitter.emit(EMITTER_CONSTANTS.RELOAD_EVENT_STRIP);
      if (isActiveTab) {
        setDoneReset(true);
      }
    }
  };

  const updateEventOutOfPending = _.debounce(async () => {
    await clearApolloCache();
    setIsRenderViewerEcg(false);
    setTimeout(() => {
      setIsRenderViewerEcg(true);
    }, 500);
  }, 2000);

  useEffect(() => {
    handleFetchRrOverview(true);
  }, []);

  useEffect(() => {
    if (originalDailySummaries?.length) {
      const dailySummariesCombine = [];
      for (let i = 0; i < originalDailySummaries.length; i += 1) {
        dailySummariesCombine.push({
          ...originalDailySummaries[i],
          ...(updatedDailySummaries.find((x) => x.date === originalDailySummaries[i].date)),
        });
      }
      setDailySummariesCombine(dailySummariesCombine);
    }
  }, [originalDailySummaries, updatedDailySummaries]);

  useEffect(() => {
    if (doneReset && doneSetListOriginReviewedCells) {
      setTimeout(() => {
        emitter.emit(EMITTER_CONSTANTS.AI_LOADING, {
          tab: 'beatHr',
          isLoading: false,
          isExcuted: isExcutedRef.current,
        });
        setDoneReset(false);
        if (isExcutedRef.current) {
          isExcutedRef.current = false;
        }
      }, 2000);
    }
  }, [doneReset, doneSetListOriginReviewedCells]);

  useEmitter(EMITTER_CONSTANTS.UPDATE_SET_LIST_ORIGIN_REVIEWED_CELLS_STATUS, (msg) => {
    setDoneSetListOriginReviewedCells(msg);
  }, []);

  useEmitter(EMITTER_CONSTANTS.RR_CELL_REVIEWED, () => {
    handleFetchRrOverview();
  }, []);

  useEmitter(EMITTER_CONSTANTS.RR_HEATMAP_UPDATED, () => {
    handleReloadRrHeatMap();
  }, [
    activeButton,
    studyId,
    profileId,
  ]);

  useEmitter(EMITTER_CONSTANTS.EVENTSUPDATED_EVENT, (msg) => {
    const foundMsg = updateDataMessageQueue.current.find((x) => x.type === AI_COMMAND.EVENT);
    if (foundMsg) {
      if (!_.isEmpty(msg)) {
        Object.keys(msg).forEach((key) => {
          if (foundMsg.msg[key]) {
            foundMsg.msg[key] = foundMsg.msg[key].concat(msg[key]);
          } else {
            foundMsg.msg[key] = msg[key];
          }
        });
      }
    } else {
      updateDataMessageQueue.current.push({
        type: AI_COMMAND.EVENT,
        msg: _.cloneDeep(msg),
      });
    }
    if (commandPendingQueue.current.length === 0) { // update out of pending command
      updateEventOutOfPending();
    }
  }, []);

  useEmitter(EMITTER_CONSTANTS.BEATSUPDATED_EVENT, (msg) => {
    const foundMsg = updateDataMessageQueue.current.find((x) => x.type === AI_COMMAND.BEAT);
    if (foundMsg) {
      if (!_.isEmpty(msg)) {
        _.assign(foundMsg, { msg });
      }
    } else {
      updateDataMessageQueue.current.push({
        type: AI_COMMAND.BEAT,
        msg,
      });
    }
  }, []);

  useEmitter(EMITTER_CONSTANTS.DAILY_SUMMARY_UPDATED, (msg) => {
    setOriginalDailySummaries((prev) => {
      if (msg) {
        const cloneDailySummaries = _.cloneDeep(prev);
        _.forEach(msg, (dailySummary) => {
          const foundDailySummary = _.find(cloneDailySummaries, (x) => x.date === dailySummary.date);
          if (foundDailySummary) {
            _.assign(foundDailySummary, dailySummary);
          }
        });
        return cloneDailySummaries;
      }
      return prev;
    });
    setUpdatedDailySummaries([]);
  }, []);

  useEmitter(EMITTER_CONSTANTS.AFIB_HR_SUMMARY_UPDATED, (msg) => {
    const { afibAvgHr } = msg;
    setProfileAfibAvgHr(afibAvgHr);
  }, []);

  useEmitter(EMITTER_CONSTANTS.AI_PROCESS_SAVED, async (msg) => {
    await batchUpdateData();
    setIsNotReadyAfterSaveTab1(false);
  }, [selectedDateValue, activeButton, studyId, profileId, isActiveTab]);

  useEmitter(EMITTER_CONSTANTS.COMMAND_PENDING, (msg) => {
    // *: Khi 1 user save, BE gửi command pending về tuỳ theo số lượng api gọi lúc save, push command vào mảng và khi
    // có socket command execute thì remove => khi mảng về 0 thì get hết data nhận đc trong mảng updateDataMessage => update UI
    if (msg.messageId !== profileId) {
      return;
    }

    emitter.emit(EMITTER_CONSTANTS.AI_LOADING, {
      tab: 'beatHr',
      isLoading: true,
    });
    commandPendingQueue.current.push(msg.command);
  }, [profileId]);

  useEmitter(EMITTER_CONSTANTS.COMMAND_EXECUTED, async (msg) => {
    // msg.command: update-events, update-beats, updateHolterHrDailySummary,reviewRrIntervals,get-single-events
    // updateHolterProfile, generate-report-comments
    if (msg.messageId !== profileId) return;
    if (msg.command === 'updateHolterProfile' || msg.command === 'generate-report-comments') return;
    console.log('[beatHrRecoilDataEffect]-COMMANDEXECUTED-BEFORE', {
      msg,
      commandPendingQueue: commandPendingQueue.current,
      updateDataMessageQueue: updateDataMessageQueue.current,
    });
    const foundIndexCommand = commandPendingQueue.current.findIndex((command) => command === msg.command);
    if (foundIndexCommand !== -1) {
      commandPendingQueue.current.splice(foundIndexCommand, 1);
    }
    // *: Finish all command
    if (commandPendingQueue.current.length === 0) {
      isExcutedRef.current = true;
      if (isActiveTab) {
        if (updateDataMessageQueue.current.length !== 0) {
          // *: Announce this tab have data to update
          emitter.emit(EMITTER_CONSTANTS.AI_UPDATE_TAB, '1');
          const { events, strips } = await handleCheckSavingAiProcess({
            studyId,
            profileId,
          });
          if (!events) {
            setIsNotReadyAfterSaveTab2(true);
          }
          if (!strips) {
            setIsNotReadyAfterSaveTab3(true);
          }
          await batchUpdateData();
        } else {
          setDoneReset(true);
        }
      } else {
        await batchUpdateData();
      }
    }
  }, [selectedDateValue, activeButton, isActiveTab, studyId, profileId]);

  return null;
};

export default BeatHrRecoilDataEffect;
/* eslint-disable class-methods-use-this */
/* eslint no-console:0 */
// import logHandler from './logHandler';
import { Auth } from '@aws-amplify/auth';
import _ from 'lodash';
import io from 'socket.io-client';
import { EMITTER_CONSTANTS } from '../ConstantsV2';
import AppConstant from '../ConstantsV2/appFlowActions';
import { logError } from '../LayoutV2/Reports/AiEditReport/handler';
import CONFIG from '../config/config';
import auth from './auth';
import emitter from './eventEmitter';

class SocketClient {
  constructor() {
    this.isConnected = false;
    this.isLazyLoading = false;
    this.rooms = [];
    this.intervalRoom = null;

    this.queueECGEvent = [];
    this.queueNewEvent = [];
    this.queueReportUpdate = [];

    this.roomUsersEvent = [];
    this.timeOutRoomEvent = undefined;
    this.intervalJoinRoomEvent = null;
    this.queueRoomEvent = [];

    this.roomUsersReport = [];
    this.timeOutRoomReport = undefined;
    this.intervalJoinRoomReport = null;
    this.queueRoomReport = [];

    this.timeOutOverviewtUpdate = undefined;
    this.queueOverviewUpdate = [];
  }

  getAuth = async () => {
    const accessToken = auth.isLoginWithMicrosoftAccount()
      ? (await Auth.currentSession()).getAccessToken().getJwtToken()
      : auth.token();
    auth.setOriginalToken(accessToken);
    return {
      accessToken,
    };
  };

  connectToServer = async () => {
    try {
      if (!this.socket) {
        this.socket = io(CONFIG.SOCKET, {
          forceNew: true,
          transports: ['websocket'],
          auth: async cb => cb(await this.getAuth()),
          // Prevent disconnect socket before unload to send close event to server
          closeOnBeforeunload: false,
        });
        this.socket.on('connect', this.connectListener);
      }
    } catch (error) {
      logError('Failed to connect socket: ', error);
      this.disconnectSocket();
    }
  };

  connectListener = () => {
    this.isConnected = true;
    auth.setSocketId(this.socket?.id);
    this.socket.off('reconnect');
    this.socket.on('disconnect', this.disconnectListener);
    // this.socket.on('studyEvent', this.studyEventListener);
    // this.socket.on('deviceEvent', this.deviceEventListener);
    // this.socket.on('lastSync', this.lastSyncListener);
    // this.socket.on('studyUpdated', this.studyUpdatedListener);
    // this.socket.on('studyDeleted', this.studyDeletedListener);
    // this.socket.on('inbox', this.inboxListener);
    this.socket.on('roomUsers', this.roomUsersListener);
    this.socket.on('KickClientsByToken', this.kickClientsByTokenListener);
    this.socket.on('KickClientsByUsername', this.kickClientsByUsernameListener);
    this.socket.on('newSession', this.newSessionListener);
    if (auth.isCallCenter()) {
      // this.socket.on('isPreparingFullData', this.isPreparingFullDataListener);
      // this.socket.on('newEvent', this.newEventListener);
      // this.socket.on('multipleEventsClosed', this.multipleEventsClosedListener);
      // this.socket.on('facilityUpdated', this.facilityUpdatedListener);
      // this.socket.on('bucketChanged', this.bucketChangedListener);
      // this.socket.on('moreStudies', this.moreStudiesListener);

      this.socket.on('eventUpdated', this.eventUpdatedListener);
      this.socket.on('reportUpdated', this.reportUpdatedListener);
      this.socket.on('groupUpdated', this.groupUpdatedListener);
      this.socket.on('profileReady', this.profileReadyListener);
      this.socket.on('beatsUpdated', this.beatsUpdatedListener);
      this.socket.on('eventsUpdated', this.eventsUpdatedListener);
      this.socket.on('dailySummaryUpdated', this.dailySummaryUpdatedListener);
      this.socket.on('afibHrSummaryUpdated', this.afibHrSummaryUpdatedListener);
      this.socket.on('holterProfileUpdated', this.holterProfileUpdatedListener);
      this.socket.on('technicianCommentsUpdated', this.technicianCommentsUpdatedListener);
      this.socket.on('rrCellsReviewed', this.rrCellsReviewedListener);
      this.socket.on('commandProgressUpdated', this.commandProgressUpdatedListener);
      this.socket.on('commandExecuted', this.commandExecutedListener);
      this.socket.on('commandPending', this.commandPendingListener);
      this.socket.on('rrHeatMapUpdated', this.rrHeatMapUpdatedListener);
      this.socket.on('aiProcessSaved', this.aiProcessSavedListener);
      this.socket.on('migrateAiData', this.migrateAiDataListener);
      this.socket.on('reCapturedEvents', this.reCapturedEventsListener);
    }
    //* Test socket
    // setTimeout(() => {
    //   emitter.emit(EMITTER_CONSTANTS.COMMAND_PENDING, {
    //     messageId: '65857578925735af4701e5ad',
    //     command: 'update-beats',
    //   });
    // }, 10000);
    // setTimeout(() => {
    //   emitter.emit(EMITTER_CONSTANTS.COMMAND_EXECUTED, {
    //     messageId: '65857578925735af4701e5ad',
    //     command: 'update-beats',
    //     isSuccess: true,
    //   });
    // }, 11000);
  };

  disconnectListener = (error) => {
    console.log('socket io - on disconnect:', error);

    // emitter.emit(EMITTER_CONSTANTS.LOST_CONNECTION, CONNECTION_TYPE.SOCKET);
    // alert('Sorry for the inconvenience!\nThe system ran into a problem and needs to reload a page.');
    // window.location.reload();

    this.isConnected = false;
    this.socket.io.on('reconnect', this.reconnectListener);

    this.socket.off('connect');
    this.socket.off('disconnect');

    // this.socket.off('studyEvent');
    // this.socket.off('deviceEvent');
    // this.socket.off('lastSync');
    // this.socket.off('studyUpdated');
    // this.socket.off('studyDeleted');
    // this.socket.off('inbox');
    this.socket.off('roomUsers');
    this.socket.off('KickClientsByToken');
    this.socket.off('KickClientsByUsername');
    this.socket.off('newSession');

    if (auth.isCallCenter()) {
      // this.socket.off('isPreparingFullData');
      // this.socket.off('newEvent');
      // this.socket.off('multipleEventsClosed');
      // this.socket.off('facilityUpdated');
      // this.socket.off('bucketChanged');
      // this.socket.off('moreStudies');

      this.socket.off('eventUpdated');
      this.socket.off('reportUpdated');
      this.socket.off('groupUpdated');
      this.socket.off('profileReady');
      this.socket.off('beatsUpdated');
      this.socket.off('eventsUpdated');
      this.socket.off('dailySummaryUpdated');
      this.socket.off('afibHrSummaryUpdated');
      this.socket.off('holterProfileUpdated');
      this.socket.off('technicianCommentsUpdated');
      this.socket.off('rrCellsReviewed');
      this.socket.off('commandProgressUpdated');
      this.socket.off('commandExecuted');
      this.socket.off('commandPending');
      this.socket.off('rrHeatMapUpdated');
      this.socket.off('aiProcessSaved');
      this.socket.off('migrateAiData');
    }

    if (error && error.trim() === 'io server disconnect') {
      window.isSessionExpired = true;
      emitter.emit(EMITTER_CONSTANTS.EXPIRED_TOKEN, 'request');
      this.socket = null;
    }

    // if (error && error.trim() === 'ping timeout' && !auth.token()) {
    //   this.disconnectSocket();
    //   this.socket = null;
    // }
    // if (error && error.trim() === 'io server disconnect') {
    //   emitter.emit(EMITTER_CONSTANTS.EXPIRED_TOKEN, 'request');
    //   this.socket = null;
    // }
  };

  reconnectListener = () => {
    console.log('on reconnect');
    this.socket.on('connect', this.connectListener);
    // window.location.reload();
    // Remove duplicate data
    const uniqRooms = _.uniqWith(this.rooms, _.isEqual);
    console.log('uniqRooms', uniqRooms);
    _.forEach(uniqRooms, (room) => {
      const { name, id } = room;
      switch (name) {
        case 'joinReportRoom': {
          this.sendJoinReportRoom(id);
          break;
        }
        default: {
          this.emitIntervalEvent(name, id);
          break;
        }
      }
    });
  };

  eventUpdatedListener = (msg) => {
    console.log('socket io - eventUpdatedListener', msg);
    if (msg.study?._id) {
      this.addQueueECGEventUpdate(msg.study?._id);
    }
    emitter.emit(EMITTER_CONSTANTS.UPDATE_EVENT_ECG, msg);
    if (auth.isCallCenter()) {
      this.addQueueHandleUpdateReport({ type: 'eventUpdated', data: msg });
    }
  };

  reportUpdatedListener = (msg) => {
    console.log('socket io - reportUpdatedListener', msg);
    emitter.emit(EMITTER_CONSTANTS.REPORT_UPDATED, msg);
    if (auth.isCallCenter()) {
      this.addQueueHandleUpdateReport({ type: 'reportUpdated', data: msg });

      if (auth.isCallCenterSupervisor() || auth.isCallCenterQaLeader()) {
        this.addQueueHandleUpdateOverview({ type: 'reportUpdated', data: msg });
      }
    }
  };

  migrateAiDataListener = (msg) => {
    console.log('socket io - migrateAiDataListener', msg);
    emitter.emit(EMITTER_CONSTANTS.MIGRATE_AI_DATA_VER1_TO_VER2, msg);
  };

  newSessionListener = (msg) => {
    console.log('socket io - newSessionListener', msg);
    emitter.emit(EMITTER_CONSTANTS.NEW_SESSION, msg);
  };

  groupUpdatedListener = (msg) => {
    console.log('socket io - groupUpdatedListener', msg);
    emitter.emit(EMITTER_CONSTANTS.GROUP_UPDATED, msg);
  };

  profileReadyListener = (msg) => {
    console.log('socket io - profileReadyListener', msg);
    emitter.emit(EMITTER_CONSTANTS.PROFILE_READY, msg);
  };

  beatsUpdatedListener = (msg) => {
    console.log('socket io - beatsUpdatedListener', msg);
    // logHandler.addLog('beatsUpdated', msg);
    emitter.emit(EMITTER_CONSTANTS.BEATSUPDATED_EVENT, msg);
  };

  eventsUpdatedListener = (msg) => {
    console.log('socket io - eventsUpdatedListener', msg);
    // logHandler.addLog('eventsUpdated', msg);
    emitter.emit(EMITTER_CONSTANTS.EVENTSUPDATED_EVENT, msg);
  };

  afibHrSummaryUpdatedListener = (msg) => {
    console.log('socket io - afibHrSummaryUpdatedListener', msg);
    // logHandler.addLog('afibHrSummaryUpdated', msg);
    emitter.emit(EMITTER_CONSTANTS.AFIB_HR_SUMMARY_UPDATED, msg);
  };

  dailySummaryUpdatedListener = (msg) => {
    console.log('socket io - dailySummaryUpdatedListener', msg);
    // logHandler.addLog('dailySummaryUpdated', msg);
    emitter.emit(EMITTER_CONSTANTS.DAILY_SUMMARY_UPDATED, msg);
  };

  holterProfileUpdatedListener = (msg) => {
    console.log('socket io - holterProfileUpdatedListener', msg);
    emitter.emit(EMITTER_CONSTANTS.HOLTER_PROFILE_UPDATED, msg);
  };

  technicianCommentsUpdatedListener = (msg) => {
    console.log('socket io - technicianCommentsUpdatedListener', msg);
    emitter.emit(EMITTER_CONSTANTS.TECHNICIAN_COMMENT_UPDATED, msg);
  };

  rrCellsReviewedListener = (msg) => {
    console.log('socket io - rrCellsReviewedListener', msg);
    // logHandler.addLog('rrCellsReviewed', msg);
    emitter.emit(EMITTER_CONSTANTS.RR_CELL_REVIEWED, msg);
  };

  commandProgressUpdatedListener = (msg) => {
    console.log('socket io - commandProgressUpdatedListener', msg);
    emitter.emit(EMITTER_CONSTANTS.COMMAND_PROGRESS_UPDATED, msg);
  };

  commandExecutedListener = (msg) => {
    console.log('socket io - commandExecutedListener', msg);
    // logHandler.addLog('commandExecuted', msg);
    // logHandler.sendLog();
    emitter.emit(EMITTER_CONSTANTS.COMMAND_EXECUTED, msg);
  };

  commandPendingListener = (msg) => {
    console.log('socket io - commandPendingListener', msg);
    // logHandler.addLog('commandPending', msg);
    emitter.emit(EMITTER_CONSTANTS.COMMAND_PENDING, msg);
  };

  rrHeatMapUpdatedListener = (msg) => {
    console.log('socket io - rrHeatMapUpdatedListener', msg);
    // logHandler.addLog('rrHeatMapUpdated', msg);
    emitter.emit(EMITTER_CONSTANTS.RR_HEATMAP_UPDATED, msg);
  };

  aiProcessSavedListener = (msg) => {
    console.log('socket io - aiProcessSavedListener', msg);
    // logHandler.addLog('aiProcessSaved', msg);
    // logHandler.sendLog();
    emitter.emit(EMITTER_CONSTANTS.AI_PROCESS_SAVED, msg);
  };

  reCapturedEventsListener = async (msg) => {
    console.log('socket io - reCapturedEventsListener', msg);
    emitter.emit(EMITTER_CONSTANTS.RE_CAPTURE_EVENTS, msg);
  };

  roomUsersListener = (msg) => {
    console.log('socket io - roomUsersListener', msg);
    // logHandler.addLog('roomUsers', msg);
    if (msg.roomType === 'Event') {
      this.roomUsersEvent.push(msg);
    } else if (msg.roomType === 'Report') {
      this.roomUsersReport.push(msg);
    }
    if (!this.timeOutRoomEvent) {
      this.timeOutRoomEvent = setTimeout(() => {
        if (this.roomUsersEvent.length > 0) {
          emitter.emit(EMITTER_CONSTANTS.EVENT_ROOM_USER, this.roomUsersEvent.splice(0, this.roomUsersEvent.length));
        }
        if (this.roomUsersReport.length > 0) {
          emitter.emit(EMITTER_CONSTANTS.REPORT_ROOM_USER, this.roomUsersReport.splice(0, this.roomUsersReport.length));
        }
        this.timeOutRoomEvent = undefined;
      }, 1000);
    }
  };

  kickClientsByTokenListener = (msg) => {
    console.log('socket io - kickClientsByTokenListener', msg);
    emitter.emit(AppConstant.LOGOUT_REQUEST, 'request');
  };

  kickClientsByUsernameListener = (msg) => {
    console.log('socket io - kickClientsByUsernameListener', msg);
    emitter.emit(AppConstant.LOGOUT_REQUEST, 'request');
  };

  emitIntervalEvent = (status, id) => {
    console.log('EMITEVENT', status, id, this.isConnected);
    if (this.isConnected) {
      // console.log(`${this.TAG} ${status} `, id);
      this.socket.emit(status, id);
    } else {
      const interval = setInterval(() => {
        // console.log(`${this.TAG} ${status} `, id);
        if (this.isConnected) {
          this.socket.emit(status, id);
          clearInterval(interval);
        }
        if (!auth.token()) {
          clearInterval(interval);
        }
      }, 1000);
    }
  };

  handleStoreRooms = (name, id) => {
    if (!_.some(this.rooms, x => x.id === id)) {
      this.rooms.push({ name, id });
    }
  };

  emitRoom = (id) => {
    if (id && id !== 'undefined') {
      this.handleStoreRooms('room', id);
      this.emitIntervalEvent('room', id);
    }
  };

  addQueueECGEventUpdate = (studyId, msg = {}) => {
    this.queueECGEvent.push(studyId);
    if (!_.isEmpty(msg)) {
      this.queueNewEvent.push({ id: msg.id, stripImgs: msg.stripImgs });
    }
    if (!this.timeOutEventUpdate) {
      this.timeOutEventUpdate = setTimeout(() => {
        this.timeOutEventUpdate = undefined;
        emitter.emit(EMITTER_CONSTANTS.UPDATE_TOTAL_EVENTS, this.queueECGEvent.splice(0, this.queueECGEvent.length));
        if (this.queueNewEvent.length > 0) {
          emitter.emit(EMITTER_CONSTANTS.UPDATE_NEW_EVENT_ECG, this.queueNewEvent.splice(0, this.queueNewEvent.length));
        }
      }, 5000);
    }
  };

  addQueueHandleUpdateReport = (msg) => {
    this.queueReportUpdate.push(msg);
    if (!this.timeOutReportUpdate) {
      this.timeOutReportUpdate = setTimeout(() => {
        this.timeOutReportUpdate = undefined;
        if (this.updateReportReminder) {
          console.log('this.queueReportUpdate', this.queueReportUpdate);
          this.updateReportReminder(this.queueReportUpdate.splice(0, this.queueReportUpdate.length));
        }
      }, 1000);
    }
  };

  addQueueHandleUpdateOverview = (msg) => {
    this.queueOverviewUpdate.push(msg);
    if (!this.timeOutOverviewtUpdate) {
      this.timeOutOverviewtUpdate = setTimeout(() => {
        this.timeOutOverviewtUpdate = undefined;
        emitter.emit(EMITTER_CONSTANTS.UPDATE_OVERVIEW, this.queueOverviewUpdate.splice(0, this.queueOverviewUpdate.length));
      }, 15000);
    }
  };

  sendMessageToServer(event, data) {
    console.log('sendMessageToServer ', event, data);
    this.socket.emit(event, data);
  }

  // send join event room
  sendJoinEventRoom(room, isPreview = false) {
    const msg = {
      room,
      isPreview,
    };
    this.queueRoomEvent.push(msg);
    if (this.isConnected) {
      this.socket.emit('joinEventRoom', msg);
    } else if (!this.intervalJoinRoomEvent) {
      this.intervalJoinRoomEvent = setInterval(() => {
        if (this.isConnected) {
          const datas = _.assign([], this.queueRoomEvent);
          this.queueRoomEvent.splice(0, datas.length);
          _.forEach(datas, (e) => {
            this.socket.emit('joinEventRoom', e);
          });
          clearInterval(this.intervalJoinRoomEvent);
          this.intervalJoinRoomEvent = null;
        }
      }, 1000);
    }
  }

  // send join report room
  sendJoinReportRoom(room, isPreview = false) {
    const msg = {
      room,
      isPreview,
    };
    this.queueRoomReport.push(msg);
    if (this.isConnected) {
      console.log('[ ==> ] sendJoinReportRoom connected', msg);
      this.handleStoreRooms('joinReportRoom', msg.room);
      this.socket.emit('joinReportRoom', msg);
    } else if (!this.intervalJoinRoomReport) {
      this.intervalJoinRoomReport = setInterval(() => {
        if (this.isConnected) {
          const datas = _.assign([], this.queueRoomReport);
          this.queueRoomReport.splice(0, datas.length);
          // Remove duplicate data
          const uniqDatas = _.uniqWith(datas, _.isEqual);
          _.forEach(uniqDatas, (e) => {
            console.log('[ ==> ] sendJoinReportRoom', e);
            this.handleStoreRooms('joinReportRoom', e.room);
            this.socket.emit('joinReportRoom', e);
          });
          clearInterval(this.intervalJoinRoomReport);
          this.intervalJoinRoomReport = null;
        }
      }, 1000);
    }
  }

  sendLeaveReportRoom(room, isPreview = false) {
    const msg = {
      room,
      isPreview,
    };
    // *: Only use interval for emiting room
    // this.emitIntervalEvent('leaveReportRoom', msg);
    if (this.socket && this.isConnected) {
      console.log('[ ==> ] sendLeaveReportRoom', msg);
      _.remove(this.rooms, x => x.id === msg.room);
      this.socket.emit('leaveReportRoom', msg);
    }
  }

  sendLeaveEventRoom(room, isPreview = false) {
    const msg = {
      room,
      isPreview,
    };
    if (this.socket && this.isConnected) {
      _.remove(this.rooms, x => x.id === msg.room);
      this.socket.emit('leaveEventRoom', msg);
    }
  }

  disconnectSocket() {
    console.log('socket io disconnect', this.socket);
    if (this.socket) {
      this.socket.disconnect();
    }
    this.socket = null;
    this.rooms.length = 0;
  }
}

const staticSocket = new SocketClient();

export default staticSocket;
<script> 
$( document ).ready(function() {  
  
	//Change this ID's for the ID's of the pages you'd like to exclude.
	var exclude = ["d295a5b5-9761-4e54-a776-76fcbcafdd7e", 
                       "582eee08-77a6-4038-8e92-8c356f1bb64b", 
                       "dcd9aed3-ca05-4f9c-9fb9-4f09b44246e7"]; 
   
  	//Get page id.
	var pageId = window.ub.page.id
  	//Compare pageId to array
  	if (jQuery.inArray(pageId, exclude)=='-1') {
      
    		//ADD YOUR SCRIPT HERE
      
        }
});
</script>
////////////////**** FILTER FUNCTION*****///////////////////
const MyNum = [1,2,3,4,5,6,7,8,9,10]
   
   
   
const  mynums = MyNum
                .map((num) => num  * 10)
                .map((num) => num  + 1)
                .filter((num) => num  >= 40)
                
console.log(mynums);
                
//////// reduce function ///////////////////////
                
const NUM = [1, 2, 3, 4];
const mytotal = NUM.reduce(function (acc, currval) {
    console.log(`acc: ${acc} and currval: ${currval}`);
    return acc + currval;
}, 0); // zero is the acc's initial value
console.log(mytotal);

const mytot = NUM.reduce((acc, curr) => acc+curr, 0 )
console.log(mytot);

const shoppingCart = [
    {
        itemName: "js course",
        price: 2999
    },
    {
        itemName: "py course",
        price: 999
    },
    {
        itemName: "mobile dev course",
        price: 5999
    },
    {
        itemName: "data science course",
        price: 12999
    },
]

const priceToPay = shoppingCart.reduce((acc, item) => acc + item.price, 0)

console.log(priceToPay);
    $cnpp = cnplanpriceTable::getOneByPlan('A_PP_FREE1');

    $ads = cnadTable::getInstance()
      ->createQuery()
      ->andWhere('userid = ?', 1107924)
      ->andWhere('hw_pay_plan LIKE ?', '%A_PA_FREE1%')
      ->execute([], Doctrine::HYDRATE_ON_DEMAND);
    $this->log('Found ' . count($ads) . ' ads');

    foreach ( $ads as $cnad )
    {
      $cnad->setPlan($cnpp);
      $cnad->save();

      $cnexp = cnexpirationTable::getItem($cnad, 'ad_plan');
      $cnexp->setValue('A_PP_FREE1');
      $cnexp->save();
      $this->log('Processed ' . $cnad->getLinkId());
    }
const getWeekOfYear = (date: Date): number => {
  const startOfYear = new Date(date.getFullYear(), 0, 1);
  const days = Math.floor(
    (date.getTime() - startOfYear.getTime()) / (24 * 60 * 60 * 1000)
  );
  return Math.ceil((days + startOfYear.getDay() + 1) / 7);
};
///////////***********FILTER , MAP AND REDUCE ********////////////

 const coding = ["js", "ruby", "java", "python", "cpp"]


 const values = coding.forEach( (item) => {
   console.log(item);
     return item
 } )

 console.log(values);

/////////////////*********** FILTER FUNCTION **********************////////////
const myNums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// const newNums = myNums.filter( (num) => {
//  return num > 4
// } )

const newNums = []

 myNums.forEach( (num) => {
     if (num > 4) {
         newNums.push(num)
    }
 } )

console.log(newNums);


const books = [
    { title: 'Book One', genre: 'Fiction', publish: 1981, edition: 2004 },
    { title: 'Book Two', genre: 'Non-Fiction', publish: 1992, edition: 2008 },
    { title: 'Book Three', genre: 'History', publish: 1999, edition: 2007 },
    { title: 'Book Four', genre: 'Non-Fiction', publish: 1989, edition: 2010 },
    { title: 'Book Five', genre: 'Science', publish: 2009, edition: 2014 },
    { title: 'Book Six', genre: 'Fiction', publish: 1987, edition: 2010 },
    { title: 'Book Seven', genre: 'History', publish: 1986, edition: 1996 },
    { title: 'Book Eight', genre: 'Science', publish: 2011, edition: 2016 },
    { title: 'Book Nine', genre: 'Non-Fiction', publish: 1981, edition: 1989 },
  ];

  let userBooks  = books.filter( (bk) => bk.genre === 'History')
  console.log(userBooks);
  
  userBook = books.filter( (bk) => { 
    return bk.publish >= 1995 && bk.genre === "History"
})
  console.log(userBook);
#include <iostream>

int main() {
    int a, b, f1=0, f2=1, i;

    std::cout << "Введите число a: ";
    std::cin >> a;
    
    std::cout << "Введите число b: ";
    std::cin >> b;
    
    for(i = a; i <= b; i++)
        std::cout << i << " " ;
        
    std::cout << std::endl;    
    
    if( a == 0 )
        std::cout << 0 << " " ;
        
    while( f2 <= b ){
        if( f2 >= a )
            std::cout << f2 << " " ;
        i = f2;
        f2 = f1 + f2;
        f1 = i;
        }    
        
    return 0;
}
if (!function_exists('media_sideload_image')) {
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    require_once(ABSPATH . 'wp-admin/includes/file.php');
    require_once(ABSPATH . 'wp-admin/includes/media.php');
}


add_action('gform_after_submission_2', 'create_gallery_post_after_submission', 10, 2);
function create_gallery_post_after_submission($entry, $form) {
    // Include necessary functions for media handling
    if (!function_exists('media_sideload_image')) {
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');
    }

    // Define your custom post type
    $post_type = 'gallery';

    // Prepare post data
    $post_data = array(
        'post_title'   => rgar($entry, '5'), // Assuming field ID 5 is the title
        'post_content' => '', // Assuming field ID 2 is the content
        'post_status'  => 'publish',
        'post_type'    => $post_type,
    );

    // Insert the post into the database
    $post_id = wp_insert_post($post_data);

    // Get the image URLs from entry
    $image_urls = json_decode(rgar($entry, '1')); // Assuming field ID 1 contains the JSON array string
    $image_ids = array(); // Array to hold the IDs of uploaded images

    // Loop through each image URL
    if (is_array($image_urls)) {
        foreach ($image_urls as $image_url) {
            // Upload the image to the Media Library
            $image_id = media_sideload_image($image_url, $post_id, null, 'id');
            if (!is_wp_error($image_id)) {
                $image_ids[] = $image_id; // Collect the image ID
            }
        }
    }

    // Optionally, you can set post meta for the uploaded images
    if (!empty($image_ids)) {
        update_post_meta($post_id, 'gallery_images', $image_ids); // Store the array of image IDs
    }
}


add_filter('woocommerce_get_breadcrumb', 'precise_custom_woocommerce_breadcrumbs', 20, 2);
function precise_custom_woocommerce_breadcrumbs($crumbs, $breadcrumb) {
    // הסרת עמוד הבית
    if (isset($crumbs[0]) && $crumbs[0][0] == get_bloginfo('name')) {
        array_shift($crumbs);
    }

    // אם אנחנו בעמוד מוצר
    if (is_product()) {
        $product = wc_get_product();
        $product_categories = get_the_terms($product->get_id(), 'product_cat');
       
        if ($product_categories) {
            // מציאת הקטגוריה העמוקה ביותר
            $deepest_category = null;
            foreach ($product_categories as $category) {
                if (!$deepest_category || count(get_ancestors($category->term_id, 'product_cat')) >
                    count(get_ancestors($deepest_category->term_id, 'product_cat'))) {
                    $deepest_category = $category;
                }
            }

            if ($deepest_category) {
                // הכנת מערך חדש של פירורי לחם
                $new_crumbs = [];
               
                // קבלת ההורים של הקטגוריה
                $term_parents = get_ancestors($deepest_category->term_id, 'product_cat');
                $term_parents = array_reverse($term_parents);

                // הוספת ההורים
                foreach ($term_parents as $parent_id) {
                    $parent_term = get_term($parent_id, 'product_cat');
                    $new_crumbs[] = [$parent_term->name, get_term_link($parent_term)];
                }

                // הוספת הקטגוריה העמוקה ביותר
                $new_crumbs[] = [$deepest_category->name, get_term_link($deepest_category)];

                // הוספת שם המוצר
                $new_crumbs[] = [$product->get_name(), get_permalink($product)];

                // החלפת הפירורי לחם המקוריים
                $crumbs = $new_crumbs;
            }
        }
    }

    // אם אנחנו בדף קטגוריה
    if (is_product_category()) {
        $current_category = get_queried_object();
        $ancestors = get_ancestors($current_category->term_id, 'product_cat');
        $ancestors = array_reverse($ancestors);

        // הכנת מערך חדש של פירורי לחם
        $new_crumbs = [];

        // הוספת ההורים
        foreach ($ancestors as $ancestor_id) {
            $ancestor_term = get_term($ancestor_id, 'product_cat');
            $new_crumbs[] = [$ancestor_term->name, get_term_link($ancestor_term)];
        }

        // הוספת הקטגוריה הנוכחית
        $new_crumbs[] = [$current_category->name, get_term_link($current_category)];

        // החלפת הפירורי לחם המקוריים
        $crumbs = $new_crumbs;
    }

    return $crumbs;
// import React, { useRef, useState, useEffect } from 'react'
// import { HotTable } from '@handsontable/react'
// import 'handsontable/dist/handsontable.full.min.css'
// import Handsontable from 'handsontable'
// import {
//   registerControl,
//   RegisterControlProps,
//   RegisteredControlProperties,
// } from '../hoc/registerControl'
// import { CustomContentRenderer } from './utils/customButtonRenderer'
// import { hyperformulaInstance, sheetId } from './utils/hyperformulaConfig'
// import { reformatDate, reformatCurrency } from './utils/formatters'
// import { SpreadsheetProperties } from '@components/features/FormBuilder/FormBuilderFieldProperties/Spreadsheet/types'
// import { registerAllCellTypes } from 'handsontable/cellTypes'
// import { registerAllPlugins } from 'handsontable/plugins'
// import { useFormBuilderWorksheetGrid } from '../../hooks/useFormBuilderWorksheetGrid'
// import { createSpreadsheetDefaultValue } from '../../FormBuilderFieldProperties/Spreadsheet/constants'
// import { useFormBuilder } from '../../hooks/useFormBuilder'
// import { useFormService } from '../../hooks/useFormService'

// registerAllCellTypes()
// registerAllPlugins()

// type Properties = RegisteredControlProperties &
//   SpreadsheetProperties & {
//     externalVariables?: {
//       [key: string]: {
//         propertyName?: string
//         defaultValue?: number
//       }
//     }
//   }

// const SpreadsheetControl: React.FC<RegisterControlProps<Properties>> = (
//   props
// ) => {
//   const hotTableRef = useRef<any>(null)
//   const containerRef = useRef<HTMLDivElement>(null)

//   const { rows = 1, columns = 1 } = props.properties || {}

//   const DEFAULT_COLUMN_WIDTH = 100
//   const DEFAULT_ROW_HEIGHT = 25

//   const defaultMeta = {
//     data: createSpreadsheetDefaultValue(rows, columns),
//     cellFormats: {} as { [key: string]: 'date' | 'currency' | undefined },
//     mergeCellsConfig: [],
//   }

//   const meta = props.properties?.meta || defaultMeta
//   const { actions: formBuilderWorksheetActions } = useFormBuilderWorksheetGrid()
//   const { actions, data: formBuilderData } = useFormBuilder()
//   const { watch } = useFormService()
//   const formData = watch()

//   if (!actions || !actions.getAllFields) {
//   }

//   const [data, setData] = useState(() => JSON.parse(JSON.stringify(meta.data)))
//   const [cellFormats, setCellFormats] = useState(meta.cellFormats)
//   const [mergeCellsConfig, setMergeCellsConfig] = useState(
//     meta.mergeCellsConfig
//   )

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName) {
//           if (!existingExpressions.includes(propertyName)) {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//           } else {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           }
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (props.externalVariables) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       Object.entries(props.externalVariables).forEach(([key, property]) => {
//         const typedProperty = property as {
//           propertyName?: string
//           defaultValue?: number
//         }

//         const variableName = typedProperty.propertyName || key
//         const value = Number(typedProperty.defaultValue || 0)

//         if (!existingExpressions.has(variableName)) {
//           try {
//             hyperformulaInstance.addNamedExpression(
//               variableName,
//               value,
//               sheetId
//             )
//             existingExpressions.add(variableName)
//           } catch (error) {
//             console.error(
//               `Error adding named expression ${variableName}:`,
//               error
//             )
//           }
//         } else {
//           try {
//             hyperformulaInstance.changeNamedExpression(
//               variableName,
//               value,
//               sheetId
//             )
//           } catch (error) {
//             console.error(
//               `Error updating named expression ${variableName}:`,
//               error
//             )
//           }
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {
//         console.error(
//           'Error during HyperFormula rebuild and recalculation:',
//           error
//         )
//       }
//     }
//   }, [props.externalVariables])

//   useEffect(() => {
//     if (formBuilderData) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formBuilderData).forEach(([key, value]) => {
//         const numericValue = Number(value) || 0

//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, numericValue)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, numericValue)
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName && !existingExpressions.has(propertyName)) {
//           try {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//             existingExpressions.add(propertyName)
//           } catch (error) {
//             console.error(
//               `Error adding named expression for ${propertyName}: ${error}`
//             )
//           }
//         } else if (propertyName) {
//           try {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           } catch (error) {
//             console.error(
//               `Error updating named expression for ${propertyName}: ${error}`
//             )
//           }
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {
//         console.error(
//           'Error during HyperFormula rebuild and recalculation:',
//           error
//         )
//       }
//     }
//   }, [formBuilderData?.fields])

//   useEffect(() => {
//     if (formData && Object.keys(formData).length > 0) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formData).forEach(([key, value]) => {
//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, Number(value) || 0)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, Number(value) || 0)
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {}
//     }
//   }, [formData])

//   useEffect(() => {
//     const adjustedData = adjustDataDimensions(data, rows, columns)
//     if (JSON.stringify(data) !== JSON.stringify(adjustedData)) {
//       setData(adjustedData)
//     }
//   }, [rows, columns])

//   const adjustDataDimensions = (
//     currentData: any[][],
//     rows: number,
//     columns: number
//   ) => {
//     const newData = currentData.map((row) => [...row])
//     if (newData.length < rows) {
//       for (let i = newData.length; i < rows; i++) {
//         newData.push(Array(columns).fill(null))
//       }
//     } else if (newData.length > rows) {
//       newData.length = rows
//     }
//     newData.forEach((row) => {
//       if (row.length < columns) {
//         row.push(...Array(columns - row.length).fill(null))
//       } else if (row.length > columns) {
//         row.length = columns
//       }
//     })
//     return newData
//   }

//   const handleAfterChange = (changes: any, source: string) => {
//     if (!changes || source === 'loadData') return

//     const validSheetId = sheetId ?? 0

//     changes.forEach(([row, col, oldValue, newValue]: any) => {
//       if (
//         newValue &&
//         typeof newValue === 'string' &&
//         newValue.startsWith('=')
//       ) {
//         try {
//           hyperformulaInstance.setCellContents(
//             { sheet: validSheetId, row, col },
//             [[newValue]]
//           )
//         } catch (error) {
//           console.error('Error setting formula:', error)
//         }
//       }
//     })

//     const updatedData = hotTableRef.current?.hotInstance?.getData()
//     if (JSON.stringify(data) !== JSON.stringify(updatedData)) {
//       setData(updatedData)
//       updateFieldProperties({ data: updatedData })
//     }
//   }

//   const handleMergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol, endRow, endCol] = selected[0]
//       const newMerge = {
//         row: startRow,
//         col: startCol,
//         rowspan: endRow - startRow + 1,
//         colspan: endCol - startCol + 1,
//       }

//       const updatedMergeCellsConfig = [...mergeCellsConfig, newMerge]
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleUnmergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol] = selected[0]
//       const mergeCellsPlugin = hotInstance.getPlugin('mergeCells')
//       mergeCellsPlugin.unmerge(startRow, startCol)

//       const updatedMergeCellsConfig = mergeCellsConfig.filter(
//         (cell) => cell.row !== startRow || cell.col !== startCol
//       )
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleSetAsDate = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = { ...cellFormats, [`${row}-${col}`]: 'date' as const }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }

//   const handleSetAsCurrency = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = {
//         ...cellFormats,
//         [`${row}-${col}`]: 'currency' as const,
//       }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }

//   const updateFieldProperties = (
//     updatedMeta: Partial<SpreadsheetProperties['meta']>
//   ) => {
//     if (!props?.runtime) {
//       const safeData = data ?? []

//       formBuilderWorksheetActions?.setFieldConfigProperty(props.config?.id!, {
//         meta: {
//           data: [...safeData.map((row: any) => (row ? [...row] : []))],
//           cellFormats: { ...cellFormats },
//           mergeCellsConfig: [...mergeCellsConfig],
//           ...updatedMeta,
//         },
//       } as Properties)
//     }
//   }

//   const cellsHandler = (row: number, col: number) => {
//     const cellProperties = {} as Handsontable.CellProperties
//     cellProperties.width = DEFAULT_COLUMN_WIDTH
//     cellProperties.height = DEFAULT_ROW_HEIGHT

//     // Check if the cell format exists, or default to undefined
//     const format = cellFormats?.[`${row}-${col}`]

//     if (format === 'date') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatDate(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     } else if (format === 'currency') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatCurrency(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     }

//     return cellProperties
//   }

//   return (
//     <div
//       ref={containerRef}
//       className="h-[400px] w-1/2 resize-x overflow-auto border md:w-full"
//       style={{ minWidth: '50%', maxWidth: '100%', resize: 'horizontal' }}
//       onMouseDown={(e) => e.stopPropagation()}
//     >
//       <HotTable
//         id="mySpreadsheet"
//         data={data}
//         colHeaders={true}
//         rowHeaders={true}
//         width="100%"
//         height="100%"
//         selectionMode="multiple"
//         copyPaste={true}
//         contextMenu={{
//           items: {
//             row_above: {},
//             row_below: {},
//             col_left: {},
//             col_right: {},
//             remove_row: {},
//             remove_col: {},
//             clear_column: {},
//             mergeCells: { name: 'Merge Cells', callback: handleMergeCells },
//             unmergeCells: {
//               name: 'Unmerge Cells',
//               callback: handleUnmergeCells,
//             },
//             set_as_date: { name: 'Set as Date', callback: handleSetAsDate },
//             set_as_currency: {
//               name: 'Set as Currency',
//               callback: handleSetAsCurrency,
//             },
//           },
//         }}
//         ref={hotTableRef}
//         afterChange={handleAfterChange}
//         persistentState={true}
//         licenseKey="non-commercial-and-evaluation"
//         manualColumnResize={false}
//         manualRowResize={false}
//         autoColumnSize={false}
//         autoRowSize={false}
//         stretchH="all"
//         mergeCells={mergeCellsConfig}
//         formulas={{ engine: hyperformulaInstance }}
//         cells={cellsHandler}
//         colWidths={DEFAULT_COLUMN_WIDTH}
//         rowHeights={DEFAULT_ROW_HEIGHT}
//       />
//     </div>
//   )
// }

// export default registerControl<Properties>(SpreadsheetControl, {
//   noDisplayLabel: true,
// })

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// import React, { useRef, useState, useEffect } from 'react'
// import { HotTable } from '@handsontable/react'
// import 'handsontable/dist/handsontable.full.min.css'
// import Handsontable from 'handsontable'
// import {
//   registerControl,
//   RegisterControlProps,
//   RegisteredControlProperties,
// } from '../hoc/registerControl'
// import { CustomContentRenderer } from './utils/customButtonRenderer'
// import { hyperformulaInstance, sheetId } from './utils/hyperformulaConfig'
// import { reformatDate, reformatCurrency } from './utils/formatters'
// import { SpreadsheetProperties } from '@components/features/FormBuilder/FormBuilderFieldProperties/Spreadsheet/types'
// import { registerAllCellTypes } from 'handsontable/cellTypes'
// import { registerAllPlugins } from 'handsontable/plugins'
// import { useFormBuilderWorksheetGrid } from '../../hooks/useFormBuilderWorksheetGrid'
// import { createSpreadsheetDefaultValue } from '../../FormBuilderFieldProperties/Spreadsheet/constants'
// import { useFormBuilder } from '../../hooks/useFormBuilder'
// import { useFormService } from '../../hooks/useFormService'

// registerAllCellTypes()
// registerAllPlugins()

// type Properties = RegisteredControlProperties &
//   SpreadsheetProperties & {
//     externalVariables?: {
//       [key: string]: {
//         propertyName?: string
//         defaultValue?: number
//       }
//     }
//   }

// const SpreadsheetControl: React.FC<RegisterControlProps<Properties>> = (
//   props
// ) => {
//   const hotTableRef = useRef<any>(null)
//   const containerRef = useRef<HTMLDivElement>(null)

//   const { rows = 1, columns = 1 } = props.properties || {}

//   const DEFAULT_COLUMN_WIDTH = 100
//   const DEFAULT_ROW_HEIGHT = 25

//   const defaultMeta = {
//     data: createSpreadsheetDefaultValue(rows, columns),
//     cellFormats: {} as { [key: string]: 'date' | 'currency' | undefined },
//     mergeCellsConfig: [],
//   }

//   const meta = props.properties?.meta || defaultMeta
//   const { actions: formBuilderWorksheetActions } = useFormBuilderWorksheetGrid()
//   const { actions, data: formBuilderData } = useFormBuilder()
//   const { watch } = useFormService()
//   const formData = watch()

//   if (!actions || !actions.getAllFields) {
//   }

//   const [data, setData] = useState(() => JSON.parse(JSON.stringify(meta.data)))
//   const [cellFormats, setCellFormats] = useState(meta.cellFormats)
//   const [mergeCellsConfig, setMergeCellsConfig] = useState(
//     meta.mergeCellsConfig
//   )

//   useEffect(() => {
//     console.log('Initializing meta from props:', props.properties?.meta)
//     const initialMeta = props.properties?.meta || defaultMeta
//     setData(JSON.parse(JSON.stringify(initialMeta.data)))
//     setCellFormats(initialMeta.cellFormats)
//     setMergeCellsConfig(initialMeta.mergeCellsConfig)
//   }, [props.properties?.meta])

//   useEffect(() => {
//     console.log('Data updated:', data)
//   }, [data])

//   useEffect(() => {
//     console.log('Cell formats updated:', cellFormats)
//   }, [cellFormats])

//   useEffect(() => {
//     console.log('Merge cells configuration updated:', mergeCellsConfig)
//   }, [mergeCellsConfig])

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName) {
//           if (!existingExpressions.includes(propertyName)) {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//           } else {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           }
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (props.externalVariables) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       Object.entries(props.externalVariables).forEach(([key, variable]) => {
//         const typedVariable = variable as {
//           propertyName?: string
//           defaultValue?: number
//         }

//         const variableName = typedVariable.propertyName || key
//         const value = Number(typedVariable.defaultValue || 0)

//         if (!existingExpressions.has(variableName)) {
//           hyperformulaInstance.addNamedExpression(variableName, value, sheetId)
//         } else {
//           hyperformulaInstance.changeNamedExpression(
//             variableName,
//             value,
//             sheetId
//           )
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//       syncSpreadsheetWithEngine()
//     }
//   }, [props.externalVariables])

//   useEffect(() => {
//     if (formBuilderData) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formBuilderData).forEach(([key, value]) => {
//         const numericValue = Number(value) || 0

//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, numericValue)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, numericValue)
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName && !existingExpressions.has(propertyName)) {
//           try {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//             existingExpressions.add(propertyName)
//           } catch (error) {
//             console.error(
//               `Error adding named expression for ${propertyName}: ${error}`
//             )
//           }
//         } else if (propertyName) {
//           try {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           } catch (error) {
//             console.error(
//               `Error updating named expression for ${propertyName}: ${error}`
//             )
//           }
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {
//         console.error(
//           'Error during HyperFormula rebuild and recalculation:',
//           error
//         )
//       }
//     }
//   }, [formBuilderData?.fields])

//   useEffect(() => {
//     if (formData && Object.keys(formData).length > 0) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formData).forEach(([key, value]) => {
//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, Number(value) || 0)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, Number(value) || 0)
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {}
//     }
//   }, [formData])

//   useEffect(() => {
//     const adjustedData = adjustDataDimensions(data, rows, columns)
//     if (JSON.stringify(data) !== JSON.stringify(adjustedData)) {
//       setData(adjustedData)
//       updateFieldProperties({ data: adjustedData })
//     }
//   }, [rows, columns])

//   const adjustDataDimensions = (
//     currentData: any[][],
//     rows: number,
//     columns: number
//   ) => {
//     const newData = currentData.map((row) => [...row])
//     if (newData.length < rows) {
//       for (let i = newData.length; i < rows; i++) {
//         newData.push(Array(columns).fill(null))
//       }
//     } else if (newData.length > rows) {
//       newData.length = rows
//     }
//     newData.forEach((row) => {
//       if (row.length < columns) {
//         row.push(...Array(columns - row.length).fill(null))
//       } else if (row.length > columns) {
//         row.length = columns
//       }
//     })
//     return newData
//   }
//   const syncSpreadsheetWithEngine = () => {
//     if (hotTableRef.current?.hotInstance) {
//       const updatedData = hyperformulaInstance.getSheetValues(sheetId)
//       console.log('Syncing spreadsheet with engine. Updated Data:', updatedData)
//       hotTableRef.current.hotInstance.loadData(updatedData)
//     }
//   }

//   const handleAfterChange = (changes: any, source: string) => {
//     console.log('After Change Triggered. Source:', source)
//     console.log('Changes:', changes)

//     if (!changes || source === 'loadData') return

//     const validSheetId = sheetId ?? 0

//     changes.forEach(([row, col, oldValue, newValue]: any) => {
//       console.log(
//         `Updating cell [${row}, ${col}] from ${oldValue} to ${newValue}`
//       )
//       if (
//         newValue &&
//         typeof newValue === 'string' &&
//         newValue.startsWith('=')
//       ) {
//         hyperformulaInstance.setCellContents(
//           { sheet: validSheetId, row, col },
//           [[newValue]]
//         )
//       } else {
//         hyperformulaInstance.setCellContents(
//           { sheet: validSheetId, row, col },
//           [[newValue || null]]
//         )
//       }
//     })

//     // Recalculate and sync data
//     hyperformulaInstance.rebuildAndRecalculate()
//     console.log(
//       'Recalculated HyperFormula Instance:',
//       hyperformulaInstance.getSheetValues(sheetId)
//     )
//     syncSpreadsheetWithEngine()
//   }

//   const handleMergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol, endRow, endCol] = selected[0]
//       const newMerge = {
//         row: startRow,
//         col: startCol,
//         rowspan: endRow - startRow + 1,
//         colspan: endCol - startCol + 1,
//       }

//       const updatedMergeCellsConfig = [...mergeCellsConfig, newMerge]
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleUnmergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol] = selected[0]
//       const mergeCellsPlugin = hotInstance.getPlugin('mergeCells')
//       mergeCellsPlugin.unmerge(startRow, startCol)

//       const updatedMergeCellsConfig = mergeCellsConfig.filter(
//         (cell) => cell.row !== startRow || cell.col !== startCol
//       )
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleSetAsDate = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = { ...cellFormats, [`${row}-${col}`]: 'date' as const }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }

//   const handleSetAsCurrency = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = {
//         ...cellFormats,
//         [`${row}-${col}`]: 'currency' as const,
//       }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }
//   const updateFieldProperties = (
//     updatedMeta: Partial<SpreadsheetProperties['meta']>
//   ) => {
//     console.log('Updating field properties with meta:', updatedMeta)
//     console.log('Current data:', data)
//     if (!props.runtime) {
//       formBuilderWorksheetActions?.setFieldConfigProperty(props.config?.id!, {
//         meta: {
//           data: [...data.map((row: any) => (row ? [...row] : []))],
//           cellFormats: { ...cellFormats },
//           mergeCellsConfig: [...mergeCellsConfig],
//           ...updatedMeta,
//         },
//       } as Properties)
//     }
//   }

//   const cellsHandler = (row: number, col: number) => {
//     const cellProperties = {} as Handsontable.CellProperties
//     cellProperties.width = DEFAULT_COLUMN_WIDTH
//     cellProperties.height = DEFAULT_ROW_HEIGHT

//     // Check if the cell format exists, or default to undefined
//     const format = cellFormats?.[`${row}-${col}`]

//     if (format === 'date') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatDate(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     } else if (format === 'currency') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatCurrency(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     }

//     return cellProperties
//   }

//   return (
//     <div
//       ref={containerRef}
//       className="h-[400px] w-1/2 resize-x overflow-auto border md:w-full"
//       style={{ minWidth: '50%', maxWidth: '100%', resize: 'horizontal' }}
//       onMouseDown={(e) => e.stopPropagation()}
//     >
//       <HotTable
//         id="mySpreadsheet"
//         data={data}
//         colHeaders={true}
//         rowHeaders={true}
//         width="100%"
//         height="100%"
//         selectionMode="multiple"
//         copyPaste={true}
//         contextMenu={{
//           items: {
//             row_above: {},
//             row_below: {},
//             col_left: {},
//             col_right: {},
//             remove_row: {},
//             remove_col: {},
//             clear_column: {},
//             mergeCells: { name: 'Merge Cells', callback: handleMergeCells },
//             unmergeCells: {
//               name: 'Unmerge Cells',
//               callback: handleUnmergeCells,
//             },
//             set_as_date: { name: 'Set as Date', callback: handleSetAsDate },
//             set_as_currency: {
//               name: 'Set as Currency',
//               callback: handleSetAsCurrency,
//             },
//           },
//         }}
//         ref={hotTableRef}
//         afterChange={handleAfterChange}
//         persistentState={true}
//         licenseKey="non-commercial-and-evaluation"
//         manualColumnResize={false}
//         manualRowResize={false}
//         autoColumnSize={false}
//         autoRowSize={false}
//         stretchH="all"
//         mergeCells={mergeCellsConfig}
//         formulas={{ engine: hyperformulaInstance }}
//         cells={cellsHandler}
//         colWidths={DEFAULT_COLUMN_WIDTH}
//         rowHeights={DEFAULT_ROW_HEIGHT}
//       />
//     </div>
//   )
// }

// export default registerControl<Properties>(SpreadsheetControl, {
//   noDisplayLabel: true,
// })

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

import React, { useRef, useState, useEffect } from 'react'
import { HotTable } from '@handsontable/react'
import 'handsontable/dist/handsontable.full.min.css'
import Handsontable from 'handsontable'
import {
  registerControl,
  RegisterControlProps,
  RegisteredControlProperties,
} from '../hoc/registerControl'
import { CustomContentRenderer } from './utils/customButtonRenderer'
import { hyperformulaInstance, sheetId } from './utils/hyperformulaConfig'
import { reformatDate, reformatCurrency } from './utils/formatters'
import { SpreadsheetProperties } from '@components/features/FormBuilder/FormBuilderFieldProperties/Spreadsheet/types'
import { registerAllCellTypes } from 'handsontable/cellTypes'
import { registerAllPlugins } from 'handsontable/plugins'
import { useFormBuilderWorksheetGrid } from '../../hooks/useFormBuilderWorksheetGrid'
import { createSpreadsheetDefaultValue } from '../../FormBuilderFieldProperties/Spreadsheet/constants'
import { useFormBuilder } from '../../hooks/useFormBuilder'
import { useFormService } from '../../hooks/useFormService'

registerAllCellTypes()
registerAllPlugins()

type Properties = RegisteredControlProperties &
  SpreadsheetProperties & {
    externalVariables?: {
      [key: string]: {
        propertyName?: string
        defaultValue?: number
      }
    }
  }

const SpreadsheetControl: React.FC<RegisterControlProps<Properties>> = (
  props
) => {
  const hotTableRef = useRef<any>(null)
  const containerRef = useRef<HTMLDivElement>(null)

  const { rows = 1, columns = 1 } = props.properties || {}

  const DEFAULT_COLUMN_WIDTH = 100
  const DEFAULT_ROW_HEIGHT = 25

  const defaultMeta = {
    data: createSpreadsheetDefaultValue(rows, columns),
    cellFormats: {} as { [key: string]: 'date' | 'currency' | undefined },
    mergeCellsConfig: [],
  }

  const meta = props.properties?.meta || defaultMeta
  const { actions: formBuilderWorksheetActions } = useFormBuilderWorksheetGrid()
  const { actions, data: formBuilderData } = useFormBuilder()
  const { watch } = useFormService()
  const formData = watch()

  if (!actions || !actions.getAllFields) {
  }

  const [data, setData] = useState(() => JSON.parse(JSON.stringify(meta.data)))
  const [cellFormats, setCellFormats] = useState(meta.cellFormats)
  const [mergeCellsConfig, setMergeCellsConfig] = useState(
    meta.mergeCellsConfig
  )

  useEffect(() => {
    if (props.externalVariables) {
      const existingExpressions = new Set(
        hyperformulaInstance.listNamedExpressions()
      )

      Object.entries(props.externalVariables).forEach(([key, property]) => {
        const typedProperty = property as {
          propertyName?: string
          defaultValue?: number
        }

        const variableName = typedProperty.propertyName || key
        const value = Number(typedProperty.defaultValue || 0)

        if (!existingExpressions.has(variableName)) {
          try {
            hyperformulaInstance.addNamedExpression(
              variableName,
              value,
              sheetId
            )
            existingExpressions.add(variableName)
          } catch (error) {
            console.error(
              `Error adding named expression ${variableName}:`,
              error
            )
          }
        } else {
          try {
            hyperformulaInstance.changeNamedExpression(
              variableName,
              value,
              sheetId
            )
          } catch (error) {
            console.error(
              `Error updating named expression ${variableName}:`,
              error
            )
          }
        }
      })

      try {
        hyperformulaInstance.rebuildAndRecalculate()
        syncSpreadsheetWithEngine()
      } catch (error) {
        console.error(
          'Error during HyperFormula rebuild and recalculation:',
          error
        )
      }
    }
  }, [props.externalVariables])

  const syncSpreadsheetWithEngine = () => {
    if (hotTableRef.current?.hotInstance) {
      const updatedData = hyperformulaInstance.getSheetValues(sheetId)
      console.log('Syncing spreadsheet with engine. Updated Data:', updatedData)
      hotTableRef.current.hotInstance.loadData(updatedData)
    }
  }

  useEffect(() => {
    const syncSpreadsheetWithEngine = () => {
      if (hotTableRef.current?.hotInstance) {
        const updatedData = hyperformulaInstance.getSheetValues(sheetId)
        console.log(
          'Syncing spreadsheet with engine. Updated Data:',
          updatedData
        )
        hotTableRef.current.hotInstance.loadData(updatedData)
      }
    }

    if (formBuilderData) {
      const existingExpressions = hyperformulaInstance.listNamedExpressions()

      Object.entries(formBuilderData).forEach(([key, value]) => {
        const numericValue = Number(value) || 0

        if (!existingExpressions.includes(key)) {
          hyperformulaInstance.addNamedExpression(key, numericValue)
        } else {
          hyperformulaInstance.changeNamedExpression(key, numericValue)
        }
      })

      hyperformulaInstance.rebuildAndRecalculate()
      syncSpreadsheetWithEngine()
    }
  }, [formBuilderData])

  useEffect(() => {
    if (formBuilderData?.fields) {
      const existingExpressions = new Set(
        hyperformulaInstance.listNamedExpressions()
      )

      formBuilderData.fields.forEach((field) => {
        const propertyName = field.properties?.propertyName
        const defaultValue = Number(field.properties?.defaultValue || 0)

        if (propertyName && !existingExpressions.has(propertyName)) {
          try {
            hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
            existingExpressions.add(propertyName)
          } catch (error) {
            console.error(
              `Error adding named expression for ${propertyName}: ${error}`
            )
          }
        } else if (propertyName) {
          try {
            hyperformulaInstance.changeNamedExpression(
              propertyName,
              defaultValue
            )
          } catch (error) {
            console.error(
              `Error updating named expression for ${propertyName}: ${error}`
            )
          }
        }
      })

      try {
        hyperformulaInstance.rebuildAndRecalculate()
      } catch (error) {
        console.error(
          'Error during HyperFormula rebuild and recalculation:',
          error
        )
      }
    }
  }, [formBuilderData?.fields])

  useEffect(() => {
    if (formData && Object.keys(formData).length > 0) {
      const existingExpressions = hyperformulaInstance.listNamedExpressions()

      Object.entries(formData).forEach(([key, value]) => {
        if (!existingExpressions.includes(key)) {
          hyperformulaInstance.addNamedExpression(key, Number(value) || 0)
        } else {
          hyperformulaInstance.changeNamedExpression(key, Number(value) || 0)
        }
      })

      try {
        hyperformulaInstance.rebuildAndRecalculate()
      } catch (error) {}
    }
  }, [formData])

  useEffect(() => {
    const adjustedData = adjustDataDimensions(data, rows, columns)
    if (JSON.stringify(data) !== JSON.stringify(adjustedData)) {
      setData(adjustedData)
    }
  }, [rows, columns])

  const adjustDataDimensions = (
    currentData: any[][],
    rows: number,
    columns: number
  ) => {
    const newData = currentData.map((row) => [...row])
    if (newData.length < rows) {
      for (let i = newData.length; i < rows; i++) {
        newData.push(Array(columns).fill(null))
      }
    } else if (newData.length > rows) {
      newData.length = rows
    }
    newData.forEach((row) => {
      if (row.length < columns) {
        row.push(...Array(columns - row.length).fill(null))
      } else if (row.length > columns) {
        row.length = columns
      }
    })
    return newData
  }

  const handleAfterChange = (changes: any, source: string) => {
    if (!changes || source === 'loadData') return

    const validSheetId = sheetId ?? 0

    changes.forEach(([row, col, oldValue, newValue]: any) => {
      if (
        newValue &&
        typeof newValue === 'string' &&
        newValue.startsWith('=')
      ) {
        try {
          hyperformulaInstance.setCellContents(
            { sheet: validSheetId, row, col },
            [[newValue]]
          )
        } catch (error) {
          console.error('Error setting formula:', error)
        }
      }
    })

    try {
      hyperformulaInstance.rebuildAndRecalculate()
      syncSpreadsheetWithEngine() // Ensure the spreadsheet reflects changes
    } catch (error) {
      console.error('Error recalculating formulas:', error)
    }
  }

  const handleMergeCells = () => {
    const hotInstance = hotTableRef.current?.hotInstance
    const selected = hotInstance?.getSelected()
    if (selected) {
      const [startRow, startCol, endRow, endCol] = selected[0]
      const newMerge = {
        row: startRow,
        col: startCol,
        rowspan: endRow - startRow + 1,
        colspan: endCol - startCol + 1,
      }

      const updatedMergeCellsConfig = [...mergeCellsConfig, newMerge]
      hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
      setMergeCellsConfig(updatedMergeCellsConfig)

      updateFieldProperties({
        data,
        cellFormats,
        mergeCellsConfig: updatedMergeCellsConfig,
      })
    }
  }

  const handleUnmergeCells = () => {
    const hotInstance = hotTableRef.current?.hotInstance
    const selected = hotInstance?.getSelected()
    if (selected) {
      const [startRow, startCol] = selected[0]
      const mergeCellsPlugin = hotInstance.getPlugin('mergeCells')
      mergeCellsPlugin.unmerge(startRow, startCol)

      const updatedMergeCellsConfig = mergeCellsConfig.filter(
        (cell) => cell.row !== startRow || cell.col !== startCol
      )
      hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
      setMergeCellsConfig(updatedMergeCellsConfig)

      updateFieldProperties({
        data,
        cellFormats,
        mergeCellsConfig: updatedMergeCellsConfig,
      })
    }
  }

  const handleSetAsDate = () => {
    const selected = hotTableRef.current?.hotInstance.getSelected()
    if (selected) {
      const [row, col] = selected[0]
      const newFormats = { ...cellFormats, [`${row}-${col}`]: 'date' as const }
      setCellFormats(newFormats)
      updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
    }
  }

  const handleSetAsCurrency = () => {
    const selected = hotTableRef.current?.hotInstance.getSelected()
    if (selected) {
      const [row, col] = selected[0]
      const newFormats = {
        ...cellFormats,
        [`${row}-${col}`]: 'currency' as const,
      }
      setCellFormats(newFormats)
      updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
    }
  }

  const updateFieldProperties = (
    updatedMeta: Partial<SpreadsheetProperties['meta']>
  ) => {
    if (!props?.runtime) {
      const safeData = data ?? []

      formBuilderWorksheetActions?.setFieldConfigProperty(props.config?.id!, {
        meta: {
          data: [...safeData.map((row: any) => (row ? [...row] : []))],
          cellFormats: { ...cellFormats },
          mergeCellsConfig: [...mergeCellsConfig],
          ...updatedMeta,
        },
      } as Properties)
    }
  }

  const cellsHandler = (row: number, col: number) => {
    const cellProperties = {} as Handsontable.CellProperties
    cellProperties.width = DEFAULT_COLUMN_WIDTH
    cellProperties.height = DEFAULT_ROW_HEIGHT

    // Check if the cell format exists, or default to undefined
    const format = cellFormats?.[`${row}-${col}`]

    if (format === 'date') {
      cellProperties.renderer = (
        instance,
        td,
        row,
        col,
        prop,
        value,
        cellProperties
      ) =>
        CustomContentRenderer(instance, td, row, col, () => {
          const span = document.createElement('span')
          span.innerText = reformatDate(
            instance.getDataAtCell(row, col) as string
          )
          return span
        })
    } else if (format === 'currency') {
      cellProperties.renderer = (
        instance,
        td,
        row,
        col,
        prop,
        value,
        cellProperties
      ) =>
        CustomContentRenderer(instance, td, row, col, () => {
          const span = document.createElement('span')
          span.innerText = reformatCurrency(
            instance.getDataAtCell(row, col) as string
          )
          return span
        })
    }

    return cellProperties
  }

  return (
    <div
      ref={containerRef}
      className="h-[400px] w-1/2 resize-x overflow-auto border md:w-full"
      style={{ minWidth: '50%', maxWidth: '100%', resize: 'horizontal' }}
      onMouseDown={(e) => e.stopPropagation()}
    >
      <HotTable
        id="mySpreadsheet"
        data={data}
        colHeaders={true}
        rowHeaders={true}
        width="100%"
        height="100%"
        selectionMode="multiple"
        copyPaste={true}
        contextMenu={{
          items: {
            row_above: {},
            row_below: {},
            col_left: {},
            col_right: {},
            remove_row: {},
            remove_col: {},
            clear_column: {},
            mergeCells: { name: 'Merge Cells', callback: handleMergeCells },
            unmergeCells: {
              name: 'Unmerge Cells',
              callback: handleUnmergeCells,
            },
            set_as_date: { name: 'Set as Date', callback: handleSetAsDate },
            set_as_currency: {
              name: 'Set as Currency',
              callback: handleSetAsCurrency,
            },
          },
        }}
        ref={hotTableRef}
        afterChange={handleAfterChange}
        persistentState={true}
        licenseKey="non-commercial-and-evaluation"
        manualColumnResize={false}
        manualRowResize={false}
        autoColumnSize={false}
        autoRowSize={false}
        stretchH="all"
        mergeCells={mergeCellsConfig}
        formulas={{ engine: hyperformulaInstance }}
        cells={cellsHandler}
        colWidths={DEFAULT_COLUMN_WIDTH}
        rowHeights={DEFAULT_ROW_HEIGHT}
      />
    </div>
  )
}

export default registerControl<Properties>(SpreadsheetControl, {
  noDisplayLabel: true,
})
n = input("Введите число с периодом (например, 0.1(23)): ")

f_index = n.index('(')
period = n[f_index + 1:n.index(')')]
non_periodic = n[:f_index]

a = non_periodic.replace('.', '') + period

integer_part = int(non_periodic.replace('.', '')) if '.' in non_periodic else int(non_periodic)

non_periodic_length = len(non_periodic.split('.')[-1]) if '.' in non_periodic else 0
period_length = len(period)

numerator = integer_part * (10 ** (non_periodic_length + period_length) - 1) + int(period)
denominator = (10 ** non_periodic_length - 1) * (10 ** period_length)

def to_base_6(value):
    if value == 0:
        return '0'
    base_6_value = ''
    while value > 0:
        base_6_value = str(value % 6) + base_6_value
        value //= 6
    return base_6_value

base_6_numerator = to_base_6(numerator)
base_6_denominator = to_base_6(denominator)

print(f'Число в шестиричной системе: {base_6_numerator}/{base_6_denominator}')
class employe{
    private String nom;
    private String pre;
    private int age;
    private float salaire;
    employe(){
        this.nom="sahar";
        this.pre="mess";
        this.age=20;
        this.salaire=2500;
    }
    employe(String nom,String pre,int age,float salaire){
        this.nom=nom;
        this.pre=pre;
        this.age=age;
        this.salaire=salaire;
    }
    employe(employe e){
        this.nom=e.nom;
        this.pre=e.pre;
        this.age=e.age;
        this.salaire=e.salaire;
    }
    public String getNom(){
        return this.nom;
    }
    public String getPre(){
        return this.pre;
    }
     int getAge(){
        return this.age;
    }
    float getSalaire(){
        return this.salaire;
    }
    void setNom(String nom){
        this.nom=nom;
    }
    void setPre(String pre){
        this.pre=pre;
    }
    void setAge(int age){
        this.age=age;
    }
    void setSalaire(float salaire){
        this.salaire=salaire;
    }
    void aug(float sa){
        this.salaire+=sa;
    }
    public String toString(){
        String ch;
        ch="Nom:"+this.nom+" | Prenom:"+this.pre+"|age :"+this.age+" | le salaire :"+this.salaire;
        return ch;
    }
    void affiche(){
        System.out.println(this.toString());
    }
    
}
class tech extends employe{
    private int grade;
    tech(){
        this.grade=1;
    }
    tech(String nom,String pre,int age,float salaire,int grade){
        super(nom,pre,age,salaire);
        setGrade(grade);
    }
    int getGrade(){
        return this.grade;
    }
    void setGrade(int grade){
        if(grade>=1 && grade<=3){
            this.grade=grade;
        }else{
            System.out.println("grade invalid il doit contenir 1,2 ou 3");
        }
    }
int prime(){
    switch(grade){
             case 1:return 100;
             case 2:return 200;
             case 3:return 300;
             default:return 0;
         }
}
public String toString(){
    String ch;
    ch=super.toString()+"|le grade :"+this.grade+"| le prime :"+this.prime();
    return ch;
}
void augme(){
    super.aug(this.prime());
}


}
class equipe{
    private tech[] tab;
    equipe(tech[] tab){
        this.tab=tab;
    }
  public tech hisa(){
       tech higs=tab[0];
      for(tech t:tab) {
          if(t.getSalaire() > higs.getSalaire()){
              higs=t;
          }
      }
      return higs;
  }
  public tech higa() {
        tech hig = tab[0];
        for (tech t : tab) {
            if (t.getGrade() > hig.getGrade()) {
                hig = t;
            }
        }
        return hig;
    }
    
}
public class Main{
    public static void main(String [] args){
        employe e1=new employe("yasmin","tri",20,2500);
        tech t1=new tech("asma","ben",25,3000,2);
        e1.affiche();
        t1.affiche();
        e1.aug(200);
        e1.affiche();
        t1.setGrade(2);
        t1.augme();
        t1.affiche();        
        tech t22 = new tech("Lemoine", "Claire", 28, 1900, 2);
        tech t3 = new tech("Bernard", "Alice", 32, 2100, 1);
        tech t4 = new tech("Durand", "Eric", 27, 1950, 1);
        tech t5 = new tech("Morel", "Sophie", 26, 1850, 2);
        tech[] tab={t22,t3,t4,t5};
        equipe eq=new equipe(tab);
        System.out.println("Highest Salary Technician: " + eq.hisa());
        System.out.println("Highest Grade Technician: " + eq.higa());
    }
}
class employe{
    private String nom;
    private String prenom;
    private int age;
    private float salaire;
    public employe(){
        this.nom="sahar";
        this.prenom="mess";
        this.age=20;
        this.salaire=4000;}
     employe(String nom,String prenom,int age,float salaire){
        this.nom=nom;
        this.prenom=prenom;
        this.age=age;
        this.salaire=salaire;
    }
      employe(employe e){
         this.nom=e.nom;
         this.prenom=e.prenom;
         this.age=e.age;
         this.salaire=e.salaire;
     }   
    public String getNom(){
        return this.nom;
    }
    public String getPrenom(){
        return this.prenom;
    }
     int getAge(){
        return this.age;
    }
    float getSalaire(){
        return this.salaire;
    }
     void setNom(String nom){
        this.nom=nom;
    }
     void setPrenom(String prenom){
        this.prenom=prenom;
    }
     void setAge(int age){
        this.age=age;
    }
     void setSalaire(float salaire){
        this.salaire=salaire;
    }
 void aug(float so){
     this.salaire+=so;
 } 
 public String toString(){
     String ch;
     ch="le nom est :"+this.nom+"| prenom est :"+this.prenom+"| age est :"+this.age+"| le salaire est :"+this.salaire;
     return ch;
 }
 public void affiche(){
     System.out.println(this.toString());
 }}
  class tech extends employe{
     private int grade;
     public tech(){
         this.grade=1;
     }
     public tech(String nom,String prenom,int age,float salaire,int grade){
         super(nom,prenom,age,salaire);
         setGrade(grade);
     }
     public int getGrade(){
         return this.grade;
     } 
     public void setGrade(int grade){
         if(grade>=1 && grade<=3){
             this.grade=grade;
         }else{
             System.out.println("grade invalid il doit contrnir 1,2 ou 3");
         }
     }
     public float prime(){
         switch(grade){
             case 1:return 100;
             case 2:return 200;
             case 3:return 300;
             default:return 0;
         }
     }
     public String toString(){
         String ch;
         ch=super.toString()+", grade:"+this.grade+", prime"+this.prime();
         return ch;
     }
    void augmentation(){
         super.aug(this.prime());
     }
 }
 class equipe{
     tech[] tab=new tech[10];
     equipe(tech[] t){
         tab=t;

         }
     }
  public class Main{
      public static void main(String [] args){
          employe E1=new employe();
          employe E2=new employe("sarsar","messour",19,4000);
          tech t1=new tech();
          tech t2=new tech("ahmed","messaoui",49,3500,1);
          E1.affiche();
          E2.affiche();
          t1.affiche();
          t2.affiche();
          E1.aug(200);
          E1.affiche();
          t1.setGrade(2);
          t1.augmentation();
          t1.affiche();
        tech t22 = new tech("Lemoine", "Claire", 28, 1900, 2);
        tech t3 = new tech("Bernard", "Alice", 32, 2100, 1);
        tech t4 = new tech("Durand", "Eric", 27, 1950, 1);
        tech t5 = new tech("Morel", "Sophie", 26, 1850, 2);
         tech[] tab={t1,t2,t3,t4,t5};
         equipe eq=new equipe(tab);
         Technicien meilleur = techniciens[0];
        for (tech tab : 10) {
            if (t.getSalaire() > meilleur.getSalaire()) {
                meilleur = t;
            }
        }
         tech mei=grmax;
         System.out.println("le plus rande est:");
        System.out.println(mei);
    

         
      }
  }
services:
  webui:
    image: ghcr.io/open-webui/open-webui:main
    ports:
      - 3000:8080/tcp
    volumes:
      - open-webui:/app/backend/data
    extra_hosts:
      - "host.docker.internal:host-gateway"
    depends_on:
      - ollama

  ollama:
    image: ollama/ollama
    expose:
      - 11434/tcp
    ports:
      - 11434:11434/tcp
    healthcheck:
      test: ollama --version || exit 1
    volumes:
      - ollama:/root/.ollama

volumes:
  ollama:
  open-webui:
New-Item -Path 'D:\temp\Test Folder' -ItemType Directory
SELECT
EmailAddress,AMC_Status__c,Job_Role__c,AMC_Last_Activity_Date__c, Industry_Level_2_Master__c, Industry__c, SubscriberKey, Consent_Level_Summary__c,
Business_Unit__c, Region, Cat_Campaign_Most_Recent__c , Mailing_Country__c, LastModifiedDate, Language__c AS LanguageCode, CreatedDate,
FirstName, LastName, UCID

FROM (
SELECT
DISTINCT LOWER(Email__c) AS EmailAddress, i.Region__c AS Region,c.AMC_Status__c,c.Job_Role__c,c.AMC_Last_Activity_Date__c, i.Industry_Level_2_Master__c, i.Industry__c,
c.Id AS SubscriberKey, c.Consent_Level_Summary__c, i.Business_Unit__c,i.Cat_Campaign_Most_Recent__c , i.Mailing_Country__c, i.LastModifiedDate, c.Language__c, i.CreatedDate,
c.FirstName, c.LastName, ec.UCID,

ROW_NUMBER() OVER(PARTITION BY c.ID ORDER BY i.LastModifiedDate DESC) as RowNum

FROM ent.Interaction__c_Salesforce i

JOIN ent.Contact_Salesforce_1 c ON LOWER(c.Email) = LOWER(i.Email__c)
JOIN ent.[Aftermarket eCommerce - Registered Customers – Stage] ec  ON LOWER(c.Email) = LOWER(ec.Email)
INNER JOIN ent.ContactPointConsent_Salesforce AS cpc ON c.Id = cpc.Contact__c
INNER JOIN ent.DataUsePurpose_Salesforce AS dup ON cpc.DataUsePurposeId = dup.Id

WHERE ec.Email IS NOT NULL
    AND Email__c NOT LIKE '%@cat.com'
    AND i.Mailing_Country__c IS NOT NULL
    AND cpc.CaptureContactPointType = 'Email'
    AND cpc.MATM_Owner__c = 'Caterpillar'
    AND dup.Name = 'Caterpillar Marketing'
    AND cpc.PrivacyConsentStatus = 'OptIn' 
    AND (cpc.EffectiveTo IS NULL OR cpc.EffectiveTo < GetDate())
    AND (i.Mailing_State_Province__c != 'QC' OR (i.Mailing_Country__c != 'CA' AND i.Mailing_State_Province__c IS NULL))
    AND  (i.System_Language__c like 'en_%' OR (i.Mailing_Country__c != 'CA' AND i.System_Language__c is null))
        )t2

WHERE RowNum = 1
Are you looking for effective solution to build your resume online then utilize top rated online resume builder, which makes your resume building process simple and easy. It is user-friendly and completely professional tool. It helps individuals create professional resumes quickly and easily. The tool offers customizable templates, pre-written content suggestions, and formatting options to enhance visual appeal. Users can input their information, adjust layouts, and download finished resumes in various formats like Word or PDF. 
import { compareDesc, parseISO } from "date-fns";

import { allPortfolioExamplesPosts } from "contentlayer/generated";
import { sortBlogs } from "@/lib/onehour/utils";
import BlogMain from "@/components/onehoursite/blog/BlogMain";

export default async function InspirationHomePage() {
  const allPosts = allPortfolioExamplesPosts
    .filter((post) => post.isPublished)
    .sort((a, b) => {
      return compareDesc(parseISO(a.updatedAt), parseISO(b.updatedAt));
    });
  return (
    <div className="container-large ">
      <div className=" left-0 top-0 min-h-full w-full">
        <div className=" min-h-full w-full bg-[#f9fafc]">
          <div className="section mx-auto mt-0 max-w-[1440px] bg-[#f7fcfd] ">
            <section className=" relative flex flex-col bg-[url('/oneHour/marketer/marketer_hero.png')] bg-contain bg-[50%_0%]  bg-repeat pb-24 pt-0 font-garamond_normal sm:pb-40">
              <div className="container relative mx-auto flex max-w-[1440px] flex-wrap  px-4 py-0 md:px-8">
                <div className="row flex w-full flex-wrap justify-center lg:-mx-5">
                  <div className="column flex w-full max-w-full flex-shrink-0 flex-grow-0 basis-full break-words px-5 pt-4 md:w-[75%] md:max-w-[75%] md:basis-3/4 md:pt-16  xl:pt-32">
                    <div className="content-wrapper w-full">
                      <div className="column-content1 w-full">
                        <div>
                          <h1 className="pb-8 text-center text-[2.5rem] font-bold leading-[2.75rem] text-midnightBlue md:text-[3rem] md:leading-[3rem] xl:text-[4.25rem] xl:leading-[5rem]">
                            <span>Portfolio Inspirations</span>
                          </h1>
                          <p className="pb-8 text-center  text-[1.25rem] font-medium leading-[1.75rem] text-midnightBlue   md:text-[1.5rem] md:leading-[1.75] xl:text-[1.75rem] xl:leading-[2.5rem]">
                            <span>
                              Browse top portfolio examples across professions
                              to inspire your next project and showcase your
                              unique skills
                            </span>
                          </p>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </section>
          </div>
        </div>
      </div>

      <div className="relative bg-[#f7fcfd] pb-24 pt-[10px] md:pt-[20px] lg:pt-[30px]">
        <div className="px-2 md:px-5 lg:px-20">
          <section>
            <div className="mx-2 pb-8 md:mx-3 md:pb-12 lg:mx-5 lg:pb-16">
              <div className="flex flex-col items-center justify-center px-1 md:px-2 lg:px-5">
                <h2 className="font-garamond_normal  text-[1.5rem]  font-extrabold leading-[1.75rem] text-midnightBlue md:text-[1.75rem] md:leading-[1.5rem] xl:text-[2.5rem] xl:leading-[3.75rem]">
                  All Posts
                </h2>
              </div>
            </div>

            <div>
              <BlogMain allblogposts={allPosts} />
            </div>
          </section>
        </div>
      </div>
    </div>
  );
}
/**
 *
 * @param {string[]} names - an array of ids
 * @param {string[]} names - an array of ids
 * @param {string[]} names - a blank array to push into
 *
 * This function will compare array1 with array2 and if the items dont match then they are pushed to array3
 */
const compareIds = (array1, array2, array3) => {
    array1.forEach((id) => {
        if (!array2.includes(id)) {
            array3.push(id);
        }
    });
};
class compte{
    private int solde;
    //constructeur
    public compte(int solde){
        this.solde=solde;
    }
    public int getSolde(){
        return solde;
    }
    public void retirer(int montant){
        if(montant>0 && montant <=solde){
            solde=solde-montant;
            System.out.println("Retrait de "+montant+"effectue.nouveau solde"+solde);
        }else{
            System.out.println("Retrait impossible. Solde insuffisant ou montant invalide.");
        }
    }
    public void deposer(int mon){
        if(mon>0){
            solde=solde+mon;
            System.out.println("la desposition de montant "+mon+ "avec succes"+solde);
        }else{
             System.out.println("Dépôt impossible. Montant invalide.");
        }
    }
    public void transfere(int arg,compte c2){
        if(arg>0 && arg<=solde){
            this.retirer(arg);
            c2.deposer(arg);
            System.out.println("le transfer est succes c2:"+c2);
        }else{
            System.out.println("la transfer est invalid");
        }
    }
 public class Main{
   public static void main(String[] args){
       compte c1=new compte(500);
       c1.retirer(100);
       c1.deposer(200);
       compte c2=new compte(0);
       c1.transfere(300,c2);
       System.out.println("solde final de c1:"+c1.getSolde()+"d");
       System.out.println("solde final de c2:"+c2.getSolde()+"d");
   } 
    }
}
class compte{
    private int solde;
    //constructeur
    public compte(int solde){
        this.solde=solde;
    }
    public int getSolde(){
        return solde;
    }
    public void retirer(int montant){
        if(montant>0 && montant <=solde){
            solde=solde-montant;
            System.out.println("Retrait de "+montant+"effectue.nouveau solde"+solde);
        }else{
            System.out.println("Retrait impossible. Solde insuffisant ou montant invalide.");
        }
    }
    public void deposer(int mon){
        if(mon>0){
            solde=solde+mon;
            System.out.println("la desposition de montant "+mon+ "avec succes"+solde);
        }else{
             System.out.println("Dépôt impossible. Montant invalide.");
        }
    }
    public void transfere(int arg,compte c2){
        if(arg>0 && arg<=solde){
            this.retirer(arg);
            c2.deposer(arg);
            System.out.println("le transfer est succes c2:"+c2);
        }else{
            System.out.println("la transfer est invalid");
        }
    }
 public class Main{
   public static void main(String[] args){
       compte c1=new compte(500);
       c1.retirer(100);
       c1.deposer(200);
       compte c2=new compte(0);
       c1.transfere(300,c2);
       System.out.println("solde final de c1:"+c1.getSolde()+"d");
       System.out.println("solde final de c2:"+c2.getSolde()+"d");
   } 
    }
}
<script>
    window.onscroll = function() {
        var button = document.getElementById("scrollToTop");
        if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
            button.style.display = "block";
        } else {
            button.style.display = "none";
        }
    };
</script>
// config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.fingerprintauth" version="1.0.0" xmlns="http://www.w3.org/ns/widgets">
    <name>FingerprintAuth</name>
    <description>Aplicación de autenticación por huella digital</description>
    <author email="dev@example.com" href="http://example.com">
        Tu Nombre
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-fingerprint-aio" spec="^4.0.0" />
    <access origin="*" />
</widget>

// www/index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Autenticación por Huella Digital</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">
        <h1>Bienvenido</h1>
        <button id="authenticateButton">Autenticar con Huella Digital</button>
        <p id="status"></p>
    </div>
    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>

// www/css/style.css
.container {
    padding: 20px;
    text-align: center;
}

button {
    padding: 15px 30px;
    font-size: 16px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    margin: 20px 0;
    cursor: pointer;
}

#status {
    margin-top: 20px;
    font-weight: bold;
}

// www/js/index.js
document.addEventListener('deviceready', onDeviceReady, false);

function onDeviceReady() {
    document.getElementById('authenticateButton').addEventListener('click', authenticate);
    
    // Verificar si el dispositivo soporta la autenticación biométrica
    Fingerprint.isAvailable(function(result) {
        // result contiene el tipo de biometría disponible
        console.log("Tipo de biometría: " + result);
    }, function(error) {
        console.error("Error al verificar biometría: " + error);
        document.getElementById('status').textContent = 
            "Tu dispositivo no soporta autenticación por huella digital";
    });
}

function authenticate() {
    Fingerprint.show({
        title: 'Autenticación Biométrica', // título opcional
        subtitle: 'Por favor, autentícate usando tu huella digital', // subtítulo opcional
        description: 'Toca el sensor de huella digital', // descripción opcional
        fallbackButtonTitle: 'Usar alternativa', // título del botón alternativo
        disableBackup: false // permitir autenticación alternativa
    }, successCallback, errorCallback);
}

function successCallback() {
    document.getElementById('status').textContent = 
        "¡Autenticación exitosa!";
    // Aquí puedes agregar la lógica para después de una autenticación exitosa
}

function errorCallback(error) {
    document.getElementById('status').textContent = 
        "Error en la autenticación: " + error.message;
}
// Online C++ compiler to run C++ program online
#include <iostream>
#include <vector>
#include <queue>

using namespace std ;

struct Node
{
    int data ;
    Node* left;
    Node* right;
    
    Node(int x){
        data = x;
        left = right = NULL; 
    }
}

vector <int> levelOrder(Node* root){
    vector<int> ans;
    if(!root) 
    {
        return ans; // means no root (base case )
    }
    
    queue<Node*> q ;
    q.push(root);
    while(!q.empty()){
        Node* t= q.front();
        ans.push_back(t->data);
        if(t->left) {
            q.push(t->left);
        }
        if(t->right) {
            q.push(t->right);
        }
        q.pop();
    }
    return ans;
    
}
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n,m;
    cout<<"Please enter the number";
    cin>>n;
    cout<<"please enter the bit u want to manipulate";
    cin>>m;
    cout<<"we are printing all the bits in this number";
    int bits = sizeof(n) * 4;
    for(int i=bits-1;i>=0;i--)
    {
        int bit = (n>>i)&1;
        cout<<bit;
    }
    cout<<endl;
    cout<<"now we want to manipulate bit";
    n = n^(1<<m);
    cout<<"the main vlue    "<<n<<endl;
    for(int i=bits-1;i>=0;i--)
    {
        int bit = (n>>i)&1;
        cout<<bit;
    }
    
}
<#
.SYNOPSIS
Synopsis Here

.DESCRIPTION
Description Here

.PARAMETER <parameterNameHere>
Parameter Description Here

.EXAMPLE

Example Here

.NOTES
Notes Here

#>
<strong title="Following" data-e2e="following-count">1k</strong>
<strong title="Likes" data-e2e="likes-count">55879</strong>
Integrating mapping services into a taxi booking app like Gett is essential for providing accurate navigation and real-time tracking. Here's a breakdown of how to achieve this using Gett clone:

1. Choose a reliable mapping service:
Majorly two service providers can avail of mapping services for their project demands like Google Maps, Here Maps, and OpenStreetMap. To utilize any one of the tools APIs to utilize it for your platform.

2. Get API keys and credentials
sign up for your official mail address to your chosen mapping service provider and obtain API keys and credentials.

3. Integrate the Mapping API
Utilize your purchased API to set up the display map with things like the user's current location, nearby taxis, and the route to the destination. Leverage the API for routing capabilities to calculate the shortest and most efficient routes for taxis. Incorporate real-time traffic data to avoid congestion and optimize routes. Analyze the past user activity to predict and suggest the point of interest nearby places depending upon the user's interest.

4. Optimize Map Performance
Cache frequently accessed map data to reduce API calls and improve performance. Avail offline map features for the user's convenience with limited or no network connectivity.

5.  Handle Errors and Exceptions
Incorporate robust bugs and error handling, specifically the cause of using APIs and network issues. Provide informative error messages to users and developers.

Above, these are the steps you should follow to get a far better taxi booking platform for your targeted audience. If you're seeking a taxi booking platform like Gett, then Appticz is the choice for your business demands because we have experience in providing taxi-related apps for our clients.
import java.util.*;

class Ae {

int x;

void getAe() {

System.out.println("Enter the value of x"); Scanner sc = new Scanner(System.in); x = sc.nextInt(); }

class B extends Ae {

int y:

void getB() {

System.out.println("Enter the value of y"); Scanner sc = new Scanner(System.in); y = sc.nextInt(); }

}

class C extends B {

void result() {

System.out.println("Result:=" .println("Result:=\t" + (x + y)); }

public class W2_iii_MultiLevellnheritance {

public static void main(String[] args) {

C c1 = new C();

c1.getAe();

c1.getB();

c1.result();
package csd.java.lab;

class ParentClass{

int a;

void SetData(int x) {

a=x;

}

}

class ChildClass extends ParentClass{

void ShowData() {

System.out.println("Value of a is\t"+a);

}

}

public class W2_ii_SInheritance {

public static void main(String[] args) {

ChildClass c1=new ChildClass();

c1.SetData(25);

c1.ShowData();

}

}
import java.util.Scanner;

public class EvenOddChecker {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int[] numbers = new int[20];

        // Input 20 numbers from the user

        System.out.println("Enter 20 numbers:");

        for (int i = 0; i < 20; i++) {

            numbers[i] = scanner.nextInt();

        }

        // Check if each number is even or odd

        for (int i = 0; i < 20; i++) {

            if (numbers[i] % 2 == 0) {

                System.out.println(numbers[i] + " is even.");

            } else {

                System.out.println(numbers[i] + " is odd.");

            }

        }

        scanner.close();

    }

}
// ExampleShader.usf

// Include common material functions
#include "Common.usf"

// Vertex shader input structure
struct VertexInput
{
    float4 Position : ATTRIBUTE0; // Vertex position
    float2 UV : ATTRIBUTE1;       // Texture coordinates
};

// Vertex shader output structure
struct VertexOutput
{
    float4 Position : SV_POSITION; // Clip-space position
    float2 UV : TEXCOORD0;         // Texture coordinates passed to the pixel shader
};

// Vertex shader function
VertexOutput MainVS(VertexInput In)
{
    VertexOutput Out;
    
    // Transform the vertex position to clip space
    Out.Position = mul(In.Position, View.WorldToClip);
    
    // Pass the UV coordinates to the pixel shader
    Out.UV = In.UV;
    
    return Out;
}

// Pixel shader function
float4 MainPS(VertexOutput In) : SV_Target
{
    // Define a constant color (e.g., blue)
    float3 BaseColor = float3(0.0, 0.0, 1.0);
    
    // Return the color with full opacity
    return float4(BaseColor, 1.0);
}

// Register the shaders
VS_Main(MainVS); // Register the vertex shader
PS_Main(MainPS); // Register the pixel shader
#include <Servo.h>

// Declare servo objects
Servo servo1; // Right leg - top
Servo servo2; // Left leg - top
Servo servo3; // Left leg - bottom
Servo servo4; // Right leg - bottom

// Servo neutral positions
int servo1Neutral = 90; // Right leg - top neutral position
int servo2Neutral = 90; // Left leg - top neutral position
int servo3Neutral = 90; // Left leg - bottom neutral position
int servo4Neutral = 90; // Right leg - bottom neutral position

// Movement parameters
int stepAngle = 20; // Angle to move for a step
int delayTime = 300; // Delay between movements (ms)

void setup() {
  // Attach servos to pins
  servo1.attach(3); // Pin for right leg top
  servo2.attach(5); // Pin for left leg top
  servo3.attach(6); // Pin for left leg bottom
  servo4.attach(9); // Pin for right leg bottom

  // Set servos to neutral positions
  resetToNeutral();
}

void loop() {
  takeStep(); // Make Otto take a step
  delay(500); // Short pause between steps
}

// Function to reset all servos to their neutral positions
void resetToNeutral() {
  servo1.write(servo1Neutral);
  servo2.write(servo2Neutral);
  servo3.write(servo3Neutral);
  servo4.write(servo4Neutral);
  delay(500); // Allow servos to move to position
}

// Function for a walking step
void takeStep() {
  // Step 1: Lift left leg
  servo3.write(servo3Neutral + stepAngle); // Move left bottom servo up
  delay(delayTime);

  // Step 2: Swing left leg forward
  servo2.write(servo2Neutral - stepAngle); // Move left top servo forward
  delay(delayTime);

  // Step 3: Place left leg down
  servo3.write(servo3Neutral); // Return left bottom servo to neutral
  delay(delayTime);

  // Step 4: Lift right leg
  servo4.write(servo4Neutral + stepAngle); // Move right bottom servo up
  delay(delayTime);

  // Step 5: Swing right leg forward
  servo1.write(servo1Neutral - stepAngle); // Move right top servo forward
  delay(delayTime);

  // Step 6: Place right leg down
  servo4.write(servo4Neutral); // Return right bottom servo to neutral
  delay(delayTime);

  // Reset to neutral after each step
  resetToNeutral();
}
// Register Custom Post Type
function custom_post_type() {

	$labels = array(
		'name'                  => _x( 'Post Types', 'Post Type General Name', 'text_domain' ),
		'singular_name'         => _x( 'Post Type', 'Post Type Singular Name', 'text_domain' ),
		'menu_name'             => __( 'Post Types', 'text_domain' ),
		'name_admin_bar'        => __( 'Post Type', 'text_domain' ),
		'archives'              => __( 'Item Archives', 'text_domain' ),
		'attributes'            => __( 'Item Attributes', 'text_domain' ),
		'parent_item_colon'     => __( 'Parent Item:', 'text_domain' ),
		'all_items'             => __( 'All Items', 'text_domain' ),
		'add_new_item'          => __( 'Add New Item', 'text_domain' ),
		'add_new'               => __( 'Add New', 'text_domain' ),
		'new_item'              => __( 'New Item', 'text_domain' ),
		'edit_item'             => __( 'Edit Item', 'text_domain' ),
		'update_item'           => __( 'Update Item', 'text_domain' ),
		'view_item'             => __( 'View Item', 'text_domain' ),
		'view_items'            => __( 'View Items', 'text_domain' ),
		'search_items'          => __( 'Search Item', 'text_domain' ),
		'not_found'             => __( 'Not found', 'text_domain' ),
		'not_found_in_trash'    => __( 'Not found in Trash', 'text_domain' ),
		'featured_image'        => __( 'Featured Image', 'text_domain' ),
		'set_featured_image'    => __( 'Set featured image', 'text_domain' ),
		'remove_featured_image' => __( 'Remove featured image', 'text_domain' ),
		'use_featured_image'    => __( 'Use as featured image', 'text_domain' ),
		'insert_into_item'      => __( 'Insert into item', 'text_domain' ),
		'uploaded_to_this_item' => __( 'Uploaded to this item', 'text_domain' ),
		'items_list'            => __( 'Items list', 'text_domain' ),
		'items_list_navigation' => __( 'Items list navigation', 'text_domain' ),
		'filter_items_list'     => __( 'Filter items list', 'text_domain' ),
	);
	$args = array(
		'label'                 => __( 'Post Type', 'text_domain' ),
		'description'           => __( 'Post Type Description', 'text_domain' ),
		'labels'                => $labels,
		'supports'              => false,
		'taxonomies'            => array( 'category', 'post_tag' ),
		'hierarchical'          => false,
		'public'                => true,
		'show_ui'               => true,
		'show_in_menu'          => true,
		'menu_position'         => 5,
		'show_in_admin_bar'     => true,
		'show_in_nav_menus'     => true,
		'can_export'            => true,
		'has_archive'           => true,
		'exclude_from_search'   => false,
		'publicly_queryable'    => true,
		'capability_type'       => 'page',
	);
	register_post_type( 'post_type', $args );

}
add_action( 'init', 'custom_post_type', 0 );
#include <iostream>
using namespace std;

class Queue {
public:
    int *arr;     // Pointer for dynamically allocated array
    int front;    // Index of the front element
    int rear;     // Index of the rear element
    int size;     // Maximum size of the queue

    // Constructor to initialize the queue
    Queue(int size) {
        this->size = size;
        arr = new int[size];
        front = 0; // Initially, front is 0
        rear = 0;  // Initially, rear is 0
    }

    // Enqueue: Add an element to the rear of the queue
    void enqueue(int element) {
        // Check if the queue is full
        if (rear == size) {
            cout << "Queue is full (Overflow)" << endl;
        } else {
            arr[rear] = element; // Add element at the rear
            rear++;              // Increment the rear index
            cout << element << " added to the queue" << endl;
        }
    }

    // Dequeue: Remove an element from the front of the queue
    void dequeue() {
        // Check if the queue is empty
        if (front == rear) {
            cout << "Queue is empty (Underflow)" << endl;
        } else {
            cout << arr[front] << " removed from the queue" << endl;
            front++; // Increment the front index to the next element
        }
    }

    // isEmpty: Check if the queue is empty
    bool isEmpty() {
        return front == rear;
    }

    // Front: Retrieve the front element without removing it
    int getFront() {
        if (isEmpty()) {
            cout << "Queue is empty (No front element)" << endl;
            return -1; // Return an invalid value as the queue is empty
        } else {
            return arr[front]; // Return the front element
        }
    }
};

int main() {
    // Create a queue of size 5
    Queue q(5);

    // Enqueue elements
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);

    // Display the front element
    cout << "Front element: " << q.getFront() << endl;

    // Dequeue elements
    q.dequeue();
    cout << "Front element after dequeue: " << q.getFront() << endl;

    // Check if the queue is empty
    if (q.isEmpty()) {
        cout << "The queue is empty" << endl;
    } else {
        cout << "The queue is not empty" << endl;
    }

    return 0;
}
#include <iostream>
using namespace std;

class Stack {
public:
    int *arr; // properties
    int top;
    int size;

    // constructor
    Stack(int size) {
        this->size = size;
        arr = new int[size];
        top = -1;
    }

    // push function
    void push(int element) {
        if (size - top > 1) { // Check for empty space 
            top++;
            arr[top] = element;
        } else {
            cout << "Stack overflow" << endl;
        }
    }

    // pop function
    void pop() {
        if (top >= 0) {
            top--;
        } else {
            cout << "Stack underflow" << endl;
        }
    }

    // peek function
    int peek() {
        if (top >= 0) {
            return arr[top];
        } else {
            cout << "Stack is empty" << endl;
            return -1;
        }
    }

    // isEmpty function
    bool isEmpty() {
        return top == -1;
    }

    // delete stack function
    void deleteStack() {
        delete[] arr; // Free the allocated memory
        arr = nullptr; // Reset the pointer
        top = -1; // Reset the top
        size = 0; // Reset the size
        cout << "Stack has been deleted" << endl;
    }
};

int main() {
    Stack st(5);

    st.push(20);
    st.push(30);
    st.push(50);
    cout << "Top element before deletion: " << st.peek() << endl;

    st.deleteStack();

    // After deletion, trying to access the stack
    if (st.arr == nullptr) {
        cout << "Stack array is nullptr after deletion." << endl;
    }

    return 0;
}
import pendulum

def calc_expire_date(prodact_date, expiry):
    prodact_date = pendulum.parse('{:0>2}-{:0>2}-{:0>2}'.format(*prodact_date))
    target_date = pendulum.duration(**expiry) + prodact_date
    days_to_expire = (target_date.date() - pendulum.now().date()).days
    print(f'Product vaild until : {target_date} You have {days_to_expire} days')


calc_expire_date((2024, 11, 15), expiry = {'days': 15})
import tkinter as tk

root = tk.Tk()
root.geometry('200x200')

def close_window():
    root.destroy()

close_bt = tk.Button(root, text = 'close', command = close_window)
close_bt.pack()

def disable_close_bt():
    return

root.protocol('WM_DELETE_WINDOW', disable_close_bt)
root.mainloop()
star

Thu Nov 28 2024 10:44:22 GMT+0000 (Coordinated Universal Time) JIBAZM1u

@odesign

star

Thu Nov 28 2024 09:48:29 GMT+0000 (Coordinated Universal Time) https://algoji.com/apibridge-python-sample-code/

@pk20

star

Thu Nov 28 2024 08:14:15 GMT+0000 (Coordinated Universal Time)

@hamzahanif192

star

Thu Nov 28 2024 02:30:32 GMT+0000 (Coordinated Universal Time) /Users/khainguyen/ITRVN_REPO/BTCY/btcy-bioflux-frontend-ai_report_processing/app/LayoutV2/Reports/AiEditReport/RhythmEvents/recoil/rhythmEventsRecoilDataEffect.js

@khainguyenhm

star

Thu Nov 28 2024 02:28:57 GMT+0000 (Coordinated Universal Time) /Users/khainguyen/ITRVN_REPO/BTCY/btcy-bioflux-frontend-ai_report_processing/app/LayoutV2/Reports/AiEditReport/BeatHR/recoil/beatHrRecoilDataEffect.js

@khainguyenhm

star

Thu Nov 28 2024 02:27:42 GMT+0000 (Coordinated Universal Time)

@khainguyenhm

star

Thu Nov 28 2024 01:48:36 GMT+0000 (Coordinated Universal Time) https://gist.github.com/victorzen/c5aae1a5880fe2be79a92776ee040d7a

@D_Unbounce

star

Wed Nov 27 2024 21:26:25 GMT+0000 (Coordinated Universal Time)

@E23CSEU1151

star

Wed Nov 27 2024 20:55:24 GMT+0000 (Coordinated Universal Time)

@nachopascual #php

star

Wed Nov 27 2024 20:37:53 GMT+0000 (Coordinated Universal Time)

@desiboli #javascript #typescript

star

Wed Nov 27 2024 20:26:06 GMT+0000 (Coordinated Universal Time)

@E23CSEU1151

star

Wed Nov 27 2024 19:53:07 GMT+0000 (Coordinated Universal Time)

@okkpurple

star

Wed Nov 27 2024 17:38:58 GMT+0000 (Coordinated Universal Time)

@shusanto

star

Wed Nov 27 2024 15:54:20 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/watch?v

@abcabcabc

star

Wed Nov 27 2024 13:06:53 GMT+0000 (Coordinated Universal Time) https://learn.upgrad.com/course/6955/segment/55858/338400/1023321/5117004

@dorjee

star

Wed Nov 27 2024 13:05:27 GMT+0000 (Coordinated Universal Time)

@odesign

star

Wed Nov 27 2024 11:46:09 GMT+0000 (Coordinated Universal Time)

@anamarie

star

Wed Nov 27 2024 06:49:36 GMT+0000 (Coordinated Universal Time) https://www.coinsclone.com/nft-sports-marketplace-development/

@LilianAnderson #nftsportsmarketplace #sportsnfts #nftmarketplacedevelopment #blockchaininsports #sportscollectiblesnft

star

Wed Nov 27 2024 02:27:52 GMT+0000 (Coordinated Universal Time)

@sk #python

star

Wed Nov 27 2024 01:02:17 GMT+0000 (Coordinated Universal Time)

@saharmess #mysql

star

Wed Nov 27 2024 01:02:17 GMT+0000 (Coordinated Universal Time)

@saharmess #mysql

star

Tue Nov 26 2024 20:04:40 GMT+0000 (Coordinated Universal Time) https://a-chacon.com/en/docker/2024/09/16/run-llm-locally.html

@Shex #ollama #docker-compose #ai #webui

star

Tue Nov 26 2024 18:57:37 GMT+0000 (Coordinated Universal Time) https://www.tutorialspoint.com/powershell/powershell_files_create_folders.htm

@acassell

star

Tue Nov 26 2024 17:29:25 GMT+0000 (Coordinated Universal Time)

@shirnunn

star

Tue Nov 26 2024 10:08:43 GMT+0000 (Coordinated Universal Time) https://www.linkedin.com/pulse/discover-best-online-resume-builder-build-within-5-adam-gilchrist-g40zc/

@adamsmith #resumebuilder #buildyourresume #resume

star

Tue Nov 26 2024 06:14:43 GMT+0000 (Coordinated Universal Time)

@asha #react

star

Mon Nov 25 2024 23:46:51 GMT+0000 (Coordinated Universal Time)

@davidmchale

star

Mon Nov 25 2024 22:05:13 GMT+0000 (Coordinated Universal Time)

@saharmess #mysql

star

Mon Nov 25 2024 22:05:12 GMT+0000 (Coordinated Universal Time)

@saharmess #mysql

star

Mon Nov 25 2024 21:10:01 GMT+0000 (Coordinated Universal Time)

@webisko #javascript

star

Mon Nov 25 2024 20:41:03 GMT+0000 (Coordinated Universal Time)

@marcopinero #html #javascript #cordova

star

Mon Nov 25 2024 19:16:39 GMT+0000 (Coordinated Universal Time)

@E23CSEU1151

star

Mon Nov 25 2024 18:03:23 GMT+0000 (Coordinated Universal Time)

@Narendra

star

Mon Nov 25 2024 15:49:18 GMT+0000 (Coordinated Universal Time)

@rick_m #powershell

star

Mon Nov 25 2024 15:23:52 GMT+0000 (Coordinated Universal Time)

@khairo0311

star

Mon Nov 25 2024 13:47:36 GMT+0000 (Coordinated Universal Time) https://appticz.com/gett-clone

@aditi_sharma_

star

Mon Nov 25 2024 12:11:16 GMT+0000 (Coordinated Universal Time) https://maticz.com/real-estate-tokenization-services

@jamielucas

star

Mon Nov 25 2024 10:34:06 GMT+0000 (Coordinated Universal Time) https://jsdev.space/directional-hover-effect/?ref=dailydev

@rstringa

star

Mon Nov 25 2024 08:51:27 GMT+0000 (Coordinated Universal Time)

@javalab

star

Mon Nov 25 2024 08:48:45 GMT+0000 (Coordinated Universal Time)

@javalab

star

Mon Nov 25 2024 08:44:26 GMT+0000 (Coordinated Universal Time)

@javalab

star

Mon Nov 25 2024 06:54:33 GMT+0000 (Coordinated Universal Time) https://chatgpt.com/c/67441edb-cd9c-8004-823a-3e9415658214

@ergergergerg

star

Mon Nov 25 2024 06:23:20 GMT+0000 (Coordinated Universal Time)

@iliavial

star

Mon Nov 25 2024 04:55:43 GMT+0000 (Coordinated Universal Time) https://generatewp.com/post-type/

@bbexperience

star

Mon Nov 25 2024 04:28:01 GMT+0000 (Coordinated Universal Time)

@lahi2010

star

Sun Nov 24 2024 23:20:17 GMT+0000 (Coordinated Universal Time)

@E23CSEU1151

star

Sun Nov 24 2024 21:42:50 GMT+0000 (Coordinated Universal Time)

@E23CSEU1151

star

Sun Nov 24 2024 21:00:54 GMT+0000 (Coordinated Universal Time) https://support.hivebrite.com/hc/en-us/articles/12765100278428-User-fields-Standard-and-Custom-Customization-and-creation

@ackt

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension