From 2fa19599467263dcf582bb12906e03328e03b4a4 Mon Sep 17 00:00:00 2001
From: zhang <zc857179121@qq.com>
Date: 星期三, 02 七月 2025 13:12:26 +0800
Subject: [PATCH] 初版提交

---
 algorithm_system/__init__.py                       |    2 
 algorithm_system/models/agv_model.py               |  572 +
 common/utils.py                                    |  286 
 algorithm_system/algorithm_server.py               |  623 +
 config/environment.py                              |  360 
 algorithm_system/models/__init__.py                |    2 
 common/data_models.py                              |  184 
 run_algorithm.py                                   |  216 
 common/__init__.py                                 |    2 
 algorithm_system/algorithms/collision_detection.py |  701 +
 .idea/.gitignore                                   |   10 
 .idea/misc.xml                                     |    4 
 common/api_client.py                               |  124 
 algorithm_system/algorithms/__init__.py            |    2 
 RCS与算法的接口协议v1.1.docx                               |    0 
 environment.json                                   | 14960 +++++++++++++++++++++++++++
 algorithm_system/algorithms/task_allocation.py     |  687 +
 algorithm_system/path_monitor.py                   |  442 
 config/settings.py                                 |   27 
 path_mapping.json                                  | 11880 ++++++++++++++++++++++
 ZY_algorithm_system.zip                            |    0 
 algorithm_system/algorithms/path_planning.py       | 1131 ++
 22 files changed, 32,215 insertions(+), 0 deletions(-)

diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..7bc07ec
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Environment-dependent path to Maven home directory
+/mavenHomeManager.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..90dee70
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="KubernetesApiProvider">{}</component>
+</project>
\ No newline at end of file
diff --git "a/RCS\344\270\216\347\256\227\346\263\225\347\232\204\346\216\245\345\217\243\345\215\217\350\256\256v1.1.docx" "b/RCS\344\270\216\347\256\227\346\263\225\347\232\204\346\216\245\345\217\243\345\215\217\350\256\256v1.1.docx"
new file mode 100644
index 0000000..1b75e87
--- /dev/null
+++ "b/RCS\344\270\216\347\256\227\346\263\225\347\232\204\346\216\245\345\217\243\345\215\217\350\256\256v1.1.docx"
Binary files differ
diff --git a/ZY_algorithm_system.zip b/ZY_algorithm_system.zip
new file mode 100644
index 0000000..9c6c868
--- /dev/null
+++ b/ZY_algorithm_system.zip
Binary files differ
diff --git a/algorithm_system/__init__.py b/algorithm_system/__init__.py
new file mode 100644
index 0000000..444220e
--- /dev/null
+++ b/algorithm_system/__init__.py
@@ -0,0 +1,2 @@
+# Algorithm System Module
+__version__ = "1.0.0" 
\ No newline at end of file
diff --git a/algorithm_system/algorithm_server.py b/algorithm_system/algorithm_server.py
new file mode 100644
index 0000000..f338288
--- /dev/null
+++ b/algorithm_system/algorithm_server.py
@@ -0,0 +1,623 @@
+"""
+绠楁硶绯荤粺鏈嶅姟鍣�
+"""
+import json
+import logging
+import os
+import time
+from typing import Dict, List, Optional, Any, Tuple
+from flask import Flask, request, jsonify
+
+from common.data_models import (
+    TaskData, AGVStatus, TaskAssignment, PlannedPath, 
+    create_success_response, create_error_response, ResponseCode, to_dict, from_dict
+)
+from common.utils import load_path_mapping
+from algorithm_system.models.agv_model import AGVModelManager
+from algorithm_system.algorithms.task_allocation import TaskAllocationFactory
+from algorithm_system.algorithms.path_planning import PathPlanningFactory
+from common.api_client import RCSAPIClient
+from algorithm_system.path_monitor import PathMonitorService
+
+try:
+    from config.settings import (
+        ALGORITHM_SERVER_HOST, ALGORITHM_SERVER_PORT,
+        RCS_SERVER_HOST, RCS_SERVER_PORT,
+        MONITOR_POLLING_INTERVAL
+    )
+except ImportError:
+    ALGORITHM_SERVER_HOST = "10.10.10.239"
+    ALGORITHM_SERVER_PORT = 8002
+    RCS_SERVER_HOST = "10.10.10.156"
+    RCS_SERVER_PORT = 8088
+    MONITOR_POLLING_INTERVAL = 5.0
+    logging.warning("鏃犳硶浠巆onfig.settings瀵煎叆閰嶇疆锛屼娇鐢ㄩ粯璁ゅ��")
+
+
+class AlgorithmServer:
+    """绠楁硶绯荤粺鏈嶅姟鍣�"""
+    
+    def __init__(self, host: str = None, port: int = None, enable_path_monitor: bool = True, 
+                 monitor_interval: float = None):
+        """鍒濆鍖栫畻娉曟湇鍔″櫒"""
+        self.host = host or ALGORITHM_SERVER_HOST
+        self.port = port or ALGORITHM_SERVER_PORT
+        self.enable_path_monitor = enable_path_monitor
+        self.monitor_interval = monitor_interval or MONITOR_POLLING_INTERVAL
+        self.logger = logging.getLogger(__name__)
+        
+        self.app = Flask(__name__)
+        
+        self.path_mapping = load_path_mapping()
+        
+        self.agv_manager = AGVModelManager(self.path_mapping)
+        
+        self.rcs_client = RCSAPIClient()
+        
+        self.task_allocation_algorithm = "LOAD_BALANCED"  # 榛樿浠诲姟鍒嗛厤
+        self.path_planning_algorithm = "A_STAR"  # 榛樿璺緞瑙勫垝
+
+        self.path_monitor = None
+        if self.enable_path_monitor:
+            self.path_monitor = PathMonitorService(
+                rcs_host=RCS_SERVER_HOST,
+                rcs_port=RCS_SERVER_PORT,
+                poll_interval=self.monitor_interval,
+                path_algorithm=self.path_planning_algorithm,
+                auto_send_paths=True  # 鑷姩鍙戦�佽矾寰勫埌RCS
+            )
+            self.logger.info(f"璺緞鐩戞帶鏈嶅姟宸插垵濮嬪寲 - 杞闂撮殧: {self.monitor_interval}s, 鑷姩鍙戦�佽矾寰�: True")
+        
+        self._setup_routes()
+        
+        self.logger.info("绠楁硶绯荤粺鏈嶅姟鍣ㄥ垵濮嬪寲瀹屾垚")
+    
+    def _setup_routes(self):
+        """璁剧疆API璺敱"""
+        
+        @self.app.route('/open/task/send/v1', methods=['POST'])
+        def task_send_endpoint():
+            """浠诲姟涓嬪彂鎺ュ彛"""
+            return self._handle_task_send_request()
+        
+        @self.app.route('/open/path/plan/v1', methods=['POST'])
+        def path_plan_endpoint():
+            """璺緞瑙勫垝鎺ュ彛"""
+            return self._handle_path_planning_request()
+        
+        @self.app.route('/open/path/batch/plan/v1', methods=['POST'])
+        def batch_path_plan_endpoint():
+            """鎵归噺璺緞瑙勫垝鎺ュ彛"""
+            return self._handle_batch_path_planning_request()
+        
+        @self.app.route('/open/algorithm/config/v1', methods=['POST'])
+        def algorithm_config_endpoint():
+            """绠楁硶閰嶇疆鎺ュ彛"""
+            return self._handle_algorithm_config_request()
+        
+        @self.app.route('/monitor/path/start/v1', methods=['POST'])
+        def start_path_monitor_endpoint():
+            """鍚姩璺緞鐩戞帶鏈嶅姟鎺ュ彛"""
+            return self._handle_start_path_monitor_request()
+        
+        @self.app.route('/monitor/path/stop/v1', methods=['POST'])
+        def stop_path_monitor_endpoint():
+            """鍋滄璺緞鐩戞帶鏈嶅姟鎺ュ彛"""
+            return self._handle_stop_path_monitor_request()
+        
+        @self.app.route('/monitor/path/status/v1', methods=['GET'])
+        def path_monitor_status_endpoint():
+            """璺緞鐩戞帶鏈嶅姟鐘舵�佹煡璇㈡帴鍙�"""
+            return self._handle_path_monitor_status_request()
+        
+        @self.app.route('/health', methods=['GET'])
+        def health_check():
+            """鍋ュ悍妫�鏌ユ帴鍙�"""
+            monitor_status = None
+            if self.path_monitor:
+                monitor_status = self.path_monitor.get_monitoring_status()
+            
+            return jsonify({
+                "status": "healthy", 
+                "service": "algorithm_system",
+                "timestamp": time.time(),
+                "path_mapping_loaded": len(self.path_mapping) > 0,
+                "algorithms": {
+                    "task_allocation": self.task_allocation_algorithm,
+                    "path_planning": self.path_planning_algorithm
+                },
+                "agv_count": len(self.agv_manager.get_all_agvs()),
+                "path_monitor": monitor_status,
+                "available_endpoints": [
+                    "POST /open/task/send/v1 - 浠诲姟鍒嗛厤鎺ュ彛",
+                    "POST /open/path/plan/v1 - 鍗曡矾寰勮鍒掓帴鍙�", 
+                    "POST /open/path/batch/plan/v1 - 鎵归噺璺緞瑙勫垝鎺ュ彛",
+                    "POST /open/algorithm/config/v1 - 绠楁硶閰嶇疆鎺ュ彛",
+                    "POST /monitor/path/start/v1 - 鍚姩璺緞鐩戞帶鏈嶅姟",
+                    "POST /monitor/path/stop/v1 - 鍋滄璺緞鐩戞帶鏈嶅姟",
+                    "GET /monitor/path/status/v1 - 璺緞鐩戞帶鏈嶅姟鐘舵�佹煡璇�",
+                    "GET /health - 鍋ュ悍妫�鏌ユ帴鍙�"
+                ]
+            })
+        
+        @self.app.errorhandler(404)
+        def not_found(error):
+            """404閿欒澶勭悊"""
+            return jsonify(to_dict(create_error_response(404, "鎺ュ彛涓嶅瓨鍦�"))), 404
+        
+        @self.app.errorhandler(500)
+        def internal_error(error):
+            """500閿欒澶勭悊"""
+            self.logger.error(f"鍐呴儴鏈嶅姟鍣ㄩ敊璇�: {error}")
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, "鍐呴儴鏈嶅姟鍣ㄩ敊璇�"))), 500
+    
+    def _handle_task_send_request(self) -> Dict[str, Any]:
+        """澶勭悊浠诲姟涓嬪彂璇锋眰"""
+        try:
+            if not request.is_json:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "璇锋眰鏁版嵁鏍煎紡閿欒")))
+            
+            request_data = request.get_json()
+            if not request_data:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "璇锋眰鏁版嵁涓虹┖")))
+            
+            if isinstance(request_data, dict) and "tasks" in request_data:
+                task_data = request_data.get("tasks", [])
+                agv_status_data = request_data.get("agvStatus", [])
+                self.logger.info(f"鏀跺埌缁撴瀯鍖栦换鍔″垎閰嶈姹傦紝浠诲姟鏁伴噺: {len(task_data)}, AGV鏁伴噺: {len(agv_status_data)}")
+            elif isinstance(request_data, list):
+                task_data = request_data
+                agv_status_data = []
+                self.logger.info(f"鏀跺埌浠诲姟鍒嗛厤璇锋眰锛屼换鍔℃暟閲�: {len(task_data)}")
+            else:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "浠诲姟鏁版嵁鏍煎紡鏃犳晥")))
+            
+            if not task_data or not isinstance(task_data, list):
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "浠诲姟鏁版嵁鏃犳晥")))
+            
+            tasks = []
+            for task_dict in task_data:
+                try:
+                    task = TaskData(
+                        taskId=task_dict.get("taskId", ""),
+                        start=task_dict.get("start", ""),
+                        end=task_dict.get("end", ""),
+                        type=task_dict.get("type", "1"),
+                        priority=task_dict.get("priority", 5)
+                    )
+                    tasks.append(task)
+                except Exception as e:
+                    self.logger.warning(f"瑙f瀽浠诲姟鏁版嵁澶辫触: {task_dict} - {e}")
+                    continue
+            
+            if not tasks:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "娌℃湁鏈夋晥鐨勪换鍔℃暟鎹�")))
+            
+            agv_status_list = []
+            if agv_status_data:
+                self.logger.info("浣跨敤璇锋眰涓彁渚涚殑AGV鐘舵�佹暟鎹�")
+                for agv_data in agv_status_data:
+                    try:
+                        agv_status = from_dict(AGVStatus, agv_data)
+                        agv_status_list.append(agv_status)
+                    except Exception as e:
+                        self.logger.warning(f"瑙f瀽璇锋眰涓殑AGV鐘舵�佹暟鎹け璐�: {agv_data} - {e}")
+                        continue
+            else:
+                self.logger.info("浠嶳CS绯荤粺鑾峰彇AGV鐘舵�佹暟鎹�")
+                agv_response = self.rcs_client.get_agv_status()
+                if agv_response.code == ResponseCode.SUCCESS and agv_response.data:
+                    for agv_data in agv_response.data:
+                        try:
+                            agv_status = from_dict(AGVStatus, agv_data)
+                            agv_status_list.append(agv_status)
+                        except Exception as e:
+                            self.logger.warning(f"瑙f瀽RCS杩斿洖鐨凙GV鐘舵�佹暟鎹け璐�: {agv_data} - {e}")
+                            continue
+                else:
+                    error_msg = f"鏃犳硶鑾峰彇AGV鐘舵��: {agv_response.msg if agv_response else 'RCS绯荤粺杩炴帴澶辫触'}"
+                    self.logger.error(error_msg)
+                    
+                    use_fallback_allocation = getattr(self, 'use_fallback_allocation', True)
+                    
+                    if use_fallback_allocation:
+                        self.logger.warning("浣跨敤杞鍒嗛厤浣滀负澶囩敤鏂规")
+                        return self._simple_round_robin_allocation(tasks)
+                    else:
+                        return jsonify(to_dict(create_error_response(
+                            ResponseCode.SERVER_ERROR, 
+                            error_msg
+                        )))
+            
+            if not agv_status_list:
+                return jsonify(to_dict(create_error_response(ResponseCode.NO_DATA, "娌℃湁鍙敤鐨凙GV鐘舵�佹暟鎹�")))
+            
+            self.agv_manager.update_agv_data(agv_status_list)
+            self.logger.info(f"鏇存柊浜� {len(agv_status_list)} 涓狝GV鐘舵��")
+            
+            all_agvs = self.agv_manager.get_all_agvs()
+            self.logger.info(f"绠楁硶绯荤粺涓綋鍓嶆湁 {len(all_agvs)} 涓狝GV妯″瀷")
+            
+            available_count = 0
+            for agv in all_agvs:
+                can_accept = agv.can_accept_task(5) 
+                self.logger.debug(f"AGV {agv.agvId}: status={agv.status}, can_accept_task={can_accept}, "
+                                f"is_overloaded={agv.is_overloaded()}, task_count={agv.current_task_count}")
+                if can_accept:
+                    available_count += 1
+            
+            self.logger.info(f"鍏朵腑 {available_count} 涓狝GV鍙互鎺ュ彈浠诲姟")
+            
+            if available_count == 0:
+                self.logger.warning("娌℃湁AGV鍙互鎺ュ彈浠诲姟锛佽缁嗙姸鎬�:")
+                for agv in all_agvs:
+                    status_str = str(agv.status)
+                    self.logger.warning(f"  AGV {agv.agvId}: 鐘舵��={status_str}, 绫诲瀷={type(agv.status)}, "
+                                      f"浠诲姟鏁�={agv.current_task_count}/{agv.max_capacity}")
+            
+            allocator = TaskAllocationFactory.create_allocator(
+                self.task_allocation_algorithm, 
+                self.agv_manager
+            )
+            
+            start_time = time.time()
+            assignments = allocator.allocate_tasks(tasks)
+            end_time = time.time()
+            
+            allocation_time = (end_time - start_time) * 1000  # 杞崲涓烘绉�
+            
+            assignment_data = [to_dict(assignment) for assignment in assignments]
+            
+            self.logger.info(f"浠诲姟鍒嗛厤瀹屾垚锛屽垎閰嶄簡 {len(assignments)} 涓换鍔★紝鑰楁椂: {allocation_time:.2f}ms")
+            
+            response = create_success_response(assignment_data)
+            return jsonify(to_dict(response))
+            
+        except Exception as e:
+            self.logger.error(f"澶勭悊浠诲姟鍒嗛厤璇锋眰澶辫触: {e}", exc_info=True)
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鏈嶅姟鍣ㄩ敊璇�: {str(e)}")))
+    
+    def _handle_path_planning_request(self) -> Dict[str, Any]:
+        """澶勭悊璺緞瑙勫垝璇锋眰"""
+        try:
+            # 楠岃瘉璇锋眰鏁版嵁
+            if not request.is_json:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "璇锋眰鏁版嵁鏍煎紡閿欒")))
+            
+            request_data = request.get_json()
+            if not request_data:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "璇锋眰鏁版嵁涓虹┖")))
+            
+            agv_id = request_data.get("agvId")
+            start_code = request_data.get("start")
+            end_code = request_data.get("end")
+            constraints = request_data.get("constraints", [])
+            
+            if not agv_id or not start_code or not end_code:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "缂哄皯蹇呰鍙傛暟")))
+            
+            self.logger.info(f"鏀跺埌璺緞瑙勫垝璇锋眰 - AGV: {agv_id}, 浠� {start_code} 鍒� {end_code}")
+            
+            # 鍒涘缓璺緞瑙勫垝鍣�
+            path_planner = PathPlanningFactory.create_path_planner(
+                self.path_planning_algorithm, 
+                self.path_mapping
+            )
+            
+            # 鎵ц璺緞瑙勫垝
+            start_time = time.time()
+            planned_path = path_planner.plan_path(start_code, end_code, constraints)
+            end_time = time.time()
+            
+            planning_time = (end_time - start_time) * 1000  # 杞崲涓烘绉�
+            
+            if planned_path:
+                # 璁剧疆AGV ID
+                planned_path.agvId = agv_id
+                
+                # 杞崲涓哄搷搴旀牸寮�
+                path_data = to_dict(planned_path)
+                
+                self.logger.info(f"璺緞瑙勫垝瀹屾垚 - AGV: {agv_id}, 璺緞闀垮害: {len(planned_path.codeList)}, 鑰楁椂: {planning_time:.2f}ms")
+                
+                response = create_success_response(path_data)
+                return jsonify(to_dict(response))
+            else:
+                self.logger.warning(f"璺緞瑙勫垝澶辫触 - AGV: {agv_id}, 浠� {start_code} 鍒� {end_code}")
+                return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, "鏃犳硶瑙勫垝璺緞")))
+                
+        except Exception as e:
+            self.logger.error(f"澶勭悊璺緞瑙勫垝璇锋眰澶辫触: {e}", exc_info=True)
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鏈嶅姟鍣ㄩ敊璇�: {str(e)}")))
+    
+    def _handle_batch_path_planning_request(self) -> Dict[str, Any]:
+        """澶勭悊鎵归噺璺緞瑙勫垝璇锋眰"""
+        try:
+            if not request.is_json:
+                request_data = {}
+            else:
+                request_data = request.get_json() or {}
+            
+            constraints = request_data.get("constraints", [])
+            include_idle_agv = request_data.get("includeIdleAgv", False)
+            use_enhanced_planning = request_data.get("useEnhancedPlanning", True)
+            
+            agv_status_from_request = (
+                request_data.get("agvStatusList", []) or
+                request_data.get("agvs", [])
+            )
+            
+            self.logger.info(f"鏀跺埌鎵归噺璺緞瑙勫垝璇锋眰锛屽寘鍚┖闂睞GV: {include_idle_agv}, "
+                           f"璇锋眰涓瑼GV鏁伴噺: {len(agv_status_from_request)}, "
+                           f"浣跨敤澧炲己瑙勫垝: {use_enhanced_planning}")
+            
+            agv_status_list = []
+            if agv_status_from_request:
+                self.logger.info("浣跨敤璇锋眰涓彁渚涚殑AGV鐘舵�佹暟鎹繘琛岃矾寰勮鍒�")
+                for agv_data in agv_status_from_request:
+                    try:
+                        agv_status = from_dict(AGVStatus, agv_data)
+                        agv_status_list.append(agv_status)
+                    except Exception as e:
+                        self.logger.warning(f"瑙f瀽璇锋眰涓殑AGV鐘舵�佹暟鎹け璐�: {agv_data} - {e}")
+                        continue
+            else:
+                self.logger.info("浠嶳CS绯荤粺鑾峰彇AGV鐘舵�佹暟鎹繘琛岃矾寰勮鍒�")
+                agv_response = self.rcs_client.get_agv_status()
+                if agv_response.code != ResponseCode.SUCCESS or not agv_response.data:
+                    error_msg = f"鏃犳硶鑾峰彇AGV鐘舵�佽繘琛岃矾寰勮鍒�: {agv_response.msg if agv_response else 'RCS绯荤粺杩炴帴澶辫触'}"
+                    self.logger.error(error_msg)
+                    return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, error_msg)))
+                
+                for agv_data in agv_response.data:
+                    try:
+                        agv_status = from_dict(AGVStatus, agv_data)
+                        agv_status_list.append(agv_status)
+                    except Exception as e:
+                        self.logger.warning(f"瑙f瀽RCS杩斿洖鐨凙GV鐘舵�佹暟鎹け璐�: {agv_data} - {e}")
+                        continue
+            
+            if not agv_status_list:
+                error_msg = "娌℃湁鍙敤鐨凙GV鐘舵�佹暟鎹繘琛岃矾寰勮鍒�"
+                self.logger.error(error_msg)
+                return jsonify(to_dict(create_error_response(ResponseCode.NO_DATA, error_msg)))
+            
+            # 鏇存柊AGV妯″瀷绠$悊鍣�
+            self.agv_manager.update_agv_data(agv_status_list)
+            
+            self.logger.info(f"寮哄埗浣跨敤璺緞瑙勫垝浠ョ‘淇濆寘鍚柊瀛楁")
+            result = self._enhanced_batch_path_planning(agv_status_list, include_idle_agv, constraints)
+            
+            response = create_success_response(result)
+            return jsonify(to_dict(response))
+            
+        except Exception as e:
+            self.logger.error(f"澶勭悊鎵归噺璺緞瑙勫垝璇锋眰澶辫触: {e}", exc_info=True)
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鏈嶅姟鍣ㄩ敊璇�: {str(e)}")))
+    
+    def _enhanced_batch_path_planning(self, agv_status_list: List[AGVStatus], 
+                                    include_idle_agv: bool, 
+                                    constraints: List[Tuple[int, int, float]]) -> Dict[str, Any]:
+        """鎵归噺璺緞瑙勫垝"""
+        from algorithm_system.algorithms.path_planning import PathPlanningFactory
+        
+        # 鍒涘缓鎵归噺璺緞瑙勫垝鍣�
+        batch_planner = PathPlanningFactory.create_batch_path_planner(
+            algorithm_type=self.path_planning_algorithm,
+            path_mapping=self.path_mapping
+        )
+        
+        # 鎵ц鎵归噺璺緞瑙勫垝
+        result = batch_planner.plan_all_agv_paths(
+            agv_status_list=agv_status_list,
+            include_idle_agv=include_idle_agv,
+            constraints=constraints
+        )
+        
+        # 鎻愬彇plannedPaths浣滀负鏈�缁堣繑鍥炴暟鎹�
+        planned_paths = result.get('plannedPaths', [])
+        
+        self.logger.info(f"鎵归噺璺緞瑙勫垝瀹屾垚 - 鎬籄GV: {result['totalAgvs']}, "
+                        f"鎵ц浠诲姟: {result['executingTasksCount']}, "
+                        f"瑙勫垝璺緞: {result['plannedPathsCount']}, "
+                        f"鍐茬獊妫�娴�: {result['conflictsDetected']}, "
+                        f"鎬昏�楁椂: {result['totalPlanningTime']:.2f}ms")
+        
+        # 鍙繑鍥炶矾寰勬暟缁勶紝涓嶅寘鍚叾浠栫粺璁′俊鎭�
+        return planned_paths
+    
+    def _handle_algorithm_config_request(self) -> Dict[str, Any]:
+        """
+        澶勭悊绠楁硶閰嶇疆璇锋眰
+        
+        Returns:
+            Dict: 鍝嶅簲鏁版嵁
+        """
+        try:
+            # 楠岃瘉璇锋眰鏁版嵁
+            if not request.is_json:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "璇锋眰鏁版嵁鏍煎紡閿欒")))
+            
+            config_data = request.get_json()
+            if not config_data:
+                return jsonify(to_dict(create_error_response(ResponseCode.PARAM_EMPTY, "閰嶇疆鏁版嵁涓虹┖")))
+            
+            # 鏇存柊绠楁硶閰嶇疆
+            if "task_allocation_algorithm" in config_data:
+                self.task_allocation_algorithm = config_data["task_allocation_algorithm"]
+                self.logger.info(f"浠诲姟鍒嗛厤绠楁硶鏇存柊涓�: {self.task_allocation_algorithm}")
+            
+            if "path_planning_algorithm" in config_data:
+                self.path_planning_algorithm = config_data["path_planning_algorithm"]
+                self.logger.info(f"璺緞瑙勫垝绠楁硶鏇存柊涓�: {self.path_planning_algorithm}")
+            
+            # 杩斿洖褰撳墠閰嶇疆
+            current_config = {
+                "task_allocation_algorithm": self.task_allocation_algorithm,
+                "path_planning_algorithm": self.path_planning_algorithm
+            }
+            
+            response = create_success_response(current_config)
+            return jsonify(to_dict(response))
+            
+        except Exception as e:
+            self.logger.error(f"澶勭悊绠楁硶閰嶇疆璇锋眰澶辫触: {e}", exc_info=True)
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鏈嶅姟鍣ㄩ敊璇�: {str(e)}")))
+    
+    def _simple_round_robin_allocation(self, tasks: List[TaskData]) -> Dict[str, Any]:
+        """绠�鍗曠殑杞鍒嗛厤"""
+        assignments = []
+        
+        # 灏濊瘯浠嶳CS绯荤粺鑾峰彇AGV鏁伴噺
+        agv_count = 5  # 榛樿鍊�
+        try:
+            agv_response = self.rcs_client.get_agv_status()
+            if agv_response.code == ResponseCode.SUCCESS and agv_response.data:
+                agv_count = len(agv_response.data)
+                self.logger.info(f"浠嶳CS绯荤粺鑾峰彇鍒癆GV鏁伴噺: {agv_count}")
+            else:
+                # 濡傛灉RCS杩斿洖鏃犳暟鎹紝浣跨敤閰嶇疆鐨勯粯璁ゅ��
+                from config.settings import DEFAULT_AGV_COUNT
+                agv_count = DEFAULT_AGV_COUNT
+                self.logger.warning(f"鏃犳硶浠嶳CS鑾峰彇AGV鏁伴噺锛屼娇鐢ㄩ粯璁ゅ��: {agv_count}")
+        except Exception as e:
+            # 濡傛灉瀹屽叏鏃犳硶杩炴帴RCS锛屼娇鐢ㄩ厤缃殑榛樿鍊�
+            from config.settings import DEFAULT_AGV_COUNT
+            agv_count = DEFAULT_AGV_COUNT
+            self.logger.error(f"鑾峰彇AGV鏁伴噺澶辫触锛屼娇鐢ㄩ粯璁ゅ��: {agv_count} - {e}")
+        
+        for i, task in enumerate(tasks):
+            agv_id = f"AGV_{10001 + (i % agv_count)}"
+            assignment = TaskAssignment(
+                taskId=task.taskId,
+                agvId=agv_id
+            )
+            assignments.append(assignment)
+        
+        assignment_data = [to_dict(assignment) for assignment in assignments]
+        
+        self.logger.info(f"浣跨敤绠�鍗曡疆璇㈠垎閰嶄簡 {len(assignments)} 涓换鍔★紝AGV鏁伴噺: {agv_count}")
+        
+        response = create_success_response(assignment_data)
+        return jsonify(to_dict(response))
+    
+    def _handle_start_path_monitor_request(self) -> Dict[str, Any]:
+        """澶勭悊鍚姩璺緞鐩戞帶鏈嶅姟璇锋眰"""
+        try:
+            if not self.path_monitor:
+                return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, "璺緞鐩戞帶鏈嶅姟鏈垵濮嬪寲")))
+            
+            if self.path_monitor.is_running:
+                return jsonify(to_dict(create_success_response({"message": "璺緞鐩戞帶鏈嶅姟宸插湪杩愯涓�"})))
+            
+            # 鍚姩璺緞鐩戞帶鏈嶅姟
+            self.path_monitor.start_monitoring()
+            
+            self.logger.info("璺緞鐩戞帶鏈嶅姟宸查�氳繃API鍚姩")
+            
+            response = create_success_response({
+                "message": "璺緞鐩戞帶鏈嶅姟鍚姩鎴愬姛",
+                "monitor_status": self.path_monitor.get_monitoring_status()
+            })
+            
+            return jsonify(to_dict(response))
+            
+        except Exception as e:
+            self.logger.error(f"鍚姩璺緞鐩戞帶鏈嶅姟澶辫触: {e}")
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鍚姩璺緞鐩戞帶鏈嶅姟澶辫触: {str(e)}")))
+    
+    def _handle_stop_path_monitor_request(self) -> Dict[str, Any]:
+        """澶勭悊鍋滄璺緞鐩戞帶鏈嶅姟璇锋眰"""
+        try:
+            if not self.path_monitor:
+                return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, "璺緞鐩戞帶鏈嶅姟鏈垵濮嬪寲")))
+            
+            if not self.path_monitor.is_running:
+                return jsonify(to_dict(create_success_response({"message": "璺緞鐩戞帶鏈嶅姟鏈湪杩愯"})))
+            
+            # 鍋滄璺緞鐩戞帶鏈嶅姟
+            self.path_monitor.stop_monitoring()
+            
+            self.logger.info("璺緞鐩戞帶鏈嶅姟宸查�氳繃API鍋滄")
+            
+            response = create_success_response({
+                "message": "璺緞鐩戞帶鏈嶅姟鍋滄鎴愬姛",
+                "monitor_status": self.path_monitor.get_monitoring_status()
+            })
+            
+            return jsonify(to_dict(response))
+            
+        except Exception as e:
+            self.logger.error(f"鍋滄璺緞鐩戞帶鏈嶅姟澶辫触: {e}")
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鍋滄璺緞鐩戞帶鏈嶅姟澶辫触: {str(e)}")))
+    
+    def _handle_path_monitor_status_request(self) -> Dict[str, Any]:
+        """澶勭悊璺緞鐩戞帶鏈嶅姟鐘舵�佹煡璇㈣姹�"""
+        try:
+            if not self.path_monitor:
+                return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, "璺緞鐩戞帶鏈嶅姟鏈垵濮嬪寲")))
+            
+            monitor_status = self.path_monitor.get_monitoring_status()
+            
+            response = create_success_response({
+                "monitor_status": monitor_status,
+                "description": "璺緞鐩戞帶鏈嶅姟鐘舵�佷俊鎭�"
+            })
+            
+            return jsonify(to_dict(response))
+            
+        except Exception as e:
+            self.logger.error(f"鑾峰彇璺緞鐩戞帶鏈嶅姟鐘舵�佸け璐�: {e}")
+            return jsonify(to_dict(create_error_response(ResponseCode.SERVER_ERROR, f"鑾峰彇璺緞鐩戞帶鏈嶅姟鐘舵�佸け璐�: {str(e)}")))
+    
+    def start_server(self):
+        """鍚姩绠楁硶鏈嶅姟鍣�"""
+        self.logger.info(f"鍚姩绠楁硶绯荤粺鏈嶅姟鍣�: http://{self.host}:{self.port}")
+        
+        try:
+            # 濡傛灉鍚敤浜嗚矾寰勭洃鎺ф湇鍔★紝鑷姩鍚姩
+            if self.path_monitor and self.enable_path_monitor:
+                self.path_monitor.start_monitoring()
+                self.logger.info("璺緞鐩戞帶鏈嶅姟宸茶嚜鍔ㄥ惎鍔�")
+            
+            self.app.run(
+                host=self.host,
+                port=self.port,
+                debug=False,
+                threaded=True
+            )
+        except Exception as e:
+            self.logger.error(f"鍚姩绠楁硶鏈嶅姟鍣ㄥけ璐�: {e}")
+            # 纭繚鍦ㄥ惎鍔ㄥけ璐ユ椂鍋滄璺緞鐩戞帶鏈嶅姟
+            if self.path_monitor and self.path_monitor.is_running:
+                self.path_monitor.stop_monitoring()
+            raise
+    
+    def stop_server(self):
+        """鍋滄绠楁硶鏈嶅姟鍣�"""
+        self.logger.info("鍋滄绠楁硶鏈嶅姟鍣�")
+        
+        # 鍋滄璺緞鐩戞帶鏈嶅姟
+        if self.path_monitor and self.path_monitor.is_running:
+            self.path_monitor.stop_monitoring()
+            self.logger.info("璺緞鐩戞帶鏈嶅姟宸插仠姝�")
+
+    
+    def get_server_status(self) -> Dict[str, Any]:
+        """鑾峰彇鏈嶅姟鍣ㄧ姸鎬�"""
+        monitor_status = None
+        if self.path_monitor:
+            monitor_status = self.path_monitor.get_monitoring_status()
+        
+        return {
+            "host": self.host,
+            "port": self.port,
+            "path_mapping_loaded": len(self.path_mapping) > 0,
+            "agv_count": len(self.agv_manager.get_all_agvs()),
+            "algorithms": {
+                "task_allocation": self.task_allocation_algorithm,
+                "path_planning": self.path_planning_algorithm
+            },
+            "path_monitor": monitor_status,
+            "timestamp": time.time()
+        } 
\ No newline at end of file
diff --git a/algorithm_system/algorithms/__init__.py b/algorithm_system/algorithms/__init__.py
new file mode 100644
index 0000000..57ac5fa
--- /dev/null
+++ b/algorithm_system/algorithms/__init__.py
@@ -0,0 +1,2 @@
+# Algorithm System Algorithms Module
+__version__ = "1.0.0" 
\ No newline at end of file
diff --git a/algorithm_system/algorithms/collision_detection.py b/algorithm_system/algorithms/collision_detection.py
new file mode 100644
index 0000000..5b099bf
--- /dev/null
+++ b/algorithm_system/algorithms/collision_detection.py
@@ -0,0 +1,701 @@
+"""
+AGV璺緞纰版挒妫�娴嬪拰瑙e喅妯″潡
+"""
+import math
+import logging
+from typing import Dict, List, Tuple, Optional, Set
+from dataclasses import dataclass
+from collections import defaultdict
+
+from common.data_models import PlannedPath, PathCode, AGVActionTypeEnum
+from common.utils import get_coordinate_from_path_id
+
+
+@dataclass
+class SpaceTimeNode:
+    """鏃剁┖鑺傜偣 - 琛ㄧずAGV鍦ㄧ壒瀹氭椂闂村拰浣嶇疆鐨勭姸鎬�"""
+    agv_id: str
+    position: str  # 浣嶇疆鐮�
+    coordinates: Tuple[int, int]  # 鍧愭爣
+    time_step: int  # 鏃堕棿姝�
+    direction: str  # 鏂瑰悜
+
+
+@dataclass
+class Conflict:
+    """鍐茬獊鎻忚堪"""
+    type: str  # 鍐茬獊绫诲瀷: "vertex", "edge", "follow"
+    agv1: str
+    agv2: str
+    time_step: int
+    position1: str
+    position2: str
+    description: str
+
+
+@dataclass
+class AGVPriority:
+    """AGV浼樺厛绾ц瘎浼扮粨鏋�"""
+    agv_id: str
+    priority_score: float  # 浼樺厛绾у垎鏁帮紝瓒婇珮瓒婁紭鍏�
+    task_status: str  # 浠诲姟鐘舵��
+    action_type: str  # 鍔ㄤ綔绫诲瀷
+    task_priority: int  # 浠诲姟浼樺厛绾�
+    voltage: int  # 鐢甸噺
+    explanation: str  # 浼樺厛绾ц鏄�
+
+
+class CollisionDetector:
+    """AGV璺緞纰版挒妫�娴嬪櫒"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]], 
+                 min_distance: float = 3.0, time_buffer: int = 1):
+        """
+        鍒濆鍖栫鎾炴娴嬪櫒
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+            min_distance: AGV涔嬮棿鐨勬渶灏忓畨鍏ㄨ窛绂�
+            time_buffer: 鏃堕棿缂撳啿鍖猴紙鏃堕棿姝ユ暟锛�
+        """
+        self.path_mapping = path_mapping
+        self.min_distance = min_distance
+        self.time_buffer = time_buffer
+        self.logger = logging.getLogger(__name__)
+    
+    def detect_conflicts(self, planned_paths: List[Dict]) -> List[Conflict]:
+        """
+        妫�娴嬫墍鏈堿GV璺緞涔嬮棿鐨勫啿绐�
+        
+        Args:
+            planned_paths: 瑙勫垝璺緞鍒楄〃
+            
+        Returns:
+            List[Conflict]: 鍐茬獊鍒楄〃
+        """
+        conflicts = []
+        
+        # 鏋勫缓鏃剁┖琛�
+        space_time_table = self._build_space_time_table(planned_paths)
+        
+        # 妫�娴嬮《鐐瑰啿绐侊紙鍚屼竴鏃堕棿鍚屼竴浣嶇疆锛�
+        conflicts.extend(self._detect_vertex_conflicts(space_time_table))
+        
+        # 妫�娴嬭竟鍐茬獊锛圓GV浜ゆ崲浣嶇疆锛�
+        conflicts.extend(self._detect_edge_conflicts(space_time_table))
+        
+        # 妫�娴嬭窡闅忓啿绐侊紙AGV璺濈杩囪繎锛�
+        conflicts.extend(self._detect_following_conflicts(space_time_table))
+        
+        self.logger.info(f"妫�娴嬪埌 {len(conflicts)} 涓矾寰勫啿绐�")
+        return conflicts
+    
+    def _build_space_time_table(self, planned_paths: List[Dict]) -> Dict[int, List[SpaceTimeNode]]:
+        """
+        鏋勫缓鏃剁┖琛�
+        
+        Args:
+            planned_paths: 瑙勫垝璺緞鍒楄〃
+            
+        Returns:
+            Dict[int, List[SpaceTimeNode]]: 鏃堕棿姝� -> 鏃剁┖鑺傜偣鍒楄〃
+        """
+        space_time_table = defaultdict(list)
+        
+        for path_data in planned_paths:
+            agv_id = path_data.get('agvId', '')
+            code_list = path_data.get('codeList', [])
+            
+            for time_step, path_code in enumerate(code_list):
+                position = path_code.get('code', '') if isinstance(path_code, dict) else path_code.code
+                direction = path_code.get('direction', '90') if isinstance(path_code, dict) else path_code.direction
+                
+                coordinates = get_coordinate_from_path_id(position, self.path_mapping)
+                if coordinates:
+                    node = SpaceTimeNode(
+                        agv_id=agv_id,
+                        position=position,
+                        coordinates=coordinates,
+                        time_step=time_step,
+                        direction=direction
+                    )
+                    space_time_table[time_step].append(node)
+        
+        return space_time_table
+    
+    def _detect_vertex_conflicts(self, space_time_table: Dict[int, List[SpaceTimeNode]]) -> List[Conflict]:
+        """妫�娴嬮《鐐瑰啿绐侊紙鍚屼竴鏃堕棿鍚屼竴浣嶇疆锛�"""
+        conflicts = []
+        
+        for time_step, nodes in space_time_table.items():
+            # 鎸変綅缃垎缁�
+            position_groups = defaultdict(list)
+            for node in nodes:
+                position_groups[node.position].append(node)
+            
+            # 妫�鏌ユ瘡涓綅缃槸鍚︽湁澶氫釜AGV
+            for position, agv_nodes in position_groups.items():
+                if len(agv_nodes) > 1:
+                    # 鍙戠幇鍐茬獊
+                    for i in range(len(agv_nodes)):
+                        for j in range(i + 1, len(agv_nodes)):
+                            conflict = Conflict(
+                                type="vertex",
+                                agv1=agv_nodes[i].agv_id,
+                                agv2=agv_nodes[j].agv_id,
+                                time_step=time_step,
+                                position1=position,
+                                position2=position,
+                                description=f"AGV {agv_nodes[i].agv_id} 鍜� {agv_nodes[j].agv_id} 鍦ㄦ椂闂� {time_step} 鍗犵敤鍚屼竴浣嶇疆 {position}"
+                            )
+                            conflicts.append(conflict)
+        
+        return conflicts
+    
+    def _detect_edge_conflicts(self, space_time_table: Dict[int, List[SpaceTimeNode]]) -> List[Conflict]:
+        """妫�娴嬭竟鍐茬獊锛圓GV浜ゆ崲浣嶇疆锛�"""
+        conflicts = []
+        
+        max_time = max(space_time_table.keys()) if space_time_table else 0
+        
+        for time_step in range(max_time):
+            current_nodes = space_time_table.get(time_step, [])
+            next_nodes = space_time_table.get(time_step + 1, [])
+            
+            # 鏋勫缓褰撳墠鍜屼笅涓�鏃跺埢鐨勪綅缃槧灏�
+            current_positions = {node.agv_id: node.position for node in current_nodes}
+            next_positions = {node.agv_id: node.position for node in next_nodes}
+            
+            # 妫�鏌ユ槸鍚︽湁AGV浜ゆ崲浣嶇疆
+            for agv1, pos1_current in current_positions.items():
+                for agv2, pos2_current in current_positions.items():
+                    if agv1 >= agv2:  # 閬垮厤閲嶅妫�鏌�
+                        continue
+                    
+                    pos1_next = next_positions.get(agv1)
+                    pos2_next = next_positions.get(agv2)
+                    
+                    if (pos1_next and pos2_next and 
+                        pos1_current == pos2_next and pos2_current == pos1_next):
+                        # 鍙戠幇杈瑰啿绐�
+                        conflict = Conflict(
+                            type="edge",
+                            agv1=agv1,
+                            agv2=agv2,
+                            time_step=time_step,
+                            position1=pos1_current,
+                            position2=pos2_current,
+                            description=f"AGV {agv1} 鍜� {agv2} 鍦ㄦ椂闂� {time_step}-{time_step+1} 浜ゆ崲浣嶇疆 {pos1_current}<->{pos2_current}"
+                        )
+                        conflicts.append(conflict)
+        
+        return conflicts
+    
+    def _detect_following_conflicts(self, space_time_table: Dict[int, List[SpaceTimeNode]]) -> List[Conflict]:
+        """妫�娴嬭窡闅忓啿绐侊紙AGV璺濈杩囪繎锛�"""
+        conflicts = []
+        
+        for time_step, nodes in space_time_table.items():
+            # 妫�鏌ユ墍鏈堿GV瀵逛箣闂寸殑璺濈
+            for i in range(len(nodes)):
+                for j in range(i + 1, len(nodes)):
+                    node1, node2 = nodes[i], nodes[j]
+                    
+                    # 璁$畻娆у嚑閲屽緱璺濈
+                    distance = math.sqrt(
+                        (node1.coordinates[0] - node2.coordinates[0]) ** 2 +
+                        (node1.coordinates[1] - node2.coordinates[1]) ** 2
+                    )
+                    
+                    if distance < self.min_distance and distance > 0:
+                        conflict = Conflict(
+                            type="follow",
+                            agv1=node1.agv_id,
+                            agv2=node2.agv_id,
+                            time_step=time_step,
+                            position1=node1.position,
+                            position2=node2.position,
+                            description=f"AGV {node1.agv_id} 鍜� {node2.agv_id} 鍦ㄦ椂闂� {time_step} 璺濈杩囪繎 ({distance:.2f} < {self.min_distance})"
+                        )
+                        conflicts.append(conflict)
+        
+        return conflicts
+
+
+class CollisionResolver:
+    """AGV璺緞纰版挒瑙e喅鍣�"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]], detector: CollisionDetector, agv_manager=None):
+        """
+        鍒濆鍖栫鎾炶В鍐冲櫒
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+            detector: 纰版挒妫�娴嬪櫒
+            agv_manager: AGV绠$悊鍣紝鐢ㄤ簬鑾峰彇AGV鐘舵�佷俊鎭�
+        """
+        self.path_mapping = path_mapping
+        self.detector = detector
+        self.agv_manager = agv_manager
+        self.logger = logging.getLogger(__name__)
+    
+    def evaluate_agv_priority(self, agv_id: str, path: Dict, executing_tasks: List[Dict] = None) -> AGVPriority:
+        """
+        璇勪及AGV鐨勯伩璁╀紭鍏堢骇
+        
+        Args:
+            agv_id: AGV ID
+            path: AGV璺緞淇℃伅
+            executing_tasks: 鎵ц涓殑浠诲姟鍒楄〃
+            
+        Returns:
+            AGVPriority: AGV浼樺厛绾ц瘎浼扮粨鏋�
+        """
+        # 榛樿鍊�
+        task_status = "idle"
+        action_type = "unknown"
+        task_priority = 1
+        voltage = 100
+        priority_score = 0.0
+        explanation_parts = []
+        
+        # 鑾峰彇AGV鐘舵�佷俊鎭�
+        agv_model = None
+        if self.agv_manager:
+            agv_model = self.agv_manager.get_agv_by_id(agv_id)
+            if agv_model:
+                voltage = agv_model.voltage
+                
+        # 浠庤矾寰勪俊鎭腑鑾峰彇鍔ㄤ綔绫诲瀷
+        code_list = path.get('codeList', [])
+        if code_list:
+            first_code = code_list[0]
+            if isinstance(first_code, dict):
+                action_type = first_code.get('type', 'unknown')
+                
+        # 浠庢墽琛屼腑浠诲姟鑾峰彇浠诲姟鐘舵�佸拰浼樺厛绾�
+        if executing_tasks:
+            for task in executing_tasks:
+                if task.get('agvId') == agv_id:
+                    task_status = task.get('status', 'idle')
+                    # 灏濊瘯浠庝换鍔D鑾峰彇浼樺厛绾э紙绠�鍖栧鐞嗭級
+                    task_id = task.get('taskId', '')
+                    if 'HIGH_PRIORITY' in task_id:
+                        task_priority = 10
+                    elif 'PRIORITY' in task_id:
+                        task_priority = 8
+                    else:
+                        task_priority = 5
+                    break
+        
+        # 璁$畻浼樺厛绾у垎鏁帮紙鍒嗘暟瓒婇珮浼樺厛绾ц秺楂橈紝瓒婁笉瀹规槗璁╂锛�
+        priority_score = 0.0
+        
+        # 1. 浠诲姟鐘舵�佷紭鍏堢骇 (40%鏉冮噸)
+        if task_status == "executing":
+            priority_score += 40.0
+            explanation_parts.append("鎵ц浠诲姟涓�(+40)")
+        elif task_status == "assigned":
+            priority_score += 20.0
+            explanation_parts.append("宸插垎閰嶄换鍔�(+20)")
+        else:
+            priority_score += 5.0
+            explanation_parts.append("绌洪棽鐘舵��(+5)")
+        
+        # 2. 鍔ㄤ綔绫诲瀷浼樺厛绾� (30%鏉冮噸)
+        if action_type == AGVActionTypeEnum.TASK.value:
+            priority_score += 30.0
+            explanation_parts.append("浠诲姟琛屼负(+30)")
+        elif action_type == AGVActionTypeEnum.CHARGING.value:
+            priority_score += 25.0
+            explanation_parts.append("鍏呯數琛屼负(+25)")
+        elif action_type == AGVActionTypeEnum.AVOIDANCE.value:
+            priority_score += 5.0
+            explanation_parts.append("閬胯琛屼负(+5)")
+        elif action_type == AGVActionTypeEnum.STANDBY.value:
+            priority_score += 10.0
+            explanation_parts.append("寰呮満琛屼负(+10)")
+        else:
+            priority_score += 15.0
+            explanation_parts.append("鏈煡琛屼负(+15)")
+        
+        # 3. 浠诲姟浼樺厛绾� (20%鏉冮噸)
+        task_priority_score = (task_priority / 10.0) * 20.0
+        priority_score += task_priority_score
+        explanation_parts.append(f"浠诲姟浼樺厛绾task_priority}(+{task_priority_score:.1f})")
+        
+        # 4. 鐢甸噺鐘舵�� (10%鏉冮噸)
+        if voltage <= 10:  # 蹇呴』鍏呯數
+            priority_score += 10.0
+            explanation_parts.append("鐢甸噺鍗遍櫓(+10)")
+        elif voltage <= 20:  # 鍙嚜鍔ㄥ厖鐢�
+            priority_score += 8.0
+            explanation_parts.append("鐢甸噺鍋忎綆(+8)")
+        elif voltage <= 50:
+            priority_score += 5.0
+            explanation_parts.append("鐢甸噺涓�鑸�(+5)")
+        else:
+            priority_score += 2.0
+            explanation_parts.append("鐢甸噺鍏呰冻(+2)")
+        
+        explanation = f"鎬诲垎{priority_score:.1f}: " + ", ".join(explanation_parts)
+        
+        return AGVPriority(
+            agv_id=agv_id,
+            priority_score=priority_score,
+            task_status=task_status,
+            action_type=action_type,
+            task_priority=task_priority,
+            voltage=voltage,
+            explanation=explanation
+        )
+    
+    def resolve_conflicts(self, planned_paths: List[Dict], conflicts: List[Conflict], executing_tasks: List[Dict] = None) -> List[Dict]:
+        """
+        瑙e喅鍐茬獊
+        
+        Args:
+            planned_paths: 鍘熷瑙勫垝璺緞
+            conflicts: 鍐茬獊鍒楄〃
+            executing_tasks: 鎵ц涓殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[Dict]: 瑙e喅鍐茬獊鍚庣殑璺緞
+        """
+        if not conflicts:
+            return planned_paths
+        
+        resolved_paths = [path.copy() for path in planned_paths]
+        
+        # 鎸夋椂闂存鎺掑簭鍐茬獊锛屼紭鍏堣В鍐虫棭鏈熷啿绐�
+        conflicts_sorted = sorted(conflicts, key=lambda c: c.time_step)
+        
+        for conflict in conflicts_sorted:
+            resolved_paths = self._resolve_single_conflict(resolved_paths, conflict, executing_tasks)
+        
+        self.logger.info(f"瑙e喅浜� {len(conflicts)} 涓矾寰勫啿绐�")
+        return resolved_paths
+    
+    def _resolve_single_conflict(self, paths: List[Dict], conflict: Conflict, executing_tasks: List[Dict] = None) -> List[Dict]:
+        """
+        瑙e喅鍗曚釜鍐茬獊
+        
+        Args:
+            paths: 褰撳墠璺緞鍒楄〃
+            conflict: 鍐茬獊
+            executing_tasks: 鎵ц涓殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[Dict]: 鏇存柊鍚庣殑璺緞鍒楄〃
+        """
+        if conflict.type == "vertex":
+            return self._resolve_vertex_conflict(paths, conflict, executing_tasks)
+        elif conflict.type == "edge":
+            return self._resolve_edge_conflict(paths, conflict, executing_tasks)
+        elif conflict.type == "follow":
+            return self._resolve_following_conflict(paths, conflict, executing_tasks)
+        
+        return paths
+    
+    def _resolve_vertex_conflict(self, paths: List[Dict], conflict: Conflict, executing_tasks: List[Dict] = None) -> List[Dict]:
+        """瑙e喅椤剁偣鍐茬獊 - 鍩轰簬浼樺厛绾ц瘎浼伴�夋嫨璁╂鐨凙GV"""
+        updated_paths = paths.copy()
+        
+        # 鎵惧埌鍐茬獊鐨凙GV璺緞
+        agv1_path = None
+        agv2_path = None
+        agv1_index = agv2_index = -1
+        
+        for i, path in enumerate(updated_paths):
+            if path.get('agvId') == conflict.agv1:
+                agv1_path = path
+                agv1_index = i
+            elif path.get('agvId') == conflict.agv2:
+                agv2_path = path
+                agv2_index = i
+        
+        if not agv1_path or not agv2_path:
+            return updated_paths
+        
+        # 璇勪及涓や釜AGV鐨勪紭鍏堢骇
+        agv1_priority = self.evaluate_agv_priority(conflict.agv1, agv1_path, executing_tasks)
+        agv2_priority = self.evaluate_agv_priority(conflict.agv2, agv2_path, executing_tasks)
+        
+        # 閫夋嫨浼樺厛绾ц緝浣庣殑AGV杩涜绛夊緟
+        if agv1_priority.priority_score <= agv2_priority.priority_score:
+            waiting_agv_path = agv1_path
+            waiting_agv_index = agv1_index
+            waiting_agv_id = conflict.agv1
+            higher_priority_agv_id = conflict.agv2
+        else:
+            waiting_agv_path = agv2_path
+            waiting_agv_index = agv2_index
+            waiting_agv_id = conflict.agv2
+            higher_priority_agv_id = conflict.agv1
+        
+        # 璁板綍璇︾粏鐨勯伩璁╁喅绛栦俊鎭�
+        self.logger.info(f"椤剁偣鍐茬獊閬胯鍐崇瓥 - 浣嶇疆: {conflict.position1}, 鏃堕棿: {conflict.time_step}")
+        self.logger.info(f"  AGV {conflict.agv1}: {agv1_priority.explanation}")
+        self.logger.info(f"  AGV {conflict.agv2}: {agv2_priority.explanation}")
+        self.logger.info(f"  鍐崇瓥: AGV {waiting_agv_id} 璁╂缁� AGV {higher_priority_agv_id}")
+        
+        # 鍦ㄥ啿绐佷綅缃箣鍓嶆彃鍏ョ瓑寰呮楠�
+        self._insert_wait_step(waiting_agv_path, conflict.time_step)
+        updated_paths[waiting_agv_index] = waiting_agv_path
+        
+        return updated_paths
+    
+    def _resolve_edge_conflict(self, paths: List[Dict], conflict: Conflict, executing_tasks: List[Dict] = None) -> List[Dict]:
+        """瑙e喅杈瑰啿绐� - 鍩轰簬浼樺厛绾ц瘎浼伴�夋嫨璁╂鐨凙GV"""
+        updated_paths = paths.copy()
+        
+        # 鎵惧埌鍐茬獊鐨凙GV璺緞
+        agv1_path = None
+        agv2_path = None
+        agv1_index = agv2_index = -1
+        
+        for i, path in enumerate(updated_paths):
+            if path.get('agvId') == conflict.agv1:
+                agv1_path = path
+                agv1_index = i
+            elif path.get('agvId') == conflict.agv2:
+                agv2_path = path
+                agv2_index = i
+        
+        if not agv1_path or not agv2_path:
+            return updated_paths
+        
+        # 璇勪及涓や釜AGV鐨勪紭鍏堢骇
+        agv1_priority = self.evaluate_agv_priority(conflict.agv1, agv1_path, executing_tasks)
+        agv2_priority = self.evaluate_agv_priority(conflict.agv2, agv2_path, executing_tasks)
+        
+        # 閫夋嫨浼樺厛绾ц緝浣庣殑AGV杩涜绛夊緟
+        if agv1_priority.priority_score <= agv2_priority.priority_score:
+            waiting_agv_path = agv1_path
+            waiting_agv_index = agv1_index
+            waiting_agv_id = conflict.agv1
+            higher_priority_agv_id = conflict.agv2
+        else:
+            waiting_agv_path = agv2_path
+            waiting_agv_index = agv2_index
+            waiting_agv_id = conflict.agv2
+            higher_priority_agv_id = conflict.agv1
+        
+        # 璁板綍璇︾粏鐨勯伩璁╁喅绛栦俊鎭�
+        self.logger.info(f"杈瑰啿绐侀伩璁╁喅绛� - 浣嶇疆浜ゆ崲: {conflict.position1}<->{conflict.position2}, 鏃堕棿: {conflict.time_step}")
+        self.logger.info(f"  AGV {conflict.agv1}: {agv1_priority.explanation}")
+        self.logger.info(f"  AGV {conflict.agv2}: {agv2_priority.explanation}")
+        self.logger.info(f"  鍐崇瓥: AGV {waiting_agv_id} 璁╂缁� AGV {higher_priority_agv_id}")
+        
+        # 鍦ㄥ啿绐佷綅缃箣鍓嶆彃鍏ョ瓑寰呮楠�
+        self._insert_wait_step(waiting_agv_path, conflict.time_step)
+        updated_paths[waiting_agv_index] = waiting_agv_path
+        
+        return updated_paths
+    
+    def _resolve_following_conflict(self, paths: List[Dict], conflict: Conflict, executing_tasks: List[Dict] = None) -> List[Dict]:
+        """瑙e喅璺熼殢鍐茬獊 - 鍩轰簬浼樺厛绾ц瘎浼伴�夋嫨璁╂鐨凙GV"""
+        updated_paths = paths.copy()
+        
+        # 鎵惧埌鍐茬獊鐨凙GV璺緞
+        agv1_path = None
+        agv2_path = None
+        agv1_index = agv2_index = -1
+        
+        for i, path in enumerate(updated_paths):
+            if path.get('agvId') == conflict.agv1:
+                agv1_path = path
+                agv1_index = i
+            elif path.get('agvId') == conflict.agv2:
+                agv2_path = path
+                agv2_index = i
+        
+        if not agv1_path or not agv2_path:
+            return updated_paths
+        
+        # 璇勪及涓や釜AGV鐨勪紭鍏堢骇
+        agv1_priority = self.evaluate_agv_priority(conflict.agv1, agv1_path, executing_tasks)
+        agv2_priority = self.evaluate_agv_priority(conflict.agv2, agv2_path, executing_tasks)
+        
+        # 閫夋嫨浼樺厛绾ц緝浣庣殑AGV杩涜绛夊緟
+        if agv1_priority.priority_score <= agv2_priority.priority_score:
+            waiting_agv_path = agv1_path
+            waiting_agv_index = agv1_index
+            waiting_agv_id = conflict.agv1
+            higher_priority_agv_id = conflict.agv2
+        else:
+            waiting_agv_path = agv2_path
+            waiting_agv_index = agv2_index
+            waiting_agv_id = conflict.agv2
+            higher_priority_agv_id = conflict.agv1
+        
+        # 璁板綍璇︾粏鐨勯伩璁╁喅绛栦俊鎭�
+        self.logger.info(f"璺熼殢鍐茬獊閬胯鍐崇瓥 - 璺濈杩囪繎, 鏃堕棿: {conflict.time_step}")
+        self.logger.info(f"  AGV {conflict.agv1} (浣嶇疆: {conflict.position1}): {agv1_priority.explanation}")
+        self.logger.info(f"  AGV {conflict.agv2} (浣嶇疆: {conflict.position2}): {agv2_priority.explanation}")
+        self.logger.info(f"  鍐崇瓥: AGV {waiting_agv_id} 璁╂缁� AGV {higher_priority_agv_id}")
+        
+        # 鍦ㄥ啿绐佷綅缃箣鍓嶆彃鍏ョ瓑寰呮楠�
+        self._insert_wait_step(waiting_agv_path, conflict.time_step)
+        updated_paths[waiting_agv_index] = waiting_agv_path
+        
+        return updated_paths
+    
+    def _insert_wait_step(self, path: Dict, time_step: int):
+        """
+        鍦ㄦ寚瀹氭椂闂存鎻掑叆绛夊緟姝ラ
+        
+        Args:
+            path: AGV璺緞
+            time_step: 鎻掑叆浣嶇疆鐨勬椂闂存
+        """
+        code_list = path.get('codeList', [])
+        
+        if time_step < len(code_list) and time_step > 0:
+            # 鍦ㄦ寚瀹氫綅缃彃鍏ョ瓑寰呮楠わ紙閲嶅鍓嶄竴涓綅缃級
+            prev_code = code_list[time_step - 1]
+            
+            # 纭繚澶嶅埗鎵�鏈夊瓧娈�
+            if isinstance(prev_code, dict):
+                wait_code = prev_code.copy()
+            else:
+                wait_code = {
+                    'code': prev_code.code,
+                    'direction': prev_code.direction
+                }
+            
+            code_list.insert(time_step, wait_code)
+            path['codeList'] = code_list
+    
+    def validate_four_direction_movement(self, planned_paths: List[Dict]) -> List[Dict]:
+        """
+        楠岃瘉骞朵慨姝h矾寰勶紝纭繚AGV鍙兘浠�0銆�90銆�180銆�270搴︾Щ鍔�
+        
+        Args:
+            planned_paths: 瑙勫垝璺緞鍒楄〃
+            
+        Returns:
+            List[Dict]: 淇鍚庣殑璺緞鍒楄〃
+        """
+        validated_paths = []
+        
+        for path_data in planned_paths:
+            validated_path = self._validate_single_path_directions(path_data)
+            validated_paths.append(validated_path)
+        
+        return validated_paths
+    
+    def _validate_single_path_directions(self, path_data: Dict) -> Dict:
+        """
+        楠岃瘉鍗曚釜璺緞鐨勭Щ鍔ㄦ柟鍚�
+        
+        Args:
+            path_data: 鍗曚釜AGV璺緞鏁版嵁
+            
+        Returns:
+            Dict: 淇鍚庣殑璺緞鏁版嵁
+        """
+        validated_path = path_data.copy()
+        code_list = path_data.get('codeList', [])
+        
+        if len(code_list) < 2:
+            return validated_path
+        
+        validated_code_list = []
+        
+        for i in range(len(code_list)):
+            current_code = code_list[i]
+            
+            if isinstance(current_code, dict):
+                position = current_code.get('code', '')
+                direction = current_code.get('direction', '90')
+                
+                # 淇濈暀鍘熸湁鐨勬墍鏈夊瓧娈�
+                validated_code = current_code.copy()
+            else:
+                position = current_code.code
+                direction = current_code.direction
+                
+                # 杞崲涓哄瓧鍏告牸寮忓苟淇濈暀鍩烘湰瀛楁
+                validated_code = {
+                    'code': position,
+                    'direction': direction
+                }
+            
+            # 濡傛灉涓嶆槸绗竴涓偣锛岃绠楁纭殑鏂瑰悜
+            if i > 0:
+                prev_code = code_list[i - 1]
+                prev_position = prev_code.get('code', '') if isinstance(prev_code, dict) else prev_code.code
+                
+                # 璁$畻绉诲姩鏂瑰悜
+                correct_direction = self._calculate_movement_direction(prev_position, position)
+                if correct_direction:
+                    direction = correct_direction
+            
+            # 纭繚鏂瑰悜鏄湁鏁堢殑鍥涙柟鍚戜箣涓�
+            direction = self._normalize_direction(direction)
+            
+            # 鏇存柊鏂瑰悜锛屼繚鐣欏叾浠栨墍鏈夊瓧娈�
+            validated_code['direction'] = direction
+            validated_code_list.append(validated_code)
+        
+        validated_path['codeList'] = validated_code_list
+        return validated_path
+    
+    def _calculate_movement_direction(self, from_position: str, to_position: str) -> Optional[str]:
+        """
+        璁$畻浠庝竴涓綅缃埌鍙︿竴涓綅缃殑绉诲姩鏂瑰悜
+        
+        Args:
+            from_position: 璧峰浣嶇疆鐮�
+            to_position: 鐩爣浣嶇疆鐮�
+            
+        Returns:
+            Optional[str]: 绉诲姩鏂瑰悜锛�0, 90, 180, 270锛�
+        """
+        from_coord = get_coordinate_from_path_id(from_position, self.path_mapping)
+        to_coord = get_coordinate_from_path_id(to_position, self.path_mapping)
+        
+        if not from_coord or not to_coord:
+            return None
+        
+        dx = to_coord[0] - from_coord[0]
+        dy = to_coord[1] - from_coord[1]
+        
+        # 鍙厑璁稿洓涓柟鍚戠殑绉诲姩
+        if dx > 0 and dy == 0:
+            return "0"    # 鍚戜笢
+        elif dx < 0 and dy == 0:
+            return "180"  # 鍚戣タ
+        elif dx == 0 and dy > 0:
+            return "90"   # 鍚戝崡
+        elif dx == 0 and dy < 0:
+            return "270"  # 鍚戝寳
+        else:
+            # 涓嶆槸鏍囧噯鍥涙柟鍚戠Щ鍔紝杩斿洖榛樿鏂瑰悜
+            return "90"
+    
+    def _normalize_direction(self, direction: str) -> str:
+        """
+        鏍囧噯鍖栨柟鍚戝�硷紝纭繚鍙湁0銆�90銆�180銆�270
+        
+        Args:
+            direction: 鍘熷鏂瑰悜鍊�
+            
+        Returns:
+            str: 鏍囧噯鍖栧悗鐨勬柟鍚戝��
+        """
+        try:
+            angle = int(direction) % 360
+            
+            # 灏嗚搴︽槧灏勫埌鏈�杩戠殑鍥涙柟鍚�
+            if angle <= 45 or angle > 315:
+                return "0"
+            elif 45 < angle <= 135:
+                return "90"
+            elif 135 < angle <= 225:
+                return "180"
+            else:
+                return "270"
+        except:
+            return "90"  # 榛樿鏂瑰悜 
\ No newline at end of file
diff --git a/algorithm_system/algorithms/path_planning.py b/algorithm_system/algorithms/path_planning.py
new file mode 100644
index 0000000..8820f7a
--- /dev/null
+++ b/algorithm_system/algorithms/path_planning.py
@@ -0,0 +1,1131 @@
+"""
+璺緞瑙勫垝绠楁硶
+"""
+import heapq
+import random
+import math
+import time
+import logging
+from typing import Dict, List, Tuple, Optional, Set, Any
+from collections import defaultdict, deque
+
+from common.data_models import PlannedPath, PathCode, AGVStatus, BackpackData
+from common.utils import get_coordinate_from_path_id, calculate_distance, calculate_manhattan_distance, generate_segment_id, generate_navigation_code
+from algorithm_system.algorithms.collision_detection import CollisionDetector, CollisionResolver
+
+
+class ExecutingTaskExtractor:
+    """鎵ц涓换鍔℃彁鍙栧櫒"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]]):
+        """
+        鍒濆鍖栦换鍔℃彁鍙栧櫒
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+        """
+        self.path_mapping = path_mapping
+        self.logger = logging.getLogger(__name__)
+        
+        # 棰勮绠楀潗鏍囨槧灏�
+        self.coord_to_code = {(data['x'], data['y']): code for code, data in path_mapping.items()}
+        
+        # 棰勫垎绫讳綅缃被鍨�
+        self.pickup_positions = [pos for pos in path_mapping.keys() if pos.startswith("1")]
+        self.charging_positions = [pos for pos in path_mapping.keys() if pos.startswith("2")]
+        self.delivery_positions = [pos for pos in path_mapping.keys() if pos.startswith("3")]
+        self.standby_positions = [pos for pos in path_mapping.keys() if pos.startswith("4")]
+    
+    def extract_optimized_executing_tasks(self, agv_status_list: List[AGVStatus]) -> List[Dict]:
+        """鏅鸿兘鎻愬彇AGV鎵ц浠诲姟"""
+        executing_tasks = []
+        
+        for agv_status in agv_status_list:
+            agv_id = agv_status.agvId
+            current_position = agv_status.position
+            
+            if not agv_status.backpack:
+                continue
+                
+            optimized_task = self._analyze_all_backpack_tasks(
+                agv_id, current_position, agv_status.backpack, agv_status
+            )
+            
+            if optimized_task:
+                executing_tasks.append(optimized_task)
+                
+        self.logger.info(f"鏅鸿兘鍒嗘瀽 {len(executing_tasks)} 涓狝GV鐨勮儗绡撲换鍔″苟鐢熸垚鏈�浼樿矾寰�")
+        return executing_tasks
+    
+    def _analyze_all_backpack_tasks(self, agv_id: str, current_position: str, 
+                                   backpack: List[BackpackData], agv_status: AGVStatus) -> Optional[Dict]:
+        """
+        鍒嗘瀽鎵�鏈夎儗绡撲换鍔★紝纭畾鏈�浼樻墽琛岀瓥鐣�
+        """
+        # 1. 鎻愬彇骞跺垎绫绘墍鏈夋湁鏁堜换鍔�
+        loaded_tasks = []      # 宸茶杞界殑浠诲姟
+        unloaded_tasks = []    # 鏈杞界殑浠诲姟
+        all_tasks = []         # 鎵�鏈変换鍔�
+        
+        self.logger.debug(f"[AGV {agv_id}] 寮�濮嬪垎鏋愯儗绡撲换鍔★紝浣嶇疆: {current_position}")
+        
+        for i, bp in enumerate(backpack):
+            self.logger.debug(f"[AGV {agv_id}] 鑳岀瘬浣嶇疆{i+1}: taskId={bp.taskId}, loaded={bp.loaded}, execute={bp.execute}")
+            
+            if not bp.taskId:
+                self.logger.debug(f"[AGV {agv_id}] 鑳岀瘬浣嶇疆{i+1}: 璺宠繃锛堟棤浠诲姟ID锛�")
+                continue
+                
+            # 灏濊瘯瑙f瀽浠诲姟璇︽儏
+            task_info = self._parse_task_details(bp.taskId, current_position)
+            if not task_info:
+                self.logger.warning(f"[AGV {agv_id}] 浠诲姟 {bp.taskId} 瑙f瀽澶辫触锛岃烦杩�")
+                continue
+                
+            task_data = {
+                'backpack_item': bp,
+                'task_info': task_info,
+                'distance_to_start': task_info.get('distance_to_start', float('inf')),
+                'distance_to_end': task_info.get('distance_to_end', float('inf'))
+            }
+            
+            all_tasks.append(task_data)
+            
+            if bp.loaded:
+                loaded_tasks.append(task_data)
+                self.logger.debug(f"[AGV {agv_id}] 浠诲姟 {bp.taskId} 宸茶杞斤紝璺濈缁堢偣: {task_info.get('distance_to_end', 'N/A')}")
+            else:
+                unloaded_tasks.append(task_data)
+                self.logger.debug(f"[AGV {agv_id}] 浠诲姟 {bp.taskId} 鏈杞斤紝璺濈璧风偣: {task_info.get('distance_to_start', 'N/A')}")
+        
+        self.logger.debug(f"[AGV {agv_id}] 浠诲姟鍒嗘瀽缁撴灉: 鎬讳换鍔�={len(all_tasks)}, 宸茶杞�={len(loaded_tasks)}, 鏈杞�={len(unloaded_tasks)}")
+        
+        # 2. 濡傛灉娌℃湁浠讳綍浠诲姟锛岃繑鍥濶one
+        if not all_tasks:
+            self.logger.debug(f"[AGV {agv_id}] 娌℃湁鏈夋晥浠诲姟锛岃繑鍥濶one")
+            return None
+            
+        # 3. 鍐崇瓥鏈�浼樿矾寰勭瓥鐣�
+        optimal_strategy = self._determine_next_best_action(
+            loaded_tasks, unloaded_tasks, current_position
+        )
+        
+        if not optimal_strategy:
+            self.logger.debug(f"[AGV {agv_id}] 鍐崇瓥杩斿洖None锛屾病鏈夋渶浼樼瓥鐣�")
+            return None
+            
+        self.logger.debug(f"[AGV {agv_id}] 鍐崇瓥瀹屾垚: {optimal_strategy['strategy']} - {optimal_strategy['action']}")
+        self.logger.debug(f"[AGV {agv_id}] 鐩爣浣嶇疆: {optimal_strategy['target_position']}")
+        self.logger.debug(f"[AGV {agv_id}] 鍐崇瓥鍘熷洜: {optimal_strategy.get('reason', 'N/A')}")
+            
+        # 4. 鏋勫缓浠诲姟淇℃伅
+        result = {
+            'agvId': agv_id,
+            'currentPosition': current_position,
+            'strategy': optimal_strategy['strategy'],
+            'next_action': optimal_strategy['action'],
+            'target_position': optimal_strategy['target_position'],
+            'primary_task': optimal_strategy['selected_task'],
+            'all_loaded_tasks': loaded_tasks,
+            'all_unloaded_tasks': unloaded_tasks,
+            'total_tasks_count': len(all_tasks),
+            'estimated_efficiency': optimal_strategy.get('efficiency_score', 0),
+            'decision_reason': optimal_strategy.get('reason', ''),
+            'agvDirection': agv_status.direction,
+            'agvVoltage': agv_status.vol,
+            'agvError': agv_status.error
+        }
+        
+        self.logger.debug(f"[AGV {agv_id}] 鏈�缁堜换鍔′俊鎭瀯寤哄畬鎴愶紝杩斿洖缁撴灉")
+        return result
+    
+    def _determine_next_best_action(self, loaded_tasks: List[Dict], 
+                                   unloaded_tasks: List[Dict], current_position: str) -> Optional[Dict]:
+        """
+        纭畾AGV涓嬩竴姝ユ渶浼樿鍔�
+        
+        Args:
+            loaded_tasks: 宸茶杞界殑浠诲姟
+            unloaded_tasks: 鏈杞界殑浠诲姟
+            current_position: 褰撳墠浣嶇疆
+            
+        Returns:
+            Optional[Dict]: 鏈�浼樿鍔ㄧ瓥鐣�
+        """
+        # 榛樿绛栫暐锛氱患鍚堜紭鍖栧喅绛�
+        # 1. 濡傛灉鏈夊凡瑁呰浇浠诲姟锛屼紭鍏堥�佽揣
+        if loaded_tasks:
+            nearest_delivery = min(loaded_tasks, key=lambda t: t['distance_to_end'])
+            
+            # 2. 濡傛灉涔熸湁鏈杞戒换鍔★紝姣旇緝璺濈鍐崇瓥
+            if unloaded_tasks:
+                nearest_pickup = min(unloaded_tasks, key=lambda t: t['distance_to_start'])
+                
+                # 缁煎悎浼樺寲绛栫暐锛氬鏋滃彇璐х偣鏄捐憲鏇磋繎锛屼紭鍏堝彇璐э紱鍚﹀垯浼樺厛閫佽揣
+                if nearest_pickup['distance_to_start'] * 1.5 < nearest_delivery['distance_to_end']:
+                    return {
+                        'strategy': 'comprehensive_optimization',
+                        'action': 'pickup',
+                        'selected_task': nearest_pickup,
+                        'target_position': nearest_pickup['task_info']['start_position'],
+                        'efficiency_score': self._calculate_pickup_efficiency(nearest_pickup, current_position),
+                        'reason': f"缁煎悎浼樺寲锛氬彇璐х偣({nearest_pickup['distance_to_start']})姣旈�佽揣鐐�({nearest_delivery['distance_to_end']})鏄捐憲鏇磋繎"
+                    }
+                else:
+                    return {
+                        'strategy': 'comprehensive_optimization',
+                        'action': 'deliver',
+                        'selected_task': nearest_delivery,
+                        'target_position': nearest_delivery['task_info']['end_position'],
+                        'efficiency_score': self._calculate_delivery_efficiency(nearest_delivery, current_position),
+                        'reason': f"缁煎悎浼樺寲锛氫紭鍏堥�佽揪宸茶杞借揣鐗╋紝閫佽揣璺濈{nearest_delivery['distance_to_end']}"
+                    }
+            else:
+                # 鍙湁宸茶杞戒换鍔★紝鐩存帴閫佽揣
+                return {
+                    'strategy': 'comprehensive_optimization',
+                    'action': 'deliver',
+                    'selected_task': nearest_delivery,
+                    'target_position': nearest_delivery['task_info']['end_position'],
+                    'efficiency_score': self._calculate_delivery_efficiency(nearest_delivery, current_position),
+                    'reason': f"缁煎悎浼樺寲锛氶�佽揪鍞竴宸茶杞借揣鐗╋紝璺濈{nearest_delivery['distance_to_end']}"
+                }
+        
+        # 3. 濡傛灉鍙湁鏈杞戒换鍔★紝鍙栬揣
+        elif unloaded_tasks:
+            nearest_pickup = min(unloaded_tasks, key=lambda t: t['distance_to_start'])
+            return {
+                'strategy': 'comprehensive_optimization',
+                'action': 'pickup',
+                'selected_task': nearest_pickup,
+                'target_position': nearest_pickup['task_info']['start_position'],
+                'efficiency_score': self._calculate_pickup_efficiency(nearest_pickup, current_position),
+                'reason': f"缁煎悎浼樺寲锛氬彇璐у敮涓�鏈杞戒换鍔★紝璺濈{nearest_pickup['distance_to_start']}"
+            }
+        
+        # 4. 娌℃湁浠诲姟
+        return None
+    
+    def _parse_task_details(self, task_id: str, current_position: str) -> Optional[Dict]:
+        """
+        瑙f瀽浠诲姟璇︾粏淇℃伅锛屽寘鎷捣缁堢偣鍜岃窛绂�
+        
+        Args:
+            task_id: 浠诲姟ID
+            current_position: 褰撳墠浣嶇疆
+            
+        Returns:
+            Optional[Dict]: 浠诲姟璇︾粏淇℃伅
+        """
+        self.logger.debug(f"寮�濮嬭В鏋愪换鍔� {task_id}锛屽綋鍓嶄綅缃�: {current_position}")
+        
+        start_pos, end_pos = self._fast_parse_task_start_end(task_id)
+        
+        if not start_pos or not end_pos:
+            self.logger.warning(f"浠诲姟 {task_id} 瑙f瀽澶辫触: start_pos={start_pos}, end_pos={end_pos}")
+            return None
+            
+        self.logger.debug(f"浠诲姟 {task_id} 瑙f瀽鎴愬姛: start={start_pos}, end={end_pos}")
+        
+        # 璁$畻璺濈
+        current_coord = get_coordinate_from_path_id(current_position, self.path_mapping)
+        start_coord = get_coordinate_from_path_id(start_pos, self.path_mapping) 
+        end_coord = get_coordinate_from_path_id(end_pos, self.path_mapping)
+        
+        if not all([current_coord, start_coord, end_coord]):
+            return None
+            
+        distance_to_start = calculate_manhattan_distance(current_coord, start_coord)
+        distance_to_end = calculate_manhattan_distance(current_coord, end_coord)
+        
+        return {
+            'task_id': task_id,
+            'start_position': start_pos,
+            'end_position': end_pos,
+            'distance_to_start': distance_to_start,
+            'distance_to_end': distance_to_end,
+            'start_coord': start_coord,
+            'end_coord': end_coord
+        }
+    
+    def _calculate_delivery_efficiency(self, task_data: Dict, current_position: str) -> float:
+        """
+        璁$畻閫佽揣鏁堢巼鍒嗘暟
+        
+        Args:
+            task_data: 浠诲姟鏁版嵁
+            current_position: 褰撳墠浣嶇疆
+            
+        Returns:
+            float: 鏁堢巼鍒嗘暟 (0-10)
+        """
+        distance = task_data['distance_to_end']
+        
+        # 璺濈瓒婅繎鏁堢巼瓒婇珮
+        distance_score = max(0, 10 - distance / 5)
+        
+        # 宸茶杞界殑浠诲姟鏈夐澶栧鍔�
+        loaded_bonus = 3.0 if task_data['backpack_item'].loaded else 0
+        
+        return distance_score + loaded_bonus
+    
+    def _calculate_pickup_efficiency(self, task_data: Dict, current_position: str) -> float:
+        """
+        璁$畻鍙栬揣鏁堢巼鍒嗘暟
+        
+        Args:
+            task_data: 浠诲姟鏁版嵁
+            current_position: 褰撳墠浣嶇疆
+            
+        Returns:
+            float: 鏁堢巼鍒嗘暟 (0-10)
+        """
+        distance_to_start = task_data['distance_to_start']
+        
+        # 璺濈瓒婅繎鏁堢巼瓒婇珮
+        distance_score = max(0, 10 - distance_to_start / 3)
+        
+        # 寰堣繎鐨勫彇璐х偣鏈夐珮濂栧姳
+        if distance_to_start <= 3:
+            distance_score += 5.0
+        elif distance_to_start <= 5:
+            distance_score += 2.0
+            
+        return distance_score
+    
+    def _fast_parse_task_start_end(self, task_id: str) -> Tuple[Optional[str], Optional[str]]:
+        """
+        瑙f瀽浠诲姟璧风偣鍜岀粓鐐�
+        鏀寔涓ょ鏍煎紡锛�
+        1. 鏍囧噯鏍煎紡锛歺xx_start_end
+        2. 绠�鍗曟牸寮忥細鏁板瓧ID锛堥�氳繃hash鍒嗛厤浣嶇疆锛�
+        
+        Args:
+            task_id: 浠诲姟ID
+            
+        Returns:
+            Tuple[Optional[str], Optional[str]]: (璧风偣, 缁堢偣)
+        """
+        self.logger.debug(f"瑙f瀽浠诲姟ID: {task_id}")
+        
+        # 鏂规硶1锛氬皾璇曟爣鍑嗘牸寮忚В鏋愶紙鍖呭惈涓嬪垝绾匡級
+        if "_" in task_id:
+            parts = task_id.split("_")
+            self.logger.debug(f"浠诲姟ID鍖呭惈涓嬪垝绾匡紝鍒嗗壊缁撴灉: {parts}")
+            
+            if len(parts) >= 3:
+                potential_start = parts[-2]
+                potential_end = parts[-1]
+                
+                start_valid = potential_start in self.path_mapping
+                end_valid = potential_end in self.path_mapping
+                
+                self.logger.debug(f"鏍囧噯鏍煎紡瑙f瀽缁撴灉: start={potential_start}(valid={start_valid}), end={potential_end}(valid={end_valid})")
+                
+                if start_valid and end_valid:
+                    return potential_start, potential_end
+                    
+            self.logger.debug(f"浠诲姟ID鍒嗗壊鍚庨儴鍒嗘暟閲忎笉瓒�: {len(parts)} < 3")
+        
+        # 鏂规硶2锛氱畝鍗曟暟瀛桰D鐨勫閫夋満鍒讹紙閫氳繃hash鍒嗛厤浣嶇疆锛�
+        self.logger.debug(f"灏濊瘯绠�鍗曟暟瀛桰D澶囬�夎В鏋愭満鍒�")
+        
+        # 鑾峰彇鎵�鏈夊彲鐢ㄤ綅缃�
+        all_positions = list(self.path_mapping.keys())
+        if len(all_positions) < 2:
+            self.logger.warning(f"璺緞鏄犲皠浣嶇疆涓嶈冻锛屾棤娉曚负浠诲姟鍒嗛厤璧风粓鐐�")
+            return None, None
+        
+        # 浣跨敤浠诲姟ID鐨刪ash鍊兼潵鍒嗛厤璧风偣鍜岀粓鐐�
+        try:
+            task_hash = abs(hash(task_id))
+            
+            # 鍒嗛厤璧风偣锛堜娇鐢╤ash鐨勫墠涓�鍗婏級
+            start_index = task_hash % len(all_positions)
+            start_pos = all_positions[start_index]
+            
+            # 鍒嗛厤缁堢偣锛堜娇鐢╤ash鐨勫悗涓�鍗婏紝纭繚涓庤捣鐐逛笉鍚岋級
+            end_index = (task_hash // len(all_positions)) % len(all_positions)
+            if end_index == start_index:
+                end_index = (end_index + 1) % len(all_positions)
+            end_pos = all_positions[end_index]
+            
+            self.logger.debug(f"绠�鍗旾D澶囬�夎В鏋愭垚鍔�: 浠诲姟{task_id} -> start={start_pos}, end={end_pos}")
+            return start_pos, end_pos
+            
+        except Exception as e:
+            self.logger.error(f"绠�鍗旾D澶囬�夎В鏋愬け璐�: {e}")
+        
+        self.logger.warning(f"浠诲姟ID {task_id} 鎵�鏈夎В鏋愭柟娉曢兘澶辫触锛岃繑鍥� None, None")
+        return None, None
+    
+    def _fast_parse_target(self, task_id: str, current_position: str, loaded: bool) -> Optional[str]:
+        """
+        瑙f瀽浠诲姟鐩爣浣嶇疆
+        
+        Args:
+            task_id: 浠诲姟ID
+            current_position: 褰撳墠浣嶇疆
+            loaded: 鏄惁宸茶杞�
+            
+        Returns:
+            Optional[str]: 鐩爣浣嶇疆鐮�
+        """
+        _, task_end = self._fast_parse_task_start_end(task_id)
+        if task_end:
+            return task_end
+        
+        # 鍩轰簬hash鍊煎拰瑁呰浇鐘舵�佸揩閫熼�夋嫨
+        hash_val = hash(task_id) % 1000
+        
+        if loaded:
+            # 宸茶杞斤紝閫夋嫨鍑哄簱鍖哄煙
+            target_positions = [pos for pos in self.delivery_positions if pos != current_position]
+            if not target_positions:
+                target_positions = [pos for pos in self.path_mapping.keys() if pos != current_position]
+        else:
+            # 鏈杞斤紝閫夋嫨浠撳簱鍖哄煙
+            target_positions = [pos for pos in self.pickup_positions if pos != current_position]
+            if not target_positions:
+                target_positions = [pos for pos in self.path_mapping.keys() if pos != current_position]
+        
+        if target_positions:
+            return target_positions[hash_val % len(target_positions)]
+        
+        return None
+
+    def extract_executing_tasks(self, agv_status_list: List[AGVStatus]) -> List[Dict]:
+        """鎻愬彇鎵�鏈堿GV姝e湪鎵ц鐨勪换鍔�"""
+        self.logger.debug(f"寮�濮嬭浆鎹换鍔′负鏍囧噯鏍煎紡锛孉GV鏁伴噺: {len(agv_status_list)}")
+        
+        optimized_tasks = self.extract_optimized_executing_tasks(agv_status_list)
+        
+        self.logger.debug(f"鎻愬彇缁撴灉鏁伴噺: {len(optimized_tasks)}")
+        
+        legacy_tasks = []
+        for i, task in enumerate(optimized_tasks):
+            try:
+                self.logger.debug(f"杞崲浠诲姟 #{i+1}: AGV {task['agvId']}")
+                
+                primary_task = task['primary_task']
+                task_info = primary_task['task_info']
+                backpack_item = primary_task['backpack_item']
+                
+                self.logger.debug(f"  - primary_task瀛樺湪: {primary_task is not None}")
+                self.logger.debug(f"  - task_info瀛樺湪: {task_info is not None}")
+                self.logger.debug(f"  - backpack_item瀛樺湪: {backpack_item is not None}")
+                
+                # 鏍规嵁action纭畾鐘舵��
+                is_pickup_action = task['next_action'] == 'pickup'
+                
+                self.logger.debug(f"  - next_action: {task['next_action']}")
+                self.logger.debug(f"  - is_pickup_action: {is_pickup_action}")
+                self.logger.debug(f"  - target_position: {task['target_position']}")
+                
+                # 淇濇寔鍘熸湁鐨勬爣鍑咼SON鏍煎紡
+                legacy_task = {
+                    'agvId': task['agvId'],
+                    'taskId': task_info['task_id'],
+                    'currentPosition': task['currentPosition'],
+                    'backpackIndex': backpack_item.index,
+                    'status': 'executing',
+                    'agvDirection': task['agvDirection'],
+                    'agvVoltage': task['agvVoltage'],
+                    'agvError': task['agvError'],
+                    'loaded': backpack_item.loaded,
+                    'needPickup': is_pickup_action,
+                    'targetPosition': task['target_position'],
+                    'taskStart': task_info['start_position'],
+                    'taskEnd': task_info['end_position']
+                }
+                
+                self.logger.debug(f"  - 浠诲姟鏋勫缓鎴愬姛: {legacy_task['agvId']} -> {legacy_task['targetPosition']}")
+                legacy_tasks.append(legacy_task)
+                
+            except Exception as e:
+                self.logger.error(f"杞崲浠诲姟 #{i+1} 澶辫触: {e}")
+                self.logger.error(f"浠诲姟鍐呭: {task}")
+                continue
+            
+        self.logger.info(f"浣跨敤缁煎悎浼樺寲绛栫暐锛屼负 {len(legacy_tasks)} 涓狝GV鐢熸垚鏍囧噯鏍煎紡璺緞")
+        return legacy_tasks
+
+
+class BatchPathPlanner:
+    """鎵归噺璺緞瑙勫垝鍣�"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]], 
+                 algorithm_type: str = "A_STAR", agv_manager=None):
+        """
+        鍒濆鍖栨壒閲忚矾寰勮鍒掑櫒
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+            algorithm_type: 鍩虹璺緞瑙勫垝绠楁硶绫诲瀷
+            agv_manager: 鐢ㄤ簬鑾峰彇AGV鐘舵�佷俊鎭�
+        """
+        self.path_mapping = path_mapping
+        self.algorithm_type = algorithm_type
+        self.agv_manager = agv_manager
+        self.logger = logging.getLogger(__name__)
+        
+        # 鍒濆鍖栦紭鍖栫粍浠�
+        self.task_extractor = ExecutingTaskExtractor(path_mapping)
+        self.collision_detector = FastCollisionDetector(min_distance=3.0)
+        self.collision_resolver = FastCollisionResolver(path_mapping, self.collision_detector, agv_manager)
+        self.base_planner = PathPlanningFactory.create_path_planner(algorithm_type, path_mapping)
+    
+    def plan_all_agv_paths(self, agv_status_list: List[AGVStatus], 
+                          include_idle_agv: bool = False,
+                          constraints: List[Tuple[int, int, float]] = None) -> Dict:
+        """
+        涓烘墍鏈堿GV瑙勫垝璺緞锛堟瘡涓狝GV鍙敓鎴愪竴涓矾寰勶級
+        
+        Args:
+            agv_status_list: AGV鐘舵�佸垪琛�
+            include_idle_agv: 鏄惁鍖呭惈绌洪棽AGV
+            constraints: 璺緞绾︽潫鏉′欢
+            
+        Returns:
+            Dict: 鍖呭惈鎵�鏈夎矾寰勪俊鎭殑缁撴灉
+        """
+        start_time = time.time()
+        
+        # 1. 鎻愬彇鎵ц涓殑浠诲姟锛堜娇鐢ㄥ悜鍚庡吋瀹圭殑鏂规硶锛�
+        executing_tasks = self.task_extractor.extract_executing_tasks(agv_status_list)
+        
+        # 2. 璺緞瑙勫垝
+        planned_paths = []
+        total_planning_time = 0
+        planned_agv_ids = set()
+        
+        for task in executing_tasks:
+            agv_id = task['agvId']
+            current_pos = task['currentPosition']
+            target_pos = task['targetPosition']
+            task_id = task['taskId']
+            
+            self.logger.debug(f"寮�濮嬭矾寰勮鍒�: AGV {agv_id}, 浠诲姟 {task_id}")
+            self.logger.debug(f"  - current_pos: {current_pos} ({type(current_pos)})")
+            self.logger.debug(f"  - target_pos: {target_pos} ({type(target_pos)})")
+            
+            # 閬垮厤閲嶅瑙勫垝
+            if agv_id in planned_agv_ids:
+                self.logger.debug(f"  - 璺宠繃AGV {agv_id}锛氬凡瑙勫垝")
+                continue
+            
+            # 楠岃瘉浣嶇疆鏍煎紡
+            if not current_pos or not target_pos:
+                self.logger.error(f"  - AGV {agv_id} 浣嶇疆淇℃伅鏃犳晥: current={current_pos}, target={target_pos}")
+                continue
+            
+            # 璺緞鏍煎紡鏍囧噯鍖�
+            from common.utils import normalize_path_id
+            normalized_current = normalize_path_id(current_pos)
+            normalized_target = normalize_path_id(target_pos)
+            
+            self.logger.debug(f"  - 鏍煎紡鏍囧噯鍖�: {current_pos} -> {normalized_current}, {target_pos} -> {normalized_target}")
+            
+            # 璺緞瑙勫垝
+            path_start_time = time.time()
+            self.logger.debug(f"  - 璋冪敤base_planner.plan_path({normalized_current}, {normalized_target})")
+            planned_path = self.base_planner.plan_path(normalized_current, normalized_target, constraints)
+            path_end_time = time.time()
+            
+            planning_time = (path_end_time - path_start_time) * 1000
+            total_planning_time += planning_time
+            
+            self.logger.debug(f"  - 璺緞瑙勫垝缁撴灉: {planned_path is not None}")
+            if planned_path:
+                self.logger.debug(f"  - 璺緞闀垮害: {len(planned_path.codeList) if hasattr(planned_path, 'codeList') else 'N/A'}")
+            else:
+                self.logger.error(f"  - AGV {agv_id} 璺緞瑙勫垝澶辫触: {current_pos} -> {target_pos}")
+            
+            if planned_path:
+                # 鐢熸垚璺緞瀛楀吀
+                seg_id = generate_segment_id(agv_id=agv_id, task_id=task_id, action_type="2")
+                
+                path_dict = {
+                    'agvId': agv_id,
+                    'segId': seg_id,
+                    'codeList': []
+                }
+                
+                # 杞崲璺緞鐐规牸寮�
+                for i, path_code in enumerate(planned_path.codeList):
+                    if isinstance(path_code, PathCode):
+                        action_type = "2"  # 浠诲姟绫诲瀷
+                        pos_type = None
+                        backpack_level = task.get('backpackIndex', 0)
+                        is_target_point = False
+                        
+                        # 纭畾浣嶇疆绫诲瀷锛氭渶鍚庝竴涓偣鐨勫姩浣滅被鍨�
+                        if i == len(planned_path.codeList) - 1:  # 鏈�鍚庝竴涓矾寰勭偣
+                            is_target_point = True
+                            if task.get('loaded', False):
+                                # 宸茶杞戒换鍔★細褰撳墠璺緞鏄幓缁堢偣鏀捐揣
+                                pos_type = "2"  # 鏀捐揣
+                                self.logger.debug(f"AGV {agv_id} 鍦ㄧ粓鐐� {path_code.code} 璁剧疆鏀捐揣鍔ㄤ綔")
+                            else:
+                                # 鏈杞戒换鍔★細褰撳墠璺緞鏄幓璧风偣鍙栬揣
+                                pos_type = "1"  # 鍙栬揣
+                                self.logger.debug(f"AGV {agv_id} 鍦ㄨ捣鐐� {path_code.code} 璁剧疆鍙栬揣鍔ㄤ綔")
+                        
+                        enhanced_code = generate_navigation_code(
+                            code=path_code.code,
+                            direction=path_code.direction,
+                            action_type=action_type,
+                            task_id=task_id,
+                            pos_type=pos_type,
+                            backpack_level=backpack_level,
+                            is_target_point=is_target_point
+                        )
+                        path_dict['codeList'].append(enhanced_code)
+                    else:
+                        enhanced_code = generate_navigation_code(
+                            code=path_code.get('code', ''),
+                            direction=path_code.get('direction', '90'),
+                            action_type="2",
+                            task_id=task_id
+                        )
+                        path_dict['codeList'].append(enhanced_code)
+                
+                planned_paths.append(path_dict)
+                planned_agv_ids.add(agv_id)
+                self.logger.debug(f"AGV {agv_id} 蹇�熻鍒�: {current_pos} -> {target_pos}")
+        
+        # 3. 绌洪棽AGV澶勭悊
+        if include_idle_agv:
+            idle_paths = self._fast_plan_idle_agv_paths(agv_status_list, executing_tasks, constraints, planned_agv_ids)
+            planned_paths.extend(idle_paths)
+        
+        # 4. 鍘婚噸妫�鏌�
+        final_paths = []
+        final_agv_ids = set()
+        for path in planned_paths:
+            agv_id = path['agvId']
+            if agv_id not in final_agv_ids:
+                final_paths.append(path)
+                final_agv_ids.add(agv_id)
+        planned_paths = final_paths
+        
+        # 5. 纰版挒妫�娴嬪拰瑙e喅
+        conflicts = self.collision_detector.detect_conflicts(planned_paths)
+        
+        if conflicts:
+            self.logger.info(f"鍙戠幇 {len(conflicts)} 涓鎾烇紝蹇�熻В鍐充腑...")
+            planned_paths = self.collision_resolver.resolve_conflicts(planned_paths, conflicts, executing_tasks)
+            remaining_conflicts = self.collision_detector.detect_conflicts(planned_paths)
+        else:
+            remaining_conflicts = []
+        
+        end_time = time.time()
+        total_time = (end_time - start_time) * 1000
+        
+        # 6. 鏋勫缓浼樺寲缁撴灉
+        result = {
+            'totalAgvs': len(agv_status_list),
+            'executingTasksCount': len(executing_tasks),
+            'plannedPathsCount': len(planned_paths),
+            'totalPlanningTime': round(total_time, 2),
+            'pathPlanningTime': round(total_planning_time, 2),
+            'conflictsDetected': len(conflicts),
+            'remainingConflicts': len(remaining_conflicts),
+            'algorithm': f"Optimized_{self.algorithm_type}",
+            'fourDirectionCompliant': True,
+            'collisionFree': len(remaining_conflicts) == 0,
+            'plannedPaths': planned_paths,
+            'executingTasks': executing_tasks
+        }
+        
+        self.logger.info(f"浼樺寲鎵归噺璺緞瑙勫垝瀹屾垚 - 鎬籄GV: {result['totalAgvs']}, "
+                        f"鎵ц涓换鍔�: {result['executingTasksCount']}, "
+                        f"瑙勫垝璺緞: {result['plannedPathsCount']}, "
+                        f"鎬昏�楁椂: {result['totalPlanningTime']:.2f}ms, "
+                        f"鏃犵鎾�: {result['collisionFree']}")
+        
+        return result
+    
+    def _fast_plan_idle_agv_paths(self, agv_status_list: List[AGVStatus], 
+                                 executing_tasks: List[Dict],
+                                 constraints: List[Tuple[int, int, float]] = None,
+                                 planned_agv_ids: Set[str] = None) -> List[Dict]:
+        """
+        涓虹┖闂睞GV瑙勫垝璺緞
+        """
+        idle_paths = []
+        executing_agv_ids = {task['agvId'] for task in executing_tasks}
+        
+        if planned_agv_ids is None:
+            planned_agv_ids = executing_agv_ids.copy()
+        
+        for agv_status in agv_status_list:
+            agv_id = agv_status.agvId
+            
+            if agv_id in planned_agv_ids:
+                continue
+            
+            if self._is_agv_idle_fast(agv_status):
+                current_pos = agv_status.position
+                target_pos = self._get_idle_agv_target_fast(agv_id, current_pos)
+                
+                if target_pos and target_pos != current_pos:
+                    planned_path = self.base_planner.plan_path(current_pos, target_pos, constraints)
+                    
+                    if planned_path:
+                        action_type = "3" if self._is_charging_path(target_pos) else "4"
+                        seg_id = generate_segment_id(agv_id=agv_id, target_position=target_pos, action_type=action_type)
+                        
+                        path_dict = {
+                            'agvId': agv_id,
+                            'segId': seg_id,
+                            'codeList': []
+                        }
+                        
+                        for i, path_code in enumerate(planned_path.codeList):
+                            if isinstance(path_code, PathCode):
+                                # 绌洪棽AGV涓嶉渶瑕乼askId銆乸osType鍜宭ev瀛楁
+                                enhanced_code = generate_navigation_code(
+                                    code=path_code.code,
+                                    direction=path_code.direction,
+                                    action_type=action_type,
+                                    is_target_point=False  # 绌洪棽AGV璺緞鏃犵洰鏍囩偣姒傚康
+                                )
+                                path_dict['codeList'].append(enhanced_code)
+                        
+                        idle_paths.append(path_dict)
+                        planned_agv_ids.add(agv_id)
+        
+        return idle_paths
+    
+    def _is_agv_idle_fast(self, agv_status: AGVStatus) -> bool:
+        """鍒ゆ柇AGV鏄惁绌洪棽"""
+        if agv_status.status not in [0, 1, 2] or agv_status.error != 0:
+            return False
+        
+        # 妫�鏌ヨ儗绡�
+        if agv_status.backpack:
+            for item in agv_status.backpack[:2]:  # 鍙鏌ュ墠涓や釜
+                if item.loaded and item.execute:
+                    return False
+        
+        return True
+    
+    def _get_idle_agv_target_fast(self, agv_id: str, current_position: str) -> Optional[str]:
+        """鑾峰彇绌洪棽AGV鐩爣浣嶇疆"""
+        hash_val = hash(agv_id) % 1000
+        
+        # 閫夋嫨閫昏緫
+        charging_positions = [pos for pos in self.task_extractor.charging_positions if pos != current_position]
+        if charging_positions:
+            return charging_positions[hash_val % len(charging_positions)]
+        
+        standby_positions = [pos for pos in self.task_extractor.standby_positions if pos != current_position]
+        if standby_positions:
+            return standby_positions[hash_val % len(standby_positions)]
+        
+        all_positions = [pos for pos in self.path_mapping.keys() if pos != current_position]
+        if all_positions:
+            return all_positions[hash_val % len(all_positions)]
+        
+        return None
+
+    def _is_charging_path(self, target_position: str) -> bool:
+        """
+        鍒ゆ柇鐩爣浣嶇疆鏄惁涓哄厖鐢电珯锛堝悗鏈熶慨鏀癸級
+        """
+        if not target_position:
+            return False
+        
+        # 鍏呯數绔欒瘑鍒�
+        return target_position.startswith("2") or "charge" in target_position.lower()
+
+
+class PathPlanner:
+    """璺緞瑙勫垝鍣ㄥ熀绫�"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]]):
+        """
+        鍒濆鍖栬矾寰勮鍒掑櫒
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+        """
+        self.path_mapping = path_mapping
+        self.logger = logging.getLogger(__name__)
+    
+    def plan_path(self, start_code: str, end_code: str, 
+                 constraints: List[Tuple[int, int, float]] = None) -> Optional[PlannedPath]:
+        """
+        瑙勫垝浠庤捣鐐瑰埌缁堢偣鐨勮矾寰�
+        
+        Args:
+            start_code: 璧峰璺緞鐐笽D
+            end_code: 鐩爣璺緞鐐笽D
+            constraints: 绾︽潫鏉′欢鍒楄〃
+            
+        Returns:
+            Optional[PlannedPath]: 瑙勫垝鐨勮矾寰勶紝濡傛灉鏃犳硶瑙勫垝鍒欒繑鍥濶one
+        """
+        raise NotImplementedError("瀛愮被蹇呴』瀹炵幇姝ゆ柟娉�")
+    
+    def is_valid_path_point(self, code: str) -> bool:
+        """
+        妫�鏌ヨ矾寰勭偣ID鏄惁鏈夋晥
+        
+        Args:
+            code: 璺緞鐐笽D
+            
+        Returns:
+            bool: 鏄惁鏈夋晥
+        """
+        return code in self.path_mapping
+
+
+class AStarPathPlanner(PathPlanner):
+    """A*璺緞瑙勫垝鍣�"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]], turn_cost: float = 0.5):
+        """
+        鍒濆鍖朅*璺緞瑙勫垝鍣�
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+            turn_cost: 杞悜浠d环
+        """
+        super().__init__(path_mapping)
+        self.turn_cost = turn_cost
+        self.logger = logging.getLogger(__name__)
+        
+        # 鍥涗釜鏂瑰悜锛氫笂銆佸彸銆佷笅銆佸乏 (涓ユ牸鍥涙柟鍚戠Щ鍔�)
+        self.directions = [(0, -1), (1, 0), (0, 1), (-1, 0)]
+        self.direction_angles = ["270", "0", "90", "180"]
+        
+        # 棰勮绠楀潗鏍囨槧灏勶紙蹇呴』鍦� _build_adjacency_list 涔嬪墠鍒濆鍖栵級
+        self.coord_to_code = {}
+        for code, data in path_mapping.items():
+            if isinstance(data, dict) and 'x' in data and 'y' in data:
+                self.coord_to_code[(data['x'], data['y'])] = code
+        
+        # 棰勮绠楅偦鎺ヨ〃
+        self.adjacency = self._build_adjacency_list()
+        
+        # 鎬ц兘鐩戞帶
+        self.planning_count = 0
+        self.total_planning_time = 0.0
+        
+        self.logger.debug(f"A*瑙勫垝鍣ㄥ垵濮嬪寲瀹屾垚锛岄偦鎺ヨ〃: {len(self.adjacency)} 涓妭鐐�")
+    
+    def _build_adjacency_list(self) -> Dict[str, List[Tuple[str, str]]]:
+        """
+        棰勮绠楅偦鎺ヨ〃
+        
+        Returns:
+            Dict[str, List[Tuple[str, str]]]: {鑺傜偣: [(閭诲眳鑺傜偣, 绉诲姩鏂瑰悜), ...]}
+        """
+        adjacency = defaultdict(list)
+        
+        for code, coord_data in self.path_mapping.items():
+            x, y = coord_data['x'], coord_data['y']
+            
+            # 妫�鏌ュ洓涓柟鍚戠殑閭诲眳
+            for i, (dx, dy) in enumerate(self.directions):
+                next_x, next_y = x + dx, y + dy
+                
+                # 鏌ユ壘閭诲眳浠g爜
+                neighbor_coord = (next_x, next_y)
+                if neighbor_coord in self.coord_to_code:
+                    neighbor_code = self.coord_to_code[neighbor_coord]
+                    direction = self.direction_angles[i]
+                    adjacency[code].append((neighbor_code, direction))
+        
+        return adjacency
+    
+    def plan_path(self, start_code: str, end_code: str, 
+                 constraints: List[Tuple[int, int, float]] = None) -> Optional[PlannedPath]:
+        """       
+        Args:
+            start_code: 璧峰璺緞鐐笽D
+            end_code: 鐩爣璺緞鐐笽D
+            constraints: 绾︽潫鏉′欢鍒楄〃
+            
+        Returns:
+            Optional[PlannedPath]: 瑙勫垝鐨勮矾寰�
+        """
+        # 楠岃瘉
+        if not self.is_valid_path_point(start_code) or not self.is_valid_path_point(end_code):
+            return None
+        
+        if start_code == end_code:
+            return PlannedPath(agvId="", codeList=[PathCode(code=start_code, direction="90")])
+        
+        # 鑾峰彇鍧愭爣锛堜娇鐢ㄩ璁$畻鏄犲皠锛�
+        start_coord = (self.path_mapping[start_code]['x'], self.path_mapping[start_code]['y'])
+        end_coord = (self.path_mapping[end_code]['x'], self.path_mapping[end_code]['y'])
+        
+        # A*瀹炵幇
+        # 浣跨敤鍏冪粍鍫嗭紝鍑忓皯瀵硅薄鍒涘缓寮�閿�
+        open_set = [(0, start_code, None, [])]  # (f_score, code, parent, path)
+        closed_set = set()
+        g_scores = {start_code: 0}
+        
+        # 棰勮绠楃害鏉熸鏌ュ嚱鏁�
+        constraint_check = self._build_constraint_checker(constraints) if constraints else None
+        
+        while open_set:
+            f_score, current_code, parent_code, path = heapq.heappop(open_set)
+            
+            if current_code in closed_set:
+                continue
+                
+            closed_set.add(current_code)
+            current_path = path + [current_code]
+            
+            if current_code == end_code:
+                # 閲嶅缓璺緞
+                return self._build_path_result(current_path)
+            
+            # 浣跨敤棰勮绠楃殑閭绘帴琛�
+            for neighbor_code, direction in self.adjacency[current_code]:
+                if neighbor_code in closed_set:
+                    continue
+                
+                # 绾︽潫妫�鏌�
+                if constraint_check and constraint_check(neighbor_code):
+                    continue
+                
+                # 浠d环璁$畻
+                g_cost = g_scores[current_code] + 1
+                
+                if neighbor_code not in g_scores or g_cost < g_scores[neighbor_code]:
+                    g_scores[neighbor_code] = g_cost
+                    
+                    # 鍚彂寮忚绠�
+                    neighbor_coord = (self.path_mapping[neighbor_code]['x'], 
+                                    self.path_mapping[neighbor_code]['y'])
+                    h_cost = abs(neighbor_coord[0] - end_coord[0]) + abs(neighbor_coord[1] - end_coord[1])
+                    f_cost = g_cost + h_cost
+                    
+                    heapq.heappush(open_set, (f_cost, neighbor_code, current_code, current_path))
+        
+        return None
+    
+    def _build_constraint_checker(self, constraints: List[Tuple[int, int, float]]):
+        """鏋勫缓绾︽潫妫�鏌ュ嚱鏁�"""
+        def check_constraints(code: str) -> bool:
+            coord = (self.path_mapping[code]['x'], self.path_mapping[code]['y'])
+            for cx, cy, radius in constraints:
+                if (coord[0] - cx) ** 2 + (coord[1] - cy) ** 2 <= radius ** 2:
+                    return True
+            return False
+        return check_constraints
+    
+    def _build_path_result(self, path_codes: List[str]) -> PlannedPath:
+        """鏋勫缓璺緞缁撴灉"""
+        result_codes = []
+        
+        for i, code in enumerate(path_codes):
+            direction = "90"  # 榛樿鏂瑰悜
+            
+            if i < len(path_codes) - 1:
+                # 浣跨敤棰勮绠楃殑閭绘帴琛ㄦ煡鎵炬柟鍚�
+                next_code = path_codes[i + 1]
+                for neighbor_code, neighbor_direction in self.adjacency[code]:
+                    if neighbor_code == next_code:
+                        direction = neighbor_direction
+                        break
+            
+            result_codes.append(PathCode(code=code, direction=direction))
+        
+        return PlannedPath(agvId="", codeList=result_codes)
+
+
+# 纰版挒妫�娴嬪櫒
+class FastCollisionDetector:
+    """纰版挒妫�娴嬪櫒"""
+    
+    def __init__(self, min_distance: float = 3.0):
+        self.min_distance = min_distance
+        self.logger = logging.getLogger(__name__)
+    
+    def detect_conflicts(self, planned_paths: List[Dict]) -> List[Dict]:
+        """
+        纰版挒妫�娴� - 鍩轰簬鏃堕棿姝ョ殑浼樺寲妫�娴�
+        
+        Args:
+            planned_paths: 瑙勫垝璺緞鍒楄〃
+            
+        Returns:
+            List[Dict]: 鍐茬獊鍒楄〃
+        """
+        conflicts = []
+        if len(planned_paths) < 2:
+            return conflicts
+        
+        # 鏋勫缓鏃堕棿-浣嶇疆鏄犲皠
+        time_positions = defaultdict(list)
+        
+        for path_data in planned_paths:
+            agv_id = path_data['agvId']
+            code_list = path_data.get('codeList', [])
+            
+            for time_step, path_code in enumerate(code_list):
+                # 蹇�熸彁鍙栦綅缃爜
+                if isinstance(path_code, dict):
+                    position = path_code.get('code', '')
+                elif hasattr(path_code, 'code'):
+                    position = path_code.code
+                else:
+                    position = str(path_code)
+                
+                if position:
+                    time_positions[time_step].append((agv_id, position))
+        
+        # 蹇�熷啿绐佹娴�
+        for time_step, agv_positions in time_positions.items():
+            if len(agv_positions) < 2:
+                continue
+            
+            # 浣嶇疆鍒嗙粍妫�鏌�
+            position_groups = defaultdict(list)
+            for agv_id, position in agv_positions:
+                position_groups[position].append(agv_id)
+            
+            # 鍙戠幇鍐茬獊
+            for position, agv_list in position_groups.items():
+                if len(agv_list) > 1:
+                    conflicts.append({
+                        'type': 'position_conflict',
+                        'time_step': time_step,
+                        'position': position,
+                        'agv_ids': agv_list,
+                        'severity': 'high'
+                    })
+        
+        self.logger.debug(f"蹇�熸娴嬪埌 {len(conflicts)} 涓啿绐�")
+        return conflicts
+
+
+# 纰版挒瑙e喅鍣�
+class FastCollisionResolver:
+    """纰版挒瑙e喅鍣�"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]], 
+                 collision_detector: FastCollisionDetector, agv_manager=None):
+        self.path_mapping = path_mapping
+        self.collision_detector = collision_detector
+        self.agv_manager = agv_manager
+        self.logger = logging.getLogger(__name__)
+    
+    def resolve_conflicts(self, planned_paths: List[Dict], conflicts: List[Dict], executing_tasks: List[Dict] = None) -> List[Dict]:
+        """
+        瑙e喅鍐茬獊
+        
+        Args:
+            planned_paths: 瑙勫垝璺緞鍒楄〃
+            conflicts: 鍐茬獊鍒楄〃
+            executing_tasks: 鎵ц浠诲姟鍒楄〃
+            
+        Returns:
+            List[Dict]: 瑙e喅鍐茬獊鍚庣殑璺緞鍒楄〃
+        """
+        if not conflicts:
+            return planned_paths
+        
+        # 鏋勫缓璺緞瀛楀吀渚夸簬蹇�熻闂�
+        paths_dict = {path['agvId']: path for path in planned_paths}
+        
+        # 鎸夋椂闂存鎺掑簭澶勭悊鍐茬獊
+        sorted_conflicts = sorted(conflicts, key=lambda x: x.get('time_step', 0))
+        
+        for conflict in sorted_conflicts:
+            if conflict['type'] == 'position_conflict':
+                agv_ids = conflict['agv_ids']
+                time_step = conflict['time_step']
+                
+                # 绠�鍗曠瓥鐣ワ細淇濈暀绗竴涓狝GV锛屽叾浠栧欢杩�
+                sorted_agv_ids = sorted(agv_ids)
+                
+                for i, agv_id in enumerate(sorted_agv_ids[1:], 1):
+                    if agv_id in paths_dict:
+                        self._add_delay_to_path(paths_dict[agv_id], delay_steps=i)
+                        self.logger.debug(f"涓篈GV {agv_id} 娣诲姞 {i} 姝ュ欢杩�")
+        
+        return list(paths_dict.values())
+    
+    def _add_delay_to_path(self, path_data: Dict, delay_steps: int):
+        """涓鸿矾寰勬坊鍔犲欢杩熸楠�"""
+        if delay_steps <= 0 or not path_data.get('codeList'):
+            return
+        
+        # 鍦ㄨ矾寰勫紑濮嬪閲嶅绗竴涓綅缃�
+        first_code = path_data['codeList'][0]
+        
+        # 鍒涘缓寤惰繜浠g爜
+        if isinstance(first_code, dict):
+            delay_code = first_code.copy()
+        else:
+            delay_code = {
+                'code': first_code.code if hasattr(first_code, 'code') else str(first_code),
+                'direction': first_code.direction if hasattr(first_code, 'direction') else "90"
+            }
+        
+        # 娣诲姞寤惰繜姝ラ
+        for _ in range(delay_steps):
+            path_data['codeList'].insert(0, delay_code)
+    
+    def validate_four_direction_movement(self, planned_paths: List[Dict]) -> List[Dict]:
+        """楠岃瘉鍥涘悜绉诲姩绾︽潫"""
+        return planned_paths
+
+
+class PathPlanningFactory:
+    """璺緞瑙勫垝鍣ㄥ伐鍘傜被"""
+    
+    @staticmethod
+    def create_path_planner(algorithm_type: str, path_mapping: Dict[str, Dict[str, int]]) -> PathPlanner:
+        """
+        鍒涘缓璺緞瑙勫垝鍣ㄥ疄渚�
+        
+        Args:
+            algorithm_type: 绠楁硶绫诲瀷
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+            
+        Returns:
+            PathPlanner: 璺緞瑙勫垝鍣ㄥ疄渚�
+        """
+        algorithm_upper = algorithm_type.upper()
+        
+        if algorithm_upper in ["A_STAR", "ASTAR", "A*", "DIJKSTRA", "GREEDY"]:
+            return AStarPathPlanner(path_mapping)
+        else:
+            # 榛樿A*绠楁硶
+            logging.getLogger(__name__).warning(f"鏈煡绠楁硶绫诲瀷 {algorithm_type}锛屼娇鐢ㄩ粯璁*绠楁硶")
+            return AStarPathPlanner(path_mapping)
+    
+    @staticmethod
+    def create_batch_path_planner(algorithm_type: str, path_mapping: Dict[str, Dict[str, int]], 
+                                 agv_manager=None) -> BatchPathPlanner:
+        """
+        鍒涘缓鎵归噺璺緞瑙勫垝鍣ㄥ疄渚�
+        
+        Args:
+            algorithm_type: 鍩虹绠楁硶绫诲瀷
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+            agv_manager: AGV绠$悊鍣紝鐢ㄤ簬鑾峰彇AGV鐘舵�佷俊鎭�
+            
+        Returns:
+            BatchPathPlanner: 鎵归噺璺緞瑙勫垝鍣ㄥ疄渚�
+        """
+        return BatchPathPlanner(path_mapping, algorithm_type, agv_manager)
+
+# 瀵煎嚭鏍稿績绫诲拰鍑芥暟
+__all__ = [
+    'ExecutingTaskExtractor',
+    'BatchPathPlanner',
+    'PathPlanner',
+    'AStarPathPlanner',
+    'PathPlanningFactory',
+    'FastCollisionDetector',
+    'FastCollisionResolver'
+] 
\ No newline at end of file
diff --git a/algorithm_system/algorithms/task_allocation.py b/algorithm_system/algorithms/task_allocation.py
new file mode 100644
index 0000000..883ed50
--- /dev/null
+++ b/algorithm_system/algorithms/task_allocation.py
@@ -0,0 +1,687 @@
+"""
+浠诲姟鍒嗛厤绠楁硶
+"""
+import time
+import random
+import logging
+from typing import Dict, List, Tuple, Optional, Set, Any
+from collections import defaultdict
+from abc import ABC, abstractmethod
+
+from common.data_models import TaskData, AGVStatus, TaskAssignment, BackpackData
+from algorithm_system.models.agv_model import AGVModel, AGVModelManager
+from common.utils import get_coordinate_from_path_id, calculate_distance, calculate_manhattan_distance
+from dataclasses import dataclass
+
+
+class TaskAllocation(ABC):
+    """浠诲姟鍒嗛厤绠楁硶鍩虹被"""
+    
+    def __init__(self, agv_manager: AGVModelManager):
+        """
+        鍒濆鍖栦换鍔″垎閰嶇畻娉�
+        
+        Args:
+            agv_manager: AGV妯″瀷绠$悊鍣�
+        """
+        self.agv_manager = agv_manager
+        self.logger = logging.getLogger(__name__)
+    
+    @abstractmethod
+    def allocate_tasks(self, tasks: List[TaskData]) -> List[TaskAssignment]:
+        """
+        鍒嗛厤浠诲姟缁橝GV
+        
+        Args:
+            tasks: 寰呭垎閰嶇殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[TaskAssignment]: 鍒嗛厤缁撴灉鍒楄〃
+        """
+        pass
+    
+    def find_available_backpack_slot(self, agv_status: AGVStatus) -> Optional[int]:
+        """
+        鏌ユ壘AGV鐨勫彲鐢ㄨ儗绡撲綅缃�
+        
+        Args:
+            agv_status: AGV鐘舵�佷俊鎭�
+            
+        Returns:
+            Optional[int]: 鍙敤鐨勮儗绡撲綅缃紪鍙凤紝濡傛灉娌℃湁鍙敤浣嶇疆鍒欒繑鍥濶one
+        """
+        if not agv_status.backpack:
+            # 濡傛灉娌℃湁鑳岀瘬淇℃伅锛屽亣璁句粠绗竴涓綅缃紑濮�
+            self.logger.warning(f"AGV {agv_status.agvId} 娌℃湁鑳岀瘬淇℃伅锛屽垎閰嶅埌浣嶇疆0")
+            return 0
+        
+        # 鏌ユ壘绌洪棽涓旀湭鎵ц浠诲姟鐨勮儗绡撲綅缃�
+        for backpack_item in agv_status.backpack:
+            if not backpack_item.loaded and not backpack_item.execute and not backpack_item.taskId:
+                self.logger.debug(f"AGV {agv_status.agvId} 鎵惧埌鍙敤鑳岀瘬浣嶇疆: {backpack_item.index}")
+                return backpack_item.index
+        
+        # 濡傛灉鎵�鏈変綅缃兘琚崰鐢紝杩斿洖None
+        self.logger.debug(f"AGV {agv_status.agvId} 娌℃湁鍙敤鐨勮儗绡撲綅缃�")
+        return None
+    
+    def get_agv_available_capacity(self, agv_status: AGVStatus) -> int:
+        """
+        鑾峰彇AGV鐨勫彲鐢ㄨ儗绡撳閲�
+        
+        Args:
+            agv_status: AGV鐘舵�佷俊鎭�
+            
+        Returns:
+            int: 鍙敤鑳岀瘬鏁伴噺
+        """
+        if not agv_status.backpack:
+            return 1  # 鍋囪鑷冲皯鏈変竴涓儗绡撲綅缃�
+        
+        available_count = 0
+        for backpack_item in agv_status.backpack:
+            if not backpack_item.loaded and not backpack_item.execute and not backpack_item.taskId:
+                available_count += 1
+        
+        return available_count
+    
+    def assign_task_with_backpack(self, agv_model, task: TaskData, lev_id: int) -> bool:
+        """
+        灏嗕换鍔″垎閰嶇粰AGV鐨勬寚瀹氳儗绡撲綅缃�
+        
+        Args:
+            agv_model: AGV妯″瀷
+            task: 浠诲姟鏁版嵁
+            lev_id: 鑳岀瘬浣嶇疆缂栧彿
+            
+        Returns:
+            bool: 鍒嗛厤鏄惁鎴愬姛
+        """
+        try:
+            # 浣跨敤AGV妯″瀷鐨刟ssign_task鏂规硶
+            success = agv_model.assign_task(
+                task_id=task.taskId,
+                priority=task.priority,
+                start_code=task.start,
+                end_code=task.end
+            )
+            
+            if success:
+                self.logger.info(f"浠诲姟 {task.taskId} 鎴愬姛鍒嗛厤缁橝GV {agv_model.agvId} 鐨勮儗绡撲綅缃� {lev_id}")
+                return True
+            else:
+                self.logger.warning(f"浠诲姟 {task.taskId} 鍒嗛厤缁橝GV {agv_model.agvId} 澶辫触")
+                return False
+                
+        except Exception as e:
+            self.logger.error(f"鍒嗛厤浠诲姟鏃跺彂鐢熷紓甯�: {e}")
+            return False
+
+
+class NearestFirstAllocation(TaskAllocation):
+    """鏈�杩戜紭鍏堝垎閰嶇畻娉�"""
+    
+    def allocate_tasks(self, tasks: List[TaskData]) -> List[TaskAssignment]:
+        """
+        浣跨敤鏈�杩戜紭鍏堢瓥鐣ュ垎閰嶄换鍔�
+        
+        Args:
+            tasks: 寰呭垎閰嶇殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[TaskAssignment]: 鍒嗛厤缁撴灉鍒楄〃
+        """
+        if not tasks:
+            return []
+        
+        # 鑾峰彇鍙敤鐨凙GV
+        available_agvs = self.agv_manager.get_available_agvs()
+        
+        if not available_agvs:
+            self.logger.warning("娌℃湁鍙敤鐨凙GV杩涜浠诲姟鍒嗛厤")
+            return []
+        
+        # 1. 棣栧厛妫�鏌ヤ换鍔℃槸鍚﹀凡缁忓垎閰嶏紝閬垮厤閲嶅鍒嗛厤
+        already_assigned_tasks = set()
+        all_agvs = self.agv_manager.get_all_agvs()
+        for agv in all_agvs:
+            if agv.backpack:
+                for backpack_item in agv.backpack:
+                    if backpack_item.taskId:
+                        already_assigned_tasks.add(backpack_item.taskId)
+                        self.logger.info(f"浠诲姟 {backpack_item.taskId} 宸插垎閰嶇粰 AGV {agv.agvId}锛岃烦杩囬噸澶嶅垎閰�")
+        
+        # 2. 杩囨护鎺夊凡鍒嗛厤鐨勪换鍔�
+        unassigned_tasks = [task for task in tasks if task.taskId not in already_assigned_tasks]
+        
+        if not unassigned_tasks:
+            self.logger.info("鎵�鏈変换鍔¢兘宸插垎閰嶏紝鏃犻渶閲嶆柊鍒嗛厤")
+            return []
+        
+        self.logger.info(f"鎬讳换鍔℃暟: {len(tasks)}, 宸插垎閰�: {len(already_assigned_tasks)}, 寰呭垎閰�: {len(unassigned_tasks)}")
+        
+        assignments = []
+        path_mapping = self.agv_manager.path_mapping
+        
+        # 瀵规瘡涓换鍔℃壘鍒版渶杩戠殑AGV
+        for task in unassigned_tasks:
+            if not available_agvs:
+                break
+                
+            # 鑾峰彇浠诲姟璧风偣鍧愭爣
+            task_start_coord = get_coordinate_from_path_id(task.start, path_mapping)
+            if not task_start_coord:
+                self.logger.warning(f"鏃犳硶鑾峰彇浠诲姟 {task.taskId} 璧风偣 {task.start} 鐨勫潗鏍�")
+                continue
+            
+            # 鎵惧埌璺濈鏈�杩戠殑AGV
+            nearest_agv = None
+            min_distance = float('inf')
+            
+            for agv in available_agvs:
+                if agv.coordinates:
+                    distance = calculate_manhattan_distance(agv.coordinates, task_start_coord)
+                    
+                    # 濡傛灉AGV宸叉湁浠诲姟锛岃绠楀畬鎴愬綋鍓嶄换鍔″悗鍒版柊浠诲姟璧风偣鐨勮窛绂�
+                    if agv.current_task_count > 0:
+                        # 绠�鍖栵細鍋囪AGV闇�瑕侀澶栨椂闂村畬鎴愬綋鍓嶄换鍔�
+                        distance += agv.current_task_count * 10
+                    
+                    if distance < min_distance:
+                        min_distance = distance
+                        nearest_agv = agv
+            
+            if nearest_agv and nearest_agv.can_accept_task(task.priority):
+                # 鑾峰彇AGV鐨勫師濮嬬姸鎬佹暟鎹潵鏌ユ壘鍙敤鑳岀瘬浣嶇疆
+                agv_status = None
+                for agv_state in self.agv_manager.get_all_agv_status():
+                    if agv_state.agvId == nearest_agv.agvId:
+                        agv_status = agv_state
+                        break
+                
+                if agv_status:
+                    # 鏌ユ壘鍙敤鐨勮儗绡撲綅缃�
+                    available_lev_id = self.find_available_backpack_slot(agv_status)
+                    
+                    if available_lev_id is not None:
+                        # 鍒嗛厤浠诲姟鍒版寚瀹氳儗绡撲綅缃�
+                        success = self.assign_task_with_backpack(nearest_agv, task, available_lev_id)
+                        if success:
+                            assignments.append(TaskAssignment(
+                                taskId=task.taskId,
+                                agvId=nearest_agv.agvId,
+                                lev_id=available_lev_id
+                            ))
+                            
+                            self.logger.info(f"浠诲姟 {task.taskId} 鍒嗛厤缁欐渶杩戠殑AGV {nearest_agv.agvId}锛岃儗绡撲綅缃�: {available_lev_id}锛岃窛绂�: {min_distance}")
+                            
+                            # 妫�鏌GV鏄惁杩樻湁鍙敤鑳岀瘬浣嶇疆
+                            remaining_capacity = self.get_agv_available_capacity(agv_status) - 1
+                            if remaining_capacity <= 0:
+                                available_agvs.remove(nearest_agv)
+                        else:
+                            self.logger.warning(f"浠诲姟 {task.taskId} 鍒嗛厤缁橝GV {nearest_agv.agvId} 澶辫触")
+                    else:
+                        self.logger.warning(f"AGV {nearest_agv.agvId} 娌℃湁鍙敤鐨勮儗绡撲綅缃�")
+                        available_agvs.remove(nearest_agv)
+                else:
+                    self.logger.warning(f"鏃犳硶鑾峰彇AGV {nearest_agv.agvId} 鐨勭姸鎬佷俊鎭�")
+        
+        return assignments
+
+
+class LoadBalancedAllocation(TaskAllocation):
+    """璐熻浇鍧囪 鍒嗛厤绠楁硶"""
+    
+    def allocate_tasks(self, tasks: List[TaskData]) -> List[TaskAssignment]:
+        """
+        浣跨敤璐熻浇鍧囪 绛栫暐鍒嗛厤浠诲姟
+        
+        Args:
+            tasks: 寰呭垎閰嶇殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[TaskAssignment]: 鍒嗛厤缁撴灉鍒楄〃
+        """
+        if not tasks:
+            return []
+        
+        # 鑾峰彇鎵�鏈堿GV
+        all_agvs = self.agv_manager.get_all_agvs()
+        
+        if not all_agvs:
+            self.logger.warning("娌℃湁AGV杩涜浠诲姟鍒嗛厤")
+            return []
+        
+        # 1. 棣栧厛妫�鏌ヤ换鍔℃槸鍚﹀凡缁忓垎閰嶏紝閬垮厤閲嶅鍒嗛厤
+        already_assigned_tasks = set()
+        for agv in all_agvs:
+            if agv.backpack:
+                for backpack_item in agv.backpack:
+                    if backpack_item.taskId:
+                        already_assigned_tasks.add(backpack_item.taskId)
+                        self.logger.info(f"浠诲姟 {backpack_item.taskId} 宸插垎閰嶇粰 AGV {agv.agvId}锛岃烦杩囬噸澶嶅垎閰�")
+        
+        # 2. 杩囨护鎺夊凡鍒嗛厤鐨勪换鍔�
+        unassigned_tasks = [task for task in tasks if task.taskId not in already_assigned_tasks]
+        
+        if not unassigned_tasks:
+            self.logger.info("鎵�鏈変换鍔¢兘宸插垎閰嶏紝鏃犻渶閲嶆柊鍒嗛厤")
+            return []
+        
+        self.logger.info(f"鎬讳换鍔℃暟: {len(tasks)}, 宸插垎閰�: {len(already_assigned_tasks)}, 寰呭垎閰�: {len(unassigned_tasks)}")
+        
+        assignments = []
+        path_mapping = self.agv_manager.path_mapping
+        
+        # 鎸変紭鍏堢骇鎺掑簭浠诲姟
+        sorted_tasks = sorted(unassigned_tasks, key=lambda t: t.priority, reverse=True)
+        
+        # 瀵规瘡涓换鍔″垎閰嶇粰璐熻浇鏈�浣庣殑AGV
+        for task in sorted_tasks:
+            # 鑾峰彇浠诲姟璧风偣鍧愭爣
+            task_start_coord = get_coordinate_from_path_id(task.start, path_mapping)
+            if not task_start_coord:
+                self.logger.warning(f"鏃犳硶鑾峰彇浠诲姟 {task.taskId} 璧风偣 {task.start} 鐨勫潗鏍�")
+                continue
+            
+            # 鎸夎礋杞藉拰璺濈鎺掑簭AGV
+            agv_scores = []
+            for agv in all_agvs:
+                if not agv.can_accept_task(task.priority):
+                    continue
+                    
+                # 璁$畻璐熻浇寰楀垎锛堣礋杞借秺浣庡緱鍒嗚秺楂橈級
+                load_score = 1.0 - agv.get_workload_ratio()
+                
+                # 璁$畻璺濈寰楀垎锛堣窛绂昏秺杩戝緱鍒嗚秺楂橈級
+                distance_score = 0.0
+                if agv.coordinates and task_start_coord:
+                    distance = calculate_manhattan_distance(agv.coordinates, task_start_coord)
+                    distance_score = 1.0 / (1.0 + distance / 100.0)  # 褰掍竴鍖栬窛绂诲緱鍒�
+                
+                # 璁$畻鏁堢巼寰楀垎
+                efficiency_score = agv.calculate_efficiency_score(path_mapping)
+                
+                # 缁煎悎寰楀垎
+                total_score = 0.4 * load_score + 0.3 * distance_score + 0.3 * efficiency_score
+                agv_scores.append((agv, total_score))
+            
+            if not agv_scores:
+                # 璇︾粏鍒嗘瀽涓轰粈涔堟病鏈堿GV鍙互鎺ュ彈浠诲姟
+                total_agvs = len(all_agvs)
+                busy_count = 0
+                low_battery_count = 0
+                overloaded_count = 0
+                status_invalid_count = 0
+                
+                for agv in all_agvs:
+                    if agv.is_overloaded():
+                        overloaded_count += 1
+                    elif str(agv.status) not in ["0", "1", "2"]:
+                        status_invalid_count += 1
+                    elif agv.need_charging():
+                        low_battery_count += 1
+                    else:
+                        busy_count += 1
+                
+                self.logger.warning(f"娌℃湁AGV鍙互鎺ュ彈浠诲姟 {task.taskId} - 璇︾粏鍒嗘瀽:")
+                self.logger.warning(f"  鎬籄GV鏁�: {total_agvs}")
+                self.logger.warning(f"  浠诲姟婊¤浇: {overloaded_count}")
+                self.logger.warning(f"  鐘舵�佸紓甯�: {status_invalid_count}") 
+                self.logger.warning(f"  鐢甸噺杩囦綆: {low_battery_count}")
+                self.logger.warning(f"  鍏朵粬鍘熷洜: {busy_count}")
+                self.logger.warning(f"  浠诲姟浼樺厛绾�: {task.priority}")
+                continue
+            
+            # 閫夋嫨寰楀垎鏈�楂樼殑AGV
+            agv_scores.sort(key=lambda x: x[1], reverse=True)
+            best_agv = agv_scores[0][0]
+            
+            # 鑾峰彇AGV鐨勫師濮嬬姸鎬佹暟鎹潵鏌ユ壘鍙敤鑳岀瘬浣嶇疆
+            agv_status = self.agv_manager.get_agv_status(best_agv.agvId)
+            
+            if agv_status:
+                # 鏌ユ壘鍙敤鐨勮儗绡撲綅缃�
+                available_lev_id = self.find_available_backpack_slot(agv_status)
+                
+                if available_lev_id is not None:
+                    # 鍒嗛厤浠诲姟鍒版寚瀹氳儗绡撲綅缃�
+                    success = self.assign_task_with_backpack(best_agv, task, available_lev_id)
+                    if success:
+                        assignments.append(TaskAssignment(
+                            taskId=task.taskId,
+                            agvId=best_agv.agvId,
+                            lev_id=available_lev_id
+                        ))
+                        
+                        self.logger.info(f"浠诲姟 {task.taskId} 鍒嗛厤缁欒礋杞藉潎琛$殑AGV {best_agv.agvId}锛岃儗绡撲綅缃�: {available_lev_id}锛屽緱鍒�: {agv_scores[0][1]:.3f}")
+                    else:
+                        self.logger.warning(f"浠诲姟 {task.taskId} 鍒嗛厤缁橝GV {best_agv.agvId} 澶辫触")
+                else:
+                    self.logger.warning(f"AGV {best_agv.agvId} 娌℃湁鍙敤鐨勮儗绡撲綅缃�")
+            else:
+                self.logger.warning(f"鏃犳硶鑾峰彇AGV {best_agv.agvId} 鐨勭姸鎬佷俊鎭�")
+        
+        return assignments
+
+
+class PriorityFirstAllocation(TaskAllocation):
+    """浼樺厛绾т紭鍏堝垎閰嶇畻娉�"""
+    
+    def allocate_tasks(self, tasks: List[TaskData]) -> List[TaskAssignment]:
+        """
+        浣跨敤浼樺厛绾т紭鍏堢瓥鐣ュ垎閰嶄换鍔�
+        
+        Args:
+            tasks: 寰呭垎閰嶇殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[TaskAssignment]: 鍒嗛厤缁撴灉鍒楄〃
+        """
+        if not tasks:
+            return []
+        
+        # 鑾峰彇鍙敤鐨凙GV
+        available_agvs = self.agv_manager.get_available_agvs()
+        
+        if not available_agvs:
+            self.logger.warning("娌℃湁鍙敤鐨凙GV杩涜浠诲姟鍒嗛厤")
+            return []
+        
+        # 1. 棣栧厛妫�鏌ヤ换鍔℃槸鍚﹀凡缁忓垎閰嶏紝閬垮厤閲嶅鍒嗛厤
+        already_assigned_tasks = set()
+        all_agvs = self.agv_manager.get_all_agvs()
+        for agv in all_agvs:
+            if agv.backpack:
+                for backpack_item in agv.backpack:
+                    if backpack_item.taskId:
+                        already_assigned_tasks.add(backpack_item.taskId)
+                        self.logger.info(f"浠诲姟 {backpack_item.taskId} 宸插垎閰嶇粰 AGV {agv.agvId}锛岃烦杩囬噸澶嶅垎閰�")
+        
+        # 2. 杩囨护鎺夊凡鍒嗛厤鐨勪换鍔�
+        unassigned_tasks = [task for task in tasks if task.taskId not in already_assigned_tasks]
+        
+        if not unassigned_tasks:
+            self.logger.info("鎵�鏈変换鍔¢兘宸插垎閰嶏紝鏃犻渶閲嶆柊鍒嗛厤")
+            return []
+        
+        self.logger.info(f"鎬讳换鍔℃暟: {len(tasks)}, 宸插垎閰�: {len(already_assigned_tasks)}, 寰呭垎閰�: {len(unassigned_tasks)}")
+        
+        # 鎸変紭鍏堢骇鎺掑簭浠诲姟锛堥珮浼樺厛绾у湪鍓嶏級
+        sorted_tasks = sorted(unassigned_tasks, key=lambda t: t.priority, reverse=True)
+        
+        assignments = []
+        path_mapping = self.agv_manager.path_mapping
+        
+        # 浼樺厛鍒嗛厤楂樹紭鍏堢骇浠诲姟
+        for task in sorted_tasks:
+            if not available_agvs:
+                break
+                
+            # 鑾峰彇浠诲姟璧风偣鍧愭爣
+            task_start_coord = get_coordinate_from_path_id(task.start, path_mapping)
+            if not task_start_coord:
+                self.logger.warning(f"鏃犳硶鑾峰彇浠诲姟 {task.taskId} 璧风偣 {task.start} 鐨勫潗鏍�")
+                continue
+            
+            # 涓洪珮浼樺厛绾т换鍔¢�夋嫨鏈�浣矨GV
+            best_agv = None
+            best_score = -1
+            
+            for agv in available_agvs:
+                if not agv.can_accept_task(task.priority):
+                    continue
+                
+                # 璁$畻缁煎悎寰楀垎
+                distance_score = 0.0
+                if agv.coordinates and task_start_coord:
+                    distance = calculate_manhattan_distance(agv.coordinates, task_start_coord)
+                    distance_score = 1.0 / (1.0 + distance / 50.0)
+                
+                efficiency_score = agv.calculate_efficiency_score(path_mapping)
+                capacity_score = agv.get_task_capacity() / agv.max_capacity
+                
+                # 楂樹紭鍏堢骇浠诲姟鏇存敞閲嶆晥鐜囧拰璺濈
+                total_score = 0.5 * distance_score + 0.3 * efficiency_score + 0.2 * capacity_score
+                
+                if total_score > best_score:
+                    best_score = total_score
+                    best_agv = agv
+            
+            if best_agv:
+                # 鑾峰彇AGV鐨勫師濮嬬姸鎬佹暟鎹潵鏌ユ壘鍙敤鑳岀瘬浣嶇疆
+                agv_status = self.agv_manager.get_agv_status(best_agv.agvId)
+                
+                if agv_status:
+                    # 鏌ユ壘鍙敤鐨勮儗绡撲綅缃�
+                    available_lev_id = self.find_available_backpack_slot(agv_status)
+                    
+                    if available_lev_id is not None:
+                        # 鍒嗛厤浠诲姟鍒版寚瀹氳儗绡撲綅缃�
+                        success = self.assign_task_with_backpack(best_agv, task, available_lev_id)
+                        if success:
+                            assignments.append(TaskAssignment(
+                                taskId=task.taskId,
+                                agvId=best_agv.agvId,
+                                lev_id=available_lev_id
+                            ))
+                            
+                            self.logger.info(f"楂樹紭鍏堢骇浠诲姟 {task.taskId} (浼樺厛绾�: {task.priority}) 鍒嗛厤缁橝GV {best_agv.agvId}锛岃儗绡撲綅缃�: {available_lev_id}")
+                            
+                            # 妫�鏌GV鏄惁杩樻湁鍙敤鑳岀瘬浣嶇疆
+                            remaining_capacity = self.get_agv_available_capacity(agv_status) - 1
+                            if remaining_capacity <= 0:
+                                available_agvs.remove(best_agv)
+                        else:
+                            self.logger.warning(f"浠诲姟 {task.taskId} 鍒嗛厤缁橝GV {best_agv.agvId} 澶辫触")
+                    else:
+                        self.logger.warning(f"AGV {best_agv.agvId} 娌℃湁鍙敤鐨勮儗绡撲綅缃�")
+                        available_agvs.remove(best_agv)
+                else:
+                    self.logger.warning(f"鏃犳硶鑾峰彇AGV {best_agv.agvId} 鐨勭姸鎬佷俊鎭�")
+        
+        return assignments
+
+
+class MultiObjectiveAllocation(TaskAllocation):
+    """澶氱洰鏍囦紭鍖栧垎閰嶇畻娉�"""
+    
+    def __init__(self, agv_manager: AGVModelManager, 
+                 distance_weight: float = 0.4, 
+                 load_weight: float = 0.3, 
+                 efficiency_weight: float = 0.3):
+        """
+        鍒濆鍖栧鐩爣浼樺寲鍒嗛厤绠楁硶
+        
+        Args:
+            agv_manager: AGV妯″瀷绠$悊鍣�
+            distance_weight: 璺濈鏉冮噸
+            load_weight: 璐熻浇鏉冮噸
+            efficiency_weight: 鏁堢巼鏉冮噸
+        """
+        super().__init__(agv_manager)
+        self.distance_weight = distance_weight
+        self.load_weight = load_weight
+        self.efficiency_weight = efficiency_weight
+    
+    def allocate_tasks(self, tasks: List[TaskData]) -> List[TaskAssignment]:
+        """
+        浣跨敤澶氱洰鏍囦紭鍖栫瓥鐣ュ垎閰嶄换鍔�
+        
+        Args:
+            tasks: 寰呭垎閰嶇殑浠诲姟鍒楄〃
+            
+        Returns:
+            List[TaskAssignment]: 鍒嗛厤缁撴灉鍒楄〃
+        """
+        if not tasks:
+            return []
+        
+        # 鑾峰彇鎵�鏈堿GV
+        all_agvs = self.agv_manager.get_all_agvs()
+        
+        if not all_agvs:
+            self.logger.warning("娌℃湁AGV杩涜浠诲姟鍒嗛厤")
+            return []
+        
+        # 1. 棣栧厛妫�鏌ヤ换鍔℃槸鍚﹀凡缁忓垎閰嶏紝閬垮厤閲嶅鍒嗛厤
+        already_assigned_tasks = set()
+        for agv in all_agvs:
+            if agv.backpack:
+                for backpack_item in agv.backpack:
+                    if backpack_item.taskId:
+                        already_assigned_tasks.add(backpack_item.taskId)
+                        self.logger.info(f"浠诲姟 {backpack_item.taskId} 宸插垎閰嶇粰 AGV {agv.agvId}锛岃烦杩囬噸澶嶅垎閰�")
+        
+        # 2. 杩囨护鎺夊凡鍒嗛厤鐨勪换鍔�
+        unassigned_tasks = [task for task in tasks if task.taskId not in already_assigned_tasks]
+        
+        if not unassigned_tasks:
+            self.logger.info("鎵�鏈変换鍔¢兘宸插垎閰嶏紝鏃犻渶閲嶆柊鍒嗛厤")
+            return []
+        
+        self.logger.info(f"鎬讳换鍔℃暟: {len(tasks)}, 宸插垎閰�: {len(already_assigned_tasks)}, 寰呭垎閰�: {len(unassigned_tasks)}")
+        
+        assignments = []
+        path_mapping = self.agv_manager.path_mapping
+        
+        # 瀵规瘡涓换鍔�-AGV瀵硅绠楀緱鍒�
+        task_agv_scores = {}
+        
+        for task in unassigned_tasks:
+            task_start_coord = get_coordinate_from_path_id(task.start, path_mapping)
+            if not task_start_coord:
+                continue
+                
+            for agv in all_agvs:
+                if not agv.can_accept_task(task.priority):
+                    continue
+                
+                # 璺濈寰楀垎
+                distance_score = 0.0
+                if agv.coordinates:
+                    distance = calculate_manhattan_distance(agv.coordinates, task_start_coord)
+                    distance_score = 1.0 / (1.0 + distance / 100.0)
+                
+                # 璐熻浇寰楀垎
+                load_score = 1.0 - agv.get_workload_ratio()
+                
+                # 鏁堢巼寰楀垎
+                efficiency_score = agv.calculate_efficiency_score(path_mapping)
+                
+                # 璁$畻缁煎悎寰楀垎
+                total_score = (
+                    self.distance_weight * distance_score +
+                    self.load_weight * load_score +
+                    self.efficiency_weight * efficiency_score
+                )
+                
+                task_agv_scores[(task.taskId, agv.agvId)] = total_score
+        
+        # 浣跨敤璐績绠楁硶杩涜鍖归厤
+        assignments = self._greedy_matching(unassigned_tasks, all_agvs, task_agv_scores)
+        
+        return assignments
+    
+    def _greedy_matching(self, tasks: List[TaskData], agvs: List[AGVModel], 
+                        scores: Dict[Tuple[str, str], float]) -> List[TaskAssignment]:
+        """
+        浣跨敤璐績绠楁硶杩涜浠诲姟-AGV鍖归厤
+        
+        Args:
+            tasks: 浠诲姟鍒楄〃
+            agvs: AGV鍒楄〃
+            scores: 浠诲姟-AGV瀵圭殑寰楀垎
+            
+        Returns:
+            List[TaskAssignment]: 鍒嗛厤缁撴灉
+        """
+        assignments = []
+        remaining_tasks = [task.taskId for task in tasks]
+        
+        # 閲嶅鍒嗛厤鐩村埌娌℃湁浠诲姟鎴栨病鏈夊彲鐢ˋGV
+        while remaining_tasks:
+            # 鎵惧埌寰楀垎鏈�楂樼殑浠诲姟-AGV瀵�
+            best_score = -1
+            best_task_id = None
+            best_agv = None
+            
+            for task_id in remaining_tasks:
+                for agv in agvs:
+                    if agv.is_overloaded():
+                        continue
+                        
+                    score = scores.get((task_id, agv.agvId), 0.0)
+                    if score > best_score:
+                        best_score = score
+                        best_task_id = task_id
+                        best_agv = agv
+            
+            if best_task_id and best_agv:
+                # 鑾峰彇AGV鐨勫師濮嬬姸鎬佹暟鎹潵鏌ユ壘鍙敤鑳岀瘬浣嶇疆
+                agv_status = self.agv_manager.get_agv_status(best_agv.agvId)
+                
+                if agv_status:
+                    # 鏌ユ壘鍙敤鐨勮儗绡撲綅缃�
+                    available_lev_id = self.find_available_backpack_slot(agv_status)
+                    
+                    if available_lev_id is not None:
+                        # 鎵惧埌瀵瑰簲鐨勪换鍔″璞�
+                        task = next((t for t in tasks if t.taskId == best_task_id), None)
+                        if task:
+                            # 鍒嗛厤浠诲姟鍒版寚瀹氳儗绡撲綅缃�
+                            success = self.assign_task_with_backpack(best_agv, task, available_lev_id)
+                            if success:
+                                assignments.append(TaskAssignment(
+                                    taskId=best_task_id,
+                                    agvId=best_agv.agvId,
+                                    lev_id=available_lev_id
+                                ))
+                                
+                                remaining_tasks.remove(best_task_id)
+                                self.logger.info(f"澶氱洰鏍囦紭鍖栵細浠诲姟 {best_task_id} 鍒嗛厤缁橝GV {best_agv.agvId}锛岃儗绡撲綅缃�: {available_lev_id}锛屽緱鍒�: {best_score:.3f}")
+                            else:
+                                self.logger.warning(f"浠诲姟 {best_task_id} 鍒嗛厤缁橝GV {best_agv.agvId} 澶辫触")
+                                break
+                        else:
+                            self.logger.error(f"鎵句笉鍒颁换鍔� {best_task_id} 鐨勮缁嗕俊鎭�")
+                            break
+                    else:
+                        self.logger.debug(f"AGV {best_agv.agvId} 娌℃湁鍙敤鐨勮儗绡撲綅缃紝璺宠繃")
+                        break
+                else:
+                    self.logger.warning(f"鏃犳硶鑾峰彇AGV {best_agv.agvId} 鐨勭姸鎬佷俊鎭�")
+                    break
+            else:
+                break
+        
+        return assignments
+
+
+class TaskAllocationFactory:
+    """浠诲姟鍒嗛厤绠楁硶宸ュ巶绫�"""
+    
+    @staticmethod
+    def create_allocator(algorithm_type: str, agv_manager: AGVModelManager) -> TaskAllocation:
+        """
+        鍒涘缓浠诲姟鍒嗛厤绠楁硶
+        
+        Args:
+            algorithm_type: 绠楁硶绫诲瀷
+            agv_manager: AGV妯″瀷绠$悊鍣�
+            
+        Returns:
+            TaskAllocation: 浠诲姟鍒嗛厤绠楁硶瀵硅薄
+        """
+        if algorithm_type == "NEAREST_FIRST":
+            return NearestFirstAllocation(agv_manager)
+        elif algorithm_type == "LOAD_BALANCED":
+            return LoadBalancedAllocation(agv_manager)
+        elif algorithm_type == "PRIORITY_FIRST":
+            return PriorityFirstAllocation(agv_manager)
+        elif algorithm_type == "MULTI_OBJECTIVE":
+            return MultiObjectiveAllocation(agv_manager)
+        else:
+            # 榛樿浣跨敤璐熻浇鍧囪 绠楁硶
+            return LoadBalancedAllocation(agv_manager) 
\ No newline at end of file
diff --git a/algorithm_system/models/__init__.py b/algorithm_system/models/__init__.py
new file mode 100644
index 0000000..d63e257
--- /dev/null
+++ b/algorithm_system/models/__init__.py
@@ -0,0 +1,2 @@
+# Algorithm System Models Module
+__version__ = "1.0.0" 
\ No newline at end of file
diff --git a/algorithm_system/models/agv_model.py b/algorithm_system/models/agv_model.py
new file mode 100644
index 0000000..6131862
--- /dev/null
+++ b/algorithm_system/models/agv_model.py
@@ -0,0 +1,572 @@
+"""
+AGV妯″瀷 - 鐢ㄤ簬绠楁硶绯荤粺鐨凙GV鏁版嵁寤烘ā
+"""
+import time
+import logging
+from typing import Dict, List, Optional, Tuple, Set
+from dataclasses import dataclass, field
+from enum import Enum
+
+from common.data_models import AGVStatus, BackpackData
+from common.utils import get_coordinate_from_path_id, calculate_manhattan_distance
+
+
+class AGVTaskStatus(Enum):
+    """AGV浠诲姟鐘舵��"""
+    IDLE = "IDLE"           # 绌洪棽
+    ASSIGNED = "ASSIGNED"   # 宸插垎閰嶄换鍔′絾鏈紑濮�
+    EXECUTING = "EXECUTING" # 鎵ц涓�
+    COMPLETED = "COMPLETED" # 宸插畬鎴�
+
+
+@dataclass
+class TaskAssignment:
+    """浠诲姟鍒嗛厤淇℃伅"""
+    task_id: str
+    assigned_time: float
+    priority: int
+    status: AGVTaskStatus = AGVTaskStatus.ASSIGNED
+    start_code: Optional[str] = None
+    end_code: Optional[str] = None
+    estimated_duration: Optional[float] = None
+
+
+class AGVModel:
+    """AGV妯″瀷绫伙紝鐢ㄤ簬绠楁硶璁$畻"""
+    
+    def __init__(self, agv_id: str, path_mapping: Dict[str, Dict[str, int]]):
+        """
+        鍒濆鍖朅GV妯″瀷
+        
+        Args:
+            agv_id: AGV ID
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+        """
+        self.agvId = agv_id
+        self.path_mapping = path_mapping
+        self.logger = logging.getLogger(__name__)
+        
+        # AGV鐘舵�佷俊鎭�
+        self.status: str = "0"  # AGV鐘舵�佺爜
+        self.mapCode: str = ""  # 褰撳墠浣嶇疆鐮�
+        self.coordinates: Optional[Tuple[int, int]] = None  # 褰撳墠鍧愭爣
+        self.backpack: Optional[List[BackpackData]] = None  # 鑳屽寘淇℃伅
+        
+        # 鍏呯數鐩稿叧
+        self.voltage: int = 100  # 褰撳墠鐢甸噺鐧惧垎姣�
+        self.autoCharge: int = 20  # 浣庣數閲忚瀹氶槇鍊�
+        self.lowVol: int = 10  # 鏈�浣庣數閲忛槇鍊�
+        
+        # 浠诲姟鐩稿叧
+        self.assigned_tasks: List[TaskAssignment] = []
+        self.current_task_count: int = 0
+        self.max_capacity: int = 5  # 鏈�澶т换鍔″閲�
+        
+        # 鎬ц兘鐩稿叧
+        self.efficiency_score: float = 1.0  # 鏁堢巼寰楀垎
+        self.last_update_time: float = time.time()
+        
+        # 缁熻淇℃伅
+        self.total_completed_tasks: int = 0
+        self.total_distance_traveled: float = 0.0
+        self.average_completion_time: float = 0.0
+    
+    def update_from_agv_status(self, agv_status: AGVStatus):
+        """浠嶢GV鐘舵�佹洿鏂版ā鍨�"""
+        self.status = agv_status.status
+        if hasattr(agv_status, 'position'):
+            self.mapCode = agv_status.position
+        elif hasattr(agv_status, 'mapCode'):
+            self.mapCode = agv_status.mapCode
+        else:
+            self.mapCode = ""
+        
+        self.backpack = agv_status.backpack
+        self.last_update_time = time.time()
+        
+        raw_voltage = getattr(agv_status, 'vol', 100)
+        raw_auto_charge = getattr(agv_status, 'autoCharge', 20)
+        raw_low_vol = getattr(agv_status, 'lowVol', 10)
+        
+        # 鐢甸噺鏁版嵁鏍囧噯鍖栧鐞�
+        # 濡傛灉鐢靛帇鍊煎ぇ浜�100锛屽彲鑳芥槸姣紡鍊硷紝闇�瑕佽浆鎹负鐧惧垎姣�
+        if raw_voltage > 100:
+            # 鍋囪姝e父鐢靛帇鑼冨洿鏄�3000-5000mV锛岃浆鎹负0-100%
+            # 杩欓噷浣跨敤绠�鍗曠殑绾挎�ф槧灏�
+            normalized_voltage = max(0, min(100, ((raw_voltage - 3000) / 2000) * 100))
+            self.logger.debug(f"AGV {self.agvId} 鐢靛帇鏍囧噯鍖�: {raw_voltage}mV -> {normalized_voltage:.1f}%")
+            self.voltage = int(normalized_voltage)
+        else:
+            self.voltage = raw_voltage
+        
+        # 闃堝�兼爣鍑嗗寲澶勭悊
+        if raw_auto_charge > 100:
+            # 濡傛灉闃堝�间篃鏄浼忓�硷紝鍚屾牱杞崲
+            self.autoCharge = max(0, min(100, ((raw_auto_charge - 3000) / 2000) * 100))
+            self.logger.debug(f"AGV {self.agvId} 鑷姩鍏呯數闃堝�兼爣鍑嗗寲: {raw_auto_charge}mV -> {self.autoCharge:.1f}%")
+        else:
+            self.autoCharge = raw_auto_charge
+            
+        if raw_low_vol > 100:
+            # 濡傛灉鏈�浣庣數閲忛槇鍊间篃鏄浼忓�硷紝鍚屾牱杞崲
+            self.lowVol = max(0, min(100, ((raw_low_vol - 3000) / 2000) * 100))
+            self.logger.debug(f"AGV {self.agvId} 鏈�浣庣數閲忛槇鍊兼爣鍑嗗寲: {raw_low_vol}mV -> {self.lowVol:.1f}%")
+        else:
+            self.lowVol = raw_low_vol
+        
+        # 鏇存柊鍧愭爣
+        if self.mapCode:
+            self.coordinates = get_coordinate_from_path_id(self.mapCode, self.path_mapping)
+        
+        # 鏍规嵁AGV鐘舵�佹洿鏂颁换鍔¤鏁�
+        if self.backpack and self.backpack:
+            self.current_task_count = len([bp for bp in self.backpack if bp.execute])
+        else:
+            self.current_task_count = 0
+    
+    def assign_task(self, task_id: str, priority: int = 5, 
+                   start_code: str = "", end_code: str = "") -> bool:
+        """
+        鍒嗛厤浠诲姟缁橝GV
+        
+        Args:
+            task_id: 浠诲姟ID
+            priority: 浠诲姟浼樺厛绾�
+            start_code: 璧峰浣嶇疆鐮�
+            end_code: 缁撴潫浣嶇疆鐮�
+            
+        Returns:
+            bool: 鏄惁鍒嗛厤鎴愬姛
+        """
+        if self.is_overloaded():
+            self.logger.warning(f"AGV {self.agvId} 宸叉弧杞斤紝鏃犳硶鍒嗛厤鏇村浠诲姟")
+            return False
+        
+        # 鍒涘缓浠诲姟鍒嗛厤璁板綍
+        task_assignment = TaskAssignment(
+            task_id=task_id,
+            assigned_time=time.time(),
+            priority=priority,
+            start_code=start_code,
+            end_code=end_code
+        )
+        
+        self.assigned_tasks.append(task_assignment)
+        self.current_task_count += 1
+        
+        self.logger.info(f"浠诲姟 {task_id} 宸插垎閰嶇粰AGV {self.agvId}")
+        return True
+    
+    def complete_task(self, task_id: str) -> bool:
+        """
+        瀹屾垚浠诲姟
+        
+        Args:
+            task_id: 浠诲姟ID
+            
+        Returns:
+            bool: 鏄惁瀹屾垚鎴愬姛
+        """
+        for task in self.assigned_tasks:
+            if task.task_id == task_id:
+                task.status = AGVTaskStatus.COMPLETED
+                self.current_task_count = max(0, self.current_task_count - 1)
+                self.total_completed_tasks += 1
+                
+                self.logger.info(f"AGV {self.agvId} 瀹屾垚浠诲姟 {task_id}")
+                return True
+        
+        return False
+    
+    def can_accept_task(self, priority: int) -> bool:
+        """
+        妫�鏌ユ槸鍚﹀彲浠ユ帴鍙楁柊浠诲姟
+        
+        Args:
+            priority: 浠诲姟浼樺厛绾�
+            
+        Returns:
+            bool: 鏄惁鍙互鎺ュ彈
+        """
+        # 妫�鏌ュ閲�
+        if self.is_overloaded():
+            self.logger.debug(f"AGV {self.agvId} 浠诲姟宸叉弧杞�({self.current_task_count}/{self.max_capacity})锛屾嫆缁濇柊浠诲姟")
+            return False
+        
+        # 妫�鏌GV鐘舵�侊紙鍏煎鏁存暟鍜屽瓧绗︿覆鏍煎紡锛�
+        # 鐘舵�� 0(绌洪棽), 1(蹇欑), 2(鍏呯數) 鍙互鎺ュ彈浠诲姟
+        # 鐘舵�� 3(鏁呴殰), 4(缁存姢) 涓嶈兘鎺ュ彈浠诲姟
+        status_value = str(self.status)  # 缁熶竴杞崲涓哄瓧绗︿覆杩涜姣旇緝
+        if status_value not in ["0", "1", "2"]:
+            self.logger.debug(f"AGV {self.agvId} 鐘舵�佸紓甯�(status={status_value})锛屾嫆缁濇柊浠诲姟")
+            return False
+        
+        # 妫�鏌ュ厖鐢电姸鎬� - 濡傛灉鐢甸噺杩囦綆蹇呴』鍏呯數锛屼笉鑳芥帴鍙楁柊浠诲姟
+        if self.need_charging():
+            self.logger.debug(f"AGV {self.agvId} 鐢甸噺杩囦綆({self.voltage}% <= {self.lowVol}%)锛屽繀椤诲厖鐢碉紝鎷掔粷鏂颁换鍔�")
+            return False
+        
+        # 濡傛灉鏄珮浼樺厛绾т换鍔★紝鍗充娇浣庣數閲忎篃鍙互鎺ュ彈
+        if priority >= 9:  # 楂樹紭鍏堢骇浠诲姟闃堝��
+            self.logger.debug(f"AGV {self.agvId} 鎺ュ彈楂樹紭鍏堢骇浠诲姟(priority={priority})")
+            return True
+        
+        # 瀵逛簬鏅�氫紭鍏堢骇浠诲姟锛屽鏋滅數閲忎綆浣嗕笉鏄繀椤诲厖鐢碉紝鍙互鏍规嵁浼樺厛绾у喅瀹�
+        if self.can_auto_charge():
+            # 浼樺厛绾ц秺楂橈紝瓒婂�惧悜浜庢帴鍙椾换鍔�
+            if priority >= 5:  # 涓珮浼樺厛绾�
+                self.logger.debug(f"AGV {self.agvId} 鎺ュ彈涓珮浼樺厛绾т换鍔�(priority={priority}, 鐢甸噺={self.voltage}%)")
+                return True
+            elif priority >= 3:  # 涓瓑浼樺厛绾э紝75%姒傜巼鎺ュ彈
+                import random
+                accept = random.random() < 0.75
+                self.logger.debug(f"AGV {self.agvId} 闅忔満鍐冲畾{'鎺ュ彈' if accept else '鎷掔粷'}涓瓑浼樺厛绾т换鍔�(priority={priority}, 鐢甸噺={self.voltage}%)")
+                return accept
+            elif priority >= 1:  # 浣庝紭鍏堢骇锛�50%姒傜巼鎺ュ彈锛堝寘鎷紭鍏堢骇1锛�
+                import random
+                accept = random.random() < 0.5
+                self.logger.debug(f"AGV {self.agvId} 闅忔満鍐冲畾{'鎺ュ彈' if accept else '鎷掔粷'}浣庝紭鍏堢骇浠诲姟(priority={priority}, 鐢甸噺={self.voltage}%)")
+                return accept
+            else:  # 鏋佷綆浼樺厛绾э紙priority=0锛夛紝鎷掔粷
+                self.logger.debug(f"AGV {self.agvId} 鐢甸噺鍋忎綆({self.voltage}%)锛屾嫆缁濇瀬浣庝紭鍏堢骇浠诲姟(priority={priority})")
+                return False
+        
+        # 姝e父鎯呭喌涓嬪彲浠ユ帴鍙椾换鍔�
+        self.logger.debug(f"AGV {self.agvId} 鐘舵�佽壇濂斤紝鍙互鎺ュ彈浠诲姟(鐢甸噺={self.voltage}%, priority={priority})")
+        return True
+    
+    def is_overloaded(self) -> bool:
+        """
+        妫�鏌ユ槸鍚﹁繃杞�
+        
+        Returns:
+            bool: 鏄惁杩囪浇
+        """
+        return self.current_task_count >= self.max_capacity
+    
+    def get_workload_ratio(self) -> float:
+        """
+        鑾峰彇宸ヤ綔璐熻浇姣斾緥
+        
+        Returns:
+            float: 宸ヤ綔璐熻浇姣斾緥 (0.0 - 1.0)
+        """
+        return min(1.0, self.current_task_count / self.max_capacity)
+    
+    def get_task_capacity(self) -> int:
+        """
+        鑾峰彇鍓╀綑浠诲姟瀹归噺
+        
+        Returns:
+            int: 鍓╀綑瀹归噺
+        """
+        return max(0, self.max_capacity - self.current_task_count)
+    
+    def need_charging(self) -> bool:
+        """
+        妫�鏌ユ槸鍚﹂渶瑕佸厖鐢�
+        
+        Returns:
+            bool: 鏄惁闇�瑕佸厖鐢�
+        """
+        return self.voltage <= self.lowVol
+    
+    def can_auto_charge(self) -> bool:
+        """
+        妫�鏌ユ槸鍚﹀彲浠ヨ嚜鍔ㄥ厖鐢碉紙浣庝簬闃堝�间絾涓嶆槸蹇呴』鍏呯數锛�
+        
+        Returns:
+            bool: 鏄惁鍙互鑷姩鍏呯數
+        """
+        return self.lowVol < self.voltage <= self.autoCharge
+    
+    def is_low_power(self) -> bool:
+        """
+        妫�鏌ユ槸鍚︿负浣庣數閲忕姸鎬�
+        
+        Returns:
+            bool: 鏄惁涓轰綆鐢甸噺鐘舵��
+        """
+        return self.voltage <= self.autoCharge
+    
+    def get_charging_priority(self) -> int:
+        """
+        鑾峰彇鍏呯數浼樺厛绾э紙鏁板�艰秺澶т紭鍏堢骇瓒婇珮锛�
+        
+        Returns:
+            int: 鍏呯數浼樺厛绾�
+        """
+        if self.need_charging():
+            return 100  # 蹇呴』鍏呯數锛屾渶楂樹紭鍏堢骇
+        elif self.can_auto_charge():
+            return 50 + (self.autoCharge - self.voltage)  # 鏍规嵁鐢甸噺宸绠椾紭鍏堢骇
+        else:
+            return 0  # 鏃犻渶鍏呯數
+    
+    def calculate_efficiency_score(self, path_mapping: Dict[str, Dict[str, int]]) -> float:
+        """
+        璁$畻AGV鏁堢巼寰楀垎
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏�
+            
+        Returns:
+            float: 鏁堢巼寰楀垎 (0.0 - 1.0)
+        """
+        # 鍩虹鏁堢巼鍒嗘暟
+        base_score = 0.7
+        
+        # 鏍规嵁瀹屾垚浠诲姟鏁伴噺璋冩暣
+        if self.total_completed_tasks > 0:
+            completion_bonus = min(0.2, self.total_completed_tasks * 0.01)
+            base_score += completion_bonus
+        
+        # 鏍规嵁璐熻浇鎯呭喌璋冩暣
+        load_ratio = self.get_workload_ratio()
+        if load_ratio < 0.8:  # 璐熻浇涓嶅お楂樻椂鏁堢巼鏇撮珮
+            load_bonus = (0.8 - load_ratio) * 0.1
+            base_score += load_bonus
+        
+        # 鏍规嵁AGV鐘舵�佽皟鏁�
+        if self.status == "0":  # 姝e父鐘舵��
+            base_score += 0.1
+        elif self.status in ["3", "4"]:  # 寮傚父鐘舵��
+            base_score -= 0.2
+        
+        # 鏃堕棿鍥犲瓙锛氭渶杩戞洿鏂扮殑AGV寰楀垎鏇撮珮
+        time_since_update = time.time() - self.last_update_time
+        if time_since_update < 60:  # 1鍒嗛挓鍐呮洿鏂�
+            time_bonus = (60 - time_since_update) / 600  # 鏈�澶氬姞0.1
+            base_score += time_bonus
+        
+        return max(0.0, min(1.0, base_score))
+    
+    def estimate_travel_time(self, target_code: str) -> float:
+        """
+        浼扮畻鍒扮洰鏍囦綅缃殑琛岄┒鏃堕棿
+        
+        Args:
+            target_code: 鐩爣浣嶇疆鐮�
+            
+        Returns:
+            float: 浼扮畻鏃堕棿锛堢锛�
+        """
+        if not self.coordinates:
+            return float('inf')
+        
+        target_coord = get_coordinate_from_path_id(target_code, self.path_mapping)
+        if not target_coord:
+            return float('inf')
+        
+        # 璁$畻鏇煎搱椤胯窛绂�
+        distance = calculate_manhattan_distance(self.coordinates, target_coord)
+        
+        # 鍋囪AGV骞冲潎閫熷害涓�1鍗曚綅/绉�
+        estimated_time = distance * 1.0
+        
+        # 鑰冭檻褰撳墠璐熻浇瀵归�熷害鐨勫奖鍝�
+        load_factor = 1.0 + (self.get_workload_ratio() * 0.2)
+        
+        return estimated_time * load_factor
+    
+    def get_task_by_id(self, task_id: str) -> Optional[TaskAssignment]:
+        """
+        鏍规嵁浠诲姟ID鑾峰彇浠诲姟鍒嗛厤淇℃伅
+        
+        Args:
+            task_id: 浠诲姟ID
+            
+        Returns:
+            Optional[TaskAssignment]: 浠诲姟鍒嗛厤淇℃伅
+        """
+        for task in self.assigned_tasks:
+            if task.task_id == task_id:
+                return task
+        return None
+    
+    def get_pending_tasks(self) -> List[TaskAssignment]:
+        """
+        鑾峰彇寰呮墽琛岀殑浠诲姟
+        
+        Returns:
+            List[TaskAssignment]: 寰呮墽琛屼换鍔″垪琛�
+        """
+        return [task for task in self.assigned_tasks 
+                if task.status in [AGVTaskStatus.ASSIGNED, AGVTaskStatus.EXECUTING]]
+    
+    def clear_completed_tasks(self):
+        """娓呯悊宸插畬鎴愮殑浠诲姟"""
+        self.assigned_tasks = [task for task in self.assigned_tasks 
+                              if task.status != AGVTaskStatus.COMPLETED]
+    
+    def __str__(self) -> str:
+        """瀛楃涓茶〃绀�"""
+        return (f"AGV({self.agvId}, status={self.status}, "
+                f"pos={self.mapCode}, tasks={self.current_task_count}/{self.max_capacity})")
+
+
+class AGVModelManager:
+    """AGV妯″瀷绠$悊鍣�"""
+    
+    def __init__(self, path_mapping: Dict[str, Dict[str, int]]):
+        """
+        鍒濆鍖朅GV妯″瀷绠$悊鍣�
+        
+        Args:
+            path_mapping: 璺緞鐐规槧灏勫瓧鍏�
+        """
+        self.path_mapping = path_mapping
+        self.agv_models: Dict[str, AGVModel] = {}
+        self.agv_status_data: Dict[str, AGVStatus] = {}  # 瀛樺偍鍘熷AGV鐘舵�佹暟鎹�
+        self.logger = logging.getLogger(__name__)
+    
+    def update_agv_data(self, agv_status_list: List[AGVStatus]):
+        """
+        鏇存柊AGV鏁版嵁
+        
+        Args:
+            agv_status_list: AGV鐘舵�佸垪琛�
+        """
+        # 鑾峰彇褰撳墠鏇存柊鐨凙GV ID鍒楄〃
+        current_agv_ids = {agv_status.agvId for agv_status in agv_status_list}
+        
+        # 绉婚櫎涓嶅啀瀛樺湪鐨凙GV妯″瀷鍜岀姸鎬佹暟鎹�
+        removed_agvs = []
+        for agv_id in list(self.agv_models.keys()):
+            if agv_id not in current_agv_ids:
+                removed_agvs.append(agv_id)
+                del self.agv_models[agv_id]
+                if agv_id in self.agv_status_data:
+                    del self.agv_status_data[agv_id]
+        
+        if removed_agvs:
+            self.logger.info(f"绉婚櫎涓嶅瓨鍦ㄧ殑AGV: {removed_agvs}")
+        
+        # 鏇存柊鎴栧垱寤篈GV妯″瀷鍜岀姸鎬佹暟鎹�
+        for agv_status in agv_status_list:
+            agv_id = agv_status.agvId
+            
+            # 瀛樺偍鍘熷AGV鐘舵�佹暟鎹�
+            self.agv_status_data[agv_id] = agv_status
+            
+            # 濡傛灉AGV妯″瀷涓嶅瓨鍦紝鍒涘缓鏂扮殑
+            if agv_id not in self.agv_models:
+                self.agv_models[agv_id] = AGVModel(agv_id, self.path_mapping)
+                self.logger.info(f"鍒涘缓鏂扮殑AGV妯″瀷: {agv_id}")
+            
+            # 鏇存柊AGV妯″瀷
+            self.agv_models[agv_id].update_from_agv_status(agv_status)
+        
+        self.logger.debug(f"鏇存柊浜� {len(agv_status_list)} 涓狝GV妯″瀷锛屽綋鍓嶆�绘暟: {len(self.agv_models)}")
+    
+    def get_all_agv_status(self) -> List[AGVStatus]:
+        """
+        鑾峰彇鎵�鏈堿GV鐨勫師濮嬬姸鎬佹暟鎹�
+        
+        Returns:
+            List[AGVStatus]: AGV鐘舵�佹暟鎹垪琛�
+        """
+        return list(self.agv_status_data.values())
+    
+    def get_agv_status(self, agv_id: str) -> Optional[AGVStatus]:
+        """
+        鑾峰彇鎸囧畾AGV鐨勫師濮嬬姸鎬佹暟鎹�
+        
+        Args:
+            agv_id: AGV ID
+            
+        Returns:
+            Optional[AGVStatus]: AGV鐘舵�佹暟鎹�
+        """
+        return self.agv_status_data.get(agv_id)
+    
+    def get_agv_model(self, agv_id: str) -> Optional[AGVModel]:
+        """
+        鑾峰彇AGV妯″瀷
+        
+        Args:
+            agv_id: AGV ID
+            
+        Returns:
+            Optional[AGVModel]: AGV妯″瀷
+        """
+        return self.agv_models.get(agv_id)
+    
+    def get_all_agvs(self) -> List[AGVModel]:
+        """
+        鑾峰彇鎵�鏈堿GV妯″瀷
+        
+        Returns:
+            List[AGVModel]: AGV妯″瀷鍒楄〃
+        """
+        return list(self.agv_models.values())
+    
+    def get_available_agvs(self) -> List[AGVModel]:
+        """
+        鑾峰彇鍙敤鐨凙GV妯″瀷锛堟湭婊¤浇涓旂姸鎬佹甯革級
+        
+        Returns:
+            List[AGVModel]: 鍙敤AGV妯″瀷鍒楄〃
+        """
+        available_agvs = []
+        for agv in self.agv_models.values():
+            if not agv.is_overloaded() and agv.can_accept_task(5):
+                available_agvs.append(agv)
+        
+        return available_agvs
+    
+    def get_agvs_by_status(self, status: str) -> List[AGVModel]:
+        """
+        鏍规嵁鐘舵�佽幏鍙朅GV鍒楄〃
+        
+        Args:
+            status: AGV鐘舵��
+            
+        Returns:
+            List[AGVModel]: 绗﹀悎鐘舵�佺殑AGV鍒楄〃
+        """
+        return [agv for agv in self.agv_models.values() if agv.status == status]
+    
+    def cleanup_old_agvs(self, max_age_seconds: float = 300):
+        """
+        娓呯悊闀挎椂闂存湭鏇存柊鐨凙GV
+        
+        Args:
+            max_age_seconds: 鏈�澶у厑璁哥殑鏈洿鏂版椂闂达紙绉掞級
+        """
+        current_time = time.time()
+        old_agvs = []
+        
+        for agv_id, agv in self.agv_models.items():
+            if current_time - agv.last_update_time > max_age_seconds:
+                old_agvs.append(agv_id)
+        
+        for agv_id in old_agvs:
+            del self.agv_models[agv_id]
+            self.logger.info(f"娓呯悊闀挎椂闂存湭鏇存柊鐨凙GV: {agv_id}")
+    
+    def get_statistics(self) -> Dict[str, any]:
+        """
+        鑾峰彇AGV缁熻淇℃伅
+        
+        Returns:
+            Dict: 缁熻淇℃伅
+        """
+        total_agvs = len(self.agv_models)
+        available_agvs = len(self.get_available_agvs())
+        total_tasks = sum(agv.current_task_count for agv in self.agv_models.values())
+        total_capacity = sum(agv.max_capacity for agv in self.agv_models.values())
+        
+        avg_efficiency = 0.0
+        if self.agv_models:
+            avg_efficiency = sum(agv.calculate_efficiency_score(self.path_mapping) 
+                               for agv in self.agv_models.values()) / total_agvs
+        
+        return {
+            "total_agvs": total_agvs,
+            "available_agvs": available_agvs,
+            "total_assigned_tasks": total_tasks,
+            "total_capacity": total_capacity,
+            "capacity_utilization": total_tasks / total_capacity if total_capacity > 0 else 0.0,
+            "average_efficiency": avg_efficiency
+        } 
\ No newline at end of file
diff --git a/algorithm_system/path_monitor.py b/algorithm_system/path_monitor.py
new file mode 100644
index 0000000..33623db
--- /dev/null
+++ b/algorithm_system/path_monitor.py
@@ -0,0 +1,442 @@
+"""
+鐩戞帶RCS绯荤粺鐘舵�佸苟鐢熸垚璺緞
+"""
+import time
+import threading
+import logging
+from typing import Dict, List, Optional, Any
+import queue
+
+from common.data_models import AGVStatus, PlannedPath, from_dict
+from common.api_client import RCSAPIClient
+from algorithm_system.algorithms.path_planning import BatchPathPlanner
+from algorithm_system.models.agv_model import AGVModelManager
+from common.utils import load_path_mapping, generate_segment_id
+
+try:
+    from config.settings import RCS_SERVER_HOST, RCS_SERVER_PORT, MONITOR_POLLING_INTERVAL
+except ImportError:
+    RCS_SERVER_HOST = "10.10.10.156"
+    RCS_SERVER_PORT = 8088
+    MONITOR_POLLING_INTERVAL = 5.0
+    logging.warning("鏃犳硶浠巆onfig.settings瀵煎叆閰嶇疆锛屼娇鐢ㄩ粯璁ゅ��")
+
+
+class PathMonitorService:
+    """鐩戞帶RCS鐘舵�佸苟鐢熸垚璺緞"""
+    
+    def __init__(self, 
+                 rcs_host: str = None, 
+                 rcs_port: int = None,
+                 poll_interval: float = None,
+                 path_algorithm: str = "A_STAR",
+                 auto_send_paths: bool = True):
+        #鍒濆鍖栬矾寰勭洃鎺ф湇鍔�
+        self.logger = logging.getLogger(__name__)
+        
+        self.rcs_host = rcs_host or RCS_SERVER_HOST
+        self.rcs_port = rcs_port or RCS_SERVER_PORT
+        self.poll_interval = poll_interval or MONITOR_POLLING_INTERVAL
+        self.path_algorithm = path_algorithm
+        self.auto_send_paths = auto_send_paths
+        
+        self.rcs_client = RCSAPIClient(self.rcs_host, self.rcs_port, timeout=10)
+        self.path_mapping = load_path_mapping()
+        self.agv_manager = AGVModelManager(self.path_mapping)
+        
+        self.path_planner = BatchPathPlanner(
+            self.path_mapping, 
+            self.path_algorithm,
+            self.agv_manager
+        )
+        
+        self.is_running = False
+        self.monitor_thread = None
+        self._stop_event = threading.Event()
+        
+        self.stats = {
+            'poll_count': 0,           # 杞娆℃暟
+            'successful_polls': 0,     # 鎴愬姛杞娆℃暟  
+            'path_generations': 0,     # 璺緞鐢熸垚娆℃暟
+            'last_poll_time': None,    # 鏈�鍚庤疆璇㈡椂闂�
+            'last_generation_time': None  # 鏈�鍚庣敓鎴愭椂闂�
+        }
+        
+        self.logger.info(f"璺緞鐩戞帶鏈嶅姟鍒濆鍖栧畬鎴� - 杞闂撮殧: {poll_interval}s, 绠楁硶: {path_algorithm}")
+    
+    def start_monitoring(self):
+        """鍚姩鐩戞帶鏈嶅姟"""
+        if self.is_running:
+            self.logger.warning("鐩戞帶鏈嶅姟宸插湪杩愯涓�")
+            return
+        
+        self.is_running = True
+        self._stop_event.clear()
+        
+        self.monitor_thread = threading.Thread(
+            target=self._monitoring_loop,
+            name="PathMonitorThread",
+            daemon=True
+        )
+        self.monitor_thread.start()
+        
+        self.logger.info("鐩戞帶鏈嶅姟宸插惎鍔�")
+    
+    def stop_monitoring(self):
+        """鍋滄鐩戞帶鏈嶅姟"""
+        if not self.is_running:
+            self.logger.warning("鐩戞帶鏈嶅姟鏈湪杩愯")
+            return
+        
+        self.is_running = False
+        self._stop_event.set()
+        
+        if self.monitor_thread and self.monitor_thread.is_alive():
+            self.monitor_thread.join(timeout=5.0)
+        
+        self.logger.info("鐩戞帶鏈嶅姟宸插仠姝�")
+    
+    def _monitoring_loop(self):
+        """鐩戞帶涓诲惊鐜�"""
+        self.logger.info("寮�濮嬬洃鎺у惊鐜�...")
+        
+        while self.is_running and not self._stop_event.is_set():
+            try:
+                self._perform_monitoring_cycle()
+                
+                if not self._stop_event.wait(self.poll_interval):
+                    continue
+                else:
+                    break
+                    
+            except Exception as e:
+                self.logger.error(f"鐩戞帶寰幆寮傚父: {e}")
+                self._stop_event.wait(min(self.poll_interval * 2, 10.0))
+        
+        self.logger.info("鐩戞帶寰幆宸茬粨鏉�")
+    
+    def _perform_monitoring_cycle(self):
+        """鎵ц涓�娆$洃鎺у懆鏈�"""
+        start_time = time.time()
+        
+        self.stats['poll_count'] += 1
+        self.stats['last_poll_time'] = start_time
+        
+        try:
+            self.logger.info(f"寮�濮嬭矾寰勭洃鎺у懆鏈� #{self.stats['poll_count']}")
+            
+            # 1. 鑾峰彇褰撳墠AGV鐘舵�佸拰浠诲姟鐘舵��
+            current_agv_status, current_task_status = self._fetch_rcs_status()
+            
+            if not current_agv_status:
+                self.logger.debug("鏈幏鍙栧埌AGV鐘舵�佹暟鎹紝璺宠繃璺緞鐢熸垚")
+                return
+            
+            # 2. 鐩存帴鏍规嵁褰撳墠鐘舵�佺敓鎴愬厤纰版挒璺緞
+            self.logger.info(f"[璺緞鐢熸垚] 寮�濮嬩负 {len(current_agv_status)} 涓狝GV鐢熸垚璺緞")
+            
+            generated_paths = self._generate_collision_free_paths(current_agv_status)
+            
+            # 3. 鍙戦�佽矾寰勫埌RCS锛堟牴鎹厤缃喅瀹氾級
+            if generated_paths:
+                if self.auto_send_paths:
+                    self._send_paths_to_rcs(generated_paths)
+                else:
+                    self.logger.debug(f"璺緞鐢熸垚瀹屾垚浣嗘湭鍙戦�佸埌RCS - AGV鏁伴噺: {len(current_agv_status)}, 璺緞鏁�: {len(generated_paths)}")
+                
+                self.logger.info(f"璺緞鐢熸垚瀹屾垚 - AGV鏁伴噺: {len(current_agv_status)}, 璺緞鏁�: {len(generated_paths)}, 鑷姩鍙戦��: {self.auto_send_paths}")
+            else:
+                self.logger.debug("鏈敓鎴愪换浣曡矾寰勶紙鍙兘鎵�鏈堿GV閮藉浜庣┖闂茬姸鎬侊級")
+            
+            # 鏇存柊鎴愬姛缁熻
+            self.stats['successful_polls'] += 1
+            self.stats['path_generations'] += 1
+            self.stats['last_generation_time'] = time.time()
+            
+            generation_time = (time.time() - start_time) * 1000
+            self.logger.debug(f"鐩戞帶鍛ㄦ湡瀹屾垚 - 鑰楁椂: {generation_time:.2f}ms")
+            
+        except Exception as e:
+            self.logger.error(f"鐩戞帶鍛ㄦ湡鎵ц澶辫触: {e}")
+    
+    def _generate_unique_seg_id(self, agv_id: str, task_id: str = '') -> str:
+        """鐢熸垚segId"""
+        try:
+            if task_id:
+                # 鏈変换鍔℃椂浣跨敤task_id
+                return generate_segment_id(agv_id=agv_id, task_id=task_id, action_type="2")
+            else:
+                # 鏃犱换鍔℃椂浣跨敤鏃堕棿鎴充綔涓虹洰鏍囦綅缃紝纭繚涓嶅悓鏃堕棿鏈変笉鍚宻egId
+                import time
+                time_target = f"IDLE_{int(time.time() / 3600)}"  # 鎸夊皬鏃跺垎缁�
+                return generate_segment_id(agv_id=agv_id, target_position=time_target, action_type="4")
+            
+        except Exception as e:
+            self.logger.error(f"鐢熸垚segId澶辫触: {e}")
+            # 闄嶇骇鏂规锛氫娇鐢╟ommon.utils鐨勫嚱鏁扮敓鎴愬鐢↖D
+            import time
+            fallback_target = f"FALLBACK_{int(time.time())}"
+            return generate_segment_id(agv_id=agv_id, target_position=fallback_target, action_type="1")
+    
+    def _fetch_rcs_status(self) -> tuple[List[AGVStatus], Dict]:
+        """浠嶳CS鑾峰彇褰撳墠鐘舵��"""
+        agv_status_list = []
+        task_status = {}
+        
+        try:
+            # 鑾峰彇AGV鐘舵�� - 浣跨敤绌哄弬鏁拌幏鍙栨墍鏈堿GV鐘舵�佸拰浠诲姟鐘舵��
+            self.logger.info(" 杞鐩爣: 浣跨敤绌哄弬鏁�(agvId=None, mapId=None)鑾峰彇RCS鎵�鏈堿GV鐘舵�佸拰浠诲姟鐘舵��")
+            agv_response = self.rcs_client.get_agv_status(agv_id=None, map_id=None)
+            
+            if agv_response.code == 200 and agv_response.data:
+                self.logger.info(f"鎴愬姛鑾峰彇AGV鐘舵�� - 鏁伴噺: {len(agv_response.data)}")
+                
+                # 缁熻淇℃伅
+                total_tasks = 0
+                executing_tasks = 0
+                loaded_tasks = 0
+                
+                self.logger.info("=" * 80)
+                self.logger.info("[璇︾粏AGV鐘舵�佷俊鎭痌")
+                self.logger.info("=" * 80)
+                
+                for i, agv_data in enumerate(agv_response.data, 1):
+                    try:
+                        # 杞崲涓篈GVStatus瀵硅薄
+                        agv_status = from_dict(AGVStatus, agv_data)
+                        agv_status_list.append(agv_status)
+                        
+                        # 鎵撳嵃AGV鍩烘湰淇℃伅
+                        self.logger.info(f"[AGV #{i}] {agv_status.agvId}")
+                        self.logger.info(f"   鐘舵��: {agv_status.status} | 浣嶇疆: {agv_status.position} | 鏂瑰悜: {agv_status.direction}")
+                        self.logger.info(f"   鐢靛帇: {agv_status.vol} | 閿欒鐮�: {agv_status.error} | 绌鸿儗绡�: {agv_status.empty}")
+                        
+                        # 鍒嗘瀽鑳岀瘬淇℃伅
+                        if agv_status.backpack:
+                            self.logger.info(f"   [鑳岀瘬淇℃伅] ({len(agv_status.backpack)} 涓�):")
+                            for backpack_item in agv_status.backpack:
+                                status_text = "鎵ц涓�" if backpack_item.execute else ("宸茶杞�" if backpack_item.loaded else "绌洪棽")
+                                task_info = f"浠诲姟: {backpack_item.taskId}" if backpack_item.taskId else "鏃犱换鍔�"
+                                
+                                self.logger.info(f"     [浣嶇疆{backpack_item.index}] {task_info} | "
+                                                f"鐘舵��: {status_text} | 宸茶杞�: {backpack_item.loaded} | 鎵ц涓�: {backpack_item.execute}")
+                                
+                                # 缁熻浠诲姟
+                                if backpack_item.taskId:
+                                    total_tasks += 1
+                                    if backpack_item.execute:
+                                        executing_tasks += 1
+                                    if backpack_item.loaded:
+                                        loaded_tasks += 1
+                                    
+                                    # 鎻愬彇浠诲姟鐘舵�佷俊鎭�
+                                    task_status[backpack_item.taskId] = {
+                                        'agvId': agv_status.agvId,
+                                        'loaded': backpack_item.loaded,
+                                        'execute': backpack_item.execute,
+                                        'index': backpack_item.index
+                                    }
+                        else:
+                            self.logger.info(f"   [鑳岀瘬淇℃伅] 鏃犺儗绡撲俊鎭�")
+                        
+                        self.logger.info("-" * 60)
+                    except Exception as e:
+                        self.logger.warning(f"瑙f瀽AGV鐘舵�佹暟鎹け璐�: {agv_data} - {e}")
+                
+                # 鎵撳嵃缁熻鎽樿
+                self.logger.info("[浠诲姟缁熻鎽樿]")
+                self.logger.info(f"   鎬籄GV鏁伴噺: {len(agv_status_list)}")
+                self.logger.info(f"   鎬讳换鍔℃暟閲�: {total_tasks}")
+                self.logger.info(f"   鎵ц涓换鍔�: {executing_tasks}")
+                self.logger.info(f"   宸茶杞戒换鍔�: {loaded_tasks}")
+                self.logger.info(f"   鏈杞戒换鍔�: {total_tasks - loaded_tasks}")
+                self.logger.info("=" * 80)
+                
+            else:
+                self.logger.warning(f"鑾峰彇AGV鐘舵�佸け璐�: {agv_response.msg if agv_response else '鏃犲搷搴�'}")
+        
+        except Exception as e:
+            self.logger.error(f"浠嶳CS鑾峰彇鐘舵�佸け璐�: {e}")
+        
+        return agv_status_list, task_status
+    
+
+    
+    def _generate_collision_free_paths(self, agv_status_list: List[AGVStatus]) -> List[Dict]:
+        """涓烘墍鏈堿GV鐢熸垚鍏嶇鎾炶矾寰�"""
+        try:
+            self.logger.debug(f"寮�濮嬩负 {len(agv_status_list)} 涓狝GV鐢熸垚鍏嶇鎾炶矾寰�")
+            
+            # 浣跨敤鎵归噺璺緞瑙勫垝鍣ㄧ敓鎴愯矾寰�
+            result = self.path_planner.plan_all_agv_paths(
+                agv_status_list=agv_status_list,
+                include_idle_agv=False,  # 鍙负鎵ц浠诲姟鐨凙GV鐢熸垚璺緞
+                constraints=None
+            )
+
+            planned_paths = result.get('plannedPaths', result.get('planned_paths', []))
+            
+            # 璇婃柇锛氭樉绀鸿矾寰勮鍒掔粨鏋滅殑鎵�鏈夊瓧娈�
+            self.logger.debug(f"璺緞瑙勫垝鍣ㄨ繑鍥炵殑瀛楁: {list(result.keys())}")
+            self.logger.debug(f"planned_paths瀛楁瀛樺湪: {'planned_paths' in result}")
+            self.logger.debug(f"plannedPaths瀛楁瀛樺湪: {'plannedPaths' in result}")
+            self.logger.debug(f"鏈�缁堣幏鍙栧埌鐨勮矾寰勬暟閲�: {len(planned_paths)}")
+            
+            if planned_paths:
+                self.logger.info(f"鎴愬姛鐢熸垚 {len(planned_paths)} 鏉″厤纰版挒璺緞")
+                
+                # 璁板綍姣忎釜AGV鐨勮矾寰勪俊鎭�
+                for path_info in planned_paths:
+                    agv_id = path_info.get('agvId', 'unknown')
+                    code_list = path_info.get('codeList', [])
+                    self.logger.debug(f"AGV {agv_id} 璺緞闀垮害: {len(code_list)}")
+            else:
+                self.logger.info("鏈敓鎴愪换浣曡矾寰勶紙鍙兘鎵�鏈堿GV閮藉浜庣┖闂茬姸鎬侊級")
+            
+            return planned_paths
+            
+        except Exception as e:
+            self.logger.error(f"鐢熸垚鍏嶇鎾炶矾寰勫け璐�: {e}")
+            return []
+    
+
+    
+    def _send_paths_to_rcs(self, generated_paths: List[Dict]):
+        """灏嗙敓鎴愮殑璺緞鎵归噺鍙戦�佸埌RCS绯荤粺"""
+        try:
+            self.logger.info(f"寮�濮嬫壒閲忓彂閫� {len(generated_paths)} 鏉¤矾寰勫埌RCS绯荤粺")
+            
+            # 鏋勫缓鎵归噺璺緞鏁版嵁
+            agv_paths = []
+            import uuid
+            import time as time_module
+            
+            for path_info in generated_paths:
+                agv_id = path_info.get('agvId')
+                code_list = path_info.get('codeList', [])
+                
+                if agv_id and code_list:
+                    path_task_id = ''
+                    for path_code in code_list:
+                        if path_code.get('taskId'):
+                            path_task_id = path_code.get('taskId')
+                            break
+                    
+                    navigation_data = []
+                    for path_code in code_list:
+                        nav_item = {
+                            'code': path_code.get('code', ''),
+                            'direction': path_code.get('direction', '90'),
+                            'type': path_code.get('type')
+                        }
+                        
+                        if path_code.get('taskId'):
+                            nav_item['taskId'] = path_code.get('taskId')
+                        
+                        if path_code.get('posType'):
+                            nav_item['posType'] = path_code.get('posType')
+                        
+                        if path_code.get('lev') is not None:
+                            nav_item['lev'] = path_code.get('lev')
+                            
+                        navigation_data.append(nav_item)
+                    
+                    auto_seg_id = self._generate_unique_seg_id(agv_id, path_task_id)
+                    
+                    agv_path_data = {
+                        'agvId': agv_id,
+                        'segId': auto_seg_id,
+                        'codeList': navigation_data
+                    }
+                    
+                    agv_paths.append(agv_path_data)
+            
+            if not agv_paths:
+                self.logger.warning("娌℃湁鏈夋晥鐨勮矾寰勬暟鎹渶瑕佸彂閫�")
+                return
+            
+            try:
+                import requests
+                import json
+                
+                rcs_url = f"http://{self.rcs_host}:{self.rcs_port}/api/open/algorithm/zkd/navigation/v1"
+                
+                self.logger.info(f"绠楁硶绯荤粺鍙戦�佽矾寰勮鍒掔粨鏋滃埌RCS:")
+                self.logger.info(f"   AGV鏁伴噺: {len(agv_paths)}")
+                self.logger.info(f"   鐩爣URL: {rcs_url}")
+                
+                successful_sends = 0
+                
+                for agv_path in agv_paths:
+                    agv_id = agv_path['agvId']
+                    seg_id = agv_path['segId']
+                    code_list = agv_path['codeList']
+                    
+                    # 鏋勯�犳爣鍑嗗鑸姹傛暟鎹紙agvId, segId, codeList鏍煎紡锛�
+                    navigation_data = {
+                        'agvId': agv_id,
+                        'segId': seg_id,
+                        'codeList': code_list
+                    }
+                    
+                    # 鏄剧ず璺緞鎽樿
+                    start_code = code_list[0].get('code', '') if code_list else ''
+                    end_code = code_list[-1].get('code', '') if code_list else ''
+                    task_codes = [nc for nc in code_list if nc.get('taskId')]
+                    task_id = task_codes[0].get('taskId', '') if task_codes else ''
+                    
+                    self.logger.info(f"    AGV: {agv_id}, 浠诲姟: {task_id}, 璺緞: {start_code} -> {end_code} ({len(code_list)}鐐�)")
+                    
+                    # 璇︾粏鏄剧ず璺緞JSON鏁版嵁
+                    self.logger.info(f"鍙戦�佽矾寰凧SON鏁版嵁:")
+                    self.logger.info(json.dumps(navigation_data, ensure_ascii=False, indent=2))
+                    
+                    try:
+                        response = requests.post(
+                            rcs_url,
+                            json=navigation_data,
+                            timeout=10,
+                            headers={'Content-Type': 'application/json'}
+                        )
+                        
+                        if response.status_code == 200:
+                            response_data = response.json()
+                            self.logger.info(f" 鎴愬姛鍙戦�佽矾寰勫埌RCS - AGV: {agv_id}, 鍝嶅簲: {response_data.get('msg', 'OK')}")
+                            successful_sends += 1
+                        else:
+                            self.logger.warning(f" 鍙戦�佽矾寰勫埌RCS澶辫触 - AGV: {agv_id}, HTTP鐘舵��: {response.status_code}")
+                            self.logger.warning(f"   鍝嶅簲鍐呭: {response.text}")
+                            
+                    except Exception as e:
+                        self.logger.warning(f" 鍙戦�佸鑸寚浠ゅ紓甯� - AGV: {agv_id}, 閿欒: {e}")
+                
+                self.logger.info(f" 璺緞鍙戦�佸畬鎴� - 鎴愬姛: {successful_sends}/{len(agv_paths)}")
+                    
+            except Exception as e:
+                self.logger.error(f" 鍙戦�佸鑸寚浠ゅ紓甯�: {e}")
+        
+        except Exception as e:
+            self.logger.error(f"鍙戦�佽矾寰勫埌RCS寮傚父: {e}")
+    
+    def get_monitoring_status(self) -> Dict[str, Any]:
+        """鑾峰彇鐩戞帶鏈嶅姟鐘舵��"""
+        return {
+            'is_running': self.is_running,
+            'rcs_host': self.rcs_host,
+            'rcs_port': self.rcs_port,
+            'poll_interval': self.poll_interval,
+            'path_algorithm': self.path_algorithm,
+            'auto_send_paths': self.auto_send_paths,
+            'stats': self.stats.copy()
+        }
+    
+    def reset_stats(self):
+        """閲嶇疆缁熻淇℃伅"""
+        self.stats = {
+            'poll_count': 0,
+            'successful_polls': 0,
+            'path_generations': 0,
+            'last_poll_time': None,
+            'last_generation_time': None
+        }
+        self.logger.info("鐩戞帶缁熻淇℃伅宸查噸缃�") 
\ No newline at end of file
diff --git a/common/__init__.py b/common/__init__.py
new file mode 100644
index 0000000..cee7d4f
--- /dev/null
+++ b/common/__init__.py
@@ -0,0 +1,2 @@
+# Common Components Module
+__version__ = "1.0.0" 
\ No newline at end of file
diff --git a/common/api_client.py b/common/api_client.py
new file mode 100644
index 0000000..ffc818e
--- /dev/null
+++ b/common/api_client.py
@@ -0,0 +1,124 @@
+"""
+涓嶳CS绯荤粺閫氫俊
+"""
+import requests
+import json
+import logging
+import time
+from typing import Dict, Optional, Any
+from .data_models import (
+    APIResponse, create_error_response, ResponseCode
+)
+
+try:
+    from config.settings import (
+        RCS_SERVER_HOST, RCS_SERVER_PORT, 
+        REQUEST_TIMEOUT, AGV_STATUS_API_ENDPOINT
+    )
+except ImportError:
+    RCS_SERVER_HOST = "10.10.10.156"
+    RCS_SERVER_PORT = 8088
+    REQUEST_TIMEOUT = 30
+    AGV_STATUS_API_ENDPOINT = "/api/open/algorithm/getAgv"
+    logging.warning("鏃犳硶浠巆onfig.settings瀵煎叆閰嶇疆锛屼娇鐢ㄩ粯璁ゅ��")
+
+
+class APIClient:
+    """HTTP API瀹㈡埛绔熀绫�"""
+    
+    def __init__(self, base_url: str, timeout: int = 30):
+        """鍒濆鍖朅PI瀹㈡埛绔�"""
+        self.base_url = base_url.rstrip('/')
+        self.timeout = timeout
+        self.logger = logging.getLogger(__name__)
+        self.session = requests.Session()
+
+        self.session.headers.update({
+            'Content-Type': 'application/json',
+            'Accept': 'application/json'
+        })
+    
+    def _make_request(self, method: str, endpoint: str, data: Any = None, 
+                     params: Dict = None) -> APIResponse:
+        """鍙戦�丠TTP璇锋眰"""
+        url = f"{self.base_url}{endpoint}"
+        
+        try:
+            start_time = time.time()
+
+            request_kwargs = {
+                'timeout': self.timeout,
+                'params': params
+            }
+            
+            if data is not None:
+                if isinstance(data, (dict, list)):
+                    request_kwargs['json'] = data
+                else:
+                    request_kwargs['data'] = json.dumps(data)
+
+            response = self.session.request(method, url, **request_kwargs)
+            
+            end_time = time.time()
+            duration = (end_time - start_time) * 1000  # 杞崲涓烘绉�
+            
+            self.logger.info(f"{method} {url} - {response.status_code} - {duration:.2f}ms")
+
+            try:
+                response_data = response.json()
+            except ValueError:
+                response_data = {"text": response.text}
+
+            if response.status_code == 200:
+                if isinstance(response_data, dict) and 'code' in response_data:
+                    return APIResponse(
+                        code=response_data.get('code', ResponseCode.SUCCESS),
+                        msg=response_data.get('msg', '鎿嶄綔鎴愬姛'),
+                        data=response_data.get('data')
+                    )
+                else:
+                    return APIResponse(
+                        code=ResponseCode.SUCCESS,
+                        msg='鎿嶄綔鎴愬姛',
+                        data=response_data
+                    )
+            else:
+                return create_error_response(
+                    ResponseCode.SERVER_ERROR,
+                    f"HTTP {response.status_code}: {response.text}"
+                )
+                
+        except requests.exceptions.Timeout:
+            self.logger.error(f"璇锋眰瓒呮椂: {url}")
+            return create_error_response(ResponseCode.SERVER_ERROR, "璇锋眰瓒呮椂")
+            
+        except requests.exceptions.ConnectionError:
+            self.logger.error(f"杩炴帴閿欒: {url}")
+            return create_error_response(ResponseCode.SERVER_ERROR, "杩炴帴閿欒")
+            
+        except Exception as e:
+            self.logger.error(f"璇锋眰寮傚父: {url} - {str(e)}")
+            return create_error_response(ResponseCode.SERVER_ERROR, f"璇锋眰寮傚父: {str(e)}")
+
+
+class RCSAPIClient(APIClient):
+    
+    def __init__(self, rcs_host: str = None, rcs_port: int = None, timeout: int = None):
+        """鍒濆鍖朢CS API瀹㈡埛绔�"""
+        rcs_host = rcs_host or RCS_SERVER_HOST
+        rcs_port = rcs_port or RCS_SERVER_PORT
+        timeout = timeout or REQUEST_TIMEOUT
+        
+        base_url = f"http://{rcs_host}:{rcs_port}"
+        super().__init__(base_url, timeout)
+    
+    def get_agv_status(self, agv_id: Optional[str] = None, 
+                      map_id: Optional[str] = None) -> APIResponse:
+        """鑾峰彇AGV鐘舵��"""
+        data = {}
+        if agv_id:
+            data['agvId'] = agv_id
+        if map_id:
+            data['mapId'] = map_id
+            
+        return self._make_request('POST', AGV_STATUS_API_ENDPOINT, data=data) 
\ No newline at end of file
diff --git a/common/data_models.py b/common/data_models.py
new file mode 100644
index 0000000..132df1e
--- /dev/null
+++ b/common/data_models.py
@@ -0,0 +1,184 @@
+"""
+鏁版嵁妯″瀷瀹氫箟
+"""
+from dataclasses import dataclass, field
+from typing import List, Optional, Dict, Any
+from enum import Enum
+import json
+
+
+class AGVStatusEnum(Enum):
+    # AGV鐘舵��
+    IDLE = 0        # 绌洪棽
+    BUSY = 1        # 蹇欑
+    CHARGING = 2    # 鍏呯數
+    ERROR = 3       # 鏁呴殰
+    MAINTENANCE = 4 # 缁存姢
+
+
+class TaskTypeEnum(Enum):
+    # 浠诲姟绫诲瀷
+    PICKUP = "1"    # 鍙栬揣
+    DELIVERY = "2"  # 閫佽揣
+    TRANSPORT = "3" # 杩愯緭
+
+
+class AGVActionTypeEnum(Enum):
+    # AGV鍔ㄤ綔绫诲瀷
+    AVOIDANCE = "1"    # 閬胯
+    TASK = "2"         # 浠诲姟
+    CHARGING = "3"     # 鍏呯數
+    STANDBY = "4"      # 鍘诲緟鏈轰綅
+
+
+@dataclass
+class BackpackData:
+    # 鑳岀瘬鏁版嵁
+    index: int                    # 鑳岀瘬缂栧彿
+    loaded: bool                  # 鏄惁杞借揣
+    execute: bool                 # 鏄惁鍦ㄦ墽琛�
+    taskId: Optional[str] = None  # 鎵ц浠诲姟缂栧彿
+
+
+@dataclass
+class AGVStatus:
+    # AGV鐘舵��
+    agvId: str                          # 灏忚溅缂栧彿
+    status: int                         # 鐘舵��
+    position: str                       # 灏忚溅褰撳墠鐐逛綅
+    empty: int                          # 绌鸿儗绡撴暟閲�
+    direction: str                      # 灏忚溅瑙掑害
+    vol: int                           # 鐢靛帇
+    error: int                         # 寮傚父鐮侊紝0琛ㄧず姝e父
+    backpack: List[BackpackData] = field(default_factory=list)  # 鑳岀瘬鏁版嵁
+    autoCharge: int = 20               # 浣庣數閲忚瀹氶槇鍊硷紝浣庝簬璇ュ�煎彲浠ュ幓鑷姩鍏呯數涔熷彲浠ョ户缁仛浠诲姟
+    lowVol: int = 10                   # 鏈�浣庣數閲忥紝鐢甸噺浣庝簬璇ュ�煎繀椤诲幓鍏呯數
+
+
+@dataclass
+class TaskData:
+    # 浠诲姟鏁版嵁
+    taskId: str         # 浠诲姟id
+    start: str          # 璧风偣
+    end: str            # 缁堢偣
+    type: str          # 浠诲姟绫诲瀷
+    priority: int      # 浼樺厛绾�
+
+
+@dataclass
+class PathCode:
+    # 璺緞鐐�
+    code: str                          # 鍦板浘鐐逛綅id
+    direction: str                     # 鏂瑰悜
+    type: Optional[str] = None         # AGV鍔ㄤ綔绫诲瀷锛堥伩璁┿�佷换鍔°�佸厖鐢点�佸幓寰呮満浣嶏級
+    taskId: Optional[str] = None       # 浠诲姟缂栧彿锛屽鏋滄槸鎵ц浠诲姟鍒欏繀闇�
+    posType: Optional[str] = None      # 鍔ㄤ綔绫诲瀷锛岃〃绀哄埌杈炬煇涓偣浣嶈繘琛岀殑鍔ㄤ綔锛屽鍙栥�佹斁
+    lev: Optional[int] = None          # 琛ㄧずposType瀵瑰簲鐨勪换鍔℃墍瑕佹搷浣滅殑鏄鍑犱釜鑳岀瘬
+
+
+@dataclass
+class PlannedPath:
+    # 瑙勫垝璺緞
+    agvId: str                      # 灏忚溅缂栧彿
+    codeList: List[PathCode]        # 鐐逛綅闆嗗悎
+    segId: Optional[str] = None     # 瀵艰埅閲嶅鍙戦�佹椂鐨勫幓閲嶆爣璇�
+
+
+@dataclass
+class TaskAssignment:
+    # 浠诲姟鍒嗛厤缁撴灉
+    taskId: str        # 浠诲姟ID
+    agvId: str         # 鍒嗛厤鐨凙GV ID
+    lev_id: int = 0    # 鑳岀瘬浣嶇疆缂栧彿
+
+
+@dataclass
+class APIResponse:
+    # API鍝嶅簲鏍煎紡 - 瀛楁椤哄簭鍥哄畾涓� code, msg, data
+    code: int                       # 鐘舵�佺爜
+    msg: str                        # 娑堟伅
+    data: Optional[Any] = None      # 鏁版嵁
+    
+    def to_ordered_dict(self) -> Dict:
+        # 杞崲涓烘湁搴忓瓧鍏�
+        from collections import OrderedDict
+        return OrderedDict([
+            ('code', self.code),
+            ('msg', self.msg),
+            ('data', self.data)
+        ])
+
+
+class ResponseCode:
+    # 鍝嶅簲鐘舵�佺爜
+    SUCCESS = 200           # 鎿嶄綔鎴愬姛
+    NO_DATA = 201          # 鏆傛棤鏁版嵁
+    PARAM_EMPTY = 401      # 鍙傛暟涓虹┖
+    PERMISSION_DENIED = 403 # 鏉冮檺涓嶈冻
+    DUPLICATE_SUBMIT = 407  # 璇峰嬁閲嶅鎻愪氦
+    SERVER_ERROR = 500     # 鏈嶅姟鍣ㄩ敊璇�
+
+
+def create_success_response(data: Any = None, msg: str = "鎿嶄綔鎴愬姛") -> APIResponse:
+    # 鍒涘缓鎴愬姛鍝嶅簲
+    return APIResponse(code=ResponseCode.SUCCESS, msg=msg, data=data)
+
+def create_error_response(code: int, msg: str) -> APIResponse:
+    # 鍒涘缓閿欒鍝嶅簲
+    return APIResponse(code=code, msg=msg, data=None)
+
+def to_dict(obj) -> Dict:
+    # 灏嗘暟鎹被杞崲涓哄瓧鍏�
+    if hasattr(obj, '__dict__'):
+        if isinstance(obj, APIResponse):
+            return obj.to_ordered_dict()
+        
+        result = {}
+        for key, value in obj.__dict__.items():
+            if isinstance(value, list):
+                result[key] = [to_dict(item) if hasattr(item, '__dict__') else item for item in value]
+            elif hasattr(value, '__dict__'):
+                result[key] = to_dict(value)
+            else:
+                result[key] = value
+        return result
+    return obj
+
+
+def from_dict(data_class, data: Dict):
+    # 浠庡瓧鍏稿垱寤烘暟鎹被瀹炰緥
+    if isinstance(data, dict):
+        field_types = data_class.__annotations__
+        kwargs = {}
+        
+        for field_name, field_type in field_types.items():
+            if field_name in data:
+                value = data[field_name]
+                
+                if hasattr(field_type, '__origin__') and field_type.__origin__ is list:
+                    inner_type = field_type.__args__[0]
+                    if hasattr(inner_type, '__annotations__'):
+                        kwargs[field_name] = [from_dict(inner_type, item) for item in value]
+                    else:
+                        kwargs[field_name] = value
+                elif hasattr(field_type, '__origin__'):
+                    import typing
+                    origin = getattr(field_type, '__origin__', None)
+                    
+                    if origin is typing.Union or str(origin) == 'typing.Union':
+                        kwargs[field_name] = value
+                    else:
+                        kwargs[field_name] = value
+                elif hasattr(field_type, '__annotations__'):
+                    kwargs[field_name] = from_dict(field_type, value)
+                else:
+                    kwargs[field_name] = value
+            else:
+                field_info = data_class.__dataclass_fields__.get(field_name)
+                if field_info and field_info.default is not field_info.default_factory:
+                    pass
+                elif field_info and field_info.default_factory is not field_info.default_factory:
+                    pass
+        
+        return data_class(**kwargs)
+    return data 
\ No newline at end of file
diff --git a/common/utils.py b/common/utils.py
new file mode 100644
index 0000000..6340727
--- /dev/null
+++ b/common/utils.py
@@ -0,0 +1,286 @@
+import json
+import logging
+import os
+import random
+import time
+import uuid
+import string
+from typing import Dict, List, Tuple, Optional, Any
+from datetime import datetime
+
+
+def setup_logging(log_level: str = "INFO", log_file: Optional[str] = None) -> None:
+    """璁剧疆鏃ュ織閰嶇疆"""
+    log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
+    formatter = logging.Formatter(log_format)
+    
+    root_logger = logging.getLogger()
+    root_logger.setLevel(getattr(logging, log_level.upper()))
+    
+    for handler in root_logger.handlers[:]:
+        root_logger.removeHandler(handler)
+
+    console_handler = logging.StreamHandler()
+    console_handler.setFormatter(formatter)
+    root_logger.addHandler(console_handler)
+
+    if log_file:
+        file_handler = logging.FileHandler(log_file, encoding='utf-8')
+        file_handler.setFormatter(formatter)
+        root_logger.addHandler(file_handler)
+
+
+def load_path_mapping(mapping_file: str = "path_mapping.json") -> Dict[str, Dict[str, int]]:
+    """鍔犺浇璺緞鏄犲皠鏂囦欢"""
+    logger = logging.getLogger(__name__)
+    
+    try:
+        with open(mapping_file, 'r', encoding='utf-8') as f:
+            data = json.load(f)
+        
+        path_mapping = {}
+        if "path_id_to_coordinates" in data:
+            for path_id, coordinates in data["path_id_to_coordinates"].items():
+                if coordinates and len(coordinates) > 0:
+                    coord = coordinates[0]
+                    path_mapping[path_id] = {
+                        "x": coord["x"],
+                        "y": coord["y"]
+                    }
+        
+        logger.info(f"鎴愬姛鍔犺浇璺緞鏄犲皠锛屽叡 {len(path_mapping)} 涓矾寰勭偣")
+        return path_mapping
+        
+    except FileNotFoundError:
+        logger.error(f"璺緞鏄犲皠鏂囦欢涓嶅瓨鍦�: {mapping_file}")
+        return {}
+    except json.JSONDecodeError as e:
+        logger.error(f"璺緞鏄犲皠鏂囦欢鏍煎紡閿欒: {e}")
+        return {}
+    except Exception as e:
+        logger.error(f"鍔犺浇璺緞鏄犲皠鏂囦欢澶辫触: {e}")
+        return {}
+
+
+def get_coordinate_from_path_id(path_id: str, path_mapping: Dict[str, Dict[str, int]]) -> Optional[Tuple[int, int]]:
+    """
+    鏍规嵁璺緞鐐笽D鑾峰彇鍧愭爣
+    
+    Args:
+        path_id: 璺緞鐐笽D锛堟敮鎸佸甫8浣嶅甫闆剁殑鏍煎紡锛宔.g.'00000206'锛�
+        path_mapping: 璺緞鏄犲皠瀛楀吀
+        
+    Returns:
+        Optional[Tuple[int, int]]: 鍧愭爣(x, y)锛屽鏋滄壘涓嶅埌鍒欒繑鍥濶one
+    """
+    logger = logging.getLogger(__name__)
+    
+    if path_id in path_mapping:
+        coord = path_mapping[path_id]
+        logger.debug(f"璺緞ID {path_id} 鍖归厤鎴愬姛锛屽潗鏍�: ({coord['x']}, {coord['y']})")
+        return (coord["x"], coord["y"])
+    
+    # 濡傛灉鍖归厤澶辫触锛屽皾璇曞幓鎺夐浂鍚庡尮閰�
+    try:
+        normalized_path_id = str(int(path_id))
+        if normalized_path_id in path_mapping:
+            coord = path_mapping[normalized_path_id]
+            logger.debug(f"璺緞ID {path_id} 瑙勮寖鍖栦负 {normalized_path_id} 鍚庡尮閰嶆垚鍔燂紝鍧愭爣: ({coord['x']}, {coord['y']})")
+            return (coord["x"], coord["y"])
+        else:
+            logger.warning(f"瑙勮寖鍖栧悗鐨勮矾寰処D {normalized_path_id}锛堝師濮�: {path_id}锛夊湪璺緞鏄犲皠涓湭鎵惧埌")
+    except (ValueError, TypeError):
+        logger.warning(f"璺緞ID {path_id} 涓嶆槸鏈夋晥鐨勬暟瀛楁牸寮�")
+    
+    logger.warning(f"鏃犳硶鎵惧埌璺緞ID {path_id} 瀵瑰簲鐨勫潗鏍�")
+    return None
+
+
+def get_path_id_from_coordinate(x: int, y: int, path_mapping: Dict[str, Dict[str, int]]) -> Optional[str]:
+    """鏍规嵁鍧愭爣鑾峰彇璺緞鐐笽D"""
+    for path_id, coord in path_mapping.items():
+        if coord["x"] == x and coord["y"] == y:
+            return path_id
+    return None
+
+
+def calculate_distance(pos1: Tuple[int, int], pos2: Tuple[int, int]) -> float:
+    """璁$畻涓ょ偣涔嬮棿鐨勬姘忚窛绂�"""
+    return ((pos1[0] - pos2[0]) ** 2 + (pos1[1] - pos2[1]) ** 2) ** 0.5
+
+
+def calculate_manhattan_distance(pos1: Tuple[int, int], pos2: Tuple[int, int]) -> int:
+    """璁$畻涓ょ偣涔嬮棿鐨勬浖鍝堥】璺濈"""
+    return abs(pos1[0] - pos2[0]) + abs(pos1[1] - pos2[1])
+
+
+def generate_random_agv_id() -> str:
+    """鐢熸垚闅忔満AGV ID"""
+    return f"AGV_{random.randint(10001, 99999)}"
+
+
+def generate_random_task_id() -> str:
+    """鐢熸垚闅忔満浠诲姟ID"""
+    timestamp = int(time.time() * 1000)  # 姣鏃堕棿鎴�
+    random_suffix = random.randint(100, 999)
+    return f"TASK_{timestamp}_{random_suffix}"
+
+
+def get_random_path_ids(path_mapping: Dict[str, Dict[str, int]], count: int = 2) -> List[str]:
+    """闅忔満鑾峰彇璺緞鐐笽D"""
+    if not path_mapping:
+        return []
+    
+    path_ids = list(path_mapping.keys())
+    if len(path_ids) < count:
+        return path_ids
+    
+    return random.sample(path_ids, count)
+
+
+def format_timestamp(timestamp: Optional[float] = None) -> str:
+    """鏍煎紡鍖栨椂闂存埑"""
+    if timestamp is None:
+        timestamp = time.time()
+    
+    return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
+
+
+def normalize_path_id(path_id: str) -> str:
+    """鏍囧噯鍖栬矾寰勭偣ID鏍煎紡"""
+    if not path_id:
+        return path_id
+    
+    try:
+        normalized_path_id = str(int(path_id))
+        return normalized_path_id
+    except (ValueError, TypeError):
+        return path_id
+
+
+def validate_path_id(path_id: str) -> bool:
+    """楠岃瘉璺緞鐐笽D鏍煎紡"""
+    try:
+        # 璺緞鐐笽D搴旇鏄暟瀛楀瓧绗︿覆锛屽湪1-1696鑼冨洿鍐�
+        path_num = int(path_id)
+        return 1 <= path_num <= 1696
+    except (ValueError, TypeError):
+        return False
+
+
+def validate_agv_id(agv_id: str) -> bool:
+    """楠岃瘉AGV ID鏍煎紡"""
+    if not agv_id or not isinstance(agv_id, str):
+        return False
+    # AGV ID涓嶈兘涓虹┖涓旈暱搴﹀悎鐞�
+    return len(agv_id.strip()) > 0 and len(agv_id) <= 50
+
+
+def save_json_file(data: Any, file_path: str) -> bool:
+    """淇濆瓨鏁版嵁鍒癑SON"""
+    logger = logging.getLogger(__name__)
+    
+    try:
+        with open(file_path, 'w', encoding='utf-8') as f:
+            json.dump(data, f, ensure_ascii=False, indent=2)
+        
+        logger.info(f"鏁版嵁宸蹭繚瀛樺埌鏂囦欢: {file_path}")
+        return True
+        
+    except Exception as e:
+        logger.error(f"淇濆瓨鏂囦欢澶辫触: {file_path} - {e}")
+        return False
+
+
+def load_json_file(file_path: str) -> Optional[Any]:
+    """浠嶫SON鏂囦欢鍔犺浇鏁版嵁"""
+    logger = logging.getLogger(__name__)
+    
+    try:
+        with open(file_path, 'r', encoding='utf-8') as f:
+            data = json.load(f)
+        
+        logger.info(f"鏁版嵁宸蹭粠鏂囦欢鍔犺浇: {file_path}")
+        return data
+        
+    except FileNotFoundError:
+        logger.warning(f"鏂囦欢涓嶅瓨鍦�: {file_path}")
+        return None
+    except json.JSONDecodeError as e:
+        logger.error(f"JSON鏍煎紡閿欒: {file_path} - {e}")
+        return None
+    except Exception as e:
+        logger.error(f"鍔犺浇鏂囦欢澶辫触: {file_path} - {e}")
+        return None
+
+
+def ensure_directory_exists(directory: str) -> bool:
+    """纭繚鐩綍瀛樺湪锛屽鏋滀笉瀛樺湪鍒欏垱寤�"""
+    try:
+        os.makedirs(directory, exist_ok=True)
+        return True
+    except Exception as e:
+        logging.getLogger(__name__).error(f"鍒涘缓鐩綍澶辫触: {directory} - {e}")
+        return False
+
+
+def generate_segment_id(agv_id: str, task_id: Optional[str] = None, 
+                       target_position: Optional[str] = None, 
+                       action_type: str = "2") -> str:
+    """
+    鐢熸垚瀵艰埅娈礗D锛岀敤浜庡幓閲嶆爣璇�
+    鍩轰簬AGV ID銆佷换鍔D銆佺洰鏍囦綅缃拰鍔ㄤ綔绫诲瀷鐢熸垚鍥哄畾鐨�11浣岻D
+    
+    Args:
+        agv_id: AGV ID
+        task_id: 浠诲姟ID
+        target_position: 鐩爣浣嶇疆
+        action_type: 鍔ㄤ綔绫诲瀷
+        
+    Returns:
+        str: 11浣嶅鑸ID
+    """
+    import hashlib
+    
+    # 鏋勫缓鐢ㄤ簬鍝堝笇鐨勫瓧绗︿覆
+    if task_id:
+        # 浠诲姟绫诲瀷锛氫娇鐢╝gv_id + task_id
+        hash_input = f"{agv_id}_{task_id}_{action_type}"
+    else:
+        # 闈炰换鍔$被鍨嬶細浣跨敤agv_id + target_position + action_type
+        target = target_position or "unknown"
+        hash_input = f"{agv_id}_{target}_{action_type}"
+    
+    # 浣跨敤MD5鍝堝笇鐢熸垚鍥哄畾鍊�
+    hash_object = hashlib.md5(hash_input.encode())
+    hash_hex = hash_object.hexdigest()
+    
+    # 灏�16杩涘埗杞崲涓烘暟瀛楀苟鎴彇11浣�
+    hash_int = int(hash_hex[:8], 16) 
+    seg_id = str(hash_int)[-11:].zfill(11) 
+    
+    return seg_id
+
+
+def generate_navigation_code(code: str, direction: str, action_type: str = "2", 
+                           task_id: Optional[str] = None, pos_type: Optional[str] = None,
+                           backpack_level: Optional[int] = None, is_target_point: bool = False) -> Dict:
+    """鐢熸垚瀵艰埅璺緞鐐逛唬鐮�"""
+    path_code = {
+        'code': code,
+        'direction': direction,
+        'type': action_type
+    }
+    
+    if task_id and action_type == "2":
+        path_code['taskId'] = task_id
+    
+    # 鍙湁鍒拌揪鐩爣鐐规椂鎵嶆坊鍔爌osType鍜宭ev锛屼笖鏈夊�兼椂鎵嶅寘鍚瓧娈�
+    if is_target_point:
+        if pos_type:
+            path_code['posType'] = pos_type
+
+        if backpack_level is not None:
+            path_code['lev'] = backpack_level
+    
+    return path_code 
\ No newline at end of file
diff --git a/config/environment.py b/config/environment.py
new file mode 100644
index 0000000..47f42d0
--- /dev/null
+++ b/config/environment.py
@@ -0,0 +1,360 @@
+"""
+鐜閰嶇疆妯″潡 - 璐熻矗瀹氫箟鍔犺浇浠撳簱鐜閰嶇疆
+"""
+import json
+from enum import Enum, auto
+import numpy as np
+from typing import Dict, List, Tuple, Optional, Union
+
+
+class CellType(Enum):
+    """鍗曞厓鏍肩被鍨嬫灇涓�"""
+    EMPTY = auto()  # 绌哄崟鍏冩牸
+    STATION = auto()  # 绔欑偣
+    PATH = auto()  # 璺緞
+    STORAGE = auto()  # 浠撳偍鍖哄煙
+    OBSTACLE = auto()  # 闅滅鐗�
+    LOADING = auto()  # 瑁呰浇鍖�
+    UNLOADING = auto()  # 鍗歌浇鍖�
+
+
+class EnvironmentConfig:
+    """鐜閰嶇疆绫�"""
+    
+    def __init__(self, width: int, height: int):
+        """鍒濆鍖栫幆澧冮厤缃�"""
+        self.width = width
+        self.height = height
+        # 鍒濆鍖栨墍鏈夊崟鍏冩牸涓虹┖
+        self.grid = np.full((height, width), CellType.EMPTY)
+        # 绔欑偣浣嶇疆鍙婂叾閰嶇疆
+        self.stations = {}  # 鏍煎紡: {(x, y): {"capacity": 4, "load_position": (x-1, y), "unload_position": (x+1, y)}}
+        # 璺緞鐐逛綅缃�
+        self.paths = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 浠撳偍鍖哄煙浣嶇疆
+        self.storage_areas = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 瑁呭嵏鍖轰綅缃�
+        self.loading_areas = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        self.unloading_areas = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 闅滅鐗╀綅缃�
+        self.obstacles = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 缃戞牸鐐归偦鎺ヨ〃锛堢敤浜庤矾寰勮鍒掞級
+        self.adjacency_list = {}  # 鏍煎紡: {(x1, y1): {(x2, y2): distance, ...}, ...}
+        
+    def set_cell_type(self, x: int, y: int, cell_type: CellType) -> bool:
+        """
+        璁剧疆鍗曞厓鏍肩被鍨�
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            cell_type: 鍗曞厓鏍肩被鍨�
+            
+        Returns:
+            bool: 璁剧疆鏄惁鎴愬姛
+        """
+        if 0 <= x < self.width and 0 <= y < self.height:
+            self.grid[y, x] = cell_type
+            
+            # 鏍规嵁鍗曞厓鏍肩被鍨嬫洿鏂扮浉搴旂殑闆嗗悎
+            pos = (x, y)
+            if cell_type == CellType.PATH:
+                self.paths.add(pos)
+            elif cell_type == CellType.STATION:
+                if pos not in self.stations:
+                    self.stations[pos] = {
+                        "capacity": 4,  # 榛樿瀹归噺
+                        "load_position": (x-1, y),  # 榛樿鍔犺浇浣嶇疆
+                        "unload_position": (x+1, y)  # 榛樿鍗歌浇浣嶇疆
+                    }
+            elif cell_type == CellType.STORAGE:
+                self.storage_areas.add(pos)
+            elif cell_type == CellType.LOADING:
+                self.loading_areas.add(pos)
+            elif cell_type == CellType.UNLOADING:
+                self.unloading_areas.add(pos)
+            elif cell_type == CellType.OBSTACLE:
+                self.obstacles.add(pos)
+            
+            return True
+        return False
+    
+    def add_station(self, x: int, y: int, capacity: int = 4,
+                   load_position: Tuple[int, int] = None,
+                   unload_position: Tuple[int, int] = None) -> bool:
+        """
+        娣诲姞绔欑偣
+        
+        Args:
+            x: 绔欑偣x鍧愭爣
+            y: 绔欑偣y鍧愭爣
+            capacity: 绔欑偣瀹归噺
+            load_position: 鍔犺浇浣嶇疆
+            unload_position: 鍗歌浇浣嶇疆
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        if 0 <= x < self.width and 0 <= y < self.height:
+            # 璁剧疆榛樿鐨勮鍗镐綅缃�
+            if load_position is None:
+                load_position = (x-1, y)  # 宸︿晶涓哄嵏鏂欑浣嶇疆
+            if unload_position is None:
+                unload_position = (x+1, y)  # 鍙充晶涓哄彇鏂欑浣嶇疆
+                
+            # 鏇存柊缃戞牸鍜岀珯鐐逛俊鎭�
+            self.grid[y, x] = CellType.STATION
+            self.stations[(x, y)] = {
+                "capacity": capacity,
+                "load_position": load_position,
+                "unload_position": unload_position
+            }
+            
+            # 纭繚瑁呭嵏浣嶇疆涔熻鏍囪
+            self.set_cell_type(load_position[0], load_position[1], CellType.LOADING)
+            self.set_cell_type(unload_position[0], unload_position[1], CellType.UNLOADING)
+            
+            return True
+        return False
+    
+    def add_path(self, x: int, y: int) -> bool:
+        """
+        娣诲姞璺緞鐐�
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        return self.set_cell_type(x, y, CellType.PATH)
+    
+    def add_storage_area(self, x: int, y: int) -> bool:
+        """
+        娣诲姞浠撳偍鍖哄煙
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        return self.set_cell_type(x, y, CellType.STORAGE)
+    
+    def add_obstacle(self, x: int, y: int) -> bool:
+        """
+        娣诲姞闅滅鐗�
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        return self.set_cell_type(x, y, CellType.OBSTACLE)
+    
+    def is_valid_position(self, x: int, y: int) -> bool:
+        """
+        妫�鏌ヤ綅缃槸鍚﹀悎娉曪紙鍦ㄧ綉鏍煎唴涓旈潪闅滅鐗╋級
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 浣嶇疆鏄惁鍚堟硶
+        """
+        return (0 <= x < self.width and 
+                0 <= y < self.height and 
+                self.grid[y, x] != CellType.OBSTACLE)
+    
+    def build_adjacency_list(self):
+        """鏋勫缓缃戞牸鐐归偦鎺ヨ〃锛堢敤浜庤矾寰勮鍒掞級"""
+        # 娓呯┖鐜版湁閭绘帴琛�
+        self.adjacency_list = {}
+        
+        # AGV杩涜鍥涙柟鍚戠Щ鍔�
+        directions = [
+            (0, 1),   # 涓�
+            (1, 0),   # 鍙�  
+            (0, -1),  # 涓�
+            (-1, 0)   # 宸�
+        ]
+        
+        # 涓烘瘡涓矾寰勭偣鏋勫缓閭绘帴琛�
+        for x, y in self.paths:
+            if (x, y) not in self.adjacency_list:
+                self.adjacency_list[(x, y)] = {}
+                
+            # 妫�鏌ュ洓涓柟鍚戠殑閭诲眳
+            for dx, dy in directions:
+                nx, ny = x + dx, y + dy
+                # 妫�鏌ョ浉閭荤偣鏄惁涓烘湁鏁堣矾寰勭偣
+                if (nx, ny) in self.paths:
+                    # 绉诲姩璺濈缁熶竴涓�1.0
+                    distance = 1.0
+                    self.adjacency_list[(x, y)][(nx, ny)] = distance
+        
+        # 娣诲姞绔欑偣鐨勮鍗哥偣鍒伴偦鎺ヨ〃
+        for station_pos, station_info in self.stations.items():
+            load_pos = station_info["load_position"]
+            unload_pos = station_info["unload_position"]
+            
+            # 纭繚瑁呭嵏鐐瑰凡娣诲姞鍒伴偦鎺ヨ〃
+            if load_pos not in self.adjacency_list:
+                self.adjacency_list[load_pos] = {}
+            if unload_pos not in self.adjacency_list:
+                self.adjacency_list[unload_pos] = {}
+                
+            # 杩炴帴瑁呭嵏鐐瑰埌鏈�杩戠殑璺緞鐐�
+            for pos in [load_pos, unload_pos]:
+                # 鎵惧埌鏈�杩戠殑璺緞鐐瑰苟杩炴帴
+                min_dist = float('inf')
+                nearest_path = None
+                
+                for path_pos in self.paths:
+                    dist = ((pos[0] - path_pos[0]) ** 2 + (pos[1] - path_pos[1]) ** 2) ** 0.5
+                    if dist < min_dist:
+                        min_dist = dist
+                        nearest_path = path_pos
+                
+                if nearest_path:
+                    self.adjacency_list[pos][nearest_path] = min_dist
+                    self.adjacency_list[nearest_path][pos] = min_dist
+    
+    def save_to_file(self, filepath: str):
+        """
+        灏嗙幆澧冮厤缃繚瀛樺埌鏂囦欢
+        
+        Args:
+            filepath: 鏂囦欢璺緞
+        """
+        config_data = {
+            "width": self.width,
+            "height": self.height,
+            "stations": {f"{x},{y}": info for (x, y), info in self.stations.items()},
+            "paths": [{"x": x, "y": y} for x, y in self.paths],
+            "storage_areas": [{"x": x, "y": y} for x, y in self.storage_areas],
+            "loading_areas": [{"x": x, "y": y} for x, y in self.loading_areas],
+            "unloading_areas": [{"x": x, "y": y} for x, y in self.unloading_areas],
+            "obstacles": [{"x": x, "y": y} for x, y in self.obstacles]
+        }
+        
+        with open(filepath, 'w') as f:
+            json.dump(config_data, f, indent=2)
+    
+    @classmethod
+    def load_from_file(cls, filepath: str) -> 'EnvironmentConfig':
+        """
+        浠庢枃浠跺姞杞界幆澧冮厤缃�
+        
+        Args:
+            filepath: 鏂囦欢璺緞
+            
+        Returns:
+            EnvironmentConfig: 鐜閰嶇疆瀵硅薄
+        """
+        with open(filepath, 'r') as f:
+            config_data = json.load(f)
+        
+        env_config = cls(config_data["width"], config_data["height"])
+        
+        # 鍔犺浇绔欑偣
+        for pos_str, info in config_data["stations"].items():
+            x, y = map(int, pos_str.split(','))
+            load_x, load_y = info["load_position"]
+            unload_x, unload_y = info["unload_position"]
+            env_config.add_station(x, y, info["capacity"], 
+                                  (load_x, load_y), (unload_x, unload_y))
+        
+        # 鍔犺浇璺緞
+        for path in config_data["paths"]:
+            env_config.add_path(path["x"], path["y"])
+        
+        # 鍔犺浇浠撳偍鍖哄煙
+        for area in config_data["storage_areas"]:
+            env_config.add_storage_area(area["x"], area["y"])
+        
+        # 鍔犺浇闅滅鐗�
+        for obstacle in config_data["obstacles"]:
+            env_config.add_obstacle(obstacle["x"], obstacle["y"])
+        
+        # 鏋勫缓閭绘帴琛�
+        env_config.build_adjacency_list()
+        
+        return env_config
+    
+    def create_default_environment(self) -> 'EnvironmentConfig':
+        """
+        鍒涘缓榛樿鐜閰嶇疆锛堟寜鐓ч渶姹傛弿杩伴厤缃珯鐐瑰拰璺緞锛�
+        
+        Returns:
+            EnvironmentConfig: 鐜閰嶇疆瀵硅薄
+        """
+        # 娓呯┖褰撳墠閰嶇疆
+        self.grid = np.full((self.height, self.width), CellType.EMPTY)
+        self.stations = {}
+        self.paths = set()
+        self.storage_areas = set()
+        self.loading_areas = set()
+        self.unloading_areas = set()
+        self.obstacles = set()
+        
+        # 閰嶇疆20涓珯鐐�
+        station_y = self.height - 5 
+        station_spacing = self.width // 25  # 绔欑偣闂磋窛
+        
+        for i in range(20):
+            station_x = (i + 1) * station_spacing
+            self.add_station(station_x, station_y)
+        
+        # 浠撳偍鍖哄煙
+        storage_start_y = 5
+        storage_end_y = station_y - 10
+        
+        for col in range(5):
+            col_x = (col + 1) * (self.width // 6)
+            
+            for row_y in range(storage_start_y, storage_end_y, 5):
+                for dx in range(-1, 2):
+                    for dy in range(-1, 2):
+                        self.add_storage_area(col_x + dx, row_y + dy)
+        
+        # 閰嶇疆璺緞
+        # 姘村钩涓昏矾寰�
+        for x in range(5, self.width - 5):
+            # 绔欑偣鍓嶆按骞宠矾寰�
+            self.add_path(x, station_y - 5)
+            # 璐ф灦鍖哄煙姘村钩璺緞
+            for path_y in range(10, storage_end_y, 10):
+                self.add_path(x, path_y)
+        
+        # 鍨傜洿杩炴帴璺緞
+        for col in range(7):
+            path_x = col * (self.width // 7)
+            for y in range(5, station_y):
+                self.add_path(path_x, y)
+        
+        # 鏋勫缓閭绘帴琛�
+        self.build_adjacency_list()
+        
+        return self
+
+
+# 鍒涘缓鍜屽垵濮嬪寲榛樿鐜鐨勮緟鍔╁嚱鏁�
+def create_default_environment(width=100, height=100) -> EnvironmentConfig:
+    """
+    鍒涘缓榛樿鐜閰嶇疆
+    
+    Args:
+        width: 鐜瀹藉害
+        height: 鐜楂樺害
+        
+    Returns:
+        EnvironmentConfig: 榛樿鐜閰嶇疆
+    """
+    env_config = EnvironmentConfig(width, height)
+    return env_config.create_default_environment()
\ No newline at end of file
diff --git a/config/settings.py b/config/settings.py
new file mode 100644
index 0000000..6911d2d
--- /dev/null
+++ b/config/settings.py
@@ -0,0 +1,27 @@
+"""
+鍏ㄥ眬璁剧疆鍜屽弬鏁伴厤缃� - 浠呬繚鐣欏疄闄呬娇鐢ㄧ殑閰嶇疆椤�
+"""
+
+# RCS鏈嶅姟鍣ㄩ厤缃�
+RCS_SERVER_HOST = "10.10.10.156"
+RCS_SERVER_PORT = 8088
+
+# 绠楁硶鏈嶅姟鍣ㄩ厤缃�  
+ALGORITHM_SERVER_HOST = "10.10.10.239"
+ALGORITHM_SERVER_PORT = 8002
+
+# 璺緞鐩戞帶鏈嶅姟閰嶇疆
+MONITOR_POLLING_INTERVAL = 5.0  # 璺緞鐩戞帶杞闂撮殧
+
+# API閰嶇疆
+AGV_STATUS_API_ENDPOINT = "/api/open/algorithm/getAgv"  # AGV鐘舵�佹煡璇rl
+
+# AGV閰嶇疆
+DEFAULT_AGV_COUNT = 50  # 榛樿AGV鏁伴噺
+
+# 缃戠粶閰嶇疆
+REQUEST_TIMEOUT = 30  # HTTP璇锋眰瓒呮椂鏃堕棿锛堢锛�
+
+# 鏃ュ織閰嶇疆
+LOG_LEVEL = "INFO" 
+LOG_FILE = "warehouse_system.log"  # 鏃ュ織鏂囦欢璺緞
\ No newline at end of file
diff --git a/environment.json b/environment.json
new file mode 100644
index 0000000..6915ebc
--- /dev/null
+++ b/environment.json
@@ -0,0 +1,14960 @@
+{
+  "width": 78,
+  "height": 50,
+  "stations": {
+    "2,48": {
+      "capacity": 4,
+      "load_position": [
+        3,
+        48
+      ],
+      "unload_position": [
+        1,
+        48
+      ]
+    },
+    "5,48": {
+      "capacity": 4,
+      "load_position": [
+        6,
+        48
+      ],
+      "unload_position": [
+        4,
+        48
+      ]
+    },
+    "8,48": {
+      "capacity": 4,
+      "load_position": [
+        9,
+        48
+      ],
+      "unload_position": [
+        7,
+        48
+      ]
+    },
+    "12,48": {
+      "capacity": 4,
+      "load_position": [
+        13,
+        48
+      ],
+      "unload_position": [
+        11,
+        48
+      ]
+    },
+    "18,48": {
+      "capacity": 4,
+      "load_position": [
+        19,
+        48
+      ],
+      "unload_position": [
+        17,
+        48
+      ]
+    },
+    "21,48": {
+      "capacity": 4,
+      "load_position": [
+        22,
+        48
+      ],
+      "unload_position": [
+        20,
+        48
+      ]
+    },
+    "24,48": {
+      "capacity": 4,
+      "load_position": [
+        25,
+        48
+      ],
+      "unload_position": [
+        23,
+        48
+      ]
+    },
+    "28,48": {
+      "capacity": 4,
+      "load_position": [
+        29,
+        48
+      ],
+      "unload_position": [
+        27,
+        48
+      ]
+    },
+    "34,48": {
+      "capacity": 4,
+      "load_position": [
+        35,
+        48
+      ],
+      "unload_position": [
+        33,
+        48
+      ]
+    },
+    "37,48": {
+      "capacity": 4,
+      "load_position": [
+        38,
+        48
+      ],
+      "unload_position": [
+        36,
+        48
+      ]
+    },
+    "40,48": {
+      "capacity": 4,
+      "load_position": [
+        41,
+        48
+      ],
+      "unload_position": [
+        39,
+        48
+      ]
+    },
+    "44,48": {
+      "capacity": 4,
+      "load_position": [
+        45,
+        48
+      ],
+      "unload_position": [
+        43,
+        48
+      ]
+    },
+    "50,48": {
+      "capacity": 4,
+      "load_position": [
+        51,
+        48
+      ],
+      "unload_position": [
+        49,
+        48
+      ]
+    },
+    "53,48": {
+      "capacity": 4,
+      "load_position": [
+        54,
+        48
+      ],
+      "unload_position": [
+        52,
+        48
+      ]
+    },
+    "56,48": {
+      "capacity": 4,
+      "load_position": [
+        57,
+        48
+      ],
+      "unload_position": [
+        55,
+        48
+      ]
+    },
+    "60,48": {
+      "capacity": 4,
+      "load_position": [
+        61,
+        48
+      ],
+      "unload_position": [
+        59,
+        48
+      ]
+    },
+    "66,48": {
+      "capacity": 4,
+      "load_position": [
+        67,
+        48
+      ],
+      "unload_position": [
+        65,
+        48
+      ]
+    },
+    "69,48": {
+      "capacity": 4,
+      "load_position": [
+        70,
+        48
+      ],
+      "unload_position": [
+        68,
+        48
+      ]
+    },
+    "72,48": {
+      "capacity": 4,
+      "load_position": [
+        73,
+        48
+      ],
+      "unload_position": [
+        71,
+        48
+      ]
+    },
+    "76,48": {
+      "capacity": 4,
+      "load_position": [
+        77,
+        48
+      ],
+      "unload_position": [
+        75,
+        48
+      ]
+    }
+  },
+  "paths": [
+    {
+      "x": 17,
+      "y": 0
+    },
+    {
+      "x": 18,
+      "y": 0
+    },
+    {
+      "x": 19,
+      "y": 0
+    },
+    {
+      "x": 20,
+      "y": 0
+    },
+    {
+      "x": 21,
+      "y": 0
+    },
+    {
+      "x": 22,
+      "y": 0
+    },
+    {
+      "x": 23,
+      "y": 0
+    },
+    {
+      "x": 24,
+      "y": 0
+    },
+    {
+      "x": 25,
+      "y": 0
+    },
+    {
+      "x": 26,
+      "y": 0
+    },
+    {
+      "x": 27,
+      "y": 0
+    },
+    {
+      "x": 28,
+      "y": 0
+    },
+    {
+      "x": 29,
+      "y": 0
+    },
+    {
+      "x": 30,
+      "y": 0
+    },
+    {
+      "x": 31,
+      "y": 0
+    },
+    {
+      "x": 32,
+      "y": 0
+    },
+    {
+      "x": 33,
+      "y": 0
+    },
+    {
+      "x": 34,
+      "y": 0
+    },
+    {
+      "x": 35,
+      "y": 0
+    },
+    {
+      "x": 36,
+      "y": 0
+    },
+    {
+      "x": 37,
+      "y": 0
+    },
+    {
+      "x": 38,
+      "y": 0
+    },
+    {
+      "x": 39,
+      "y": 0
+    },
+    {
+      "x": 40,
+      "y": 0
+    },
+    {
+      "x": 41,
+      "y": 0
+    },
+    {
+      "x": 42,
+      "y": 0
+    },
+    {
+      "x": 43,
+      "y": 0
+    },
+    {
+      "x": 44,
+      "y": 0
+    },
+    {
+      "x": 45,
+      "y": 0
+    },
+    {
+      "x": 46,
+      "y": 0
+    },
+    {
+      "x": 47,
+      "y": 0
+    },
+    {
+      "x": 48,
+      "y": 0
+    },
+    {
+      "x": 49,
+      "y": 0
+    },
+    {
+      "x": 50,
+      "y": 0
+    },
+    {
+      "x": 51,
+      "y": 0
+    },
+    {
+      "x": 52,
+      "y": 0
+    },
+    {
+      "x": 53,
+      "y": 0
+    },
+    {
+      "x": 54,
+      "y": 0
+    },
+    {
+      "x": 55,
+      "y": 0
+    },
+    {
+      "x": 56,
+      "y": 0
+    },
+    {
+      "x": 57,
+      "y": 0
+    },
+    {
+      "x": 58,
+      "y": 0
+    },
+    {
+      "x": 59,
+      "y": 0
+    },
+    {
+      "x": 60,
+      "y": 0
+    },
+    {
+      "x": 61,
+      "y": 0
+    },
+    {
+      "x": 17,
+      "y": 1
+    },
+    {
+      "x": 19,
+      "y": 1
+    },
+    {
+      "x": 21,
+      "y": 1
+    },
+    {
+      "x": 23,
+      "y": 1
+    },
+    {
+      "x": 25,
+      "y": 1
+    },
+    {
+      "x": 27,
+      "y": 1
+    },
+    {
+      "x": 29,
+      "y": 1
+    },
+    {
+      "x": 31,
+      "y": 1
+    },
+    {
+      "x": 33,
+      "y": 1
+    },
+    {
+      "x": 35,
+      "y": 1
+    },
+    {
+      "x": 37,
+      "y": 1
+    },
+    {
+      "x": 39,
+      "y": 1
+    },
+    {
+      "x": 41,
+      "y": 1
+    },
+    {
+      "x": 43,
+      "y": 1
+    },
+    {
+      "x": 45,
+      "y": 1
+    },
+    {
+      "x": 47,
+      "y": 1
+    },
+    {
+      "x": 49,
+      "y": 1
+    },
+    {
+      "x": 51,
+      "y": 1
+    },
+    {
+      "x": 53,
+      "y": 1
+    },
+    {
+      "x": 55,
+      "y": 1
+    },
+    {
+      "x": 57,
+      "y": 1
+    },
+    {
+      "x": 59,
+      "y": 1
+    },
+    {
+      "x": 61,
+      "y": 1
+    },
+    {
+      "x": 17,
+      "y": 2
+    },
+    {
+      "x": 19,
+      "y": 2
+    },
+    {
+      "x": 21,
+      "y": 2
+    },
+    {
+      "x": 23,
+      "y": 2
+    },
+    {
+      "x": 25,
+      "y": 2
+    },
+    {
+      "x": 27,
+      "y": 2
+    },
+    {
+      "x": 29,
+      "y": 2
+    },
+    {
+      "x": 31,
+      "y": 2
+    },
+    {
+      "x": 33,
+      "y": 2
+    },
+    {
+      "x": 35,
+      "y": 2
+    },
+    {
+      "x": 37,
+      "y": 2
+    },
+    {
+      "x": 39,
+      "y": 2
+    },
+    {
+      "x": 41,
+      "y": 2
+    },
+    {
+      "x": 43,
+      "y": 2
+    },
+    {
+      "x": 45,
+      "y": 2
+    },
+    {
+      "x": 47,
+      "y": 2
+    },
+    {
+      "x": 49,
+      "y": 2
+    },
+    {
+      "x": 51,
+      "y": 2
+    },
+    {
+      "x": 53,
+      "y": 2
+    },
+    {
+      "x": 55,
+      "y": 2
+    },
+    {
+      "x": 57,
+      "y": 2
+    },
+    {
+      "x": 59,
+      "y": 2
+    },
+    {
+      "x": 61,
+      "y": 2
+    },
+    {
+      "x": 17,
+      "y": 3
+    },
+    {
+      "x": 19,
+      "y": 3
+    },
+    {
+      "x": 21,
+      "y": 3
+    },
+    {
+      "x": 23,
+      "y": 3
+    },
+    {
+      "x": 25,
+      "y": 3
+    },
+    {
+      "x": 27,
+      "y": 3
+    },
+    {
+      "x": 29,
+      "y": 3
+    },
+    {
+      "x": 31,
+      "y": 3
+    },
+    {
+      "x": 33,
+      "y": 3
+    },
+    {
+      "x": 35,
+      "y": 3
+    },
+    {
+      "x": 37,
+      "y": 3
+    },
+    {
+      "x": 39,
+      "y": 3
+    },
+    {
+      "x": 41,
+      "y": 3
+    },
+    {
+      "x": 43,
+      "y": 3
+    },
+    {
+      "x": 45,
+      "y": 3
+    },
+    {
+      "x": 47,
+      "y": 3
+    },
+    {
+      "x": 49,
+      "y": 3
+    },
+    {
+      "x": 51,
+      "y": 3
+    },
+    {
+      "x": 53,
+      "y": 3
+    },
+    {
+      "x": 55,
+      "y": 3
+    },
+    {
+      "x": 57,
+      "y": 3
+    },
+    {
+      "x": 59,
+      "y": 3
+    },
+    {
+      "x": 61,
+      "y": 3
+    },
+    {
+      "x": 17,
+      "y": 4
+    },
+    {
+      "x": 19,
+      "y": 4
+    },
+    {
+      "x": 21,
+      "y": 4
+    },
+    {
+      "x": 23,
+      "y": 4
+    },
+    {
+      "x": 25,
+      "y": 4
+    },
+    {
+      "x": 27,
+      "y": 4
+    },
+    {
+      "x": 29,
+      "y": 4
+    },
+    {
+      "x": 31,
+      "y": 4
+    },
+    {
+      "x": 33,
+      "y": 4
+    },
+    {
+      "x": 35,
+      "y": 4
+    },
+    {
+      "x": 37,
+      "y": 4
+    },
+    {
+      "x": 39,
+      "y": 4
+    },
+    {
+      "x": 41,
+      "y": 4
+    },
+    {
+      "x": 43,
+      "y": 4
+    },
+    {
+      "x": 45,
+      "y": 4
+    },
+    {
+      "x": 47,
+      "y": 4
+    },
+    {
+      "x": 49,
+      "y": 4
+    },
+    {
+      "x": 51,
+      "y": 4
+    },
+    {
+      "x": 53,
+      "y": 4
+    },
+    {
+      "x": 55,
+      "y": 4
+    },
+    {
+      "x": 57,
+      "y": 4
+    },
+    {
+      "x": 59,
+      "y": 4
+    },
+    {
+      "x": 61,
+      "y": 4
+    },
+    {
+      "x": 17,
+      "y": 5
+    },
+    {
+      "x": 19,
+      "y": 5
+    },
+    {
+      "x": 21,
+      "y": 5
+    },
+    {
+      "x": 23,
+      "y": 5
+    },
+    {
+      "x": 25,
+      "y": 5
+    },
+    {
+      "x": 27,
+      "y": 5
+    },
+    {
+      "x": 29,
+      "y": 5
+    },
+    {
+      "x": 31,
+      "y": 5
+    },
+    {
+      "x": 33,
+      "y": 5
+    },
+    {
+      "x": 35,
+      "y": 5
+    },
+    {
+      "x": 37,
+      "y": 5
+    },
+    {
+      "x": 39,
+      "y": 5
+    },
+    {
+      "x": 41,
+      "y": 5
+    },
+    {
+      "x": 43,
+      "y": 5
+    },
+    {
+      "x": 45,
+      "y": 5
+    },
+    {
+      "x": 47,
+      "y": 5
+    },
+    {
+      "x": 49,
+      "y": 5
+    },
+    {
+      "x": 51,
+      "y": 5
+    },
+    {
+      "x": 53,
+      "y": 5
+    },
+    {
+      "x": 55,
+      "y": 5
+    },
+    {
+      "x": 57,
+      "y": 5
+    },
+    {
+      "x": 59,
+      "y": 5
+    },
+    {
+      "x": 61,
+      "y": 5
+    },
+    {
+      "x": 17,
+      "y": 6
+    },
+    {
+      "x": 18,
+      "y": 6
+    },
+    {
+      "x": 19,
+      "y": 6
+    },
+    {
+      "x": 20,
+      "y": 6
+    },
+    {
+      "x": 21,
+      "y": 6
+    },
+    {
+      "x": 22,
+      "y": 6
+    },
+    {
+      "x": 23,
+      "y": 6
+    },
+    {
+      "x": 24,
+      "y": 6
+    },
+    {
+      "x": 25,
+      "y": 6
+    },
+    {
+      "x": 26,
+      "y": 6
+    },
+    {
+      "x": 27,
+      "y": 6
+    },
+    {
+      "x": 28,
+      "y": 6
+    },
+    {
+      "x": 29,
+      "y": 6
+    },
+    {
+      "x": 30,
+      "y": 6
+    },
+    {
+      "x": 31,
+      "y": 6
+    },
+    {
+      "x": 32,
+      "y": 6
+    },
+    {
+      "x": 33,
+      "y": 6
+    },
+    {
+      "x": 34,
+      "y": 6
+    },
+    {
+      "x": 35,
+      "y": 6
+    },
+    {
+      "x": 36,
+      "y": 6
+    },
+    {
+      "x": 37,
+      "y": 6
+    },
+    {
+      "x": 38,
+      "y": 6
+    },
+    {
+      "x": 39,
+      "y": 6
+    },
+    {
+      "x": 40,
+      "y": 6
+    },
+    {
+      "x": 41,
+      "y": 6
+    },
+    {
+      "x": 42,
+      "y": 6
+    },
+    {
+      "x": 43,
+      "y": 6
+    },
+    {
+      "x": 44,
+      "y": 6
+    },
+    {
+      "x": 45,
+      "y": 6
+    },
+    {
+      "x": 46,
+      "y": 6
+    },
+    {
+      "x": 47,
+      "y": 6
+    },
+    {
+      "x": 48,
+      "y": 6
+    },
+    {
+      "x": 49,
+      "y": 6
+    },
+    {
+      "x": 50,
+      "y": 6
+    },
+    {
+      "x": 51,
+      "y": 6
+    },
+    {
+      "x": 52,
+      "y": 6
+    },
+    {
+      "x": 53,
+      "y": 6
+    },
+    {
+      "x": 54,
+      "y": 6
+    },
+    {
+      "x": 55,
+      "y": 6
+    },
+    {
+      "x": 56,
+      "y": 6
+    },
+    {
+      "x": 57,
+      "y": 6
+    },
+    {
+      "x": 58,
+      "y": 6
+    },
+    {
+      "x": 59,
+      "y": 6
+    },
+    {
+      "x": 60,
+      "y": 6
+    },
+    {
+      "x": 61,
+      "y": 6
+    },
+    {
+      "x": 17,
+      "y": 7
+    },
+    {
+      "x": 19,
+      "y": 7
+    },
+    {
+      "x": 21,
+      "y": 7
+    },
+    {
+      "x": 23,
+      "y": 7
+    },
+    {
+      "x": 25,
+      "y": 7
+    },
+    {
+      "x": 27,
+      "y": 7
+    },
+    {
+      "x": 29,
+      "y": 7
+    },
+    {
+      "x": 31,
+      "y": 7
+    },
+    {
+      "x": 33,
+      "y": 7
+    },
+    {
+      "x": 35,
+      "y": 7
+    },
+    {
+      "x": 37,
+      "y": 7
+    },
+    {
+      "x": 39,
+      "y": 7
+    },
+    {
+      "x": 41,
+      "y": 7
+    },
+    {
+      "x": 43,
+      "y": 7
+    },
+    {
+      "x": 45,
+      "y": 7
+    },
+    {
+      "x": 47,
+      "y": 7
+    },
+    {
+      "x": 49,
+      "y": 7
+    },
+    {
+      "x": 51,
+      "y": 7
+    },
+    {
+      "x": 53,
+      "y": 7
+    },
+    {
+      "x": 55,
+      "y": 7
+    },
+    {
+      "x": 57,
+      "y": 7
+    },
+    {
+      "x": 59,
+      "y": 7
+    },
+    {
+      "x": 61,
+      "y": 7
+    },
+    {
+      "x": 17,
+      "y": 8
+    },
+    {
+      "x": 19,
+      "y": 8
+    },
+    {
+      "x": 21,
+      "y": 8
+    },
+    {
+      "x": 23,
+      "y": 8
+    },
+    {
+      "x": 25,
+      "y": 8
+    },
+    {
+      "x": 27,
+      "y": 8
+    },
+    {
+      "x": 29,
+      "y": 8
+    },
+    {
+      "x": 31,
+      "y": 8
+    },
+    {
+      "x": 33,
+      "y": 8
+    },
+    {
+      "x": 35,
+      "y": 8
+    },
+    {
+      "x": 37,
+      "y": 8
+    },
+    {
+      "x": 39,
+      "y": 8
+    },
+    {
+      "x": 41,
+      "y": 8
+    },
+    {
+      "x": 43,
+      "y": 8
+    },
+    {
+      "x": 45,
+      "y": 8
+    },
+    {
+      "x": 47,
+      "y": 8
+    },
+    {
+      "x": 49,
+      "y": 8
+    },
+    {
+      "x": 51,
+      "y": 8
+    },
+    {
+      "x": 53,
+      "y": 8
+    },
+    {
+      "x": 55,
+      "y": 8
+    },
+    {
+      "x": 57,
+      "y": 8
+    },
+    {
+      "x": 59,
+      "y": 8
+    },
+    {
+      "x": 61,
+      "y": 8
+    },
+    {
+      "x": 17,
+      "y": 9
+    },
+    {
+      "x": 19,
+      "y": 9
+    },
+    {
+      "x": 21,
+      "y": 9
+    },
+    {
+      "x": 23,
+      "y": 9
+    },
+    {
+      "x": 25,
+      "y": 9
+    },
+    {
+      "x": 27,
+      "y": 9
+    },
+    {
+      "x": 29,
+      "y": 9
+    },
+    {
+      "x": 31,
+      "y": 9
+    },
+    {
+      "x": 33,
+      "y": 9
+    },
+    {
+      "x": 35,
+      "y": 9
+    },
+    {
+      "x": 37,
+      "y": 9
+    },
+    {
+      "x": 39,
+      "y": 9
+    },
+    {
+      "x": 41,
+      "y": 9
+    },
+    {
+      "x": 43,
+      "y": 9
+    },
+    {
+      "x": 45,
+      "y": 9
+    },
+    {
+      "x": 47,
+      "y": 9
+    },
+    {
+      "x": 49,
+      "y": 9
+    },
+    {
+      "x": 51,
+      "y": 9
+    },
+    {
+      "x": 53,
+      "y": 9
+    },
+    {
+      "x": 55,
+      "y": 9
+    },
+    {
+      "x": 57,
+      "y": 9
+    },
+    {
+      "x": 59,
+      "y": 9
+    },
+    {
+      "x": 61,
+      "y": 9
+    },
+    {
+      "x": 17,
+      "y": 10
+    },
+    {
+      "x": 19,
+      "y": 10
+    },
+    {
+      "x": 21,
+      "y": 10
+    },
+    {
+      "x": 23,
+      "y": 10
+    },
+    {
+      "x": 25,
+      "y": 10
+    },
+    {
+      "x": 27,
+      "y": 10
+    },
+    {
+      "x": 29,
+      "y": 10
+    },
+    {
+      "x": 31,
+      "y": 10
+    },
+    {
+      "x": 33,
+      "y": 10
+    },
+    {
+      "x": 35,
+      "y": 10
+    },
+    {
+      "x": 37,
+      "y": 10
+    },
+    {
+      "x": 39,
+      "y": 10
+    },
+    {
+      "x": 41,
+      "y": 10
+    },
+    {
+      "x": 43,
+      "y": 10
+    },
+    {
+      "x": 45,
+      "y": 10
+    },
+    {
+      "x": 47,
+      "y": 10
+    },
+    {
+      "x": 49,
+      "y": 10
+    },
+    {
+      "x": 51,
+      "y": 10
+    },
+    {
+      "x": 53,
+      "y": 10
+    },
+    {
+      "x": 55,
+      "y": 10
+    },
+    {
+      "x": 57,
+      "y": 10
+    },
+    {
+      "x": 59,
+      "y": 10
+    },
+    {
+      "x": 61,
+      "y": 10
+    },
+    {
+      "x": 17,
+      "y": 11
+    },
+    {
+      "x": 19,
+      "y": 11
+    },
+    {
+      "x": 21,
+      "y": 11
+    },
+    {
+      "x": 23,
+      "y": 11
+    },
+    {
+      "x": 25,
+      "y": 11
+    },
+    {
+      "x": 27,
+      "y": 11
+    },
+    {
+      "x": 29,
+      "y": 11
+    },
+    {
+      "x": 31,
+      "y": 11
+    },
+    {
+      "x": 33,
+      "y": 11
+    },
+    {
+      "x": 35,
+      "y": 11
+    },
+    {
+      "x": 37,
+      "y": 11
+    },
+    {
+      "x": 39,
+      "y": 11
+    },
+    {
+      "x": 41,
+      "y": 11
+    },
+    {
+      "x": 43,
+      "y": 11
+    },
+    {
+      "x": 45,
+      "y": 11
+    },
+    {
+      "x": 47,
+      "y": 11
+    },
+    {
+      "x": 49,
+      "y": 11
+    },
+    {
+      "x": 51,
+      "y": 11
+    },
+    {
+      "x": 53,
+      "y": 11
+    },
+    {
+      "x": 55,
+      "y": 11
+    },
+    {
+      "x": 57,
+      "y": 11
+    },
+    {
+      "x": 59,
+      "y": 11
+    },
+    {
+      "x": 61,
+      "y": 11
+    },
+    {
+      "x": 1,
+      "y": 12
+    },
+    {
+      "x": 2,
+      "y": 12
+    },
+    {
+      "x": 3,
+      "y": 12
+    },
+    {
+      "x": 4,
+      "y": 12
+    },
+    {
+      "x": 5,
+      "y": 12
+    },
+    {
+      "x": 6,
+      "y": 12
+    },
+    {
+      "x": 7,
+      "y": 12
+    },
+    {
+      "x": 8,
+      "y": 12
+    },
+    {
+      "x": 9,
+      "y": 12
+    },
+    {
+      "x": 10,
+      "y": 12
+    },
+    {
+      "x": 11,
+      "y": 12
+    },
+    {
+      "x": 12,
+      "y": 12
+    },
+    {
+      "x": 13,
+      "y": 12
+    },
+    {
+      "x": 14,
+      "y": 12
+    },
+    {
+      "x": 15,
+      "y": 12
+    },
+    {
+      "x": 16,
+      "y": 12
+    },
+    {
+      "x": 17,
+      "y": 12
+    },
+    {
+      "x": 18,
+      "y": 12
+    },
+    {
+      "x": 19,
+      "y": 12
+    },
+    {
+      "x": 20,
+      "y": 12
+    },
+    {
+      "x": 21,
+      "y": 12
+    },
+    {
+      "x": 22,
+      "y": 12
+    },
+    {
+      "x": 23,
+      "y": 12
+    },
+    {
+      "x": 24,
+      "y": 12
+    },
+    {
+      "x": 25,
+      "y": 12
+    },
+    {
+      "x": 26,
+      "y": 12
+    },
+    {
+      "x": 27,
+      "y": 12
+    },
+    {
+      "x": 28,
+      "y": 12
+    },
+    {
+      "x": 29,
+      "y": 12
+    },
+    {
+      "x": 30,
+      "y": 12
+    },
+    {
+      "x": 31,
+      "y": 12
+    },
+    {
+      "x": 32,
+      "y": 12
+    },
+    {
+      "x": 33,
+      "y": 12
+    },
+    {
+      "x": 34,
+      "y": 12
+    },
+    {
+      "x": 35,
+      "y": 12
+    },
+    {
+      "x": 36,
+      "y": 12
+    },
+    {
+      "x": 37,
+      "y": 12
+    },
+    {
+      "x": 38,
+      "y": 12
+    },
+    {
+      "x": 39,
+      "y": 12
+    },
+    {
+      "x": 40,
+      "y": 12
+    },
+    {
+      "x": 41,
+      "y": 12
+    },
+    {
+      "x": 42,
+      "y": 12
+    },
+    {
+      "x": 43,
+      "y": 12
+    },
+    {
+      "x": 44,
+      "y": 12
+    },
+    {
+      "x": 45,
+      "y": 12
+    },
+    {
+      "x": 46,
+      "y": 12
+    },
+    {
+      "x": 47,
+      "y": 12
+    },
+    {
+      "x": 48,
+      "y": 12
+    },
+    {
+      "x": 49,
+      "y": 12
+    },
+    {
+      "x": 50,
+      "y": 12
+    },
+    {
+      "x": 51,
+      "y": 12
+    },
+    {
+      "x": 52,
+      "y": 12
+    },
+    {
+      "x": 53,
+      "y": 12
+    },
+    {
+      "x": 54,
+      "y": 12
+    },
+    {
+      "x": 55,
+      "y": 12
+    },
+    {
+      "x": 56,
+      "y": 12
+    },
+    {
+      "x": 57,
+      "y": 12
+    },
+    {
+      "x": 58,
+      "y": 12
+    },
+    {
+      "x": 59,
+      "y": 12
+    },
+    {
+      "x": 60,
+      "y": 12
+    },
+    {
+      "x": 61,
+      "y": 12
+    },
+    {
+      "x": 62,
+      "y": 12
+    },
+    {
+      "x": 63,
+      "y": 12
+    },
+    {
+      "x": 64,
+      "y": 12
+    },
+    {
+      "x": 65,
+      "y": 12
+    },
+    {
+      "x": 66,
+      "y": 12
+    },
+    {
+      "x": 67,
+      "y": 12
+    },
+    {
+      "x": 68,
+      "y": 12
+    },
+    {
+      "x": 69,
+      "y": 12
+    },
+    {
+      "x": 70,
+      "y": 12
+    },
+    {
+      "x": 71,
+      "y": 12
+    },
+    {
+      "x": 72,
+      "y": 12
+    },
+    {
+      "x": 73,
+      "y": 12
+    },
+    {
+      "x": 74,
+      "y": 12
+    },
+    {
+      "x": 75,
+      "y": 12
+    },
+    {
+      "x": 1,
+      "y": 13
+    },
+    {
+      "x": 3,
+      "y": 13
+    },
+    {
+      "x": 5,
+      "y": 13
+    },
+    {
+      "x": 7,
+      "y": 13
+    },
+    {
+      "x": 9,
+      "y": 13
+    },
+    {
+      "x": 11,
+      "y": 13
+    },
+    {
+      "x": 13,
+      "y": 13
+    },
+    {
+      "x": 15,
+      "y": 13
+    },
+    {
+      "x": 17,
+      "y": 13
+    },
+    {
+      "x": 19,
+      "y": 13
+    },
+    {
+      "x": 21,
+      "y": 13
+    },
+    {
+      "x": 23,
+      "y": 13
+    },
+    {
+      "x": 25,
+      "y": 13
+    },
+    {
+      "x": 27,
+      "y": 13
+    },
+    {
+      "x": 29,
+      "y": 13
+    },
+    {
+      "x": 31,
+      "y": 13
+    },
+    {
+      "x": 33,
+      "y": 13
+    },
+    {
+      "x": 35,
+      "y": 13
+    },
+    {
+      "x": 37,
+      "y": 13
+    },
+    {
+      "x": 39,
+      "y": 13
+    },
+    {
+      "x": 41,
+      "y": 13
+    },
+    {
+      "x": 43,
+      "y": 13
+    },
+    {
+      "x": 45,
+      "y": 13
+    },
+    {
+      "x": 47,
+      "y": 13
+    },
+    {
+      "x": 49,
+      "y": 13
+    },
+    {
+      "x": 51,
+      "y": 13
+    },
+    {
+      "x": 53,
+      "y": 13
+    },
+    {
+      "x": 55,
+      "y": 13
+    },
+    {
+      "x": 57,
+      "y": 13
+    },
+    {
+      "x": 59,
+      "y": 13
+    },
+    {
+      "x": 61,
+      "y": 13
+    },
+    {
+      "x": 63,
+      "y": 13
+    },
+    {
+      "x": 65,
+      "y": 13
+    },
+    {
+      "x": 67,
+      "y": 13
+    },
+    {
+      "x": 69,
+      "y": 13
+    },
+    {
+      "x": 71,
+      "y": 13
+    },
+    {
+      "x": 73,
+      "y": 13
+    },
+    {
+      "x": 75,
+      "y": 13
+    },
+    {
+      "x": 1,
+      "y": 14
+    },
+    {
+      "x": 3,
+      "y": 14
+    },
+    {
+      "x": 5,
+      "y": 14
+    },
+    {
+      "x": 7,
+      "y": 14
+    },
+    {
+      "x": 9,
+      "y": 14
+    },
+    {
+      "x": 11,
+      "y": 14
+    },
+    {
+      "x": 13,
+      "y": 14
+    },
+    {
+      "x": 15,
+      "y": 14
+    },
+    {
+      "x": 17,
+      "y": 14
+    },
+    {
+      "x": 19,
+      "y": 14
+    },
+    {
+      "x": 21,
+      "y": 14
+    },
+    {
+      "x": 23,
+      "y": 14
+    },
+    {
+      "x": 25,
+      "y": 14
+    },
+    {
+      "x": 27,
+      "y": 14
+    },
+    {
+      "x": 29,
+      "y": 14
+    },
+    {
+      "x": 31,
+      "y": 14
+    },
+    {
+      "x": 33,
+      "y": 14
+    },
+    {
+      "x": 35,
+      "y": 14
+    },
+    {
+      "x": 37,
+      "y": 14
+    },
+    {
+      "x": 39,
+      "y": 14
+    },
+    {
+      "x": 41,
+      "y": 14
+    },
+    {
+      "x": 43,
+      "y": 14
+    },
+    {
+      "x": 45,
+      "y": 14
+    },
+    {
+      "x": 47,
+      "y": 14
+    },
+    {
+      "x": 49,
+      "y": 14
+    },
+    {
+      "x": 51,
+      "y": 14
+    },
+    {
+      "x": 53,
+      "y": 14
+    },
+    {
+      "x": 55,
+      "y": 14
+    },
+    {
+      "x": 57,
+      "y": 14
+    },
+    {
+      "x": 59,
+      "y": 14
+    },
+    {
+      "x": 61,
+      "y": 14
+    },
+    {
+      "x": 63,
+      "y": 14
+    },
+    {
+      "x": 65,
+      "y": 14
+    },
+    {
+      "x": 67,
+      "y": 14
+    },
+    {
+      "x": 69,
+      "y": 14
+    },
+    {
+      "x": 71,
+      "y": 14
+    },
+    {
+      "x": 73,
+      "y": 14
+    },
+    {
+      "x": 75,
+      "y": 14
+    },
+    {
+      "x": 1,
+      "y": 15
+    },
+    {
+      "x": 3,
+      "y": 15
+    },
+    {
+      "x": 5,
+      "y": 15
+    },
+    {
+      "x": 7,
+      "y": 15
+    },
+    {
+      "x": 9,
+      "y": 15
+    },
+    {
+      "x": 11,
+      "y": 15
+    },
+    {
+      "x": 13,
+      "y": 15
+    },
+    {
+      "x": 15,
+      "y": 15
+    },
+    {
+      "x": 17,
+      "y": 15
+    },
+    {
+      "x": 19,
+      "y": 15
+    },
+    {
+      "x": 21,
+      "y": 15
+    },
+    {
+      "x": 23,
+      "y": 15
+    },
+    {
+      "x": 25,
+      "y": 15
+    },
+    {
+      "x": 27,
+      "y": 15
+    },
+    {
+      "x": 29,
+      "y": 15
+    },
+    {
+      "x": 31,
+      "y": 15
+    },
+    {
+      "x": 33,
+      "y": 15
+    },
+    {
+      "x": 35,
+      "y": 15
+    },
+    {
+      "x": 37,
+      "y": 15
+    },
+    {
+      "x": 39,
+      "y": 15
+    },
+    {
+      "x": 41,
+      "y": 15
+    },
+    {
+      "x": 43,
+      "y": 15
+    },
+    {
+      "x": 45,
+      "y": 15
+    },
+    {
+      "x": 47,
+      "y": 15
+    },
+    {
+      "x": 49,
+      "y": 15
+    },
+    {
+      "x": 51,
+      "y": 15
+    },
+    {
+      "x": 53,
+      "y": 15
+    },
+    {
+      "x": 55,
+      "y": 15
+    },
+    {
+      "x": 57,
+      "y": 15
+    },
+    {
+      "x": 59,
+      "y": 15
+    },
+    {
+      "x": 61,
+      "y": 15
+    },
+    {
+      "x": 63,
+      "y": 15
+    },
+    {
+      "x": 65,
+      "y": 15
+    },
+    {
+      "x": 67,
+      "y": 15
+    },
+    {
+      "x": 69,
+      "y": 15
+    },
+    {
+      "x": 71,
+      "y": 15
+    },
+    {
+      "x": 73,
+      "y": 15
+    },
+    {
+      "x": 75,
+      "y": 15
+    },
+    {
+      "x": 1,
+      "y": 16
+    },
+    {
+      "x": 3,
+      "y": 16
+    },
+    {
+      "x": 5,
+      "y": 16
+    },
+    {
+      "x": 7,
+      "y": 16
+    },
+    {
+      "x": 9,
+      "y": 16
+    },
+    {
+      "x": 11,
+      "y": 16
+    },
+    {
+      "x": 13,
+      "y": 16
+    },
+    {
+      "x": 15,
+      "y": 16
+    },
+    {
+      "x": 17,
+      "y": 16
+    },
+    {
+      "x": 19,
+      "y": 16
+    },
+    {
+      "x": 21,
+      "y": 16
+    },
+    {
+      "x": 23,
+      "y": 16
+    },
+    {
+      "x": 25,
+      "y": 16
+    },
+    {
+      "x": 27,
+      "y": 16
+    },
+    {
+      "x": 29,
+      "y": 16
+    },
+    {
+      "x": 31,
+      "y": 16
+    },
+    {
+      "x": 33,
+      "y": 16
+    },
+    {
+      "x": 35,
+      "y": 16
+    },
+    {
+      "x": 37,
+      "y": 16
+    },
+    {
+      "x": 39,
+      "y": 16
+    },
+    {
+      "x": 41,
+      "y": 16
+    },
+    {
+      "x": 43,
+      "y": 16
+    },
+    {
+      "x": 45,
+      "y": 16
+    },
+    {
+      "x": 47,
+      "y": 16
+    },
+    {
+      "x": 49,
+      "y": 16
+    },
+    {
+      "x": 51,
+      "y": 16
+    },
+    {
+      "x": 53,
+      "y": 16
+    },
+    {
+      "x": 55,
+      "y": 16
+    },
+    {
+      "x": 57,
+      "y": 16
+    },
+    {
+      "x": 59,
+      "y": 16
+    },
+    {
+      "x": 61,
+      "y": 16
+    },
+    {
+      "x": 63,
+      "y": 16
+    },
+    {
+      "x": 65,
+      "y": 16
+    },
+    {
+      "x": 67,
+      "y": 16
+    },
+    {
+      "x": 69,
+      "y": 16
+    },
+    {
+      "x": 71,
+      "y": 16
+    },
+    {
+      "x": 73,
+      "y": 16
+    },
+    {
+      "x": 75,
+      "y": 16
+    },
+    {
+      "x": 1,
+      "y": 17
+    },
+    {
+      "x": 3,
+      "y": 17
+    },
+    {
+      "x": 5,
+      "y": 17
+    },
+    {
+      "x": 7,
+      "y": 17
+    },
+    {
+      "x": 9,
+      "y": 17
+    },
+    {
+      "x": 11,
+      "y": 17
+    },
+    {
+      "x": 13,
+      "y": 17
+    },
+    {
+      "x": 15,
+      "y": 17
+    },
+    {
+      "x": 17,
+      "y": 17
+    },
+    {
+      "x": 19,
+      "y": 17
+    },
+    {
+      "x": 21,
+      "y": 17
+    },
+    {
+      "x": 23,
+      "y": 17
+    },
+    {
+      "x": 25,
+      "y": 17
+    },
+    {
+      "x": 27,
+      "y": 17
+    },
+    {
+      "x": 29,
+      "y": 17
+    },
+    {
+      "x": 31,
+      "y": 17
+    },
+    {
+      "x": 33,
+      "y": 17
+    },
+    {
+      "x": 35,
+      "y": 17
+    },
+    {
+      "x": 37,
+      "y": 17
+    },
+    {
+      "x": 39,
+      "y": 17
+    },
+    {
+      "x": 41,
+      "y": 17
+    },
+    {
+      "x": 43,
+      "y": 17
+    },
+    {
+      "x": 45,
+      "y": 17
+    },
+    {
+      "x": 47,
+      "y": 17
+    },
+    {
+      "x": 49,
+      "y": 17
+    },
+    {
+      "x": 51,
+      "y": 17
+    },
+    {
+      "x": 53,
+      "y": 17
+    },
+    {
+      "x": 55,
+      "y": 17
+    },
+    {
+      "x": 57,
+      "y": 17
+    },
+    {
+      "x": 59,
+      "y": 17
+    },
+    {
+      "x": 61,
+      "y": 17
+    },
+    {
+      "x": 63,
+      "y": 17
+    },
+    {
+      "x": 65,
+      "y": 17
+    },
+    {
+      "x": 67,
+      "y": 17
+    },
+    {
+      "x": 69,
+      "y": 17
+    },
+    {
+      "x": 71,
+      "y": 17
+    },
+    {
+      "x": 73,
+      "y": 17
+    },
+    {
+      "x": 75,
+      "y": 17
+    },
+    {
+      "x": 1,
+      "y": 18
+    },
+    {
+      "x": 3,
+      "y": 18
+    },
+    {
+      "x": 5,
+      "y": 18
+    },
+    {
+      "x": 7,
+      "y": 18
+    },
+    {
+      "x": 9,
+      "y": 18
+    },
+    {
+      "x": 11,
+      "y": 18
+    },
+    {
+      "x": 13,
+      "y": 18
+    },
+    {
+      "x": 15,
+      "y": 18
+    },
+    {
+      "x": 17,
+      "y": 18
+    },
+    {
+      "x": 19,
+      "y": 18
+    },
+    {
+      "x": 21,
+      "y": 18
+    },
+    {
+      "x": 23,
+      "y": 18
+    },
+    {
+      "x": 25,
+      "y": 18
+    },
+    {
+      "x": 27,
+      "y": 18
+    },
+    {
+      "x": 29,
+      "y": 18
+    },
+    {
+      "x": 31,
+      "y": 18
+    },
+    {
+      "x": 33,
+      "y": 18
+    },
+    {
+      "x": 35,
+      "y": 18
+    },
+    {
+      "x": 37,
+      "y": 18
+    },
+    {
+      "x": 39,
+      "y": 18
+    },
+    {
+      "x": 41,
+      "y": 18
+    },
+    {
+      "x": 43,
+      "y": 18
+    },
+    {
+      "x": 45,
+      "y": 18
+    },
+    {
+      "x": 47,
+      "y": 18
+    },
+    {
+      "x": 49,
+      "y": 18
+    },
+    {
+      "x": 51,
+      "y": 18
+    },
+    {
+      "x": 53,
+      "y": 18
+    },
+    {
+      "x": 55,
+      "y": 18
+    },
+    {
+      "x": 57,
+      "y": 18
+    },
+    {
+      "x": 59,
+      "y": 18
+    },
+    {
+      "x": 61,
+      "y": 18
+    },
+    {
+      "x": 63,
+      "y": 18
+    },
+    {
+      "x": 65,
+      "y": 18
+    },
+    {
+      "x": 67,
+      "y": 18
+    },
+    {
+      "x": 69,
+      "y": 18
+    },
+    {
+      "x": 71,
+      "y": 18
+    },
+    {
+      "x": 73,
+      "y": 18
+    },
+    {
+      "x": 75,
+      "y": 18
+    },
+    {
+      "x": 1,
+      "y": 19
+    },
+    {
+      "x": 3,
+      "y": 19
+    },
+    {
+      "x": 5,
+      "y": 19
+    },
+    {
+      "x": 7,
+      "y": 19
+    },
+    {
+      "x": 9,
+      "y": 19
+    },
+    {
+      "x": 11,
+      "y": 19
+    },
+    {
+      "x": 13,
+      "y": 19
+    },
+    {
+      "x": 15,
+      "y": 19
+    },
+    {
+      "x": 17,
+      "y": 19
+    },
+    {
+      "x": 19,
+      "y": 19
+    },
+    {
+      "x": 21,
+      "y": 19
+    },
+    {
+      "x": 23,
+      "y": 19
+    },
+    {
+      "x": 25,
+      "y": 19
+    },
+    {
+      "x": 27,
+      "y": 19
+    },
+    {
+      "x": 29,
+      "y": 19
+    },
+    {
+      "x": 31,
+      "y": 19
+    },
+    {
+      "x": 33,
+      "y": 19
+    },
+    {
+      "x": 35,
+      "y": 19
+    },
+    {
+      "x": 37,
+      "y": 19
+    },
+    {
+      "x": 39,
+      "y": 19
+    },
+    {
+      "x": 41,
+      "y": 19
+    },
+    {
+      "x": 43,
+      "y": 19
+    },
+    {
+      "x": 45,
+      "y": 19
+    },
+    {
+      "x": 47,
+      "y": 19
+    },
+    {
+      "x": 49,
+      "y": 19
+    },
+    {
+      "x": 51,
+      "y": 19
+    },
+    {
+      "x": 53,
+      "y": 19
+    },
+    {
+      "x": 55,
+      "y": 19
+    },
+    {
+      "x": 57,
+      "y": 19
+    },
+    {
+      "x": 59,
+      "y": 19
+    },
+    {
+      "x": 61,
+      "y": 19
+    },
+    {
+      "x": 63,
+      "y": 19
+    },
+    {
+      "x": 65,
+      "y": 19
+    },
+    {
+      "x": 67,
+      "y": 19
+    },
+    {
+      "x": 69,
+      "y": 19
+    },
+    {
+      "x": 71,
+      "y": 19
+    },
+    {
+      "x": 73,
+      "y": 19
+    },
+    {
+      "x": 75,
+      "y": 19
+    },
+    {
+      "x": 1,
+      "y": 20
+    },
+    {
+      "x": 3,
+      "y": 20
+    },
+    {
+      "x": 5,
+      "y": 20
+    },
+    {
+      "x": 7,
+      "y": 20
+    },
+    {
+      "x": 9,
+      "y": 20
+    },
+    {
+      "x": 11,
+      "y": 20
+    },
+    {
+      "x": 13,
+      "y": 20
+    },
+    {
+      "x": 15,
+      "y": 20
+    },
+    {
+      "x": 17,
+      "y": 20
+    },
+    {
+      "x": 19,
+      "y": 20
+    },
+    {
+      "x": 21,
+      "y": 20
+    },
+    {
+      "x": 23,
+      "y": 20
+    },
+    {
+      "x": 25,
+      "y": 20
+    },
+    {
+      "x": 27,
+      "y": 20
+    },
+    {
+      "x": 29,
+      "y": 20
+    },
+    {
+      "x": 31,
+      "y": 20
+    },
+    {
+      "x": 33,
+      "y": 20
+    },
+    {
+      "x": 35,
+      "y": 20
+    },
+    {
+      "x": 37,
+      "y": 20
+    },
+    {
+      "x": 39,
+      "y": 20
+    },
+    {
+      "x": 41,
+      "y": 20
+    },
+    {
+      "x": 43,
+      "y": 20
+    },
+    {
+      "x": 45,
+      "y": 20
+    },
+    {
+      "x": 47,
+      "y": 20
+    },
+    {
+      "x": 49,
+      "y": 20
+    },
+    {
+      "x": 51,
+      "y": 20
+    },
+    {
+      "x": 53,
+      "y": 20
+    },
+    {
+      "x": 55,
+      "y": 20
+    },
+    {
+      "x": 57,
+      "y": 20
+    },
+    {
+      "x": 59,
+      "y": 20
+    },
+    {
+      "x": 61,
+      "y": 20
+    },
+    {
+      "x": 63,
+      "y": 20
+    },
+    {
+      "x": 65,
+      "y": 20
+    },
+    {
+      "x": 67,
+      "y": 20
+    },
+    {
+      "x": 69,
+      "y": 20
+    },
+    {
+      "x": 71,
+      "y": 20
+    },
+    {
+      "x": 73,
+      "y": 20
+    },
+    {
+      "x": 75,
+      "y": 20
+    },
+    {
+      "x": 1,
+      "y": 21
+    },
+    {
+      "x": 3,
+      "y": 21
+    },
+    {
+      "x": 5,
+      "y": 21
+    },
+    {
+      "x": 7,
+      "y": 21
+    },
+    {
+      "x": 9,
+      "y": 21
+    },
+    {
+      "x": 11,
+      "y": 21
+    },
+    {
+      "x": 13,
+      "y": 21
+    },
+    {
+      "x": 15,
+      "y": 21
+    },
+    {
+      "x": 17,
+      "y": 21
+    },
+    {
+      "x": 19,
+      "y": 21
+    },
+    {
+      "x": 21,
+      "y": 21
+    },
+    {
+      "x": 23,
+      "y": 21
+    },
+    {
+      "x": 25,
+      "y": 21
+    },
+    {
+      "x": 27,
+      "y": 21
+    },
+    {
+      "x": 29,
+      "y": 21
+    },
+    {
+      "x": 31,
+      "y": 21
+    },
+    {
+      "x": 33,
+      "y": 21
+    },
+    {
+      "x": 35,
+      "y": 21
+    },
+    {
+      "x": 37,
+      "y": 21
+    },
+    {
+      "x": 39,
+      "y": 21
+    },
+    {
+      "x": 41,
+      "y": 21
+    },
+    {
+      "x": 43,
+      "y": 21
+    },
+    {
+      "x": 45,
+      "y": 21
+    },
+    {
+      "x": 47,
+      "y": 21
+    },
+    {
+      "x": 49,
+      "y": 21
+    },
+    {
+      "x": 51,
+      "y": 21
+    },
+    {
+      "x": 53,
+      "y": 21
+    },
+    {
+      "x": 55,
+      "y": 21
+    },
+    {
+      "x": 57,
+      "y": 21
+    },
+    {
+      "x": 59,
+      "y": 21
+    },
+    {
+      "x": 61,
+      "y": 21
+    },
+    {
+      "x": 63,
+      "y": 21
+    },
+    {
+      "x": 65,
+      "y": 21
+    },
+    {
+      "x": 67,
+      "y": 21
+    },
+    {
+      "x": 69,
+      "y": 21
+    },
+    {
+      "x": 71,
+      "y": 21
+    },
+    {
+      "x": 73,
+      "y": 21
+    },
+    {
+      "x": 75,
+      "y": 21
+    },
+    {
+      "x": 1,
+      "y": 22
+    },
+    {
+      "x": 2,
+      "y": 22
+    },
+    {
+      "x": 3,
+      "y": 22
+    },
+    {
+      "x": 4,
+      "y": 22
+    },
+    {
+      "x": 5,
+      "y": 22
+    },
+    {
+      "x": 6,
+      "y": 22
+    },
+    {
+      "x": 7,
+      "y": 22
+    },
+    {
+      "x": 8,
+      "y": 22
+    },
+    {
+      "x": 9,
+      "y": 22
+    },
+    {
+      "x": 10,
+      "y": 22
+    },
+    {
+      "x": 11,
+      "y": 22
+    },
+    {
+      "x": 12,
+      "y": 22
+    },
+    {
+      "x": 13,
+      "y": 22
+    },
+    {
+      "x": 14,
+      "y": 22
+    },
+    {
+      "x": 15,
+      "y": 22
+    },
+    {
+      "x": 16,
+      "y": 22
+    },
+    {
+      "x": 17,
+      "y": 22
+    },
+    {
+      "x": 18,
+      "y": 22
+    },
+    {
+      "x": 19,
+      "y": 22
+    },
+    {
+      "x": 20,
+      "y": 22
+    },
+    {
+      "x": 21,
+      "y": 22
+    },
+    {
+      "x": 22,
+      "y": 22
+    },
+    {
+      "x": 23,
+      "y": 22
+    },
+    {
+      "x": 24,
+      "y": 22
+    },
+    {
+      "x": 25,
+      "y": 22
+    },
+    {
+      "x": 26,
+      "y": 22
+    },
+    {
+      "x": 27,
+      "y": 22
+    },
+    {
+      "x": 28,
+      "y": 22
+    },
+    {
+      "x": 29,
+      "y": 22
+    },
+    {
+      "x": 30,
+      "y": 22
+    },
+    {
+      "x": 31,
+      "y": 22
+    },
+    {
+      "x": 32,
+      "y": 22
+    },
+    {
+      "x": 33,
+      "y": 22
+    },
+    {
+      "x": 34,
+      "y": 22
+    },
+    {
+      "x": 35,
+      "y": 22
+    },
+    {
+      "x": 36,
+      "y": 22
+    },
+    {
+      "x": 37,
+      "y": 22
+    },
+    {
+      "x": 38,
+      "y": 22
+    },
+    {
+      "x": 39,
+      "y": 22
+    },
+    {
+      "x": 40,
+      "y": 22
+    },
+    {
+      "x": 41,
+      "y": 22
+    },
+    {
+      "x": 42,
+      "y": 22
+    },
+    {
+      "x": 43,
+      "y": 22
+    },
+    {
+      "x": 44,
+      "y": 22
+    },
+    {
+      "x": 45,
+      "y": 22
+    },
+    {
+      "x": 46,
+      "y": 22
+    },
+    {
+      "x": 47,
+      "y": 22
+    },
+    {
+      "x": 48,
+      "y": 22
+    },
+    {
+      "x": 49,
+      "y": 22
+    },
+    {
+      "x": 50,
+      "y": 22
+    },
+    {
+      "x": 51,
+      "y": 22
+    },
+    {
+      "x": 52,
+      "y": 22
+    },
+    {
+      "x": 53,
+      "y": 22
+    },
+    {
+      "x": 54,
+      "y": 22
+    },
+    {
+      "x": 55,
+      "y": 22
+    },
+    {
+      "x": 56,
+      "y": 22
+    },
+    {
+      "x": 57,
+      "y": 22
+    },
+    {
+      "x": 58,
+      "y": 22
+    },
+    {
+      "x": 59,
+      "y": 22
+    },
+    {
+      "x": 60,
+      "y": 22
+    },
+    {
+      "x": 61,
+      "y": 22
+    },
+    {
+      "x": 62,
+      "y": 22
+    },
+    {
+      "x": 63,
+      "y": 22
+    },
+    {
+      "x": 64,
+      "y": 22
+    },
+    {
+      "x": 65,
+      "y": 22
+    },
+    {
+      "x": 66,
+      "y": 22
+    },
+    {
+      "x": 67,
+      "y": 22
+    },
+    {
+      "x": 68,
+      "y": 22
+    },
+    {
+      "x": 69,
+      "y": 22
+    },
+    {
+      "x": 70,
+      "y": 22
+    },
+    {
+      "x": 71,
+      "y": 22
+    },
+    {
+      "x": 72,
+      "y": 22
+    },
+    {
+      "x": 73,
+      "y": 22
+    },
+    {
+      "x": 74,
+      "y": 22
+    },
+    {
+      "x": 75,
+      "y": 22
+    },
+    {
+      "x": 1,
+      "y": 23
+    },
+    {
+      "x": 3,
+      "y": 23
+    },
+    {
+      "x": 5,
+      "y": 23
+    },
+    {
+      "x": 9,
+      "y": 23
+    },
+    {
+      "x": 11,
+      "y": 23
+    },
+    {
+      "x": 13,
+      "y": 23
+    },
+    {
+      "x": 17,
+      "y": 23
+    },
+    {
+      "x": 19,
+      "y": 23
+    },
+    {
+      "x": 21,
+      "y": 23
+    },
+    {
+      "x": 25,
+      "y": 23
+    },
+    {
+      "x": 27,
+      "y": 23
+    },
+    {
+      "x": 29,
+      "y": 23
+    },
+    {
+      "x": 33,
+      "y": 23
+    },
+    {
+      "x": 35,
+      "y": 23
+    },
+    {
+      "x": 37,
+      "y": 23
+    },
+    {
+      "x": 41,
+      "y": 23
+    },
+    {
+      "x": 43,
+      "y": 23
+    },
+    {
+      "x": 45,
+      "y": 23
+    },
+    {
+      "x": 49,
+      "y": 23
+    },
+    {
+      "x": 51,
+      "y": 23
+    },
+    {
+      "x": 53,
+      "y": 23
+    },
+    {
+      "x": 57,
+      "y": 23
+    },
+    {
+      "x": 59,
+      "y": 23
+    },
+    {
+      "x": 61,
+      "y": 23
+    },
+    {
+      "x": 65,
+      "y": 23
+    },
+    {
+      "x": 67,
+      "y": 23
+    },
+    {
+      "x": 69,
+      "y": 23
+    },
+    {
+      "x": 73,
+      "y": 23
+    },
+    {
+      "x": 75,
+      "y": 23
+    },
+    {
+      "x": 1,
+      "y": 24
+    },
+    {
+      "x": 3,
+      "y": 24
+    },
+    {
+      "x": 5,
+      "y": 24
+    },
+    {
+      "x": 9,
+      "y": 24
+    },
+    {
+      "x": 11,
+      "y": 24
+    },
+    {
+      "x": 13,
+      "y": 24
+    },
+    {
+      "x": 17,
+      "y": 24
+    },
+    {
+      "x": 19,
+      "y": 24
+    },
+    {
+      "x": 21,
+      "y": 24
+    },
+    {
+      "x": 25,
+      "y": 24
+    },
+    {
+      "x": 27,
+      "y": 24
+    },
+    {
+      "x": 29,
+      "y": 24
+    },
+    {
+      "x": 33,
+      "y": 24
+    },
+    {
+      "x": 35,
+      "y": 24
+    },
+    {
+      "x": 37,
+      "y": 24
+    },
+    {
+      "x": 41,
+      "y": 24
+    },
+    {
+      "x": 43,
+      "y": 24
+    },
+    {
+      "x": 45,
+      "y": 24
+    },
+    {
+      "x": 49,
+      "y": 24
+    },
+    {
+      "x": 51,
+      "y": 24
+    },
+    {
+      "x": 53,
+      "y": 24
+    },
+    {
+      "x": 57,
+      "y": 24
+    },
+    {
+      "x": 59,
+      "y": 24
+    },
+    {
+      "x": 61,
+      "y": 24
+    },
+    {
+      "x": 65,
+      "y": 24
+    },
+    {
+      "x": 67,
+      "y": 24
+    },
+    {
+      "x": 69,
+      "y": 24
+    },
+    {
+      "x": 73,
+      "y": 24
+    },
+    {
+      "x": 75,
+      "y": 24
+    },
+    {
+      "x": 1,
+      "y": 25
+    },
+    {
+      "x": 3,
+      "y": 25
+    },
+    {
+      "x": 5,
+      "y": 25
+    },
+    {
+      "x": 9,
+      "y": 25
+    },
+    {
+      "x": 11,
+      "y": 25
+    },
+    {
+      "x": 13,
+      "y": 25
+    },
+    {
+      "x": 17,
+      "y": 25
+    },
+    {
+      "x": 19,
+      "y": 25
+    },
+    {
+      "x": 21,
+      "y": 25
+    },
+    {
+      "x": 25,
+      "y": 25
+    },
+    {
+      "x": 27,
+      "y": 25
+    },
+    {
+      "x": 29,
+      "y": 25
+    },
+    {
+      "x": 33,
+      "y": 25
+    },
+    {
+      "x": 35,
+      "y": 25
+    },
+    {
+      "x": 37,
+      "y": 25
+    },
+    {
+      "x": 41,
+      "y": 25
+    },
+    {
+      "x": 43,
+      "y": 25
+    },
+    {
+      "x": 45,
+      "y": 25
+    },
+    {
+      "x": 49,
+      "y": 25
+    },
+    {
+      "x": 51,
+      "y": 25
+    },
+    {
+      "x": 53,
+      "y": 25
+    },
+    {
+      "x": 57,
+      "y": 25
+    },
+    {
+      "x": 59,
+      "y": 25
+    },
+    {
+      "x": 61,
+      "y": 25
+    },
+    {
+      "x": 65,
+      "y": 25
+    },
+    {
+      "x": 67,
+      "y": 25
+    },
+    {
+      "x": 69,
+      "y": 25
+    },
+    {
+      "x": 73,
+      "y": 25
+    },
+    {
+      "x": 75,
+      "y": 25
+    },
+    {
+      "x": 1,
+      "y": 26
+    },
+    {
+      "x": 3,
+      "y": 26
+    },
+    {
+      "x": 5,
+      "y": 26
+    },
+    {
+      "x": 9,
+      "y": 26
+    },
+    {
+      "x": 11,
+      "y": 26
+    },
+    {
+      "x": 13,
+      "y": 26
+    },
+    {
+      "x": 17,
+      "y": 26
+    },
+    {
+      "x": 19,
+      "y": 26
+    },
+    {
+      "x": 21,
+      "y": 26
+    },
+    {
+      "x": 25,
+      "y": 26
+    },
+    {
+      "x": 27,
+      "y": 26
+    },
+    {
+      "x": 29,
+      "y": 26
+    },
+    {
+      "x": 33,
+      "y": 26
+    },
+    {
+      "x": 35,
+      "y": 26
+    },
+    {
+      "x": 37,
+      "y": 26
+    },
+    {
+      "x": 41,
+      "y": 26
+    },
+    {
+      "x": 43,
+      "y": 26
+    },
+    {
+      "x": 45,
+      "y": 26
+    },
+    {
+      "x": 49,
+      "y": 26
+    },
+    {
+      "x": 51,
+      "y": 26
+    },
+    {
+      "x": 53,
+      "y": 26
+    },
+    {
+      "x": 57,
+      "y": 26
+    },
+    {
+      "x": 59,
+      "y": 26
+    },
+    {
+      "x": 61,
+      "y": 26
+    },
+    {
+      "x": 65,
+      "y": 26
+    },
+    {
+      "x": 67,
+      "y": 26
+    },
+    {
+      "x": 69,
+      "y": 26
+    },
+    {
+      "x": 73,
+      "y": 26
+    },
+    {
+      "x": 75,
+      "y": 26
+    },
+    {
+      "x": 1,
+      "y": 27
+    },
+    {
+      "x": 3,
+      "y": 27
+    },
+    {
+      "x": 5,
+      "y": 27
+    },
+    {
+      "x": 9,
+      "y": 27
+    },
+    {
+      "x": 11,
+      "y": 27
+    },
+    {
+      "x": 13,
+      "y": 27
+    },
+    {
+      "x": 17,
+      "y": 27
+    },
+    {
+      "x": 19,
+      "y": 27
+    },
+    {
+      "x": 21,
+      "y": 27
+    },
+    {
+      "x": 25,
+      "y": 27
+    },
+    {
+      "x": 27,
+      "y": 27
+    },
+    {
+      "x": 29,
+      "y": 27
+    },
+    {
+      "x": 33,
+      "y": 27
+    },
+    {
+      "x": 35,
+      "y": 27
+    },
+    {
+      "x": 37,
+      "y": 27
+    },
+    {
+      "x": 41,
+      "y": 27
+    },
+    {
+      "x": 43,
+      "y": 27
+    },
+    {
+      "x": 45,
+      "y": 27
+    },
+    {
+      "x": 49,
+      "y": 27
+    },
+    {
+      "x": 51,
+      "y": 27
+    },
+    {
+      "x": 53,
+      "y": 27
+    },
+    {
+      "x": 57,
+      "y": 27
+    },
+    {
+      "x": 59,
+      "y": 27
+    },
+    {
+      "x": 61,
+      "y": 27
+    },
+    {
+      "x": 65,
+      "y": 27
+    },
+    {
+      "x": 67,
+      "y": 27
+    },
+    {
+      "x": 69,
+      "y": 27
+    },
+    {
+      "x": 73,
+      "y": 27
+    },
+    {
+      "x": 75,
+      "y": 27
+    },
+    {
+      "x": 1,
+      "y": 28
+    },
+    {
+      "x": 3,
+      "y": 28
+    },
+    {
+      "x": 5,
+      "y": 28
+    },
+    {
+      "x": 7,
+      "y": 28
+    },
+    {
+      "x": 9,
+      "y": 28
+    },
+    {
+      "x": 11,
+      "y": 28
+    },
+    {
+      "x": 13,
+      "y": 28
+    },
+    {
+      "x": 15,
+      "y": 28
+    },
+    {
+      "x": 17,
+      "y": 28
+    },
+    {
+      "x": 19,
+      "y": 28
+    },
+    {
+      "x": 21,
+      "y": 28
+    },
+    {
+      "x": 23,
+      "y": 28
+    },
+    {
+      "x": 25,
+      "y": 28
+    },
+    {
+      "x": 27,
+      "y": 28
+    },
+    {
+      "x": 29,
+      "y": 28
+    },
+    {
+      "x": 31,
+      "y": 28
+    },
+    {
+      "x": 33,
+      "y": 28
+    },
+    {
+      "x": 35,
+      "y": 28
+    },
+    {
+      "x": 37,
+      "y": 28
+    },
+    {
+      "x": 39,
+      "y": 28
+    },
+    {
+      "x": 41,
+      "y": 28
+    },
+    {
+      "x": 43,
+      "y": 28
+    },
+    {
+      "x": 45,
+      "y": 28
+    },
+    {
+      "x": 47,
+      "y": 28
+    },
+    {
+      "x": 49,
+      "y": 28
+    },
+    {
+      "x": 51,
+      "y": 28
+    },
+    {
+      "x": 53,
+      "y": 28
+    },
+    {
+      "x": 55,
+      "y": 28
+    },
+    {
+      "x": 57,
+      "y": 28
+    },
+    {
+      "x": 59,
+      "y": 28
+    },
+    {
+      "x": 61,
+      "y": 28
+    },
+    {
+      "x": 63,
+      "y": 28
+    },
+    {
+      "x": 65,
+      "y": 28
+    },
+    {
+      "x": 67,
+      "y": 28
+    },
+    {
+      "x": 69,
+      "y": 28
+    },
+    {
+      "x": 71,
+      "y": 28
+    },
+    {
+      "x": 73,
+      "y": 28
+    },
+    {
+      "x": 75,
+      "y": 28
+    },
+    {
+      "x": 1,
+      "y": 29
+    },
+    {
+      "x": 3,
+      "y": 29
+    },
+    {
+      "x": 5,
+      "y": 29
+    },
+    {
+      "x": 7,
+      "y": 29
+    },
+    {
+      "x": 9,
+      "y": 29
+    },
+    {
+      "x": 11,
+      "y": 29
+    },
+    {
+      "x": 13,
+      "y": 29
+    },
+    {
+      "x": 15,
+      "y": 29
+    },
+    {
+      "x": 17,
+      "y": 29
+    },
+    {
+      "x": 19,
+      "y": 29
+    },
+    {
+      "x": 21,
+      "y": 29
+    },
+    {
+      "x": 23,
+      "y": 29
+    },
+    {
+      "x": 25,
+      "y": 29
+    },
+    {
+      "x": 27,
+      "y": 29
+    },
+    {
+      "x": 29,
+      "y": 29
+    },
+    {
+      "x": 31,
+      "y": 29
+    },
+    {
+      "x": 33,
+      "y": 29
+    },
+    {
+      "x": 35,
+      "y": 29
+    },
+    {
+      "x": 37,
+      "y": 29
+    },
+    {
+      "x": 39,
+      "y": 29
+    },
+    {
+      "x": 41,
+      "y": 29
+    },
+    {
+      "x": 43,
+      "y": 29
+    },
+    {
+      "x": 45,
+      "y": 29
+    },
+    {
+      "x": 47,
+      "y": 29
+    },
+    {
+      "x": 49,
+      "y": 29
+    },
+    {
+      "x": 51,
+      "y": 29
+    },
+    {
+      "x": 53,
+      "y": 29
+    },
+    {
+      "x": 55,
+      "y": 29
+    },
+    {
+      "x": 57,
+      "y": 29
+    },
+    {
+      "x": 59,
+      "y": 29
+    },
+    {
+      "x": 61,
+      "y": 29
+    },
+    {
+      "x": 63,
+      "y": 29
+    },
+    {
+      "x": 65,
+      "y": 29
+    },
+    {
+      "x": 67,
+      "y": 29
+    },
+    {
+      "x": 69,
+      "y": 29
+    },
+    {
+      "x": 71,
+      "y": 29
+    },
+    {
+      "x": 73,
+      "y": 29
+    },
+    {
+      "x": 75,
+      "y": 29
+    },
+    {
+      "x": 1,
+      "y": 30
+    },
+    {
+      "x": 3,
+      "y": 30
+    },
+    {
+      "x": 5,
+      "y": 30
+    },
+    {
+      "x": 7,
+      "y": 30
+    },
+    {
+      "x": 9,
+      "y": 30
+    },
+    {
+      "x": 11,
+      "y": 30
+    },
+    {
+      "x": 13,
+      "y": 30
+    },
+    {
+      "x": 15,
+      "y": 30
+    },
+    {
+      "x": 17,
+      "y": 30
+    },
+    {
+      "x": 19,
+      "y": 30
+    },
+    {
+      "x": 21,
+      "y": 30
+    },
+    {
+      "x": 23,
+      "y": 30
+    },
+    {
+      "x": 25,
+      "y": 30
+    },
+    {
+      "x": 27,
+      "y": 30
+    },
+    {
+      "x": 29,
+      "y": 30
+    },
+    {
+      "x": 31,
+      "y": 30
+    },
+    {
+      "x": 33,
+      "y": 30
+    },
+    {
+      "x": 35,
+      "y": 30
+    },
+    {
+      "x": 37,
+      "y": 30
+    },
+    {
+      "x": 39,
+      "y": 30
+    },
+    {
+      "x": 41,
+      "y": 30
+    },
+    {
+      "x": 43,
+      "y": 30
+    },
+    {
+      "x": 45,
+      "y": 30
+    },
+    {
+      "x": 47,
+      "y": 30
+    },
+    {
+      "x": 49,
+      "y": 30
+    },
+    {
+      "x": 51,
+      "y": 30
+    },
+    {
+      "x": 53,
+      "y": 30
+    },
+    {
+      "x": 55,
+      "y": 30
+    },
+    {
+      "x": 57,
+      "y": 30
+    },
+    {
+      "x": 59,
+      "y": 30
+    },
+    {
+      "x": 61,
+      "y": 30
+    },
+    {
+      "x": 63,
+      "y": 30
+    },
+    {
+      "x": 65,
+      "y": 30
+    },
+    {
+      "x": 67,
+      "y": 30
+    },
+    {
+      "x": 69,
+      "y": 30
+    },
+    {
+      "x": 71,
+      "y": 30
+    },
+    {
+      "x": 73,
+      "y": 30
+    },
+    {
+      "x": 75,
+      "y": 30
+    },
+    {
+      "x": 1,
+      "y": 31
+    },
+    {
+      "x": 3,
+      "y": 31
+    },
+    {
+      "x": 5,
+      "y": 31
+    },
+    {
+      "x": 7,
+      "y": 31
+    },
+    {
+      "x": 9,
+      "y": 31
+    },
+    {
+      "x": 11,
+      "y": 31
+    },
+    {
+      "x": 13,
+      "y": 31
+    },
+    {
+      "x": 15,
+      "y": 31
+    },
+    {
+      "x": 17,
+      "y": 31
+    },
+    {
+      "x": 19,
+      "y": 31
+    },
+    {
+      "x": 21,
+      "y": 31
+    },
+    {
+      "x": 23,
+      "y": 31
+    },
+    {
+      "x": 25,
+      "y": 31
+    },
+    {
+      "x": 27,
+      "y": 31
+    },
+    {
+      "x": 29,
+      "y": 31
+    },
+    {
+      "x": 31,
+      "y": 31
+    },
+    {
+      "x": 33,
+      "y": 31
+    },
+    {
+      "x": 35,
+      "y": 31
+    },
+    {
+      "x": 37,
+      "y": 31
+    },
+    {
+      "x": 39,
+      "y": 31
+    },
+    {
+      "x": 41,
+      "y": 31
+    },
+    {
+      "x": 43,
+      "y": 31
+    },
+    {
+      "x": 45,
+      "y": 31
+    },
+    {
+      "x": 47,
+      "y": 31
+    },
+    {
+      "x": 49,
+      "y": 31
+    },
+    {
+      "x": 51,
+      "y": 31
+    },
+    {
+      "x": 53,
+      "y": 31
+    },
+    {
+      "x": 55,
+      "y": 31
+    },
+    {
+      "x": 57,
+      "y": 31
+    },
+    {
+      "x": 59,
+      "y": 31
+    },
+    {
+      "x": 61,
+      "y": 31
+    },
+    {
+      "x": 63,
+      "y": 31
+    },
+    {
+      "x": 65,
+      "y": 31
+    },
+    {
+      "x": 67,
+      "y": 31
+    },
+    {
+      "x": 69,
+      "y": 31
+    },
+    {
+      "x": 71,
+      "y": 31
+    },
+    {
+      "x": 73,
+      "y": 31
+    },
+    {
+      "x": 75,
+      "y": 31
+    },
+    {
+      "x": 1,
+      "y": 32
+    },
+    {
+      "x": 2,
+      "y": 32
+    },
+    {
+      "x": 3,
+      "y": 32
+    },
+    {
+      "x": 4,
+      "y": 32
+    },
+    {
+      "x": 5,
+      "y": 32
+    },
+    {
+      "x": 6,
+      "y": 32
+    },
+    {
+      "x": 7,
+      "y": 32
+    },
+    {
+      "x": 8,
+      "y": 32
+    },
+    {
+      "x": 9,
+      "y": 32
+    },
+    {
+      "x": 10,
+      "y": 32
+    },
+    {
+      "x": 11,
+      "y": 32
+    },
+    {
+      "x": 12,
+      "y": 32
+    },
+    {
+      "x": 13,
+      "y": 32
+    },
+    {
+      "x": 14,
+      "y": 32
+    },
+    {
+      "x": 15,
+      "y": 32
+    },
+    {
+      "x": 16,
+      "y": 32
+    },
+    {
+      "x": 17,
+      "y": 32
+    },
+    {
+      "x": 18,
+      "y": 32
+    },
+    {
+      "x": 19,
+      "y": 32
+    },
+    {
+      "x": 20,
+      "y": 32
+    },
+    {
+      "x": 21,
+      "y": 32
+    },
+    {
+      "x": 22,
+      "y": 32
+    },
+    {
+      "x": 23,
+      "y": 32
+    },
+    {
+      "x": 24,
+      "y": 32
+    },
+    {
+      "x": 25,
+      "y": 32
+    },
+    {
+      "x": 26,
+      "y": 32
+    },
+    {
+      "x": 27,
+      "y": 32
+    },
+    {
+      "x": 28,
+      "y": 32
+    },
+    {
+      "x": 29,
+      "y": 32
+    },
+    {
+      "x": 30,
+      "y": 32
+    },
+    {
+      "x": 31,
+      "y": 32
+    },
+    {
+      "x": 32,
+      "y": 32
+    },
+    {
+      "x": 33,
+      "y": 32
+    },
+    {
+      "x": 34,
+      "y": 32
+    },
+    {
+      "x": 35,
+      "y": 32
+    },
+    {
+      "x": 36,
+      "y": 32
+    },
+    {
+      "x": 37,
+      "y": 32
+    },
+    {
+      "x": 38,
+      "y": 32
+    },
+    {
+      "x": 39,
+      "y": 32
+    },
+    {
+      "x": 40,
+      "y": 32
+    },
+    {
+      "x": 41,
+      "y": 32
+    },
+    {
+      "x": 42,
+      "y": 32
+    },
+    {
+      "x": 43,
+      "y": 32
+    },
+    {
+      "x": 44,
+      "y": 32
+    },
+    {
+      "x": 45,
+      "y": 32
+    },
+    {
+      "x": 46,
+      "y": 32
+    },
+    {
+      "x": 47,
+      "y": 32
+    },
+    {
+      "x": 48,
+      "y": 32
+    },
+    {
+      "x": 49,
+      "y": 32
+    },
+    {
+      "x": 50,
+      "y": 32
+    },
+    {
+      "x": 51,
+      "y": 32
+    },
+    {
+      "x": 52,
+      "y": 32
+    },
+    {
+      "x": 53,
+      "y": 32
+    },
+    {
+      "x": 54,
+      "y": 32
+    },
+    {
+      "x": 55,
+      "y": 32
+    },
+    {
+      "x": 56,
+      "y": 32
+    },
+    {
+      "x": 57,
+      "y": 32
+    },
+    {
+      "x": 58,
+      "y": 32
+    },
+    {
+      "x": 59,
+      "y": 32
+    },
+    {
+      "x": 60,
+      "y": 32
+    },
+    {
+      "x": 61,
+      "y": 32
+    },
+    {
+      "x": 62,
+      "y": 32
+    },
+    {
+      "x": 63,
+      "y": 32
+    },
+    {
+      "x": 64,
+      "y": 32
+    },
+    {
+      "x": 65,
+      "y": 32
+    },
+    {
+      "x": 66,
+      "y": 32
+    },
+    {
+      "x": 67,
+      "y": 32
+    },
+    {
+      "x": 68,
+      "y": 32
+    },
+    {
+      "x": 69,
+      "y": 32
+    },
+    {
+      "x": 70,
+      "y": 32
+    },
+    {
+      "x": 71,
+      "y": 32
+    },
+    {
+      "x": 72,
+      "y": 32
+    },
+    {
+      "x": 73,
+      "y": 32
+    },
+    {
+      "x": 74,
+      "y": 32
+    },
+    {
+      "x": 75,
+      "y": 32
+    },
+    {
+      "x": 76,
+      "y": 32
+    },
+    {
+      "x": 77,
+      "y": 32
+    },
+    {
+      "x": 1,
+      "y": 33
+    },
+    {
+      "x": 3,
+      "y": 33
+    },
+    {
+      "x": 5,
+      "y": 33
+    },
+    {
+      "x": 7,
+      "y": 33
+    },
+    {
+      "x": 9,
+      "y": 33
+    },
+    {
+      "x": 11,
+      "y": 33
+    },
+    {
+      "x": 13,
+      "y": 33
+    },
+    {
+      "x": 15,
+      "y": 33
+    },
+    {
+      "x": 17,
+      "y": 33
+    },
+    {
+      "x": 19,
+      "y": 33
+    },
+    {
+      "x": 21,
+      "y": 33
+    },
+    {
+      "x": 23,
+      "y": 33
+    },
+    {
+      "x": 25,
+      "y": 33
+    },
+    {
+      "x": 27,
+      "y": 33
+    },
+    {
+      "x": 29,
+      "y": 33
+    },
+    {
+      "x": 31,
+      "y": 33
+    },
+    {
+      "x": 33,
+      "y": 33
+    },
+    {
+      "x": 35,
+      "y": 33
+    },
+    {
+      "x": 37,
+      "y": 33
+    },
+    {
+      "x": 39,
+      "y": 33
+    },
+    {
+      "x": 41,
+      "y": 33
+    },
+    {
+      "x": 43,
+      "y": 33
+    },
+    {
+      "x": 45,
+      "y": 33
+    },
+    {
+      "x": 47,
+      "y": 33
+    },
+    {
+      "x": 49,
+      "y": 33
+    },
+    {
+      "x": 51,
+      "y": 33
+    },
+    {
+      "x": 53,
+      "y": 33
+    },
+    {
+      "x": 55,
+      "y": 33
+    },
+    {
+      "x": 57,
+      "y": 33
+    },
+    {
+      "x": 59,
+      "y": 33
+    },
+    {
+      "x": 61,
+      "y": 33
+    },
+    {
+      "x": 63,
+      "y": 33
+    },
+    {
+      "x": 65,
+      "y": 33
+    },
+    {
+      "x": 67,
+      "y": 33
+    },
+    {
+      "x": 69,
+      "y": 33
+    },
+    {
+      "x": 71,
+      "y": 33
+    },
+    {
+      "x": 73,
+      "y": 33
+    },
+    {
+      "x": 75,
+      "y": 33
+    },
+    {
+      "x": 77,
+      "y": 33
+    },
+    {
+      "x": 1,
+      "y": 34
+    },
+    {
+      "x": 3,
+      "y": 34
+    },
+    {
+      "x": 5,
+      "y": 34
+    },
+    {
+      "x": 7,
+      "y": 34
+    },
+    {
+      "x": 9,
+      "y": 34
+    },
+    {
+      "x": 11,
+      "y": 34
+    },
+    {
+      "x": 13,
+      "y": 34
+    },
+    {
+      "x": 15,
+      "y": 34
+    },
+    {
+      "x": 17,
+      "y": 34
+    },
+    {
+      "x": 19,
+      "y": 34
+    },
+    {
+      "x": 21,
+      "y": 34
+    },
+    {
+      "x": 23,
+      "y": 34
+    },
+    {
+      "x": 25,
+      "y": 34
+    },
+    {
+      "x": 27,
+      "y": 34
+    },
+    {
+      "x": 29,
+      "y": 34
+    },
+    {
+      "x": 31,
+      "y": 34
+    },
+    {
+      "x": 33,
+      "y": 34
+    },
+    {
+      "x": 35,
+      "y": 34
+    },
+    {
+      "x": 37,
+      "y": 34
+    },
+    {
+      "x": 39,
+      "y": 34
+    },
+    {
+      "x": 41,
+      "y": 34
+    },
+    {
+      "x": 43,
+      "y": 34
+    },
+    {
+      "x": 45,
+      "y": 34
+    },
+    {
+      "x": 47,
+      "y": 34
+    },
+    {
+      "x": 49,
+      "y": 34
+    },
+    {
+      "x": 51,
+      "y": 34
+    },
+    {
+      "x": 53,
+      "y": 34
+    },
+    {
+      "x": 55,
+      "y": 34
+    },
+    {
+      "x": 57,
+      "y": 34
+    },
+    {
+      "x": 59,
+      "y": 34
+    },
+    {
+      "x": 61,
+      "y": 34
+    },
+    {
+      "x": 63,
+      "y": 34
+    },
+    {
+      "x": 65,
+      "y": 34
+    },
+    {
+      "x": 67,
+      "y": 34
+    },
+    {
+      "x": 69,
+      "y": 34
+    },
+    {
+      "x": 71,
+      "y": 34
+    },
+    {
+      "x": 73,
+      "y": 34
+    },
+    {
+      "x": 75,
+      "y": 34
+    },
+    {
+      "x": 77,
+      "y": 34
+    },
+    {
+      "x": 1,
+      "y": 35
+    },
+    {
+      "x": 3,
+      "y": 35
+    },
+    {
+      "x": 5,
+      "y": 35
+    },
+    {
+      "x": 7,
+      "y": 35
+    },
+    {
+      "x": 9,
+      "y": 35
+    },
+    {
+      "x": 11,
+      "y": 35
+    },
+    {
+      "x": 13,
+      "y": 35
+    },
+    {
+      "x": 15,
+      "y": 35
+    },
+    {
+      "x": 17,
+      "y": 35
+    },
+    {
+      "x": 19,
+      "y": 35
+    },
+    {
+      "x": 21,
+      "y": 35
+    },
+    {
+      "x": 23,
+      "y": 35
+    },
+    {
+      "x": 25,
+      "y": 35
+    },
+    {
+      "x": 27,
+      "y": 35
+    },
+    {
+      "x": 29,
+      "y": 35
+    },
+    {
+      "x": 31,
+      "y": 35
+    },
+    {
+      "x": 33,
+      "y": 35
+    },
+    {
+      "x": 35,
+      "y": 35
+    },
+    {
+      "x": 37,
+      "y": 35
+    },
+    {
+      "x": 39,
+      "y": 35
+    },
+    {
+      "x": 41,
+      "y": 35
+    },
+    {
+      "x": 43,
+      "y": 35
+    },
+    {
+      "x": 45,
+      "y": 35
+    },
+    {
+      "x": 47,
+      "y": 35
+    },
+    {
+      "x": 49,
+      "y": 35
+    },
+    {
+      "x": 51,
+      "y": 35
+    },
+    {
+      "x": 53,
+      "y": 35
+    },
+    {
+      "x": 55,
+      "y": 35
+    },
+    {
+      "x": 57,
+      "y": 35
+    },
+    {
+      "x": 59,
+      "y": 35
+    },
+    {
+      "x": 61,
+      "y": 35
+    },
+    {
+      "x": 63,
+      "y": 35
+    },
+    {
+      "x": 65,
+      "y": 35
+    },
+    {
+      "x": 67,
+      "y": 35
+    },
+    {
+      "x": 69,
+      "y": 35
+    },
+    {
+      "x": 71,
+      "y": 35
+    },
+    {
+      "x": 73,
+      "y": 35
+    },
+    {
+      "x": 75,
+      "y": 35
+    },
+    {
+      "x": 77,
+      "y": 35
+    },
+    {
+      "x": 1,
+      "y": 36
+    },
+    {
+      "x": 3,
+      "y": 36
+    },
+    {
+      "x": 5,
+      "y": 36
+    },
+    {
+      "x": 7,
+      "y": 36
+    },
+    {
+      "x": 9,
+      "y": 36
+    },
+    {
+      "x": 11,
+      "y": 36
+    },
+    {
+      "x": 13,
+      "y": 36
+    },
+    {
+      "x": 15,
+      "y": 36
+    },
+    {
+      "x": 17,
+      "y": 36
+    },
+    {
+      "x": 19,
+      "y": 36
+    },
+    {
+      "x": 21,
+      "y": 36
+    },
+    {
+      "x": 23,
+      "y": 36
+    },
+    {
+      "x": 25,
+      "y": 36
+    },
+    {
+      "x": 27,
+      "y": 36
+    },
+    {
+      "x": 29,
+      "y": 36
+    },
+    {
+      "x": 31,
+      "y": 36
+    },
+    {
+      "x": 33,
+      "y": 36
+    },
+    {
+      "x": 35,
+      "y": 36
+    },
+    {
+      "x": 37,
+      "y": 36
+    },
+    {
+      "x": 39,
+      "y": 36
+    },
+    {
+      "x": 41,
+      "y": 36
+    },
+    {
+      "x": 43,
+      "y": 36
+    },
+    {
+      "x": 45,
+      "y": 36
+    },
+    {
+      "x": 47,
+      "y": 36
+    },
+    {
+      "x": 49,
+      "y": 36
+    },
+    {
+      "x": 51,
+      "y": 36
+    },
+    {
+      "x": 53,
+      "y": 36
+    },
+    {
+      "x": 55,
+      "y": 36
+    },
+    {
+      "x": 57,
+      "y": 36
+    },
+    {
+      "x": 59,
+      "y": 36
+    },
+    {
+      "x": 61,
+      "y": 36
+    },
+    {
+      "x": 63,
+      "y": 36
+    },
+    {
+      "x": 65,
+      "y": 36
+    },
+    {
+      "x": 67,
+      "y": 36
+    },
+    {
+      "x": 69,
+      "y": 36
+    },
+    {
+      "x": 71,
+      "y": 36
+    },
+    {
+      "x": 73,
+      "y": 36
+    },
+    {
+      "x": 75,
+      "y": 36
+    },
+    {
+      "x": 77,
+      "y": 36
+    },
+    {
+      "x": 1,
+      "y": 37
+    },
+    {
+      "x": 3,
+      "y": 37
+    },
+    {
+      "x": 5,
+      "y": 37
+    },
+    {
+      "x": 7,
+      "y": 37
+    },
+    {
+      "x": 9,
+      "y": 37
+    },
+    {
+      "x": 11,
+      "y": 37
+    },
+    {
+      "x": 13,
+      "y": 37
+    },
+    {
+      "x": 15,
+      "y": 37
+    },
+    {
+      "x": 17,
+      "y": 37
+    },
+    {
+      "x": 19,
+      "y": 37
+    },
+    {
+      "x": 21,
+      "y": 37
+    },
+    {
+      "x": 23,
+      "y": 37
+    },
+    {
+      "x": 25,
+      "y": 37
+    },
+    {
+      "x": 27,
+      "y": 37
+    },
+    {
+      "x": 29,
+      "y": 37
+    },
+    {
+      "x": 31,
+      "y": 37
+    },
+    {
+      "x": 33,
+      "y": 37
+    },
+    {
+      "x": 35,
+      "y": 37
+    },
+    {
+      "x": 37,
+      "y": 37
+    },
+    {
+      "x": 39,
+      "y": 37
+    },
+    {
+      "x": 41,
+      "y": 37
+    },
+    {
+      "x": 43,
+      "y": 37
+    },
+    {
+      "x": 45,
+      "y": 37
+    },
+    {
+      "x": 47,
+      "y": 37
+    },
+    {
+      "x": 49,
+      "y": 37
+    },
+    {
+      "x": 51,
+      "y": 37
+    },
+    {
+      "x": 53,
+      "y": 37
+    },
+    {
+      "x": 55,
+      "y": 37
+    },
+    {
+      "x": 57,
+      "y": 37
+    },
+    {
+      "x": 59,
+      "y": 37
+    },
+    {
+      "x": 61,
+      "y": 37
+    },
+    {
+      "x": 63,
+      "y": 37
+    },
+    {
+      "x": 65,
+      "y": 37
+    },
+    {
+      "x": 67,
+      "y": 37
+    },
+    {
+      "x": 69,
+      "y": 37
+    },
+    {
+      "x": 71,
+      "y": 37
+    },
+    {
+      "x": 73,
+      "y": 37
+    },
+    {
+      "x": 75,
+      "y": 37
+    },
+    {
+      "x": 77,
+      "y": 37
+    },
+    {
+      "x": 1,
+      "y": 38
+    },
+    {
+      "x": 3,
+      "y": 38
+    },
+    {
+      "x": 5,
+      "y": 38
+    },
+    {
+      "x": 7,
+      "y": 38
+    },
+    {
+      "x": 9,
+      "y": 38
+    },
+    {
+      "x": 11,
+      "y": 38
+    },
+    {
+      "x": 13,
+      "y": 38
+    },
+    {
+      "x": 15,
+      "y": 38
+    },
+    {
+      "x": 17,
+      "y": 38
+    },
+    {
+      "x": 19,
+      "y": 38
+    },
+    {
+      "x": 21,
+      "y": 38
+    },
+    {
+      "x": 23,
+      "y": 38
+    },
+    {
+      "x": 25,
+      "y": 38
+    },
+    {
+      "x": 27,
+      "y": 38
+    },
+    {
+      "x": 29,
+      "y": 38
+    },
+    {
+      "x": 31,
+      "y": 38
+    },
+    {
+      "x": 33,
+      "y": 38
+    },
+    {
+      "x": 35,
+      "y": 38
+    },
+    {
+      "x": 37,
+      "y": 38
+    },
+    {
+      "x": 39,
+      "y": 38
+    },
+    {
+      "x": 41,
+      "y": 38
+    },
+    {
+      "x": 43,
+      "y": 38
+    },
+    {
+      "x": 45,
+      "y": 38
+    },
+    {
+      "x": 47,
+      "y": 38
+    },
+    {
+      "x": 49,
+      "y": 38
+    },
+    {
+      "x": 51,
+      "y": 38
+    },
+    {
+      "x": 53,
+      "y": 38
+    },
+    {
+      "x": 55,
+      "y": 38
+    },
+    {
+      "x": 57,
+      "y": 38
+    },
+    {
+      "x": 59,
+      "y": 38
+    },
+    {
+      "x": 61,
+      "y": 38
+    },
+    {
+      "x": 63,
+      "y": 38
+    },
+    {
+      "x": 65,
+      "y": 38
+    },
+    {
+      "x": 67,
+      "y": 38
+    },
+    {
+      "x": 69,
+      "y": 38
+    },
+    {
+      "x": 71,
+      "y": 38
+    },
+    {
+      "x": 73,
+      "y": 38
+    },
+    {
+      "x": 75,
+      "y": 38
+    },
+    {
+      "x": 77,
+      "y": 38
+    },
+    {
+      "x": 1,
+      "y": 39
+    },
+    {
+      "x": 3,
+      "y": 39
+    },
+    {
+      "x": 5,
+      "y": 39
+    },
+    {
+      "x": 7,
+      "y": 39
+    },
+    {
+      "x": 9,
+      "y": 39
+    },
+    {
+      "x": 11,
+      "y": 39
+    },
+    {
+      "x": 13,
+      "y": 39
+    },
+    {
+      "x": 15,
+      "y": 39
+    },
+    {
+      "x": 17,
+      "y": 39
+    },
+    {
+      "x": 19,
+      "y": 39
+    },
+    {
+      "x": 21,
+      "y": 39
+    },
+    {
+      "x": 23,
+      "y": 39
+    },
+    {
+      "x": 25,
+      "y": 39
+    },
+    {
+      "x": 27,
+      "y": 39
+    },
+    {
+      "x": 29,
+      "y": 39
+    },
+    {
+      "x": 31,
+      "y": 39
+    },
+    {
+      "x": 33,
+      "y": 39
+    },
+    {
+      "x": 35,
+      "y": 39
+    },
+    {
+      "x": 37,
+      "y": 39
+    },
+    {
+      "x": 39,
+      "y": 39
+    },
+    {
+      "x": 41,
+      "y": 39
+    },
+    {
+      "x": 43,
+      "y": 39
+    },
+    {
+      "x": 45,
+      "y": 39
+    },
+    {
+      "x": 47,
+      "y": 39
+    },
+    {
+      "x": 49,
+      "y": 39
+    },
+    {
+      "x": 51,
+      "y": 39
+    },
+    {
+      "x": 53,
+      "y": 39
+    },
+    {
+      "x": 55,
+      "y": 39
+    },
+    {
+      "x": 57,
+      "y": 39
+    },
+    {
+      "x": 59,
+      "y": 39
+    },
+    {
+      "x": 61,
+      "y": 39
+    },
+    {
+      "x": 63,
+      "y": 39
+    },
+    {
+      "x": 65,
+      "y": 39
+    },
+    {
+      "x": 67,
+      "y": 39
+    },
+    {
+      "x": 69,
+      "y": 39
+    },
+    {
+      "x": 71,
+      "y": 39
+    },
+    {
+      "x": 73,
+      "y": 39
+    },
+    {
+      "x": 75,
+      "y": 39
+    },
+    {
+      "x": 77,
+      "y": 39
+    },
+    {
+      "x": 1,
+      "y": 40
+    },
+    {
+      "x": 3,
+      "y": 40
+    },
+    {
+      "x": 5,
+      "y": 40
+    },
+    {
+      "x": 7,
+      "y": 40
+    },
+    {
+      "x": 9,
+      "y": 40
+    },
+    {
+      "x": 11,
+      "y": 40
+    },
+    {
+      "x": 13,
+      "y": 40
+    },
+    {
+      "x": 15,
+      "y": 40
+    },
+    {
+      "x": 17,
+      "y": 40
+    },
+    {
+      "x": 19,
+      "y": 40
+    },
+    {
+      "x": 21,
+      "y": 40
+    },
+    {
+      "x": 23,
+      "y": 40
+    },
+    {
+      "x": 25,
+      "y": 40
+    },
+    {
+      "x": 27,
+      "y": 40
+    },
+    {
+      "x": 29,
+      "y": 40
+    },
+    {
+      "x": 31,
+      "y": 40
+    },
+    {
+      "x": 33,
+      "y": 40
+    },
+    {
+      "x": 35,
+      "y": 40
+    },
+    {
+      "x": 37,
+      "y": 40
+    },
+    {
+      "x": 39,
+      "y": 40
+    },
+    {
+      "x": 41,
+      "y": 40
+    },
+    {
+      "x": 43,
+      "y": 40
+    },
+    {
+      "x": 45,
+      "y": 40
+    },
+    {
+      "x": 47,
+      "y": 40
+    },
+    {
+      "x": 49,
+      "y": 40
+    },
+    {
+      "x": 51,
+      "y": 40
+    },
+    {
+      "x": 53,
+      "y": 40
+    },
+    {
+      "x": 55,
+      "y": 40
+    },
+    {
+      "x": 57,
+      "y": 40
+    },
+    {
+      "x": 59,
+      "y": 40
+    },
+    {
+      "x": 61,
+      "y": 40
+    },
+    {
+      "x": 63,
+      "y": 40
+    },
+    {
+      "x": 65,
+      "y": 40
+    },
+    {
+      "x": 67,
+      "y": 40
+    },
+    {
+      "x": 69,
+      "y": 40
+    },
+    {
+      "x": 71,
+      "y": 40
+    },
+    {
+      "x": 73,
+      "y": 40
+    },
+    {
+      "x": 75,
+      "y": 40
+    },
+    {
+      "x": 77,
+      "y": 40
+    },
+    {
+      "x": 1,
+      "y": 41
+    },
+    {
+      "x": 3,
+      "y": 41
+    },
+    {
+      "x": 5,
+      "y": 41
+    },
+    {
+      "x": 7,
+      "y": 41
+    },
+    {
+      "x": 9,
+      "y": 41
+    },
+    {
+      "x": 11,
+      "y": 41
+    },
+    {
+      "x": 13,
+      "y": 41
+    },
+    {
+      "x": 15,
+      "y": 41
+    },
+    {
+      "x": 17,
+      "y": 41
+    },
+    {
+      "x": 19,
+      "y": 41
+    },
+    {
+      "x": 21,
+      "y": 41
+    },
+    {
+      "x": 23,
+      "y": 41
+    },
+    {
+      "x": 25,
+      "y": 41
+    },
+    {
+      "x": 27,
+      "y": 41
+    },
+    {
+      "x": 29,
+      "y": 41
+    },
+    {
+      "x": 31,
+      "y": 41
+    },
+    {
+      "x": 33,
+      "y": 41
+    },
+    {
+      "x": 35,
+      "y": 41
+    },
+    {
+      "x": 37,
+      "y": 41
+    },
+    {
+      "x": 39,
+      "y": 41
+    },
+    {
+      "x": 41,
+      "y": 41
+    },
+    {
+      "x": 43,
+      "y": 41
+    },
+    {
+      "x": 45,
+      "y": 41
+    },
+    {
+      "x": 47,
+      "y": 41
+    },
+    {
+      "x": 49,
+      "y": 41
+    },
+    {
+      "x": 51,
+      "y": 41
+    },
+    {
+      "x": 53,
+      "y": 41
+    },
+    {
+      "x": 55,
+      "y": 41
+    },
+    {
+      "x": 57,
+      "y": 41
+    },
+    {
+      "x": 59,
+      "y": 41
+    },
+    {
+      "x": 61,
+      "y": 41
+    },
+    {
+      "x": 63,
+      "y": 41
+    },
+    {
+      "x": 65,
+      "y": 41
+    },
+    {
+      "x": 67,
+      "y": 41
+    },
+    {
+      "x": 69,
+      "y": 41
+    },
+    {
+      "x": 71,
+      "y": 41
+    },
+    {
+      "x": 73,
+      "y": 41
+    },
+    {
+      "x": 75,
+      "y": 41
+    },
+    {
+      "x": 77,
+      "y": 41
+    },
+    {
+      "x": 1,
+      "y": 42
+    },
+    {
+      "x": 2,
+      "y": 42
+    },
+    {
+      "x": 3,
+      "y": 42
+    },
+    {
+      "x": 4,
+      "y": 42
+    },
+    {
+      "x": 5,
+      "y": 42
+    },
+    {
+      "x": 6,
+      "y": 42
+    },
+    {
+      "x": 7,
+      "y": 42
+    },
+    {
+      "x": 8,
+      "y": 42
+    },
+    {
+      "x": 9,
+      "y": 42
+    },
+    {
+      "x": 10,
+      "y": 42
+    },
+    {
+      "x": 11,
+      "y": 42
+    },
+    {
+      "x": 12,
+      "y": 42
+    },
+    {
+      "x": 13,
+      "y": 42
+    },
+    {
+      "x": 14,
+      "y": 42
+    },
+    {
+      "x": 15,
+      "y": 42
+    },
+    {
+      "x": 16,
+      "y": 42
+    },
+    {
+      "x": 17,
+      "y": 42
+    },
+    {
+      "x": 18,
+      "y": 42
+    },
+    {
+      "x": 19,
+      "y": 42
+    },
+    {
+      "x": 20,
+      "y": 42
+    },
+    {
+      "x": 21,
+      "y": 42
+    },
+    {
+      "x": 22,
+      "y": 42
+    },
+    {
+      "x": 23,
+      "y": 42
+    },
+    {
+      "x": 24,
+      "y": 42
+    },
+    {
+      "x": 25,
+      "y": 42
+    },
+    {
+      "x": 26,
+      "y": 42
+    },
+    {
+      "x": 27,
+      "y": 42
+    },
+    {
+      "x": 28,
+      "y": 42
+    },
+    {
+      "x": 29,
+      "y": 42
+    },
+    {
+      "x": 30,
+      "y": 42
+    },
+    {
+      "x": 31,
+      "y": 42
+    },
+    {
+      "x": 32,
+      "y": 42
+    },
+    {
+      "x": 33,
+      "y": 42
+    },
+    {
+      "x": 34,
+      "y": 42
+    },
+    {
+      "x": 35,
+      "y": 42
+    },
+    {
+      "x": 36,
+      "y": 42
+    },
+    {
+      "x": 37,
+      "y": 42
+    },
+    {
+      "x": 38,
+      "y": 42
+    },
+    {
+      "x": 39,
+      "y": 42
+    },
+    {
+      "x": 40,
+      "y": 42
+    },
+    {
+      "x": 41,
+      "y": 42
+    },
+    {
+      "x": 42,
+      "y": 42
+    },
+    {
+      "x": 43,
+      "y": 42
+    },
+    {
+      "x": 44,
+      "y": 42
+    },
+    {
+      "x": 45,
+      "y": 42
+    },
+    {
+      "x": 46,
+      "y": 42
+    },
+    {
+      "x": 47,
+      "y": 42
+    },
+    {
+      "x": 48,
+      "y": 42
+    },
+    {
+      "x": 49,
+      "y": 42
+    },
+    {
+      "x": 50,
+      "y": 42
+    },
+    {
+      "x": 51,
+      "y": 42
+    },
+    {
+      "x": 52,
+      "y": 42
+    },
+    {
+      "x": 53,
+      "y": 42
+    },
+    {
+      "x": 54,
+      "y": 42
+    },
+    {
+      "x": 55,
+      "y": 42
+    },
+    {
+      "x": 56,
+      "y": 42
+    },
+    {
+      "x": 57,
+      "y": 42
+    },
+    {
+      "x": 58,
+      "y": 42
+    },
+    {
+      "x": 59,
+      "y": 42
+    },
+    {
+      "x": 60,
+      "y": 42
+    },
+    {
+      "x": 61,
+      "y": 42
+    },
+    {
+      "x": 62,
+      "y": 42
+    },
+    {
+      "x": 63,
+      "y": 42
+    },
+    {
+      "x": 64,
+      "y": 42
+    },
+    {
+      "x": 65,
+      "y": 42
+    },
+    {
+      "x": 66,
+      "y": 42
+    },
+    {
+      "x": 67,
+      "y": 42
+    },
+    {
+      "x": 68,
+      "y": 42
+    },
+    {
+      "x": 69,
+      "y": 42
+    },
+    {
+      "x": 70,
+      "y": 42
+    },
+    {
+      "x": 71,
+      "y": 42
+    },
+    {
+      "x": 72,
+      "y": 42
+    },
+    {
+      "x": 73,
+      "y": 42
+    },
+    {
+      "x": 74,
+      "y": 42
+    },
+    {
+      "x": 75,
+      "y": 42
+    },
+    {
+      "x": 76,
+      "y": 42
+    },
+    {
+      "x": 77,
+      "y": 42
+    },
+    {
+      "x": 1,
+      "y": 43
+    },
+    {
+      "x": 3,
+      "y": 43
+    },
+    {
+      "x": 5,
+      "y": 43
+    },
+    {
+      "x": 9,
+      "y": 43
+    },
+    {
+      "x": 11,
+      "y": 43
+    },
+    {
+      "x": 13,
+      "y": 43
+    },
+    {
+      "x": 17,
+      "y": 43
+    },
+    {
+      "x": 19,
+      "y": 43
+    },
+    {
+      "x": 21,
+      "y": 43
+    },
+    {
+      "x": 25,
+      "y": 43
+    },
+    {
+      "x": 27,
+      "y": 43
+    },
+    {
+      "x": 29,
+      "y": 43
+    },
+    {
+      "x": 33,
+      "y": 43
+    },
+    {
+      "x": 35,
+      "y": 43
+    },
+    {
+      "x": 37,
+      "y": 43
+    },
+    {
+      "x": 41,
+      "y": 43
+    },
+    {
+      "x": 43,
+      "y": 43
+    },
+    {
+      "x": 45,
+      "y": 43
+    },
+    {
+      "x": 49,
+      "y": 43
+    },
+    {
+      "x": 51,
+      "y": 43
+    },
+    {
+      "x": 53,
+      "y": 43
+    },
+    {
+      "x": 57,
+      "y": 43
+    },
+    {
+      "x": 59,
+      "y": 43
+    },
+    {
+      "x": 61,
+      "y": 43
+    },
+    {
+      "x": 65,
+      "y": 43
+    },
+    {
+      "x": 67,
+      "y": 43
+    },
+    {
+      "x": 69,
+      "y": 43
+    },
+    {
+      "x": 73,
+      "y": 43
+    },
+    {
+      "x": 75,
+      "y": 43
+    },
+    {
+      "x": 77,
+      "y": 43
+    },
+    {
+      "x": 1,
+      "y": 44
+    },
+    {
+      "x": 2,
+      "y": 44
+    },
+    {
+      "x": 3,
+      "y": 44
+    },
+    {
+      "x": 4,
+      "y": 44
+    },
+    {
+      "x": 5,
+      "y": 44
+    },
+    {
+      "x": 6,
+      "y": 44
+    },
+    {
+      "x": 7,
+      "y": 44
+    },
+    {
+      "x": 8,
+      "y": 44
+    },
+    {
+      "x": 9,
+      "y": 44
+    },
+    {
+      "x": 10,
+      "y": 44
+    },
+    {
+      "x": 11,
+      "y": 44
+    },
+    {
+      "x": 12,
+      "y": 44
+    },
+    {
+      "x": 13,
+      "y": 44
+    },
+    {
+      "x": 14,
+      "y": 44
+    },
+    {
+      "x": 15,
+      "y": 44
+    },
+    {
+      "x": 16,
+      "y": 44
+    },
+    {
+      "x": 17,
+      "y": 44
+    },
+    {
+      "x": 18,
+      "y": 44
+    },
+    {
+      "x": 19,
+      "y": 44
+    },
+    {
+      "x": 20,
+      "y": 44
+    },
+    {
+      "x": 21,
+      "y": 44
+    },
+    {
+      "x": 22,
+      "y": 44
+    },
+    {
+      "x": 23,
+      "y": 44
+    },
+    {
+      "x": 24,
+      "y": 44
+    },
+    {
+      "x": 25,
+      "y": 44
+    },
+    {
+      "x": 26,
+      "y": 44
+    },
+    {
+      "x": 27,
+      "y": 44
+    },
+    {
+      "x": 28,
+      "y": 44
+    },
+    {
+      "x": 29,
+      "y": 44
+    },
+    {
+      "x": 30,
+      "y": 44
+    },
+    {
+      "x": 31,
+      "y": 44
+    },
+    {
+      "x": 32,
+      "y": 44
+    },
+    {
+      "x": 33,
+      "y": 44
+    },
+    {
+      "x": 34,
+      "y": 44
+    },
+    {
+      "x": 35,
+      "y": 44
+    },
+    {
+      "x": 36,
+      "y": 44
+    },
+    {
+      "x": 37,
+      "y": 44
+    },
+    {
+      "x": 38,
+      "y": 44
+    },
+    {
+      "x": 39,
+      "y": 44
+    },
+    {
+      "x": 40,
+      "y": 44
+    },
+    {
+      "x": 41,
+      "y": 44
+    },
+    {
+      "x": 42,
+      "y": 44
+    },
+    {
+      "x": 43,
+      "y": 44
+    },
+    {
+      "x": 44,
+      "y": 44
+    },
+    {
+      "x": 45,
+      "y": 44
+    },
+    {
+      "x": 46,
+      "y": 44
+    },
+    {
+      "x": 47,
+      "y": 44
+    },
+    {
+      "x": 48,
+      "y": 44
+    },
+    {
+      "x": 49,
+      "y": 44
+    },
+    {
+      "x": 50,
+      "y": 44
+    },
+    {
+      "x": 51,
+      "y": 44
+    },
+    {
+      "x": 52,
+      "y": 44
+    },
+    {
+      "x": 53,
+      "y": 44
+    },
+    {
+      "x": 54,
+      "y": 44
+    },
+    {
+      "x": 55,
+      "y": 44
+    },
+    {
+      "x": 56,
+      "y": 44
+    },
+    {
+      "x": 57,
+      "y": 44
+    },
+    {
+      "x": 58,
+      "y": 44
+    },
+    {
+      "x": 59,
+      "y": 44
+    },
+    {
+      "x": 60,
+      "y": 44
+    },
+    {
+      "x": 61,
+      "y": 44
+    },
+    {
+      "x": 62,
+      "y": 44
+    },
+    {
+      "x": 63,
+      "y": 44
+    },
+    {
+      "x": 64,
+      "y": 44
+    },
+    {
+      "x": 65,
+      "y": 44
+    },
+    {
+      "x": 66,
+      "y": 44
+    },
+    {
+      "x": 67,
+      "y": 44
+    },
+    {
+      "x": 68,
+      "y": 44
+    },
+    {
+      "x": 69,
+      "y": 44
+    },
+    {
+      "x": 70,
+      "y": 44
+    },
+    {
+      "x": 71,
+      "y": 44
+    },
+    {
+      "x": 72,
+      "y": 44
+    },
+    {
+      "x": 73,
+      "y": 44
+    },
+    {
+      "x": 74,
+      "y": 44
+    },
+    {
+      "x": 75,
+      "y": 44
+    },
+    {
+      "x": 76,
+      "y": 44
+    },
+    {
+      "x": 77,
+      "y": 44
+    },
+    {
+      "x": 1,
+      "y": 45
+    },
+    {
+      "x": 3,
+      "y": 45
+    },
+    {
+      "x": 5,
+      "y": 45
+    },
+    {
+      "x": 9,
+      "y": 45
+    },
+    {
+      "x": 11,
+      "y": 45
+    },
+    {
+      "x": 13,
+      "y": 45
+    },
+    {
+      "x": 17,
+      "y": 45
+    },
+    {
+      "x": 19,
+      "y": 45
+    },
+    {
+      "x": 21,
+      "y": 45
+    },
+    {
+      "x": 25,
+      "y": 45
+    },
+    {
+      "x": 27,
+      "y": 45
+    },
+    {
+      "x": 29,
+      "y": 45
+    },
+    {
+      "x": 33,
+      "y": 45
+    },
+    {
+      "x": 35,
+      "y": 45
+    },
+    {
+      "x": 37,
+      "y": 45
+    },
+    {
+      "x": 41,
+      "y": 45
+    },
+    {
+      "x": 43,
+      "y": 45
+    },
+    {
+      "x": 45,
+      "y": 45
+    },
+    {
+      "x": 49,
+      "y": 45
+    },
+    {
+      "x": 51,
+      "y": 45
+    },
+    {
+      "x": 53,
+      "y": 45
+    },
+    {
+      "x": 57,
+      "y": 45
+    },
+    {
+      "x": 59,
+      "y": 45
+    },
+    {
+      "x": 61,
+      "y": 45
+    },
+    {
+      "x": 65,
+      "y": 45
+    },
+    {
+      "x": 67,
+      "y": 45
+    },
+    {
+      "x": 69,
+      "y": 45
+    },
+    {
+      "x": 73,
+      "y": 45
+    },
+    {
+      "x": 75,
+      "y": 45
+    },
+    {
+      "x": 77,
+      "y": 45
+    },
+    {
+      "x": 1,
+      "y": 46
+    },
+    {
+      "x": 3,
+      "y": 46
+    },
+    {
+      "x": 5,
+      "y": 46
+    },
+    {
+      "x": 9,
+      "y": 46
+    },
+    {
+      "x": 11,
+      "y": 46
+    },
+    {
+      "x": 13,
+      "y": 46
+    },
+    {
+      "x": 17,
+      "y": 46
+    },
+    {
+      "x": 19,
+      "y": 46
+    },
+    {
+      "x": 21,
+      "y": 46
+    },
+    {
+      "x": 25,
+      "y": 46
+    },
+    {
+      "x": 27,
+      "y": 46
+    },
+    {
+      "x": 29,
+      "y": 46
+    },
+    {
+      "x": 33,
+      "y": 46
+    },
+    {
+      "x": 35,
+      "y": 46
+    },
+    {
+      "x": 37,
+      "y": 46
+    },
+    {
+      "x": 41,
+      "y": 46
+    },
+    {
+      "x": 43,
+      "y": 46
+    },
+    {
+      "x": 45,
+      "y": 46
+    },
+    {
+      "x": 49,
+      "y": 46
+    },
+    {
+      "x": 51,
+      "y": 46
+    },
+    {
+      "x": 53,
+      "y": 46
+    },
+    {
+      "x": 57,
+      "y": 46
+    },
+    {
+      "x": 59,
+      "y": 46
+    },
+    {
+      "x": 61,
+      "y": 46
+    },
+    {
+      "x": 65,
+      "y": 46
+    },
+    {
+      "x": 67,
+      "y": 46
+    },
+    {
+      "x": 69,
+      "y": 46
+    },
+    {
+      "x": 73,
+      "y": 46
+    },
+    {
+      "x": 75,
+      "y": 46
+    },
+    {
+      "x": 77,
+      "y": 46
+    },
+    {
+      "x": 1,
+      "y": 47
+    },
+    {
+      "x": 2,
+      "y": 47
+    },
+    {
+      "x": 3,
+      "y": 47
+    },
+    {
+      "x": 4,
+      "y": 47
+    },
+    {
+      "x": 5,
+      "y": 47
+    },
+    {
+      "x": 6,
+      "y": 47
+    },
+    {
+      "x": 7,
+      "y": 47
+    },
+    {
+      "x": 8,
+      "y": 47
+    },
+    {
+      "x": 9,
+      "y": 47
+    },
+    {
+      "x": 11,
+      "y": 47
+    },
+    {
+      "x": 13,
+      "y": 47
+    },
+    {
+      "x": 17,
+      "y": 47
+    },
+    {
+      "x": 18,
+      "y": 47
+    },
+    {
+      "x": 19,
+      "y": 47
+    },
+    {
+      "x": 20,
+      "y": 47
+    },
+    {
+      "x": 21,
+      "y": 47
+    },
+    {
+      "x": 22,
+      "y": 47
+    },
+    {
+      "x": 23,
+      "y": 47
+    },
+    {
+      "x": 24,
+      "y": 47
+    },
+    {
+      "x": 25,
+      "y": 47
+    },
+    {
+      "x": 27,
+      "y": 47
+    },
+    {
+      "x": 29,
+      "y": 47
+    },
+    {
+      "x": 33,
+      "y": 47
+    },
+    {
+      "x": 34,
+      "y": 47
+    },
+    {
+      "x": 35,
+      "y": 47
+    },
+    {
+      "x": 36,
+      "y": 47
+    },
+    {
+      "x": 37,
+      "y": 47
+    },
+    {
+      "x": 38,
+      "y": 47
+    },
+    {
+      "x": 39,
+      "y": 47
+    },
+    {
+      "x": 40,
+      "y": 47
+    },
+    {
+      "x": 41,
+      "y": 47
+    },
+    {
+      "x": 43,
+      "y": 47
+    },
+    {
+      "x": 45,
+      "y": 47
+    },
+    {
+      "x": 49,
+      "y": 47
+    },
+    {
+      "x": 50,
+      "y": 47
+    },
+    {
+      "x": 51,
+      "y": 47
+    },
+    {
+      "x": 52,
+      "y": 47
+    },
+    {
+      "x": 53,
+      "y": 47
+    },
+    {
+      "x": 54,
+      "y": 47
+    },
+    {
+      "x": 55,
+      "y": 47
+    },
+    {
+      "x": 56,
+      "y": 47
+    },
+    {
+      "x": 57,
+      "y": 47
+    },
+    {
+      "x": 59,
+      "y": 47
+    },
+    {
+      "x": 61,
+      "y": 47
+    },
+    {
+      "x": 65,
+      "y": 47
+    },
+    {
+      "x": 66,
+      "y": 47
+    },
+    {
+      "x": 67,
+      "y": 47
+    },
+    {
+      "x": 68,
+      "y": 47
+    },
+    {
+      "x": 69,
+      "y": 47
+    },
+    {
+      "x": 70,
+      "y": 47
+    },
+    {
+      "x": 71,
+      "y": 47
+    },
+    {
+      "x": 72,
+      "y": 47
+    },
+    {
+      "x": 73,
+      "y": 47
+    },
+    {
+      "x": 75,
+      "y": 47
+    },
+    {
+      "x": 77,
+      "y": 47
+    }
+  ],
+  "storage_areas": [
+    {
+      "x": 18,
+      "y": 1
+    },
+    {
+      "x": 20,
+      "y": 1
+    },
+    {
+      "x": 22,
+      "y": 1
+    },
+    {
+      "x": 24,
+      "y": 1
+    },
+    {
+      "x": 26,
+      "y": 1
+    },
+    {
+      "x": 28,
+      "y": 1
+    },
+    {
+      "x": 30,
+      "y": 1
+    },
+    {
+      "x": 32,
+      "y": 1
+    },
+    {
+      "x": 34,
+      "y": 1
+    },
+    {
+      "x": 36,
+      "y": 1
+    },
+    {
+      "x": 38,
+      "y": 1
+    },
+    {
+      "x": 40,
+      "y": 1
+    },
+    {
+      "x": 42,
+      "y": 1
+    },
+    {
+      "x": 44,
+      "y": 1
+    },
+    {
+      "x": 46,
+      "y": 1
+    },
+    {
+      "x": 48,
+      "y": 1
+    },
+    {
+      "x": 50,
+      "y": 1
+    },
+    {
+      "x": 52,
+      "y": 1
+    },
+    {
+      "x": 54,
+      "y": 1
+    },
+    {
+      "x": 56,
+      "y": 1
+    },
+    {
+      "x": 58,
+      "y": 1
+    },
+    {
+      "x": 60,
+      "y": 1
+    },
+    {
+      "x": 18,
+      "y": 2
+    },
+    {
+      "x": 20,
+      "y": 2
+    },
+    {
+      "x": 22,
+      "y": 2
+    },
+    {
+      "x": 24,
+      "y": 2
+    },
+    {
+      "x": 26,
+      "y": 2
+    },
+    {
+      "x": 28,
+      "y": 2
+    },
+    {
+      "x": 30,
+      "y": 2
+    },
+    {
+      "x": 32,
+      "y": 2
+    },
+    {
+      "x": 34,
+      "y": 2
+    },
+    {
+      "x": 36,
+      "y": 2
+    },
+    {
+      "x": 38,
+      "y": 2
+    },
+    {
+      "x": 40,
+      "y": 2
+    },
+    {
+      "x": 42,
+      "y": 2
+    },
+    {
+      "x": 44,
+      "y": 2
+    },
+    {
+      "x": 46,
+      "y": 2
+    },
+    {
+      "x": 48,
+      "y": 2
+    },
+    {
+      "x": 50,
+      "y": 2
+    },
+    {
+      "x": 52,
+      "y": 2
+    },
+    {
+      "x": 54,
+      "y": 2
+    },
+    {
+      "x": 56,
+      "y": 2
+    },
+    {
+      "x": 58,
+      "y": 2
+    },
+    {
+      "x": 60,
+      "y": 2
+    },
+    {
+      "x": 18,
+      "y": 3
+    },
+    {
+      "x": 20,
+      "y": 3
+    },
+    {
+      "x": 22,
+      "y": 3
+    },
+    {
+      "x": 24,
+      "y": 3
+    },
+    {
+      "x": 26,
+      "y": 3
+    },
+    {
+      "x": 28,
+      "y": 3
+    },
+    {
+      "x": 30,
+      "y": 3
+    },
+    {
+      "x": 32,
+      "y": 3
+    },
+    {
+      "x": 34,
+      "y": 3
+    },
+    {
+      "x": 36,
+      "y": 3
+    },
+    {
+      "x": 38,
+      "y": 3
+    },
+    {
+      "x": 40,
+      "y": 3
+    },
+    {
+      "x": 42,
+      "y": 3
+    },
+    {
+      "x": 44,
+      "y": 3
+    },
+    {
+      "x": 46,
+      "y": 3
+    },
+    {
+      "x": 48,
+      "y": 3
+    },
+    {
+      "x": 50,
+      "y": 3
+    },
+    {
+      "x": 52,
+      "y": 3
+    },
+    {
+      "x": 54,
+      "y": 3
+    },
+    {
+      "x": 56,
+      "y": 3
+    },
+    {
+      "x": 58,
+      "y": 3
+    },
+    {
+      "x": 60,
+      "y": 3
+    },
+    {
+      "x": 18,
+      "y": 4
+    },
+    {
+      "x": 20,
+      "y": 4
+    },
+    {
+      "x": 22,
+      "y": 4
+    },
+    {
+      "x": 24,
+      "y": 4
+    },
+    {
+      "x": 26,
+      "y": 4
+    },
+    {
+      "x": 28,
+      "y": 4
+    },
+    {
+      "x": 30,
+      "y": 4
+    },
+    {
+      "x": 32,
+      "y": 4
+    },
+    {
+      "x": 34,
+      "y": 4
+    },
+    {
+      "x": 36,
+      "y": 4
+    },
+    {
+      "x": 38,
+      "y": 4
+    },
+    {
+      "x": 40,
+      "y": 4
+    },
+    {
+      "x": 42,
+      "y": 4
+    },
+    {
+      "x": 44,
+      "y": 4
+    },
+    {
+      "x": 46,
+      "y": 4
+    },
+    {
+      "x": 48,
+      "y": 4
+    },
+    {
+      "x": 50,
+      "y": 4
+    },
+    {
+      "x": 52,
+      "y": 4
+    },
+    {
+      "x": 54,
+      "y": 4
+    },
+    {
+      "x": 56,
+      "y": 4
+    },
+    {
+      "x": 58,
+      "y": 4
+    },
+    {
+      "x": 60,
+      "y": 4
+    },
+    {
+      "x": 18,
+      "y": 5
+    },
+    {
+      "x": 20,
+      "y": 5
+    },
+    {
+      "x": 22,
+      "y": 5
+    },
+    {
+      "x": 24,
+      "y": 5
+    },
+    {
+      "x": 26,
+      "y": 5
+    },
+    {
+      "x": 28,
+      "y": 5
+    },
+    {
+      "x": 30,
+      "y": 5
+    },
+    {
+      "x": 32,
+      "y": 5
+    },
+    {
+      "x": 34,
+      "y": 5
+    },
+    {
+      "x": 36,
+      "y": 5
+    },
+    {
+      "x": 38,
+      "y": 5
+    },
+    {
+      "x": 40,
+      "y": 5
+    },
+    {
+      "x": 42,
+      "y": 5
+    },
+    {
+      "x": 44,
+      "y": 5
+    },
+    {
+      "x": 46,
+      "y": 5
+    },
+    {
+      "x": 48,
+      "y": 5
+    },
+    {
+      "x": 50,
+      "y": 5
+    },
+    {
+      "x": 52,
+      "y": 5
+    },
+    {
+      "x": 54,
+      "y": 5
+    },
+    {
+      "x": 56,
+      "y": 5
+    },
+    {
+      "x": 58,
+      "y": 5
+    },
+    {
+      "x": 60,
+      "y": 5
+    },
+    {
+      "x": 18,
+      "y": 7
+    },
+    {
+      "x": 20,
+      "y": 7
+    },
+    {
+      "x": 22,
+      "y": 7
+    },
+    {
+      "x": 24,
+      "y": 7
+    },
+    {
+      "x": 26,
+      "y": 7
+    },
+    {
+      "x": 28,
+      "y": 7
+    },
+    {
+      "x": 30,
+      "y": 7
+    },
+    {
+      "x": 32,
+      "y": 7
+    },
+    {
+      "x": 34,
+      "y": 7
+    },
+    {
+      "x": 36,
+      "y": 7
+    },
+    {
+      "x": 38,
+      "y": 7
+    },
+    {
+      "x": 40,
+      "y": 7
+    },
+    {
+      "x": 42,
+      "y": 7
+    },
+    {
+      "x": 44,
+      "y": 7
+    },
+    {
+      "x": 46,
+      "y": 7
+    },
+    {
+      "x": 48,
+      "y": 7
+    },
+    {
+      "x": 50,
+      "y": 7
+    },
+    {
+      "x": 52,
+      "y": 7
+    },
+    {
+      "x": 54,
+      "y": 7
+    },
+    {
+      "x": 56,
+      "y": 7
+    },
+    {
+      "x": 58,
+      "y": 7
+    },
+    {
+      "x": 60,
+      "y": 7
+    },
+    {
+      "x": 18,
+      "y": 8
+    },
+    {
+      "x": 20,
+      "y": 8
+    },
+    {
+      "x": 22,
+      "y": 8
+    },
+    {
+      "x": 24,
+      "y": 8
+    },
+    {
+      "x": 26,
+      "y": 8
+    },
+    {
+      "x": 28,
+      "y": 8
+    },
+    {
+      "x": 30,
+      "y": 8
+    },
+    {
+      "x": 32,
+      "y": 8
+    },
+    {
+      "x": 34,
+      "y": 8
+    },
+    {
+      "x": 36,
+      "y": 8
+    },
+    {
+      "x": 38,
+      "y": 8
+    },
+    {
+      "x": 40,
+      "y": 8
+    },
+    {
+      "x": 42,
+      "y": 8
+    },
+    {
+      "x": 44,
+      "y": 8
+    },
+    {
+      "x": 46,
+      "y": 8
+    },
+    {
+      "x": 48,
+      "y": 8
+    },
+    {
+      "x": 50,
+      "y": 8
+    },
+    {
+      "x": 52,
+      "y": 8
+    },
+    {
+      "x": 54,
+      "y": 8
+    },
+    {
+      "x": 56,
+      "y": 8
+    },
+    {
+      "x": 58,
+      "y": 8
+    },
+    {
+      "x": 60,
+      "y": 8
+    },
+    {
+      "x": 18,
+      "y": 9
+    },
+    {
+      "x": 20,
+      "y": 9
+    },
+    {
+      "x": 22,
+      "y": 9
+    },
+    {
+      "x": 24,
+      "y": 9
+    },
+    {
+      "x": 26,
+      "y": 9
+    },
+    {
+      "x": 28,
+      "y": 9
+    },
+    {
+      "x": 30,
+      "y": 9
+    },
+    {
+      "x": 32,
+      "y": 9
+    },
+    {
+      "x": 34,
+      "y": 9
+    },
+    {
+      "x": 36,
+      "y": 9
+    },
+    {
+      "x": 38,
+      "y": 9
+    },
+    {
+      "x": 40,
+      "y": 9
+    },
+    {
+      "x": 42,
+      "y": 9
+    },
+    {
+      "x": 44,
+      "y": 9
+    },
+    {
+      "x": 46,
+      "y": 9
+    },
+    {
+      "x": 48,
+      "y": 9
+    },
+    {
+      "x": 50,
+      "y": 9
+    },
+    {
+      "x": 52,
+      "y": 9
+    },
+    {
+      "x": 54,
+      "y": 9
+    },
+    {
+      "x": 56,
+      "y": 9
+    },
+    {
+      "x": 58,
+      "y": 9
+    },
+    {
+      "x": 60,
+      "y": 9
+    },
+    {
+      "x": 18,
+      "y": 10
+    },
+    {
+      "x": 20,
+      "y": 10
+    },
+    {
+      "x": 22,
+      "y": 10
+    },
+    {
+      "x": 24,
+      "y": 10
+    },
+    {
+      "x": 26,
+      "y": 10
+    },
+    {
+      "x": 28,
+      "y": 10
+    },
+    {
+      "x": 30,
+      "y": 10
+    },
+    {
+      "x": 32,
+      "y": 10
+    },
+    {
+      "x": 34,
+      "y": 10
+    },
+    {
+      "x": 36,
+      "y": 10
+    },
+    {
+      "x": 38,
+      "y": 10
+    },
+    {
+      "x": 40,
+      "y": 10
+    },
+    {
+      "x": 42,
+      "y": 10
+    },
+    {
+      "x": 44,
+      "y": 10
+    },
+    {
+      "x": 46,
+      "y": 10
+    },
+    {
+      "x": 48,
+      "y": 10
+    },
+    {
+      "x": 50,
+      "y": 10
+    },
+    {
+      "x": 52,
+      "y": 10
+    },
+    {
+      "x": 54,
+      "y": 10
+    },
+    {
+      "x": 56,
+      "y": 10
+    },
+    {
+      "x": 58,
+      "y": 10
+    },
+    {
+      "x": 60,
+      "y": 10
+    },
+    {
+      "x": 18,
+      "y": 11
+    },
+    {
+      "x": 20,
+      "y": 11
+    },
+    {
+      "x": 22,
+      "y": 11
+    },
+    {
+      "x": 24,
+      "y": 11
+    },
+    {
+      "x": 26,
+      "y": 11
+    },
+    {
+      "x": 28,
+      "y": 11
+    },
+    {
+      "x": 30,
+      "y": 11
+    },
+    {
+      "x": 32,
+      "y": 11
+    },
+    {
+      "x": 34,
+      "y": 11
+    },
+    {
+      "x": 36,
+      "y": 11
+    },
+    {
+      "x": 38,
+      "y": 11
+    },
+    {
+      "x": 40,
+      "y": 11
+    },
+    {
+      "x": 42,
+      "y": 11
+    },
+    {
+      "x": 44,
+      "y": 11
+    },
+    {
+      "x": 46,
+      "y": 11
+    },
+    {
+      "x": 48,
+      "y": 11
+    },
+    {
+      "x": 50,
+      "y": 11
+    },
+    {
+      "x": 52,
+      "y": 11
+    },
+    {
+      "x": 54,
+      "y": 11
+    },
+    {
+      "x": 56,
+      "y": 11
+    },
+    {
+      "x": 58,
+      "y": 11
+    },
+    {
+      "x": 60,
+      "y": 11
+    },
+    {
+      "x": 0,
+      "y": 13
+    },
+    {
+      "x": 2,
+      "y": 13
+    },
+    {
+      "x": 4,
+      "y": 13
+    },
+    {
+      "x": 6,
+      "y": 13
+    },
+    {
+      "x": 8,
+      "y": 13
+    },
+    {
+      "x": 10,
+      "y": 13
+    },
+    {
+      "x": 12,
+      "y": 13
+    },
+    {
+      "x": 14,
+      "y": 13
+    },
+    {
+      "x": 16,
+      "y": 13
+    },
+    {
+      "x": 18,
+      "y": 13
+    },
+    {
+      "x": 20,
+      "y": 13
+    },
+    {
+      "x": 22,
+      "y": 13
+    },
+    {
+      "x": 24,
+      "y": 13
+    },
+    {
+      "x": 26,
+      "y": 13
+    },
+    {
+      "x": 28,
+      "y": 13
+    },
+    {
+      "x": 30,
+      "y": 13
+    },
+    {
+      "x": 32,
+      "y": 13
+    },
+    {
+      "x": 34,
+      "y": 13
+    },
+    {
+      "x": 36,
+      "y": 13
+    },
+    {
+      "x": 38,
+      "y": 13
+    },
+    {
+      "x": 40,
+      "y": 13
+    },
+    {
+      "x": 42,
+      "y": 13
+    },
+    {
+      "x": 44,
+      "y": 13
+    },
+    {
+      "x": 46,
+      "y": 13
+    },
+    {
+      "x": 48,
+      "y": 13
+    },
+    {
+      "x": 50,
+      "y": 13
+    },
+    {
+      "x": 52,
+      "y": 13
+    },
+    {
+      "x": 54,
+      "y": 13
+    },
+    {
+      "x": 56,
+      "y": 13
+    },
+    {
+      "x": 58,
+      "y": 13
+    },
+    {
+      "x": 60,
+      "y": 13
+    },
+    {
+      "x": 62,
+      "y": 13
+    },
+    {
+      "x": 64,
+      "y": 13
+    },
+    {
+      "x": 66,
+      "y": 13
+    },
+    {
+      "x": 68,
+      "y": 13
+    },
+    {
+      "x": 70,
+      "y": 13
+    },
+    {
+      "x": 72,
+      "y": 13
+    },
+    {
+      "x": 74,
+      "y": 13
+    },
+    {
+      "x": 0,
+      "y": 14
+    },
+    {
+      "x": 2,
+      "y": 14
+    },
+    {
+      "x": 4,
+      "y": 14
+    },
+    {
+      "x": 6,
+      "y": 14
+    },
+    {
+      "x": 8,
+      "y": 14
+    },
+    {
+      "x": 10,
+      "y": 14
+    },
+    {
+      "x": 12,
+      "y": 14
+    },
+    {
+      "x": 14,
+      "y": 14
+    },
+    {
+      "x": 16,
+      "y": 14
+    },
+    {
+      "x": 18,
+      "y": 14
+    },
+    {
+      "x": 20,
+      "y": 14
+    },
+    {
+      "x": 22,
+      "y": 14
+    },
+    {
+      "x": 24,
+      "y": 14
+    },
+    {
+      "x": 26,
+      "y": 14
+    },
+    {
+      "x": 28,
+      "y": 14
+    },
+    {
+      "x": 30,
+      "y": 14
+    },
+    {
+      "x": 32,
+      "y": 14
+    },
+    {
+      "x": 34,
+      "y": 14
+    },
+    {
+      "x": 36,
+      "y": 14
+    },
+    {
+      "x": 38,
+      "y": 14
+    },
+    {
+      "x": 40,
+      "y": 14
+    },
+    {
+      "x": 42,
+      "y": 14
+    },
+    {
+      "x": 44,
+      "y": 14
+    },
+    {
+      "x": 46,
+      "y": 14
+    },
+    {
+      "x": 48,
+      "y": 14
+    },
+    {
+      "x": 50,
+      "y": 14
+    },
+    {
+      "x": 52,
+      "y": 14
+    },
+    {
+      "x": 54,
+      "y": 14
+    },
+    {
+      "x": 56,
+      "y": 14
+    },
+    {
+      "x": 58,
+      "y": 14
+    },
+    {
+      "x": 60,
+      "y": 14
+    },
+    {
+      "x": 62,
+      "y": 14
+    },
+    {
+      "x": 64,
+      "y": 14
+    },
+    {
+      "x": 66,
+      "y": 14
+    },
+    {
+      "x": 68,
+      "y": 14
+    },
+    {
+      "x": 70,
+      "y": 14
+    },
+    {
+      "x": 72,
+      "y": 14
+    },
+    {
+      "x": 74,
+      "y": 14
+    },
+    {
+      "x": 0,
+      "y": 15
+    },
+    {
+      "x": 2,
+      "y": 15
+    },
+    {
+      "x": 4,
+      "y": 15
+    },
+    {
+      "x": 6,
+      "y": 15
+    },
+    {
+      "x": 8,
+      "y": 15
+    },
+    {
+      "x": 10,
+      "y": 15
+    },
+    {
+      "x": 12,
+      "y": 15
+    },
+    {
+      "x": 14,
+      "y": 15
+    },
+    {
+      "x": 16,
+      "y": 15
+    },
+    {
+      "x": 18,
+      "y": 15
+    },
+    {
+      "x": 20,
+      "y": 15
+    },
+    {
+      "x": 22,
+      "y": 15
+    },
+    {
+      "x": 24,
+      "y": 15
+    },
+    {
+      "x": 26,
+      "y": 15
+    },
+    {
+      "x": 28,
+      "y": 15
+    },
+    {
+      "x": 30,
+      "y": 15
+    },
+    {
+      "x": 32,
+      "y": 15
+    },
+    {
+      "x": 34,
+      "y": 15
+    },
+    {
+      "x": 36,
+      "y": 15
+    },
+    {
+      "x": 38,
+      "y": 15
+    },
+    {
+      "x": 40,
+      "y": 15
+    },
+    {
+      "x": 42,
+      "y": 15
+    },
+    {
+      "x": 44,
+      "y": 15
+    },
+    {
+      "x": 46,
+      "y": 15
+    },
+    {
+      "x": 48,
+      "y": 15
+    },
+    {
+      "x": 50,
+      "y": 15
+    },
+    {
+      "x": 52,
+      "y": 15
+    },
+    {
+      "x": 54,
+      "y": 15
+    },
+    {
+      "x": 56,
+      "y": 15
+    },
+    {
+      "x": 58,
+      "y": 15
+    },
+    {
+      "x": 60,
+      "y": 15
+    },
+    {
+      "x": 62,
+      "y": 15
+    },
+    {
+      "x": 64,
+      "y": 15
+    },
+    {
+      "x": 66,
+      "y": 15
+    },
+    {
+      "x": 68,
+      "y": 15
+    },
+    {
+      "x": 70,
+      "y": 15
+    },
+    {
+      "x": 72,
+      "y": 15
+    },
+    {
+      "x": 74,
+      "y": 15
+    },
+    {
+      "x": 0,
+      "y": 16
+    },
+    {
+      "x": 2,
+      "y": 16
+    },
+    {
+      "x": 4,
+      "y": 16
+    },
+    {
+      "x": 6,
+      "y": 16
+    },
+    {
+      "x": 8,
+      "y": 16
+    },
+    {
+      "x": 10,
+      "y": 16
+    },
+    {
+      "x": 12,
+      "y": 16
+    },
+    {
+      "x": 14,
+      "y": 16
+    },
+    {
+      "x": 16,
+      "y": 16
+    },
+    {
+      "x": 18,
+      "y": 16
+    },
+    {
+      "x": 20,
+      "y": 16
+    },
+    {
+      "x": 22,
+      "y": 16
+    },
+    {
+      "x": 24,
+      "y": 16
+    },
+    {
+      "x": 26,
+      "y": 16
+    },
+    {
+      "x": 28,
+      "y": 16
+    },
+    {
+      "x": 30,
+      "y": 16
+    },
+    {
+      "x": 32,
+      "y": 16
+    },
+    {
+      "x": 34,
+      "y": 16
+    },
+    {
+      "x": 36,
+      "y": 16
+    },
+    {
+      "x": 38,
+      "y": 16
+    },
+    {
+      "x": 40,
+      "y": 16
+    },
+    {
+      "x": 42,
+      "y": 16
+    },
+    {
+      "x": 44,
+      "y": 16
+    },
+    {
+      "x": 46,
+      "y": 16
+    },
+    {
+      "x": 48,
+      "y": 16
+    },
+    {
+      "x": 50,
+      "y": 16
+    },
+    {
+      "x": 52,
+      "y": 16
+    },
+    {
+      "x": 54,
+      "y": 16
+    },
+    {
+      "x": 56,
+      "y": 16
+    },
+    {
+      "x": 58,
+      "y": 16
+    },
+    {
+      "x": 60,
+      "y": 16
+    },
+    {
+      "x": 62,
+      "y": 16
+    },
+    {
+      "x": 64,
+      "y": 16
+    },
+    {
+      "x": 66,
+      "y": 16
+    },
+    {
+      "x": 68,
+      "y": 16
+    },
+    {
+      "x": 70,
+      "y": 16
+    },
+    {
+      "x": 72,
+      "y": 16
+    },
+    {
+      "x": 74,
+      "y": 16
+    },
+    {
+      "x": 0,
+      "y": 17
+    },
+    {
+      "x": 2,
+      "y": 17
+    },
+    {
+      "x": 4,
+      "y": 17
+    },
+    {
+      "x": 6,
+      "y": 17
+    },
+    {
+      "x": 8,
+      "y": 17
+    },
+    {
+      "x": 10,
+      "y": 17
+    },
+    {
+      "x": 12,
+      "y": 17
+    },
+    {
+      "x": 14,
+      "y": 17
+    },
+    {
+      "x": 16,
+      "y": 17
+    },
+    {
+      "x": 18,
+      "y": 17
+    },
+    {
+      "x": 20,
+      "y": 17
+    },
+    {
+      "x": 22,
+      "y": 17
+    },
+    {
+      "x": 24,
+      "y": 17
+    },
+    {
+      "x": 26,
+      "y": 17
+    },
+    {
+      "x": 28,
+      "y": 17
+    },
+    {
+      "x": 30,
+      "y": 17
+    },
+    {
+      "x": 32,
+      "y": 17
+    },
+    {
+      "x": 34,
+      "y": 17
+    },
+    {
+      "x": 36,
+      "y": 17
+    },
+    {
+      "x": 38,
+      "y": 17
+    },
+    {
+      "x": 40,
+      "y": 17
+    },
+    {
+      "x": 42,
+      "y": 17
+    },
+    {
+      "x": 44,
+      "y": 17
+    },
+    {
+      "x": 46,
+      "y": 17
+    },
+    {
+      "x": 48,
+      "y": 17
+    },
+    {
+      "x": 50,
+      "y": 17
+    },
+    {
+      "x": 52,
+      "y": 17
+    },
+    {
+      "x": 54,
+      "y": 17
+    },
+    {
+      "x": 56,
+      "y": 17
+    },
+    {
+      "x": 58,
+      "y": 17
+    },
+    {
+      "x": 60,
+      "y": 17
+    },
+    {
+      "x": 62,
+      "y": 17
+    },
+    {
+      "x": 64,
+      "y": 17
+    },
+    {
+      "x": 66,
+      "y": 17
+    },
+    {
+      "x": 68,
+      "y": 17
+    },
+    {
+      "x": 70,
+      "y": 17
+    },
+    {
+      "x": 72,
+      "y": 17
+    },
+    {
+      "x": 74,
+      "y": 17
+    },
+    {
+      "x": 0,
+      "y": 18
+    },
+    {
+      "x": 2,
+      "y": 18
+    },
+    {
+      "x": 4,
+      "y": 18
+    },
+    {
+      "x": 6,
+      "y": 18
+    },
+    {
+      "x": 8,
+      "y": 18
+    },
+    {
+      "x": 10,
+      "y": 18
+    },
+    {
+      "x": 12,
+      "y": 18
+    },
+    {
+      "x": 14,
+      "y": 18
+    },
+    {
+      "x": 16,
+      "y": 18
+    },
+    {
+      "x": 18,
+      "y": 18
+    },
+    {
+      "x": 20,
+      "y": 18
+    },
+    {
+      "x": 22,
+      "y": 18
+    },
+    {
+      "x": 24,
+      "y": 18
+    },
+    {
+      "x": 26,
+      "y": 18
+    },
+    {
+      "x": 28,
+      "y": 18
+    },
+    {
+      "x": 30,
+      "y": 18
+    },
+    {
+      "x": 32,
+      "y": 18
+    },
+    {
+      "x": 34,
+      "y": 18
+    },
+    {
+      "x": 36,
+      "y": 18
+    },
+    {
+      "x": 38,
+      "y": 18
+    },
+    {
+      "x": 40,
+      "y": 18
+    },
+    {
+      "x": 42,
+      "y": 18
+    },
+    {
+      "x": 44,
+      "y": 18
+    },
+    {
+      "x": 46,
+      "y": 18
+    },
+    {
+      "x": 48,
+      "y": 18
+    },
+    {
+      "x": 50,
+      "y": 18
+    },
+    {
+      "x": 52,
+      "y": 18
+    },
+    {
+      "x": 54,
+      "y": 18
+    },
+    {
+      "x": 56,
+      "y": 18
+    },
+    {
+      "x": 58,
+      "y": 18
+    },
+    {
+      "x": 60,
+      "y": 18
+    },
+    {
+      "x": 62,
+      "y": 18
+    },
+    {
+      "x": 64,
+      "y": 18
+    },
+    {
+      "x": 66,
+      "y": 18
+    },
+    {
+      "x": 68,
+      "y": 18
+    },
+    {
+      "x": 70,
+      "y": 18
+    },
+    {
+      "x": 72,
+      "y": 18
+    },
+    {
+      "x": 74,
+      "y": 18
+    },
+    {
+      "x": 0,
+      "y": 19
+    },
+    {
+      "x": 2,
+      "y": 19
+    },
+    {
+      "x": 4,
+      "y": 19
+    },
+    {
+      "x": 6,
+      "y": 19
+    },
+    {
+      "x": 8,
+      "y": 19
+    },
+    {
+      "x": 10,
+      "y": 19
+    },
+    {
+      "x": 12,
+      "y": 19
+    },
+    {
+      "x": 14,
+      "y": 19
+    },
+    {
+      "x": 16,
+      "y": 19
+    },
+    {
+      "x": 18,
+      "y": 19
+    },
+    {
+      "x": 20,
+      "y": 19
+    },
+    {
+      "x": 22,
+      "y": 19
+    },
+    {
+      "x": 24,
+      "y": 19
+    },
+    {
+      "x": 26,
+      "y": 19
+    },
+    {
+      "x": 28,
+      "y": 19
+    },
+    {
+      "x": 30,
+      "y": 19
+    },
+    {
+      "x": 32,
+      "y": 19
+    },
+    {
+      "x": 34,
+      "y": 19
+    },
+    {
+      "x": 36,
+      "y": 19
+    },
+    {
+      "x": 38,
+      "y": 19
+    },
+    {
+      "x": 40,
+      "y": 19
+    },
+    {
+      "x": 42,
+      "y": 19
+    },
+    {
+      "x": 44,
+      "y": 19
+    },
+    {
+      "x": 46,
+      "y": 19
+    },
+    {
+      "x": 48,
+      "y": 19
+    },
+    {
+      "x": 50,
+      "y": 19
+    },
+    {
+      "x": 52,
+      "y": 19
+    },
+    {
+      "x": 54,
+      "y": 19
+    },
+    {
+      "x": 56,
+      "y": 19
+    },
+    {
+      "x": 58,
+      "y": 19
+    },
+    {
+      "x": 60,
+      "y": 19
+    },
+    {
+      "x": 62,
+      "y": 19
+    },
+    {
+      "x": 64,
+      "y": 19
+    },
+    {
+      "x": 66,
+      "y": 19
+    },
+    {
+      "x": 68,
+      "y": 19
+    },
+    {
+      "x": 70,
+      "y": 19
+    },
+    {
+      "x": 72,
+      "y": 19
+    },
+    {
+      "x": 74,
+      "y": 19
+    },
+    {
+      "x": 0,
+      "y": 20
+    },
+    {
+      "x": 2,
+      "y": 20
+    },
+    {
+      "x": 4,
+      "y": 20
+    },
+    {
+      "x": 6,
+      "y": 20
+    },
+    {
+      "x": 8,
+      "y": 20
+    },
+    {
+      "x": 10,
+      "y": 20
+    },
+    {
+      "x": 12,
+      "y": 20
+    },
+    {
+      "x": 14,
+      "y": 20
+    },
+    {
+      "x": 16,
+      "y": 20
+    },
+    {
+      "x": 18,
+      "y": 20
+    },
+    {
+      "x": 20,
+      "y": 20
+    },
+    {
+      "x": 22,
+      "y": 20
+    },
+    {
+      "x": 24,
+      "y": 20
+    },
+    {
+      "x": 26,
+      "y": 20
+    },
+    {
+      "x": 28,
+      "y": 20
+    },
+    {
+      "x": 30,
+      "y": 20
+    },
+    {
+      "x": 32,
+      "y": 20
+    },
+    {
+      "x": 34,
+      "y": 20
+    },
+    {
+      "x": 36,
+      "y": 20
+    },
+    {
+      "x": 38,
+      "y": 20
+    },
+    {
+      "x": 40,
+      "y": 20
+    },
+    {
+      "x": 42,
+      "y": 20
+    },
+    {
+      "x": 44,
+      "y": 20
+    },
+    {
+      "x": 46,
+      "y": 20
+    },
+    {
+      "x": 48,
+      "y": 20
+    },
+    {
+      "x": 50,
+      "y": 20
+    },
+    {
+      "x": 52,
+      "y": 20
+    },
+    {
+      "x": 54,
+      "y": 20
+    },
+    {
+      "x": 56,
+      "y": 20
+    },
+    {
+      "x": 58,
+      "y": 20
+    },
+    {
+      "x": 60,
+      "y": 20
+    },
+    {
+      "x": 62,
+      "y": 20
+    },
+    {
+      "x": 64,
+      "y": 20
+    },
+    {
+      "x": 66,
+      "y": 20
+    },
+    {
+      "x": 68,
+      "y": 20
+    },
+    {
+      "x": 70,
+      "y": 20
+    },
+    {
+      "x": 72,
+      "y": 20
+    },
+    {
+      "x": 74,
+      "y": 20
+    },
+    {
+      "x": 0,
+      "y": 21
+    },
+    {
+      "x": 2,
+      "y": 21
+    },
+    {
+      "x": 4,
+      "y": 21
+    },
+    {
+      "x": 6,
+      "y": 21
+    },
+    {
+      "x": 8,
+      "y": 21
+    },
+    {
+      "x": 10,
+      "y": 21
+    },
+    {
+      "x": 12,
+      "y": 21
+    },
+    {
+      "x": 14,
+      "y": 21
+    },
+    {
+      "x": 16,
+      "y": 21
+    },
+    {
+      "x": 18,
+      "y": 21
+    },
+    {
+      "x": 20,
+      "y": 21
+    },
+    {
+      "x": 22,
+      "y": 21
+    },
+    {
+      "x": 24,
+      "y": 21
+    },
+    {
+      "x": 26,
+      "y": 21
+    },
+    {
+      "x": 28,
+      "y": 21
+    },
+    {
+      "x": 30,
+      "y": 21
+    },
+    {
+      "x": 32,
+      "y": 21
+    },
+    {
+      "x": 34,
+      "y": 21
+    },
+    {
+      "x": 36,
+      "y": 21
+    },
+    {
+      "x": 38,
+      "y": 21
+    },
+    {
+      "x": 40,
+      "y": 21
+    },
+    {
+      "x": 42,
+      "y": 21
+    },
+    {
+      "x": 44,
+      "y": 21
+    },
+    {
+      "x": 46,
+      "y": 21
+    },
+    {
+      "x": 48,
+      "y": 21
+    },
+    {
+      "x": 50,
+      "y": 21
+    },
+    {
+      "x": 52,
+      "y": 21
+    },
+    {
+      "x": 54,
+      "y": 21
+    },
+    {
+      "x": 56,
+      "y": 21
+    },
+    {
+      "x": 58,
+      "y": 21
+    },
+    {
+      "x": 60,
+      "y": 21
+    },
+    {
+      "x": 62,
+      "y": 21
+    },
+    {
+      "x": 64,
+      "y": 21
+    },
+    {
+      "x": 66,
+      "y": 21
+    },
+    {
+      "x": 68,
+      "y": 21
+    },
+    {
+      "x": 70,
+      "y": 21
+    },
+    {
+      "x": 72,
+      "y": 21
+    },
+    {
+      "x": 74,
+      "y": 21
+    },
+    {
+      "x": 0,
+      "y": 23
+    },
+    {
+      "x": 2,
+      "y": 23
+    },
+    {
+      "x": 4,
+      "y": 23
+    },
+    {
+      "x": 6,
+      "y": 23
+    },
+    {
+      "x": 8,
+      "y": 23
+    },
+    {
+      "x": 10,
+      "y": 23
+    },
+    {
+      "x": 12,
+      "y": 23
+    },
+    {
+      "x": 14,
+      "y": 23
+    },
+    {
+      "x": 16,
+      "y": 23
+    },
+    {
+      "x": 18,
+      "y": 23
+    },
+    {
+      "x": 20,
+      "y": 23
+    },
+    {
+      "x": 22,
+      "y": 23
+    },
+    {
+      "x": 24,
+      "y": 23
+    },
+    {
+      "x": 26,
+      "y": 23
+    },
+    {
+      "x": 28,
+      "y": 23
+    },
+    {
+      "x": 30,
+      "y": 23
+    },
+    {
+      "x": 32,
+      "y": 23
+    },
+    {
+      "x": 34,
+      "y": 23
+    },
+    {
+      "x": 36,
+      "y": 23
+    },
+    {
+      "x": 38,
+      "y": 23
+    },
+    {
+      "x": 40,
+      "y": 23
+    },
+    {
+      "x": 42,
+      "y": 23
+    },
+    {
+      "x": 44,
+      "y": 23
+    },
+    {
+      "x": 46,
+      "y": 23
+    },
+    {
+      "x": 48,
+      "y": 23
+    },
+    {
+      "x": 50,
+      "y": 23
+    },
+    {
+      "x": 52,
+      "y": 23
+    },
+    {
+      "x": 54,
+      "y": 23
+    },
+    {
+      "x": 56,
+      "y": 23
+    },
+    {
+      "x": 58,
+      "y": 23
+    },
+    {
+      "x": 60,
+      "y": 23
+    },
+    {
+      "x": 62,
+      "y": 23
+    },
+    {
+      "x": 64,
+      "y": 23
+    },
+    {
+      "x": 66,
+      "y": 23
+    },
+    {
+      "x": 68,
+      "y": 23
+    },
+    {
+      "x": 70,
+      "y": 23
+    },
+    {
+      "x": 72,
+      "y": 23
+    },
+    {
+      "x": 74,
+      "y": 23
+    },
+    {
+      "x": 0,
+      "y": 24
+    },
+    {
+      "x": 2,
+      "y": 24
+    },
+    {
+      "x": 4,
+      "y": 24
+    },
+    {
+      "x": 6,
+      "y": 24
+    },
+    {
+      "x": 8,
+      "y": 24
+    },
+    {
+      "x": 10,
+      "y": 24
+    },
+    {
+      "x": 12,
+      "y": 24
+    },
+    {
+      "x": 14,
+      "y": 24
+    },
+    {
+      "x": 16,
+      "y": 24
+    },
+    {
+      "x": 18,
+      "y": 24
+    },
+    {
+      "x": 20,
+      "y": 24
+    },
+    {
+      "x": 22,
+      "y": 24
+    },
+    {
+      "x": 24,
+      "y": 24
+    },
+    {
+      "x": 26,
+      "y": 24
+    },
+    {
+      "x": 28,
+      "y": 24
+    },
+    {
+      "x": 30,
+      "y": 24
+    },
+    {
+      "x": 32,
+      "y": 24
+    },
+    {
+      "x": 34,
+      "y": 24
+    },
+    {
+      "x": 36,
+      "y": 24
+    },
+    {
+      "x": 38,
+      "y": 24
+    },
+    {
+      "x": 40,
+      "y": 24
+    },
+    {
+      "x": 42,
+      "y": 24
+    },
+    {
+      "x": 44,
+      "y": 24
+    },
+    {
+      "x": 46,
+      "y": 24
+    },
+    {
+      "x": 48,
+      "y": 24
+    },
+    {
+      "x": 50,
+      "y": 24
+    },
+    {
+      "x": 52,
+      "y": 24
+    },
+    {
+      "x": 54,
+      "y": 24
+    },
+    {
+      "x": 56,
+      "y": 24
+    },
+    {
+      "x": 58,
+      "y": 24
+    },
+    {
+      "x": 60,
+      "y": 24
+    },
+    {
+      "x": 62,
+      "y": 24
+    },
+    {
+      "x": 64,
+      "y": 24
+    },
+    {
+      "x": 66,
+      "y": 24
+    },
+    {
+      "x": 68,
+      "y": 24
+    },
+    {
+      "x": 70,
+      "y": 24
+    },
+    {
+      "x": 72,
+      "y": 24
+    },
+    {
+      "x": 74,
+      "y": 24
+    },
+    {
+      "x": 0,
+      "y": 25
+    },
+    {
+      "x": 2,
+      "y": 25
+    },
+    {
+      "x": 4,
+      "y": 25
+    },
+    {
+      "x": 6,
+      "y": 25
+    },
+    {
+      "x": 8,
+      "y": 25
+    },
+    {
+      "x": 10,
+      "y": 25
+    },
+    {
+      "x": 12,
+      "y": 25
+    },
+    {
+      "x": 14,
+      "y": 25
+    },
+    {
+      "x": 16,
+      "y": 25
+    },
+    {
+      "x": 18,
+      "y": 25
+    },
+    {
+      "x": 20,
+      "y": 25
+    },
+    {
+      "x": 22,
+      "y": 25
+    },
+    {
+      "x": 24,
+      "y": 25
+    },
+    {
+      "x": 26,
+      "y": 25
+    },
+    {
+      "x": 28,
+      "y": 25
+    },
+    {
+      "x": 30,
+      "y": 25
+    },
+    {
+      "x": 32,
+      "y": 25
+    },
+    {
+      "x": 34,
+      "y": 25
+    },
+    {
+      "x": 36,
+      "y": 25
+    },
+    {
+      "x": 38,
+      "y": 25
+    },
+    {
+      "x": 40,
+      "y": 25
+    },
+    {
+      "x": 42,
+      "y": 25
+    },
+    {
+      "x": 44,
+      "y": 25
+    },
+    {
+      "x": 46,
+      "y": 25
+    },
+    {
+      "x": 48,
+      "y": 25
+    },
+    {
+      "x": 50,
+      "y": 25
+    },
+    {
+      "x": 52,
+      "y": 25
+    },
+    {
+      "x": 54,
+      "y": 25
+    },
+    {
+      "x": 56,
+      "y": 25
+    },
+    {
+      "x": 58,
+      "y": 25
+    },
+    {
+      "x": 60,
+      "y": 25
+    },
+    {
+      "x": 62,
+      "y": 25
+    },
+    {
+      "x": 64,
+      "y": 25
+    },
+    {
+      "x": 66,
+      "y": 25
+    },
+    {
+      "x": 68,
+      "y": 25
+    },
+    {
+      "x": 70,
+      "y": 25
+    },
+    {
+      "x": 72,
+      "y": 25
+    },
+    {
+      "x": 74,
+      "y": 25
+    },
+    {
+      "x": 0,
+      "y": 26
+    },
+    {
+      "x": 2,
+      "y": 26
+    },
+    {
+      "x": 4,
+      "y": 26
+    },
+    {
+      "x": 6,
+      "y": 26
+    },
+    {
+      "x": 8,
+      "y": 26
+    },
+    {
+      "x": 10,
+      "y": 26
+    },
+    {
+      "x": 12,
+      "y": 26
+    },
+    {
+      "x": 14,
+      "y": 26
+    },
+    {
+      "x": 16,
+      "y": 26
+    },
+    {
+      "x": 18,
+      "y": 26
+    },
+    {
+      "x": 20,
+      "y": 26
+    },
+    {
+      "x": 22,
+      "y": 26
+    },
+    {
+      "x": 24,
+      "y": 26
+    },
+    {
+      "x": 26,
+      "y": 26
+    },
+    {
+      "x": 28,
+      "y": 26
+    },
+    {
+      "x": 30,
+      "y": 26
+    },
+    {
+      "x": 32,
+      "y": 26
+    },
+    {
+      "x": 34,
+      "y": 26
+    },
+    {
+      "x": 36,
+      "y": 26
+    },
+    {
+      "x": 38,
+      "y": 26
+    },
+    {
+      "x": 40,
+      "y": 26
+    },
+    {
+      "x": 42,
+      "y": 26
+    },
+    {
+      "x": 44,
+      "y": 26
+    },
+    {
+      "x": 46,
+      "y": 26
+    },
+    {
+      "x": 48,
+      "y": 26
+    },
+    {
+      "x": 50,
+      "y": 26
+    },
+    {
+      "x": 52,
+      "y": 26
+    },
+    {
+      "x": 54,
+      "y": 26
+    },
+    {
+      "x": 56,
+      "y": 26
+    },
+    {
+      "x": 58,
+      "y": 26
+    },
+    {
+      "x": 60,
+      "y": 26
+    },
+    {
+      "x": 62,
+      "y": 26
+    },
+    {
+      "x": 64,
+      "y": 26
+    },
+    {
+      "x": 66,
+      "y": 26
+    },
+    {
+      "x": 68,
+      "y": 26
+    },
+    {
+      "x": 70,
+      "y": 26
+    },
+    {
+      "x": 72,
+      "y": 26
+    },
+    {
+      "x": 74,
+      "y": 26
+    },
+    {
+      "x": 0,
+      "y": 27
+    },
+    {
+      "x": 2,
+      "y": 27
+    },
+    {
+      "x": 4,
+      "y": 27
+    },
+    {
+      "x": 6,
+      "y": 27
+    },
+    {
+      "x": 8,
+      "y": 27
+    },
+    {
+      "x": 10,
+      "y": 27
+    },
+    {
+      "x": 12,
+      "y": 27
+    },
+    {
+      "x": 14,
+      "y": 27
+    },
+    {
+      "x": 16,
+      "y": 27
+    },
+    {
+      "x": 18,
+      "y": 27
+    },
+    {
+      "x": 20,
+      "y": 27
+    },
+    {
+      "x": 22,
+      "y": 27
+    },
+    {
+      "x": 24,
+      "y": 27
+    },
+    {
+      "x": 26,
+      "y": 27
+    },
+    {
+      "x": 28,
+      "y": 27
+    },
+    {
+      "x": 30,
+      "y": 27
+    },
+    {
+      "x": 32,
+      "y": 27
+    },
+    {
+      "x": 34,
+      "y": 27
+    },
+    {
+      "x": 36,
+      "y": 27
+    },
+    {
+      "x": 38,
+      "y": 27
+    },
+    {
+      "x": 40,
+      "y": 27
+    },
+    {
+      "x": 42,
+      "y": 27
+    },
+    {
+      "x": 44,
+      "y": 27
+    },
+    {
+      "x": 46,
+      "y": 27
+    },
+    {
+      "x": 48,
+      "y": 27
+    },
+    {
+      "x": 50,
+      "y": 27
+    },
+    {
+      "x": 52,
+      "y": 27
+    },
+    {
+      "x": 54,
+      "y": 27
+    },
+    {
+      "x": 56,
+      "y": 27
+    },
+    {
+      "x": 58,
+      "y": 27
+    },
+    {
+      "x": 60,
+      "y": 27
+    },
+    {
+      "x": 62,
+      "y": 27
+    },
+    {
+      "x": 64,
+      "y": 27
+    },
+    {
+      "x": 66,
+      "y": 27
+    },
+    {
+      "x": 68,
+      "y": 27
+    },
+    {
+      "x": 70,
+      "y": 27
+    },
+    {
+      "x": 72,
+      "y": 27
+    },
+    {
+      "x": 74,
+      "y": 27
+    },
+    {
+      "x": 0,
+      "y": 28
+    },
+    {
+      "x": 2,
+      "y": 28
+    },
+    {
+      "x": 4,
+      "y": 28
+    },
+    {
+      "x": 6,
+      "y": 28
+    },
+    {
+      "x": 8,
+      "y": 28
+    },
+    {
+      "x": 10,
+      "y": 28
+    },
+    {
+      "x": 12,
+      "y": 28
+    },
+    {
+      "x": 14,
+      "y": 28
+    },
+    {
+      "x": 16,
+      "y": 28
+    },
+    {
+      "x": 18,
+      "y": 28
+    },
+    {
+      "x": 20,
+      "y": 28
+    },
+    {
+      "x": 22,
+      "y": 28
+    },
+    {
+      "x": 24,
+      "y": 28
+    },
+    {
+      "x": 26,
+      "y": 28
+    },
+    {
+      "x": 28,
+      "y": 28
+    },
+    {
+      "x": 30,
+      "y": 28
+    },
+    {
+      "x": 32,
+      "y": 28
+    },
+    {
+      "x": 34,
+      "y": 28
+    },
+    {
+      "x": 36,
+      "y": 28
+    },
+    {
+      "x": 38,
+      "y": 28
+    },
+    {
+      "x": 40,
+      "y": 28
+    },
+    {
+      "x": 42,
+      "y": 28
+    },
+    {
+      "x": 44,
+      "y": 28
+    },
+    {
+      "x": 46,
+      "y": 28
+    },
+    {
+      "x": 48,
+      "y": 28
+    },
+    {
+      "x": 50,
+      "y": 28
+    },
+    {
+      "x": 52,
+      "y": 28
+    },
+    {
+      "x": 54,
+      "y": 28
+    },
+    {
+      "x": 56,
+      "y": 28
+    },
+    {
+      "x": 58,
+      "y": 28
+    },
+    {
+      "x": 60,
+      "y": 28
+    },
+    {
+      "x": 62,
+      "y": 28
+    },
+    {
+      "x": 64,
+      "y": 28
+    },
+    {
+      "x": 66,
+      "y": 28
+    },
+    {
+      "x": 68,
+      "y": 28
+    },
+    {
+      "x": 70,
+      "y": 28
+    },
+    {
+      "x": 72,
+      "y": 28
+    },
+    {
+      "x": 74,
+      "y": 28
+    },
+    {
+      "x": 0,
+      "y": 29
+    },
+    {
+      "x": 2,
+      "y": 29
+    },
+    {
+      "x": 4,
+      "y": 29
+    },
+    {
+      "x": 6,
+      "y": 29
+    },
+    {
+      "x": 8,
+      "y": 29
+    },
+    {
+      "x": 10,
+      "y": 29
+    },
+    {
+      "x": 12,
+      "y": 29
+    },
+    {
+      "x": 14,
+      "y": 29
+    },
+    {
+      "x": 16,
+      "y": 29
+    },
+    {
+      "x": 18,
+      "y": 29
+    },
+    {
+      "x": 20,
+      "y": 29
+    },
+    {
+      "x": 22,
+      "y": 29
+    },
+    {
+      "x": 24,
+      "y": 29
+    },
+    {
+      "x": 26,
+      "y": 29
+    },
+    {
+      "x": 28,
+      "y": 29
+    },
+    {
+      "x": 30,
+      "y": 29
+    },
+    {
+      "x": 32,
+      "y": 29
+    },
+    {
+      "x": 34,
+      "y": 29
+    },
+    {
+      "x": 36,
+      "y": 29
+    },
+    {
+      "x": 38,
+      "y": 29
+    },
+    {
+      "x": 40,
+      "y": 29
+    },
+    {
+      "x": 42,
+      "y": 29
+    },
+    {
+      "x": 44,
+      "y": 29
+    },
+    {
+      "x": 46,
+      "y": 29
+    },
+    {
+      "x": 48,
+      "y": 29
+    },
+    {
+      "x": 50,
+      "y": 29
+    },
+    {
+      "x": 52,
+      "y": 29
+    },
+    {
+      "x": 54,
+      "y": 29
+    },
+    {
+      "x": 56,
+      "y": 29
+    },
+    {
+      "x": 58,
+      "y": 29
+    },
+    {
+      "x": 60,
+      "y": 29
+    },
+    {
+      "x": 62,
+      "y": 29
+    },
+    {
+      "x": 64,
+      "y": 29
+    },
+    {
+      "x": 66,
+      "y": 29
+    },
+    {
+      "x": 68,
+      "y": 29
+    },
+    {
+      "x": 70,
+      "y": 29
+    },
+    {
+      "x": 72,
+      "y": 29
+    },
+    {
+      "x": 74,
+      "y": 29
+    },
+    {
+      "x": 0,
+      "y": 30
+    },
+    {
+      "x": 2,
+      "y": 30
+    },
+    {
+      "x": 4,
+      "y": 30
+    },
+    {
+      "x": 6,
+      "y": 30
+    },
+    {
+      "x": 8,
+      "y": 30
+    },
+    {
+      "x": 10,
+      "y": 30
+    },
+    {
+      "x": 12,
+      "y": 30
+    },
+    {
+      "x": 14,
+      "y": 30
+    },
+    {
+      "x": 16,
+      "y": 30
+    },
+    {
+      "x": 18,
+      "y": 30
+    },
+    {
+      "x": 20,
+      "y": 30
+    },
+    {
+      "x": 22,
+      "y": 30
+    },
+    {
+      "x": 24,
+      "y": 30
+    },
+    {
+      "x": 26,
+      "y": 30
+    },
+    {
+      "x": 28,
+      "y": 30
+    },
+    {
+      "x": 30,
+      "y": 30
+    },
+    {
+      "x": 32,
+      "y": 30
+    },
+    {
+      "x": 34,
+      "y": 30
+    },
+    {
+      "x": 36,
+      "y": 30
+    },
+    {
+      "x": 38,
+      "y": 30
+    },
+    {
+      "x": 40,
+      "y": 30
+    },
+    {
+      "x": 42,
+      "y": 30
+    },
+    {
+      "x": 44,
+      "y": 30
+    },
+    {
+      "x": 46,
+      "y": 30
+    },
+    {
+      "x": 48,
+      "y": 30
+    },
+    {
+      "x": 50,
+      "y": 30
+    },
+    {
+      "x": 52,
+      "y": 30
+    },
+    {
+      "x": 54,
+      "y": 30
+    },
+    {
+      "x": 56,
+      "y": 30
+    },
+    {
+      "x": 58,
+      "y": 30
+    },
+    {
+      "x": 60,
+      "y": 30
+    },
+    {
+      "x": 62,
+      "y": 30
+    },
+    {
+      "x": 64,
+      "y": 30
+    },
+    {
+      "x": 66,
+      "y": 30
+    },
+    {
+      "x": 68,
+      "y": 30
+    },
+    {
+      "x": 70,
+      "y": 30
+    },
+    {
+      "x": 72,
+      "y": 30
+    },
+    {
+      "x": 74,
+      "y": 30
+    },
+    {
+      "x": 0,
+      "y": 31
+    },
+    {
+      "x": 2,
+      "y": 31
+    },
+    {
+      "x": 4,
+      "y": 31
+    },
+    {
+      "x": 6,
+      "y": 31
+    },
+    {
+      "x": 8,
+      "y": 31
+    },
+    {
+      "x": 10,
+      "y": 31
+    },
+    {
+      "x": 12,
+      "y": 31
+    },
+    {
+      "x": 14,
+      "y": 31
+    },
+    {
+      "x": 16,
+      "y": 31
+    },
+    {
+      "x": 18,
+      "y": 31
+    },
+    {
+      "x": 20,
+      "y": 31
+    },
+    {
+      "x": 22,
+      "y": 31
+    },
+    {
+      "x": 24,
+      "y": 31
+    },
+    {
+      "x": 26,
+      "y": 31
+    },
+    {
+      "x": 28,
+      "y": 31
+    },
+    {
+      "x": 30,
+      "y": 31
+    },
+    {
+      "x": 32,
+      "y": 31
+    },
+    {
+      "x": 34,
+      "y": 31
+    },
+    {
+      "x": 36,
+      "y": 31
+    },
+    {
+      "x": 38,
+      "y": 31
+    },
+    {
+      "x": 40,
+      "y": 31
+    },
+    {
+      "x": 42,
+      "y": 31
+    },
+    {
+      "x": 44,
+      "y": 31
+    },
+    {
+      "x": 46,
+      "y": 31
+    },
+    {
+      "x": 48,
+      "y": 31
+    },
+    {
+      "x": 50,
+      "y": 31
+    },
+    {
+      "x": 52,
+      "y": 31
+    },
+    {
+      "x": 54,
+      "y": 31
+    },
+    {
+      "x": 56,
+      "y": 31
+    },
+    {
+      "x": 58,
+      "y": 31
+    },
+    {
+      "x": 60,
+      "y": 31
+    },
+    {
+      "x": 62,
+      "y": 31
+    },
+    {
+      "x": 64,
+      "y": 31
+    },
+    {
+      "x": 66,
+      "y": 31
+    },
+    {
+      "x": 68,
+      "y": 31
+    },
+    {
+      "x": 70,
+      "y": 31
+    },
+    {
+      "x": 72,
+      "y": 31
+    },
+    {
+      "x": 74,
+      "y": 31
+    },
+    {
+      "x": 0,
+      "y": 33
+    },
+    {
+      "x": 2,
+      "y": 33
+    },
+    {
+      "x": 4,
+      "y": 33
+    },
+    {
+      "x": 6,
+      "y": 33
+    },
+    {
+      "x": 8,
+      "y": 33
+    },
+    {
+      "x": 10,
+      "y": 33
+    },
+    {
+      "x": 12,
+      "y": 33
+    },
+    {
+      "x": 14,
+      "y": 33
+    },
+    {
+      "x": 16,
+      "y": 33
+    },
+    {
+      "x": 18,
+      "y": 33
+    },
+    {
+      "x": 20,
+      "y": 33
+    },
+    {
+      "x": 22,
+      "y": 33
+    },
+    {
+      "x": 24,
+      "y": 33
+    },
+    {
+      "x": 26,
+      "y": 33
+    },
+    {
+      "x": 28,
+      "y": 33
+    },
+    {
+      "x": 30,
+      "y": 33
+    },
+    {
+      "x": 32,
+      "y": 33
+    },
+    {
+      "x": 34,
+      "y": 33
+    },
+    {
+      "x": 36,
+      "y": 33
+    },
+    {
+      "x": 38,
+      "y": 33
+    },
+    {
+      "x": 40,
+      "y": 33
+    },
+    {
+      "x": 42,
+      "y": 33
+    },
+    {
+      "x": 44,
+      "y": 33
+    },
+    {
+      "x": 46,
+      "y": 33
+    },
+    {
+      "x": 48,
+      "y": 33
+    },
+    {
+      "x": 50,
+      "y": 33
+    },
+    {
+      "x": 52,
+      "y": 33
+    },
+    {
+      "x": 54,
+      "y": 33
+    },
+    {
+      "x": 56,
+      "y": 33
+    },
+    {
+      "x": 58,
+      "y": 33
+    },
+    {
+      "x": 60,
+      "y": 33
+    },
+    {
+      "x": 62,
+      "y": 33
+    },
+    {
+      "x": 64,
+      "y": 33
+    },
+    {
+      "x": 66,
+      "y": 33
+    },
+    {
+      "x": 68,
+      "y": 33
+    },
+    {
+      "x": 70,
+      "y": 33
+    },
+    {
+      "x": 72,
+      "y": 33
+    },
+    {
+      "x": 74,
+      "y": 33
+    },
+    {
+      "x": 0,
+      "y": 34
+    },
+    {
+      "x": 2,
+      "y": 34
+    },
+    {
+      "x": 4,
+      "y": 34
+    },
+    {
+      "x": 6,
+      "y": 34
+    },
+    {
+      "x": 8,
+      "y": 34
+    },
+    {
+      "x": 10,
+      "y": 34
+    },
+    {
+      "x": 12,
+      "y": 34
+    },
+    {
+      "x": 14,
+      "y": 34
+    },
+    {
+      "x": 16,
+      "y": 34
+    },
+    {
+      "x": 18,
+      "y": 34
+    },
+    {
+      "x": 20,
+      "y": 34
+    },
+    {
+      "x": 22,
+      "y": 34
+    },
+    {
+      "x": 24,
+      "y": 34
+    },
+    {
+      "x": 26,
+      "y": 34
+    },
+    {
+      "x": 28,
+      "y": 34
+    },
+    {
+      "x": 30,
+      "y": 34
+    },
+    {
+      "x": 32,
+      "y": 34
+    },
+    {
+      "x": 34,
+      "y": 34
+    },
+    {
+      "x": 36,
+      "y": 34
+    },
+    {
+      "x": 38,
+      "y": 34
+    },
+    {
+      "x": 40,
+      "y": 34
+    },
+    {
+      "x": 42,
+      "y": 34
+    },
+    {
+      "x": 44,
+      "y": 34
+    },
+    {
+      "x": 46,
+      "y": 34
+    },
+    {
+      "x": 48,
+      "y": 34
+    },
+    {
+      "x": 50,
+      "y": 34
+    },
+    {
+      "x": 52,
+      "y": 34
+    },
+    {
+      "x": 54,
+      "y": 34
+    },
+    {
+      "x": 56,
+      "y": 34
+    },
+    {
+      "x": 58,
+      "y": 34
+    },
+    {
+      "x": 60,
+      "y": 34
+    },
+    {
+      "x": 62,
+      "y": 34
+    },
+    {
+      "x": 64,
+      "y": 34
+    },
+    {
+      "x": 66,
+      "y": 34
+    },
+    {
+      "x": 68,
+      "y": 34
+    },
+    {
+      "x": 70,
+      "y": 34
+    },
+    {
+      "x": 72,
+      "y": 34
+    },
+    {
+      "x": 74,
+      "y": 34
+    },
+    {
+      "x": 0,
+      "y": 35
+    },
+    {
+      "x": 2,
+      "y": 35
+    },
+    {
+      "x": 4,
+      "y": 35
+    },
+    {
+      "x": 6,
+      "y": 35
+    },
+    {
+      "x": 8,
+      "y": 35
+    },
+    {
+      "x": 10,
+      "y": 35
+    },
+    {
+      "x": 12,
+      "y": 35
+    },
+    {
+      "x": 14,
+      "y": 35
+    },
+    {
+      "x": 16,
+      "y": 35
+    },
+    {
+      "x": 18,
+      "y": 35
+    },
+    {
+      "x": 20,
+      "y": 35
+    },
+    {
+      "x": 22,
+      "y": 35
+    },
+    {
+      "x": 24,
+      "y": 35
+    },
+    {
+      "x": 26,
+      "y": 35
+    },
+    {
+      "x": 28,
+      "y": 35
+    },
+    {
+      "x": 30,
+      "y": 35
+    },
+    {
+      "x": 32,
+      "y": 35
+    },
+    {
+      "x": 34,
+      "y": 35
+    },
+    {
+      "x": 36,
+      "y": 35
+    },
+    {
+      "x": 38,
+      "y": 35
+    },
+    {
+      "x": 40,
+      "y": 35
+    },
+    {
+      "x": 42,
+      "y": 35
+    },
+    {
+      "x": 44,
+      "y": 35
+    },
+    {
+      "x": 46,
+      "y": 35
+    },
+    {
+      "x": 48,
+      "y": 35
+    },
+    {
+      "x": 50,
+      "y": 35
+    },
+    {
+      "x": 52,
+      "y": 35
+    },
+    {
+      "x": 54,
+      "y": 35
+    },
+    {
+      "x": 56,
+      "y": 35
+    },
+    {
+      "x": 58,
+      "y": 35
+    },
+    {
+      "x": 60,
+      "y": 35
+    },
+    {
+      "x": 62,
+      "y": 35
+    },
+    {
+      "x": 64,
+      "y": 35
+    },
+    {
+      "x": 66,
+      "y": 35
+    },
+    {
+      "x": 68,
+      "y": 35
+    },
+    {
+      "x": 70,
+      "y": 35
+    },
+    {
+      "x": 72,
+      "y": 35
+    },
+    {
+      "x": 74,
+      "y": 35
+    },
+    {
+      "x": 0,
+      "y": 36
+    },
+    {
+      "x": 2,
+      "y": 36
+    },
+    {
+      "x": 4,
+      "y": 36
+    },
+    {
+      "x": 6,
+      "y": 36
+    },
+    {
+      "x": 8,
+      "y": 36
+    },
+    {
+      "x": 10,
+      "y": 36
+    },
+    {
+      "x": 12,
+      "y": 36
+    },
+    {
+      "x": 14,
+      "y": 36
+    },
+    {
+      "x": 16,
+      "y": 36
+    },
+    {
+      "x": 18,
+      "y": 36
+    },
+    {
+      "x": 20,
+      "y": 36
+    },
+    {
+      "x": 22,
+      "y": 36
+    },
+    {
+      "x": 24,
+      "y": 36
+    },
+    {
+      "x": 26,
+      "y": 36
+    },
+    {
+      "x": 28,
+      "y": 36
+    },
+    {
+      "x": 30,
+      "y": 36
+    },
+    {
+      "x": 32,
+      "y": 36
+    },
+    {
+      "x": 34,
+      "y": 36
+    },
+    {
+      "x": 36,
+      "y": 36
+    },
+    {
+      "x": 38,
+      "y": 36
+    },
+    {
+      "x": 40,
+      "y": 36
+    },
+    {
+      "x": 42,
+      "y": 36
+    },
+    {
+      "x": 44,
+      "y": 36
+    },
+    {
+      "x": 46,
+      "y": 36
+    },
+    {
+      "x": 48,
+      "y": 36
+    },
+    {
+      "x": 50,
+      "y": 36
+    },
+    {
+      "x": 52,
+      "y": 36
+    },
+    {
+      "x": 54,
+      "y": 36
+    },
+    {
+      "x": 56,
+      "y": 36
+    },
+    {
+      "x": 58,
+      "y": 36
+    },
+    {
+      "x": 60,
+      "y": 36
+    },
+    {
+      "x": 62,
+      "y": 36
+    },
+    {
+      "x": 64,
+      "y": 36
+    },
+    {
+      "x": 66,
+      "y": 36
+    },
+    {
+      "x": 68,
+      "y": 36
+    },
+    {
+      "x": 70,
+      "y": 36
+    },
+    {
+      "x": 72,
+      "y": 36
+    },
+    {
+      "x": 74,
+      "y": 36
+    },
+    {
+      "x": 0,
+      "y": 37
+    },
+    {
+      "x": 2,
+      "y": 37
+    },
+    {
+      "x": 4,
+      "y": 37
+    },
+    {
+      "x": 6,
+      "y": 37
+    },
+    {
+      "x": 8,
+      "y": 37
+    },
+    {
+      "x": 10,
+      "y": 37
+    },
+    {
+      "x": 12,
+      "y": 37
+    },
+    {
+      "x": 14,
+      "y": 37
+    },
+    {
+      "x": 16,
+      "y": 37
+    },
+    {
+      "x": 18,
+      "y": 37
+    },
+    {
+      "x": 20,
+      "y": 37
+    },
+    {
+      "x": 22,
+      "y": 37
+    },
+    {
+      "x": 24,
+      "y": 37
+    },
+    {
+      "x": 26,
+      "y": 37
+    },
+    {
+      "x": 28,
+      "y": 37
+    },
+    {
+      "x": 30,
+      "y": 37
+    },
+    {
+      "x": 32,
+      "y": 37
+    },
+    {
+      "x": 34,
+      "y": 37
+    },
+    {
+      "x": 36,
+      "y": 37
+    },
+    {
+      "x": 38,
+      "y": 37
+    },
+    {
+      "x": 40,
+      "y": 37
+    },
+    {
+      "x": 42,
+      "y": 37
+    },
+    {
+      "x": 44,
+      "y": 37
+    },
+    {
+      "x": 46,
+      "y": 37
+    },
+    {
+      "x": 48,
+      "y": 37
+    },
+    {
+      "x": 50,
+      "y": 37
+    },
+    {
+      "x": 52,
+      "y": 37
+    },
+    {
+      "x": 54,
+      "y": 37
+    },
+    {
+      "x": 56,
+      "y": 37
+    },
+    {
+      "x": 58,
+      "y": 37
+    },
+    {
+      "x": 60,
+      "y": 37
+    },
+    {
+      "x": 62,
+      "y": 37
+    },
+    {
+      "x": 64,
+      "y": 37
+    },
+    {
+      "x": 66,
+      "y": 37
+    },
+    {
+      "x": 68,
+      "y": 37
+    },
+    {
+      "x": 70,
+      "y": 37
+    },
+    {
+      "x": 72,
+      "y": 37
+    },
+    {
+      "x": 74,
+      "y": 37
+    },
+    {
+      "x": 0,
+      "y": 38
+    },
+    {
+      "x": 2,
+      "y": 38
+    },
+    {
+      "x": 4,
+      "y": 38
+    },
+    {
+      "x": 6,
+      "y": 38
+    },
+    {
+      "x": 8,
+      "y": 38
+    },
+    {
+      "x": 10,
+      "y": 38
+    },
+    {
+      "x": 12,
+      "y": 38
+    },
+    {
+      "x": 14,
+      "y": 38
+    },
+    {
+      "x": 16,
+      "y": 38
+    },
+    {
+      "x": 18,
+      "y": 38
+    },
+    {
+      "x": 20,
+      "y": 38
+    },
+    {
+      "x": 22,
+      "y": 38
+    },
+    {
+      "x": 24,
+      "y": 38
+    },
+    {
+      "x": 26,
+      "y": 38
+    },
+    {
+      "x": 28,
+      "y": 38
+    },
+    {
+      "x": 30,
+      "y": 38
+    },
+    {
+      "x": 32,
+      "y": 38
+    },
+    {
+      "x": 34,
+      "y": 38
+    },
+    {
+      "x": 36,
+      "y": 38
+    },
+    {
+      "x": 38,
+      "y": 38
+    },
+    {
+      "x": 40,
+      "y": 38
+    },
+    {
+      "x": 42,
+      "y": 38
+    },
+    {
+      "x": 44,
+      "y": 38
+    },
+    {
+      "x": 46,
+      "y": 38
+    },
+    {
+      "x": 48,
+      "y": 38
+    },
+    {
+      "x": 50,
+      "y": 38
+    },
+    {
+      "x": 52,
+      "y": 38
+    },
+    {
+      "x": 54,
+      "y": 38
+    },
+    {
+      "x": 56,
+      "y": 38
+    },
+    {
+      "x": 58,
+      "y": 38
+    },
+    {
+      "x": 60,
+      "y": 38
+    },
+    {
+      "x": 62,
+      "y": 38
+    },
+    {
+      "x": 64,
+      "y": 38
+    },
+    {
+      "x": 66,
+      "y": 38
+    },
+    {
+      "x": 68,
+      "y": 38
+    },
+    {
+      "x": 70,
+      "y": 38
+    },
+    {
+      "x": 72,
+      "y": 38
+    },
+    {
+      "x": 74,
+      "y": 38
+    },
+    {
+      "x": 0,
+      "y": 39
+    },
+    {
+      "x": 2,
+      "y": 39
+    },
+    {
+      "x": 4,
+      "y": 39
+    },
+    {
+      "x": 6,
+      "y": 39
+    },
+    {
+      "x": 8,
+      "y": 39
+    },
+    {
+      "x": 10,
+      "y": 39
+    },
+    {
+      "x": 12,
+      "y": 39
+    },
+    {
+      "x": 14,
+      "y": 39
+    },
+    {
+      "x": 16,
+      "y": 39
+    },
+    {
+      "x": 18,
+      "y": 39
+    },
+    {
+      "x": 20,
+      "y": 39
+    },
+    {
+      "x": 22,
+      "y": 39
+    },
+    {
+      "x": 24,
+      "y": 39
+    },
+    {
+      "x": 26,
+      "y": 39
+    },
+    {
+      "x": 28,
+      "y": 39
+    },
+    {
+      "x": 30,
+      "y": 39
+    },
+    {
+      "x": 32,
+      "y": 39
+    },
+    {
+      "x": 34,
+      "y": 39
+    },
+    {
+      "x": 36,
+      "y": 39
+    },
+    {
+      "x": 38,
+      "y": 39
+    },
+    {
+      "x": 40,
+      "y": 39
+    },
+    {
+      "x": 42,
+      "y": 39
+    },
+    {
+      "x": 44,
+      "y": 39
+    },
+    {
+      "x": 46,
+      "y": 39
+    },
+    {
+      "x": 48,
+      "y": 39
+    },
+    {
+      "x": 50,
+      "y": 39
+    },
+    {
+      "x": 52,
+      "y": 39
+    },
+    {
+      "x": 54,
+      "y": 39
+    },
+    {
+      "x": 56,
+      "y": 39
+    },
+    {
+      "x": 58,
+      "y": 39
+    },
+    {
+      "x": 60,
+      "y": 39
+    },
+    {
+      "x": 62,
+      "y": 39
+    },
+    {
+      "x": 64,
+      "y": 39
+    },
+    {
+      "x": 66,
+      "y": 39
+    },
+    {
+      "x": 68,
+      "y": 39
+    },
+    {
+      "x": 70,
+      "y": 39
+    },
+    {
+      "x": 72,
+      "y": 39
+    },
+    {
+      "x": 74,
+      "y": 39
+    },
+    {
+      "x": 0,
+      "y": 40
+    },
+    {
+      "x": 2,
+      "y": 40
+    },
+    {
+      "x": 4,
+      "y": 40
+    },
+    {
+      "x": 6,
+      "y": 40
+    },
+    {
+      "x": 8,
+      "y": 40
+    },
+    {
+      "x": 10,
+      "y": 40
+    },
+    {
+      "x": 12,
+      "y": 40
+    },
+    {
+      "x": 14,
+      "y": 40
+    },
+    {
+      "x": 16,
+      "y": 40
+    },
+    {
+      "x": 18,
+      "y": 40
+    },
+    {
+      "x": 20,
+      "y": 40
+    },
+    {
+      "x": 22,
+      "y": 40
+    },
+    {
+      "x": 24,
+      "y": 40
+    },
+    {
+      "x": 26,
+      "y": 40
+    },
+    {
+      "x": 28,
+      "y": 40
+    },
+    {
+      "x": 30,
+      "y": 40
+    },
+    {
+      "x": 32,
+      "y": 40
+    },
+    {
+      "x": 34,
+      "y": 40
+    },
+    {
+      "x": 36,
+      "y": 40
+    },
+    {
+      "x": 38,
+      "y": 40
+    },
+    {
+      "x": 40,
+      "y": 40
+    },
+    {
+      "x": 42,
+      "y": 40
+    },
+    {
+      "x": 44,
+      "y": 40
+    },
+    {
+      "x": 46,
+      "y": 40
+    },
+    {
+      "x": 48,
+      "y": 40
+    },
+    {
+      "x": 50,
+      "y": 40
+    },
+    {
+      "x": 52,
+      "y": 40
+    },
+    {
+      "x": 54,
+      "y": 40
+    },
+    {
+      "x": 56,
+      "y": 40
+    },
+    {
+      "x": 58,
+      "y": 40
+    },
+    {
+      "x": 60,
+      "y": 40
+    },
+    {
+      "x": 62,
+      "y": 40
+    },
+    {
+      "x": 64,
+      "y": 40
+    },
+    {
+      "x": 66,
+      "y": 40
+    },
+    {
+      "x": 68,
+      "y": 40
+    },
+    {
+      "x": 70,
+      "y": 40
+    },
+    {
+      "x": 72,
+      "y": 40
+    },
+    {
+      "x": 74,
+      "y": 40
+    },
+    {
+      "x": 0,
+      "y": 41
+    },
+    {
+      "x": 2,
+      "y": 41
+    },
+    {
+      "x": 4,
+      "y": 41
+    },
+    {
+      "x": 6,
+      "y": 41
+    },
+    {
+      "x": 8,
+      "y": 41
+    },
+    {
+      "x": 10,
+      "y": 41
+    },
+    {
+      "x": 12,
+      "y": 41
+    },
+    {
+      "x": 14,
+      "y": 41
+    },
+    {
+      "x": 16,
+      "y": 41
+    },
+    {
+      "x": 18,
+      "y": 41
+    },
+    {
+      "x": 20,
+      "y": 41
+    },
+    {
+      "x": 22,
+      "y": 41
+    },
+    {
+      "x": 24,
+      "y": 41
+    },
+    {
+      "x": 26,
+      "y": 41
+    },
+    {
+      "x": 28,
+      "y": 41
+    },
+    {
+      "x": 30,
+      "y": 41
+    },
+    {
+      "x": 32,
+      "y": 41
+    },
+    {
+      "x": 34,
+      "y": 41
+    },
+    {
+      "x": 36,
+      "y": 41
+    },
+    {
+      "x": 38,
+      "y": 41
+    },
+    {
+      "x": 40,
+      "y": 41
+    },
+    {
+      "x": 42,
+      "y": 41
+    },
+    {
+      "x": 44,
+      "y": 41
+    },
+    {
+      "x": 46,
+      "y": 41
+    },
+    {
+      "x": 48,
+      "y": 41
+    },
+    {
+      "x": 50,
+      "y": 41
+    },
+    {
+      "x": 52,
+      "y": 41
+    },
+    {
+      "x": 54,
+      "y": 41
+    },
+    {
+      "x": 56,
+      "y": 41
+    },
+    {
+      "x": 58,
+      "y": 41
+    },
+    {
+      "x": 60,
+      "y": 41
+    },
+    {
+      "x": 62,
+      "y": 41
+    },
+    {
+      "x": 64,
+      "y": 41
+    },
+    {
+      "x": 66,
+      "y": 41
+    },
+    {
+      "x": 68,
+      "y": 41
+    },
+    {
+      "x": 70,
+      "y": 41
+    },
+    {
+      "x": 72,
+      "y": 41
+    },
+    {
+      "x": 74,
+      "y": 41
+    }
+  ],
+  "loading_areas": [
+    {
+      "x": 3,
+      "y": 48
+    },
+    {
+      "x": 6,
+      "y": 48
+    },
+    {
+      "x": 9,
+      "y": 48
+    },
+    {
+      "x": 13,
+      "y": 48
+    },
+    {
+      "x": 19,
+      "y": 48
+    },
+    {
+      "x": 22,
+      "y": 48
+    },
+    {
+      "x": 25,
+      "y": 48
+    },
+    {
+      "x": 29,
+      "y": 48
+    },
+    {
+      "x": 35,
+      "y": 48
+    },
+    {
+      "x": 38,
+      "y": 48
+    },
+    {
+      "x": 41,
+      "y": 48
+    },
+    {
+      "x": 45,
+      "y": 48
+    },
+    {
+      "x": 51,
+      "y": 48
+    },
+    {
+      "x": 54,
+      "y": 48
+    },
+    {
+      "x": 57,
+      "y": 48
+    },
+    {
+      "x": 61,
+      "y": 48
+    },
+    {
+      "x": 67,
+      "y": 48
+    },
+    {
+      "x": 70,
+      "y": 48
+    },
+    {
+      "x": 73,
+      "y": 48
+    },
+    {
+      "x": 77,
+      "y": 48
+    }
+  ],
+  "unloading_areas": [
+    {
+      "x": 1,
+      "y": 48
+    },
+    {
+      "x": 4,
+      "y": 48
+    },
+    {
+      "x": 7,
+      "y": 48
+    },
+    {
+      "x": 11,
+      "y": 48
+    },
+    {
+      "x": 17,
+      "y": 48
+    },
+    {
+      "x": 20,
+      "y": 48
+    },
+    {
+      "x": 23,
+      "y": 48
+    },
+    {
+      "x": 27,
+      "y": 48
+    },
+    {
+      "x": 33,
+      "y": 48
+    },
+    {
+      "x": 36,
+      "y": 48
+    },
+    {
+      "x": 39,
+      "y": 48
+    },
+    {
+      "x": 43,
+      "y": 48
+    },
+    {
+      "x": 49,
+      "y": 48
+    },
+    {
+      "x": 52,
+      "y": 48
+    },
+    {
+      "x": 55,
+      "y": 48
+    },
+    {
+      "x": 59,
+      "y": 48
+    },
+    {
+      "x": 65,
+      "y": 48
+    },
+    {
+      "x": 68,
+      "y": 48
+    },
+    {
+      "x": 71,
+      "y": 48
+    },
+    {
+      "x": 75,
+      "y": 48
+    }
+  ],
+  "obstacles": [
+    {
+      "x": 0,
+      "y": 0
+    },
+    {
+      "x": 1,
+      "y": 0
+    },
+    {
+      "x": 2,
+      "y": 0
+    },
+    {
+      "x": 3,
+      "y": 0
+    },
+    {
+      "x": 4,
+      "y": 0
+    },
+    {
+      "x": 5,
+      "y": 0
+    },
+    {
+      "x": 6,
+      "y": 0
+    },
+    {
+      "x": 7,
+      "y": 0
+    },
+    {
+      "x": 8,
+      "y": 0
+    },
+    {
+      "x": 9,
+      "y": 0
+    },
+    {
+      "x": 10,
+      "y": 0
+    },
+    {
+      "x": 11,
+      "y": 0
+    },
+    {
+      "x": 12,
+      "y": 0
+    },
+    {
+      "x": 13,
+      "y": 0
+    },
+    {
+      "x": 14,
+      "y": 0
+    },
+    {
+      "x": 15,
+      "y": 0
+    },
+    {
+      "x": 16,
+      "y": 0
+    },
+    {
+      "x": 62,
+      "y": 0
+    },
+    {
+      "x": 63,
+      "y": 0
+    },
+    {
+      "x": 64,
+      "y": 0
+    },
+    {
+      "x": 65,
+      "y": 0
+    },
+    {
+      "x": 66,
+      "y": 0
+    },
+    {
+      "x": 67,
+      "y": 0
+    },
+    {
+      "x": 68,
+      "y": 0
+    },
+    {
+      "x": 69,
+      "y": 0
+    },
+    {
+      "x": 70,
+      "y": 0
+    },
+    {
+      "x": 71,
+      "y": 0
+    },
+    {
+      "x": 72,
+      "y": 0
+    },
+    {
+      "x": 73,
+      "y": 0
+    },
+    {
+      "x": 74,
+      "y": 0
+    },
+    {
+      "x": 75,
+      "y": 0
+    },
+    {
+      "x": 76,
+      "y": 0
+    },
+    {
+      "x": 77,
+      "y": 0
+    },
+    {
+      "x": 0,
+      "y": 1
+    },
+    {
+      "x": 1,
+      "y": 1
+    },
+    {
+      "x": 2,
+      "y": 1
+    },
+    {
+      "x": 3,
+      "y": 1
+    },
+    {
+      "x": 4,
+      "y": 1
+    },
+    {
+      "x": 5,
+      "y": 1
+    },
+    {
+      "x": 6,
+      "y": 1
+    },
+    {
+      "x": 7,
+      "y": 1
+    },
+    {
+      "x": 8,
+      "y": 1
+    },
+    {
+      "x": 9,
+      "y": 1
+    },
+    {
+      "x": 10,
+      "y": 1
+    },
+    {
+      "x": 11,
+      "y": 1
+    },
+    {
+      "x": 12,
+      "y": 1
+    },
+    {
+      "x": 13,
+      "y": 1
+    },
+    {
+      "x": 14,
+      "y": 1
+    },
+    {
+      "x": 15,
+      "y": 1
+    },
+    {
+      "x": 16,
+      "y": 1
+    },
+    {
+      "x": 62,
+      "y": 1
+    },
+    {
+      "x": 63,
+      "y": 1
+    },
+    {
+      "x": 64,
+      "y": 1
+    },
+    {
+      "x": 65,
+      "y": 1
+    },
+    {
+      "x": 66,
+      "y": 1
+    },
+    {
+      "x": 67,
+      "y": 1
+    },
+    {
+      "x": 68,
+      "y": 1
+    },
+    {
+      "x": 69,
+      "y": 1
+    },
+    {
+      "x": 70,
+      "y": 1
+    },
+    {
+      "x": 71,
+      "y": 1
+    },
+    {
+      "x": 72,
+      "y": 1
+    },
+    {
+      "x": 73,
+      "y": 1
+    },
+    {
+      "x": 74,
+      "y": 1
+    },
+    {
+      "x": 75,
+      "y": 1
+    },
+    {
+      "x": 76,
+      "y": 1
+    },
+    {
+      "x": 77,
+      "y": 1
+    },
+    {
+      "x": 0,
+      "y": 2
+    },
+    {
+      "x": 1,
+      "y": 2
+    },
+    {
+      "x": 2,
+      "y": 2
+    },
+    {
+      "x": 3,
+      "y": 2
+    },
+    {
+      "x": 4,
+      "y": 2
+    },
+    {
+      "x": 5,
+      "y": 2
+    },
+    {
+      "x": 6,
+      "y": 2
+    },
+    {
+      "x": 7,
+      "y": 2
+    },
+    {
+      "x": 8,
+      "y": 2
+    },
+    {
+      "x": 9,
+      "y": 2
+    },
+    {
+      "x": 10,
+      "y": 2
+    },
+    {
+      "x": 11,
+      "y": 2
+    },
+    {
+      "x": 12,
+      "y": 2
+    },
+    {
+      "x": 13,
+      "y": 2
+    },
+    {
+      "x": 14,
+      "y": 2
+    },
+    {
+      "x": 15,
+      "y": 2
+    },
+    {
+      "x": 16,
+      "y": 2
+    },
+    {
+      "x": 62,
+      "y": 2
+    },
+    {
+      "x": 63,
+      "y": 2
+    },
+    {
+      "x": 64,
+      "y": 2
+    },
+    {
+      "x": 65,
+      "y": 2
+    },
+    {
+      "x": 66,
+      "y": 2
+    },
+    {
+      "x": 67,
+      "y": 2
+    },
+    {
+      "x": 68,
+      "y": 2
+    },
+    {
+      "x": 69,
+      "y": 2
+    },
+    {
+      "x": 70,
+      "y": 2
+    },
+    {
+      "x": 71,
+      "y": 2
+    },
+    {
+      "x": 72,
+      "y": 2
+    },
+    {
+      "x": 73,
+      "y": 2
+    },
+    {
+      "x": 74,
+      "y": 2
+    },
+    {
+      "x": 75,
+      "y": 2
+    },
+    {
+      "x": 76,
+      "y": 2
+    },
+    {
+      "x": 77,
+      "y": 2
+    },
+    {
+      "x": 0,
+      "y": 3
+    },
+    {
+      "x": 1,
+      "y": 3
+    },
+    {
+      "x": 2,
+      "y": 3
+    },
+    {
+      "x": 3,
+      "y": 3
+    },
+    {
+      "x": 4,
+      "y": 3
+    },
+    {
+      "x": 5,
+      "y": 3
+    },
+    {
+      "x": 6,
+      "y": 3
+    },
+    {
+      "x": 7,
+      "y": 3
+    },
+    {
+      "x": 8,
+      "y": 3
+    },
+    {
+      "x": 9,
+      "y": 3
+    },
+    {
+      "x": 10,
+      "y": 3
+    },
+    {
+      "x": 11,
+      "y": 3
+    },
+    {
+      "x": 12,
+      "y": 3
+    },
+    {
+      "x": 13,
+      "y": 3
+    },
+    {
+      "x": 14,
+      "y": 3
+    },
+    {
+      "x": 15,
+      "y": 3
+    },
+    {
+      "x": 16,
+      "y": 3
+    },
+    {
+      "x": 62,
+      "y": 3
+    },
+    {
+      "x": 63,
+      "y": 3
+    },
+    {
+      "x": 64,
+      "y": 3
+    },
+    {
+      "x": 65,
+      "y": 3
+    },
+    {
+      "x": 66,
+      "y": 3
+    },
+    {
+      "x": 67,
+      "y": 3
+    },
+    {
+      "x": 68,
+      "y": 3
+    },
+    {
+      "x": 69,
+      "y": 3
+    },
+    {
+      "x": 70,
+      "y": 3
+    },
+    {
+      "x": 71,
+      "y": 3
+    },
+    {
+      "x": 72,
+      "y": 3
+    },
+    {
+      "x": 73,
+      "y": 3
+    },
+    {
+      "x": 74,
+      "y": 3
+    },
+    {
+      "x": 75,
+      "y": 3
+    },
+    {
+      "x": 76,
+      "y": 3
+    },
+    {
+      "x": 77,
+      "y": 3
+    },
+    {
+      "x": 0,
+      "y": 4
+    },
+    {
+      "x": 1,
+      "y": 4
+    },
+    {
+      "x": 2,
+      "y": 4
+    },
+    {
+      "x": 3,
+      "y": 4
+    },
+    {
+      "x": 4,
+      "y": 4
+    },
+    {
+      "x": 5,
+      "y": 4
+    },
+    {
+      "x": 6,
+      "y": 4
+    },
+    {
+      "x": 7,
+      "y": 4
+    },
+    {
+      "x": 8,
+      "y": 4
+    },
+    {
+      "x": 9,
+      "y": 4
+    },
+    {
+      "x": 10,
+      "y": 4
+    },
+    {
+      "x": 11,
+      "y": 4
+    },
+    {
+      "x": 12,
+      "y": 4
+    },
+    {
+      "x": 13,
+      "y": 4
+    },
+    {
+      "x": 14,
+      "y": 4
+    },
+    {
+      "x": 15,
+      "y": 4
+    },
+    {
+      "x": 16,
+      "y": 4
+    },
+    {
+      "x": 62,
+      "y": 4
+    },
+    {
+      "x": 63,
+      "y": 4
+    },
+    {
+      "x": 64,
+      "y": 4
+    },
+    {
+      "x": 65,
+      "y": 4
+    },
+    {
+      "x": 66,
+      "y": 4
+    },
+    {
+      "x": 67,
+      "y": 4
+    },
+    {
+      "x": 68,
+      "y": 4
+    },
+    {
+      "x": 69,
+      "y": 4
+    },
+    {
+      "x": 70,
+      "y": 4
+    },
+    {
+      "x": 71,
+      "y": 4
+    },
+    {
+      "x": 72,
+      "y": 4
+    },
+    {
+      "x": 73,
+      "y": 4
+    },
+    {
+      "x": 74,
+      "y": 4
+    },
+    {
+      "x": 75,
+      "y": 4
+    },
+    {
+      "x": 76,
+      "y": 4
+    },
+    {
+      "x": 77,
+      "y": 4
+    },
+    {
+      "x": 0,
+      "y": 5
+    },
+    {
+      "x": 1,
+      "y": 5
+    },
+    {
+      "x": 2,
+      "y": 5
+    },
+    {
+      "x": 3,
+      "y": 5
+    },
+    {
+      "x": 4,
+      "y": 5
+    },
+    {
+      "x": 5,
+      "y": 5
+    },
+    {
+      "x": 6,
+      "y": 5
+    },
+    {
+      "x": 7,
+      "y": 5
+    },
+    {
+      "x": 8,
+      "y": 5
+    },
+    {
+      "x": 9,
+      "y": 5
+    },
+    {
+      "x": 10,
+      "y": 5
+    },
+    {
+      "x": 11,
+      "y": 5
+    },
+    {
+      "x": 12,
+      "y": 5
+    },
+    {
+      "x": 13,
+      "y": 5
+    },
+    {
+      "x": 14,
+      "y": 5
+    },
+    {
+      "x": 15,
+      "y": 5
+    },
+    {
+      "x": 16,
+      "y": 5
+    },
+    {
+      "x": 62,
+      "y": 5
+    },
+    {
+      "x": 63,
+      "y": 5
+    },
+    {
+      "x": 64,
+      "y": 5
+    },
+    {
+      "x": 65,
+      "y": 5
+    },
+    {
+      "x": 66,
+      "y": 5
+    },
+    {
+      "x": 67,
+      "y": 5
+    },
+    {
+      "x": 68,
+      "y": 5
+    },
+    {
+      "x": 69,
+      "y": 5
+    },
+    {
+      "x": 70,
+      "y": 5
+    },
+    {
+      "x": 71,
+      "y": 5
+    },
+    {
+      "x": 72,
+      "y": 5
+    },
+    {
+      "x": 73,
+      "y": 5
+    },
+    {
+      "x": 74,
+      "y": 5
+    },
+    {
+      "x": 75,
+      "y": 5
+    },
+    {
+      "x": 76,
+      "y": 5
+    },
+    {
+      "x": 77,
+      "y": 5
+    },
+    {
+      "x": 0,
+      "y": 6
+    },
+    {
+      "x": 1,
+      "y": 6
+    },
+    {
+      "x": 2,
+      "y": 6
+    },
+    {
+      "x": 3,
+      "y": 6
+    },
+    {
+      "x": 4,
+      "y": 6
+    },
+    {
+      "x": 5,
+      "y": 6
+    },
+    {
+      "x": 6,
+      "y": 6
+    },
+    {
+      "x": 7,
+      "y": 6
+    },
+    {
+      "x": 8,
+      "y": 6
+    },
+    {
+      "x": 9,
+      "y": 6
+    },
+    {
+      "x": 10,
+      "y": 6
+    },
+    {
+      "x": 11,
+      "y": 6
+    },
+    {
+      "x": 12,
+      "y": 6
+    },
+    {
+      "x": 13,
+      "y": 6
+    },
+    {
+      "x": 14,
+      "y": 6
+    },
+    {
+      "x": 15,
+      "y": 6
+    },
+    {
+      "x": 16,
+      "y": 6
+    },
+    {
+      "x": 62,
+      "y": 6
+    },
+    {
+      "x": 63,
+      "y": 6
+    },
+    {
+      "x": 64,
+      "y": 6
+    },
+    {
+      "x": 65,
+      "y": 6
+    },
+    {
+      "x": 66,
+      "y": 6
+    },
+    {
+      "x": 67,
+      "y": 6
+    },
+    {
+      "x": 68,
+      "y": 6
+    },
+    {
+      "x": 69,
+      "y": 6
+    },
+    {
+      "x": 70,
+      "y": 6
+    },
+    {
+      "x": 71,
+      "y": 6
+    },
+    {
+      "x": 72,
+      "y": 6
+    },
+    {
+      "x": 73,
+      "y": 6
+    },
+    {
+      "x": 74,
+      "y": 6
+    },
+    {
+      "x": 75,
+      "y": 6
+    },
+    {
+      "x": 76,
+      "y": 6
+    },
+    {
+      "x": 77,
+      "y": 6
+    },
+    {
+      "x": 0,
+      "y": 7
+    },
+    {
+      "x": 1,
+      "y": 7
+    },
+    {
+      "x": 2,
+      "y": 7
+    },
+    {
+      "x": 3,
+      "y": 7
+    },
+    {
+      "x": 4,
+      "y": 7
+    },
+    {
+      "x": 5,
+      "y": 7
+    },
+    {
+      "x": 6,
+      "y": 7
+    },
+    {
+      "x": 7,
+      "y": 7
+    },
+    {
+      "x": 8,
+      "y": 7
+    },
+    {
+      "x": 9,
+      "y": 7
+    },
+    {
+      "x": 10,
+      "y": 7
+    },
+    {
+      "x": 11,
+      "y": 7
+    },
+    {
+      "x": 12,
+      "y": 7
+    },
+    {
+      "x": 13,
+      "y": 7
+    },
+    {
+      "x": 14,
+      "y": 7
+    },
+    {
+      "x": 15,
+      "y": 7
+    },
+    {
+      "x": 16,
+      "y": 7
+    },
+    {
+      "x": 62,
+      "y": 7
+    },
+    {
+      "x": 63,
+      "y": 7
+    },
+    {
+      "x": 64,
+      "y": 7
+    },
+    {
+      "x": 65,
+      "y": 7
+    },
+    {
+      "x": 66,
+      "y": 7
+    },
+    {
+      "x": 67,
+      "y": 7
+    },
+    {
+      "x": 68,
+      "y": 7
+    },
+    {
+      "x": 69,
+      "y": 7
+    },
+    {
+      "x": 70,
+      "y": 7
+    },
+    {
+      "x": 71,
+      "y": 7
+    },
+    {
+      "x": 72,
+      "y": 7
+    },
+    {
+      "x": 73,
+      "y": 7
+    },
+    {
+      "x": 74,
+      "y": 7
+    },
+    {
+      "x": 75,
+      "y": 7
+    },
+    {
+      "x": 76,
+      "y": 7
+    },
+    {
+      "x": 77,
+      "y": 7
+    },
+    {
+      "x": 0,
+      "y": 8
+    },
+    {
+      "x": 1,
+      "y": 8
+    },
+    {
+      "x": 2,
+      "y": 8
+    },
+    {
+      "x": 3,
+      "y": 8
+    },
+    {
+      "x": 4,
+      "y": 8
+    },
+    {
+      "x": 5,
+      "y": 8
+    },
+    {
+      "x": 6,
+      "y": 8
+    },
+    {
+      "x": 7,
+      "y": 8
+    },
+    {
+      "x": 8,
+      "y": 8
+    },
+    {
+      "x": 9,
+      "y": 8
+    },
+    {
+      "x": 10,
+      "y": 8
+    },
+    {
+      "x": 11,
+      "y": 8
+    },
+    {
+      "x": 12,
+      "y": 8
+    },
+    {
+      "x": 13,
+      "y": 8
+    },
+    {
+      "x": 14,
+      "y": 8
+    },
+    {
+      "x": 15,
+      "y": 8
+    },
+    {
+      "x": 16,
+      "y": 8
+    },
+    {
+      "x": 62,
+      "y": 8
+    },
+    {
+      "x": 63,
+      "y": 8
+    },
+    {
+      "x": 64,
+      "y": 8
+    },
+    {
+      "x": 65,
+      "y": 8
+    },
+    {
+      "x": 66,
+      "y": 8
+    },
+    {
+      "x": 67,
+      "y": 8
+    },
+    {
+      "x": 68,
+      "y": 8
+    },
+    {
+      "x": 69,
+      "y": 8
+    },
+    {
+      "x": 70,
+      "y": 8
+    },
+    {
+      "x": 71,
+      "y": 8
+    },
+    {
+      "x": 72,
+      "y": 8
+    },
+    {
+      "x": 73,
+      "y": 8
+    },
+    {
+      "x": 74,
+      "y": 8
+    },
+    {
+      "x": 75,
+      "y": 8
+    },
+    {
+      "x": 76,
+      "y": 8
+    },
+    {
+      "x": 77,
+      "y": 8
+    },
+    {
+      "x": 0,
+      "y": 9
+    },
+    {
+      "x": 1,
+      "y": 9
+    },
+    {
+      "x": 2,
+      "y": 9
+    },
+    {
+      "x": 3,
+      "y": 9
+    },
+    {
+      "x": 4,
+      "y": 9
+    },
+    {
+      "x": 5,
+      "y": 9
+    },
+    {
+      "x": 6,
+      "y": 9
+    },
+    {
+      "x": 7,
+      "y": 9
+    },
+    {
+      "x": 8,
+      "y": 9
+    },
+    {
+      "x": 9,
+      "y": 9
+    },
+    {
+      "x": 10,
+      "y": 9
+    },
+    {
+      "x": 11,
+      "y": 9
+    },
+    {
+      "x": 12,
+      "y": 9
+    },
+    {
+      "x": 13,
+      "y": 9
+    },
+    {
+      "x": 14,
+      "y": 9
+    },
+    {
+      "x": 15,
+      "y": 9
+    },
+    {
+      "x": 16,
+      "y": 9
+    },
+    {
+      "x": 62,
+      "y": 9
+    },
+    {
+      "x": 63,
+      "y": 9
+    },
+    {
+      "x": 64,
+      "y": 9
+    },
+    {
+      "x": 65,
+      "y": 9
+    },
+    {
+      "x": 66,
+      "y": 9
+    },
+    {
+      "x": 67,
+      "y": 9
+    },
+    {
+      "x": 68,
+      "y": 9
+    },
+    {
+      "x": 69,
+      "y": 9
+    },
+    {
+      "x": 70,
+      "y": 9
+    },
+    {
+      "x": 71,
+      "y": 9
+    },
+    {
+      "x": 72,
+      "y": 9
+    },
+    {
+      "x": 73,
+      "y": 9
+    },
+    {
+      "x": 74,
+      "y": 9
+    },
+    {
+      "x": 75,
+      "y": 9
+    },
+    {
+      "x": 76,
+      "y": 9
+    },
+    {
+      "x": 77,
+      "y": 9
+    },
+    {
+      "x": 0,
+      "y": 10
+    },
+    {
+      "x": 1,
+      "y": 10
+    },
+    {
+      "x": 2,
+      "y": 10
+    },
+    {
+      "x": 3,
+      "y": 10
+    },
+    {
+      "x": 4,
+      "y": 10
+    },
+    {
+      "x": 5,
+      "y": 10
+    },
+    {
+      "x": 6,
+      "y": 10
+    },
+    {
+      "x": 7,
+      "y": 10
+    },
+    {
+      "x": 8,
+      "y": 10
+    },
+    {
+      "x": 9,
+      "y": 10
+    },
+    {
+      "x": 10,
+      "y": 10
+    },
+    {
+      "x": 11,
+      "y": 10
+    },
+    {
+      "x": 12,
+      "y": 10
+    },
+    {
+      "x": 13,
+      "y": 10
+    },
+    {
+      "x": 14,
+      "y": 10
+    },
+    {
+      "x": 15,
+      "y": 10
+    },
+    {
+      "x": 16,
+      "y": 10
+    },
+    {
+      "x": 62,
+      "y": 10
+    },
+    {
+      "x": 63,
+      "y": 10
+    },
+    {
+      "x": 64,
+      "y": 10
+    },
+    {
+      "x": 65,
+      "y": 10
+    },
+    {
+      "x": 66,
+      "y": 10
+    },
+    {
+      "x": 67,
+      "y": 10
+    },
+    {
+      "x": 68,
+      "y": 10
+    },
+    {
+      "x": 69,
+      "y": 10
+    },
+    {
+      "x": 70,
+      "y": 10
+    },
+    {
+      "x": 71,
+      "y": 10
+    },
+    {
+      "x": 72,
+      "y": 10
+    },
+    {
+      "x": 73,
+      "y": 10
+    },
+    {
+      "x": 74,
+      "y": 10
+    },
+    {
+      "x": 75,
+      "y": 10
+    },
+    {
+      "x": 76,
+      "y": 10
+    },
+    {
+      "x": 77,
+      "y": 10
+    },
+    {
+      "x": 0,
+      "y": 11
+    },
+    {
+      "x": 1,
+      "y": 11
+    },
+    {
+      "x": 2,
+      "y": 11
+    },
+    {
+      "x": 3,
+      "y": 11
+    },
+    {
+      "x": 4,
+      "y": 11
+    },
+    {
+      "x": 5,
+      "y": 11
+    },
+    {
+      "x": 6,
+      "y": 11
+    },
+    {
+      "x": 7,
+      "y": 11
+    },
+    {
+      "x": 8,
+      "y": 11
+    },
+    {
+      "x": 9,
+      "y": 11
+    },
+    {
+      "x": 10,
+      "y": 11
+    },
+    {
+      "x": 11,
+      "y": 11
+    },
+    {
+      "x": 12,
+      "y": 11
+    },
+    {
+      "x": 13,
+      "y": 11
+    },
+    {
+      "x": 14,
+      "y": 11
+    },
+    {
+      "x": 15,
+      "y": 11
+    },
+    {
+      "x": 16,
+      "y": 11
+    },
+    {
+      "x": 62,
+      "y": 11
+    },
+    {
+      "x": 63,
+      "y": 11
+    },
+    {
+      "x": 64,
+      "y": 11
+    },
+    {
+      "x": 65,
+      "y": 11
+    },
+    {
+      "x": 66,
+      "y": 11
+    },
+    {
+      "x": 67,
+      "y": 11
+    },
+    {
+      "x": 68,
+      "y": 11
+    },
+    {
+      "x": 69,
+      "y": 11
+    },
+    {
+      "x": 70,
+      "y": 11
+    },
+    {
+      "x": 71,
+      "y": 11
+    },
+    {
+      "x": 72,
+      "y": 11
+    },
+    {
+      "x": 73,
+      "y": 11
+    },
+    {
+      "x": 74,
+      "y": 11
+    },
+    {
+      "x": 75,
+      "y": 11
+    },
+    {
+      "x": 76,
+      "y": 11
+    },
+    {
+      "x": 77,
+      "y": 11
+    },
+    {
+      "x": 76,
+      "y": 12
+    },
+    {
+      "x": 77,
+      "y": 12
+    },
+    {
+      "x": 76,
+      "y": 13
+    },
+    {
+      "x": 77,
+      "y": 13
+    },
+    {
+      "x": 76,
+      "y": 14
+    },
+    {
+      "x": 77,
+      "y": 14
+    },
+    {
+      "x": 76,
+      "y": 15
+    },
+    {
+      "x": 77,
+      "y": 15
+    },
+    {
+      "x": 76,
+      "y": 16
+    },
+    {
+      "x": 77,
+      "y": 16
+    },
+    {
+      "x": 76,
+      "y": 17
+    },
+    {
+      "x": 77,
+      "y": 17
+    },
+    {
+      "x": 76,
+      "y": 18
+    },
+    {
+      "x": 77,
+      "y": 18
+    },
+    {
+      "x": 76,
+      "y": 19
+    },
+    {
+      "x": 77,
+      "y": 19
+    },
+    {
+      "x": 76,
+      "y": 20
+    },
+    {
+      "x": 77,
+      "y": 20
+    },
+    {
+      "x": 76,
+      "y": 21
+    },
+    {
+      "x": 77,
+      "y": 21
+    },
+    {
+      "x": 76,
+      "y": 22
+    },
+    {
+      "x": 77,
+      "y": 22
+    },
+    {
+      "x": 7,
+      "y": 23
+    },
+    {
+      "x": 15,
+      "y": 23
+    },
+    {
+      "x": 23,
+      "y": 23
+    },
+    {
+      "x": 31,
+      "y": 23
+    },
+    {
+      "x": 39,
+      "y": 23
+    },
+    {
+      "x": 47,
+      "y": 23
+    },
+    {
+      "x": 55,
+      "y": 23
+    },
+    {
+      "x": 63,
+      "y": 23
+    },
+    {
+      "x": 71,
+      "y": 23
+    },
+    {
+      "x": 76,
+      "y": 23
+    },
+    {
+      "x": 77,
+      "y": 23
+    },
+    {
+      "x": 7,
+      "y": 24
+    },
+    {
+      "x": 15,
+      "y": 24
+    },
+    {
+      "x": 23,
+      "y": 24
+    },
+    {
+      "x": 31,
+      "y": 24
+    },
+    {
+      "x": 39,
+      "y": 24
+    },
+    {
+      "x": 47,
+      "y": 24
+    },
+    {
+      "x": 55,
+      "y": 24
+    },
+    {
+      "x": 63,
+      "y": 24
+    },
+    {
+      "x": 71,
+      "y": 24
+    },
+    {
+      "x": 76,
+      "y": 24
+    },
+    {
+      "x": 77,
+      "y": 24
+    },
+    {
+      "x": 7,
+      "y": 25
+    },
+    {
+      "x": 15,
+      "y": 25
+    },
+    {
+      "x": 23,
+      "y": 25
+    },
+    {
+      "x": 31,
+      "y": 25
+    },
+    {
+      "x": 39,
+      "y": 25
+    },
+    {
+      "x": 47,
+      "y": 25
+    },
+    {
+      "x": 55,
+      "y": 25
+    },
+    {
+      "x": 63,
+      "y": 25
+    },
+    {
+      "x": 71,
+      "y": 25
+    },
+    {
+      "x": 76,
+      "y": 25
+    },
+    {
+      "x": 77,
+      "y": 25
+    },
+    {
+      "x": 7,
+      "y": 26
+    },
+    {
+      "x": 15,
+      "y": 26
+    },
+    {
+      "x": 23,
+      "y": 26
+    },
+    {
+      "x": 31,
+      "y": 26
+    },
+    {
+      "x": 39,
+      "y": 26
+    },
+    {
+      "x": 47,
+      "y": 26
+    },
+    {
+      "x": 55,
+      "y": 26
+    },
+    {
+      "x": 63,
+      "y": 26
+    },
+    {
+      "x": 71,
+      "y": 26
+    },
+    {
+      "x": 76,
+      "y": 26
+    },
+    {
+      "x": 77,
+      "y": 26
+    },
+    {
+      "x": 7,
+      "y": 27
+    },
+    {
+      "x": 15,
+      "y": 27
+    },
+    {
+      "x": 23,
+      "y": 27
+    },
+    {
+      "x": 31,
+      "y": 27
+    },
+    {
+      "x": 39,
+      "y": 27
+    },
+    {
+      "x": 47,
+      "y": 27
+    },
+    {
+      "x": 55,
+      "y": 27
+    },
+    {
+      "x": 63,
+      "y": 27
+    },
+    {
+      "x": 71,
+      "y": 27
+    },
+    {
+      "x": 76,
+      "y": 27
+    },
+    {
+      "x": 77,
+      "y": 27
+    },
+    {
+      "x": 76,
+      "y": 28
+    },
+    {
+      "x": 77,
+      "y": 28
+    },
+    {
+      "x": 76,
+      "y": 29
+    },
+    {
+      "x": 77,
+      "y": 29
+    },
+    {
+      "x": 76,
+      "y": 30
+    },
+    {
+      "x": 77,
+      "y": 30
+    },
+    {
+      "x": 76,
+      "y": 31
+    },
+    {
+      "x": 77,
+      "y": 31
+    },
+    {
+      "x": 0,
+      "y": 49
+    },
+    {
+      "x": 1,
+      "y": 49
+    },
+    {
+      "x": 2,
+      "y": 49
+    },
+    {
+      "x": 3,
+      "y": 49
+    },
+    {
+      "x": 4,
+      "y": 49
+    },
+    {
+      "x": 5,
+      "y": 49
+    },
+    {
+      "x": 6,
+      "y": 49
+    },
+    {
+      "x": 7,
+      "y": 49
+    },
+    {
+      "x": 8,
+      "y": 49
+    },
+    {
+      "x": 9,
+      "y": 49
+    },
+    {
+      "x": 10,
+      "y": 49
+    },
+    {
+      "x": 11,
+      "y": 49
+    },
+    {
+      "x": 12,
+      "y": 49
+    },
+    {
+      "x": 13,
+      "y": 49
+    },
+    {
+      "x": 14,
+      "y": 49
+    },
+    {
+      "x": 15,
+      "y": 49
+    },
+    {
+      "x": 16,
+      "y": 49
+    },
+    {
+      "x": 17,
+      "y": 49
+    },
+    {
+      "x": 18,
+      "y": 49
+    },
+    {
+      "x": 19,
+      "y": 49
+    },
+    {
+      "x": 20,
+      "y": 49
+    },
+    {
+      "x": 21,
+      "y": 49
+    },
+    {
+      "x": 22,
+      "y": 49
+    },
+    {
+      "x": 23,
+      "y": 49
+    },
+    {
+      "x": 24,
+      "y": 49
+    },
+    {
+      "x": 25,
+      "y": 49
+    },
+    {
+      "x": 26,
+      "y": 49
+    },
+    {
+      "x": 27,
+      "y": 49
+    },
+    {
+      "x": 28,
+      "y": 49
+    },
+    {
+      "x": 29,
+      "y": 49
+    },
+    {
+      "x": 30,
+      "y": 49
+    },
+    {
+      "x": 31,
+      "y": 49
+    },
+    {
+      "x": 32,
+      "y": 49
+    },
+    {
+      "x": 33,
+      "y": 49
+    },
+    {
+      "x": 34,
+      "y": 49
+    },
+    {
+      "x": 35,
+      "y": 49
+    },
+    {
+      "x": 36,
+      "y": 49
+    },
+    {
+      "x": 37,
+      "y": 49
+    },
+    {
+      "x": 38,
+      "y": 49
+    },
+    {
+      "x": 39,
+      "y": 49
+    },
+    {
+      "x": 40,
+      "y": 49
+    },
+    {
+      "x": 41,
+      "y": 49
+    },
+    {
+      "x": 42,
+      "y": 49
+    },
+    {
+      "x": 43,
+      "y": 49
+    },
+    {
+      "x": 44,
+      "y": 49
+    },
+    {
+      "x": 45,
+      "y": 49
+    },
+    {
+      "x": 46,
+      "y": 49
+    },
+    {
+      "x": 47,
+      "y": 49
+    },
+    {
+      "x": 48,
+      "y": 49
+    },
+    {
+      "x": 49,
+      "y": 49
+    },
+    {
+      "x": 50,
+      "y": 49
+    },
+    {
+      "x": 51,
+      "y": 49
+    },
+    {
+      "x": 52,
+      "y": 49
+    },
+    {
+      "x": 53,
+      "y": 49
+    },
+    {
+      "x": 54,
+      "y": 49
+    },
+    {
+      "x": 55,
+      "y": 49
+    },
+    {
+      "x": 56,
+      "y": 49
+    },
+    {
+      "x": 57,
+      "y": 49
+    },
+    {
+      "x": 58,
+      "y": 49
+    },
+    {
+      "x": 59,
+      "y": 49
+    },
+    {
+      "x": 60,
+      "y": 49
+    },
+    {
+      "x": 61,
+      "y": 49
+    },
+    {
+      "x": 62,
+      "y": 49
+    },
+    {
+      "x": 63,
+      "y": 49
+    },
+    {
+      "x": 64,
+      "y": 49
+    },
+    {
+      "x": 65,
+      "y": 49
+    },
+    {
+      "x": 66,
+      "y": 49
+    },
+    {
+      "x": 67,
+      "y": 49
+    },
+    {
+      "x": 68,
+      "y": 49
+    },
+    {
+      "x": 69,
+      "y": 49
+    },
+    {
+      "x": 70,
+      "y": 49
+    },
+    {
+      "x": 71,
+      "y": 49
+    },
+    {
+      "x": 72,
+      "y": 49
+    },
+    {
+      "x": 73,
+      "y": 49
+    },
+    {
+      "x": 74,
+      "y": 49
+    },
+    {
+      "x": 75,
+      "y": 49
+    },
+    {
+      "x": 76,
+      "y": 49
+    },
+    {
+      "x": 77,
+      "y": 49
+    }
+  ]
+}
\ No newline at end of file
diff --git a/path_mapping.json b/path_mapping.json
new file mode 100644
index 0000000..bbb94bc
--- /dev/null
+++ b/path_mapping.json
@@ -0,0 +1,11880 @@
+{
+  "path_id_to_coordinates": {
+    "338": [
+      {
+        "x": 17,
+        "y": 0
+      }
+    ],
+    "346": [
+      {
+        "x": 18,
+        "y": 0
+      }
+    ],
+    "393": [
+      {
+        "x": 19,
+        "y": 0
+      }
+    ],
+    "401": [
+      {
+        "x": 20,
+        "y": 0
+      }
+    ],
+    "448": [
+      {
+        "x": 21,
+        "y": 0
+      }
+    ],
+    "456": [
+      {
+        "x": 22,
+        "y": 0
+      }
+    ],
+    "482": [
+      {
+        "x": 23,
+        "y": 0
+      }
+    ],
+    "490": [
+      {
+        "x": 24,
+        "y": 0
+      }
+    ],
+    "537": [
+      {
+        "x": 25,
+        "y": 0
+      }
+    ],
+    "544": [
+      {
+        "x": 26,
+        "y": 0
+      }
+    ],
+    "592": [
+      {
+        "x": 27,
+        "y": 0
+      }
+    ],
+    "599": [
+      {
+        "x": 28,
+        "y": 0
+      }
+    ],
+    "647": [
+      {
+        "x": 29,
+        "y": 0
+      }
+    ],
+    "654": [
+      {
+        "x": 30,
+        "y": 0
+      }
+    ],
+    "679": [
+      {
+        "x": 31,
+        "y": 0
+      }
+    ],
+    "686": [
+      {
+        "x": 32,
+        "y": 0
+      }
+    ],
+    "733": [
+      {
+        "x": 33,
+        "y": 0
+      }
+    ],
+    "741": [
+      {
+        "x": 34,
+        "y": 0
+      }
+    ],
+    "788": [
+      {
+        "x": 35,
+        "y": 0
+      }
+    ],
+    "796": [
+      {
+        "x": 36,
+        "y": 0
+      }
+    ],
+    "843": [
+      {
+        "x": 37,
+        "y": 0
+      }
+    ],
+    "851": [
+      {
+        "x": 38,
+        "y": 0
+      }
+    ],
+    "877": [
+      {
+        "x": 39,
+        "y": 0
+      }
+    ],
+    "885": [
+      {
+        "x": 40,
+        "y": 0
+      }
+    ],
+    "932": [
+      {
+        "x": 41,
+        "y": 0
+      }
+    ],
+    "939": [
+      {
+        "x": 42,
+        "y": 0
+      }
+    ],
+    "987": [
+      {
+        "x": 43,
+        "y": 0
+      }
+    ],
+    "994": [
+      {
+        "x": 44,
+        "y": 0
+      }
+    ],
+    "1042": [
+      {
+        "x": 45,
+        "y": 0
+      }
+    ],
+    "1049": [
+      {
+        "x": 46,
+        "y": 0
+      }
+    ],
+    "1074": [
+      {
+        "x": 47,
+        "y": 0
+      }
+    ],
+    "1081": [
+      {
+        "x": 48,
+        "y": 0
+      }
+    ],
+    "1128": [
+      {
+        "x": 49,
+        "y": 0
+      }
+    ],
+    "1136": [
+      {
+        "x": 50,
+        "y": 0
+      }
+    ],
+    "1183": [
+      {
+        "x": 51,
+        "y": 0
+      }
+    ],
+    "1191": [
+      {
+        "x": 52,
+        "y": 0
+      }
+    ],
+    "1238": [
+      {
+        "x": 53,
+        "y": 0
+      }
+    ],
+    "1246": [
+      {
+        "x": 54,
+        "y": 0
+      }
+    ],
+    "1272": [
+      {
+        "x": 55,
+        "y": 0
+      }
+    ],
+    "1280": [
+      {
+        "x": 56,
+        "y": 0
+      }
+    ],
+    "1327": [
+      {
+        "x": 57,
+        "y": 0
+      }
+    ],
+    "1334": [
+      {
+        "x": 58,
+        "y": 0
+      }
+    ],
+    "1382": [
+      {
+        "x": 59,
+        "y": 0
+      }
+    ],
+    "1389": [
+      {
+        "x": 60,
+        "y": 0
+      }
+    ],
+    "1437": [
+      {
+        "x": 61,
+        "y": 0
+      }
+    ],
+    "337": [
+      {
+        "x": 17,
+        "y": 1
+      }
+    ],
+    "392": [
+      {
+        "x": 19,
+        "y": 1
+      }
+    ],
+    "447": [
+      {
+        "x": 21,
+        "y": 1
+      }
+    ],
+    "536": [
+      {
+        "x": 25,
+        "y": 1
+      }
+    ],
+    "591": [
+      {
+        "x": 27,
+        "y": 1
+      }
+    ],
+    "646": [
+      {
+        "x": 29,
+        "y": 1
+      }
+    ],
+    "732": [
+      {
+        "x": 33,
+        "y": 1
+      }
+    ],
+    "787": [
+      {
+        "x": 35,
+        "y": 1
+      }
+    ],
+    "842": [
+      {
+        "x": 37,
+        "y": 1
+      }
+    ],
+    "931": [
+      {
+        "x": 41,
+        "y": 1
+      }
+    ],
+    "986": [
+      {
+        "x": 43,
+        "y": 1
+      }
+    ],
+    "1041": [
+      {
+        "x": 45,
+        "y": 1
+      }
+    ],
+    "1127": [
+      {
+        "x": 49,
+        "y": 1
+      }
+    ],
+    "1182": [
+      {
+        "x": 51,
+        "y": 1
+      }
+    ],
+    "1237": [
+      {
+        "x": 53,
+        "y": 1
+      }
+    ],
+    "1326": [
+      {
+        "x": 57,
+        "y": 1
+      }
+    ],
+    "1381": [
+      {
+        "x": 59,
+        "y": 1
+      }
+    ],
+    "1436": [
+      {
+        "x": 61,
+        "y": 1
+      }
+    ],
+    "336": [
+      {
+        "x": 17,
+        "y": 2
+      }
+    ],
+    "391": [
+      {
+        "x": 19,
+        "y": 2
+      }
+    ],
+    "446": [
+      {
+        "x": 21,
+        "y": 2
+      }
+    ],
+    "481": [
+      {
+        "x": 23,
+        "y": 2
+      }
+    ],
+    "535": [
+      {
+        "x": 25,
+        "y": 2
+      }
+    ],
+    "590": [
+      {
+        "x": 27,
+        "y": 2
+      }
+    ],
+    "645": [
+      {
+        "x": 29,
+        "y": 2
+      }
+    ],
+    "678": [
+      {
+        "x": 31,
+        "y": 2
+      }
+    ],
+    "731": [
+      {
+        "x": 33,
+        "y": 2
+      }
+    ],
+    "786": [
+      {
+        "x": 35,
+        "y": 2
+      }
+    ],
+    "841": [
+      {
+        "x": 37,
+        "y": 2
+      }
+    ],
+    "876": [
+      {
+        "x": 39,
+        "y": 2
+      }
+    ],
+    "930": [
+      {
+        "x": 41,
+        "y": 2
+      }
+    ],
+    "985": [
+      {
+        "x": 43,
+        "y": 2
+      }
+    ],
+    "1040": [
+      {
+        "x": 45,
+        "y": 2
+      }
+    ],
+    "1073": [
+      {
+        "x": 47,
+        "y": 2
+      }
+    ],
+    "1126": [
+      {
+        "x": 49,
+        "y": 2
+      }
+    ],
+    "1181": [
+      {
+        "x": 51,
+        "y": 2
+      }
+    ],
+    "1236": [
+      {
+        "x": 53,
+        "y": 2
+      }
+    ],
+    "1271": [
+      {
+        "x": 55,
+        "y": 2
+      }
+    ],
+    "1325": [
+      {
+        "x": 57,
+        "y": 2
+      }
+    ],
+    "1380": [
+      {
+        "x": 59,
+        "y": 2
+      }
+    ],
+    "1435": [
+      {
+        "x": 61,
+        "y": 2
+      }
+    ],
+    "335": [
+      {
+        "x": 17,
+        "y": 3
+      }
+    ],
+    "390": [
+      {
+        "x": 19,
+        "y": 3
+      }
+    ],
+    "445": [
+      {
+        "x": 21,
+        "y": 3
+      }
+    ],
+    "480": [
+      {
+        "x": 23,
+        "y": 3
+      }
+    ],
+    "534": [
+      {
+        "x": 25,
+        "y": 3
+      }
+    ],
+    "589": [
+      {
+        "x": 27,
+        "y": 3
+      }
+    ],
+    "644": [
+      {
+        "x": 29,
+        "y": 3
+      }
+    ],
+    "677": [
+      {
+        "x": 31,
+        "y": 3
+      }
+    ],
+    "730": [
+      {
+        "x": 33,
+        "y": 3
+      }
+    ],
+    "785": [
+      {
+        "x": 35,
+        "y": 3
+      }
+    ],
+    "840": [
+      {
+        "x": 37,
+        "y": 3
+      }
+    ],
+    "875": [
+      {
+        "x": 39,
+        "y": 3
+      }
+    ],
+    "929": [
+      {
+        "x": 41,
+        "y": 3
+      }
+    ],
+    "984": [
+      {
+        "x": 43,
+        "y": 3
+      }
+    ],
+    "1039": [
+      {
+        "x": 45,
+        "y": 3
+      }
+    ],
+    "1072": [
+      {
+        "x": 47,
+        "y": 3
+      }
+    ],
+    "1125": [
+      {
+        "x": 49,
+        "y": 3
+      }
+    ],
+    "1180": [
+      {
+        "x": 51,
+        "y": 3
+      }
+    ],
+    "1235": [
+      {
+        "x": 53,
+        "y": 3
+      }
+    ],
+    "1270": [
+      {
+        "x": 55,
+        "y": 3
+      }
+    ],
+    "1324": [
+      {
+        "x": 57,
+        "y": 3
+      }
+    ],
+    "1379": [
+      {
+        "x": 59,
+        "y": 3
+      }
+    ],
+    "1434": [
+      {
+        "x": 61,
+        "y": 3
+      }
+    ],
+    "334": [
+      {
+        "x": 17,
+        "y": 4
+      }
+    ],
+    "389": [
+      {
+        "x": 19,
+        "y": 4
+      }
+    ],
+    "444": [
+      {
+        "x": 21,
+        "y": 4
+      }
+    ],
+    "479": [
+      {
+        "x": 23,
+        "y": 4
+      }
+    ],
+    "533": [
+      {
+        "x": 25,
+        "y": 4
+      }
+    ],
+    "588": [
+      {
+        "x": 27,
+        "y": 4
+      }
+    ],
+    "643": [
+      {
+        "x": 29,
+        "y": 4
+      }
+    ],
+    "676": [
+      {
+        "x": 31,
+        "y": 4
+      }
+    ],
+    "729": [
+      {
+        "x": 33,
+        "y": 4
+      }
+    ],
+    "784": [
+      {
+        "x": 35,
+        "y": 4
+      }
+    ],
+    "839": [
+      {
+        "x": 37,
+        "y": 4
+      }
+    ],
+    "874": [
+      {
+        "x": 39,
+        "y": 4
+      }
+    ],
+    "928": [
+      {
+        "x": 41,
+        "y": 4
+      }
+    ],
+    "983": [
+      {
+        "x": 43,
+        "y": 4
+      }
+    ],
+    "1038": [
+      {
+        "x": 45,
+        "y": 4
+      }
+    ],
+    "1071": [
+      {
+        "x": 47,
+        "y": 4
+      }
+    ],
+    "1124": [
+      {
+        "x": 49,
+        "y": 4
+      }
+    ],
+    "1179": [
+      {
+        "x": 51,
+        "y": 4
+      }
+    ],
+    "1234": [
+      {
+        "x": 53,
+        "y": 4
+      }
+    ],
+    "1269": [
+      {
+        "x": 55,
+        "y": 4
+      }
+    ],
+    "1323": [
+      {
+        "x": 57,
+        "y": 4
+      }
+    ],
+    "1378": [
+      {
+        "x": 59,
+        "y": 4
+      }
+    ],
+    "1433": [
+      {
+        "x": 61,
+        "y": 4
+      }
+    ],
+    "333": [
+      {
+        "x": 17,
+        "y": 5
+      }
+    ],
+    "388": [
+      {
+        "x": 19,
+        "y": 5
+      }
+    ],
+    "443": [
+      {
+        "x": 21,
+        "y": 5
+      }
+    ],
+    "532": [
+      {
+        "x": 25,
+        "y": 5
+      }
+    ],
+    "587": [
+      {
+        "x": 27,
+        "y": 5
+      }
+    ],
+    "642": [
+      {
+        "x": 29,
+        "y": 5
+      }
+    ],
+    "728": [
+      {
+        "x": 33,
+        "y": 5
+      }
+    ],
+    "783": [
+      {
+        "x": 35,
+        "y": 5
+      }
+    ],
+    "838": [
+      {
+        "x": 37,
+        "y": 5
+      }
+    ],
+    "927": [
+      {
+        "x": 41,
+        "y": 5
+      }
+    ],
+    "982": [
+      {
+        "x": 43,
+        "y": 5
+      }
+    ],
+    "1037": [
+      {
+        "x": 45,
+        "y": 5
+      }
+    ],
+    "1123": [
+      {
+        "x": 49,
+        "y": 5
+      }
+    ],
+    "1178": [
+      {
+        "x": 51,
+        "y": 5
+      }
+    ],
+    "1233": [
+      {
+        "x": 53,
+        "y": 5
+      }
+    ],
+    "1322": [
+      {
+        "x": 57,
+        "y": 5
+      }
+    ],
+    "1377": [
+      {
+        "x": 59,
+        "y": 5
+      }
+    ],
+    "1432": [
+      {
+        "x": 61,
+        "y": 5
+      }
+    ],
+    "332": [
+      {
+        "x": 17,
+        "y": 6
+      }
+    ],
+    "345": [
+      {
+        "x": 18,
+        "y": 6
+      }
+    ],
+    "387": [
+      {
+        "x": 19,
+        "y": 6
+      }
+    ],
+    "400": [
+      {
+        "x": 20,
+        "y": 6
+      }
+    ],
+    "442": [
+      {
+        "x": 21,
+        "y": 6
+      }
+    ],
+    "455": [
+      {
+        "x": 22,
+        "y": 6
+      }
+    ],
+    "478": [
+      {
+        "x": 23,
+        "y": 6
+      }
+    ],
+    "489": [
+      {
+        "x": 24,
+        "y": 6
+      }
+    ],
+    "531": [
+      {
+        "x": 25,
+        "y": 6
+      }
+    ],
+    "543": [
+      {
+        "x": 26,
+        "y": 6
+      }
+    ],
+    "586": [
+      {
+        "x": 27,
+        "y": 6
+      }
+    ],
+    "598": [
+      {
+        "x": 28,
+        "y": 6
+      }
+    ],
+    "641": [
+      {
+        "x": 29,
+        "y": 6
+      }
+    ],
+    "653": [
+      {
+        "x": 30,
+        "y": 6
+      }
+    ],
+    "675": [
+      {
+        "x": 31,
+        "y": 6
+      }
+    ],
+    "685": [
+      {
+        "x": 32,
+        "y": 6
+      }
+    ],
+    "727": [
+      {
+        "x": 33,
+        "y": 6
+      }
+    ],
+    "740": [
+      {
+        "x": 34,
+        "y": 6
+      }
+    ],
+    "782": [
+      {
+        "x": 35,
+        "y": 6
+      }
+    ],
+    "795": [
+      {
+        "x": 36,
+        "y": 6
+      }
+    ],
+    "837": [
+      {
+        "x": 37,
+        "y": 6
+      }
+    ],
+    "850": [
+      {
+        "x": 38,
+        "y": 6
+      }
+    ],
+    "873": [
+      {
+        "x": 39,
+        "y": 6
+      }
+    ],
+    "884": [
+      {
+        "x": 40,
+        "y": 6
+      }
+    ],
+    "926": [
+      {
+        "x": 41,
+        "y": 6
+      }
+    ],
+    "938": [
+      {
+        "x": 42,
+        "y": 6
+      }
+    ],
+    "981": [
+      {
+        "x": 43,
+        "y": 6
+      }
+    ],
+    "993": [
+      {
+        "x": 44,
+        "y": 6
+      }
+    ],
+    "1036": [
+      {
+        "x": 45,
+        "y": 6
+      }
+    ],
+    "1048": [
+      {
+        "x": 46,
+        "y": 6
+      }
+    ],
+    "1070": [
+      {
+        "x": 47,
+        "y": 6
+      }
+    ],
+    "1080": [
+      {
+        "x": 48,
+        "y": 6
+      }
+    ],
+    "1122": [
+      {
+        "x": 49,
+        "y": 6
+      }
+    ],
+    "1135": [
+      {
+        "x": 50,
+        "y": 6
+      }
+    ],
+    "1177": [
+      {
+        "x": 51,
+        "y": 6
+      }
+    ],
+    "1190": [
+      {
+        "x": 52,
+        "y": 6
+      }
+    ],
+    "1232": [
+      {
+        "x": 53,
+        "y": 6
+      }
+    ],
+    "1245": [
+      {
+        "x": 54,
+        "y": 6
+      }
+    ],
+    "1268": [
+      {
+        "x": 55,
+        "y": 6
+      }
+    ],
+    "1279": [
+      {
+        "x": 56,
+        "y": 6
+      }
+    ],
+    "1321": [
+      {
+        "x": 57,
+        "y": 6
+      }
+    ],
+    "1333": [
+      {
+        "x": 58,
+        "y": 6
+      }
+    ],
+    "1376": [
+      {
+        "x": 59,
+        "y": 6
+      }
+    ],
+    "1388": [
+      {
+        "x": 60,
+        "y": 6
+      }
+    ],
+    "1431": [
+      {
+        "x": 61,
+        "y": 6
+      }
+    ],
+    "331": [
+      {
+        "x": 17,
+        "y": 7
+      }
+    ],
+    "386": [
+      {
+        "x": 19,
+        "y": 7
+      }
+    ],
+    "441": [
+      {
+        "x": 21,
+        "y": 7
+      }
+    ],
+    "530": [
+      {
+        "x": 25,
+        "y": 7
+      }
+    ],
+    "585": [
+      {
+        "x": 27,
+        "y": 7
+      }
+    ],
+    "640": [
+      {
+        "x": 29,
+        "y": 7
+      }
+    ],
+    "726": [
+      {
+        "x": 33,
+        "y": 7
+      }
+    ],
+    "781": [
+      {
+        "x": 35,
+        "y": 7
+      }
+    ],
+    "836": [
+      {
+        "x": 37,
+        "y": 7
+      }
+    ],
+    "925": [
+      {
+        "x": 41,
+        "y": 7
+      }
+    ],
+    "980": [
+      {
+        "x": 43,
+        "y": 7
+      }
+    ],
+    "1035": [
+      {
+        "x": 45,
+        "y": 7
+      }
+    ],
+    "1121": [
+      {
+        "x": 49,
+        "y": 7
+      }
+    ],
+    "1176": [
+      {
+        "x": 51,
+        "y": 7
+      }
+    ],
+    "1231": [
+      {
+        "x": 53,
+        "y": 7
+      }
+    ],
+    "1320": [
+      {
+        "x": 57,
+        "y": 7
+      }
+    ],
+    "1375": [
+      {
+        "x": 59,
+        "y": 7
+      }
+    ],
+    "1430": [
+      {
+        "x": 61,
+        "y": 7
+      }
+    ],
+    "330": [
+      {
+        "x": 17,
+        "y": 8
+      }
+    ],
+    "385": [
+      {
+        "x": 19,
+        "y": 8
+      }
+    ],
+    "440": [
+      {
+        "x": 21,
+        "y": 8
+      }
+    ],
+    "477": [
+      {
+        "x": 23,
+        "y": 8
+      }
+    ],
+    "529": [
+      {
+        "x": 25,
+        "y": 8
+      }
+    ],
+    "584": [
+      {
+        "x": 27,
+        "y": 8
+      }
+    ],
+    "639": [
+      {
+        "x": 29,
+        "y": 8
+      }
+    ],
+    "674": [
+      {
+        "x": 31,
+        "y": 8
+      }
+    ],
+    "725": [
+      {
+        "x": 33,
+        "y": 8
+      }
+    ],
+    "780": [
+      {
+        "x": 35,
+        "y": 8
+      }
+    ],
+    "835": [
+      {
+        "x": 37,
+        "y": 8
+      }
+    ],
+    "872": [
+      {
+        "x": 39,
+        "y": 8
+      }
+    ],
+    "924": [
+      {
+        "x": 41,
+        "y": 8
+      }
+    ],
+    "979": [
+      {
+        "x": 43,
+        "y": 8
+      }
+    ],
+    "1034": [
+      {
+        "x": 45,
+        "y": 8
+      }
+    ],
+    "1069": [
+      {
+        "x": 47,
+        "y": 8
+      }
+    ],
+    "1120": [
+      {
+        "x": 49,
+        "y": 8
+      }
+    ],
+    "1175": [
+      {
+        "x": 51,
+        "y": 8
+      }
+    ],
+    "1230": [
+      {
+        "x": 53,
+        "y": 8
+      }
+    ],
+    "1267": [
+      {
+        "x": 55,
+        "y": 8
+      }
+    ],
+    "1319": [
+      {
+        "x": 57,
+        "y": 8
+      }
+    ],
+    "1374": [
+      {
+        "x": 59,
+        "y": 8
+      }
+    ],
+    "1429": [
+      {
+        "x": 61,
+        "y": 8
+      }
+    ],
+    "329": [
+      {
+        "x": 17,
+        "y": 9
+      }
+    ],
+    "384": [
+      {
+        "x": 19,
+        "y": 9
+      }
+    ],
+    "439": [
+      {
+        "x": 21,
+        "y": 9
+      }
+    ],
+    "476": [
+      {
+        "x": 23,
+        "y": 9
+      }
+    ],
+    "528": [
+      {
+        "x": 25,
+        "y": 9
+      }
+    ],
+    "583": [
+      {
+        "x": 27,
+        "y": 9
+      }
+    ],
+    "638": [
+      {
+        "x": 29,
+        "y": 9
+      }
+    ],
+    "673": [
+      {
+        "x": 31,
+        "y": 9
+      }
+    ],
+    "724": [
+      {
+        "x": 33,
+        "y": 9
+      }
+    ],
+    "779": [
+      {
+        "x": 35,
+        "y": 9
+      }
+    ],
+    "834": [
+      {
+        "x": 37,
+        "y": 9
+      }
+    ],
+    "871": [
+      {
+        "x": 39,
+        "y": 9
+      }
+    ],
+    "923": [
+      {
+        "x": 41,
+        "y": 9
+      }
+    ],
+    "978": [
+      {
+        "x": 43,
+        "y": 9
+      }
+    ],
+    "1033": [
+      {
+        "x": 45,
+        "y": 9
+      }
+    ],
+    "1068": [
+      {
+        "x": 47,
+        "y": 9
+      }
+    ],
+    "1119": [
+      {
+        "x": 49,
+        "y": 9
+      }
+    ],
+    "1174": [
+      {
+        "x": 51,
+        "y": 9
+      }
+    ],
+    "1229": [
+      {
+        "x": 53,
+        "y": 9
+      }
+    ],
+    "1266": [
+      {
+        "x": 55,
+        "y": 9
+      }
+    ],
+    "1318": [
+      {
+        "x": 57,
+        "y": 9
+      }
+    ],
+    "1373": [
+      {
+        "x": 59,
+        "y": 9
+      }
+    ],
+    "1428": [
+      {
+        "x": 61,
+        "y": 9
+      }
+    ],
+    "328": [
+      {
+        "x": 17,
+        "y": 10
+      }
+    ],
+    "383": [
+      {
+        "x": 19,
+        "y": 10
+      }
+    ],
+    "438": [
+      {
+        "x": 21,
+        "y": 10
+      }
+    ],
+    "475": [
+      {
+        "x": 23,
+        "y": 10
+      }
+    ],
+    "527": [
+      {
+        "x": 25,
+        "y": 10
+      }
+    ],
+    "582": [
+      {
+        "x": 27,
+        "y": 10
+      }
+    ],
+    "637": [
+      {
+        "x": 29,
+        "y": 10
+      }
+    ],
+    "672": [
+      {
+        "x": 31,
+        "y": 10
+      }
+    ],
+    "723": [
+      {
+        "x": 33,
+        "y": 10
+      }
+    ],
+    "778": [
+      {
+        "x": 35,
+        "y": 10
+      }
+    ],
+    "833": [
+      {
+        "x": 37,
+        "y": 10
+      }
+    ],
+    "870": [
+      {
+        "x": 39,
+        "y": 10
+      }
+    ],
+    "922": [
+      {
+        "x": 41,
+        "y": 10
+      }
+    ],
+    "977": [
+      {
+        "x": 43,
+        "y": 10
+      }
+    ],
+    "1032": [
+      {
+        "x": 45,
+        "y": 10
+      }
+    ],
+    "1067": [
+      {
+        "x": 47,
+        "y": 10
+      }
+    ],
+    "1118": [
+      {
+        "x": 49,
+        "y": 10
+      }
+    ],
+    "1173": [
+      {
+        "x": 51,
+        "y": 10
+      }
+    ],
+    "1228": [
+      {
+        "x": 53,
+        "y": 10
+      }
+    ],
+    "1265": [
+      {
+        "x": 55,
+        "y": 10
+      }
+    ],
+    "1317": [
+      {
+        "x": 57,
+        "y": 10
+      }
+    ],
+    "1372": [
+      {
+        "x": 59,
+        "y": 10
+      }
+    ],
+    "1427": [
+      {
+        "x": 61,
+        "y": 10
+      }
+    ],
+    "327": [
+      {
+        "x": 17,
+        "y": 11
+      }
+    ],
+    "382": [
+      {
+        "x": 19,
+        "y": 11
+      }
+    ],
+    "437": [
+      {
+        "x": 21,
+        "y": 11
+      }
+    ],
+    "526": [
+      {
+        "x": 25,
+        "y": 11
+      }
+    ],
+    "581": [
+      {
+        "x": 27,
+        "y": 11
+      }
+    ],
+    "636": [
+      {
+        "x": 29,
+        "y": 11
+      }
+    ],
+    "722": [
+      {
+        "x": 33,
+        "y": 11
+      }
+    ],
+    "777": [
+      {
+        "x": 35,
+        "y": 11
+      }
+    ],
+    "832": [
+      {
+        "x": 37,
+        "y": 11
+      }
+    ],
+    "921": [
+      {
+        "x": 41,
+        "y": 11
+      }
+    ],
+    "976": [
+      {
+        "x": 43,
+        "y": 11
+      }
+    ],
+    "1031": [
+      {
+        "x": 45,
+        "y": 11
+      }
+    ],
+    "1117": [
+      {
+        "x": 49,
+        "y": 11
+      }
+    ],
+    "1172": [
+      {
+        "x": 51,
+        "y": 11
+      }
+    ],
+    "1227": [
+      {
+        "x": 53,
+        "y": 11
+      }
+    ],
+    "1316": [
+      {
+        "x": 57,
+        "y": 11
+      }
+    ],
+    "1371": [
+      {
+        "x": 59,
+        "y": 11
+      }
+    ],
+    "1426": [
+      {
+        "x": 61,
+        "y": 11
+      }
+    ],
+    "35": [
+      {
+        "x": 1,
+        "y": 12
+      }
+    ],
+    "41": [
+      {
+        "x": 2,
+        "y": 12
+      }
+    ],
+    "76": [
+      {
+        "x": 3,
+        "y": 12
+      }
+    ],
+    "82": [
+      {
+        "x": 4,
+        "y": 12
+      }
+    ],
+    "117": [
+      {
+        "x": 5,
+        "y": 12
+      }
+    ],
+    "123": [
+      {
+        "x": 6,
+        "y": 12
+      }
+    ],
+    "141": [
+      {
+        "x": 7,
+        "y": 12
+      }
+    ],
+    "147": [
+      {
+        "x": 8,
+        "y": 12
+      }
+    ],
+    "182": [
+      {
+        "x": 9,
+        "y": 12
+      }
+    ],
+    "187": [
+      {
+        "x": 10,
+        "y": 12
+      }
+    ],
+    "223": [
+      {
+        "x": 11,
+        "y": 12
+      }
+    ],
+    "228": [
+      {
+        "x": 12,
+        "y": 12
+      }
+    ],
+    "264": [
+      {
+        "x": 13,
+        "y": 12
+      }
+    ],
+    "269": [
+      {
+        "x": 14,
+        "y": 12
+      }
+    ],
+    "286": [
+      {
+        "x": 15,
+        "y": 12
+      }
+    ],
+    "291": [
+      {
+        "x": 16,
+        "y": 12
+      }
+    ],
+    "326": [
+      {
+        "x": 17,
+        "y": 12
+      }
+    ],
+    "344": [
+      {
+        "x": 18,
+        "y": 12
+      }
+    ],
+    "381": [
+      {
+        "x": 19,
+        "y": 12
+      }
+    ],
+    "399": [
+      {
+        "x": 20,
+        "y": 12
+      }
+    ],
+    "436": [
+      {
+        "x": 21,
+        "y": 12
+      }
+    ],
+    "454": [
+      {
+        "x": 22,
+        "y": 12
+      }
+    ],
+    "474": [
+      {
+        "x": 23,
+        "y": 12
+      }
+    ],
+    "488": [
+      {
+        "x": 24,
+        "y": 12
+      }
+    ],
+    "525": [
+      {
+        "x": 25,
+        "y": 12
+      }
+    ],
+    "542": [
+      {
+        "x": 26,
+        "y": 12
+      }
+    ],
+    "580": [
+      {
+        "x": 27,
+        "y": 12
+      }
+    ],
+    "597": [
+      {
+        "x": 28,
+        "y": 12
+      }
+    ],
+    "635": [
+      {
+        "x": 29,
+        "y": 12
+      }
+    ],
+    "652": [
+      {
+        "x": 30,
+        "y": 12
+      }
+    ],
+    "671": [
+      {
+        "x": 31,
+        "y": 12
+      }
+    ],
+    "684": [
+      {
+        "x": 32,
+        "y": 12
+      }
+    ],
+    "721": [
+      {
+        "x": 33,
+        "y": 12
+      }
+    ],
+    "739": [
+      {
+        "x": 34,
+        "y": 12
+      }
+    ],
+    "776": [
+      {
+        "x": 35,
+        "y": 12
+      }
+    ],
+    "794": [
+      {
+        "x": 36,
+        "y": 12
+      }
+    ],
+    "831": [
+      {
+        "x": 37,
+        "y": 12
+      }
+    ],
+    "849": [
+      {
+        "x": 38,
+        "y": 12
+      }
+    ],
+    "869": [
+      {
+        "x": 39,
+        "y": 12
+      }
+    ],
+    "883": [
+      {
+        "x": 40,
+        "y": 12
+      }
+    ],
+    "920": [
+      {
+        "x": 41,
+        "y": 12
+      }
+    ],
+    "937": [
+      {
+        "x": 42,
+        "y": 12
+      }
+    ],
+    "975": [
+      {
+        "x": 43,
+        "y": 12
+      }
+    ],
+    "992": [
+      {
+        "x": 44,
+        "y": 12
+      }
+    ],
+    "1030": [
+      {
+        "x": 45,
+        "y": 12
+      }
+    ],
+    "1047": [
+      {
+        "x": 46,
+        "y": 12
+      }
+    ],
+    "1066": [
+      {
+        "x": 47,
+        "y": 12
+      }
+    ],
+    "1079": [
+      {
+        "x": 48,
+        "y": 12
+      }
+    ],
+    "1116": [
+      {
+        "x": 49,
+        "y": 12
+      }
+    ],
+    "1134": [
+      {
+        "x": 50,
+        "y": 12
+      }
+    ],
+    "1171": [
+      {
+        "x": 51,
+        "y": 12
+      }
+    ],
+    "1189": [
+      {
+        "x": 52,
+        "y": 12
+      }
+    ],
+    "1226": [
+      {
+        "x": 53,
+        "y": 12
+      }
+    ],
+    "1244": [
+      {
+        "x": 54,
+        "y": 12
+      }
+    ],
+    "1264": [
+      {
+        "x": 55,
+        "y": 12
+      }
+    ],
+    "1278": [
+      {
+        "x": 56,
+        "y": 12
+      }
+    ],
+    "1315": [
+      {
+        "x": 57,
+        "y": 12
+      }
+    ],
+    "1332": [
+      {
+        "x": 58,
+        "y": 12
+      }
+    ],
+    "1370": [
+      {
+        "x": 59,
+        "y": 12
+      }
+    ],
+    "1387": [
+      {
+        "x": 60,
+        "y": 12
+      }
+    ],
+    "1425": [
+      {
+        "x": 61,
+        "y": 12
+      }
+    ],
+    "1442": [
+      {
+        "x": 62,
+        "y": 12
+      }
+    ],
+    "1459": [
+      {
+        "x": 63,
+        "y": 12
+      }
+    ],
+    "1464": [
+      {
+        "x": 64,
+        "y": 12
+      }
+    ],
+    "1499": [
+      {
+        "x": 65,
+        "y": 12
+      }
+    ],
+    "1505": [
+      {
+        "x": 66,
+        "y": 12
+      }
+    ],
+    "1540": [
+      {
+        "x": 67,
+        "y": 12
+      }
+    ],
+    "1546": [
+      {
+        "x": 68,
+        "y": 12
+      }
+    ],
+    "1581": [
+      {
+        "x": 69,
+        "y": 12
+      }
+    ],
+    "1587": [
+      {
+        "x": 70,
+        "y": 12
+      }
+    ],
+    "1605": [
+      {
+        "x": 71,
+        "y": 12
+      }
+    ],
+    "1611": [
+      {
+        "x": 72,
+        "y": 12
+      }
+    ],
+    "1646": [
+      {
+        "x": 73,
+        "y": 12
+      }
+    ],
+    "1651": [
+      {
+        "x": 74,
+        "y": 12
+      }
+    ],
+    "1687": [
+      {
+        "x": 75,
+        "y": 12
+      }
+    ],
+    "34": [
+      {
+        "x": 1,
+        "y": 13
+      }
+    ],
+    "75": [
+      {
+        "x": 3,
+        "y": 13
+      }
+    ],
+    "116": [
+      {
+        "x": 5,
+        "y": 13
+      }
+    ],
+    "181": [
+      {
+        "x": 9,
+        "y": 13
+      }
+    ],
+    "222": [
+      {
+        "x": 11,
+        "y": 13
+      }
+    ],
+    "263": [
+      {
+        "x": 13,
+        "y": 13
+      }
+    ],
+    "325": [
+      {
+        "x": 17,
+        "y": 13
+      }
+    ],
+    "380": [
+      {
+        "x": 19,
+        "y": 13
+      }
+    ],
+    "435": [
+      {
+        "x": 21,
+        "y": 13
+      }
+    ],
+    "524": [
+      {
+        "x": 25,
+        "y": 13
+      }
+    ],
+    "579": [
+      {
+        "x": 27,
+        "y": 13
+      }
+    ],
+    "634": [
+      {
+        "x": 29,
+        "y": 13
+      }
+    ],
+    "720": [
+      {
+        "x": 33,
+        "y": 13
+      }
+    ],
+    "775": [
+      {
+        "x": 35,
+        "y": 13
+      }
+    ],
+    "830": [
+      {
+        "x": 37,
+        "y": 13
+      }
+    ],
+    "919": [
+      {
+        "x": 41,
+        "y": 13
+      }
+    ],
+    "974": [
+      {
+        "x": 43,
+        "y": 13
+      }
+    ],
+    "1029": [
+      {
+        "x": 45,
+        "y": 13
+      }
+    ],
+    "1115": [
+      {
+        "x": 49,
+        "y": 13
+      }
+    ],
+    "1170": [
+      {
+        "x": 51,
+        "y": 13
+      }
+    ],
+    "1225": [
+      {
+        "x": 53,
+        "y": 13
+      }
+    ],
+    "1314": [
+      {
+        "x": 57,
+        "y": 13
+      }
+    ],
+    "1369": [
+      {
+        "x": 59,
+        "y": 13
+      }
+    ],
+    "1424": [
+      {
+        "x": 61,
+        "y": 13
+      }
+    ],
+    "1498": [
+      {
+        "x": 65,
+        "y": 13
+      }
+    ],
+    "1539": [
+      {
+        "x": 67,
+        "y": 13
+      }
+    ],
+    "1580": [
+      {
+        "x": 69,
+        "y": 13
+      }
+    ],
+    "1645": [
+      {
+        "x": 73,
+        "y": 13
+      }
+    ],
+    "1686": [
+      {
+        "x": 75,
+        "y": 13
+      }
+    ],
+    "33": [
+      {
+        "x": 1,
+        "y": 14
+      }
+    ],
+    "74": [
+      {
+        "x": 3,
+        "y": 14
+      }
+    ],
+    "115": [
+      {
+        "x": 5,
+        "y": 14
+      }
+    ],
+    "140": [
+      {
+        "x": 7,
+        "y": 14
+      }
+    ],
+    "180": [
+      {
+        "x": 9,
+        "y": 14
+      }
+    ],
+    "221": [
+      {
+        "x": 11,
+        "y": 14
+      }
+    ],
+    "262": [
+      {
+        "x": 13,
+        "y": 14
+      }
+    ],
+    "285": [
+      {
+        "x": 15,
+        "y": 14
+      }
+    ],
+    "324": [
+      {
+        "x": 17,
+        "y": 14
+      }
+    ],
+    "379": [
+      {
+        "x": 19,
+        "y": 14
+      }
+    ],
+    "434": [
+      {
+        "x": 21,
+        "y": 14
+      }
+    ],
+    "473": [
+      {
+        "x": 23,
+        "y": 14
+      }
+    ],
+    "523": [
+      {
+        "x": 25,
+        "y": 14
+      }
+    ],
+    "578": [
+      {
+        "x": 27,
+        "y": 14
+      }
+    ],
+    "633": [
+      {
+        "x": 29,
+        "y": 14
+      }
+    ],
+    "670": [
+      {
+        "x": 31,
+        "y": 14
+      }
+    ],
+    "719": [
+      {
+        "x": 33,
+        "y": 14
+      }
+    ],
+    "774": [
+      {
+        "x": 35,
+        "y": 14
+      }
+    ],
+    "829": [
+      {
+        "x": 37,
+        "y": 14
+      }
+    ],
+    "868": [
+      {
+        "x": 39,
+        "y": 14
+      }
+    ],
+    "918": [
+      {
+        "x": 41,
+        "y": 14
+      }
+    ],
+    "973": [
+      {
+        "x": 43,
+        "y": 14
+      }
+    ],
+    "1028": [
+      {
+        "x": 45,
+        "y": 14
+      }
+    ],
+    "1065": [
+      {
+        "x": 47,
+        "y": 14
+      }
+    ],
+    "1114": [
+      {
+        "x": 49,
+        "y": 14
+      }
+    ],
+    "1169": [
+      {
+        "x": 51,
+        "y": 14
+      }
+    ],
+    "1224": [
+      {
+        "x": 53,
+        "y": 14
+      }
+    ],
+    "1263": [
+      {
+        "x": 55,
+        "y": 14
+      }
+    ],
+    "1313": [
+      {
+        "x": 57,
+        "y": 14
+      }
+    ],
+    "1368": [
+      {
+        "x": 59,
+        "y": 14
+      }
+    ],
+    "1423": [
+      {
+        "x": 61,
+        "y": 14
+      }
+    ],
+    "1458": [
+      {
+        "x": 63,
+        "y": 14
+      }
+    ],
+    "1497": [
+      {
+        "x": 65,
+        "y": 14
+      }
+    ],
+    "1538": [
+      {
+        "x": 67,
+        "y": 14
+      }
+    ],
+    "1579": [
+      {
+        "x": 69,
+        "y": 14
+      }
+    ],
+    "1604": [
+      {
+        "x": 71,
+        "y": 14
+      }
+    ],
+    "1644": [
+      {
+        "x": 73,
+        "y": 14
+      }
+    ],
+    "1685": [
+      {
+        "x": 75,
+        "y": 14
+      }
+    ],
+    "32": [
+      {
+        "x": 1,
+        "y": 15
+      }
+    ],
+    "73": [
+      {
+        "x": 3,
+        "y": 15
+      }
+    ],
+    "114": [
+      {
+        "x": 5,
+        "y": 15
+      }
+    ],
+    "179": [
+      {
+        "x": 9,
+        "y": 15
+      }
+    ],
+    "220": [
+      {
+        "x": 11,
+        "y": 15
+      }
+    ],
+    "261": [
+      {
+        "x": 13,
+        "y": 15
+      }
+    ],
+    "323": [
+      {
+        "x": 17,
+        "y": 15
+      }
+    ],
+    "378": [
+      {
+        "x": 19,
+        "y": 15
+      }
+    ],
+    "433": [
+      {
+        "x": 21,
+        "y": 15
+      }
+    ],
+    "522": [
+      {
+        "x": 25,
+        "y": 15
+      }
+    ],
+    "577": [
+      {
+        "x": 27,
+        "y": 15
+      }
+    ],
+    "632": [
+      {
+        "x": 29,
+        "y": 15
+      }
+    ],
+    "718": [
+      {
+        "x": 33,
+        "y": 15
+      }
+    ],
+    "773": [
+      {
+        "x": 35,
+        "y": 15
+      }
+    ],
+    "828": [
+      {
+        "x": 37,
+        "y": 15
+      }
+    ],
+    "917": [
+      {
+        "x": 41,
+        "y": 15
+      }
+    ],
+    "972": [
+      {
+        "x": 43,
+        "y": 15
+      }
+    ],
+    "1027": [
+      {
+        "x": 45,
+        "y": 15
+      }
+    ],
+    "1113": [
+      {
+        "x": 49,
+        "y": 15
+      }
+    ],
+    "1168": [
+      {
+        "x": 51,
+        "y": 15
+      }
+    ],
+    "1223": [
+      {
+        "x": 53,
+        "y": 15
+      }
+    ],
+    "1312": [
+      {
+        "x": 57,
+        "y": 15
+      }
+    ],
+    "1367": [
+      {
+        "x": 59,
+        "y": 15
+      }
+    ],
+    "1422": [
+      {
+        "x": 61,
+        "y": 15
+      }
+    ],
+    "1496": [
+      {
+        "x": 65,
+        "y": 15
+      }
+    ],
+    "1537": [
+      {
+        "x": 67,
+        "y": 15
+      }
+    ],
+    "1578": [
+      {
+        "x": 69,
+        "y": 15
+      }
+    ],
+    "1643": [
+      {
+        "x": 73,
+        "y": 15
+      }
+    ],
+    "1684": [
+      {
+        "x": 75,
+        "y": 15
+      }
+    ],
+    "31": [
+      {
+        "x": 1,
+        "y": 16
+      }
+    ],
+    "72": [
+      {
+        "x": 3,
+        "y": 16
+      }
+    ],
+    "113": [
+      {
+        "x": 5,
+        "y": 16
+      }
+    ],
+    "139": [
+      {
+        "x": 7,
+        "y": 16
+      }
+    ],
+    "178": [
+      {
+        "x": 9,
+        "y": 16
+      }
+    ],
+    "219": [
+      {
+        "x": 11,
+        "y": 16
+      }
+    ],
+    "260": [
+      {
+        "x": 13,
+        "y": 16
+      }
+    ],
+    "284": [
+      {
+        "x": 15,
+        "y": 16
+      }
+    ],
+    "322": [
+      {
+        "x": 17,
+        "y": 16
+      }
+    ],
+    "377": [
+      {
+        "x": 19,
+        "y": 16
+      }
+    ],
+    "432": [
+      {
+        "x": 21,
+        "y": 16
+      }
+    ],
+    "472": [
+      {
+        "x": 23,
+        "y": 16
+      }
+    ],
+    "521": [
+      {
+        "x": 25,
+        "y": 16
+      }
+    ],
+    "576": [
+      {
+        "x": 27,
+        "y": 16
+      }
+    ],
+    "631": [
+      {
+        "x": 29,
+        "y": 16
+      }
+    ],
+    "669": [
+      {
+        "x": 31,
+        "y": 16
+      }
+    ],
+    "717": [
+      {
+        "x": 33,
+        "y": 16
+      }
+    ],
+    "772": [
+      {
+        "x": 35,
+        "y": 16
+      }
+    ],
+    "827": [
+      {
+        "x": 37,
+        "y": 16
+      }
+    ],
+    "867": [
+      {
+        "x": 39,
+        "y": 16
+      }
+    ],
+    "916": [
+      {
+        "x": 41,
+        "y": 16
+      }
+    ],
+    "971": [
+      {
+        "x": 43,
+        "y": 16
+      }
+    ],
+    "1026": [
+      {
+        "x": 45,
+        "y": 16
+      }
+    ],
+    "1064": [
+      {
+        "x": 47,
+        "y": 16
+      }
+    ],
+    "1112": [
+      {
+        "x": 49,
+        "y": 16
+      }
+    ],
+    "1167": [
+      {
+        "x": 51,
+        "y": 16
+      }
+    ],
+    "1222": [
+      {
+        "x": 53,
+        "y": 16
+      }
+    ],
+    "1262": [
+      {
+        "x": 55,
+        "y": 16
+      }
+    ],
+    "1311": [
+      {
+        "x": 57,
+        "y": 16
+      }
+    ],
+    "1366": [
+      {
+        "x": 59,
+        "y": 16
+      }
+    ],
+    "1421": [
+      {
+        "x": 61,
+        "y": 16
+      }
+    ],
+    "1457": [
+      {
+        "x": 63,
+        "y": 16
+      }
+    ],
+    "1495": [
+      {
+        "x": 65,
+        "y": 16
+      }
+    ],
+    "1536": [
+      {
+        "x": 67,
+        "y": 16
+      }
+    ],
+    "1577": [
+      {
+        "x": 69,
+        "y": 16
+      }
+    ],
+    "1603": [
+      {
+        "x": 71,
+        "y": 16
+      }
+    ],
+    "1642": [
+      {
+        "x": 73,
+        "y": 16
+      }
+    ],
+    "1683": [
+      {
+        "x": 75,
+        "y": 16
+      }
+    ],
+    "30": [
+      {
+        "x": 1,
+        "y": 17
+      }
+    ],
+    "71": [
+      {
+        "x": 3,
+        "y": 17
+      }
+    ],
+    "112": [
+      {
+        "x": 5,
+        "y": 17
+      }
+    ],
+    "138": [
+      {
+        "x": 7,
+        "y": 17
+      }
+    ],
+    "177": [
+      {
+        "x": 9,
+        "y": 17
+      }
+    ],
+    "218": [
+      {
+        "x": 11,
+        "y": 17
+      }
+    ],
+    "259": [
+      {
+        "x": 13,
+        "y": 17
+      }
+    ],
+    "283": [
+      {
+        "x": 15,
+        "y": 17
+      }
+    ],
+    "321": [
+      {
+        "x": 17,
+        "y": 17
+      }
+    ],
+    "376": [
+      {
+        "x": 19,
+        "y": 17
+      }
+    ],
+    "431": [
+      {
+        "x": 21,
+        "y": 17
+      }
+    ],
+    "471": [
+      {
+        "x": 23,
+        "y": 17
+      }
+    ],
+    "520": [
+      {
+        "x": 25,
+        "y": 17
+      }
+    ],
+    "575": [
+      {
+        "x": 27,
+        "y": 17
+      }
+    ],
+    "630": [
+      {
+        "x": 29,
+        "y": 17
+      }
+    ],
+    "668": [
+      {
+        "x": 31,
+        "y": 17
+      }
+    ],
+    "716": [
+      {
+        "x": 33,
+        "y": 17
+      }
+    ],
+    "771": [
+      {
+        "x": 35,
+        "y": 17
+      }
+    ],
+    "826": [
+      {
+        "x": 37,
+        "y": 17
+      }
+    ],
+    "866": [
+      {
+        "x": 39,
+        "y": 17
+      }
+    ],
+    "915": [
+      {
+        "x": 41,
+        "y": 17
+      }
+    ],
+    "970": [
+      {
+        "x": 43,
+        "y": 17
+      }
+    ],
+    "1025": [
+      {
+        "x": 45,
+        "y": 17
+      }
+    ],
+    "1063": [
+      {
+        "x": 47,
+        "y": 17
+      }
+    ],
+    "1111": [
+      {
+        "x": 49,
+        "y": 17
+      }
+    ],
+    "1166": [
+      {
+        "x": 51,
+        "y": 17
+      }
+    ],
+    "1221": [
+      {
+        "x": 53,
+        "y": 17
+      }
+    ],
+    "1261": [
+      {
+        "x": 55,
+        "y": 17
+      }
+    ],
+    "1310": [
+      {
+        "x": 57,
+        "y": 17
+      }
+    ],
+    "1365": [
+      {
+        "x": 59,
+        "y": 17
+      }
+    ],
+    "1420": [
+      {
+        "x": 61,
+        "y": 17
+      }
+    ],
+    "1456": [
+      {
+        "x": 63,
+        "y": 17
+      }
+    ],
+    "1494": [
+      {
+        "x": 65,
+        "y": 17
+      }
+    ],
+    "1535": [
+      {
+        "x": 67,
+        "y": 17
+      }
+    ],
+    "1576": [
+      {
+        "x": 69,
+        "y": 17
+      }
+    ],
+    "1602": [
+      {
+        "x": 71,
+        "y": 17
+      }
+    ],
+    "1641": [
+      {
+        "x": 73,
+        "y": 17
+      }
+    ],
+    "1682": [
+      {
+        "x": 75,
+        "y": 17
+      }
+    ],
+    "29": [
+      {
+        "x": 1,
+        "y": 18
+      }
+    ],
+    "70": [
+      {
+        "x": 3,
+        "y": 18
+      }
+    ],
+    "111": [
+      {
+        "x": 5,
+        "y": 18
+      }
+    ],
+    "137": [
+      {
+        "x": 7,
+        "y": 18
+      }
+    ],
+    "176": [
+      {
+        "x": 9,
+        "y": 18
+      }
+    ],
+    "217": [
+      {
+        "x": 11,
+        "y": 18
+      }
+    ],
+    "258": [
+      {
+        "x": 13,
+        "y": 18
+      }
+    ],
+    "282": [
+      {
+        "x": 15,
+        "y": 18
+      }
+    ],
+    "320": [
+      {
+        "x": 17,
+        "y": 18
+      }
+    ],
+    "375": [
+      {
+        "x": 19,
+        "y": 18
+      }
+    ],
+    "430": [
+      {
+        "x": 21,
+        "y": 18
+      }
+    ],
+    "470": [
+      {
+        "x": 23,
+        "y": 18
+      }
+    ],
+    "519": [
+      {
+        "x": 25,
+        "y": 18
+      }
+    ],
+    "574": [
+      {
+        "x": 27,
+        "y": 18
+      }
+    ],
+    "629": [
+      {
+        "x": 29,
+        "y": 18
+      }
+    ],
+    "667": [
+      {
+        "x": 31,
+        "y": 18
+      }
+    ],
+    "715": [
+      {
+        "x": 33,
+        "y": 18
+      }
+    ],
+    "770": [
+      {
+        "x": 35,
+        "y": 18
+      }
+    ],
+    "825": [
+      {
+        "x": 37,
+        "y": 18
+      }
+    ],
+    "865": [
+      {
+        "x": 39,
+        "y": 18
+      }
+    ],
+    "914": [
+      {
+        "x": 41,
+        "y": 18
+      }
+    ],
+    "969": [
+      {
+        "x": 43,
+        "y": 18
+      }
+    ],
+    "1024": [
+      {
+        "x": 45,
+        "y": 18
+      }
+    ],
+    "1062": [
+      {
+        "x": 47,
+        "y": 18
+      }
+    ],
+    "1110": [
+      {
+        "x": 49,
+        "y": 18
+      }
+    ],
+    "1165": [
+      {
+        "x": 51,
+        "y": 18
+      }
+    ],
+    "1220": [
+      {
+        "x": 53,
+        "y": 18
+      }
+    ],
+    "1260": [
+      {
+        "x": 55,
+        "y": 18
+      }
+    ],
+    "1309": [
+      {
+        "x": 57,
+        "y": 18
+      }
+    ],
+    "1364": [
+      {
+        "x": 59,
+        "y": 18
+      }
+    ],
+    "1419": [
+      {
+        "x": 61,
+        "y": 18
+      }
+    ],
+    "1455": [
+      {
+        "x": 63,
+        "y": 18
+      }
+    ],
+    "1493": [
+      {
+        "x": 65,
+        "y": 18
+      }
+    ],
+    "1534": [
+      {
+        "x": 67,
+        "y": 18
+      }
+    ],
+    "1575": [
+      {
+        "x": 69,
+        "y": 18
+      }
+    ],
+    "1601": [
+      {
+        "x": 71,
+        "y": 18
+      }
+    ],
+    "1640": [
+      {
+        "x": 73,
+        "y": 18
+      }
+    ],
+    "1681": [
+      {
+        "x": 75,
+        "y": 18
+      }
+    ],
+    "28": [
+      {
+        "x": 1,
+        "y": 19
+      }
+    ],
+    "69": [
+      {
+        "x": 3,
+        "y": 19
+      }
+    ],
+    "110": [
+      {
+        "x": 5,
+        "y": 19
+      }
+    ],
+    "175": [
+      {
+        "x": 9,
+        "y": 19
+      }
+    ],
+    "216": [
+      {
+        "x": 11,
+        "y": 19
+      }
+    ],
+    "257": [
+      {
+        "x": 13,
+        "y": 19
+      }
+    ],
+    "319": [
+      {
+        "x": 17,
+        "y": 19
+      }
+    ],
+    "374": [
+      {
+        "x": 19,
+        "y": 19
+      }
+    ],
+    "429": [
+      {
+        "x": 21,
+        "y": 19
+      }
+    ],
+    "518": [
+      {
+        "x": 25,
+        "y": 19
+      }
+    ],
+    "573": [
+      {
+        "x": 27,
+        "y": 19
+      }
+    ],
+    "628": [
+      {
+        "x": 29,
+        "y": 19
+      }
+    ],
+    "714": [
+      {
+        "x": 33,
+        "y": 19
+      }
+    ],
+    "769": [
+      {
+        "x": 35,
+        "y": 19
+      }
+    ],
+    "824": [
+      {
+        "x": 37,
+        "y": 19
+      }
+    ],
+    "913": [
+      {
+        "x": 41,
+        "y": 19
+      }
+    ],
+    "968": [
+      {
+        "x": 43,
+        "y": 19
+      }
+    ],
+    "1023": [
+      {
+        "x": 45,
+        "y": 19
+      }
+    ],
+    "1109": [
+      {
+        "x": 49,
+        "y": 19
+      }
+    ],
+    "1164": [
+      {
+        "x": 51,
+        "y": 19
+      }
+    ],
+    "1219": [
+      {
+        "x": 53,
+        "y": 19
+      }
+    ],
+    "1308": [
+      {
+        "x": 57,
+        "y": 19
+      }
+    ],
+    "1363": [
+      {
+        "x": 59,
+        "y": 19
+      }
+    ],
+    "1418": [
+      {
+        "x": 61,
+        "y": 19
+      }
+    ],
+    "1492": [
+      {
+        "x": 65,
+        "y": 19
+      }
+    ],
+    "1533": [
+      {
+        "x": 67,
+        "y": 19
+      }
+    ],
+    "1574": [
+      {
+        "x": 69,
+        "y": 19
+      }
+    ],
+    "1639": [
+      {
+        "x": 73,
+        "y": 19
+      }
+    ],
+    "1680": [
+      {
+        "x": 75,
+        "y": 19
+      }
+    ],
+    "27": [
+      {
+        "x": 1,
+        "y": 20
+      }
+    ],
+    "68": [
+      {
+        "x": 3,
+        "y": 20
+      }
+    ],
+    "109": [
+      {
+        "x": 5,
+        "y": 20
+      }
+    ],
+    "136": [
+      {
+        "x": 7,
+        "y": 20
+      }
+    ],
+    "174": [
+      {
+        "x": 9,
+        "y": 20
+      }
+    ],
+    "215": [
+      {
+        "x": 11,
+        "y": 20
+      }
+    ],
+    "256": [
+      {
+        "x": 13,
+        "y": 20
+      }
+    ],
+    "281": [
+      {
+        "x": 15,
+        "y": 20
+      }
+    ],
+    "318": [
+      {
+        "x": 17,
+        "y": 20
+      }
+    ],
+    "373": [
+      {
+        "x": 19,
+        "y": 20
+      }
+    ],
+    "428": [
+      {
+        "x": 21,
+        "y": 20
+      }
+    ],
+    "469": [
+      {
+        "x": 23,
+        "y": 20
+      }
+    ],
+    "517": [
+      {
+        "x": 25,
+        "y": 20
+      }
+    ],
+    "572": [
+      {
+        "x": 27,
+        "y": 20
+      }
+    ],
+    "627": [
+      {
+        "x": 29,
+        "y": 20
+      }
+    ],
+    "666": [
+      {
+        "x": 31,
+        "y": 20
+      }
+    ],
+    "713": [
+      {
+        "x": 33,
+        "y": 20
+      }
+    ],
+    "768": [
+      {
+        "x": 35,
+        "y": 20
+      }
+    ],
+    "823": [
+      {
+        "x": 37,
+        "y": 20
+      }
+    ],
+    "864": [
+      {
+        "x": 39,
+        "y": 20
+      }
+    ],
+    "912": [
+      {
+        "x": 41,
+        "y": 20
+      }
+    ],
+    "967": [
+      {
+        "x": 43,
+        "y": 20
+      }
+    ],
+    "1022": [
+      {
+        "x": 45,
+        "y": 20
+      }
+    ],
+    "1061": [
+      {
+        "x": 47,
+        "y": 20
+      }
+    ],
+    "1108": [
+      {
+        "x": 49,
+        "y": 20
+      }
+    ],
+    "1163": [
+      {
+        "x": 51,
+        "y": 20
+      }
+    ],
+    "1218": [
+      {
+        "x": 53,
+        "y": 20
+      }
+    ],
+    "1259": [
+      {
+        "x": 55,
+        "y": 20
+      }
+    ],
+    "1307": [
+      {
+        "x": 57,
+        "y": 20
+      }
+    ],
+    "1362": [
+      {
+        "x": 59,
+        "y": 20
+      }
+    ],
+    "1417": [
+      {
+        "x": 61,
+        "y": 20
+      }
+    ],
+    "1454": [
+      {
+        "x": 63,
+        "y": 20
+      }
+    ],
+    "1491": [
+      {
+        "x": 65,
+        "y": 20
+      }
+    ],
+    "1532": [
+      {
+        "x": 67,
+        "y": 20
+      }
+    ],
+    "1573": [
+      {
+        "x": 69,
+        "y": 20
+      }
+    ],
+    "1600": [
+      {
+        "x": 71,
+        "y": 20
+      }
+    ],
+    "1638": [
+      {
+        "x": 73,
+        "y": 20
+      }
+    ],
+    "1679": [
+      {
+        "x": 75,
+        "y": 20
+      }
+    ],
+    "26": [
+      {
+        "x": 1,
+        "y": 21
+      }
+    ],
+    "67": [
+      {
+        "x": 3,
+        "y": 21
+      }
+    ],
+    "108": [
+      {
+        "x": 5,
+        "y": 21
+      }
+    ],
+    "173": [
+      {
+        "x": 9,
+        "y": 21
+      }
+    ],
+    "214": [
+      {
+        "x": 11,
+        "y": 21
+      }
+    ],
+    "255": [
+      {
+        "x": 13,
+        "y": 21
+      }
+    ],
+    "317": [
+      {
+        "x": 17,
+        "y": 21
+      }
+    ],
+    "372": [
+      {
+        "x": 19,
+        "y": 21
+      }
+    ],
+    "427": [
+      {
+        "x": 21,
+        "y": 21
+      }
+    ],
+    "516": [
+      {
+        "x": 25,
+        "y": 21
+      }
+    ],
+    "571": [
+      {
+        "x": 27,
+        "y": 21
+      }
+    ],
+    "626": [
+      {
+        "x": 29,
+        "y": 21
+      }
+    ],
+    "712": [
+      {
+        "x": 33,
+        "y": 21
+      }
+    ],
+    "767": [
+      {
+        "x": 35,
+        "y": 21
+      }
+    ],
+    "822": [
+      {
+        "x": 37,
+        "y": 21
+      }
+    ],
+    "911": [
+      {
+        "x": 41,
+        "y": 21
+      }
+    ],
+    "966": [
+      {
+        "x": 43,
+        "y": 21
+      }
+    ],
+    "1021": [
+      {
+        "x": 45,
+        "y": 21
+      }
+    ],
+    "1107": [
+      {
+        "x": 49,
+        "y": 21
+      }
+    ],
+    "1162": [
+      {
+        "x": 51,
+        "y": 21
+      }
+    ],
+    "1217": [
+      {
+        "x": 53,
+        "y": 21
+      }
+    ],
+    "1306": [
+      {
+        "x": 57,
+        "y": 21
+      }
+    ],
+    "1361": [
+      {
+        "x": 59,
+        "y": 21
+      }
+    ],
+    "1416": [
+      {
+        "x": 61,
+        "y": 21
+      }
+    ],
+    "1490": [
+      {
+        "x": 65,
+        "y": 21
+      }
+    ],
+    "1531": [
+      {
+        "x": 67,
+        "y": 21
+      }
+    ],
+    "1572": [
+      {
+        "x": 69,
+        "y": 21
+      }
+    ],
+    "1637": [
+      {
+        "x": 73,
+        "y": 21
+      }
+    ],
+    "1678": [
+      {
+        "x": 75,
+        "y": 21
+      }
+    ],
+    "25": [
+      {
+        "x": 1,
+        "y": 22
+      }
+    ],
+    "40": [
+      {
+        "x": 2,
+        "y": 22
+      }
+    ],
+    "66": [
+      {
+        "x": 3,
+        "y": 22
+      }
+    ],
+    "81": [
+      {
+        "x": 4,
+        "y": 22
+      }
+    ],
+    "107": [
+      {
+        "x": 5,
+        "y": 22
+      }
+    ],
+    "122": [
+      {
+        "x": 6,
+        "y": 22
+      }
+    ],
+    "135": [
+      {
+        "x": 7,
+        "y": 22
+      }
+    ],
+    "146": [
+      {
+        "x": 8,
+        "y": 22
+      }
+    ],
+    "172": [
+      {
+        "x": 9,
+        "y": 22
+      }
+    ],
+    "186": [
+      {
+        "x": 10,
+        "y": 22
+      }
+    ],
+    "213": [
+      {
+        "x": 11,
+        "y": 22
+      }
+    ],
+    "227": [
+      {
+        "x": 12,
+        "y": 22
+      }
+    ],
+    "254": [
+      {
+        "x": 13,
+        "y": 22
+      }
+    ],
+    "268": [
+      {
+        "x": 14,
+        "y": 22
+      }
+    ],
+    "280": [
+      {
+        "x": 15,
+        "y": 22
+      }
+    ],
+    "290": [
+      {
+        "x": 16,
+        "y": 22
+      }
+    ],
+    "316": [
+      {
+        "x": 17,
+        "y": 22
+      }
+    ],
+    "343": [
+      {
+        "x": 18,
+        "y": 22
+      }
+    ],
+    "371": [
+      {
+        "x": 19,
+        "y": 22
+      }
+    ],
+    "398": [
+      {
+        "x": 20,
+        "y": 22
+      }
+    ],
+    "426": [
+      {
+        "x": 21,
+        "y": 22
+      }
+    ],
+    "453": [
+      {
+        "x": 22,
+        "y": 22
+      }
+    ],
+    "468": [
+      {
+        "x": 23,
+        "y": 22
+      }
+    ],
+    "487": [
+      {
+        "x": 24,
+        "y": 22
+      }
+    ],
+    "515": [
+      {
+        "x": 25,
+        "y": 22
+      }
+    ],
+    "541": [
+      {
+        "x": 26,
+        "y": 22
+      }
+    ],
+    "570": [
+      {
+        "x": 27,
+        "y": 22
+      }
+    ],
+    "596": [
+      {
+        "x": 28,
+        "y": 22
+      }
+    ],
+    "625": [
+      {
+        "x": 29,
+        "y": 22
+      }
+    ],
+    "651": [
+      {
+        "x": 30,
+        "y": 22
+      }
+    ],
+    "665": [
+      {
+        "x": 31,
+        "y": 22
+      }
+    ],
+    "683": [
+      {
+        "x": 32,
+        "y": 22
+      }
+    ],
+    "711": [
+      {
+        "x": 33,
+        "y": 22
+      }
+    ],
+    "738": [
+      {
+        "x": 34,
+        "y": 22
+      }
+    ],
+    "766": [
+      {
+        "x": 35,
+        "y": 22
+      }
+    ],
+    "793": [
+      {
+        "x": 36,
+        "y": 22
+      }
+    ],
+    "821": [
+      {
+        "x": 37,
+        "y": 22
+      }
+    ],
+    "848": [
+      {
+        "x": 38,
+        "y": 22
+      }
+    ],
+    "863": [
+      {
+        "x": 39,
+        "y": 22
+      }
+    ],
+    "882": [
+      {
+        "x": 40,
+        "y": 22
+      }
+    ],
+    "910": [
+      {
+        "x": 41,
+        "y": 22
+      }
+    ],
+    "936": [
+      {
+        "x": 42,
+        "y": 22
+      }
+    ],
+    "965": [
+      {
+        "x": 43,
+        "y": 22
+      }
+    ],
+    "991": [
+      {
+        "x": 44,
+        "y": 22
+      }
+    ],
+    "1020": [
+      {
+        "x": 45,
+        "y": 22
+      }
+    ],
+    "1046": [
+      {
+        "x": 46,
+        "y": 22
+      }
+    ],
+    "1060": [
+      {
+        "x": 47,
+        "y": 22
+      }
+    ],
+    "1078": [
+      {
+        "x": 48,
+        "y": 22
+      }
+    ],
+    "1106": [
+      {
+        "x": 49,
+        "y": 22
+      }
+    ],
+    "1133": [
+      {
+        "x": 50,
+        "y": 22
+      }
+    ],
+    "1161": [
+      {
+        "x": 51,
+        "y": 22
+      }
+    ],
+    "1188": [
+      {
+        "x": 52,
+        "y": 22
+      }
+    ],
+    "1216": [
+      {
+        "x": 53,
+        "y": 22
+      }
+    ],
+    "1243": [
+      {
+        "x": 54,
+        "y": 22
+      }
+    ],
+    "1258": [
+      {
+        "x": 55,
+        "y": 22
+      }
+    ],
+    "1277": [
+      {
+        "x": 56,
+        "y": 22
+      }
+    ],
+    "1305": [
+      {
+        "x": 57,
+        "y": 22
+      }
+    ],
+    "1331": [
+      {
+        "x": 58,
+        "y": 22
+      }
+    ],
+    "1360": [
+      {
+        "x": 59,
+        "y": 22
+      }
+    ],
+    "1386": [
+      {
+        "x": 60,
+        "y": 22
+      }
+    ],
+    "1415": [
+      {
+        "x": 61,
+        "y": 22
+      }
+    ],
+    "1441": [
+      {
+        "x": 62,
+        "y": 22
+      }
+    ],
+    "1453": [
+      {
+        "x": 63,
+        "y": 22
+      }
+    ],
+    "1463": [
+      {
+        "x": 64,
+        "y": 22
+      }
+    ],
+    "1489": [
+      {
+        "x": 65,
+        "y": 22
+      }
+    ],
+    "1504": [
+      {
+        "x": 66,
+        "y": 22
+      }
+    ],
+    "1530": [
+      {
+        "x": 67,
+        "y": 22
+      }
+    ],
+    "1545": [
+      {
+        "x": 68,
+        "y": 22
+      }
+    ],
+    "1571": [
+      {
+        "x": 69,
+        "y": 22
+      }
+    ],
+    "1586": [
+      {
+        "x": 70,
+        "y": 22
+      }
+    ],
+    "1599": [
+      {
+        "x": 71,
+        "y": 22
+      }
+    ],
+    "1610": [
+      {
+        "x": 72,
+        "y": 22
+      }
+    ],
+    "1636": [
+      {
+        "x": 73,
+        "y": 22
+      }
+    ],
+    "1650": [
+      {
+        "x": 74,
+        "y": 22
+      }
+    ],
+    "1677": [
+      {
+        "x": 75,
+        "y": 22
+      }
+    ],
+    "24": [
+      {
+        "x": 1,
+        "y": 23
+      }
+    ],
+    "65": [
+      {
+        "x": 3,
+        "y": 23
+      }
+    ],
+    "106": [
+      {
+        "x": 5,
+        "y": 23
+      }
+    ],
+    "171": [
+      {
+        "x": 9,
+        "y": 23
+      }
+    ],
+    "212": [
+      {
+        "x": 11,
+        "y": 23
+      }
+    ],
+    "253": [
+      {
+        "x": 13,
+        "y": 23
+      }
+    ],
+    "315": [
+      {
+        "x": 17,
+        "y": 23
+      }
+    ],
+    "370": [
+      {
+        "x": 19,
+        "y": 23
+      }
+    ],
+    "425": [
+      {
+        "x": 21,
+        "y": 23
+      }
+    ],
+    "514": [
+      {
+        "x": 25,
+        "y": 23
+      }
+    ],
+    "569": [
+      {
+        "x": 27,
+        "y": 23
+      }
+    ],
+    "624": [
+      {
+        "x": 29,
+        "y": 23
+      }
+    ],
+    "710": [
+      {
+        "x": 33,
+        "y": 23
+      }
+    ],
+    "765": [
+      {
+        "x": 35,
+        "y": 23
+      }
+    ],
+    "820": [
+      {
+        "x": 37,
+        "y": 23
+      }
+    ],
+    "909": [
+      {
+        "x": 41,
+        "y": 23
+      }
+    ],
+    "964": [
+      {
+        "x": 43,
+        "y": 23
+      }
+    ],
+    "1019": [
+      {
+        "x": 45,
+        "y": 23
+      }
+    ],
+    "1105": [
+      {
+        "x": 49,
+        "y": 23
+      }
+    ],
+    "1160": [
+      {
+        "x": 51,
+        "y": 23
+      }
+    ],
+    "1215": [
+      {
+        "x": 53,
+        "y": 23
+      }
+    ],
+    "1304": [
+      {
+        "x": 57,
+        "y": 23
+      }
+    ],
+    "1359": [
+      {
+        "x": 59,
+        "y": 23
+      }
+    ],
+    "1414": [
+      {
+        "x": 61,
+        "y": 23
+      }
+    ],
+    "1488": [
+      {
+        "x": 65,
+        "y": 23
+      }
+    ],
+    "1529": [
+      {
+        "x": 67,
+        "y": 23
+      }
+    ],
+    "1570": [
+      {
+        "x": 69,
+        "y": 23
+      }
+    ],
+    "1635": [
+      {
+        "x": 73,
+        "y": 23
+      }
+    ],
+    "1676": [
+      {
+        "x": 75,
+        "y": 23
+      }
+    ],
+    "23": [
+      {
+        "x": 1,
+        "y": 24
+      }
+    ],
+    "64": [
+      {
+        "x": 3,
+        "y": 24
+      }
+    ],
+    "105": [
+      {
+        "x": 5,
+        "y": 24
+      }
+    ],
+    "170": [
+      {
+        "x": 9,
+        "y": 24
+      }
+    ],
+    "211": [
+      {
+        "x": 11,
+        "y": 24
+      }
+    ],
+    "252": [
+      {
+        "x": 13,
+        "y": 24
+      }
+    ],
+    "314": [
+      {
+        "x": 17,
+        "y": 24
+      }
+    ],
+    "369": [
+      {
+        "x": 19,
+        "y": 24
+      }
+    ],
+    "424": [
+      {
+        "x": 21,
+        "y": 24
+      }
+    ],
+    "513": [
+      {
+        "x": 25,
+        "y": 24
+      }
+    ],
+    "568": [
+      {
+        "x": 27,
+        "y": 24
+      }
+    ],
+    "623": [
+      {
+        "x": 29,
+        "y": 24
+      }
+    ],
+    "709": [
+      {
+        "x": 33,
+        "y": 24
+      }
+    ],
+    "764": [
+      {
+        "x": 35,
+        "y": 24
+      }
+    ],
+    "819": [
+      {
+        "x": 37,
+        "y": 24
+      }
+    ],
+    "908": [
+      {
+        "x": 41,
+        "y": 24
+      }
+    ],
+    "963": [
+      {
+        "x": 43,
+        "y": 24
+      }
+    ],
+    "1018": [
+      {
+        "x": 45,
+        "y": 24
+      }
+    ],
+    "1104": [
+      {
+        "x": 49,
+        "y": 24
+      }
+    ],
+    "1159": [
+      {
+        "x": 51,
+        "y": 24
+      }
+    ],
+    "1214": [
+      {
+        "x": 53,
+        "y": 24
+      }
+    ],
+    "1303": [
+      {
+        "x": 57,
+        "y": 24
+      }
+    ],
+    "1358": [
+      {
+        "x": 59,
+        "y": 24
+      }
+    ],
+    "1413": [
+      {
+        "x": 61,
+        "y": 24
+      }
+    ],
+    "1487": [
+      {
+        "x": 65,
+        "y": 24
+      }
+    ],
+    "1528": [
+      {
+        "x": 67,
+        "y": 24
+      }
+    ],
+    "1569": [
+      {
+        "x": 69,
+        "y": 24
+      }
+    ],
+    "1634": [
+      {
+        "x": 73,
+        "y": 24
+      }
+    ],
+    "1675": [
+      {
+        "x": 75,
+        "y": 24
+      }
+    ],
+    "22": [
+      {
+        "x": 1,
+        "y": 25
+      }
+    ],
+    "63": [
+      {
+        "x": 3,
+        "y": 25
+      }
+    ],
+    "104": [
+      {
+        "x": 5,
+        "y": 25
+      }
+    ],
+    "169": [
+      {
+        "x": 9,
+        "y": 25
+      }
+    ],
+    "210": [
+      {
+        "x": 11,
+        "y": 25
+      }
+    ],
+    "251": [
+      {
+        "x": 13,
+        "y": 25
+      }
+    ],
+    "313": [
+      {
+        "x": 17,
+        "y": 25
+      }
+    ],
+    "368": [
+      {
+        "x": 19,
+        "y": 25
+      }
+    ],
+    "423": [
+      {
+        "x": 21,
+        "y": 25
+      }
+    ],
+    "512": [
+      {
+        "x": 25,
+        "y": 25
+      }
+    ],
+    "567": [
+      {
+        "x": 27,
+        "y": 25
+      }
+    ],
+    "622": [
+      {
+        "x": 29,
+        "y": 25
+      }
+    ],
+    "708": [
+      {
+        "x": 33,
+        "y": 25
+      }
+    ],
+    "763": [
+      {
+        "x": 35,
+        "y": 25
+      }
+    ],
+    "818": [
+      {
+        "x": 37,
+        "y": 25
+      }
+    ],
+    "907": [
+      {
+        "x": 41,
+        "y": 25
+      }
+    ],
+    "962": [
+      {
+        "x": 43,
+        "y": 25
+      }
+    ],
+    "1017": [
+      {
+        "x": 45,
+        "y": 25
+      }
+    ],
+    "1103": [
+      {
+        "x": 49,
+        "y": 25
+      }
+    ],
+    "1158": [
+      {
+        "x": 51,
+        "y": 25
+      }
+    ],
+    "1213": [
+      {
+        "x": 53,
+        "y": 25
+      }
+    ],
+    "1302": [
+      {
+        "x": 57,
+        "y": 25
+      }
+    ],
+    "1357": [
+      {
+        "x": 59,
+        "y": 25
+      }
+    ],
+    "1412": [
+      {
+        "x": 61,
+        "y": 25
+      }
+    ],
+    "1486": [
+      {
+        "x": 65,
+        "y": 25
+      }
+    ],
+    "1527": [
+      {
+        "x": 67,
+        "y": 25
+      }
+    ],
+    "1568": [
+      {
+        "x": 69,
+        "y": 25
+      }
+    ],
+    "1633": [
+      {
+        "x": 73,
+        "y": 25
+      }
+    ],
+    "1674": [
+      {
+        "x": 75,
+        "y": 25
+      }
+    ],
+    "21": [
+      {
+        "x": 1,
+        "y": 26
+      }
+    ],
+    "62": [
+      {
+        "x": 3,
+        "y": 26
+      }
+    ],
+    "103": [
+      {
+        "x": 5,
+        "y": 26
+      }
+    ],
+    "168": [
+      {
+        "x": 9,
+        "y": 26
+      }
+    ],
+    "209": [
+      {
+        "x": 11,
+        "y": 26
+      }
+    ],
+    "250": [
+      {
+        "x": 13,
+        "y": 26
+      }
+    ],
+    "312": [
+      {
+        "x": 17,
+        "y": 26
+      }
+    ],
+    "367": [
+      {
+        "x": 19,
+        "y": 26
+      }
+    ],
+    "422": [
+      {
+        "x": 21,
+        "y": 26
+      }
+    ],
+    "511": [
+      {
+        "x": 25,
+        "y": 26
+      }
+    ],
+    "566": [
+      {
+        "x": 27,
+        "y": 26
+      }
+    ],
+    "621": [
+      {
+        "x": 29,
+        "y": 26
+      }
+    ],
+    "707": [
+      {
+        "x": 33,
+        "y": 26
+      }
+    ],
+    "762": [
+      {
+        "x": 35,
+        "y": 26
+      }
+    ],
+    "817": [
+      {
+        "x": 37,
+        "y": 26
+      }
+    ],
+    "906": [
+      {
+        "x": 41,
+        "y": 26
+      }
+    ],
+    "961": [
+      {
+        "x": 43,
+        "y": 26
+      }
+    ],
+    "1016": [
+      {
+        "x": 45,
+        "y": 26
+      }
+    ],
+    "1102": [
+      {
+        "x": 49,
+        "y": 26
+      }
+    ],
+    "1157": [
+      {
+        "x": 51,
+        "y": 26
+      }
+    ],
+    "1212": [
+      {
+        "x": 53,
+        "y": 26
+      }
+    ],
+    "1301": [
+      {
+        "x": 57,
+        "y": 26
+      }
+    ],
+    "1356": [
+      {
+        "x": 59,
+        "y": 26
+      }
+    ],
+    "1411": [
+      {
+        "x": 61,
+        "y": 26
+      }
+    ],
+    "1485": [
+      {
+        "x": 65,
+        "y": 26
+      }
+    ],
+    "1526": [
+      {
+        "x": 67,
+        "y": 26
+      }
+    ],
+    "1567": [
+      {
+        "x": 69,
+        "y": 26
+      }
+    ],
+    "1632": [
+      {
+        "x": 73,
+        "y": 26
+      }
+    ],
+    "1673": [
+      {
+        "x": 75,
+        "y": 26
+      }
+    ],
+    "20": [
+      {
+        "x": 1,
+        "y": 27
+      }
+    ],
+    "61": [
+      {
+        "x": 3,
+        "y": 27
+      }
+    ],
+    "102": [
+      {
+        "x": 5,
+        "y": 27
+      }
+    ],
+    "167": [
+      {
+        "x": 9,
+        "y": 27
+      }
+    ],
+    "208": [
+      {
+        "x": 11,
+        "y": 27
+      }
+    ],
+    "249": [
+      {
+        "x": 13,
+        "y": 27
+      }
+    ],
+    "311": [
+      {
+        "x": 17,
+        "y": 27
+      }
+    ],
+    "366": [
+      {
+        "x": 19,
+        "y": 27
+      }
+    ],
+    "421": [
+      {
+        "x": 21,
+        "y": 27
+      }
+    ],
+    "510": [
+      {
+        "x": 25,
+        "y": 27
+      }
+    ],
+    "565": [
+      {
+        "x": 27,
+        "y": 27
+      }
+    ],
+    "620": [
+      {
+        "x": 29,
+        "y": 27
+      }
+    ],
+    "706": [
+      {
+        "x": 33,
+        "y": 27
+      }
+    ],
+    "761": [
+      {
+        "x": 35,
+        "y": 27
+      }
+    ],
+    "816": [
+      {
+        "x": 37,
+        "y": 27
+      }
+    ],
+    "905": [
+      {
+        "x": 41,
+        "y": 27
+      }
+    ],
+    "960": [
+      {
+        "x": 43,
+        "y": 27
+      }
+    ],
+    "1015": [
+      {
+        "x": 45,
+        "y": 27
+      }
+    ],
+    "1101": [
+      {
+        "x": 49,
+        "y": 27
+      }
+    ],
+    "1156": [
+      {
+        "x": 51,
+        "y": 27
+      }
+    ],
+    "1211": [
+      {
+        "x": 53,
+        "y": 27
+      }
+    ],
+    "1300": [
+      {
+        "x": 57,
+        "y": 27
+      }
+    ],
+    "1355": [
+      {
+        "x": 59,
+        "y": 27
+      }
+    ],
+    "1410": [
+      {
+        "x": 61,
+        "y": 27
+      }
+    ],
+    "1484": [
+      {
+        "x": 65,
+        "y": 27
+      }
+    ],
+    "1525": [
+      {
+        "x": 67,
+        "y": 27
+      }
+    ],
+    "1566": [
+      {
+        "x": 69,
+        "y": 27
+      }
+    ],
+    "1631": [
+      {
+        "x": 73,
+        "y": 27
+      }
+    ],
+    "1672": [
+      {
+        "x": 75,
+        "y": 27
+      }
+    ],
+    "19": [
+      {
+        "x": 1,
+        "y": 28
+      }
+    ],
+    "60": [
+      {
+        "x": 3,
+        "y": 28
+      }
+    ],
+    "101": [
+      {
+        "x": 5,
+        "y": 28
+      }
+    ],
+    "134": [
+      {
+        "x": 7,
+        "y": 28
+      }
+    ],
+    "166": [
+      {
+        "x": 9,
+        "y": 28
+      }
+    ],
+    "207": [
+      {
+        "x": 11,
+        "y": 28
+      }
+    ],
+    "248": [
+      {
+        "x": 13,
+        "y": 28
+      }
+    ],
+    "279": [
+      {
+        "x": 15,
+        "y": 28
+      }
+    ],
+    "310": [
+      {
+        "x": 17,
+        "y": 28
+      }
+    ],
+    "365": [
+      {
+        "x": 19,
+        "y": 28
+      }
+    ],
+    "420": [
+      {
+        "x": 21,
+        "y": 28
+      }
+    ],
+    "467": [
+      {
+        "x": 23,
+        "y": 28
+      }
+    ],
+    "509": [
+      {
+        "x": 25,
+        "y": 28
+      }
+    ],
+    "564": [
+      {
+        "x": 27,
+        "y": 28
+      }
+    ],
+    "619": [
+      {
+        "x": 29,
+        "y": 28
+      }
+    ],
+    "664": [
+      {
+        "x": 31,
+        "y": 28
+      }
+    ],
+    "705": [
+      {
+        "x": 33,
+        "y": 28
+      }
+    ],
+    "760": [
+      {
+        "x": 35,
+        "y": 28
+      }
+    ],
+    "815": [
+      {
+        "x": 37,
+        "y": 28
+      }
+    ],
+    "862": [
+      {
+        "x": 39,
+        "y": 28
+      }
+    ],
+    "904": [
+      {
+        "x": 41,
+        "y": 28
+      }
+    ],
+    "959": [
+      {
+        "x": 43,
+        "y": 28
+      }
+    ],
+    "1014": [
+      {
+        "x": 45,
+        "y": 28
+      }
+    ],
+    "1059": [
+      {
+        "x": 47,
+        "y": 28
+      }
+    ],
+    "1100": [
+      {
+        "x": 49,
+        "y": 28
+      }
+    ],
+    "1155": [
+      {
+        "x": 51,
+        "y": 28
+      }
+    ],
+    "1210": [
+      {
+        "x": 53,
+        "y": 28
+      }
+    ],
+    "1257": [
+      {
+        "x": 55,
+        "y": 28
+      }
+    ],
+    "1299": [
+      {
+        "x": 57,
+        "y": 28
+      }
+    ],
+    "1354": [
+      {
+        "x": 59,
+        "y": 28
+      }
+    ],
+    "1409": [
+      {
+        "x": 61,
+        "y": 28
+      }
+    ],
+    "1452": [
+      {
+        "x": 63,
+        "y": 28
+      }
+    ],
+    "1483": [
+      {
+        "x": 65,
+        "y": 28
+      }
+    ],
+    "1524": [
+      {
+        "x": 67,
+        "y": 28
+      }
+    ],
+    "1565": [
+      {
+        "x": 69,
+        "y": 28
+      }
+    ],
+    "1598": [
+      {
+        "x": 71,
+        "y": 28
+      }
+    ],
+    "1630": [
+      {
+        "x": 73,
+        "y": 28
+      }
+    ],
+    "1671": [
+      {
+        "x": 75,
+        "y": 28
+      }
+    ],
+    "18": [
+      {
+        "x": 1,
+        "y": 29
+      }
+    ],
+    "59": [
+      {
+        "x": 3,
+        "y": 29
+      }
+    ],
+    "100": [
+      {
+        "x": 5,
+        "y": 29
+      }
+    ],
+    "165": [
+      {
+        "x": 9,
+        "y": 29
+      }
+    ],
+    "206": [
+      {
+        "x": 11,
+        "y": 29
+      }
+    ],
+    "247": [
+      {
+        "x": 13,
+        "y": 29
+      }
+    ],
+    "309": [
+      {
+        "x": 17,
+        "y": 29
+      }
+    ],
+    "364": [
+      {
+        "x": 19,
+        "y": 29
+      }
+    ],
+    "419": [
+      {
+        "x": 21,
+        "y": 29
+      }
+    ],
+    "508": [
+      {
+        "x": 25,
+        "y": 29
+      }
+    ],
+    "563": [
+      {
+        "x": 27,
+        "y": 29
+      }
+    ],
+    "618": [
+      {
+        "x": 29,
+        "y": 29
+      }
+    ],
+    "704": [
+      {
+        "x": 33,
+        "y": 29
+      }
+    ],
+    "759": [
+      {
+        "x": 35,
+        "y": 29
+      }
+    ],
+    "814": [
+      {
+        "x": 37,
+        "y": 29
+      }
+    ],
+    "903": [
+      {
+        "x": 41,
+        "y": 29
+      }
+    ],
+    "958": [
+      {
+        "x": 43,
+        "y": 29
+      }
+    ],
+    "1013": [
+      {
+        "x": 45,
+        "y": 29
+      }
+    ],
+    "1099": [
+      {
+        "x": 49,
+        "y": 29
+      }
+    ],
+    "1154": [
+      {
+        "x": 51,
+        "y": 29
+      }
+    ],
+    "1209": [
+      {
+        "x": 53,
+        "y": 29
+      }
+    ],
+    "1298": [
+      {
+        "x": 57,
+        "y": 29
+      }
+    ],
+    "1353": [
+      {
+        "x": 59,
+        "y": 29
+      }
+    ],
+    "1408": [
+      {
+        "x": 61,
+        "y": 29
+      }
+    ],
+    "1482": [
+      {
+        "x": 65,
+        "y": 29
+      }
+    ],
+    "1523": [
+      {
+        "x": 67,
+        "y": 29
+      }
+    ],
+    "1564": [
+      {
+        "x": 69,
+        "y": 29
+      }
+    ],
+    "1629": [
+      {
+        "x": 73,
+        "y": 29
+      }
+    ],
+    "1670": [
+      {
+        "x": 75,
+        "y": 29
+      }
+    ],
+    "17": [
+      {
+        "x": 1,
+        "y": 30
+      }
+    ],
+    "58": [
+      {
+        "x": 3,
+        "y": 30
+      }
+    ],
+    "99": [
+      {
+        "x": 5,
+        "y": 30
+      }
+    ],
+    "133": [
+      {
+        "x": 7,
+        "y": 30
+      }
+    ],
+    "164": [
+      {
+        "x": 9,
+        "y": 30
+      }
+    ],
+    "205": [
+      {
+        "x": 11,
+        "y": 30
+      }
+    ],
+    "246": [
+      {
+        "x": 13,
+        "y": 30
+      }
+    ],
+    "278": [
+      {
+        "x": 15,
+        "y": 30
+      }
+    ],
+    "308": [
+      {
+        "x": 17,
+        "y": 30
+      }
+    ],
+    "363": [
+      {
+        "x": 19,
+        "y": 30
+      }
+    ],
+    "418": [
+      {
+        "x": 21,
+        "y": 30
+      }
+    ],
+    "466": [
+      {
+        "x": 23,
+        "y": 30
+      }
+    ],
+    "507": [
+      {
+        "x": 25,
+        "y": 30
+      }
+    ],
+    "562": [
+      {
+        "x": 27,
+        "y": 30
+      }
+    ],
+    "617": [
+      {
+        "x": 29,
+        "y": 30
+      }
+    ],
+    "663": [
+      {
+        "x": 31,
+        "y": 30
+      }
+    ],
+    "703": [
+      {
+        "x": 33,
+        "y": 30
+      }
+    ],
+    "758": [
+      {
+        "x": 35,
+        "y": 30
+      }
+    ],
+    "813": [
+      {
+        "x": 37,
+        "y": 30
+      }
+    ],
+    "861": [
+      {
+        "x": 39,
+        "y": 30
+      }
+    ],
+    "902": [
+      {
+        "x": 41,
+        "y": 30
+      }
+    ],
+    "957": [
+      {
+        "x": 43,
+        "y": 30
+      }
+    ],
+    "1012": [
+      {
+        "x": 45,
+        "y": 30
+      }
+    ],
+    "1058": [
+      {
+        "x": 47,
+        "y": 30
+      }
+    ],
+    "1098": [
+      {
+        "x": 49,
+        "y": 30
+      }
+    ],
+    "1153": [
+      {
+        "x": 51,
+        "y": 30
+      }
+    ],
+    "1208": [
+      {
+        "x": 53,
+        "y": 30
+      }
+    ],
+    "1256": [
+      {
+        "x": 55,
+        "y": 30
+      }
+    ],
+    "1297": [
+      {
+        "x": 57,
+        "y": 30
+      }
+    ],
+    "1352": [
+      {
+        "x": 59,
+        "y": 30
+      }
+    ],
+    "1407": [
+      {
+        "x": 61,
+        "y": 30
+      }
+    ],
+    "1451": [
+      {
+        "x": 63,
+        "y": 30
+      }
+    ],
+    "1481": [
+      {
+        "x": 65,
+        "y": 30
+      }
+    ],
+    "1522": [
+      {
+        "x": 67,
+        "y": 30
+      }
+    ],
+    "1563": [
+      {
+        "x": 69,
+        "y": 30
+      }
+    ],
+    "1597": [
+      {
+        "x": 71,
+        "y": 30
+      }
+    ],
+    "1628": [
+      {
+        "x": 73,
+        "y": 30
+      }
+    ],
+    "1669": [
+      {
+        "x": 75,
+        "y": 30
+      }
+    ],
+    "16": [
+      {
+        "x": 1,
+        "y": 31
+      }
+    ],
+    "57": [
+      {
+        "x": 3,
+        "y": 31
+      }
+    ],
+    "98": [
+      {
+        "x": 5,
+        "y": 31
+      }
+    ],
+    "163": [
+      {
+        "x": 9,
+        "y": 31
+      }
+    ],
+    "204": [
+      {
+        "x": 11,
+        "y": 31
+      }
+    ],
+    "245": [
+      {
+        "x": 13,
+        "y": 31
+      }
+    ],
+    "307": [
+      {
+        "x": 17,
+        "y": 31
+      }
+    ],
+    "362": [
+      {
+        "x": 19,
+        "y": 31
+      }
+    ],
+    "417": [
+      {
+        "x": 21,
+        "y": 31
+      }
+    ],
+    "506": [
+      {
+        "x": 25,
+        "y": 31
+      }
+    ],
+    "561": [
+      {
+        "x": 27,
+        "y": 31
+      }
+    ],
+    "616": [
+      {
+        "x": 29,
+        "y": 31
+      }
+    ],
+    "702": [
+      {
+        "x": 33,
+        "y": 31
+      }
+    ],
+    "757": [
+      {
+        "x": 35,
+        "y": 31
+      }
+    ],
+    "812": [
+      {
+        "x": 37,
+        "y": 31
+      }
+    ],
+    "901": [
+      {
+        "x": 41,
+        "y": 31
+      }
+    ],
+    "956": [
+      {
+        "x": 43,
+        "y": 31
+      }
+    ],
+    "1011": [
+      {
+        "x": 45,
+        "y": 31
+      }
+    ],
+    "1097": [
+      {
+        "x": 49,
+        "y": 31
+      }
+    ],
+    "1152": [
+      {
+        "x": 51,
+        "y": 31
+      }
+    ],
+    "1207": [
+      {
+        "x": 53,
+        "y": 31
+      }
+    ],
+    "1296": [
+      {
+        "x": 57,
+        "y": 31
+      }
+    ],
+    "1351": [
+      {
+        "x": 59,
+        "y": 31
+      }
+    ],
+    "1406": [
+      {
+        "x": 61,
+        "y": 31
+      }
+    ],
+    "1480": [
+      {
+        "x": 65,
+        "y": 31
+      }
+    ],
+    "1521": [
+      {
+        "x": 67,
+        "y": 31
+      }
+    ],
+    "1562": [
+      {
+        "x": 69,
+        "y": 31
+      }
+    ],
+    "1627": [
+      {
+        "x": 73,
+        "y": 31
+      }
+    ],
+    "1668": [
+      {
+        "x": 75,
+        "y": 31
+      }
+    ],
+    "15": [
+      {
+        "x": 1,
+        "y": 32
+      }
+    ],
+    "39": [
+      {
+        "x": 2,
+        "y": 32
+      }
+    ],
+    "56": [
+      {
+        "x": 3,
+        "y": 32
+      }
+    ],
+    "80": [
+      {
+        "x": 4,
+        "y": 32
+      }
+    ],
+    "97": [
+      {
+        "x": 5,
+        "y": 32
+      }
+    ],
+    "121": [
+      {
+        "x": 6,
+        "y": 32
+      }
+    ],
+    "132": [
+      {
+        "x": 7,
+        "y": 32
+      }
+    ],
+    "145": [
+      {
+        "x": 8,
+        "y": 32
+      }
+    ],
+    "162": [
+      {
+        "x": 9,
+        "y": 32
+      }
+    ],
+    "185": [
+      {
+        "x": 10,
+        "y": 32
+      }
+    ],
+    "203": [
+      {
+        "x": 11,
+        "y": 32
+      }
+    ],
+    "226": [
+      {
+        "x": 12,
+        "y": 32
+      }
+    ],
+    "244": [
+      {
+        "x": 13,
+        "y": 32
+      }
+    ],
+    "267": [
+      {
+        "x": 14,
+        "y": 32
+      }
+    ],
+    "277": [
+      {
+        "x": 15,
+        "y": 32
+      }
+    ],
+    "289": [
+      {
+        "x": 16,
+        "y": 32
+      }
+    ],
+    "306": [
+      {
+        "x": 17,
+        "y": 32
+      }
+    ],
+    "342": [
+      {
+        "x": 18,
+        "y": 32
+      }
+    ],
+    "361": [
+      {
+        "x": 19,
+        "y": 32
+      }
+    ],
+    "397": [
+      {
+        "x": 20,
+        "y": 32
+      }
+    ],
+    "416": [
+      {
+        "x": 21,
+        "y": 32
+      }
+    ],
+    "452": [
+      {
+        "x": 22,
+        "y": 32
+      }
+    ],
+    "465": [
+      {
+        "x": 23,
+        "y": 32
+      }
+    ],
+    "486": [
+      {
+        "x": 24,
+        "y": 32
+      }
+    ],
+    "505": [
+      {
+        "x": 25,
+        "y": 32
+      }
+    ],
+    "540": [
+      {
+        "x": 26,
+        "y": 32
+      }
+    ],
+    "560": [
+      {
+        "x": 27,
+        "y": 32
+      }
+    ],
+    "595": [
+      {
+        "x": 28,
+        "y": 32
+      }
+    ],
+    "615": [
+      {
+        "x": 29,
+        "y": 32
+      }
+    ],
+    "650": [
+      {
+        "x": 30,
+        "y": 32
+      }
+    ],
+    "662": [
+      {
+        "x": 31,
+        "y": 32
+      }
+    ],
+    "682": [
+      {
+        "x": 32,
+        "y": 32
+      }
+    ],
+    "701": [
+      {
+        "x": 33,
+        "y": 32
+      }
+    ],
+    "737": [
+      {
+        "x": 34,
+        "y": 32
+      }
+    ],
+    "756": [
+      {
+        "x": 35,
+        "y": 32
+      }
+    ],
+    "792": [
+      {
+        "x": 36,
+        "y": 32
+      }
+    ],
+    "811": [
+      {
+        "x": 37,
+        "y": 32
+      }
+    ],
+    "847": [
+      {
+        "x": 38,
+        "y": 32
+      }
+    ],
+    "860": [
+      {
+        "x": 39,
+        "y": 32
+      }
+    ],
+    "881": [
+      {
+        "x": 40,
+        "y": 32
+      }
+    ],
+    "900": [
+      {
+        "x": 41,
+        "y": 32
+      }
+    ],
+    "935": [
+      {
+        "x": 42,
+        "y": 32
+      }
+    ],
+    "955": [
+      {
+        "x": 43,
+        "y": 32
+      }
+    ],
+    "990": [
+      {
+        "x": 44,
+        "y": 32
+      }
+    ],
+    "1010": [
+      {
+        "x": 45,
+        "y": 32
+      }
+    ],
+    "1045": [
+      {
+        "x": 46,
+        "y": 32
+      }
+    ],
+    "1057": [
+      {
+        "x": 47,
+        "y": 32
+      }
+    ],
+    "1077": [
+      {
+        "x": 48,
+        "y": 32
+      }
+    ],
+    "1096": [
+      {
+        "x": 49,
+        "y": 32
+      }
+    ],
+    "1132": [
+      {
+        "x": 50,
+        "y": 32
+      }
+    ],
+    "1151": [
+      {
+        "x": 51,
+        "y": 32
+      }
+    ],
+    "1187": [
+      {
+        "x": 52,
+        "y": 32
+      }
+    ],
+    "1206": [
+      {
+        "x": 53,
+        "y": 32
+      }
+    ],
+    "1242": [
+      {
+        "x": 54,
+        "y": 32
+      }
+    ],
+    "1255": [
+      {
+        "x": 55,
+        "y": 32
+      }
+    ],
+    "1276": [
+      {
+        "x": 56,
+        "y": 32
+      }
+    ],
+    "1295": [
+      {
+        "x": 57,
+        "y": 32
+      }
+    ],
+    "1330": [
+      {
+        "x": 58,
+        "y": 32
+      }
+    ],
+    "1350": [
+      {
+        "x": 59,
+        "y": 32
+      }
+    ],
+    "1385": [
+      {
+        "x": 60,
+        "y": 32
+      }
+    ],
+    "1405": [
+      {
+        "x": 61,
+        "y": 32
+      }
+    ],
+    "1440": [
+      {
+        "x": 62,
+        "y": 32
+      }
+    ],
+    "1450": [
+      {
+        "x": 63,
+        "y": 32
+      }
+    ],
+    "1462": [
+      {
+        "x": 64,
+        "y": 32
+      }
+    ],
+    "1479": [
+      {
+        "x": 65,
+        "y": 32
+      }
+    ],
+    "1503": [
+      {
+        "x": 66,
+        "y": 32
+      }
+    ],
+    "1520": [
+      {
+        "x": 67,
+        "y": 32
+      }
+    ],
+    "1544": [
+      {
+        "x": 68,
+        "y": 32
+      }
+    ],
+    "1561": [
+      {
+        "x": 69,
+        "y": 32
+      }
+    ],
+    "1585": [
+      {
+        "x": 70,
+        "y": 32
+      }
+    ],
+    "1596": [
+      {
+        "x": 71,
+        "y": 32
+      }
+    ],
+    "1609": [
+      {
+        "x": 72,
+        "y": 32
+      }
+    ],
+    "1626": [
+      {
+        "x": 73,
+        "y": 32
+      }
+    ],
+    "1649": [
+      {
+        "x": 74,
+        "y": 32
+      }
+    ],
+    "1667": [
+      {
+        "x": 75,
+        "y": 32
+      }
+    ],
+    "1690": [
+      {
+        "x": 76,
+        "y": 32
+      }
+    ],
+    "1706": [
+      {
+        "x": 77,
+        "y": 32
+      }
+    ],
+    "14": [
+      {
+        "x": 1,
+        "y": 33
+      }
+    ],
+    "55": [
+      {
+        "x": 3,
+        "y": 33
+      }
+    ],
+    "96": [
+      {
+        "x": 5,
+        "y": 33
+      }
+    ],
+    "161": [
+      {
+        "x": 9,
+        "y": 33
+      }
+    ],
+    "202": [
+      {
+        "x": 11,
+        "y": 33
+      }
+    ],
+    "243": [
+      {
+        "x": 13,
+        "y": 33
+      }
+    ],
+    "305": [
+      {
+        "x": 17,
+        "y": 33
+      }
+    ],
+    "360": [
+      {
+        "x": 19,
+        "y": 33
+      }
+    ],
+    "415": [
+      {
+        "x": 21,
+        "y": 33
+      }
+    ],
+    "504": [
+      {
+        "x": 25,
+        "y": 33
+      }
+    ],
+    "559": [
+      {
+        "x": 27,
+        "y": 33
+      }
+    ],
+    "614": [
+      {
+        "x": 29,
+        "y": 33
+      }
+    ],
+    "700": [
+      {
+        "x": 33,
+        "y": 33
+      }
+    ],
+    "755": [
+      {
+        "x": 35,
+        "y": 33
+      }
+    ],
+    "810": [
+      {
+        "x": 37,
+        "y": 33
+      }
+    ],
+    "899": [
+      {
+        "x": 41,
+        "y": 33
+      }
+    ],
+    "954": [
+      {
+        "x": 43,
+        "y": 33
+      }
+    ],
+    "1009": [
+      {
+        "x": 45,
+        "y": 33
+      }
+    ],
+    "1095": [
+      {
+        "x": 49,
+        "y": 33
+      }
+    ],
+    "1150": [
+      {
+        "x": 51,
+        "y": 33
+      }
+    ],
+    "1205": [
+      {
+        "x": 53,
+        "y": 33
+      }
+    ],
+    "1294": [
+      {
+        "x": 57,
+        "y": 33
+      }
+    ],
+    "1349": [
+      {
+        "x": 59,
+        "y": 33
+      }
+    ],
+    "1404": [
+      {
+        "x": 61,
+        "y": 33
+      }
+    ],
+    "1478": [
+      {
+        "x": 65,
+        "y": 33
+      }
+    ],
+    "1519": [
+      {
+        "x": 67,
+        "y": 33
+      }
+    ],
+    "1560": [
+      {
+        "x": 69,
+        "y": 33
+      }
+    ],
+    "1625": [
+      {
+        "x": 73,
+        "y": 33
+      }
+    ],
+    "1666": [
+      {
+        "x": 75,
+        "y": 33
+      }
+    ],
+    "1705": [
+      {
+        "x": 77,
+        "y": 33
+      }
+    ],
+    "13": [
+      {
+        "x": 1,
+        "y": 34
+      }
+    ],
+    "54": [
+      {
+        "x": 3,
+        "y": 34
+      }
+    ],
+    "95": [
+      {
+        "x": 5,
+        "y": 34
+      }
+    ],
+    "131": [
+      {
+        "x": 7,
+        "y": 34
+      }
+    ],
+    "160": [
+      {
+        "x": 9,
+        "y": 34
+      }
+    ],
+    "201": [
+      {
+        "x": 11,
+        "y": 34
+      }
+    ],
+    "242": [
+      {
+        "x": 13,
+        "y": 34
+      }
+    ],
+    "276": [
+      {
+        "x": 15,
+        "y": 34
+      }
+    ],
+    "304": [
+      {
+        "x": 17,
+        "y": 34
+      }
+    ],
+    "359": [
+      {
+        "x": 19,
+        "y": 34
+      }
+    ],
+    "414": [
+      {
+        "x": 21,
+        "y": 34
+      }
+    ],
+    "464": [
+      {
+        "x": 23,
+        "y": 34
+      }
+    ],
+    "503": [
+      {
+        "x": 25,
+        "y": 34
+      }
+    ],
+    "558": [
+      {
+        "x": 27,
+        "y": 34
+      }
+    ],
+    "613": [
+      {
+        "x": 29,
+        "y": 34
+      }
+    ],
+    "661": [
+      {
+        "x": 31,
+        "y": 34
+      }
+    ],
+    "699": [
+      {
+        "x": 33,
+        "y": 34
+      }
+    ],
+    "754": [
+      {
+        "x": 35,
+        "y": 34
+      }
+    ],
+    "809": [
+      {
+        "x": 37,
+        "y": 34
+      }
+    ],
+    "859": [
+      {
+        "x": 39,
+        "y": 34
+      }
+    ],
+    "898": [
+      {
+        "x": 41,
+        "y": 34
+      }
+    ],
+    "953": [
+      {
+        "x": 43,
+        "y": 34
+      }
+    ],
+    "1008": [
+      {
+        "x": 45,
+        "y": 34
+      }
+    ],
+    "1056": [
+      {
+        "x": 47,
+        "y": 34
+      }
+    ],
+    "1094": [
+      {
+        "x": 49,
+        "y": 34
+      }
+    ],
+    "1149": [
+      {
+        "x": 51,
+        "y": 34
+      }
+    ],
+    "1204": [
+      {
+        "x": 53,
+        "y": 34
+      }
+    ],
+    "1254": [
+      {
+        "x": 55,
+        "y": 34
+      }
+    ],
+    "1293": [
+      {
+        "x": 57,
+        "y": 34
+      }
+    ],
+    "1348": [
+      {
+        "x": 59,
+        "y": 34
+      }
+    ],
+    "1403": [
+      {
+        "x": 61,
+        "y": 34
+      }
+    ],
+    "1449": [
+      {
+        "x": 63,
+        "y": 34
+      }
+    ],
+    "1477": [
+      {
+        "x": 65,
+        "y": 34
+      }
+    ],
+    "1518": [
+      {
+        "x": 67,
+        "y": 34
+      }
+    ],
+    "1559": [
+      {
+        "x": 69,
+        "y": 34
+      }
+    ],
+    "1595": [
+      {
+        "x": 71,
+        "y": 34
+      }
+    ],
+    "1624": [
+      {
+        "x": 73,
+        "y": 34
+      }
+    ],
+    "1665": [
+      {
+        "x": 75,
+        "y": 34
+      }
+    ],
+    "1704": [
+      {
+        "x": 77,
+        "y": 34
+      }
+    ],
+    "12": [
+      {
+        "x": 1,
+        "y": 35
+      }
+    ],
+    "53": [
+      {
+        "x": 3,
+        "y": 35
+      }
+    ],
+    "94": [
+      {
+        "x": 5,
+        "y": 35
+      }
+    ],
+    "159": [
+      {
+        "x": 9,
+        "y": 35
+      }
+    ],
+    "200": [
+      {
+        "x": 11,
+        "y": 35
+      }
+    ],
+    "241": [
+      {
+        "x": 13,
+        "y": 35
+      }
+    ],
+    "303": [
+      {
+        "x": 17,
+        "y": 35
+      }
+    ],
+    "358": [
+      {
+        "x": 19,
+        "y": 35
+      }
+    ],
+    "413": [
+      {
+        "x": 21,
+        "y": 35
+      }
+    ],
+    "502": [
+      {
+        "x": 25,
+        "y": 35
+      }
+    ],
+    "557": [
+      {
+        "x": 27,
+        "y": 35
+      }
+    ],
+    "612": [
+      {
+        "x": 29,
+        "y": 35
+      }
+    ],
+    "698": [
+      {
+        "x": 33,
+        "y": 35
+      }
+    ],
+    "753": [
+      {
+        "x": 35,
+        "y": 35
+      }
+    ],
+    "808": [
+      {
+        "x": 37,
+        "y": 35
+      }
+    ],
+    "897": [
+      {
+        "x": 41,
+        "y": 35
+      }
+    ],
+    "952": [
+      {
+        "x": 43,
+        "y": 35
+      }
+    ],
+    "1007": [
+      {
+        "x": 45,
+        "y": 35
+      }
+    ],
+    "1093": [
+      {
+        "x": 49,
+        "y": 35
+      }
+    ],
+    "1148": [
+      {
+        "x": 51,
+        "y": 35
+      }
+    ],
+    "1203": [
+      {
+        "x": 53,
+        "y": 35
+      }
+    ],
+    "1292": [
+      {
+        "x": 57,
+        "y": 35
+      }
+    ],
+    "1347": [
+      {
+        "x": 59,
+        "y": 35
+      }
+    ],
+    "1402": [
+      {
+        "x": 61,
+        "y": 35
+      }
+    ],
+    "1476": [
+      {
+        "x": 65,
+        "y": 35
+      }
+    ],
+    "1517": [
+      {
+        "x": 67,
+        "y": 35
+      }
+    ],
+    "1558": [
+      {
+        "x": 69,
+        "y": 35
+      }
+    ],
+    "1623": [
+      {
+        "x": 73,
+        "y": 35
+      }
+    ],
+    "1664": [
+      {
+        "x": 75,
+        "y": 35
+      }
+    ],
+    "1703": [
+      {
+        "x": 77,
+        "y": 35
+      }
+    ],
+    "11": [
+      {
+        "x": 1,
+        "y": 36
+      }
+    ],
+    "52": [
+      {
+        "x": 3,
+        "y": 36
+      }
+    ],
+    "93": [
+      {
+        "x": 5,
+        "y": 36
+      }
+    ],
+    "130": [
+      {
+        "x": 7,
+        "y": 36
+      }
+    ],
+    "158": [
+      {
+        "x": 9,
+        "y": 36
+      }
+    ],
+    "199": [
+      {
+        "x": 11,
+        "y": 36
+      }
+    ],
+    "240": [
+      {
+        "x": 13,
+        "y": 36
+      }
+    ],
+    "275": [
+      {
+        "x": 15,
+        "y": 36
+      }
+    ],
+    "302": [
+      {
+        "x": 17,
+        "y": 36
+      }
+    ],
+    "357": [
+      {
+        "x": 19,
+        "y": 36
+      }
+    ],
+    "412": [
+      {
+        "x": 21,
+        "y": 36
+      }
+    ],
+    "463": [
+      {
+        "x": 23,
+        "y": 36
+      }
+    ],
+    "501": [
+      {
+        "x": 25,
+        "y": 36
+      }
+    ],
+    "556": [
+      {
+        "x": 27,
+        "y": 36
+      }
+    ],
+    "611": [
+      {
+        "x": 29,
+        "y": 36
+      }
+    ],
+    "660": [
+      {
+        "x": 31,
+        "y": 36
+      }
+    ],
+    "697": [
+      {
+        "x": 33,
+        "y": 36
+      }
+    ],
+    "752": [
+      {
+        "x": 35,
+        "y": 36
+      }
+    ],
+    "807": [
+      {
+        "x": 37,
+        "y": 36
+      }
+    ],
+    "858": [
+      {
+        "x": 39,
+        "y": 36
+      }
+    ],
+    "896": [
+      {
+        "x": 41,
+        "y": 36
+      }
+    ],
+    "951": [
+      {
+        "x": 43,
+        "y": 36
+      }
+    ],
+    "1006": [
+      {
+        "x": 45,
+        "y": 36
+      }
+    ],
+    "1055": [
+      {
+        "x": 47,
+        "y": 36
+      }
+    ],
+    "1092": [
+      {
+        "x": 49,
+        "y": 36
+      }
+    ],
+    "1147": [
+      {
+        "x": 51,
+        "y": 36
+      }
+    ],
+    "1202": [
+      {
+        "x": 53,
+        "y": 36
+      }
+    ],
+    "1253": [
+      {
+        "x": 55,
+        "y": 36
+      }
+    ],
+    "1291": [
+      {
+        "x": 57,
+        "y": 36
+      }
+    ],
+    "1346": [
+      {
+        "x": 59,
+        "y": 36
+      }
+    ],
+    "1401": [
+      {
+        "x": 61,
+        "y": 36
+      }
+    ],
+    "1448": [
+      {
+        "x": 63,
+        "y": 36
+      }
+    ],
+    "1475": [
+      {
+        "x": 65,
+        "y": 36
+      }
+    ],
+    "1516": [
+      {
+        "x": 67,
+        "y": 36
+      }
+    ],
+    "1557": [
+      {
+        "x": 69,
+        "y": 36
+      }
+    ],
+    "1594": [
+      {
+        "x": 71,
+        "y": 36
+      }
+    ],
+    "1622": [
+      {
+        "x": 73,
+        "y": 36
+      }
+    ],
+    "1663": [
+      {
+        "x": 75,
+        "y": 36
+      }
+    ],
+    "1702": [
+      {
+        "x": 77,
+        "y": 36
+      }
+    ],
+    "10": [
+      {
+        "x": 1,
+        "y": 37
+      }
+    ],
+    "51": [
+      {
+        "x": 3,
+        "y": 37
+      }
+    ],
+    "92": [
+      {
+        "x": 5,
+        "y": 37
+      }
+    ],
+    "129": [
+      {
+        "x": 7,
+        "y": 37
+      }
+    ],
+    "157": [
+      {
+        "x": 9,
+        "y": 37
+      }
+    ],
+    "198": [
+      {
+        "x": 11,
+        "y": 37
+      }
+    ],
+    "239": [
+      {
+        "x": 13,
+        "y": 37
+      }
+    ],
+    "274": [
+      {
+        "x": 15,
+        "y": 37
+      }
+    ],
+    "301": [
+      {
+        "x": 17,
+        "y": 37
+      }
+    ],
+    "356": [
+      {
+        "x": 19,
+        "y": 37
+      }
+    ],
+    "411": [
+      {
+        "x": 21,
+        "y": 37
+      }
+    ],
+    "462": [
+      {
+        "x": 23,
+        "y": 37
+      }
+    ],
+    "500": [
+      {
+        "x": 25,
+        "y": 37
+      }
+    ],
+    "555": [
+      {
+        "x": 27,
+        "y": 37
+      }
+    ],
+    "610": [
+      {
+        "x": 29,
+        "y": 37
+      }
+    ],
+    "659": [
+      {
+        "x": 31,
+        "y": 37
+      }
+    ],
+    "696": [
+      {
+        "x": 33,
+        "y": 37
+      }
+    ],
+    "751": [
+      {
+        "x": 35,
+        "y": 37
+      }
+    ],
+    "806": [
+      {
+        "x": 37,
+        "y": 37
+      }
+    ],
+    "857": [
+      {
+        "x": 39,
+        "y": 37
+      }
+    ],
+    "895": [
+      {
+        "x": 41,
+        "y": 37
+      }
+    ],
+    "950": [
+      {
+        "x": 43,
+        "y": 37
+      }
+    ],
+    "1005": [
+      {
+        "x": 45,
+        "y": 37
+      }
+    ],
+    "1054": [
+      {
+        "x": 47,
+        "y": 37
+      }
+    ],
+    "1091": [
+      {
+        "x": 49,
+        "y": 37
+      }
+    ],
+    "1146": [
+      {
+        "x": 51,
+        "y": 37
+      }
+    ],
+    "1201": [
+      {
+        "x": 53,
+        "y": 37
+      }
+    ],
+    "1252": [
+      {
+        "x": 55,
+        "y": 37
+      }
+    ],
+    "1290": [
+      {
+        "x": 57,
+        "y": 37
+      }
+    ],
+    "1345": [
+      {
+        "x": 59,
+        "y": 37
+      }
+    ],
+    "1400": [
+      {
+        "x": 61,
+        "y": 37
+      }
+    ],
+    "1447": [
+      {
+        "x": 63,
+        "y": 37
+      }
+    ],
+    "1474": [
+      {
+        "x": 65,
+        "y": 37
+      }
+    ],
+    "1515": [
+      {
+        "x": 67,
+        "y": 37
+      }
+    ],
+    "1556": [
+      {
+        "x": 69,
+        "y": 37
+      }
+    ],
+    "1593": [
+      {
+        "x": 71,
+        "y": 37
+      }
+    ],
+    "1621": [
+      {
+        "x": 73,
+        "y": 37
+      }
+    ],
+    "1662": [
+      {
+        "x": 75,
+        "y": 37
+      }
+    ],
+    "1701": [
+      {
+        "x": 77,
+        "y": 37
+      }
+    ],
+    "9": [
+      {
+        "x": 1,
+        "y": 38
+      }
+    ],
+    "50": [
+      {
+        "x": 3,
+        "y": 38
+      }
+    ],
+    "91": [
+      {
+        "x": 5,
+        "y": 38
+      }
+    ],
+    "128": [
+      {
+        "x": 7,
+        "y": 38
+      }
+    ],
+    "156": [
+      {
+        "x": 9,
+        "y": 38
+      }
+    ],
+    "197": [
+      {
+        "x": 11,
+        "y": 38
+      }
+    ],
+    "238": [
+      {
+        "x": 13,
+        "y": 38
+      }
+    ],
+    "273": [
+      {
+        "x": 15,
+        "y": 38
+      }
+    ],
+    "300": [
+      {
+        "x": 17,
+        "y": 38
+      }
+    ],
+    "355": [
+      {
+        "x": 19,
+        "y": 38
+      }
+    ],
+    "410": [
+      {
+        "x": 21,
+        "y": 38
+      }
+    ],
+    "461": [
+      {
+        "x": 23,
+        "y": 38
+      }
+    ],
+    "499": [
+      {
+        "x": 25,
+        "y": 38
+      }
+    ],
+    "554": [
+      {
+        "x": 27,
+        "y": 38
+      }
+    ],
+    "609": [
+      {
+        "x": 29,
+        "y": 38
+      }
+    ],
+    "658": [
+      {
+        "x": 31,
+        "y": 38
+      }
+    ],
+    "695": [
+      {
+        "x": 33,
+        "y": 38
+      }
+    ],
+    "750": [
+      {
+        "x": 35,
+        "y": 38
+      }
+    ],
+    "805": [
+      {
+        "x": 37,
+        "y": 38
+      }
+    ],
+    "856": [
+      {
+        "x": 39,
+        "y": 38
+      }
+    ],
+    "894": [
+      {
+        "x": 41,
+        "y": 38
+      }
+    ],
+    "949": [
+      {
+        "x": 43,
+        "y": 38
+      }
+    ],
+    "1004": [
+      {
+        "x": 45,
+        "y": 38
+      }
+    ],
+    "1053": [
+      {
+        "x": 47,
+        "y": 38
+      }
+    ],
+    "1090": [
+      {
+        "x": 49,
+        "y": 38
+      }
+    ],
+    "1145": [
+      {
+        "x": 51,
+        "y": 38
+      }
+    ],
+    "1200": [
+      {
+        "x": 53,
+        "y": 38
+      }
+    ],
+    "1251": [
+      {
+        "x": 55,
+        "y": 38
+      }
+    ],
+    "1289": [
+      {
+        "x": 57,
+        "y": 38
+      }
+    ],
+    "1344": [
+      {
+        "x": 59,
+        "y": 38
+      }
+    ],
+    "1399": [
+      {
+        "x": 61,
+        "y": 38
+      }
+    ],
+    "1446": [
+      {
+        "x": 63,
+        "y": 38
+      }
+    ],
+    "1473": [
+      {
+        "x": 65,
+        "y": 38
+      }
+    ],
+    "1514": [
+      {
+        "x": 67,
+        "y": 38
+      }
+    ],
+    "1555": [
+      {
+        "x": 69,
+        "y": 38
+      }
+    ],
+    "1592": [
+      {
+        "x": 71,
+        "y": 38
+      }
+    ],
+    "1620": [
+      {
+        "x": 73,
+        "y": 38
+      }
+    ],
+    "1661": [
+      {
+        "x": 75,
+        "y": 38
+      }
+    ],
+    "1700": [
+      {
+        "x": 77,
+        "y": 38
+      }
+    ],
+    "8": [
+      {
+        "x": 1,
+        "y": 39
+      }
+    ],
+    "49": [
+      {
+        "x": 3,
+        "y": 39
+      }
+    ],
+    "90": [
+      {
+        "x": 5,
+        "y": 39
+      }
+    ],
+    "155": [
+      {
+        "x": 9,
+        "y": 39
+      }
+    ],
+    "196": [
+      {
+        "x": 11,
+        "y": 39
+      }
+    ],
+    "237": [
+      {
+        "x": 13,
+        "y": 39
+      }
+    ],
+    "299": [
+      {
+        "x": 17,
+        "y": 39
+      }
+    ],
+    "354": [
+      {
+        "x": 19,
+        "y": 39
+      }
+    ],
+    "409": [
+      {
+        "x": 21,
+        "y": 39
+      }
+    ],
+    "498": [
+      {
+        "x": 25,
+        "y": 39
+      }
+    ],
+    "553": [
+      {
+        "x": 27,
+        "y": 39
+      }
+    ],
+    "608": [
+      {
+        "x": 29,
+        "y": 39
+      }
+    ],
+    "694": [
+      {
+        "x": 33,
+        "y": 39
+      }
+    ],
+    "749": [
+      {
+        "x": 35,
+        "y": 39
+      }
+    ],
+    "804": [
+      {
+        "x": 37,
+        "y": 39
+      }
+    ],
+    "893": [
+      {
+        "x": 41,
+        "y": 39
+      }
+    ],
+    "948": [
+      {
+        "x": 43,
+        "y": 39
+      }
+    ],
+    "1003": [
+      {
+        "x": 45,
+        "y": 39
+      }
+    ],
+    "1089": [
+      {
+        "x": 49,
+        "y": 39
+      }
+    ],
+    "1144": [
+      {
+        "x": 51,
+        "y": 39
+      }
+    ],
+    "1199": [
+      {
+        "x": 53,
+        "y": 39
+      }
+    ],
+    "1288": [
+      {
+        "x": 57,
+        "y": 39
+      }
+    ],
+    "1343": [
+      {
+        "x": 59,
+        "y": 39
+      }
+    ],
+    "1398": [
+      {
+        "x": 61,
+        "y": 39
+      }
+    ],
+    "1472": [
+      {
+        "x": 65,
+        "y": 39
+      }
+    ],
+    "1513": [
+      {
+        "x": 67,
+        "y": 39
+      }
+    ],
+    "1554": [
+      {
+        "x": 69,
+        "y": 39
+      }
+    ],
+    "1619": [
+      {
+        "x": 73,
+        "y": 39
+      }
+    ],
+    "1660": [
+      {
+        "x": 75,
+        "y": 39
+      }
+    ],
+    "1699": [
+      {
+        "x": 77,
+        "y": 39
+      }
+    ],
+    "7": [
+      {
+        "x": 1,
+        "y": 40
+      }
+    ],
+    "48": [
+      {
+        "x": 3,
+        "y": 40
+      }
+    ],
+    "89": [
+      {
+        "x": 5,
+        "y": 40
+      }
+    ],
+    "127": [
+      {
+        "x": 7,
+        "y": 40
+      }
+    ],
+    "154": [
+      {
+        "x": 9,
+        "y": 40
+      }
+    ],
+    "195": [
+      {
+        "x": 11,
+        "y": 40
+      }
+    ],
+    "236": [
+      {
+        "x": 13,
+        "y": 40
+      }
+    ],
+    "272": [
+      {
+        "x": 15,
+        "y": 40
+      }
+    ],
+    "298": [
+      {
+        "x": 17,
+        "y": 40
+      }
+    ],
+    "353": [
+      {
+        "x": 19,
+        "y": 40
+      }
+    ],
+    "408": [
+      {
+        "x": 21,
+        "y": 40
+      }
+    ],
+    "460": [
+      {
+        "x": 23,
+        "y": 40
+      }
+    ],
+    "497": [
+      {
+        "x": 25,
+        "y": 40
+      }
+    ],
+    "552": [
+      {
+        "x": 27,
+        "y": 40
+      }
+    ],
+    "607": [
+      {
+        "x": 29,
+        "y": 40
+      }
+    ],
+    "657": [
+      {
+        "x": 31,
+        "y": 40
+      }
+    ],
+    "693": [
+      {
+        "x": 33,
+        "y": 40
+      }
+    ],
+    "748": [
+      {
+        "x": 35,
+        "y": 40
+      }
+    ],
+    "803": [
+      {
+        "x": 37,
+        "y": 40
+      }
+    ],
+    "855": [
+      {
+        "x": 39,
+        "y": 40
+      }
+    ],
+    "892": [
+      {
+        "x": 41,
+        "y": 40
+      }
+    ],
+    "947": [
+      {
+        "x": 43,
+        "y": 40
+      }
+    ],
+    "1002": [
+      {
+        "x": 45,
+        "y": 40
+      }
+    ],
+    "1052": [
+      {
+        "x": 47,
+        "y": 40
+      }
+    ],
+    "1088": [
+      {
+        "x": 49,
+        "y": 40
+      }
+    ],
+    "1143": [
+      {
+        "x": 51,
+        "y": 40
+      }
+    ],
+    "1198": [
+      {
+        "x": 53,
+        "y": 40
+      }
+    ],
+    "1250": [
+      {
+        "x": 55,
+        "y": 40
+      }
+    ],
+    "1287": [
+      {
+        "x": 57,
+        "y": 40
+      }
+    ],
+    "1342": [
+      {
+        "x": 59,
+        "y": 40
+      }
+    ],
+    "1397": [
+      {
+        "x": 61,
+        "y": 40
+      }
+    ],
+    "1445": [
+      {
+        "x": 63,
+        "y": 40
+      }
+    ],
+    "1471": [
+      {
+        "x": 65,
+        "y": 40
+      }
+    ],
+    "1512": [
+      {
+        "x": 67,
+        "y": 40
+      }
+    ],
+    "1553": [
+      {
+        "x": 69,
+        "y": 40
+      }
+    ],
+    "1591": [
+      {
+        "x": 71,
+        "y": 40
+      }
+    ],
+    "1618": [
+      {
+        "x": 73,
+        "y": 40
+      }
+    ],
+    "1659": [
+      {
+        "x": 75,
+        "y": 40
+      }
+    ],
+    "1698": [
+      {
+        "x": 77,
+        "y": 40
+      }
+    ],
+    "6": [
+      {
+        "x": 1,
+        "y": 41
+      }
+    ],
+    "47": [
+      {
+        "x": 3,
+        "y": 41
+      }
+    ],
+    "88": [
+      {
+        "x": 5,
+        "y": 41
+      }
+    ],
+    "153": [
+      {
+        "x": 9,
+        "y": 41
+      }
+    ],
+    "194": [
+      {
+        "x": 11,
+        "y": 41
+      }
+    ],
+    "235": [
+      {
+        "x": 13,
+        "y": 41
+      }
+    ],
+    "297": [
+      {
+        "x": 17,
+        "y": 41
+      }
+    ],
+    "352": [
+      {
+        "x": 19,
+        "y": 41
+      }
+    ],
+    "407": [
+      {
+        "x": 21,
+        "y": 41
+      }
+    ],
+    "496": [
+      {
+        "x": 25,
+        "y": 41
+      }
+    ],
+    "551": [
+      {
+        "x": 27,
+        "y": 41
+      }
+    ],
+    "606": [
+      {
+        "x": 29,
+        "y": 41
+      }
+    ],
+    "692": [
+      {
+        "x": 33,
+        "y": 41
+      }
+    ],
+    "747": [
+      {
+        "x": 35,
+        "y": 41
+      }
+    ],
+    "802": [
+      {
+        "x": 37,
+        "y": 41
+      }
+    ],
+    "891": [
+      {
+        "x": 41,
+        "y": 41
+      }
+    ],
+    "946": [
+      {
+        "x": 43,
+        "y": 41
+      }
+    ],
+    "1001": [
+      {
+        "x": 45,
+        "y": 41
+      }
+    ],
+    "1087": [
+      {
+        "x": 49,
+        "y": 41
+      }
+    ],
+    "1142": [
+      {
+        "x": 51,
+        "y": 41
+      }
+    ],
+    "1197": [
+      {
+        "x": 53,
+        "y": 41
+      }
+    ],
+    "1286": [
+      {
+        "x": 57,
+        "y": 41
+      }
+    ],
+    "1341": [
+      {
+        "x": 59,
+        "y": 41
+      }
+    ],
+    "1396": [
+      {
+        "x": 61,
+        "y": 41
+      }
+    ],
+    "1470": [
+      {
+        "x": 65,
+        "y": 41
+      }
+    ],
+    "1511": [
+      {
+        "x": 67,
+        "y": 41
+      }
+    ],
+    "1552": [
+      {
+        "x": 69,
+        "y": 41
+      }
+    ],
+    "1617": [
+      {
+        "x": 73,
+        "y": 41
+      }
+    ],
+    "1658": [
+      {
+        "x": 75,
+        "y": 41
+      }
+    ],
+    "1697": [
+      {
+        "x": 77,
+        "y": 41
+      }
+    ],
+    "5": [
+      {
+        "x": 1,
+        "y": 42
+      }
+    ],
+    "38": [
+      {
+        "x": 2,
+        "y": 42
+      }
+    ],
+    "46": [
+      {
+        "x": 3,
+        "y": 42
+      }
+    ],
+    "79": [
+      {
+        "x": 4,
+        "y": 42
+      }
+    ],
+    "87": [
+      {
+        "x": 5,
+        "y": 42
+      }
+    ],
+    "120": [
+      {
+        "x": 6,
+        "y": 42
+      }
+    ],
+    "126": [
+      {
+        "x": 7,
+        "y": 42
+      }
+    ],
+    "144": [
+      {
+        "x": 8,
+        "y": 42
+      }
+    ],
+    "152": [
+      {
+        "x": 9,
+        "y": 42
+      }
+    ],
+    "184": [
+      {
+        "x": 10,
+        "y": 42
+      }
+    ],
+    "193": [
+      {
+        "x": 11,
+        "y": 42
+      }
+    ],
+    "225": [
+      {
+        "x": 12,
+        "y": 42
+      }
+    ],
+    "234": [
+      {
+        "x": 13,
+        "y": 42
+      }
+    ],
+    "266": [
+      {
+        "x": 14,
+        "y": 42
+      }
+    ],
+    "271": [
+      {
+        "x": 15,
+        "y": 42
+      }
+    ],
+    "288": [
+      {
+        "x": 16,
+        "y": 42
+      }
+    ],
+    "296": [
+      {
+        "x": 17,
+        "y": 42
+      }
+    ],
+    "341": [
+      {
+        "x": 18,
+        "y": 42
+      }
+    ],
+    "351": [
+      {
+        "x": 19,
+        "y": 42
+      }
+    ],
+    "396": [
+      {
+        "x": 20,
+        "y": 42
+      }
+    ],
+    "406": [
+      {
+        "x": 21,
+        "y": 42
+      }
+    ],
+    "451": [
+      {
+        "x": 22,
+        "y": 42
+      }
+    ],
+    "459": [
+      {
+        "x": 23,
+        "y": 42
+      }
+    ],
+    "485": [
+      {
+        "x": 24,
+        "y": 42
+      }
+    ],
+    "495": [
+      {
+        "x": 25,
+        "y": 42
+      }
+    ],
+    "539": [
+      {
+        "x": 26,
+        "y": 42
+      }
+    ],
+    "550": [
+      {
+        "x": 27,
+        "y": 42
+      }
+    ],
+    "594": [
+      {
+        "x": 28,
+        "y": 42
+      }
+    ],
+    "605": [
+      {
+        "x": 29,
+        "y": 42
+      }
+    ],
+    "649": [
+      {
+        "x": 30,
+        "y": 42
+      }
+    ],
+    "656": [
+      {
+        "x": 31,
+        "y": 42
+      }
+    ],
+    "681": [
+      {
+        "x": 32,
+        "y": 42
+      }
+    ],
+    "691": [
+      {
+        "x": 33,
+        "y": 42
+      }
+    ],
+    "736": [
+      {
+        "x": 34,
+        "y": 42
+      }
+    ],
+    "746": [
+      {
+        "x": 35,
+        "y": 42
+      }
+    ],
+    "791": [
+      {
+        "x": 36,
+        "y": 42
+      }
+    ],
+    "801": [
+      {
+        "x": 37,
+        "y": 42
+      }
+    ],
+    "846": [
+      {
+        "x": 38,
+        "y": 42
+      }
+    ],
+    "854": [
+      {
+        "x": 39,
+        "y": 42
+      }
+    ],
+    "880": [
+      {
+        "x": 40,
+        "y": 42
+      }
+    ],
+    "890": [
+      {
+        "x": 41,
+        "y": 42
+      }
+    ],
+    "934": [
+      {
+        "x": 42,
+        "y": 42
+      }
+    ],
+    "945": [
+      {
+        "x": 43,
+        "y": 42
+      }
+    ],
+    "989": [
+      {
+        "x": 44,
+        "y": 42
+      }
+    ],
+    "1000": [
+      {
+        "x": 45,
+        "y": 42
+      }
+    ],
+    "1044": [
+      {
+        "x": 46,
+        "y": 42
+      }
+    ],
+    "1051": [
+      {
+        "x": 47,
+        "y": 42
+      }
+    ],
+    "1076": [
+      {
+        "x": 48,
+        "y": 42
+      }
+    ],
+    "1086": [
+      {
+        "x": 49,
+        "y": 42
+      }
+    ],
+    "1131": [
+      {
+        "x": 50,
+        "y": 42
+      }
+    ],
+    "1141": [
+      {
+        "x": 51,
+        "y": 42
+      }
+    ],
+    "1186": [
+      {
+        "x": 52,
+        "y": 42
+      }
+    ],
+    "1196": [
+      {
+        "x": 53,
+        "y": 42
+      }
+    ],
+    "1241": [
+      {
+        "x": 54,
+        "y": 42
+      }
+    ],
+    "1249": [
+      {
+        "x": 55,
+        "y": 42
+      }
+    ],
+    "1275": [
+      {
+        "x": 56,
+        "y": 42
+      }
+    ],
+    "1285": [
+      {
+        "x": 57,
+        "y": 42
+      }
+    ],
+    "1329": [
+      {
+        "x": 58,
+        "y": 42
+      }
+    ],
+    "1340": [
+      {
+        "x": 59,
+        "y": 42
+      }
+    ],
+    "1384": [
+      {
+        "x": 60,
+        "y": 42
+      }
+    ],
+    "1395": [
+      {
+        "x": 61,
+        "y": 42
+      }
+    ],
+    "1439": [
+      {
+        "x": 62,
+        "y": 42
+      }
+    ],
+    "1444": [
+      {
+        "x": 63,
+        "y": 42
+      }
+    ],
+    "1461": [
+      {
+        "x": 64,
+        "y": 42
+      }
+    ],
+    "1469": [
+      {
+        "x": 65,
+        "y": 42
+      }
+    ],
+    "1502": [
+      {
+        "x": 66,
+        "y": 42
+      }
+    ],
+    "1510": [
+      {
+        "x": 67,
+        "y": 42
+      }
+    ],
+    "1543": [
+      {
+        "x": 68,
+        "y": 42
+      }
+    ],
+    "1551": [
+      {
+        "x": 69,
+        "y": 42
+      }
+    ],
+    "1584": [
+      {
+        "x": 70,
+        "y": 42
+      }
+    ],
+    "1590": [
+      {
+        "x": 71,
+        "y": 42
+      }
+    ],
+    "1608": [
+      {
+        "x": 72,
+        "y": 42
+      }
+    ],
+    "1616": [
+      {
+        "x": 73,
+        "y": 42
+      }
+    ],
+    "1648": [
+      {
+        "x": 74,
+        "y": 42
+      }
+    ],
+    "1657": [
+      {
+        "x": 75,
+        "y": 42
+      }
+    ],
+    "1689": [
+      {
+        "x": 76,
+        "y": 42
+      }
+    ],
+    "1696": [
+      {
+        "x": 77,
+        "y": 42
+      }
+    ],
+    "4": [
+      {
+        "x": 1,
+        "y": 43
+      }
+    ],
+    "45": [
+      {
+        "x": 3,
+        "y": 43
+      }
+    ],
+    "86": [
+      {
+        "x": 5,
+        "y": 43
+      }
+    ],
+    "151": [
+      {
+        "x": 9,
+        "y": 43
+      }
+    ],
+    "192": [
+      {
+        "x": 11,
+        "y": 43
+      }
+    ],
+    "233": [
+      {
+        "x": 13,
+        "y": 43
+      }
+    ],
+    "295": [
+      {
+        "x": 17,
+        "y": 43
+      }
+    ],
+    "350": [
+      {
+        "x": 19,
+        "y": 43
+      }
+    ],
+    "405": [
+      {
+        "x": 21,
+        "y": 43
+      }
+    ],
+    "494": [
+      {
+        "x": 25,
+        "y": 43
+      }
+    ],
+    "549": [
+      {
+        "x": 27,
+        "y": 43
+      }
+    ],
+    "604": [
+      {
+        "x": 29,
+        "y": 43
+      }
+    ],
+    "690": [
+      {
+        "x": 33,
+        "y": 43
+      }
+    ],
+    "745": [
+      {
+        "x": 35,
+        "y": 43
+      }
+    ],
+    "800": [
+      {
+        "x": 37,
+        "y": 43
+      }
+    ],
+    "889": [
+      {
+        "x": 41,
+        "y": 43
+      }
+    ],
+    "944": [
+      {
+        "x": 43,
+        "y": 43
+      }
+    ],
+    "999": [
+      {
+        "x": 45,
+        "y": 43
+      }
+    ],
+    "1085": [
+      {
+        "x": 49,
+        "y": 43
+      }
+    ],
+    "1140": [
+      {
+        "x": 51,
+        "y": 43
+      }
+    ],
+    "1195": [
+      {
+        "x": 53,
+        "y": 43
+      }
+    ],
+    "1284": [
+      {
+        "x": 57,
+        "y": 43
+      }
+    ],
+    "1339": [
+      {
+        "x": 59,
+        "y": 43
+      }
+    ],
+    "1394": [
+      {
+        "x": 61,
+        "y": 43
+      }
+    ],
+    "1468": [
+      {
+        "x": 65,
+        "y": 43
+      }
+    ],
+    "1509": [
+      {
+        "x": 67,
+        "y": 43
+      }
+    ],
+    "1550": [
+      {
+        "x": 69,
+        "y": 43
+      }
+    ],
+    "1615": [
+      {
+        "x": 73,
+        "y": 43
+      }
+    ],
+    "1656": [
+      {
+        "x": 75,
+        "y": 43
+      }
+    ],
+    "1695": [
+      {
+        "x": 77,
+        "y": 43
+      }
+    ],
+    "3": [
+      {
+        "x": 1,
+        "y": 44
+      }
+    ],
+    "37": [
+      {
+        "x": 2,
+        "y": 44
+      }
+    ],
+    "44": [
+      {
+        "x": 3,
+        "y": 44
+      }
+    ],
+    "78": [
+      {
+        "x": 4,
+        "y": 44
+      }
+    ],
+    "85": [
+      {
+        "x": 5,
+        "y": 44
+      }
+    ],
+    "119": [
+      {
+        "x": 6,
+        "y": 44
+      }
+    ],
+    "125": [
+      {
+        "x": 7,
+        "y": 44
+      }
+    ],
+    "143": [
+      {
+        "x": 8,
+        "y": 44
+      }
+    ],
+    "150": [
+      {
+        "x": 9,
+        "y": 44
+      }
+    ],
+    "183": [
+      {
+        "x": 10,
+        "y": 44
+      }
+    ],
+    "191": [
+      {
+        "x": 11,
+        "y": 44
+      }
+    ],
+    "224": [
+      {
+        "x": 12,
+        "y": 44
+      }
+    ],
+    "232": [
+      {
+        "x": 13,
+        "y": 44
+      }
+    ],
+    "265": [
+      {
+        "x": 14,
+        "y": 44
+      }
+    ],
+    "270": [
+      {
+        "x": 15,
+        "y": 44
+      }
+    ],
+    "287": [
+      {
+        "x": 16,
+        "y": 44
+      }
+    ],
+    "294": [
+      {
+        "x": 17,
+        "y": 44
+      }
+    ],
+    "340": [
+      {
+        "x": 18,
+        "y": 44
+      }
+    ],
+    "349": [
+      {
+        "x": 19,
+        "y": 44
+      }
+    ],
+    "395": [
+      {
+        "x": 20,
+        "y": 44
+      }
+    ],
+    "404": [
+      {
+        "x": 21,
+        "y": 44
+      }
+    ],
+    "450": [
+      {
+        "x": 22,
+        "y": 44
+      }
+    ],
+    "458": [
+      {
+        "x": 23,
+        "y": 44
+      }
+    ],
+    "484": [
+      {
+        "x": 24,
+        "y": 44
+      }
+    ],
+    "493": [
+      {
+        "x": 25,
+        "y": 44
+      }
+    ],
+    "538": [
+      {
+        "x": 26,
+        "y": 44
+      }
+    ],
+    "548": [
+      {
+        "x": 27,
+        "y": 44
+      }
+    ],
+    "593": [
+      {
+        "x": 28,
+        "y": 44
+      }
+    ],
+    "603": [
+      {
+        "x": 29,
+        "y": 44
+      }
+    ],
+    "648": [
+      {
+        "x": 30,
+        "y": 44
+      }
+    ],
+    "655": [
+      {
+        "x": 31,
+        "y": 44
+      }
+    ],
+    "680": [
+      {
+        "x": 32,
+        "y": 44
+      }
+    ],
+    "689": [
+      {
+        "x": 33,
+        "y": 44
+      }
+    ],
+    "735": [
+      {
+        "x": 34,
+        "y": 44
+      }
+    ],
+    "744": [
+      {
+        "x": 35,
+        "y": 44
+      }
+    ],
+    "790": [
+      {
+        "x": 36,
+        "y": 44
+      }
+    ],
+    "799": [
+      {
+        "x": 37,
+        "y": 44
+      }
+    ],
+    "845": [
+      {
+        "x": 38,
+        "y": 44
+      }
+    ],
+    "853": [
+      {
+        "x": 39,
+        "y": 44
+      }
+    ],
+    "879": [
+      {
+        "x": 40,
+        "y": 44
+      }
+    ],
+    "888": [
+      {
+        "x": 41,
+        "y": 44
+      }
+    ],
+    "933": [
+      {
+        "x": 42,
+        "y": 44
+      }
+    ],
+    "943": [
+      {
+        "x": 43,
+        "y": 44
+      }
+    ],
+    "988": [
+      {
+        "x": 44,
+        "y": 44
+      }
+    ],
+    "998": [
+      {
+        "x": 45,
+        "y": 44
+      }
+    ],
+    "1043": [
+      {
+        "x": 46,
+        "y": 44
+      }
+    ],
+    "1050": [
+      {
+        "x": 47,
+        "y": 44
+      }
+    ],
+    "1075": [
+      {
+        "x": 48,
+        "y": 44
+      }
+    ],
+    "1084": [
+      {
+        "x": 49,
+        "y": 44
+      }
+    ],
+    "1130": [
+      {
+        "x": 50,
+        "y": 44
+      }
+    ],
+    "1139": [
+      {
+        "x": 51,
+        "y": 44
+      }
+    ],
+    "1185": [
+      {
+        "x": 52,
+        "y": 44
+      }
+    ],
+    "1194": [
+      {
+        "x": 53,
+        "y": 44
+      }
+    ],
+    "1240": [
+      {
+        "x": 54,
+        "y": 44
+      }
+    ],
+    "1248": [
+      {
+        "x": 55,
+        "y": 44
+      }
+    ],
+    "1274": [
+      {
+        "x": 56,
+        "y": 44
+      }
+    ],
+    "1283": [
+      {
+        "x": 57,
+        "y": 44
+      }
+    ],
+    "1328": [
+      {
+        "x": 58,
+        "y": 44
+      }
+    ],
+    "1338": [
+      {
+        "x": 59,
+        "y": 44
+      }
+    ],
+    "1383": [
+      {
+        "x": 60,
+        "y": 44
+      }
+    ],
+    "1393": [
+      {
+        "x": 61,
+        "y": 44
+      }
+    ],
+    "1438": [
+      {
+        "x": 62,
+        "y": 44
+      }
+    ],
+    "1443": [
+      {
+        "x": 63,
+        "y": 44
+      }
+    ],
+    "1460": [
+      {
+        "x": 64,
+        "y": 44
+      }
+    ],
+    "1467": [
+      {
+        "x": 65,
+        "y": 44
+      }
+    ],
+    "1501": [
+      {
+        "x": 66,
+        "y": 44
+      }
+    ],
+    "1508": [
+      {
+        "x": 67,
+        "y": 44
+      }
+    ],
+    "1542": [
+      {
+        "x": 68,
+        "y": 44
+      }
+    ],
+    "1549": [
+      {
+        "x": 69,
+        "y": 44
+      }
+    ],
+    "1583": [
+      {
+        "x": 70,
+        "y": 44
+      }
+    ],
+    "1589": [
+      {
+        "x": 71,
+        "y": 44
+      }
+    ],
+    "1607": [
+      {
+        "x": 72,
+        "y": 44
+      }
+    ],
+    "1614": [
+      {
+        "x": 73,
+        "y": 44
+      }
+    ],
+    "1647": [
+      {
+        "x": 74,
+        "y": 44
+      }
+    ],
+    "1655": [
+      {
+        "x": 75,
+        "y": 44
+      }
+    ],
+    "1688": [
+      {
+        "x": 76,
+        "y": 44
+      }
+    ],
+    "1694": [
+      {
+        "x": 77,
+        "y": 44
+      }
+    ],
+    "2": [
+      {
+        "x": 1,
+        "y": 45
+      }
+    ],
+    "43": [
+      {
+        "x": 3,
+        "y": 45
+      }
+    ],
+    "84": [
+      {
+        "x": 5,
+        "y": 45
+      }
+    ],
+    "149": [
+      {
+        "x": 9,
+        "y": 45
+      }
+    ],
+    "190": [
+      {
+        "x": 11,
+        "y": 45
+      }
+    ],
+    "231": [
+      {
+        "x": 13,
+        "y": 45
+      }
+    ],
+    "293": [
+      {
+        "x": 17,
+        "y": 45
+      }
+    ],
+    "348": [
+      {
+        "x": 19,
+        "y": 45
+      }
+    ],
+    "403": [
+      {
+        "x": 21,
+        "y": 45
+      }
+    ],
+    "492": [
+      {
+        "x": 25,
+        "y": 45
+      }
+    ],
+    "547": [
+      {
+        "x": 27,
+        "y": 45
+      }
+    ],
+    "602": [
+      {
+        "x": 29,
+        "y": 45
+      }
+    ],
+    "688": [
+      {
+        "x": 33,
+        "y": 45
+      }
+    ],
+    "743": [
+      {
+        "x": 35,
+        "y": 45
+      }
+    ],
+    "798": [
+      {
+        "x": 37,
+        "y": 45
+      }
+    ],
+    "887": [
+      {
+        "x": 41,
+        "y": 45
+      }
+    ],
+    "942": [
+      {
+        "x": 43,
+        "y": 45
+      }
+    ],
+    "997": [
+      {
+        "x": 45,
+        "y": 45
+      }
+    ],
+    "1083": [
+      {
+        "x": 49,
+        "y": 45
+      }
+    ],
+    "1138": [
+      {
+        "x": 51,
+        "y": 45
+      }
+    ],
+    "1193": [
+      {
+        "x": 53,
+        "y": 45
+      }
+    ],
+    "1282": [
+      {
+        "x": 57,
+        "y": 45
+      }
+    ],
+    "1337": [
+      {
+        "x": 59,
+        "y": 45
+      }
+    ],
+    "1392": [
+      {
+        "x": 61,
+        "y": 45
+      }
+    ],
+    "1466": [
+      {
+        "x": 65,
+        "y": 45
+      }
+    ],
+    "1507": [
+      {
+        "x": 67,
+        "y": 45
+      }
+    ],
+    "1548": [
+      {
+        "x": 69,
+        "y": 45
+      }
+    ],
+    "1613": [
+      {
+        "x": 73,
+        "y": 45
+      }
+    ],
+    "1654": [
+      {
+        "x": 75,
+        "y": 45
+      }
+    ],
+    "1693": [
+      {
+        "x": 77,
+        "y": 45
+      }
+    ],
+    "189": [
+      {
+        "x": 11,
+        "y": 46
+      }
+    ],
+    "230": [
+      {
+        "x": 13,
+        "y": 46
+      }
+    ],
+    "546": [
+      {
+        "x": 27,
+        "y": 46
+      }
+    ],
+    "601": [
+      {
+        "x": 29,
+        "y": 46
+      }
+    ],
+    "941": [
+      {
+        "x": 43,
+        "y": 46
+      }
+    ],
+    "996": [
+      {
+        "x": 45,
+        "y": 46
+      }
+    ],
+    "1336": [
+      {
+        "x": 59,
+        "y": 46
+      }
+    ],
+    "1391": [
+      {
+        "x": 61,
+        "y": 46
+      }
+    ],
+    "1653": [
+      {
+        "x": 75,
+        "y": 46
+      }
+    ],
+    "1692": [
+      {
+        "x": 77,
+        "y": 46
+      }
+    ],
+    "1": [
+      {
+        "x": 1,
+        "y": 47
+      }
+    ],
+    "36": [
+      {
+        "x": 2,
+        "y": 47
+      }
+    ],
+    "42": [
+      {
+        "x": 3,
+        "y": 47
+      }
+    ],
+    "77": [
+      {
+        "x": 4,
+        "y": 47
+      }
+    ],
+    "83": [
+      {
+        "x": 5,
+        "y": 47
+      }
+    ],
+    "118": [
+      {
+        "x": 6,
+        "y": 47
+      }
+    ],
+    "124": [
+      {
+        "x": 7,
+        "y": 47
+      }
+    ],
+    "142": [
+      {
+        "x": 8,
+        "y": 47
+      }
+    ],
+    "148": [
+      {
+        "x": 9,
+        "y": 47
+      }
+    ],
+    "292": [
+      {
+        "x": 17,
+        "y": 47
+      }
+    ],
+    "339": [
+      {
+        "x": 18,
+        "y": 47
+      }
+    ],
+    "347": [
+      {
+        "x": 19,
+        "y": 47
+      }
+    ],
+    "394": [
+      {
+        "x": 20,
+        "y": 47
+      }
+    ],
+    "402": [
+      {
+        "x": 21,
+        "y": 47
+      }
+    ],
+    "449": [
+      {
+        "x": 22,
+        "y": 47
+      }
+    ],
+    "457": [
+      {
+        "x": 23,
+        "y": 47
+      }
+    ],
+    "483": [
+      {
+        "x": 24,
+        "y": 47
+      }
+    ],
+    "491": [
+      {
+        "x": 25,
+        "y": 47
+      }
+    ],
+    "687": [
+      {
+        "x": 33,
+        "y": 47
+      }
+    ],
+    "734": [
+      {
+        "x": 34,
+        "y": 47
+      }
+    ],
+    "742": [
+      {
+        "x": 35,
+        "y": 47
+      }
+    ],
+    "789": [
+      {
+        "x": 36,
+        "y": 47
+      }
+    ],
+    "797": [
+      {
+        "x": 37,
+        "y": 47
+      }
+    ],
+    "844": [
+      {
+        "x": 38,
+        "y": 47
+      }
+    ],
+    "852": [
+      {
+        "x": 39,
+        "y": 47
+      }
+    ],
+    "878": [
+      {
+        "x": 40,
+        "y": 47
+      }
+    ],
+    "886": [
+      {
+        "x": 41,
+        "y": 47
+      }
+    ],
+    "1082": [
+      {
+        "x": 49,
+        "y": 47
+      }
+    ],
+    "1129": [
+      {
+        "x": 50,
+        "y": 47
+      }
+    ],
+    "1137": [
+      {
+        "x": 51,
+        "y": 47
+      }
+    ],
+    "1184": [
+      {
+        "x": 52,
+        "y": 47
+      }
+    ],
+    "1192": [
+      {
+        "x": 53,
+        "y": 47
+      }
+    ],
+    "1239": [
+      {
+        "x": 54,
+        "y": 47
+      }
+    ],
+    "1247": [
+      {
+        "x": 55,
+        "y": 47
+      }
+    ],
+    "1273": [
+      {
+        "x": 56,
+        "y": 47
+      }
+    ],
+    "1281": [
+      {
+        "x": 57,
+        "y": 47
+      }
+    ],
+    "1465": [
+      {
+        "x": 65,
+        "y": 47
+      }
+    ],
+    "1500": [
+      {
+        "x": 66,
+        "y": 47
+      }
+    ],
+    "1506": [
+      {
+        "x": 67,
+        "y": 47
+      }
+    ],
+    "1541": [
+      {
+        "x": 68,
+        "y": 47
+      }
+    ],
+    "1547": [
+      {
+        "x": 69,
+        "y": 47
+      }
+    ],
+    "1582": [
+      {
+        "x": 70,
+        "y": 47
+      }
+    ],
+    "1588": [
+      {
+        "x": 71,
+        "y": 47
+      }
+    ],
+    "1606": [
+      {
+        "x": 72,
+        "y": 47
+      }
+    ],
+    "1612": [
+      {
+        "x": 73,
+        "y": 47
+      }
+    ]
+  },
+  "coordinate_to_path_id": {
+    "17,0": 338,
+    "18,0": 346,
+    "19,0": 393,
+    "20,0": 401,
+    "21,0": 448,
+    "22,0": 456,
+    "23,0": 482,
+    "24,0": 490,
+    "25,0": 537,
+    "26,0": 544,
+    "27,0": 592,
+    "28,0": 599,
+    "29,0": 647,
+    "30,0": 654,
+    "31,0": 679,
+    "32,0": 686,
+    "33,0": 733,
+    "34,0": 741,
+    "35,0": 788,
+    "36,0": 796,
+    "37,0": 843,
+    "38,0": 851,
+    "39,0": 877,
+    "40,0": 885,
+    "41,0": 932,
+    "42,0": 939,
+    "43,0": 987,
+    "44,0": 994,
+    "45,0": 1042,
+    "46,0": 1049,
+    "47,0": 1074,
+    "48,0": 1081,
+    "49,0": 1128,
+    "50,0": 1136,
+    "51,0": 1183,
+    "52,0": 1191,
+    "53,0": 1238,
+    "54,0": 1246,
+    "55,0": 1272,
+    "56,0": 1280,
+    "57,0": 1327,
+    "58,0": 1334,
+    "59,0": 1382,
+    "60,0": 1389,
+    "61,0": 1437,
+    "17,1": 337,
+    "19,1": 392,
+    "21,1": 447,
+    "25,1": 536,
+    "27,1": 591,
+    "29,1": 646,
+    "33,1": 732,
+    "35,1": 787,
+    "37,1": 842,
+    "41,1": 931,
+    "43,1": 986,
+    "45,1": 1041,
+    "49,1": 1127,
+    "51,1": 1182,
+    "53,1": 1237,
+    "57,1": 1326,
+    "59,1": 1381,
+    "61,1": 1436,
+    "17,2": 336,
+    "19,2": 391,
+    "21,2": 446,
+    "23,2": 481,
+    "25,2": 535,
+    "27,2": 590,
+    "29,2": 645,
+    "31,2": 678,
+    "33,2": 731,
+    "35,2": 786,
+    "37,2": 841,
+    "39,2": 876,
+    "41,2": 930,
+    "43,2": 985,
+    "45,2": 1040,
+    "47,2": 1073,
+    "49,2": 1126,
+    "51,2": 1181,
+    "53,2": 1236,
+    "55,2": 1271,
+    "57,2": 1325,
+    "59,2": 1380,
+    "61,2": 1435,
+    "17,3": 335,
+    "19,3": 390,
+    "21,3": 445,
+    "23,3": 480,
+    "25,3": 534,
+    "27,3": 589,
+    "29,3": 644,
+    "31,3": 677,
+    "33,3": 730,
+    "35,3": 785,
+    "37,3": 840,
+    "39,3": 875,
+    "41,3": 929,
+    "43,3": 984,
+    "45,3": 1039,
+    "47,3": 1072,
+    "49,3": 1125,
+    "51,3": 1180,
+    "53,3": 1235,
+    "55,3": 1270,
+    "57,3": 1324,
+    "59,3": 1379,
+    "61,3": 1434,
+    "17,4": 334,
+    "19,4": 389,
+    "21,4": 444,
+    "23,4": 479,
+    "25,4": 533,
+    "27,4": 588,
+    "29,4": 643,
+    "31,4": 676,
+    "33,4": 729,
+    "35,4": 784,
+    "37,4": 839,
+    "39,4": 874,
+    "41,4": 928,
+    "43,4": 983,
+    "45,4": 1038,
+    "47,4": 1071,
+    "49,4": 1124,
+    "51,4": 1179,
+    "53,4": 1234,
+    "55,4": 1269,
+    "57,4": 1323,
+    "59,4": 1378,
+    "61,4": 1433,
+    "17,5": 333,
+    "19,5": 388,
+    "21,5": 443,
+    "25,5": 532,
+    "27,5": 587,
+    "29,5": 642,
+    "33,5": 728,
+    "35,5": 783,
+    "37,5": 838,
+    "41,5": 927,
+    "43,5": 982,
+    "45,5": 1037,
+    "49,5": 1123,
+    "51,5": 1178,
+    "53,5": 1233,
+    "57,5": 1322,
+    "59,5": 1377,
+    "61,5": 1432,
+    "17,6": 332,
+    "18,6": 345,
+    "19,6": 387,
+    "20,6": 400,
+    "21,6": 442,
+    "22,6": 455,
+    "23,6": 478,
+    "24,6": 489,
+    "25,6": 531,
+    "26,6": 543,
+    "27,6": 586,
+    "28,6": 598,
+    "29,6": 641,
+    "30,6": 653,
+    "31,6": 675,
+    "32,6": 685,
+    "33,6": 727,
+    "34,6": 740,
+    "35,6": 782,
+    "36,6": 795,
+    "37,6": 837,
+    "38,6": 850,
+    "39,6": 873,
+    "40,6": 884,
+    "41,6": 926,
+    "42,6": 938,
+    "43,6": 981,
+    "44,6": 993,
+    "45,6": 1036,
+    "46,6": 1048,
+    "47,6": 1070,
+    "48,6": 1080,
+    "49,6": 1122,
+    "50,6": 1135,
+    "51,6": 1177,
+    "52,6": 1190,
+    "53,6": 1232,
+    "54,6": 1245,
+    "55,6": 1268,
+    "56,6": 1279,
+    "57,6": 1321,
+    "58,6": 1333,
+    "59,6": 1376,
+    "60,6": 1388,
+    "61,6": 1431,
+    "17,7": 331,
+    "19,7": 386,
+    "21,7": 441,
+    "25,7": 530,
+    "27,7": 585,
+    "29,7": 640,
+    "33,7": 726,
+    "35,7": 781,
+    "37,7": 836,
+    "41,7": 925,
+    "43,7": 980,
+    "45,7": 1035,
+    "49,7": 1121,
+    "51,7": 1176,
+    "53,7": 1231,
+    "57,7": 1320,
+    "59,7": 1375,
+    "61,7": 1430,
+    "17,8": 330,
+    "19,8": 385,
+    "21,8": 440,
+    "23,8": 477,
+    "25,8": 529,
+    "27,8": 584,
+    "29,8": 639,
+    "31,8": 674,
+    "33,8": 725,
+    "35,8": 780,
+    "37,8": 835,
+    "39,8": 872,
+    "41,8": 924,
+    "43,8": 979,
+    "45,8": 1034,
+    "47,8": 1069,
+    "49,8": 1120,
+    "51,8": 1175,
+    "53,8": 1230,
+    "55,8": 1267,
+    "57,8": 1319,
+    "59,8": 1374,
+    "61,8": 1429,
+    "17,9": 329,
+    "19,9": 384,
+    "21,9": 439,
+    "23,9": 476,
+    "25,9": 528,
+    "27,9": 583,
+    "29,9": 638,
+    "31,9": 673,
+    "33,9": 724,
+    "35,9": 779,
+    "37,9": 834,
+    "39,9": 871,
+    "41,9": 923,
+    "43,9": 978,
+    "45,9": 1033,
+    "47,9": 1068,
+    "49,9": 1119,
+    "51,9": 1174,
+    "53,9": 1229,
+    "55,9": 1266,
+    "57,9": 1318,
+    "59,9": 1373,
+    "61,9": 1428,
+    "17,10": 328,
+    "19,10": 383,
+    "21,10": 438,
+    "23,10": 475,
+    "25,10": 527,
+    "27,10": 582,
+    "29,10": 637,
+    "31,10": 672,
+    "33,10": 723,
+    "35,10": 778,
+    "37,10": 833,
+    "39,10": 870,
+    "41,10": 922,
+    "43,10": 977,
+    "45,10": 1032,
+    "47,10": 1067,
+    "49,10": 1118,
+    "51,10": 1173,
+    "53,10": 1228,
+    "55,10": 1265,
+    "57,10": 1317,
+    "59,10": 1372,
+    "61,10": 1427,
+    "17,11": 327,
+    "19,11": 382,
+    "21,11": 437,
+    "25,11": 526,
+    "27,11": 581,
+    "29,11": 636,
+    "33,11": 722,
+    "35,11": 777,
+    "37,11": 832,
+    "41,11": 921,
+    "43,11": 976,
+    "45,11": 1031,
+    "49,11": 1117,
+    "51,11": 1172,
+    "53,11": 1227,
+    "57,11": 1316,
+    "59,11": 1371,
+    "61,11": 1426,
+    "1,12": 35,
+    "2,12": 41,
+    "3,12": 76,
+    "4,12": 82,
+    "5,12": 117,
+    "6,12": 123,
+    "7,12": 141,
+    "8,12": 147,
+    "9,12": 182,
+    "10,12": 187,
+    "11,12": 223,
+    "12,12": 228,
+    "13,12": 264,
+    "14,12": 269,
+    "15,12": 286,
+    "16,12": 291,
+    "17,12": 326,
+    "18,12": 344,
+    "19,12": 381,
+    "20,12": 399,
+    "21,12": 436,
+    "22,12": 454,
+    "23,12": 474,
+    "24,12": 488,
+    "25,12": 525,
+    "26,12": 542,
+    "27,12": 580,
+    "28,12": 597,
+    "29,12": 635,
+    "30,12": 652,
+    "31,12": 671,
+    "32,12": 684,
+    "33,12": 721,
+    "34,12": 739,
+    "35,12": 776,
+    "36,12": 794,
+    "37,12": 831,
+    "38,12": 849,
+    "39,12": 869,
+    "40,12": 883,
+    "41,12": 920,
+    "42,12": 937,
+    "43,12": 975,
+    "44,12": 992,
+    "45,12": 1030,
+    "46,12": 1047,
+    "47,12": 1066,
+    "48,12": 1079,
+    "49,12": 1116,
+    "50,12": 1134,
+    "51,12": 1171,
+    "52,12": 1189,
+    "53,12": 1226,
+    "54,12": 1244,
+    "55,12": 1264,
+    "56,12": 1278,
+    "57,12": 1315,
+    "58,12": 1332,
+    "59,12": 1370,
+    "60,12": 1387,
+    "61,12": 1425,
+    "62,12": 1442,
+    "63,12": 1459,
+    "64,12": 1464,
+    "65,12": 1499,
+    "66,12": 1505,
+    "67,12": 1540,
+    "68,12": 1546,
+    "69,12": 1581,
+    "70,12": 1587,
+    "71,12": 1605,
+    "72,12": 1611,
+    "73,12": 1646,
+    "74,12": 1651,
+    "75,12": 1687,
+    "1,13": 34,
+    "3,13": 75,
+    "5,13": 116,
+    "9,13": 181,
+    "11,13": 222,
+    "13,13": 263,
+    "17,13": 325,
+    "19,13": 380,
+    "21,13": 435,
+    "25,13": 524,
+    "27,13": 579,
+    "29,13": 634,
+    "33,13": 720,
+    "35,13": 775,
+    "37,13": 830,
+    "41,13": 919,
+    "43,13": 974,
+    "45,13": 1029,
+    "49,13": 1115,
+    "51,13": 1170,
+    "53,13": 1225,
+    "57,13": 1314,
+    "59,13": 1369,
+    "61,13": 1424,
+    "65,13": 1498,
+    "67,13": 1539,
+    "69,13": 1580,
+    "73,13": 1645,
+    "75,13": 1686,
+    "1,14": 33,
+    "3,14": 74,
+    "5,14": 115,
+    "7,14": 140,
+    "9,14": 180,
+    "11,14": 221,
+    "13,14": 262,
+    "15,14": 285,
+    "17,14": 324,
+    "19,14": 379,
+    "21,14": 434,
+    "23,14": 473,
+    "25,14": 523,
+    "27,14": 578,
+    "29,14": 633,
+    "31,14": 670,
+    "33,14": 719,
+    "35,14": 774,
+    "37,14": 829,
+    "39,14": 868,
+    "41,14": 918,
+    "43,14": 973,
+    "45,14": 1028,
+    "47,14": 1065,
+    "49,14": 1114,
+    "51,14": 1169,
+    "53,14": 1224,
+    "55,14": 1263,
+    "57,14": 1313,
+    "59,14": 1368,
+    "61,14": 1423,
+    "63,14": 1458,
+    "65,14": 1497,
+    "67,14": 1538,
+    "69,14": 1579,
+    "71,14": 1604,
+    "73,14": 1644,
+    "75,14": 1685,
+    "1,15": 32,
+    "3,15": 73,
+    "5,15": 114,
+    "9,15": 179,
+    "11,15": 220,
+    "13,15": 261,
+    "17,15": 323,
+    "19,15": 378,
+    "21,15": 433,
+    "25,15": 522,
+    "27,15": 577,
+    "29,15": 632,
+    "33,15": 718,
+    "35,15": 773,
+    "37,15": 828,
+    "41,15": 917,
+    "43,15": 972,
+    "45,15": 1027,
+    "49,15": 1113,
+    "51,15": 1168,
+    "53,15": 1223,
+    "57,15": 1312,
+    "59,15": 1367,
+    "61,15": 1422,
+    "65,15": 1496,
+    "67,15": 1537,
+    "69,15": 1578,
+    "73,15": 1643,
+    "75,15": 1684,
+    "1,16": 31,
+    "3,16": 72,
+    "5,16": 113,
+    "7,16": 139,
+    "9,16": 178,
+    "11,16": 219,
+    "13,16": 260,
+    "15,16": 284,
+    "17,16": 322,
+    "19,16": 377,
+    "21,16": 432,
+    "23,16": 472,
+    "25,16": 521,
+    "27,16": 576,
+    "29,16": 631,
+    "31,16": 669,
+    "33,16": 717,
+    "35,16": 772,
+    "37,16": 827,
+    "39,16": 867,
+    "41,16": 916,
+    "43,16": 971,
+    "45,16": 1026,
+    "47,16": 1064,
+    "49,16": 1112,
+    "51,16": 1167,
+    "53,16": 1222,
+    "55,16": 1262,
+    "57,16": 1311,
+    "59,16": 1366,
+    "61,16": 1421,
+    "63,16": 1457,
+    "65,16": 1495,
+    "67,16": 1536,
+    "69,16": 1577,
+    "71,16": 1603,
+    "73,16": 1642,
+    "75,16": 1683,
+    "1,17": 30,
+    "3,17": 71,
+    "5,17": 112,
+    "7,17": 138,
+    "9,17": 177,
+    "11,17": 218,
+    "13,17": 259,
+    "15,17": 283,
+    "17,17": 321,
+    "19,17": 376,
+    "21,17": 431,
+    "23,17": 471,
+    "25,17": 520,
+    "27,17": 575,
+    "29,17": 630,
+    "31,17": 668,
+    "33,17": 716,
+    "35,17": 771,
+    "37,17": 826,
+    "39,17": 866,
+    "41,17": 915,
+    "43,17": 970,
+    "45,17": 1025,
+    "47,17": 1063,
+    "49,17": 1111,
+    "51,17": 1166,
+    "53,17": 1221,
+    "55,17": 1261,
+    "57,17": 1310,
+    "59,17": 1365,
+    "61,17": 1420,
+    "63,17": 1456,
+    "65,17": 1494,
+    "67,17": 1535,
+    "69,17": 1576,
+    "71,17": 1602,
+    "73,17": 1641,
+    "75,17": 1682,
+    "1,18": 29,
+    "3,18": 70,
+    "5,18": 111,
+    "7,18": 137,
+    "9,18": 176,
+    "11,18": 217,
+    "13,18": 258,
+    "15,18": 282,
+    "17,18": 320,
+    "19,18": 375,
+    "21,18": 430,
+    "23,18": 470,
+    "25,18": 519,
+    "27,18": 574,
+    "29,18": 629,
+    "31,18": 667,
+    "33,18": 715,
+    "35,18": 770,
+    "37,18": 825,
+    "39,18": 865,
+    "41,18": 914,
+    "43,18": 969,
+    "45,18": 1024,
+    "47,18": 1062,
+    "49,18": 1110,
+    "51,18": 1165,
+    "53,18": 1220,
+    "55,18": 1260,
+    "57,18": 1309,
+    "59,18": 1364,
+    "61,18": 1419,
+    "63,18": 1455,
+    "65,18": 1493,
+    "67,18": 1534,
+    "69,18": 1575,
+    "71,18": 1601,
+    "73,18": 1640,
+    "75,18": 1681,
+    "1,19": 28,
+    "3,19": 69,
+    "5,19": 110,
+    "9,19": 175,
+    "11,19": 216,
+    "13,19": 257,
+    "17,19": 319,
+    "19,19": 374,
+    "21,19": 429,
+    "25,19": 518,
+    "27,19": 573,
+    "29,19": 628,
+    "33,19": 714,
+    "35,19": 769,
+    "37,19": 824,
+    "41,19": 913,
+    "43,19": 968,
+    "45,19": 1023,
+    "49,19": 1109,
+    "51,19": 1164,
+    "53,19": 1219,
+    "57,19": 1308,
+    "59,19": 1363,
+    "61,19": 1418,
+    "65,19": 1492,
+    "67,19": 1533,
+    "69,19": 1574,
+    "73,19": 1639,
+    "75,19": 1680,
+    "1,20": 27,
+    "3,20": 68,
+    "5,20": 109,
+    "7,20": 136,
+    "9,20": 174,
+    "11,20": 215,
+    "13,20": 256,
+    "15,20": 281,
+    "17,20": 318,
+    "19,20": 373,
+    "21,20": 428,
+    "23,20": 469,
+    "25,20": 517,
+    "27,20": 572,
+    "29,20": 627,
+    "31,20": 666,
+    "33,20": 713,
+    "35,20": 768,
+    "37,20": 823,
+    "39,20": 864,
+    "41,20": 912,
+    "43,20": 967,
+    "45,20": 1022,
+    "47,20": 1061,
+    "49,20": 1108,
+    "51,20": 1163,
+    "53,20": 1218,
+    "55,20": 1259,
+    "57,20": 1307,
+    "59,20": 1362,
+    "61,20": 1417,
+    "63,20": 1454,
+    "65,20": 1491,
+    "67,20": 1532,
+    "69,20": 1573,
+    "71,20": 1600,
+    "73,20": 1638,
+    "75,20": 1679,
+    "1,21": 26,
+    "3,21": 67,
+    "5,21": 108,
+    "9,21": 173,
+    "11,21": 214,
+    "13,21": 255,
+    "17,21": 317,
+    "19,21": 372,
+    "21,21": 427,
+    "25,21": 516,
+    "27,21": 571,
+    "29,21": 626,
+    "33,21": 712,
+    "35,21": 767,
+    "37,21": 822,
+    "41,21": 911,
+    "43,21": 966,
+    "45,21": 1021,
+    "49,21": 1107,
+    "51,21": 1162,
+    "53,21": 1217,
+    "57,21": 1306,
+    "59,21": 1361,
+    "61,21": 1416,
+    "65,21": 1490,
+    "67,21": 1531,
+    "69,21": 1572,
+    "73,21": 1637,
+    "75,21": 1678,
+    "1,22": 25,
+    "2,22": 40,
+    "3,22": 66,
+    "4,22": 81,
+    "5,22": 107,
+    "6,22": 122,
+    "7,22": 135,
+    "8,22": 146,
+    "9,22": 172,
+    "10,22": 186,
+    "11,22": 213,
+    "12,22": 227,
+    "13,22": 254,
+    "14,22": 268,
+    "15,22": 280,
+    "16,22": 290,
+    "17,22": 316,
+    "18,22": 343,
+    "19,22": 371,
+    "20,22": 398,
+    "21,22": 426,
+    "22,22": 453,
+    "23,22": 468,
+    "24,22": 487,
+    "25,22": 515,
+    "26,22": 541,
+    "27,22": 570,
+    "28,22": 596,
+    "29,22": 625,
+    "30,22": 651,
+    "31,22": 665,
+    "32,22": 683,
+    "33,22": 711,
+    "34,22": 738,
+    "35,22": 766,
+    "36,22": 793,
+    "37,22": 821,
+    "38,22": 848,
+    "39,22": 863,
+    "40,22": 882,
+    "41,22": 910,
+    "42,22": 936,
+    "43,22": 965,
+    "44,22": 991,
+    "45,22": 1020,
+    "46,22": 1046,
+    "47,22": 1060,
+    "48,22": 1078,
+    "49,22": 1106,
+    "50,22": 1133,
+    "51,22": 1161,
+    "52,22": 1188,
+    "53,22": 1216,
+    "54,22": 1243,
+    "55,22": 1258,
+    "56,22": 1277,
+    "57,22": 1305,
+    "58,22": 1331,
+    "59,22": 1360,
+    "60,22": 1386,
+    "61,22": 1415,
+    "62,22": 1441,
+    "63,22": 1453,
+    "64,22": 1463,
+    "65,22": 1489,
+    "66,22": 1504,
+    "67,22": 1530,
+    "68,22": 1545,
+    "69,22": 1571,
+    "70,22": 1586,
+    "71,22": 1599,
+    "72,22": 1610,
+    "73,22": 1636,
+    "74,22": 1650,
+    "75,22": 1677,
+    "1,23": 24,
+    "3,23": 65,
+    "5,23": 106,
+    "9,23": 171,
+    "11,23": 212,
+    "13,23": 253,
+    "17,23": 315,
+    "19,23": 370,
+    "21,23": 425,
+    "25,23": 514,
+    "27,23": 569,
+    "29,23": 624,
+    "33,23": 710,
+    "35,23": 765,
+    "37,23": 820,
+    "41,23": 909,
+    "43,23": 964,
+    "45,23": 1019,
+    "49,23": 1105,
+    "51,23": 1160,
+    "53,23": 1215,
+    "57,23": 1304,
+    "59,23": 1359,
+    "61,23": 1414,
+    "65,23": 1488,
+    "67,23": 1529,
+    "69,23": 1570,
+    "73,23": 1635,
+    "75,23": 1676,
+    "1,24": 23,
+    "3,24": 64,
+    "5,24": 105,
+    "9,24": 170,
+    "11,24": 211,
+    "13,24": 252,
+    "17,24": 314,
+    "19,24": 369,
+    "21,24": 424,
+    "25,24": 513,
+    "27,24": 568,
+    "29,24": 623,
+    "33,24": 709,
+    "35,24": 764,
+    "37,24": 819,
+    "41,24": 908,
+    "43,24": 963,
+    "45,24": 1018,
+    "49,24": 1104,
+    "51,24": 1159,
+    "53,24": 1214,
+    "57,24": 1303,
+    "59,24": 1358,
+    "61,24": 1413,
+    "65,24": 1487,
+    "67,24": 1528,
+    "69,24": 1569,
+    "73,24": 1634,
+    "75,24": 1675,
+    "1,25": 22,
+    "3,25": 63,
+    "5,25": 104,
+    "9,25": 169,
+    "11,25": 210,
+    "13,25": 251,
+    "17,25": 313,
+    "19,25": 368,
+    "21,25": 423,
+    "25,25": 512,
+    "27,25": 567,
+    "29,25": 622,
+    "33,25": 708,
+    "35,25": 763,
+    "37,25": 818,
+    "41,25": 907,
+    "43,25": 962,
+    "45,25": 1017,
+    "49,25": 1103,
+    "51,25": 1158,
+    "53,25": 1213,
+    "57,25": 1302,
+    "59,25": 1357,
+    "61,25": 1412,
+    "65,25": 1486,
+    "67,25": 1527,
+    "69,25": 1568,
+    "73,25": 1633,
+    "75,25": 1674,
+    "1,26": 21,
+    "3,26": 62,
+    "5,26": 103,
+    "9,26": 168,
+    "11,26": 209,
+    "13,26": 250,
+    "17,26": 312,
+    "19,26": 367,
+    "21,26": 422,
+    "25,26": 511,
+    "27,26": 566,
+    "29,26": 621,
+    "33,26": 707,
+    "35,26": 762,
+    "37,26": 817,
+    "41,26": 906,
+    "43,26": 961,
+    "45,26": 1016,
+    "49,26": 1102,
+    "51,26": 1157,
+    "53,26": 1212,
+    "57,26": 1301,
+    "59,26": 1356,
+    "61,26": 1411,
+    "65,26": 1485,
+    "67,26": 1526,
+    "69,26": 1567,
+    "73,26": 1632,
+    "75,26": 1673,
+    "1,27": 20,
+    "3,27": 61,
+    "5,27": 102,
+    "9,27": 167,
+    "11,27": 208,
+    "13,27": 249,
+    "17,27": 311,
+    "19,27": 366,
+    "21,27": 421,
+    "25,27": 510,
+    "27,27": 565,
+    "29,27": 620,
+    "33,27": 706,
+    "35,27": 761,
+    "37,27": 816,
+    "41,27": 905,
+    "43,27": 960,
+    "45,27": 1015,
+    "49,27": 1101,
+    "51,27": 1156,
+    "53,27": 1211,
+    "57,27": 1300,
+    "59,27": 1355,
+    "61,27": 1410,
+    "65,27": 1484,
+    "67,27": 1525,
+    "69,27": 1566,
+    "73,27": 1631,
+    "75,27": 1672,
+    "1,28": 19,
+    "3,28": 60,
+    "5,28": 101,
+    "7,28": 134,
+    "9,28": 166,
+    "11,28": 207,
+    "13,28": 248,
+    "15,28": 279,
+    "17,28": 310,
+    "19,28": 365,
+    "21,28": 420,
+    "23,28": 467,
+    "25,28": 509,
+    "27,28": 564,
+    "29,28": 619,
+    "31,28": 664,
+    "33,28": 705,
+    "35,28": 760,
+    "37,28": 815,
+    "39,28": 862,
+    "41,28": 904,
+    "43,28": 959,
+    "45,28": 1014,
+    "47,28": 1059,
+    "49,28": 1100,
+    "51,28": 1155,
+    "53,28": 1210,
+    "55,28": 1257,
+    "57,28": 1299,
+    "59,28": 1354,
+    "61,28": 1409,
+    "63,28": 1452,
+    "65,28": 1483,
+    "67,28": 1524,
+    "69,28": 1565,
+    "71,28": 1598,
+    "73,28": 1630,
+    "75,28": 1671,
+    "1,29": 18,
+    "3,29": 59,
+    "5,29": 100,
+    "9,29": 165,
+    "11,29": 206,
+    "13,29": 247,
+    "17,29": 309,
+    "19,29": 364,
+    "21,29": 419,
+    "25,29": 508,
+    "27,29": 563,
+    "29,29": 618,
+    "33,29": 704,
+    "35,29": 759,
+    "37,29": 814,
+    "41,29": 903,
+    "43,29": 958,
+    "45,29": 1013,
+    "49,29": 1099,
+    "51,29": 1154,
+    "53,29": 1209,
+    "57,29": 1298,
+    "59,29": 1353,
+    "61,29": 1408,
+    "65,29": 1482,
+    "67,29": 1523,
+    "69,29": 1564,
+    "73,29": 1629,
+    "75,29": 1670,
+    "1,30": 17,
+    "3,30": 58,
+    "5,30": 99,
+    "7,30": 133,
+    "9,30": 164,
+    "11,30": 205,
+    "13,30": 246,
+    "15,30": 278,
+    "17,30": 308,
+    "19,30": 363,
+    "21,30": 418,
+    "23,30": 466,
+    "25,30": 507,
+    "27,30": 562,
+    "29,30": 617,
+    "31,30": 663,
+    "33,30": 703,
+    "35,30": 758,
+    "37,30": 813,
+    "39,30": 861,
+    "41,30": 902,
+    "43,30": 957,
+    "45,30": 1012,
+    "47,30": 1058,
+    "49,30": 1098,
+    "51,30": 1153,
+    "53,30": 1208,
+    "55,30": 1256,
+    "57,30": 1297,
+    "59,30": 1352,
+    "61,30": 1407,
+    "63,30": 1451,
+    "65,30": 1481,
+    "67,30": 1522,
+    "69,30": 1563,
+    "71,30": 1597,
+    "73,30": 1628,
+    "75,30": 1669,
+    "1,31": 16,
+    "3,31": 57,
+    "5,31": 98,
+    "9,31": 163,
+    "11,31": 204,
+    "13,31": 245,
+    "17,31": 307,
+    "19,31": 362,
+    "21,31": 417,
+    "25,31": 506,
+    "27,31": 561,
+    "29,31": 616,
+    "33,31": 702,
+    "35,31": 757,
+    "37,31": 812,
+    "41,31": 901,
+    "43,31": 956,
+    "45,31": 1011,
+    "49,31": 1097,
+    "51,31": 1152,
+    "53,31": 1207,
+    "57,31": 1296,
+    "59,31": 1351,
+    "61,31": 1406,
+    "65,31": 1480,
+    "67,31": 1521,
+    "69,31": 1562,
+    "73,31": 1627,
+    "75,31": 1668,
+    "1,32": 15,
+    "2,32": 39,
+    "3,32": 56,
+    "4,32": 80,
+    "5,32": 97,
+    "6,32": 121,
+    "7,32": 132,
+    "8,32": 145,
+    "9,32": 162,
+    "10,32": 185,
+    "11,32": 203,
+    "12,32": 226,
+    "13,32": 244,
+    "14,32": 267,
+    "15,32": 277,
+    "16,32": 289,
+    "17,32": 306,
+    "18,32": 342,
+    "19,32": 361,
+    "20,32": 397,
+    "21,32": 416,
+    "22,32": 452,
+    "23,32": 465,
+    "24,32": 486,
+    "25,32": 505,
+    "26,32": 540,
+    "27,32": 560,
+    "28,32": 595,
+    "29,32": 615,
+    "30,32": 650,
+    "31,32": 662,
+    "32,32": 682,
+    "33,32": 701,
+    "34,32": 737,
+    "35,32": 756,
+    "36,32": 792,
+    "37,32": 811,
+    "38,32": 847,
+    "39,32": 860,
+    "40,32": 881,
+    "41,32": 900,
+    "42,32": 935,
+    "43,32": 955,
+    "44,32": 990,
+    "45,32": 1010,
+    "46,32": 1045,
+    "47,32": 1057,
+    "48,32": 1077,
+    "49,32": 1096,
+    "50,32": 1132,
+    "51,32": 1151,
+    "52,32": 1187,
+    "53,32": 1206,
+    "54,32": 1242,
+    "55,32": 1255,
+    "56,32": 1276,
+    "57,32": 1295,
+    "58,32": 1330,
+    "59,32": 1350,
+    "60,32": 1385,
+    "61,32": 1405,
+    "62,32": 1440,
+    "63,32": 1450,
+    "64,32": 1462,
+    "65,32": 1479,
+    "66,32": 1503,
+    "67,32": 1520,
+    "68,32": 1544,
+    "69,32": 1561,
+    "70,32": 1585,
+    "71,32": 1596,
+    "72,32": 1609,
+    "73,32": 1626,
+    "74,32": 1649,
+    "75,32": 1667,
+    "76,32": 1690,
+    "77,32": 1706,
+    "1,33": 14,
+    "3,33": 55,
+    "5,33": 96,
+    "9,33": 161,
+    "11,33": 202,
+    "13,33": 243,
+    "17,33": 305,
+    "19,33": 360,
+    "21,33": 415,
+    "25,33": 504,
+    "27,33": 559,
+    "29,33": 614,
+    "33,33": 700,
+    "35,33": 755,
+    "37,33": 810,
+    "41,33": 899,
+    "43,33": 954,
+    "45,33": 1009,
+    "49,33": 1095,
+    "51,33": 1150,
+    "53,33": 1205,
+    "57,33": 1294,
+    "59,33": 1349,
+    "61,33": 1404,
+    "65,33": 1478,
+    "67,33": 1519,
+    "69,33": 1560,
+    "73,33": 1625,
+    "75,33": 1666,
+    "77,33": 1705,
+    "1,34": 13,
+    "3,34": 54,
+    "5,34": 95,
+    "7,34": 131,
+    "9,34": 160,
+    "11,34": 201,
+    "13,34": 242,
+    "15,34": 276,
+    "17,34": 304,
+    "19,34": 359,
+    "21,34": 414,
+    "23,34": 464,
+    "25,34": 503,
+    "27,34": 558,
+    "29,34": 613,
+    "31,34": 661,
+    "33,34": 699,
+    "35,34": 754,
+    "37,34": 809,
+    "39,34": 859,
+    "41,34": 898,
+    "43,34": 953,
+    "45,34": 1008,
+    "47,34": 1056,
+    "49,34": 1094,
+    "51,34": 1149,
+    "53,34": 1204,
+    "55,34": 1254,
+    "57,34": 1293,
+    "59,34": 1348,
+    "61,34": 1403,
+    "63,34": 1449,
+    "65,34": 1477,
+    "67,34": 1518,
+    "69,34": 1559,
+    "71,34": 1595,
+    "73,34": 1624,
+    "75,34": 1665,
+    "77,34": 1704,
+    "1,35": 12,
+    "3,35": 53,
+    "5,35": 94,
+    "9,35": 159,
+    "11,35": 200,
+    "13,35": 241,
+    "17,35": 303,
+    "19,35": 358,
+    "21,35": 413,
+    "25,35": 502,
+    "27,35": 557,
+    "29,35": 612,
+    "33,35": 698,
+    "35,35": 753,
+    "37,35": 808,
+    "41,35": 897,
+    "43,35": 952,
+    "45,35": 1007,
+    "49,35": 1093,
+    "51,35": 1148,
+    "53,35": 1203,
+    "57,35": 1292,
+    "59,35": 1347,
+    "61,35": 1402,
+    "65,35": 1476,
+    "67,35": 1517,
+    "69,35": 1558,
+    "73,35": 1623,
+    "75,35": 1664,
+    "77,35": 1703,
+    "1,36": 11,
+    "3,36": 52,
+    "5,36": 93,
+    "7,36": 130,
+    "9,36": 158,
+    "11,36": 199,
+    "13,36": 240,
+    "15,36": 275,
+    "17,36": 302,
+    "19,36": 357,
+    "21,36": 412,
+    "23,36": 463,
+    "25,36": 501,
+    "27,36": 556,
+    "29,36": 611,
+    "31,36": 660,
+    "33,36": 697,
+    "35,36": 752,
+    "37,36": 807,
+    "39,36": 858,
+    "41,36": 896,
+    "43,36": 951,
+    "45,36": 1006,
+    "47,36": 1055,
+    "49,36": 1092,
+    "51,36": 1147,
+    "53,36": 1202,
+    "55,36": 1253,
+    "57,36": 1291,
+    "59,36": 1346,
+    "61,36": 1401,
+    "63,36": 1448,
+    "65,36": 1475,
+    "67,36": 1516,
+    "69,36": 1557,
+    "71,36": 1594,
+    "73,36": 1622,
+    "75,36": 1663,
+    "77,36": 1702,
+    "1,37": 10,
+    "3,37": 51,
+    "5,37": 92,
+    "7,37": 129,
+    "9,37": 157,
+    "11,37": 198,
+    "13,37": 239,
+    "15,37": 274,
+    "17,37": 301,
+    "19,37": 356,
+    "21,37": 411,
+    "23,37": 462,
+    "25,37": 500,
+    "27,37": 555,
+    "29,37": 610,
+    "31,37": 659,
+    "33,37": 696,
+    "35,37": 751,
+    "37,37": 806,
+    "39,37": 857,
+    "41,37": 895,
+    "43,37": 950,
+    "45,37": 1005,
+    "47,37": 1054,
+    "49,37": 1091,
+    "51,37": 1146,
+    "53,37": 1201,
+    "55,37": 1252,
+    "57,37": 1290,
+    "59,37": 1345,
+    "61,37": 1400,
+    "63,37": 1447,
+    "65,37": 1474,
+    "67,37": 1515,
+    "69,37": 1556,
+    "71,37": 1593,
+    "73,37": 1621,
+    "75,37": 1662,
+    "77,37": 1701,
+    "1,38": 9,
+    "3,38": 50,
+    "5,38": 91,
+    "7,38": 128,
+    "9,38": 156,
+    "11,38": 197,
+    "13,38": 238,
+    "15,38": 273,
+    "17,38": 300,
+    "19,38": 355,
+    "21,38": 410,
+    "23,38": 461,
+    "25,38": 499,
+    "27,38": 554,
+    "29,38": 609,
+    "31,38": 658,
+    "33,38": 695,
+    "35,38": 750,
+    "37,38": 805,
+    "39,38": 856,
+    "41,38": 894,
+    "43,38": 949,
+    "45,38": 1004,
+    "47,38": 1053,
+    "49,38": 1090,
+    "51,38": 1145,
+    "53,38": 1200,
+    "55,38": 1251,
+    "57,38": 1289,
+    "59,38": 1344,
+    "61,38": 1399,
+    "63,38": 1446,
+    "65,38": 1473,
+    "67,38": 1514,
+    "69,38": 1555,
+    "71,38": 1592,
+    "73,38": 1620,
+    "75,38": 1661,
+    "77,38": 1700,
+    "1,39": 8,
+    "3,39": 49,
+    "5,39": 90,
+    "9,39": 155,
+    "11,39": 196,
+    "13,39": 237,
+    "17,39": 299,
+    "19,39": 354,
+    "21,39": 409,
+    "25,39": 498,
+    "27,39": 553,
+    "29,39": 608,
+    "33,39": 694,
+    "35,39": 749,
+    "37,39": 804,
+    "41,39": 893,
+    "43,39": 948,
+    "45,39": 1003,
+    "49,39": 1089,
+    "51,39": 1144,
+    "53,39": 1199,
+    "57,39": 1288,
+    "59,39": 1343,
+    "61,39": 1398,
+    "65,39": 1472,
+    "67,39": 1513,
+    "69,39": 1554,
+    "73,39": 1619,
+    "75,39": 1660,
+    "77,39": 1699,
+    "1,40": 7,
+    "3,40": 48,
+    "5,40": 89,
+    "7,40": 127,
+    "9,40": 154,
+    "11,40": 195,
+    "13,40": 236,
+    "15,40": 272,
+    "17,40": 298,
+    "19,40": 353,
+    "21,40": 408,
+    "23,40": 460,
+    "25,40": 497,
+    "27,40": 552,
+    "29,40": 607,
+    "31,40": 657,
+    "33,40": 693,
+    "35,40": 748,
+    "37,40": 803,
+    "39,40": 855,
+    "41,40": 892,
+    "43,40": 947,
+    "45,40": 1002,
+    "47,40": 1052,
+    "49,40": 1088,
+    "51,40": 1143,
+    "53,40": 1198,
+    "55,40": 1250,
+    "57,40": 1287,
+    "59,40": 1342,
+    "61,40": 1397,
+    "63,40": 1445,
+    "65,40": 1471,
+    "67,40": 1512,
+    "69,40": 1553,
+    "71,40": 1591,
+    "73,40": 1618,
+    "75,40": 1659,
+    "77,40": 1698,
+    "1,41": 6,
+    "3,41": 47,
+    "5,41": 88,
+    "9,41": 153,
+    "11,41": 194,
+    "13,41": 235,
+    "17,41": 297,
+    "19,41": 352,
+    "21,41": 407,
+    "25,41": 496,
+    "27,41": 551,
+    "29,41": 606,
+    "33,41": 692,
+    "35,41": 747,
+    "37,41": 802,
+    "41,41": 891,
+    "43,41": 946,
+    "45,41": 1001,
+    "49,41": 1087,
+    "51,41": 1142,
+    "53,41": 1197,
+    "57,41": 1286,
+    "59,41": 1341,
+    "61,41": 1396,
+    "65,41": 1470,
+    "67,41": 1511,
+    "69,41": 1552,
+    "73,41": 1617,
+    "75,41": 1658,
+    "77,41": 1697,
+    "1,42": 5,
+    "2,42": 38,
+    "3,42": 46,
+    "4,42": 79,
+    "5,42": 87,
+    "6,42": 120,
+    "7,42": 126,
+    "8,42": 144,
+    "9,42": 152,
+    "10,42": 184,
+    "11,42": 193,
+    "12,42": 225,
+    "13,42": 234,
+    "14,42": 266,
+    "15,42": 271,
+    "16,42": 288,
+    "17,42": 296,
+    "18,42": 341,
+    "19,42": 351,
+    "20,42": 396,
+    "21,42": 406,
+    "22,42": 451,
+    "23,42": 459,
+    "24,42": 485,
+    "25,42": 495,
+    "26,42": 539,
+    "27,42": 550,
+    "28,42": 594,
+    "29,42": 605,
+    "30,42": 649,
+    "31,42": 656,
+    "32,42": 681,
+    "33,42": 691,
+    "34,42": 736,
+    "35,42": 746,
+    "36,42": 791,
+    "37,42": 801,
+    "38,42": 846,
+    "39,42": 854,
+    "40,42": 880,
+    "41,42": 890,
+    "42,42": 934,
+    "43,42": 945,
+    "44,42": 989,
+    "45,42": 1000,
+    "46,42": 1044,
+    "47,42": 1051,
+    "48,42": 1076,
+    "49,42": 1086,
+    "50,42": 1131,
+    "51,42": 1141,
+    "52,42": 1186,
+    "53,42": 1196,
+    "54,42": 1241,
+    "55,42": 1249,
+    "56,42": 1275,
+    "57,42": 1285,
+    "58,42": 1329,
+    "59,42": 1340,
+    "60,42": 1384,
+    "61,42": 1395,
+    "62,42": 1439,
+    "63,42": 1444,
+    "64,42": 1461,
+    "65,42": 1469,
+    "66,42": 1502,
+    "67,42": 1510,
+    "68,42": 1543,
+    "69,42": 1551,
+    "70,42": 1584,
+    "71,42": 1590,
+    "72,42": 1608,
+    "73,42": 1616,
+    "74,42": 1648,
+    "75,42": 1657,
+    "76,42": 1689,
+    "77,42": 1696,
+    "1,43": 4,
+    "3,43": 45,
+    "5,43": 86,
+    "9,43": 151,
+    "11,43": 192,
+    "13,43": 233,
+    "17,43": 295,
+    "19,43": 350,
+    "21,43": 405,
+    "25,43": 494,
+    "27,43": 549,
+    "29,43": 604,
+    "33,43": 690,
+    "35,43": 745,
+    "37,43": 800,
+    "41,43": 889,
+    "43,43": 944,
+    "45,43": 999,
+    "49,43": 1085,
+    "51,43": 1140,
+    "53,43": 1195,
+    "57,43": 1284,
+    "59,43": 1339,
+    "61,43": 1394,
+    "65,43": 1468,
+    "67,43": 1509,
+    "69,43": 1550,
+    "73,43": 1615,
+    "75,43": 1656,
+    "77,43": 1695,
+    "1,44": 3,
+    "2,44": 37,
+    "3,44": 44,
+    "4,44": 78,
+    "5,44": 85,
+    "6,44": 119,
+    "7,44": 125,
+    "8,44": 143,
+    "9,44": 150,
+    "10,44": 183,
+    "11,44": 191,
+    "12,44": 224,
+    "13,44": 232,
+    "14,44": 265,
+    "15,44": 270,
+    "16,44": 287,
+    "17,44": 294,
+    "18,44": 340,
+    "19,44": 349,
+    "20,44": 395,
+    "21,44": 404,
+    "22,44": 450,
+    "23,44": 458,
+    "24,44": 484,
+    "25,44": 493,
+    "26,44": 538,
+    "27,44": 548,
+    "28,44": 593,
+    "29,44": 603,
+    "30,44": 648,
+    "31,44": 655,
+    "32,44": 680,
+    "33,44": 689,
+    "34,44": 735,
+    "35,44": 744,
+    "36,44": 790,
+    "37,44": 799,
+    "38,44": 845,
+    "39,44": 853,
+    "40,44": 879,
+    "41,44": 888,
+    "42,44": 933,
+    "43,44": 943,
+    "44,44": 988,
+    "45,44": 998,
+    "46,44": 1043,
+    "47,44": 1050,
+    "48,44": 1075,
+    "49,44": 1084,
+    "50,44": 1130,
+    "51,44": 1139,
+    "52,44": 1185,
+    "53,44": 1194,
+    "54,44": 1240,
+    "55,44": 1248,
+    "56,44": 1274,
+    "57,44": 1283,
+    "58,44": 1328,
+    "59,44": 1338,
+    "60,44": 1383,
+    "61,44": 1393,
+    "62,44": 1438,
+    "63,44": 1443,
+    "64,44": 1460,
+    "65,44": 1467,
+    "66,44": 1501,
+    "67,44": 1508,
+    "68,44": 1542,
+    "69,44": 1549,
+    "70,44": 1583,
+    "71,44": 1589,
+    "72,44": 1607,
+    "73,44": 1614,
+    "74,44": 1647,
+    "75,44": 1655,
+    "76,44": 1688,
+    "77,44": 1694,
+    "1,45": 2,
+    "3,45": 43,
+    "5,45": 84,
+    "9,45": 149,
+    "11,45": 190,
+    "13,45": 231,
+    "17,45": 293,
+    "19,45": 348,
+    "21,45": 403,
+    "25,45": 492,
+    "27,45": 547,
+    "29,45": 602,
+    "33,45": 688,
+    "35,45": 743,
+    "37,45": 798,
+    "41,45": 887,
+    "43,45": 942,
+    "45,45": 997,
+    "49,45": 1083,
+    "51,45": 1138,
+    "53,45": 1193,
+    "57,45": 1282,
+    "59,45": 1337,
+    "61,45": 1392,
+    "65,45": 1466,
+    "67,45": 1507,
+    "69,45": 1548,
+    "73,45": 1613,
+    "75,45": 1654,
+    "77,45": 1693,
+    "11,46": 189,
+    "13,46": 230,
+    "27,46": 546,
+    "29,46": 601,
+    "43,46": 941,
+    "45,46": 996,
+    "59,46": 1336,
+    "61,46": 1391,
+    "75,46": 1653,
+    "77,46": 1692,
+    "1,47": 1,
+    "2,47": 36,
+    "3,47": 42,
+    "4,47": 77,
+    "5,47": 83,
+    "6,47": 118,
+    "7,47": 124,
+    "8,47": 142,
+    "9,47": 148,
+    "17,47": 292,
+    "18,47": 339,
+    "19,47": 347,
+    "20,47": 394,
+    "21,47": 402,
+    "22,47": 449,
+    "23,47": 457,
+    "24,47": 483,
+    "25,47": 491,
+    "33,47": 687,
+    "34,47": 734,
+    "35,47": 742,
+    "36,47": 789,
+    "37,47": 797,
+    "38,47": 844,
+    "39,47": 852,
+    "40,47": 878,
+    "41,47": 886,
+    "49,47": 1082,
+    "50,47": 1129,
+    "51,47": 1137,
+    "52,47": 1184,
+    "53,47": 1192,
+    "54,47": 1239,
+    "55,47": 1247,
+    "56,47": 1273,
+    "57,47": 1281,
+    "65,47": 1465,
+    "66,47": 1500,
+    "67,47": 1506,
+    "68,47": 1541,
+    "69,47": 1547,
+    "70,47": 1582,
+    "71,47": 1588,
+    "72,47": 1606,
+    "73,47": 1612
+  },
+  "total_path_cells": 1696,
+  "unique_path_ids": 1696
+}
\ No newline at end of file
diff --git a/run_algorithm.py b/run_algorithm.py
new file mode 100644
index 0000000..6ae84d8
--- /dev/null
+++ b/run_algorithm.py
@@ -0,0 +1,216 @@
+#!/usr/bin/env python3
+import sys
+import os
+import signal
+import logging
+from typing import Optional
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+
+from common.utils import setup_logging
+from config.settings import (
+    ALGORITHM_SERVER_HOST, ALGORITHM_SERVER_PORT, LOG_LEVEL, LOG_FILE,
+    RCS_SERVER_HOST, RCS_SERVER_PORT, MONITOR_POLLING_INTERVAL
+)
+from algorithm_system.algorithm_server import AlgorithmServer
+
+
+class AlgorithmApplication:
+    
+    def __init__(self, host: str = None, port: int = None, log_level: str = None, 
+                 enable_path_monitor: bool = True, monitor_interval: float = None,
+                 rcs_host: str = None, rcs_port: int = None):
+        # Initialize algorithm system application
+        self.host = host or ALGORITHM_SERVER_HOST
+        self.port = port or ALGORITHM_SERVER_PORT
+        self.log_level = log_level or LOG_LEVEL
+        self.enable_path_monitor = enable_path_monitor
+        self.monitor_interval = monitor_interval or MONITOR_POLLING_INTERVAL
+        self.rcs_host = rcs_host or RCS_SERVER_HOST
+        self.rcs_port = rcs_port or RCS_SERVER_PORT
+        
+        setup_logging(self.log_level, LOG_FILE)
+        self.logger = logging.getLogger(__name__)
+        
+        self.server: Optional[AlgorithmServer] = None
+        
+        signal.signal(signal.SIGINT, self.signal_handler)
+        signal.signal(signal.SIGTERM, self.signal_handler)
+    
+    def signal_handler(self, signum, frame):
+        # Handle system signals, shutdown program
+        self.logger.info(f"Received signal {signum}, shutting down algorithm system...")
+        self.shutdown()
+        sys.exit(0)
+    
+    def start_server(self):
+        # Start algorithm server
+        try:
+            self.logger.info("Initializing algorithm system server...")
+            
+            # Set RCS connection configuration
+            os.environ['RCS_SERVER_HOST'] = self.rcs_host
+            os.environ['RCS_SERVER_PORT'] = str(self.rcs_port)
+            
+            self.server = AlgorithmServer(self.host, self.port, self.enable_path_monitor, self.monitor_interval)
+            
+            status = self.server.get_server_status()
+            self.logger.info("Algorithm system server status:")
+            self.logger.info(f"  - Host: {status['host']}")
+            self.logger.info(f"  - Port: {status['port']}")
+            self.logger.info(f"  - Path mapping loaded: {status['path_mapping_loaded']}")
+            self.logger.info(f"  - AGV count: {status['agv_count']}")
+            self.logger.info(f"  - Task allocation algorithm: {status['algorithms']['task_allocation']}")
+            self.logger.info(f"  - Path planning algorithm: {status['algorithms']['path_planning']}")
+            
+            self.logger.info("Algorithm system server initialization completed")
+            
+            self.server.start_server()
+            
+        except KeyboardInterrupt:
+            self.logger.info("Received interrupt signal, shutting down algorithm server...")
+        except Exception as e:
+            self.logger.error(f"Algorithm server startup failed: {e}")
+            raise
+        finally:
+            self.shutdown()
+    
+    def shutdown(self):
+        # Shutdown algorithm system components
+        self.logger.info("Shutting down algorithm system...")
+        
+        if self.server:
+            try:
+                self.server.stop_server()
+            except Exception as e:
+                self.logger.error(f"Failed to shutdown server: {e}")
+        
+        self.logger.info("Algorithm system shutdown completed")
+
+
+def main():
+    # Main function entry point
+    import argparse
+    
+    parser = argparse.ArgumentParser(description="Algorithm System - Provides task allocation and path planning services")
+    parser.add_argument(
+        "--host",
+        default=ALGORITHM_SERVER_HOST,
+        help=f"Algorithm server host address (default: {ALGORITHM_SERVER_HOST})"
+    )
+    parser.add_argument(
+        "--port",
+        type=int,
+        default=ALGORITHM_SERVER_PORT,
+        help=f"Algorithm server port (default: {ALGORITHM_SERVER_PORT})"
+    )
+    parser.add_argument(
+        "--log-level",
+        choices=["DEBUG", "INFO", "WARNING", "ERROR"],
+        default="DEBUG",
+        help=f"Log level (default: DEBUG)"
+    )
+    parser.add_argument(
+        "--task-algorithm",
+        choices=["NEAREST_FIRST", "LOAD_BALANCED", "PRIORITY_FIRST", "MULTI_OBJECTIVE"],
+        default="LOAD_BALANCED",
+        help="Task allocation algorithm (default: LOAD_BALANCED)"
+    )
+    parser.add_argument(
+        "--path-algorithm",
+        choices=["A_STAR", "DIJKSTRA", "GREEDY"],
+        default="DIJKSTRA",
+        help="Path planning algorithm (default: DIJKSTRA)"
+    )
+    parser.add_argument(
+        "--enable-path-monitor",
+        action="store_true",
+        default=True,
+        help="Enable path monitoring service (default: True)"
+    )
+    parser.add_argument(
+        "--disable-path-monitor",
+        action="store_true",
+        help="Disable path monitoring service"
+    )
+    parser.add_argument(
+        "--monitor-interval",
+        type=float,
+        default=MONITOR_POLLING_INTERVAL,
+        help=f"Path monitoring polling interval in seconds (default: {MONITOR_POLLING_INTERVAL})"
+    )
+    parser.add_argument(
+        "--rcs-host",
+        default=RCS_SERVER_HOST,
+        help=f"RCS server host address (default: {RCS_SERVER_HOST})"
+    )
+    parser.add_argument(
+        "--rcs-port",
+        type=int,
+        default=RCS_SERVER_PORT,
+        help=f"RCS server port (default: {RCS_SERVER_PORT})"
+    )
+    
+    args = parser.parse_args()
+    
+    # Handle path monitoring switch
+    enable_path_monitor = args.enable_path_monitor and not args.disable_path_monitor
+    
+    app = AlgorithmApplication(
+        host=args.host,
+        port=args.port,
+        log_level=args.log_level,
+        enable_path_monitor=enable_path_monitor,
+        monitor_interval=args.monitor_interval,
+        rcs_host=args.rcs_host,
+        rcs_port=args.rcs_port
+    )
+    
+    try:
+        print("=" * 60)
+        print("CTU Warehouse Management System - Algorithm System")
+        print("=" * 60)
+        print(f"Server Address: http://{args.host}:{args.port}")
+        print(f"Task Allocation Algorithm: {args.task_algorithm}")
+        print(f"Path Planning Algorithm: {args.path_algorithm}")
+        print(f"Log Level: {args.log_level}")
+        print(f"Path Monitoring Service: {'Enabled' if enable_path_monitor else 'Disabled'}")
+        if enable_path_monitor:
+            print(f"Monitor Polling Interval: {args.monitor_interval}s")
+            print(f"RCS Server Address: {args.rcs_host}:{args.rcs_port}")
+        print("=" * 60)
+        print("Available APIs:")
+        print(f"  POST http://{args.host}:{args.port}/open/task/send/v1")
+        print(f"       - Task allocation API")
+        print(f"       - Supports new format: {{\"tasks\": [...], \"agvStatus\": [...]}}")
+        print(f"       - Compatible with old format: [task1, task2, ...]")
+        print(f"  POST http://{args.host}:{args.port}/open/path/plan/v1")
+        print(f"       - Path planning API")
+        print(f"  POST http://{args.host}:{args.port}/open/path/batch/plan/v1")
+        print(f"       - Batch path planning API")
+        print(f"  POST http://{args.host}:{args.port}/open/algorithm/config/v1")
+        print(f"       - Algorithm configuration API")
+        if enable_path_monitor:
+            print(f"  POST http://{args.host}:{args.port}/monitor/path/start/v1")
+            print(f"       - Start path monitoring service")
+            print(f"  POST http://{args.host}:{args.port}/monitor/path/stop/v1")
+            print(f"       - Stop path monitoring service")
+            print(f"  GET  http://{args.host}:{args.port}/monitor/path/status/v1")
+            print(f"       - Path monitoring service status query")
+        print(f"  GET  http://{args.host}:{args.port}/health")
+        print(f"       - Health check API")
+        print("=" * 60)
+        print("Press Ctrl+C to stop server")
+        print()
+        
+        app.start_server()
+        
+    except KeyboardInterrupt:
+        print("\nReceived interrupt signal, shutting down...")
+    except Exception as e:
+        print(f"Startup failed: {e}")
+        sys.exit(1)
+
+
+if __name__ == "__main__":
+    main() 
\ No newline at end of file

--
Gitblit v1.9.1