Index: imaps-frontend/src/scripts/main/MapBuilder.js
===================================================================
--- imaps-frontend/src/scripts/main/MapBuilder.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/src/scripts/main/MapBuilder.js	(revision d56544918790c0c3bc50f2f0a98c99f3d2988ccf)
@@ -2,625 +2,565 @@
 import Konva from "konva";
 import HttpService from "../net/HttpService.js";
-import {zoomStage} from "../util/zoomStage.js";
-import {addEventHandling} from "../util/addEventHandling.js";
-import MapNode from "../base/MapNode.js";
-import {json} from "react-router-dom";
-import log from "eslint-plugin-react/lib/util/log.js";
-import ShapeRegistry from "../util/ShapeRegistry.js";
-import shapeRegistry from "../util/ShapeRegistry.js";
-import triggerMapSave from "../util/triggerMapSave.js";
+import { zoomStage } from "../util/zoomStage.js";
 
 export class MapBuilder {
-    constructor(containerId,floorNum,mapName) {
-        this.container = document.getElementById(containerId);
-        this.stage = new Konva.Stage({
-            container: containerId,
-            width: this.container.clientWidth,
-            height: this.container.clientHeight,
+  constructor(containerId) {
+    this.container = document.getElementById(containerId);
+    this.stage = new Konva.Stage({
+      container: containerId,
+      width: this.container.clientWidth,
+      height: this.container.clientHeight,
+    });
+
+    // TODO AKO DRAGNIT NEKOJ OD POCETOK NA STAGE POZICIIVE KE SA ZEZNAT
+    // TODO jwt vo cookie
+    // TODO placed shape i mouseMoveHandler da ne callback ( da ne vrakjat funkcija)
+
+    this.gridLayer = new Konva.Layer();
+    this.mainLayer = new Konva.Layer();
+    this.dragLayer = new Konva.Layer();
+    this.infoPinLayer = new Konva.Layer();
+    this.textLayer = new Konva.Layer();
+    this.gridLayer.listening(false);
+
+    this.originalWidth = this.container.clientWidth;
+    this.originalHeight = this.container.clientHeight;
+
+    this.shapes = [];
+    this.blockSize = 10;
+    this.efficientDrawingMode = false;
+    this.roomTypes = [];
+
+    this.gridLine = new Konva.Line({
+      points: [],
+      stroke: "grey",
+      strokeWidth: 1,
+      opacity: 0.3,
+    });
+
+    this.gridLine.cache();
+
+    this.mainTransformer = new Konva.Transformer({
+      centeredScaling: false,
+      rotationSnaps: [0, 90, 180, 270],
+      anchorSize: 5,
+      padding: 2,
+      anchorFill: "#ef7539",
+      borderStroke: "black",
+      anchorStroke: "black",
+      cornerRadius: 20,
+      anchorCornerRadius: 10,
+      anchorDragBoundFunc: this.transformerSnapFunc(),
+    });
+
+    this.selectionRectangle = new Konva.Rect({
+      fill: "rgba(200,0,255,0.5)",
+      visible: false,
+      listening: false,
+      zIndex: 100,
+    });
+
+    this.x1 = 0;
+    this.y1 = 0;
+    this.x2 = 0;
+    this.y2 = 0;
+
+    this.selecting = false;
+
+    this.initialize();
+  }
+
+  initialize() {
+    this.drawGrid();
+    this.mainLayer.add(this.mainTransformer);
+    this.mainLayer.add(this.selectionRectangle);
+    this.stage.add(this.gridLayer);
+    this.stage.add(this.dragLayer);
+    this.stage.add(this.mainLayer);
+    this.stage.add(this.infoPinLayer);
+    this.stage.add(this.textLayer);
+    this.setupEventListeners();
+  }
+
+  setupEventListeners() {
+    document.getElementById("shapeOptions").addEventListener("click", this.selectShape.bind(this));
+    document.getElementById("render-button").addEventListener("click", this.render.bind(this));
+    window.addEventListener("keydown", this.handleExitSelection.bind(this));
+    window.addEventListener("keydown", this.handleDelete.bind(this));
+    window.addEventListener("keydown", this.rotateShapesBy90Deg.bind(this));
+    window.addEventListener("keydown", this.toggleEfficientDrawingMode.bind(this));
+    window.addEventListener("resize", this.handleResize.bind(this));
+    this.stage.on("mousedown touchstart", this.handleMouseDown.bind(this));
+    this.stage.on("mousemove touchmove", this.handleMouseMove.bind(this));
+    this.stage.on("mouseup touchend", this.handleMouseUp.bind(this));
+    this.stage.on("click tap", this.handleStageClick.bind(this));
+    this.stage.on("contextmenu", this.placeInfoPin.bind(this));
+    this.stage.on("dragmove", this.dragStage.bind(this));
+    this.stage.on("wheel", this.zoom.bind(this));
+  }
+
+  detachKeyPressEventListeners() {
+    window.removeEventListener("keydown", this.handleExitSelection.bind(this));
+    window.removeEventListener("keydown", this.handleDelete.bind(this));
+    window.removeEventListener("keydown", this.rotateShapesBy90Deg.bind(this));
+    window.removeEventListener("keydown", this.toggleEfficientDrawingMode.bind(this));
+  }
+  attachKeyPressEventListeners() {
+    window.addEventListener("keydown", this.handleExitSelection.bind(this));
+    window.addEventListener("keydown", this.handleDelete.bind(this));
+    window.addEventListener("keydown", this.rotateShapesBy90Deg.bind(this));
+    window.addEventListener("keydown", this.toggleEfficientDrawingMode.bind(this));
+  }
+
+  dragStage(e) {
+    if (!e.evt.shiftKey) return;
+    this.drawGrid();
+  }
+
+  transformerSnapFunc() {
+    return (oldPos, newPos) => {
+      const snapDistance = 8;
+
+      if (this.mainTransformer.getActiveAnchor() === "rotater") {
+        return newPos;
+      }
+
+      const distance = Math.sqrt(Math.pow(newPos.x - oldPos.x, 2) + Math.pow(newPos.y - oldPos.y, 2));
+
+      if (distance > snapDistance) {
+        return newPos;
+      }
+
+      const nextX = Math.round(newPos.x / this.blockSize) * this.blockSize;
+      const diffX = Math.abs(newPos.x - nextX);
+
+      const nextY = Math.round(newPos.y / this.blockSize) * this.blockSize;
+      const diffY = Math.abs(newPos.y - nextY);
+
+      const snapToX = diffX < snapDistance;
+      const snapToY = diffY < snapDistance;
+
+      if (snapToX && !snapToY) {
+        return {
+          x: nextX,
+          y: oldPos.y,
+        };
+      } else if (!snapToX && snapToY) {
+        return {
+          x: oldPos.x,
+          y: nextY,
+        };
+      } else if (snapToX && snapToY) {
+        return {
+          x: nextX,
+          y: nextY,
+        };
+      }
+
+      return newPos;
+    };
+  }
+
+  handleResize() {
+    this.stage.width(this.container.offsetWidth);
+    this.stage.height(this.container.offsetHeight);
+    this.drawGrid();
+  }
+
+  zoom(e) {
+   zoomStage(e,this.stage);
+   this.drawGrid();
+  }
+
+  drawGrid() {
+    this.gridLayer.destroyChildren();
+
+    let width = this.stage.width();
+    let height = this.stage.height();
+
+    //presmetka od globalen koordinaten sistem vo lokalen na canvasot
+    let transform = this.stage.getAbsoluteTransform().copy().invert();
+    let topLeft = transform.point({
+      x: 0,
+      y: 0,
+    });
+
+    let bottomRight = transform.point({
+      x: width,
+      y: height,
+    });
+
+    let startX = Math.floor(topLeft.x / this.blockSize) * this.blockSize;
+    let startY = Math.floor(topLeft.y / this.blockSize) * this.blockSize;
+
+    let endX = Math.ceil(bottomRight.x / this.blockSize) * this.blockSize;
+    let endY = Math.ceil(bottomRight.y / this.blockSize) * this.blockSize;
+
+    for (let x = startX; x <= endX; x += this.blockSize) {
+      let line = this.gridLine.clone({
+        points: [x + 0.5, topLeft.y - this.blockSize, x + 0.5, bottomRight.y + this.blockSize],
+      });
+
+      line.transformsEnabled("position");
+      line.perfectDrawEnabled(false);
+      line.shadowForStrokeEnabled(false);
+
+      this.gridLayer.add(line);
+    }
+
+    for (let y = startY; y <= endY; y += this.blockSize) {
+      let line = this.gridLine.clone({
+        points: [topLeft.x - this.blockSize, y + 0.5, bottomRight.x + this.blockSize, y + 0.5],
+      });
+
+      line.perfectDrawEnabled(false);
+      line.shadowForStrokeEnabled(false);
+      line.transformsEnabled("position");
+      this.gridLayer.add(line);
+    }
+
+    this.mainLayer.moveToTop();
+    this.infoPinLayer.moveToTop();
+
+    this.gridLayer.batchDraw();
+  }
+
+  placeInfoPin(e) {
+    e.evt.preventDefault();
+    let mousePos = this.stage.getRelativePointerPosition();
+    let infoPin = Factory.createShape("InfoPin", mousePos, this.blockSize, this.mainLayer, 0,1,1,true);
+    this.addModalHandling(infoPin);
+    this.shapes.push(infoPin);
+    this.mainLayer.add(infoPin)
+    infoPin.displayName(this.textLayer);
+    console.log(infoPin.name());
+  }
+
+  toggleEfficientDrawingMode(e) {
+    if (e.key === "e" || e.key === "E") {
+      this.efficientDrawingMode = !this.efficientDrawingMode;
+      console.log("EFFICIENT DRAWING MODE is: ", this.efficientDrawingMode);
+
+      if (!this.efficientDrawingMode) {
+        this.stopDrawing();
+      }
+    }
+  }
+
+  placeShape() {
+    const mousePos = this.stage.getRelativePointerPosition();
+    const placedObj = Factory.createShape(
+      this.hoverObj.type,
+      mousePos,
+      this.blockSize,
+      this.mainLayer,
+      this.hoverObj.rotation(),
+        1,
+        1,
+        true
+    );
+
+    if (!placedObj) return;
+
+    this.mainLayer.add(placedObj);
+    this.shapes.push(placedObj);
+    this.addModalHandling(placedObj);
+    this.mainLayer.draw();
+    placedObj.displayName(this.textLayer);
+    placedObj.snapToGrid();
+
+    if (!this.efficientDrawingMode) {
+      this.stopDrawing();
+    }
+  }
+
+  stopDrawing() {
+    this.mainTransformer.nodes([]);
+    this.hoverObj.remove();
+    this.dragLayer.removeChildren();
+    this.stage.off("mousemove", this.boundMouseMoveHandler);
+    this.stage.off("click", this.boundPlaceShapeHandler);
+  }
+
+  mouseMoveHandler() {
+    const mousePos = this.stage.getRelativePointerPosition();
+    this.hoverObj.position({ x: mousePos.x, y: mousePos.y });
+    this.hoverObj.visible(true);
+  }
+
+  startDrawing(shapeType) {
+    let pos = { x: 0, y: 0 };
+    this.hoverObj = Factory.createShape(shapeType, pos, this.blockSize, this.dragLayer, 0);
+
+    this.hoverObj.visible(false);
+    this.dragLayer.add(this.hoverObj);
+    this.dragLayer.moveToTop();
+    this.boundMouseMoveHandler = this.mouseMoveHandler.bind(this);
+    this.boundPlaceShapeHandler = this.placeShape.bind(this);
+
+    this.stage.on("mousemove", this.boundMouseMoveHandler);
+    this.stage.on("click", this.boundPlaceShapeHandler);
+  }
+
+  selectShape(e) {
+    if (e.target.tagName === "LI") {
+      const shapeType = e.target.getAttribute("data-info");
+      this.startDrawing(shapeType);
+      this.mainTransformer.nodes([]);
+    }
+  }
+
+  addModalHandling(shape) {
+    shape.on("dblclick", () => {
+      const eventName = shape.modalEventName;
+      if (eventName) {
+        const data = {
+          room: shape,
+          map: this,
+        };
+        const event = new CustomEvent(eventName, { detail: data });
+        window.dispatchEvent(event);
+      }
+    });
+  }
+
+  rotateShapesBy90Deg(e) {
+    if (e.key === "r" || e.key === "R") {
+      if (this.hoverObj) {
+        this.hoverObj.rotate(90);
+      }
+      this.mainTransformer.nodes().forEach((node) => {
+        node.rotate(90);
+      });
+    }
+  }
+
+  handleDelete(e) {
+    if (e.key === "Delete") {
+      this.mainTransformer.nodes().forEach((node) => {
+        node.remove();
+        this.shapes.splice(this.shapes.indexOf(node), 1);
+      });
+      this.mainTransformer.nodes([]);
+      this.mainLayer.batchDraw();
+    }
+  }
+
+  handleExitSelection(e) {
+    if (e.key === "Escape") {
+      this.mainTransformer.nodes([]);
+      this.stopDrawing();
+    }
+  }
+
+  handleMouseDown(e) {
+    this.stage.draggable(e.evt.shiftKey);
+
+    if (e.target !== this.stage) {
+      return;
+    }
+
+    e.evt.preventDefault();
+    this.x1 = this.stage.getRelativePointerPosition().x;
+    this.y1 = this.stage.getRelativePointerPosition().y;
+    this.x2 = this.stage.getRelativePointerPosition().x;
+    this.y2 = this.stage.getRelativePointerPosition().y;
+
+    this.selectionRectangle.width(0);
+    this.selectionRectangle.height(0);
+    this.selecting = true;
+  }
+
+  handleMouseMove(e) {
+    if (!this.selecting) {
+      return;
+    }
+    e.evt.preventDefault();
+    this.x2 = this.stage.getRelativePointerPosition().x;
+    this.y2 = this.stage.getRelativePointerPosition().y;
+
+    this.selectionRectangle.setAttrs({
+      visible: true,
+      x: Math.min(this.x1, this.x2),
+      y: Math.min(this.y1, this.y2),
+      width: Math.abs(this.x2 - this.x1),
+      height: Math.abs(this.y2 - this.y1),
+    });
+  }
+
+  handleMouseUp(e) {
+    this.selecting = false;
+    this.stage.draggable(false);
+
+    if (!this.selectionRectangle.visible()) {
+      return;
+    }
+
+    e.evt.preventDefault();
+    this.selectionRectangle.visible(false);
+    const shapes = this.stage.find(".mapObj");
+    const box = this.selectionRectangle.getClientRect();
+    const selected = shapes.filter((shape) => Konva.Util.haveIntersection(box, shape.getClientRect()));
+    this.mainTransformer.nodes(selected);
+    console.log(this.mainTransformer.nodes());
+  }
+
+  saveShapeDetails() {
+    this.shapes.forEach((room) => {
+      room.saveShapeDetails();
+      console.log(room.info);
+    });
+  }
+
+  async render() {
+    this.saveShapeDetails();
+    const httpService = new HttpService("http://localhost:8080/api/protected", true);
+    try {
+      const response = await httpService.post("/render", this.shapes);
+      console.log(response);
+    } catch (err) {
+      console.log("ERROR --> Could not render map --->", err);
+    }
+  }
+
+  async saveMap(mapName) {
+    this.saveShapeDetails();
+    const httpService = new HttpService("http://localhost:8080/api/protected/maps", true);
+    try {
+      const response = await httpService.put(`/save?mapName=${mapName}`, this.shapes);
+      console.log(response, "resp in builder");
+    } catch (err) {
+      console.log("ERROR --> Could not Save map --->", err);
+    }
+  }
+
+  handleStageClick(e) {
+    if (this.selectionRectangle.visible()) {
+      return;
+    }
+
+    if (e.target === this.stage) {
+      this.mainTransformer.nodes([]);
+      return;
+    }
+
+    if (!e.target.hasName("mapObj")) {
+      return;
+    }
+
+    const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
+    const isSelected = this.mainTransformer.nodes().indexOf(e.target) >= 0;
+
+    if (!metaPressed && !isSelected) {
+      this.mainTransformer.nodes([e.target]);
+      console.log("Sel 1");
+    } else if (metaPressed && isSelected) {
+      const nodes = this.mainTransformer.nodes().slice();
+      nodes.splice(nodes.indexOf(e.target), 1);
+      this.mainTransformer.nodes(nodes);
+    } else if (metaPressed && !isSelected) {
+      const nodes = this.mainTransformer.nodes().concat([e.target]);
+      this.mainTransformer.nodes(nodes);
+    }
+  }
+
+  addRoomType(roomType) {
+    this.roomTypes.push(roomType);
+  }
+
+  getRoomTypes() {
+    return this.roomTypes;
+  }
+
+  getRooms() {
+    return this.getShapeInfoByType("Room");
+  }
+
+  getPins() {
+    return this.getShapeInfoByType("InfoPin");
+  }
+
+  getEntrances() {
+    return this.getShapeInfoByType("Entrance");
+  }
+
+  getConnections() {
+    const pins = this.getShapeInfoByType("InfoPin");
+    const entrances = this.getShapeInfoByType("Entrance");
+    return [...pins, ...entrances];
+  }
+
+  getShapeInfoByType(type) {
+    return this.shapes.filter((shape) => shape.className === type).map((shape) => shape.info);
+  }
+
+  updateConnections() {
+    console.log("Update");
+
+    this.shapes.forEach((shape) => {
+      if (shape.className === "InfoPin" || shape.className === "Entrance") {
+        shape.info.selectedPins.forEach((connectedShapeName) => {
+          const connectedShape = this.shapes.find((s) => s.info.name === connectedShapeName);
+          if (
+            connectedShape &&
+            (connectedShape.className === "InfoPin" || connectedShape.className === "Entrance")
+          ) {
+            if (!connectedShape.info.selectedPins.includes(shape.info.name)) {
+              connectedShape.info.selectedPins.push(shape.info.name);
+            }
+          }
         });
-
-        // TODO AKO DRAGNIT NEKOJ OD POCETOK NA STAGE POZICIIVE KE SA ZEZNAT
-        // TODO placed shape i mouseMoveHandler da ne callback ( da ne vrakjat funkcija)
-        // TODO text na top layer sekogas
-
-        this._floorNum = floorNum;
-        this.mapName = mapName;
-
-        this.gridLayer = new Konva.Layer();
-        this.mainLayer = new Konva.Layer();
-        this.dragLayer = new Konva.Layer();
-        this.infoPinLayer = new Konva.Layer();
-        this.prioLayer = new Konva.Layer();
-        this.textLayer = new Konva.Layer();
-        this.gridLayer.listening(false);
-
-        this.isDrawEventBound = false;
-
-
-        this.othStairs = [];
-
-        this.blockSize = 10;
-        this.efficientDrawingMode = false;
-        this.roomTypes = [];
-
-        this.gridLine = new Konva.Line({
-            points: [],
-            stroke: "grey",
-            strokeWidth: 1,
-            opacity: 0.3,
-        });
-
-        this.gridLine.cache();
-
-        this.mainTransformer = new Konva.Transformer({
-            centeredScaling: false,
-            rotationSnaps: [0, 90, 180, 270],
-            anchorSize: 5,
-            padding: 2,
-            anchorFill: "#f6031f",
-            borderStroke: "black",
-            anchorStroke: "black",
-            cornerRadius: 20,
-            anchorCornerRadius: 10,
-            anchorDragBoundFunc: this.transformerSnapFunc(),
-        });
-
-        this.selectionRectangle = new Konva.Rect({
-            fill: "rgba(56,194,245,0.5)",
-            visible: false,
-            listening: false,
-            zIndex: 100,
-        });
-
-        this.x1 = 0;
-        this.y1 = 0;
-        this.x2 = 0;
-        this.y2 = 0;
-
-        this.selecting = false;
-
-        this.initialize();
-    }
-
-    initialize() {
-        this.drawGrid();
-        this.mainLayer.add(this.mainTransformer);
-        this.mainLayer.add(this.selectionRectangle);
-        this.stage.add(this.gridLayer);
-        this.stage.add(this.dragLayer);
-        this.stage.add(this.mainLayer);
-        this.stage.add(this.infoPinLayer);
-        this.stage.add(this.textLayer);
-        this.setupEventListeners();
-    }
-
-    setupEventListeners() {
-        document.getElementById("shapeOptions").addEventListener("click", this.selectShape.bind(this));
-        // window.addEventListener("keydown", this.handleExitSelection.bind(this));
-        // window.addEventListener("keydown", this.handleDelete.bind(this));
-        // window.addEventListener("keydown", this.rotateShapesBy90Deg.bind(this));
-        // window.addEventListener("keydown", this.toggleEfficientDrawingMode.bind(this));
-        window.addEventListener("resize", this.handleResize.bind(this));
-
-        this.boundEscapeEventListener = this.handleExitSelection.bind(this);
-        this.boundDeleteEventListener = this.handleDelete.bind(this);
-        this.boundRotateShapeEventListener = this.rotateShapesBy90Deg.bind(this)
-        this.boundEfficientDrawingModeEventListener = this.toggleEfficientDrawingMode.bind(this);
-
-        this.attachKeyPressEventListeners();
-
-        this.stage.on("mousedown touchstart", this.handleMouseDown.bind(this));
-        this.stage.on("mousemove touchmove", this.handleMouseMove.bind(this));
-        this.stage.on("mouseup touchend", this.handleMouseUp.bind(this));
-        this.stage.on("click tap", this.handleStageClick.bind(this));
-        this.stage.on("contextmenu", this.placeInfoPin.bind(this));
-        this.stage.on("dragmove", this.dragStage.bind(this));
-        this.stage.on("wheel", this.zoom.bind(this));
-    }
-
-    detachKeyPressEventListeners() {
-        console.log("DETACH")
-        window.removeEventListener("keydown", this.boundEscapeEventListener);
-        window.removeEventListener("keydown", this.boundDeleteEventListener);
-        window.removeEventListener("keydown", this.boundRotateShapeEventListener);
-        window.removeEventListener("keydown", this.boundEfficientDrawingModeEventListener);
-    }
-
-    attachKeyPressEventListeners() {
-        console.log("ATTACH")
-        window.addEventListener("keydown", this.boundEscapeEventListener);
-        window.addEventListener("keydown", this.boundDeleteEventListener);
-        window.addEventListener("keydown", this.boundRotateShapeEventListener);
-        window.addEventListener("keydown", this.boundEfficientDrawingModeEventListener);
-    }
-
-    dragStage(e) {
-        if (!e.evt.shiftKey) return;
-        this.drawGrid();
-    }
-
-    transformerSnapFunc() {
-        return (oldPos, newPos) => {
-            const snapDistance = 8;
-
-            if (this.mainTransformer.getActiveAnchor() === "rotater") {
-                return newPos;
-            }
-
-            const distance = Math.sqrt(Math.pow(newPos.x - oldPos.x, 2) + Math.pow(newPos.y - oldPos.y, 2));
-
-            if (distance > snapDistance) {
-                return newPos;
-            }
-
-            const nextX = Math.round(newPos.x / this.blockSize) * this.blockSize;
-            const diffX = Math.abs(newPos.x - nextX);
-
-            const nextY = Math.round(newPos.y / this.blockSize) * this.blockSize;
-            const diffY = Math.abs(newPos.y - nextY);
-
-            const snapToX = diffX < snapDistance;
-            const snapToY = diffY < snapDistance;
-
-            if (snapToX && !snapToY) {
-                return {
-                    x: nextX,
-                    y: oldPos.y,
-                };
-            } else if (!snapToX && snapToY) {
-                return {
-                    x: oldPos.x,
-                    y: nextY,
-                };
-            } else if (snapToX && snapToY) {
-                return {
-                    x: nextX,
-                    y: nextY,
-                };
-            }
-
-            return newPos;
-        };
-    }
-
-    handleResize() {
-        this.stage.width(this.container.offsetWidth);
-        this.stage.height(this.container.offsetHeight);
-        this.drawGrid();
-    }
-
-    zoom(e) {
-        zoomStage(e, this.stage, true);
-        this.drawGrid();
-    }
-
-    get floorNum(){
-        return this._floorNum;
-    }
-
-    set floorNum(val){
-        this._floorNum = val;
-    }
-
-    drawGrid() {
-        this.gridLayer.destroyChildren();
-
-        let width = this.stage.width();
-        let height = this.stage.height();
-
-        //presmetka od globalen koordinaten sistem vo lokalen na canvasot
-        let transform = this.stage.getAbsoluteTransform().copy().invert();
-        let topLeft = transform.point({
-            x: 0,
-            y: 0,
-        });
-
-        let bottomRight = transform.point({
-            x: width,
-            y: height,
-        });
-
-        let startX = Math.floor(topLeft.x / this.blockSize) * this.blockSize;
-        let startY = Math.floor(topLeft.y / this.blockSize) * this.blockSize;
-
-        let endX = Math.ceil(bottomRight.x / this.blockSize) * this.blockSize;
-        let endY = Math.ceil(bottomRight.y / this.blockSize) * this.blockSize;
-
-        for (let x = startX; x <= endX; x += this.blockSize) {
-            let line = this.gridLine.clone({
-                points: [x + 0.5, topLeft.y - this.blockSize, x + 0.5, bottomRight.y + this.blockSize],
-            });
-
-            line.transformsEnabled("position");
-            line.perfectDrawEnabled(false);
-            line.shadowForStrokeEnabled(false);
-
-            this.gridLayer.add(line);
-        }
-
-        for (let y = startY; y <= endY; y += this.blockSize) {
-            let line = this.gridLine.clone({
-                points: [topLeft.x - this.blockSize, y + 0.5, bottomRight.x + this.blockSize, y + 0.5],
-            });
-
-            line.perfectDrawEnabled(false);
-            line.shadowForStrokeEnabled(false);
-            line.transformsEnabled("position");
-            this.gridLayer.add(line);
-        }
-
-        this.mainLayer.moveToTop();
-        this.infoPinLayer.moveToTop();
-
-        this.gridLayer.batchDraw();
-    }
-
-    placeInfoPin(e) {
-        e.evt.preventDefault();
-        let mousePos = this.stage.getRelativePointerPosition();
-        const attrs = {
-            type: "InfoPin",
-            position: mousePos,
-            blockSize: this.blockSize,
-            layer: this.mainLayer,
-            rotation: 0,
-            scaleX: 1,
-            scaleY: 1,
-            increment: true,
-            floorNum: this.floorNum
-        };
-        let infoPin = Factory.createShape("InfoPin", attrs);
-        addEventHandling(infoPin, this, "dblclick");
-        ShapeRegistry.add(infoPin)
-        this.mainLayer.add(infoPin);
-        infoPin.displayName(this.textLayer);
-        triggerMapSave()
-
-        console.log(infoPin.name());
-    }
-
-    toggleEfficientDrawingMode(e) {
-        if (e.key === "e" || e.key === "E") {
-            this.efficientDrawingMode = !this.efficientDrawingMode;
-            console.log("EFFICIENT DRAWING MODE is: ", this.efficientDrawingMode);
-
-            if (!this.efficientDrawingMode) {
-                this.stopDrawing();
-            }
-        }
-    }
-
-    placeShape() {
-        const mousePos = this.stage.getRelativePointerPosition();
-        const attrs = {
-            position: mousePos,
-            width: this.blockSize,
-            height: this.blockSize,
-            layer: this.mainLayer,
-            rotation: this.hoverObj.rotation(),
-            scaleX: 1,
-            scaleY: 1,
-            increment: true,
-            snap: true,
-            fromLoad: false,
-            blockSize: this.blockSize,
-            floorNum: this.floorNum
-        };
-
-        const placedObj = Factory.createShape(this.hoverObj.type, attrs);
-
-        if (!placedObj) return;
-
-        console.info("ATTRS FNUM",attrs.floorNum)
-
-        this.mainLayer.add(placedObj);
-        ShapeRegistry.add(placedObj);
-        addEventHandling(placedObj, this, "dblclick");
-        this.mainLayer.draw();
-        // site ovie func da se vo edna funkcija vo shape.
-
-        placedObj.displayName(this.textLayer);
-        placedObj.snapToGrid();
-        placedObj.onPlace();
-
-        triggerMapSave();
-
-        if (!this.efficientDrawingMode) {
-            this.stopDrawing();
-        }
-        this.mainTransformer.nodes([])
-    }
-
-    stopDrawing() {
-        if(this.isDrawEventBound){
-            this.mainTransformer.nodes([]);
-            if (this.hoverObj != null) this.hoverObj.remove();
-            this.dragLayer.removeChildren();
-            this.stage.off("mousemove", this.boundMouseMoveHandler);
-            this.stage.off("click", this.boundPlaceShapeHandler);
-            this.isDrawEventBound = false;
-        }
-
-    }
-
-    mouseMoveHandler() {
-        const mousePos = this.stage.getRelativePointerPosition();
-        this.hoverObj.position({x: mousePos.x, y: mousePos.y});
-        this.hoverObj.visible(true);
-    }
-
-    startDrawing(shapeType) {
-        const attrs = {
-            position: {x: 0, y: 0},
-            width: this.blockSize,
-            height: this.blockSize,
-            layer: this.mainLayer,
-            rotation: 0,
-            scaleX: 1,
-            scaleY: 1,
-            increment: false,
-            snap: true,
-            fromLoad: false,
-            blockSize: this.blockSize
-        };
-        this.hoverObj = Factory.createShape(shapeType, attrs);
-
-        console.log("HOVBER OBK:", this.hoverObj)
-
-        this.hoverObj.visible(false);
-        this.dragLayer.add(this.hoverObj);
-        this.dragLayer.moveToTop();
-
-
-        this.boundMouseMoveHandler = this.mouseMoveHandler.bind(this);
-        this.boundPlaceShapeHandler = this.placeShape.bind(this);
-        this.isDrawEventBound = true;
-
-        this.stage.on("mousemove", this.boundMouseMoveHandler);
-        this.stage.on("click", this.boundPlaceShapeHandler);
-    }
-
-    selectShape(e) {
-        if (e.target.tagName === "LI") {
-          this.stopDrawing()
-            const shapeType = e.target.getAttribute("data-info");
-            this.startDrawing(shapeType);
-            this.mainTransformer.nodes([])
-        }
-    }
-
-    rotateShapesBy90Deg(e) {
-        if (e.key === "r" || e.key === "R") {
-            if (this.hoverObj) {
-                this.hoverObj.rotate(90);
-            }
-            this.mainTransformer.nodes().forEach((node) => {
-                node.rotate(90);
-            });
-        }
-    }
-
-    handleDelete(e) {
-        if (e.key === "Delete") {
-            this.mainTransformer.nodes().forEach((node) => {
-                node.remove();
-                node.destroy();
-                ShapeRegistry.delete(node);
-                triggerMapSave();
-            });
-            this.mainTransformer.nodes([]);
-            this.mainLayer.batchDraw();
-        }
-    }
-
-    handleExitSelection(e) {
-        if (e.key === "Escape") {
-            this.mainTransformer.nodes([]);
-            this.stopDrawing();
-        }
-    }
-
-    handleMouseDown(e) {
-        this.stage.draggable(e.evt.shiftKey);
-
-        if (e.target !== this.stage) {
-            return;
-        }
-
-        e.evt.preventDefault();
-        this.x1 = this.stage.getRelativePointerPosition().x;
-        this.y1 = this.stage.getRelativePointerPosition().y;
-        this.x2 = this.stage.getRelativePointerPosition().x;
-        this.y2 = this.stage.getRelativePointerPosition().y;
-
-        this.selectionRectangle.width(0);
-        this.selectionRectangle.height(0);
-        this.selecting = true;
-    }
-
-    handleMouseMove(e) {
-        if (!this.selecting) {
-            return;
-        }
-        e.evt.preventDefault();
-        this.x2 = this.stage.getRelativePointerPosition().x;
-        this.y2 = this.stage.getRelativePointerPosition().y;
-
-        this.selectionRectangle.setAttrs({
-            visible: true,
-            x: Math.min(this.x1, this.x2),
-            y: Math.min(this.y1, this.y2),
-            width: Math.abs(this.x2 - this.x1),
-            height: Math.abs(this.y2 - this.y1),
-        });
-    }
-
-    handleMouseUp(e) {
-        this.selecting = false;
-        this.stage.draggable(false);
-
-        if (!this.selectionRectangle.visible()) {
-            return;
-        }
-
-        e.evt.preventDefault();
-        this.selectionRectangle.visible(false);
-        const shapes = this.stage.find(".mapObj");
-        const box = this.selectionRectangle.getClientRect();
-        const selected = shapes.filter((shape) => Konva.Util.haveIntersection(box, shape.getClientRect()));
-        this.mainTransformer.nodes(selected);
-        console.log(this.mainTransformer.nodes());
-    }
-
-    saveShapeDetails() {
-        ShapeRegistry.saveDetails();
-        console.log("thisflornum",this.floorNum)
-        return  {
-            shapes: ShapeRegistry.getShapes(this.floorNum),
-            roomTypes: JSON.stringify(this.roomTypes),
-            mapName: this.mapName,
-            floorNum: this.floorNum
-        }
-    }
-
-
-
-    handleStageClick(e) {
-        if (this.selectionRectangle.visible()) {
-            console.log("STAGECLICK1")
-            return;
-        }
-
-        if (e.target === this.stage) {
-            console.log("STAGECLICK2")
-            this.mainTransformer.nodes([]);
-            return;
-        }
-
-        if (!e.target.hasName("mapObj")) {
-            console.log("STAGECLICK3")
-            return;
-        }
-
-        const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
-        const isSelected = this.mainTransformer.nodes().indexOf(e.target) >= 0;
-
-
-        if (!metaPressed && !isSelected) {
-            this.mainTransformer.nodes([e.target]);
-            console.log("Sel 1");
-        } else if (metaPressed && isSelected) {
-            const nodes = this.mainTransformer.nodes().slice();
-            nodes.splice(nodes.indexOf(e.target), 1);
-            this.mainTransformer.nodes(nodes);
-        } else if (metaPressed && !isSelected) {
-            const nodes = this.mainTransformer.nodes().concat([e.target]);
-            this.mainTransformer.nodes(nodes);
-        }
-    }
-
-    addRoomType(type) {
-        this.roomTypes.push(type);
-    }
-
-    removeRoomType(targetType) {
-        this.roomTypes = this.roomTypes.filter(type => type !== targetType);
-    }
-
-
-    drawConnection(node1Name, node2Name) {
-
-        ShapeRegistry.drawConnection(node1Name,node2Name);
-    }
-
-    removeConnection(from, to) {
-        ShapeRegistry.removeConnection(from,to);
-    }
-
-    updateRoomNames() {
-        this.textLayer.removeChildren();
-        ShapeRegistry.getShapes(this.floorNum).forEach((shape) => {
-            shape.displayName(this.textLayer);
-        });
-
-    }
-
-
-    clearMap() {
-        this.mainLayer.removeChildren();
-        this.hoverObj = null;
-    }
-
-
-    // ova  klasa i map display da nasledbat od glavna klasa
-
-    loadNewFloor(floor) {
-
-        this._floorNum = floor?.num;
-        let data = floor?.mapData;
-
-        if (data == null || data === "") return;
-
-        this.deserializeMap(data);
-        shapeRegistry.getShapes(this.floorNum).forEach((shape) => {
-            this.mainLayer.add(shape);
-        });
-
-
-    }
-
-    //nov
-    deserializeMap(data) {
-        console.log("DESERIALIZING: ", data);
-        ShapeRegistry.clear(this.floorNum);
-
-        if (data != null) {
-            const dsrData = JSON.parse(data);
-            //load shapes
-            dsrData.forEach((shape) => {
-                const attrs = {
-                    position: {x: shape.attrs.x, y: shape.attrs.y},
-                    width: shape.attrs.width,
-                    height: shape.attrs.height,
-                    layer: this.mainLayer,
-                    blockSize: this.blockSize,
-                    rotation: shape.attrs.rotation,
-                    scaleX: shape.attrs.scaleX,
-                    scaleY: shape.attrs.scaleY,
-                    increment: false,
-                    snap: true,
-                    fromLoad: true,
-                    floorNum: this.floorNum
-                };
-
-                const loadedShape = Factory.createShape(shape.className, attrs);
-                loadedShape.loadInfo(shape.attrs);
-                ShapeRegistry.add(loadedShape);
-                // na destroy trebit events da sa trgnat
-                addEventHandling(loadedShape, this, "dblclick");
-            });
-            let nodes = ShapeRegistry.getShapes(this.floorNum).filter((shape) => shape.className === "InfoPin" || shape.className === "Entrance" || shape.className === "Stairs");
-            nodes.forEach((pin) => {
-                let connectedPins = pin.info.selectedPins;
-                if (connectedPins) {
-                    connectedPins.forEach((slPin) => {
-                        console.log("CONN node1: " + pin + "conn node2: " + slPin)
-                        this.drawConnection(pin.info.name, slPin);
-                    });
-                }
-            });
-        }
-
-        this.mainTransformer.nodes([]);
-        this.mainLayer.add(this.mainTransformer);
-        this.mainLayer.add(this.selectionRectangle);
-
-        ShapeRegistry.getShapes(this.floorNum).forEach((shape) => {
-            shape.displayName(this.textLayer);
-            if(shape.className === "Entrance"){
-                shape.setHighlight();
-            }
-        });
-    }
-
+      }
+    });
+  }
+
+  removeConnection(from, to) {
+    this.shapes
+      .filter((s) => s.info.name === from || s.info.name === to)
+      .forEach((s) => {
+        s.info.selectedPins = s.info.selectedPins.filter((pin) => pin !== from && pin !== to);
+      });
+    console.log("Remove");
+  }
+
+  updateRoomNames() {
+    this.textLayer.removeChildren();
+    this.shapes.forEach((shape) => {
+      shape.displayName(this.textLayer);
+    });
+    this.textLayer.children.forEach((child) => console.log(child));
+  }
+
+  clearMap() {
+    this.mainLayer.removeChildren();
+    this.shapes = [];
+    this.hoverObj = null;
+  }
+
+  deserializeMap(data) {
+    console.log("DESERIALIZING: ", data);
+    this.clearMap();
+    let dsrData = JSON.parse(data);
+    dsrData.forEach((child) => {
+      const shape = JSON.parse(child);
+      const loadedShape = Factory.createShape(
+        shape.className,
+        { x: shape.attrs.x, y: shape.attrs.y },
+        this.blockSize,
+        this.mainLayer,
+        shape.attrs.rotation,
+          shape.attrs.scaleX,
+          shape.attrs.scaleY
+      );
+      loadedShape.loadInfo(shape.attrs);
+      this.shapes.push(loadedShape);
+      this.addModalHandling(loadedShape);
+      this.mainLayer.add(loadedShape);
+    });
+    this.mainTransformer.nodes([]);
+    this.mainLayer.add(this.mainTransformer);
+    this.mainLayer.add(this.selectionRectangle);
+
+    this.shapes.forEach((shape) => shape.displayName(this.textLayer));
+  }
 }
Index: imaps-frontend/src/scripts/main/MapDisplay.js
===================================================================
--- imaps-frontend/src/scripts/main/MapDisplay.js	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/src/scripts/main/MapDisplay.js	(revision d56544918790c0c3bc50f2f0a98c99f3d2988ccf)
@@ -3,314 +3,121 @@
 import HttpService from "../net/HttpService.js";
 import {zoomStage} from "../util/zoomStage.js";
-import {addEventHandling} from "../util/addEventHandling.js";
-import ShapeRegistry from "../util/ShapeRegistry.js";
-import triggerNavigate from "../util/triggerNavigate.js";
-import config from "../net/netconfig.js";
-import {dispatchCustomEvent} from "../util/dispatchCustomEvent.js";
-import { jsPDF } from "jspdf";
+export class MapDisplay {
+  constructor(containerId) {
+    this.container = document.getElementById(containerId);
+    this.containerId = containerId;
+    this.stage = new Konva.Stage({
+      container: containerId,
+      width: window.innerWidth,
+      height: window.innerHeight,
+      draggable: true,
+    });
+
+    this.shapes = [];
+    this.loaded = false;
+    this.mainLayer = new Konva.Layer();
+    this.routeLayer = new Konva.Layer();
+    this.textLayer = new Konva.Layer();
+    this.stage.add(this.mainLayer);
+    this.stage.add(this.routeLayer);
+    this.stage.add(this.textLayer);
+    this.route = new Konva.Line();
+
+    this.stage.on("resize", () => {
+      this.stage.width = window.innerWidth;
+      this.stage.height = window.innerHeight;
+    });
+
+    this.stage.on("wheel",(e) => {
+        zoomStage(e,this.stage);
+    })
+
+   
+  }
+
+  deserializeMap(data) {
+    data.forEach((child) => {
+        const shape = JSON.parse(child);
+        if (shape.className !== "InfoPin") {
+            const renderedShape = Factory.createRenderedShape(
+                shape.className,
+                shape.attrs
+            );
+            this.shapes.push(renderedShape);
+      }
+    });
+  }
+
+  displayRoomNames(){
+    console.log("VLEZE")
+    this.shapes.forEach(shape => {
+      shape.displayName(this.textLayer);
+    })
+
+    this.textLayer.children.forEach(child => console.log(child,"DECAAA"));
+  }
+
+  async loadMap() {
+    const httpService = new HttpService();
+    const mapData = await httpService.get("/public/mapData");
+    console.log("DESERIALIZED --->",mapData);
+    this.deserializeMap(mapData);
+    this.shapes.forEach((shape) => {
+      this.mainLayer.add(shape);
+    });
+    this.displayRoomNames();
+  }
+
+  drawRoute(path) {
+    this.routeLayer.removeChildren();
+    console.log("====PATH====");
+    path.forEach((point) => console.log(point.x, point.y));
+
+    const pointsArray = path.flatMap((point) => [point.x, point.y]);
+
+    console.log(pointsArray, "POINTS");
+
+    let buff = [];
+    let count = 0;
+    let index = 0;
+
+    const drawNextSegment = () => {
+        if (index >= pointsArray.length) return;
+
+        buff.push(pointsArray[index]);
+        count++;
+
+        if (count % 4 === 0) {
+            const line = new Konva.Arrow({
+                points: buff,
+                stroke: "#e91332",
+                strokeWidth: 2.5,
+                dash: [5, 4],
+                lineCap: 'round',
+                lineJoin: 'round',
+                pointerLength: 7,
+                pointerWidth: 7,
+                fill:'red',
+            });
+
+            this.routeLayer.add(line);
+            this.routeLayer.draw(); 
+
+            console.log(buff, "BUFFER");
+            buff = []; 
+            index -= 2; 
+        }
+
+        index++;
+
+        setTimeout(drawNextSegment, 25); 
+    };
+
+    drawNextSegment(); 
+}
 
 
-export class MapDisplay {
-    constructor(containerId, floorNum) {
-        this.container = document.getElementById(containerId);
-        this.containerId = containerId;
-        this.stage = new Konva.Stage({
-            container: containerId,
-            width: window.innerWidth,
-            height: window.innerHeight,
-            draggable: true,
-        });
-
-        this.selectedRoom = {
-            id: 1,
-            name: "223",
-            type: "Laboratory",
-            image:
-                "data:image/jpeg;base64,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",
-            description: "223 is a laboratory with a capacity of 40 people",
-        };
-        this.toggleSearch = false;
-
-        this.shapes = [];
-        this.roomTypes = [];
-        this.loaded = false;
-        this.mainLayer = new Konva.Layer();
-        this.routeLayer = new Konva.Layer();
-        this.textLayer = new Konva.Layer();
-        this.stage.add(this.mainLayer);
-        this.stage.add(this.routeLayer);
-        this.stage.add(this.textLayer);
-
-
-        this.cachedCanvases = [];
-
-        this.floorNum = floorNum;
-
-        this.navArrow = new Konva.Arrow({
-            stroke: "#bb0000",
-            strokeWidth: 3,
-            dash: [12, 7],
-            lineCap: "round",
-            tension: 10,
-            pointerLength: 2,
-            pointerWidth: 3,
-        });
-
-        this.navArrow.cache();
-
-        this.stage.on("resize", () => {
-            this.stage.width = window.innerWidth;
-            this.stage.height = window.innerHeight;
-        });
-
-        this.stage.on("wheel", (e) => {
-            zoomStage(e, this.stage);
-        });
-    }
-
-    clearMap() {
-        this.mainLayer.removeChildren();
-        this.shapes.forEach(shape => shape.clearText())
-        this.shapes = [];
-    }
-
-    deserializeMap(data) {
-        this.clearMap();
-
-        let dsrData = JSON.parse(data);
-        dsrData.forEach((shape) => {
-            if (shape.className !== "InfoPin") {
-                console.log("SHAPE ATTRS CREATE: " + JSON.stringify(shape.attrs));
-                const renderedShape = Factory.createRenderedShape(shape.className, shape.attrs);
-                addEventHandling(renderedShape, this, "click");
-                this.shapes.push(renderedShape);
-                console.log(renderedShape)
-            }
-        });
-    }
-
-    displayRoomNames() {
-        this.shapes.forEach((shape) => {
-            shape.displayName(this.textLayer);
-        });
-
-    }
-
-    loadMapN(floorData) {
-        if (floorData == null || floorData === "") return;
-
-        this.deserializeMap(floorData);
-        this.shapes.forEach((shape) => {
-            this.mainLayer.add(shape);
-        });
-        this.displayRoomNames();
-        this.initializeRoomTypes();
-
-    }
-
-    clearRoute() {
-        this.routeLayer.removeChildren();
-    }
-
-
-
-    drawRouteNEW(nodes, offset = 0) {
-
-        this.clearRoute();
-        console.log("====PATH====");
-        nodes.forEach((node) => console.log("NODE", node));
-
-        let idx = offset;
-        let buff = [nodes[idx].coordinates.x, nodes[idx].coordinates.y];
-
-        ++idx;
-
-        console.log("INIT BUFFER", buff);
-        console.log("INIT IDX", idx);
-
-        const drawNextSegment = () => {
-
-            if (idx >= nodes.length){
-                console.log("FLOOR NUM DISPLAY: " + this.floorNum)
-                let stageInfo = {stage:this.stage.clone(),floor:this.floorNum};
-                this.cachedCanvases.push(stageInfo);
-                dispatchCustomEvent("navend",this.downloadURI)
-                return;
-            }
-
-            const currentNode = nodes[idx - 1];
-            const nextNode = nodes[idx];
-
-            if (nextNode.floorNumber !== currentNode.floorNumber) {
-                let stageInfo = {stage:this.stage.clone(),floor:this.floorNum};
-                this.cachedCanvases.push(stageInfo);
-                triggerNavigate(nodes, idx, nextNode.floorNumber, nextNode);
-                return;
-            }
-
-            const startX = currentNode.coordinates.x;
-            const startY = currentNode.coordinates.y;
-            const endX = nextNode.coordinates.x;
-            const endY = nextNode.coordinates.y;
-
-            const numSegments = 10;
-
-            const deltaX = (endX - startX) / numSegments;
-            const deltaY = (endY - startY) / numSegments;
-
-            const drawSegment = (i) => {
-                const segmentX = startX + deltaX * i;
-                const segmentY = startY + deltaY * i;
-
-                buff.push(segmentX, segmentY);
-
-                let line = this.navArrow.clone({ points: [...buff] });
-                this.routeLayer.add(line);
-                this.routeLayer.draw();
-
-                buff = [segmentX, segmentY];
-            };
-
-            let segmentIdx = 1;
-            const interval = setInterval(() => {
-                drawSegment(segmentIdx);
-                segmentIdx++;
-
-                if (segmentIdx > numSegments) {
-                    clearInterval(interval);
-                    idx++;
-                    setTimeout(drawNextSegment, 60);
-                }
-            }, 30);
-        };
-
-        drawNextSegment();
-    }
-
-    initializeRoomTypes() {
-        this.roomTypes = this.shapes
-            .filter((shape) => shape.class === "Room" && shape.info.type !== "")
-            .map((shape) => shape.info.type);
-    }
-
-    getShapeByType(type) {
-        return this.shapes.filter((shape) => shape.class === type)
-    }
-
-    //ova e loso ne trebit vaka
-    highlightShape(roomName) {
-        let foundShape = this.shapes.filter((shape) => shape.info.name === roomName)[0];
-        foundShape.highlight();
-    }
-
-     downloadURI(uri, name) {
-        let link = document.createElement('a');
-        link.download = name;
-        link.href = uri;
-        document.body.appendChild(link);
-        link.click();
-        document.body.removeChild(link);
-    }
-
-
-    getRouteImages(mapDetails = { mapName: "mapName", from: "from", to: "to" }) {
-
-        const pdf = new jsPDF("p", "mm", "a4");
-        const pageWidth = pdf.internal.pageSize.getWidth();
-        const pageHeight = pdf.internal.pageSize.getHeight();
-        const margin = 10;
-        let yOffset = margin;
-
-        const imagesData = [];
-
-        let minWidth = 800;
-
-        this.cachedCanvases.forEach((canvas, index) => {
-            console.log("CANVASL " + JSON.stringify(canvas.stage))
-            let dsrStage = Konva.Node.create(canvas.stage, document.createElement("div"));
-
-            let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
-
-            dsrStage.getLayers().forEach(layer => {
-                layer.getChildren().forEach(shape => {
-                    const shapeX = shape.x();
-                    const shapeY = shape.y();
-                    const width = shape.width() * shape.scaleX();
-                    const height = shape.height() * shape.scaleY();
-
-                    minX = Math.min(minX, shapeX - shape.offsetX() * shape.scaleX());
-                    minY = Math.min(minY, shapeY - shape.offsetY() * shape.scaleY());
-                    maxX = Math.max(maxX, shapeX + width - shape.offsetX() * shape.scaleX());
-                    maxY = Math.max(maxY, shapeY + height - shape.offsetY() * shape.scaleY());
-                });
-            });
-
-            let padding = 50;
-
-            const virtualWidth = maxX - minX + padding;
-            const virtualHeight = maxY - minY + padding;
-
-            const scaleDownFactor = Math.min(pageWidth / virtualWidth, pageHeight / virtualHeight);
-
-            dsrStage.size({ width: virtualWidth, height: virtualHeight });
-            dsrStage.position({ x: -minX, y: -minY });
-            dsrStage.batchDraw();
-
-            let canvasImageURI = dsrStage.toDataURL({
-                pixelRatio: 1
-            });
-
-            imagesData.push(canvasImageURI);
-            console.log(`Generated Image ${index + 1}`);
-        });
-
-
-
-        imagesData.forEach((imageURI, index) => {
-            const text = `Floor: ${this.cachedCanvases[index].floor}`;
-            pdf.text(text, margin, yOffset + 5);
-
-            const img = new Image();
-            img.src = imageURI;
-
-            const maxWidth = pageWidth - 2 * margin;
-            const maxHeight = pageHeight - 2 * margin;
-            let imgWidth = maxWidth;
-            let imgHeight = maxHeight / 2
-
-            if (imgHeight > maxHeight) {
-                imgHeight = maxHeight;
-                imgWidth = (pageWidth * maxHeight) / pageHeight;
-            }
-
-            if (yOffset + imgHeight > pageHeight - margin) {
-                pdf.addPage();
-                yOffset = margin;
-            }
-
-            pdf.addImage(imageURI, "PNG", margin, yOffset, imgWidth, imgHeight);
-            yOffset += imgHeight + 10;
-        });
-
-        pdf.save(`${mapDetails.mapName}-${mapDetails.from}-->${mapDetails.to}.route.pdf`);
-    }
-
-
-
-setFilter(filter) {
-        let rooms = this.getShapeByType("Room")
-        if (filter === "All") {
-            rooms.forEach((shape) => {
-                shape.unHighlight()
-            })
-        } else {
-            rooms.filter((shape) => shape.info.type === filter).forEach((shape) => {
-                shape.highlight()
-            })
-            rooms.filter((shape) => shape.info.type !== filter).forEach((shape) => {
-                shape.unHighlight()
-            })
-        }
-
-    }
+  search() {
+    console.log("VLEZE VO SEARCH");
+  }
 }
