diff --git a/jdk_21_maven/cs/rest/arimaa/.gitattributes b/jdk_21_maven/cs/rest/arimaa/.gitattributes new file mode 100644 index 000000000..3b41682ac --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/jdk_21_maven/cs/rest/arimaa/.gitignore b/jdk_21_maven/cs/rest/arimaa/.gitignore new file mode 100644 index 000000000..e4012f1e5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/.gitignore @@ -0,0 +1,37 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +# .gitignore +.env + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +Database/secrets.env diff --git a/jdk_21_maven/cs/rest/arimaa/.mvn/wrapper/maven-wrapper.properties b/jdk_21_maven/cs/rest/arimaa/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 000000000..c595b0093 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip diff --git a/jdk_21_maven/cs/rest/arimaa/Database/create_vm_db.bat b/jdk_21_maven/cs/rest/arimaa/Database/create_vm_db.bat new file mode 100644 index 000000000..67f0bb0d5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/create_vm_db.bat @@ -0,0 +1,11 @@ + + +@echo off +REM Create db in a virtual environment. Cd into /database before running in command propmpt + +docker-compose up -d +timeout /t 10 +mysql --host=localhost --port=3307 --user=root --password=123456 < .\mysql\Sql_arimaa_init.sql +echo Database setup completed successfully.. I hope! +@REM "docker compose down" to remove environment +pause \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/docker-compose.mongodb.yml b/jdk_21_maven/cs/rest/arimaa/Database/docker-compose.mongodb.yml new file mode 100644 index 000000000..7e2d45c6e --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/docker-compose.mongodb.yml @@ -0,0 +1,15 @@ +# MongoDB (Document DB) +services: + mongodb: + image: mongo:7 + container_name: arimaadockermongodb + ports: + - "27017:27017" + volumes: + - mongodb_data:/data/db + hostname: arimaadockermongodb + +volumes: + mongodb_data: + driver: local + diff --git a/jdk_21_maven/cs/rest/arimaa/Database/docker-compose.mysql.yml b/jdk_21_maven/cs/rest/arimaa/Database/docker-compose.mysql.yml new file mode 100644 index 000000000..a7b2b1d77 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/docker-compose.mysql.yml @@ -0,0 +1,26 @@ +services: + mysqldb: + image: mysql:9.5.0 + container_name: arimaadockermysqldb + ports: + - "5000:3306" + environment: + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + + healthcheck: + test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root -p${MYSQL_ROOT_PASSWORD} --silent"] + interval: 10s + timeout: 5s + retries: 30 + start_period: 40s + + volumes: + - mysql_data:/var/lib/mysql + - ./mysql:/docker-entrypoint-initdb.d + + hostname: arimaadockermysqldb + +volumes: + mysql_data: + driver: local \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_10_init.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_10_init.sql new file mode 100644 index 000000000..3b53ad7bb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_10_init.sql @@ -0,0 +1,269 @@ +-- MySQL Script generated by MySQL Workbench +-- Tue Feb 24 18:24:54 2026 +-- Model: New Model Version: 1.0 +-- MySQL Workbench Forward Engineering + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Schema arimaadockermysqldb +-- ----------------------------------------------------- + +CREATE USER 'admin'@'%' IDENTIFIED BY 'AdminPassword123!'; +CREATE USER 'user'@'%' IDENTIFIED BY 'UserPassword123!'; + +GRANT ALL PRIVILEGES ON arimaadockermysqldb.* TO 'admin'@'%'; +GRANT SELECT, INSERT, UPDATE ON arimaadockermysqldb.* TO 'user'@'%'; + +FLUSH PRIVILEGES; +-- ----------------------------------------------------- +-- Schema arimaadockermysqldb +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `arimaadockermysqldb` DEFAULT CHARACTER SET utf8 ; +USE `arimaadockermysqldb` ; + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Puzzles` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Puzzles` ( + `id` INT NOT NULL, + `name` VARCHAR(45) NOT NULL, + `objective` VARCHAR(45) NOT NULL, + `playerSide` VARCHAR(6) NOT NULL, + `rounds` INT NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `name_UNIQUE` (`name` ASC) VISIBLE) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Countries` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Countries` ( + `id` INT NOT NULL, + `name` VARCHAR(45) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `name_UNIQUE` (`name` ASC) VISIBLE) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Players` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Players` ( + `id` INT NOT NULL, + `username` VARCHAR(32) NOT NULL, + `email` VARCHAR(255) NULL, + `password` VARCHAR(32) NOT NULL, + `create_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, + `rating` INT NULL, + `RU` INT NULL, + `games_played` INT NULL, + `countries_id` INT NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `username_UNIQUE` (`username`), + UNIQUE INDEX `email_UNIQUE` (`email`), + INDEX `fk_Players_Countries_idx` (`countries_id` ASC) VISIBLE, + INDEX `idx_players_rating` (`rating`), + INDEX `idx_players_ru` (`RU`), + + CONSTRAINT `fk_Players_Countries` + FOREIGN KEY (`countries_id`) + REFERENCES `arimaadockermysqldb`.`Countries` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Events` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Events` ( + `id` INT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(45) NOT NULL, + `isRated` TINYINT(1) NOT NULL, + PRIMARY KEY (`id`)) +ENGINE = InnoDB; + + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`GameTypes` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`GameTypes` ( + `id` INT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(45) NOT NULL, + `time_increment` INT NULL, + `time_reserve` INT NULL, + PRIMARY KEY (`id`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Matches` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Matches` ( + `id` INT NOT NULL, + `termination_type` VARCHAR(45) NOT NULL, + `player_id_silver` INT NOT NULL, + `player_id_gold` INT NOT NULL, + `gold_rating` INT NULL, + `silver_rating` INT NULL, + `match_result` VARCHAR(45) NOT NULL, + `events_id` INT NOT NULL, + `gameTypes_id` INT NOT NULL, + `timestamp` TIMESTAMP NULL, + PRIMARY KEY (`id`), + INDEX `fk_Matches_Players_Silver_idx` (`player_id_silver` ASC) VISIBLE, + INDEX `fk_Matches_Players_Gold_idx` (`player_id_gold` ASC) VISIBLE, + INDEX `fk_Matches_Events_idx` (`events_id` ASC) VISIBLE, + INDEX `fk_Matches_GameTypes_idx` (`gameTypes_id` ASC) VISIBLE, + INDEX `idx_matches_termination_result` (`termination_type`, `match_result`), + INDEX `idx_matches_gametype_result` (`gameTypes_id`, `match_result`), + INDEX `idx_matches_event_result` (`events_id`, `match_result`), + INDEX `idx_matches_silver_timestamp` (`player_id_silver`, `timestamp`), + INDEX `idx_matches_gold_timestamp` (`player_id_gold`, `timestamp`), + INDEX `idx_matches_timestamp` (`timestamp`), + + CONSTRAINT `fk_Matches_Players_Silver` + FOREIGN KEY (`player_id_silver`) + REFERENCES `arimaadockermysqldb`.`Players` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Matches_Players_Gold` + FOREIGN KEY (`player_id_gold`) + REFERENCES `arimaadockermysqldb`.`Players` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Matches_Events` + FOREIGN KEY (`events_id`) + REFERENCES `arimaadockermysqldb`.`Events` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Matches_GameTypes` + FOREIGN KEY (`gameTypes_id`) + REFERENCES `arimaadockermysqldb`.`GameTypes` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Position` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Position` ( + `id` INT NOT NULL AUTO_INCREMENT, + `color` VARCHAR(6) NOT NULL, + `piece` VARCHAR(4) NOT NULL, + `cordinate` VARCHAR(2) NOT NULL, + PRIMARY KEY (`id`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Moves` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Moves` ( + `id` INT NOT NULL AUTO_INCREMENT, + `turn` INT NOT NULL, + `sequence` INT NOT NULL, + `direction` VARCHAR(1) NOT NULL, + `status` VARCHAR(1) NOT NULL, -- Død eller levende | 0 eller 1 + `matches_id` INT NOT NULL, + `position_id` INT NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_Moves_position_idx` (`position_id` ASC) VISIBLE, + INDEX `fk_Moves_Matches_idx` (`matches_id` ASC) VISIBLE, + INDEX `idx_moves_match_turn_sequence` (`matches_id`, `turn`, `sequence`), + CONSTRAINT `fk_Moves_position` + FOREIGN KEY (`position_id`) + REFERENCES `arimaadockermysqldb`.`Position` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Moves_Matches` + FOREIGN KEY (`matches_id`) + REFERENCES `arimaadockermysqldb`.`Matches` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`OpeningsByMatch` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`OpeningsByMatch` ( + `id` INT NOT NULL AUTO_INCREMENT, + `matches_id` INT NOT NULL, + `position_id` INT NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_OpeningsByMatch_position_idx` (`position_id` ASC) VISIBLE, + INDEX `fk_OpeningsByMatch_Matches_idx` (`matches_id` ASC) VISIBLE, + CONSTRAINT `fk_OpeningsByMatch_position` + FOREIGN KEY (`position_id`) + REFERENCES `arimaadockermysqldb`.`Position` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_OpeningsByMatch_Matches` + FOREIGN KEY (`matches_id`) + REFERENCES `arimaadockermysqldb`.`Matches` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`OpeningsByPuzzle` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`OpeningsByPuzzle` ( + `id` INT NOT NULL AUTO_INCREMENT, + `position_id` INT NOT NULL, + `puzzles_id` INT NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_OpeningsByPuzzle_position_idx` (`position_id` ASC) VISIBLE, + INDEX `fk_OOpeningsByPuzzle_puzzles_idx` (`puzzles_id` ASC) VISIBLE, + CONSTRAINT `fk_OpeningsByPuzzle_position` + FOREIGN KEY (`position_id`) + REFERENCES `arimaadockermysqldb`.`Position` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_OpeningsByPuzzle_puzzles` + FOREIGN KEY (`puzzles_id`) + REFERENCES `arimaadockermysqldb`.`Puzzles` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `arimaadockermysqldb`.`Solutions` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Solutions` ( + `id` INT NOT NULL AUTO_INCREMENT, + `turn` INT NOT NULL, + `sequence` INT NOT NULL, + `direction` VARCHAR(1) NOT NULL, + `status` VARCHAR(1) NOT NULL, + `position_id` INT NOT NULL, + `puzzles_id` INT NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_Solution_position_idx` (`position_id` ASC) VISIBLE, + INDEX `fk_Solution_puzzles_idx` (`puzzles_id` ASC) VISIBLE, + CONSTRAINT `fk_Solution_position` + FOREIGN KEY (`position_id`) + REFERENCES `arimaadockermysqldb`.`Position` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_Solution_puzzles` + FOREIGN KEY (`puzzles_id`) + REFERENCES `arimaadockermysqldb`.`Puzzles` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + + + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_20_support.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_20_support.sql new file mode 100644 index 000000000..94346cdbd --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_20_support.sql @@ -0,0 +1,30 @@ +-- Support objects for routines/triggers/events +-- Execution order: after Sql_arimaa_init.sql + +USE `arimaadockermysqldb`; + +CREATE TABLE IF NOT EXISTS `audit_log` ( + `id` INT NOT NULL AUTO_INCREMENT, + `table_name` VARCHAR(50), + `operation` VARCHAR(10), + `record_id` INT, + `old_value` JSON, + `new_value` JSON, + `changed_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS `match_summary` ( + `gametype` VARCHAR(45) NOT NULL, + `total_matches` INT NOT NULL, + `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`gametype`) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS `daily_match_stats` ( + `stat_date` DATE NOT NULL, + `total_matches` INT NOT NULL, + PRIMARY KEY (`stat_date`) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS `Matches_Archive` LIKE `Matches`; diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_30_procedures.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_30_procedures.sql new file mode 100644 index 000000000..7083bbb62 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_30_procedures.sql @@ -0,0 +1,193 @@ +-- Stored procedures +-- Requires: Sql_arimaa_init.sql, Sql_arimaa_20_support.sql + +USE `arimaadockermysqldb`; + +DELIMITER $$ + +DROP PROCEDURE IF EXISTS `get_top_and_bottom_players`$$ +CREATE PROCEDURE `get_top_and_bottom_players`() +BEGIN + SELECT id, username, rating + FROM Players + WHERE rating IS NOT NULL + ORDER BY rating DESC + LIMIT 5; + + SELECT id, username, rating + FROM Players + WHERE rating IS NOT NULL + ORDER BY rating ASC + LIMIT 5; +END$$ + +DROP PROCEDURE IF EXISTS `get_total_matches`$$ +CREATE PROCEDURE `get_total_matches`() +BEGIN + SELECT COUNT(*) AS total_matches + FROM Matches; +END$$ + +DROP PROCEDURE IF EXISTS `get_total_players`$$ +CREATE PROCEDURE `get_total_players`() +BEGIN + SELECT COUNT(*) AS total_players + FROM Players; +END$$ + +DROP PROCEDURE IF EXISTS `get_matches_played_by_player`$$ +CREATE PROCEDURE `get_matches_played_by_player`( + IN p_player_id INT +) +BEGIN + SELECT COUNT(*) AS matches_played + FROM Matches + WHERE player_id_silver = p_player_id + OR player_id_gold = p_player_id; +END$$ + +DROP PROCEDURE IF EXISTS `get_player_match_stats`$$ +CREATE PROCEDURE `get_player_match_stats`( + IN p_player_id INT +) +BEGIN + SELECT + COUNT(*) AS matches_played, + SUM(CASE WHEN match_result = 'WIN' THEN 1 ELSE 0 END) AS wins, + SUM(CASE WHEN match_result = 'LOSS' THEN 1 ELSE 0 END) AS losses + FROM Matches + WHERE player_id_silver = p_player_id + OR player_id_gold = p_player_id; +END$$ + +DROP PROCEDURE IF EXISTS `get_player_matches_by_gametype`$$ +CREATE PROCEDURE `get_player_matches_by_gametype`( + IN p_player_id INT, + IN p_gametype VARCHAR(45) +) +BEGIN + SELECT COUNT(*) AS matches_played + FROM Matches m + JOIN GameTypes gt ON gt.id = m.gameTypes_id + WHERE gt.name = p_gametype + AND (m.player_id_silver = p_player_id OR m.player_id_gold = p_player_id); +END$$ + +DROP PROCEDURE IF EXISTS `get_player_count_by_country`$$ +CREATE PROCEDURE `get_player_count_by_country`() +BEGIN + SELECT + c.name AS country, + COUNT(p.id) AS player_count + FROM Countries c + LEFT JOIN Players p ON c.id = p.countries_id + GROUP BY c.id, c.name + ORDER BY player_count DESC; +END$$ + +DROP PROCEDURE IF EXISTS `get_leaderboard_by_gametype`$$ +CREATE PROCEDURE `get_leaderboard_by_gametype`( + IN p_gametype VARCHAR(45) +) +BEGIN + SELECT + p.id, + p.username, + COUNT(m.id) AS matches_played + FROM Players p + JOIN Matches m ON p.id IN (m.player_id_silver, m.player_id_gold) + JOIN GameTypes gt ON gt.id = m.gameTypes_id + WHERE gt.name = p_gametype + GROUP BY p.id, p.username + ORDER BY matches_played DESC; +END$$ + +DROP PROCEDURE IF EXISTS `get_event_participation`$$ +CREATE PROCEDURE `get_event_participation`() +BEGIN + SELECT + e.name AS event_name, + COUNT(m.id) AS matches_played + FROM Events e + LEFT JOIN Matches m ON e.id = m.events_id + GROUP BY e.id, e.name; +END$$ + +DROP PROCEDURE IF EXISTS `get_player_activity_by_month`$$ +CREATE PROCEDURE `get_player_activity_by_month`() +BEGIN + SELECT + YEAR(`timestamp`) AS `year`, + MONTH(`timestamp`) AS `month`, + COUNT(*) AS matches_played + FROM Matches + GROUP BY YEAR(`timestamp`), MONTH(`timestamp`) + ORDER BY `year`, `month`; +END$$ + +DROP PROCEDURE IF EXISTS `find_invalid_matches`$$ +CREATE PROCEDURE `find_invalid_matches`() +BEGIN + SELECT * + FROM Matches + WHERE player_id_silver = player_id_gold; +END$$ + +DROP PROCEDURE IF EXISTS `find_players_without_rating`$$ +CREATE PROCEDURE `find_players_without_rating`() +BEGIN + SELECT id, username + FROM Players + WHERE rating IS NULL; +END$$ + +DROP PROCEDURE IF EXISTS `find_matches_without_moves`$$ +CREATE PROCEDURE `find_matches_without_moves`() +BEGIN + SELECT m.id + FROM Matches m + LEFT JOIN Moves mv ON m.id = mv.matches_id + WHERE mv.id IS NULL; +END$$ + +DROP PROCEDURE IF EXISTS `archive_old_matches`$$ +CREATE PROCEDURE `archive_old_matches`( + IN p_years INT +) +BEGIN + INSERT IGNORE INTO Matches_Archive + SELECT * + FROM Matches + WHERE `timestamp` < DATE_SUB(NOW(), INTERVAL p_years YEAR); + + DELETE FROM Matches + WHERE `timestamp` < DATE_SUB(NOW(), INTERVAL p_years YEAR); +END$$ + +DROP PROCEDURE IF EXISTS `recalc_games_played`$$ +CREATE PROCEDURE `recalc_games_played`() +BEGIN + UPDATE Players p + SET games_played = ( + SELECT COUNT(*) + FROM Matches m + WHERE p.id IN (m.player_id_silver, m.player_id_gold) + ); +END$$ + +DROP PROCEDURE IF EXISTS `build_match_summary`$$ +CREATE PROCEDURE `build_match_summary`() +BEGIN + DELETE FROM match_summary; + + INSERT INTO match_summary (gametype, total_matches) + SELECT gt.name, COUNT(*) + FROM Matches m + JOIN GameTypes gt ON gt.id = m.gameTypes_id + GROUP BY gt.name; +END$$ + +DELIMITER ; + +-- Optional security setup (run manually when users exist): +-- GRANT EXECUTE ON PROCEDURE arimaadockermysqldb.get_event_participation TO 'report_user'@'%'; diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_40_triggers.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_40_triggers.sql new file mode 100644 index 000000000..6d3bd5df2 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_40_triggers.sql @@ -0,0 +1,273 @@ +-- Triggers +-- Requires: Sql_arimaa_init.sql, Sql_arimaa_20_support.sql + +USE `arimaadockermysqldb`; + +DELIMITER $$ + +DROP TRIGGER IF EXISTS `trg_players_update_audit`$$ +CREATE TRIGGER `trg_players_update_audit` +AFTER UPDATE ON Players +FOR EACH ROW +BEGIN + INSERT INTO audit_log ( + table_name, + operation, + record_id, + old_value, + new_value + ) + VALUES ( + 'Players', + 'UPDATE', + OLD.id, + JSON_OBJECT( + 'rating', OLD.rating, + 'country', OLD.countries_id + ), + JSON_OBJECT( + 'rating', NEW.rating, + 'country', NEW.countries_id + ) + ); +END$$ + +DROP TRIGGER IF EXISTS `trg_match_insert_update_games`$$ +DROP TRIGGER IF EXISTS `trg_prevent_self_play`$$ +DROP TRIGGER IF EXISTS `trg_set_match_time`$$ + +DROP TRIGGER IF EXISTS `trg_matches_before_insert`$$ +CREATE TRIGGER `trg_matches_before_insert` +BEFORE INSERT ON Matches +FOR EACH ROW +BEGIN + IF NEW.player_id_silver = NEW.player_id_gold THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'A player cannot play against themselves'; + END IF; + + IF NEW.`timestamp` IS NULL THEN + SET NEW.`timestamp` = CURRENT_TIMESTAMP; + END IF; +END$$ + +DROP TRIGGER IF EXISTS `trg_matches_before_update`$$ +CREATE TRIGGER `trg_matches_before_update` +BEFORE UPDATE ON Matches +FOR EACH ROW +BEGIN + IF NEW.player_id_silver = NEW.player_id_gold THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'A player cannot play against themselves'; + END IF; +END$$ + +DROP TRIGGER IF EXISTS `trg_matches_after_insert`$$ +CREATE TRIGGER `trg_matches_after_insert` +AFTER INSERT ON Matches +FOR EACH ROW +BEGIN + DECLARE v_gametype VARCHAR(45); + + UPDATE Players + SET games_played = IFNULL(games_played, 0) + 1 + WHERE id IN (NEW.player_id_silver, NEW.player_id_gold); + + SELECT name INTO v_gametype + FROM GameTypes + WHERE id = NEW.gameTypes_id; + + IF v_gametype IS NOT NULL THEN + INSERT INTO match_summary (gametype, total_matches) + VALUES (v_gametype, 1) + ON DUPLICATE KEY UPDATE total_matches = total_matches + 1; + END IF; + + INSERT INTO audit_log ( + table_name, + operation, + record_id, + old_value, + new_value + ) + VALUES ( + 'Matches', + 'INSERT', + NEW.id, + NULL, + JSON_OBJECT( + 'player_id_silver', NEW.player_id_silver, + 'player_id_gold', NEW.player_id_gold, + 'match_result', NEW.match_result, + 'events_id', NEW.events_id, + 'gameTypes_id', NEW.gameTypes_id, + 'timestamp', NEW.`timestamp` + ) + ); +END$$ + +DROP TRIGGER IF EXISTS `trg_matches_after_update`$$ +CREATE TRIGGER `trg_matches_after_update` +AFTER UPDATE ON Matches +FOR EACH ROW +BEGIN + DECLARE v_old_gametype VARCHAR(45); + DECLARE v_new_gametype VARCHAR(45); + + IF OLD.player_id_silver <> NEW.player_id_silver THEN + UPDATE Players + SET games_played = GREATEST(IFNULL(games_played, 0) - 1, 0) + WHERE id = OLD.player_id_silver; + + UPDATE Players + SET games_played = IFNULL(games_played, 0) + 1 + WHERE id = NEW.player_id_silver; + END IF; + + IF OLD.player_id_gold <> NEW.player_id_gold THEN + UPDATE Players + SET games_played = GREATEST(IFNULL(games_played, 0) - 1, 0) + WHERE id = OLD.player_id_gold; + + UPDATE Players + SET games_played = IFNULL(games_played, 0) + 1 + WHERE id = NEW.player_id_gold; + END IF; + + IF OLD.gameTypes_id <> NEW.gameTypes_id THEN + SELECT name INTO v_old_gametype + FROM GameTypes + WHERE id = OLD.gameTypes_id; + + SELECT name INTO v_new_gametype + FROM GameTypes + WHERE id = NEW.gameTypes_id; + + IF v_old_gametype IS NOT NULL THEN + UPDATE match_summary + SET total_matches = GREATEST(total_matches - 1, 0) + WHERE gametype = v_old_gametype; + + DELETE FROM match_summary + WHERE gametype = v_old_gametype + AND total_matches <= 0; + END IF; + + IF v_new_gametype IS NOT NULL THEN + INSERT INTO match_summary (gametype, total_matches) + VALUES (v_new_gametype, 1) + ON DUPLICATE KEY UPDATE total_matches = total_matches + 1; + END IF; + END IF; + + INSERT INTO audit_log ( + table_name, + operation, + record_id, + old_value, + new_value + ) + VALUES ( + 'Matches', + 'UPDATE', + NEW.id, + JSON_OBJECT( + 'player_id_silver', OLD.player_id_silver, + 'player_id_gold', OLD.player_id_gold, + 'match_result', OLD.match_result, + 'events_id', OLD.events_id, + 'gameTypes_id', OLD.gameTypes_id, + 'timestamp', OLD.`timestamp` + ), + JSON_OBJECT( + 'player_id_silver', NEW.player_id_silver, + 'player_id_gold', NEW.player_id_gold, + 'match_result', NEW.match_result, + 'events_id', NEW.events_id, + 'gameTypes_id', NEW.gameTypes_id, + 'timestamp', NEW.`timestamp` + ) + ); +END$$ + +DROP TRIGGER IF EXISTS `trg_matches_after_delete`$$ +CREATE TRIGGER `trg_matches_after_delete` +AFTER DELETE ON Matches +FOR EACH ROW +BEGIN + DECLARE v_gametype VARCHAR(45); + + UPDATE Players + SET games_played = GREATEST(IFNULL(games_played, 0) - 1, 0) + WHERE id IN (OLD.player_id_silver, OLD.player_id_gold); + + SELECT name INTO v_gametype + FROM GameTypes + WHERE id = OLD.gameTypes_id; + + IF v_gametype IS NOT NULL THEN + UPDATE match_summary + SET total_matches = GREATEST(total_matches - 1, 0) + WHERE gametype = v_gametype; + + DELETE FROM match_summary + WHERE gametype = v_gametype + AND total_matches <= 0; + END IF; + + INSERT INTO audit_log ( + table_name, + operation, + record_id, + old_value, + new_value + ) + VALUES ( + 'Matches', + 'DELETE', + OLD.id, + JSON_OBJECT( + 'player_id_silver', OLD.player_id_silver, + 'player_id_gold', OLD.player_id_gold, + 'match_result', OLD.match_result, + 'events_id', OLD.events_id, + 'gameTypes_id', OLD.gameTypes_id, + 'timestamp', OLD.`timestamp` + ), + NULL + ); +END$$ + +DROP TRIGGER IF EXISTS `trg_moves_before_insert_validate`$$ +CREATE TRIGGER `trg_moves_before_insert_validate` +BEFORE INSERT ON Moves +FOR EACH ROW +BEGIN + IF NEW.direction NOT IN ("n", "s", "e", "w", "x") THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Invalid move direction. Use N, S, E, or W.'; + END IF; + + IF NEW.status NOT IN ('0', '1') THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Invalid move status. Use 0 or 1.'; + END IF; +END$$ + +DROP TRIGGER IF EXISTS `trg_moves_before_update_validate`$$ +CREATE TRIGGER `trg_moves_before_update_validate` +BEFORE UPDATE ON Moves +FOR EACH ROW +BEGIN + IF NEW.direction NOT IN ("n", "s", "e", "w", "x") THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Invalid move direction. Use N, S, E, or W.'; + END IF; + + IF NEW.status NOT IN ('0', '1') THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Invalid move status. Use 0 or 1.'; + END IF; +END$$ + +DELIMITER ; diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_50_events.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_50_events.sql new file mode 100644 index 000000000..f0001732b --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_50_events.sql @@ -0,0 +1,36 @@ +-- Events +-- Requires: Sql_arimaa_init.sql, Sql_arimaa_20_support.sql, Sql_arimaa_30_procedures.sql + +USE `arimaadockermysqldb`; + +DELIMITER $$ + +-- Requires event scheduler enabled. +SET GLOBAL event_scheduler = ON$$ + +DROP EVENT IF EXISTS `ev_cleanup_audit_log`$$ +CREATE EVENT `ev_cleanup_audit_log` +ON SCHEDULE EVERY 30 DAY +DO +DELETE FROM audit_log +WHERE changed_at < DATE_SUB(NOW(), INTERVAL 1 YEAR)$$ + +DROP EVENT IF EXISTS `ev_recalculate_games`$$ +CREATE EVENT `ev_recalculate_games` +ON SCHEDULE EVERY 1 DAY +DO +CALL recalc_games_played()$$ + +DROP EVENT IF EXISTS `ev_daily_match_stats`$$ +CREATE EVENT `ev_daily_match_stats` +ON SCHEDULE EVERY 1 DAY +DO +INSERT INTO daily_match_stats (stat_date, total_matches) +SELECT CURDATE(), COUNT(*) +FROM Matches +WHERE DATE(`timestamp`) = CURDATE() +ON DUPLICATE KEY UPDATE total_matches = VALUES(total_matches)$$ + +DELIMITER ; + +-- Note: Event based on Events.end_date is omitted because the column does not exist in Sql_arimaa_init.sql. diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_60_views.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_60_views.sql new file mode 100644 index 000000000..e3cf333f5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_60_views.sql @@ -0,0 +1,231 @@ +USE `arimaadockermysqldb`; + +-- Views for Arimaa ERDB + +DROP VIEW IF EXISTS `view_total_matches`; +CREATE VIEW `view_total_matches` AS +SELECT COUNT(*) AS total_matches +FROM Matches; + +DROP VIEW IF EXISTS `view_total_players`; +CREATE VIEW `view_total_players` AS +SELECT COUNT(*) AS total_players +FROM Players; + +DROP VIEW IF EXISTS `view_players_with_countries`; +CREATE VIEW `view_players_with_countries` AS +SELECT + p.id AS player_id, + p.username, + p.email, + p.rating, + p.RU, + p.games_played, + p.create_time, + c.id AS country_id, + c.name AS country_name +FROM Players p + LEFT JOIN Countries c + ON p.countries_id = c.id; + +DROP VIEW IF EXISTS `view_player_count_by_country`; +CREATE VIEW `view_player_count_by_country` AS +SELECT + c.id AS country_id, + c.name AS country, + COUNT(p.id) AS player_count +FROM Countries c + LEFT JOIN Players p + ON c.id = p.countries_id +GROUP BY c.id, c.name; + +DROP VIEW IF EXISTS `view_matches_with_players`; +CREATE VIEW `view_matches_with_players` AS +SELECT + m.id AS match_id, + m.termination_type, + m.match_result, + m.timestamp, + silver.id AS silver_player_id, + silver.username AS silver_player_username, + gold.id AS gold_player_id, + gold.username AS gold_player_username, + gt.id AS gametype_id, + gt.name AS gametype_name, + gt.time_increment, + gt.time_reserve, + e.id AS event_id, + e.name AS event_name, + e.isRated +FROM Matches m + JOIN Players silver + ON m.player_id_silver = silver.id + JOIN Players gold + ON m.player_id_gold = gold.id + LEFT JOIN GameTypes gt + ON m.gameTypes_id = gt.id + LEFT JOIN Events e + ON m.events_id = e.id; + +DROP VIEW IF EXISTS `view_matches_without_moves`; +CREATE VIEW `view_matches_without_moves` AS +SELECT + m.id AS match_id, + m.termination_type, + m.match_result, + m.timestamp, + m.player_id_silver, + m.player_id_gold, + m.events_id, + m.gameTypes_id +FROM Matches m + LEFT JOIN Moves mv + ON m.id = mv.matches_id +WHERE mv.id IS NULL; + +DROP VIEW IF EXISTS `view_event_participation`; +CREATE VIEW `view_event_participation` AS +SELECT + e.id AS event_id, + e.name AS event_name, + COUNT(m.id) AS matches_played +FROM Events e + LEFT JOIN Matches m + ON e.id = m.events_id +GROUP BY e.id, e.name; + +DROP VIEW IF EXISTS `view_player_activity_by_month`; +CREATE VIEW `view_player_activity_by_month` AS +SELECT + YEAR(`timestamp`) AS `year`, + MONTH(`timestamp`) AS `month`, + COUNT(*) AS matches_played + FROM Matches + GROUP BY YEAR(`timestamp`), MONTH(`timestamp`); + +DROP VIEW IF EXISTS `view_match_moves`; +CREATE VIEW `view_match_moves` AS +SELECT + mv.id AS move_id, + mv.matches_id AS match_id, + mv.turn, + mv.sequence, + mv.direction, + mv.status, + p.id AS position_id, + p.color, + p.piece, + p.cordinate +FROM Moves mv + JOIN Position p + ON mv.position_id = p.id; + +DROP VIEW IF EXISTS `view_turn_moves`; +CREATE VIEW `view_turn_moves` AS +SELECT + mv.matches_id AS match_id, + mv.turn, + mv.id AS move_id, + mv.sequence, + mv.direction, + mv.status, + p.id AS position_id, + p.color, + p.piece, + p.cordinate +FROM Moves mv + JOIN Position p + ON mv.position_id = p.id; + + +-- ----------------------------------------------------- +-- Full replay-style view +-- Useful for showing a match together with its moves +-- ----------------------------------------------------- + +DROP VIEW IF EXISTS `view_match_replay`; +CREATE VIEW `view_match_replay` AS +SELECT + m.id AS match_id, + silver.username AS silver_player, + gold.username AS gold_player, + gt.name AS gametype_name, + e.name AS event_name, + m.match_result, + m.timestamp, + mv.id AS move_id, + mv.turn, + mv.sequence, + mv.direction, + mv.status, + p.color, + p.piece, + p.cordinate +FROM Matches m + JOIN Players silver + ON m.player_id_silver = silver.id + JOIN Players gold + ON m.player_id_gold = gold.id + LEFT JOIN GameTypes gt + ON m.gameTypes_id = gt.id + LEFT JOIN Events e + ON m.events_id = e.id + JOIN Moves mv + ON mv.matches_id = m.id + JOIN Position p + ON mv.position_id = p.id; + +DROP VIEW IF EXISTS `view_solutions_with_puzzles`; +CREATE VIEW `view_solutions_with_puzzles` AS +SELECT + s.id AS solution_id, + s.puzzles_id AS puzzle_id, + pu.name AS puzzle_name, + pu.objective, + pu.playerSide, + pu.rounds, + s.turn, + s.sequence, + s.direction, + s.status, + p.id AS position_id, + p.color, + p.piece, + p.cordinate +FROM Solutions s + JOIN Puzzles pu + ON s.puzzles_id = pu.id + JOIN Position p + ON s.position_id = p.id; + +DROP VIEW IF EXISTS `view_openings_by_match_details`; +CREATE VIEW `view_openings_by_match_details` AS +SELECT + obm.id AS opening_by_match_id, + obm.matches_id AS match_id, + p.id AS position_id, + p.color, + p.piece, + p.cordinate +FROM OpeningsByMatch obm + JOIN Position p + ON obm.position_id = p.id; + +DROP VIEW IF EXISTS `view_openings_by_puzzle_details`; +CREATE VIEW `view_openings_by_puzzle_details` AS +SELECT + obp.id AS opening_by_puzzle_id, + obp.puzzles_id AS puzzle_id, + pu.name AS puzzle_name, + pu.objective, + pu.playerSide, + pu.rounds, + p.id AS position_id, + p.color, + p.piece, + p.cordinate +FROM OpeningsByPuzzle obp + JOIN Puzzles pu + ON obp.puzzles_id = pu.id + JOIN Position p + ON obp.position_id = p.id; \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_61_data.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_61_data.sql new file mode 100644 index 000000000..40926a92f --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_61_data.sql @@ -0,0 +1,213 @@ +-- MySQL dump 10.13 Distrib 9.6.0, for Win64 (x86_64) +-- +-- Host: 127.0.0.1 Database: arimaadockermysqldb +-- ------------------------------------------------------ +-- Server version 9.5.0 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN; +SET @@SESSION.SQL_LOG_BIN= 0; + +-- +-- GTID state at the beginning of the backup +-- + +SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '67e7d330-1323-11f1-befa-0242ac130002:1-149013'; + +-- +-- Dumping data for table `Countries` +-- + +LOCK TABLES `Countries` WRITE; +/*!40000 ALTER TABLE `Countries` DISABLE KEYS */; +INSERT INTO `Countries` VALUES (0,'CA'),(5,'DE'),(4,'FR'),(2,'GB'),(3,'RU'),(6,'Unknown'),(1,'US'); +/*!40000 ALTER TABLE `Countries` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `Events` +-- + +LOCK TABLES `Events` WRITE; +/*!40000 ALTER TABLE `Events` DISABLE KEYS */; +INSERT INTO `Events` VALUES (8,'Casual game',0); +/*!40000 ALTER TABLE `Events` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `GameTypes` +-- + +LOCK TABLES `GameTypes` WRITE; +/*!40000 ALTER TABLE `GameTypes` DISABLE KEYS */; +INSERT INTO `GameTypes` VALUES (78,'15s/2m30s/100',15,150),(79,'8s/10s/100',8,10),(80,'8s/0/100',8,NULL),(81,'2/2/100/5/0',NULL,NULL),(82,'2/2/100/10/8',NULL,NULL),(83,'8s/0/0',8,NULL),(84,'2m/6m/100/0/7h12s/0',120,360),(85,'2m/6m/100/0/7h13s/0',120,360),(86,'2m/6m/100/0/8h/6m',120,360),(87,'0:30/3/100/5/8',NULL,NULL),(88,'15s/2m/100',15,120); +/*!40000 ALTER TABLE `GameTypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `Matches` +-- + +LOCK TABLES `Matches` WRITE; +/*!40000 ALTER TABLE `Matches` DISABLE KEYS */; +INSERT INTO `Matches` (`id`, `termination_type`, `player_id_silver`, `player_id_gold`, `match_result`, `events_id`, `gameTypes_id`, `timestamp`) VALUES + (669122,'r',16866,63152,'w',8,78,'2026-02-01 11:17:31'), + (669123,'g',16866,63152,'w',8,78,'2026-02-01 11:40:02'), + (669124,'g',16866,63152,'w',8,79,'2026-02-01 12:11:04'), + (669125,'g',63152,16866,'w',8,79,'2026-02-01 12:25:14'), + (669126,'m',63152,16866,'w',8,80,'2026-02-01 12:40:04'), + (669127,'g',371,63196,'b',8,81,'2026-02-01 12:37:28'), + (669128,'g',63194,4610,'b',8,82,'2026-02-01 12:53:05'), + (669129,'r',16866,63152,'w',8,80,'2026-02-01 13:00:25'), + (669130,'t',16866,63152,'w',8,83,'2026-02-01 13:13:45'), + (669131,'g',63152,16866,'b',8,83,'2026-02-01 13:17:24'), + (669132,'t',16866,63152,'w',8,83,'2026-02-01 13:25:35'), + (669133,'t',63152,16866,'b',8,83,'2026-02-01 13:32:25'), + (669134,'t',16866,63152,'w',8,83,'2026-02-01 13:39:15'), + (669135,'g',63152,16866,'b',8,83,'2026-02-01 13:44:46'), + (669136,'t',16866,63152,'w',8,83,'2026-02-01 13:49:25'), + (669137,'g',63152,16866,'b',8,83,'2026-02-01 13:52:44'), + (669138,'g',16866,63152,'w',8,83,'2026-02-01 13:59:55'), + (669139,'g',60869,57354,'w',8,84,'2026-02-01 17:09:59'), + (669140,'g',57354,60869,'b',8,85,'2026-02-01 17:37:18'), + (669141,'r',60869,57354,'b',8,85,'2026-02-01 18:02:22'), + (669142,'g',57354,19291,'w',8,86,'2026-02-01 18:54:23'), + (669143,'g',2320,51609,'w',8,87,'2026-02-01 18:52:52'), + (669144,'g',51609,2320,'b',8,87,'2026-02-01 19:43:30'), + (669145,'t',16866,63152,'w',8,83,'2026-02-02 06:08:09'), + (669146,'t',63152,16866,'b',8,83,'2026-02-02 06:17:19'), + (669147,'t',16866,63152,'w',8,83,'2026-02-02 06:22:59'), + (669148,'t',16866,63152,'w',8,83,'2026-02-02 06:29:39'), + (669149,'t',63152,16866,'b',8,83,'2026-02-02 06:36:20'), + (669150,'r',16866,63152,'w',8,83,'2026-02-02 06:48:50'), + (669151,'t',63152,16866,'b',8,83,'2026-02-02 06:56:40'), + (669152,'t',16866,63152,'w',8,83,'2026-02-02 07:00:50'), + (669153,'t',16866,63152,'w',8,83,'2026-02-02 07:03:20'), + (669154,'t',16866,63152,'w',8,83,'2026-02-02 07:09:50'), + (669155,'r',16866,63152,'w',8,83,'2026-02-02 07:15:30'), + (669156,'t',63152,16866,'b',8,83,'2026-02-02 07:17:30'), + (669157,'t',63152,16866,'b',8,83,'2026-02-02 07:25:22'), + (669158,'r',16866,63152,'w',8,83,'2026-02-02 07:27:51'), + (669159,'g',16866,63152,'b',8,80,'2026-02-02 09:26:28'), + (669160,'t',63102,371,'w',8,81,'2026-02-02 11:24:29'), + (669161,'g',63102,371,'w',8,81,'2026-02-02 11:46:11'), + (669162,'m',63152,16866,'w',8,80,'2026-02-02 12:11:57'), + (669163,'r',16866,63152,'w',8,80,'2026-02-02 12:45:30'), + (669164,'g',16866,63152,'b',8,80,'2026-02-02 12:54:09'), + (669165,'g',63152,16866,'b',8,80,'2026-02-02 13:31:41'), + (669166,'g',63152,16866,'w',8,80,'2026-02-02 13:48:40'), + (669167,'t',16866,63152,'w',8,80,'2026-02-02 14:08:52'), + (669168,'g',63152,16866,'w',8,80,'2026-02-02 14:22:51'), + (669169,'t',63152,16866,'b',8,80,'2026-02-02 14:32:14'), + (669170,'g',63152,16866,'w',8,80,'2026-02-02 14:36:02'), + (669171,'g',16866,63152,'w',8,80,'2026-02-03 01:37:03'), + (669172,'g',16866,63152,'w',8,80,'2026-02-03 01:50:33'), + (669173,'g',63152,16866,'b',8,80,'2026-02-03 02:07:56'), + (669174,'g',63152,16866,'w',8,80,'2026-02-03 02:16:17'), + (669175,'g',16866,63152,'b',8,80,'2026-02-03 06:38:39'), + (669176,'t',63152,16866,'b',8,80,'2026-02-03 06:56:43'), + (669177,'r',16866,63152,'w',8,88,'2026-02-03 07:40:22'), + (669178,'g',372,63185,'b',8,82,'2026-02-03 07:40:33'); +/*!40000 ALTER TABLE `Matches` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `Moves` +-- + +LOCK TABLES `Moves` WRITE; +/*!40000 ALTER TABLE `Moves` DISABLE KEYS */; +INSERT INTO `Moves` VALUES (115514,2,0,'n','1',669122,2717),(115515,2,1,'n','1',669122,2718),(115516,2,2,'e','1',669122,2719),(115517,2,3,'n','1',669122,2720),(115518,3,0,'n','1',669122,2721),(115519,3,1,'n','1',669122,2722),(115520,3,2,'e','1',669122,2723),(115521,3,3,'n','1',669122,2724),(115522,4,0,'e','1',669122,2725),(115523,4,1,'e','1',669122,2726),(115524,4,2,'n','1',669122,2727),(115525,5,0,'w','1',669122,2721),(115526,5,1,'n','1',669122,2728),(115527,5,2,'e','1',669122,2729),(115528,5,3,'e','1',669122,2730),(115529,6,0,'e','1',669122,2731),(115530,6,1,'e','1',669122,2732),(115531,6,2,'n','1',669122,2733),(115532,6,3,'e','1',669122,2734),(115533,7,0,'w','1',669122,2735),(115534,7,1,'w','1',669122,2725),(115535,7,2,'w','1',669122,2719),(115536,7,3,'n','1',669122,2736),(115537,8,0,'w','1',669122,2737),(115538,8,1,'n','1',669122,2738),(115539,8,2,'n','1',669122,2739),(115540,8,3,'n','1',669122,2740),(115541,9,0,'w','1',669122,2741),(115542,9,1,'s','1',669122,2742),(115543,9,2,'s','1',669122,2743),(115544,9,3,'e','1',669122,2744),(115545,10,0,'s','1',669122,2741),(115546,10,1,'w','1',669122,2745),(115547,10,2,'w','1',669122,2740),(115548,10,3,'n','1',669122,2746),(115549,11,0,'w','1',669122,2738),(115550,11,1,'w','1',669122,2747),(115551,11,2,'w','1',669122,2734),(115552,11,3,'w','1',669122,2746),(115553,12,0,'s','1',669122,2748),(115554,12,1,'w','1',669122,2749),(115555,12,2,'w','1',669122,2750),(115556,12,3,'e','1',669122,2729),(115557,13,0,'e','1',669122,2751),(115558,13,1,'e','1',669122,2750),(115559,13,2,'s','1',669122,2752),(115560,13,3,'n','1',669122,2753),(115561,14,0,'n','1',669122,2749),(115562,14,1,'e','1',669122,2748),(115563,14,2,'w','1',669122,2754),(115564,14,3,'e','1',669122,2755),(115565,15,0,'e','1',669122,2756),(115566,15,1,'s','1',669122,2757),(115567,15,2,'s','1',669122,2758),(115568,15,3,'w','1',669122,2759),(115569,16,0,'w','1',669122,2736),(115570,16,1,'e','1',669122,2760),(115571,16,2,'s','1',669122,2761),(115572,16,3,'x','0',669122,2762),(115573,16,4,'w','1',669122,2763),(115574,17,0,'s','1',669122,2764),(115575,17,1,'w','1',669122,2765),(115576,17,2,'e','1',669122,2756),(115577,17,3,'s','1',669122,2757),(115578,18,0,'s','1',669122,2758),(115579,18,1,'w','1',669122,2759),(115580,18,2,'s','1',669122,2761),(115581,18,3,'x','0',669122,2762),(115582,18,4,'s','1',669122,2756),(115583,19,0,'n','1',669122,2740),(115584,19,1,'w','1',669122,2756),(115585,19,2,'n','1',669122,2755),(115586,19,3,'n','1',669122,2736),(115587,20,0,'w','1',669122,2766),(115588,20,1,'s','1',669122,2767),(115589,20,2,'s','1',669122,2768),(115590,20,3,'w','1',669122,2769),(115591,21,0,'w','1',669122,2770),(115592,21,1,'s','1',669122,2750),(115593,21,2,'s','1',669122,2771),(115594,21,3,'x','0',669122,2772),(115595,21,4,'w','1',669122,2731),(115596,22,0,'n','1',669122,2730),(115597,22,1,'e','1',669122,2751),(115598,22,2,'e','1',669122,2750),(115599,22,3,'s','1',669122,2773),(115600,23,0,'s','1',669122,2774),(115601,23,1,'w','1',669122,2749),(115602,23,2,'n','1',669122,2750),(115603,23,3,'s','1',669122,2737),(115604,24,0,'s','1',669122,2775),(115605,24,1,'s','1',669122,2776),(115606,24,2,'w','1',669122,2777),(115607,24,3,'x','0',669122,2778),(115608,24,4,'n','1',669122,2739),(115609,25,0,'n','1',669122,2779),(115610,25,1,'n','1',669122,2780),(115611,25,2,'n','1',669122,2781),(115612,25,3,'e','1',669122,2775),(115613,26,0,'n','1',669122,2782),(115614,26,1,'e','1',669122,2783),(115615,26,2,'n','1',669122,2784),(115616,26,3,'n','1',669122,2785),(115617,27,0,'n','1',669122,2786),(115618,27,1,'n','1',669122,2787),(115619,27,2,'w','1',669122,2788),(115620,27,3,'n','1',669122,2789),(115621,28,0,'n','1',669122,2790),(115622,28,1,'n','1',669122,2791),(115623,28,2,'n','1',669122,2777),(115624,28,3,'w','1',669122,2776),(115625,29,0,'e','1',669122,2768),(115626,29,1,'n','1',669122,2792),(115627,29,2,'n','1',669122,2793),(115628,29,3,'n','1',669122,2794),(115629,30,0,'n','1',669122,2795),(115630,30,1,'n','1',669122,2796),(115631,30,2,'n','1',669122,2797),(115632,30,3,'n','1',669122,2789),(115633,31,0,'w','1',669122,2798),(115634,31,1,'s','1',669122,2765),(115635,31,2,'w','1',669122,2799),(115636,31,3,'e','1',669122,2749),(115637,32,0,'e','1',669122,2734),(115638,32,1,'e','1',669122,2788),(115639,32,2,'s','1',669122,2800),(115640,32,3,'w','1',669122,2738),(115641,33,0,'e','1',669122,2767),(115642,33,1,'n','1',669122,2801),(115643,33,2,'e','1',669122,2774),(115644,33,3,'n','1',669122,2795),(115645,34,0,'s','1',669122,2802),(115646,34,1,'x','0',669122,2803),(115647,34,2,'s','1',669122,2734),(115648,34,3,'n','1',669122,2733),(115649,34,4,'e','1',669122,2734),(115650,35,0,'w','1',669122,2738),(115651,35,1,'s','1',669122,2743),(115652,35,2,'s','1',669122,2804),(115653,35,3,'e','1',669122,2734),(115654,36,0,'w','1',669122,2805),(115655,36,1,'w','1',669122,2806),(115656,36,2,'e','1',669122,2807),(115657,36,3,'s','1',669122,2808),(115658,36,4,'x','0',669122,2809),(115659,37,0,'e','1',669122,2798),(115660,37,1,'n','1',669122,2758),(115661,37,2,'n','1',669122,2806),(115662,37,3,'e','1',669122,2757),(115663,2,0,'n','1',669122,2717),(115664,2,1,'n','1',669122,2718),(115665,2,2,'e','1',669122,2719),(115666,2,3,'n','1',669122,2720),(115667,3,0,'n','1',669122,2721),(115668,3,1,'n','1',669122,2722),(115669,3,2,'e','1',669122,2723),(115670,3,3,'n','1',669122,2724),(115671,4,0,'e','1',669122,2725),(115672,4,1,'e','1',669122,2726),(115673,4,2,'n','1',669122,2727),(115674,5,0,'w','1',669122,2721),(115675,5,1,'n','1',669122,2728),(115676,5,2,'e','1',669122,2729),(115677,5,3,'e','1',669122,2730),(115678,6,0,'e','1',669122,2731),(115679,6,1,'e','1',669122,2732),(115680,6,2,'n','1',669122,2733),(115681,6,3,'e','1',669122,2734),(115682,7,0,'w','1',669122,2735),(115683,7,1,'w','1',669122,2725),(115684,7,2,'w','1',669122,2719),(115685,7,3,'n','1',669122,2736),(115686,8,0,'w','1',669122,2737),(115687,8,1,'n','1',669122,2738),(115688,8,2,'n','1',669122,2739),(115689,8,3,'n','1',669122,2740),(115690,9,0,'w','1',669122,2741),(115691,9,1,'s','1',669122,2742),(115692,9,2,'s','1',669122,2743),(115693,9,3,'e','1',669122,2744),(115694,10,0,'s','1',669122,2741),(115695,10,1,'w','1',669122,2745),(115696,10,2,'w','1',669122,2740),(115697,10,3,'n','1',669122,2746),(115698,11,0,'w','1',669122,2738),(115699,11,1,'w','1',669122,2747),(115700,11,2,'w','1',669122,2734),(115701,11,3,'w','1',669122,2746),(115702,12,0,'s','1',669122,2748),(115703,12,1,'w','1',669122,2749),(115704,12,2,'w','1',669122,2750),(115705,12,3,'e','1',669122,2729),(115706,13,0,'e','1',669122,2751),(115707,13,1,'e','1',669122,2750),(115708,13,2,'s','1',669122,2752),(115709,13,3,'n','1',669122,2753),(115710,14,0,'n','1',669122,2749),(115711,14,1,'e','1',669122,2748),(115712,14,2,'w','1',669122,2754),(115713,14,3,'e','1',669122,2755),(115714,15,0,'e','1',669122,2756),(115715,15,1,'s','1',669122,2757),(115716,15,2,'s','1',669122,2758),(115717,15,3,'w','1',669122,2759),(115718,16,0,'w','1',669122,2736),(115719,16,1,'e','1',669122,2760),(115720,16,2,'s','1',669122,2761),(115721,16,3,'x','0',669122,2762),(115722,16,4,'w','1',669122,2763),(115723,17,0,'s','1',669122,2764),(115724,17,1,'w','1',669122,2765),(115725,17,2,'e','1',669122,2756),(115726,17,3,'s','1',669122,2757),(115727,18,0,'s','1',669122,2758),(115728,18,1,'w','1',669122,2759),(115729,18,2,'s','1',669122,2761),(115730,18,3,'x','0',669122,2762),(115731,18,4,'s','1',669122,2756),(115732,19,0,'n','1',669122,2740),(115733,19,1,'w','1',669122,2756),(115734,19,2,'n','1',669122,2755),(115735,19,3,'n','1',669122,2736),(115736,20,0,'w','1',669122,2766),(115737,20,1,'s','1',669122,2767),(115738,20,2,'s','1',669122,2768),(115739,20,3,'w','1',669122,2769),(115740,21,0,'w','1',669122,2770),(115741,21,1,'s','1',669122,2750),(115742,21,2,'s','1',669122,2771),(115743,21,3,'x','0',669122,2772),(115744,21,4,'w','1',669122,2731),(115745,22,0,'n','1',669122,2730),(115746,22,1,'e','1',669122,2751),(115747,22,2,'e','1',669122,2750),(115748,22,3,'s','1',669122,2773),(115749,23,0,'s','1',669122,2774),(115750,23,1,'w','1',669122,2749),(115751,23,2,'n','1',669122,2750),(115752,23,3,'s','1',669122,2737),(115753,24,0,'s','1',669122,2775),(115754,24,1,'s','1',669122,2776),(115755,24,2,'w','1',669122,2777),(115756,24,3,'x','0',669122,2778),(115757,24,4,'n','1',669122,2739),(115758,25,0,'n','1',669122,2779),(115759,25,1,'n','1',669122,2780),(115760,25,2,'n','1',669122,2781),(115761,25,3,'e','1',669122,2775),(115762,26,0,'n','1',669122,2782),(115763,26,1,'e','1',669122,2783),(115764,26,2,'n','1',669122,2784),(115765,26,3,'n','1',669122,2785),(115766,27,0,'n','1',669122,2786),(115767,27,1,'n','1',669122,2787),(115768,27,2,'w','1',669122,2788),(115769,27,3,'n','1',669122,2789),(115770,28,0,'n','1',669122,2790),(115771,28,1,'n','1',669122,2791),(115772,28,2,'n','1',669122,2777),(115773,28,3,'w','1',669122,2776),(115774,29,0,'e','1',669122,2768),(115775,29,1,'n','1',669122,2792),(115776,29,2,'n','1',669122,2793),(115777,29,3,'n','1',669122,2794),(115778,30,0,'n','1',669122,2795),(115779,30,1,'n','1',669122,2796),(115780,30,2,'n','1',669122,2797),(115781,30,3,'n','1',669122,2789),(115782,31,0,'w','1',669122,2798),(115783,31,1,'s','1',669122,2765),(115784,31,2,'w','1',669122,2799),(115785,31,3,'e','1',669122,2749),(115786,32,0,'e','1',669122,2734),(115787,32,1,'e','1',669122,2788),(115788,32,2,'s','1',669122,2800),(115789,32,3,'w','1',669122,2738),(115790,33,0,'e','1',669122,2767),(115791,33,1,'n','1',669122,2801),(115792,33,2,'e','1',669122,2774),(115793,33,3,'n','1',669122,2795),(115794,34,0,'s','1',669122,2802),(115795,34,1,'x','0',669122,2803),(115796,34,2,'s','1',669122,2734),(115797,34,3,'n','1',669122,2733),(115798,34,4,'e','1',669122,2734),(115799,35,0,'w','1',669122,2738),(115800,35,1,'s','1',669122,2743),(115801,35,2,'s','1',669122,2804),(115802,35,3,'e','1',669122,2734),(115803,36,0,'w','1',669122,2805),(115804,36,1,'w','1',669122,2806),(115805,36,2,'e','1',669122,2807),(115806,36,3,'s','1',669122,2808),(115807,36,4,'x','0',669122,2809),(115808,37,0,'e','1',669122,2798),(115809,37,1,'n','1',669122,2758),(115810,37,2,'n','1',669122,2806),(115811,37,3,'e','1',669122,2757),(115812,2,0,'n','1',669123,2721),(115813,2,1,'n','1',669123,2754),(115814,2,2,'n','1',669123,2810),(115815,2,3,'n','1',669123,2811),(115816,3,0,'w','1',669123,2812),(115817,3,1,'w','1',669123,2813),(115818,3,2,'w','1',669123,2814),(115819,3,3,'n','1',669123,2815),(115820,4,0,'w','1',669123,2777),(115821,4,1,'w','1',669123,2778),(115822,4,2,'n','1',669123,2816),(115823,4,3,'n','1',669123,2732),(115824,5,0,'e','1',669123,2817),(115825,5,1,'n','1',669123,2818),(115826,5,2,'n','1',669123,2723),(115827,5,3,'n','1',669123,2819),(115828,6,0,'e','1',669123,2749),(115829,6,1,'e','1',669123,2734),(115830,6,2,'w','1',669123,2738),(115831,6,3,'s','1',669123,2806),(115832,7,0,'s','1',669123,2820),(115833,7,1,'s','1',669123,2821),(115834,7,2,'w','1',669123,2754),(115835,7,3,'s','1',669123,2745),(115836,8,0,'e','1',669123,2734),(115837,8,1,'w','1',669123,2738),(115838,8,2,'s','1',669123,2806),(115839,8,3,'w','1',669123,2822),(115840,9,0,'n','1',669123,2724),(115841,9,1,'w','1',669123,2734),(115842,9,2,'n','1',669123,2749),(115843,9,3,'n','1',669123,2782),(115844,10,0,'n','1',669123,2736),(115845,10,1,'w','1',669123,2823),(115846,10,2,'w','1',669123,2824),(115847,10,3,'x','0',669123,2762),(115848,10,4,'s','1',669123,2737),(115849,11,0,'n','1',669123,2736),(115850,11,1,'n','1',669123,2737),(115851,11,2,'n','1',669123,2825),(115852,11,3,'n','1',669123,2759),(115853,12,0,'w','1',669123,2806),(115854,12,1,'w','1',669123,2826),(115855,12,2,'n','1',669123,2807),(115856,12,3,'e','1',669123,2765),(115857,13,0,'w','1',669123,2827),(115858,13,1,'n','1',669123,2828),(115859,13,2,'w','1',669123,2735),(115860,13,3,'e','1',669123,2744),(115861,14,0,'n','1',669123,2829),(115862,14,1,'w','1',669123,2830),(115863,14,2,'w','1',669123,2831),(115864,14,3,'w','1',669123,2725),(115865,15,0,'w','1',669123,2741),(115866,15,1,'s','1',669123,2742),(115867,15,2,'e','1',669123,2743),(115868,15,3,'e','1',669123,2744),(115869,16,0,'w','1',669123,2741),(115870,16,1,'s','1',669123,2742),(115871,16,2,'s','1',669123,2743),(115872,16,3,'e','1',669123,2744),(115873,17,0,'w','1',669123,2741),(115874,17,1,'w','1',669123,2832),(115875,17,2,'s','1',669123,2744),(115876,17,3,'e','1',669123,2781),(115877,18,0,'n','1',669123,2734),(115878,18,1,'s','1',669123,2833),(115879,18,2,'w','1',669123,2744),(115880,18,3,'n','1',669123,2834),(115881,19,0,'s','1',669123,2835),(115882,19,1,'s','1',669123,2836),(115883,19,2,'n','1',669123,2837),(115884,19,3,'e','1',669123,2807),(115885,20,0,'s','1',669123,2806),(115886,20,1,'s','1',669123,2759),(115887,20,2,'n','1',669123,2838),(115888,20,3,'s','1',669123,2765),(115889,21,0,'e','1',669123,2749),(115890,21,1,'e','1',669123,2740),(115891,21,2,'s','1',669123,2839),(115892,21,3,'s','1',669123,2737),(115893,22,0,'n','1',669123,2719),(115894,22,1,'w','1',669123,2840),(115895,22,2,'s','1',669123,2759),(115896,22,3,'e','1',669123,2734),(115897,23,0,'s','1',669123,2738),(115898,23,1,'s','1',669123,2837),(115899,23,2,'n','1',669123,2841),(115900,23,3,'n','1',669123,2753),(115901,24,0,'w','1',669123,2842),(115902,24,1,'s','1',669123,2843),(115903,24,2,'n','1',669123,2733),(115904,24,3,'w','1',669123,2734),(115905,25,0,'e','1',669123,2736),(115906,25,1,'s','1',669123,2729),(115907,25,2,'w','1',669123,2824),(115908,25,3,'w','1',669123,2754),(115909,26,0,'e','1',669123,2749),(115910,26,1,'s','1',669123,2734),(115911,26,2,'s','1',669123,2844),(115912,26,3,'n','1',669123,2845),(115913,27,0,'n','1',669123,2846),(115914,27,1,'e','1',669123,2847),(115915,27,2,'e','1',669123,2848),(115916,27,3,'n','1',669123,2785),(115917,28,0,'n','1',669123,2733),(115918,28,1,'s','1',669123,2734),(115919,28,2,'w','1',669123,2804),(115920,28,3,'s','1',669123,2769),(115921,29,0,'n','1',669123,2733),(115922,29,1,'s','1',669123,2734),(115923,29,2,'w','1',669123,2804),(115924,29,3,'n','1',669123,2846),(115925,30,0,'n','1',669123,2733),(115926,30,1,'w','1',669123,2849),(115927,30,2,'w','1',669123,2850),(115928,30,3,'s','1',669123,2734),(115929,31,0,'n','1',669123,2733),(115930,31,1,'w','1',669123,2849),(115931,31,2,'w','1',669123,2850),(115932,31,3,'s','1',669123,2734),(115933,32,0,'n','1',669123,2758),(115934,32,1,'n','1',669123,2733),(115935,32,2,'s','1',669123,2734),(115936,32,3,'w','1',669123,2804),(115937,33,0,'n','1',669123,2849),(115938,33,1,'e','1',669123,2733),(115939,33,2,'e','1',669123,2804),(115940,33,3,'n','1',669123,2842),(115941,34,0,'w','1',669123,2738),(115942,34,1,'e','1',669123,2761),(115943,34,2,'s','1',669123,2734),(115944,34,3,'n','1',669123,2779),(115945,35,0,'n','1',669123,2733),(115946,35,1,'w','1',669123,2849),(115947,35,2,'w','1',669123,2850),(115948,35,3,'s','1',669123,2734),(115949,36,0,'e','1',669123,2736),(115950,36,1,'w','1',669123,2754),(115951,36,2,'s','1',669123,2745),(115952,36,3,'s','1',669123,2830),(115953,37,0,'n','1',669123,2780),(115954,37,1,'e','1',669123,2848),(115955,37,2,'n','1',669123,2785),(115956,37,3,'n','1',669123,2733),(115957,38,0,'e','1',669123,2781),(115958,38,1,'e','1',669123,2785),(115959,38,2,'s','1',669123,2851),(115960,38,3,'w','1',669123,2831),(115961,39,0,'w','1',669123,2734),(115962,39,1,'e','1',669123,2749),(115963,39,2,'s','1',669123,2852),(115964,40,0,'e','1',669123,2783),(115965,40,1,'s','1',669123,2798),(115966,40,2,'w','1',669123,2734),(115967,40,3,'w','1',669123,2749),(115968,41,0,'n','1',669123,2784),(115969,41,1,'n','1',669123,2785),(115970,41,2,'n','1',669123,2793),(115971,41,3,'w','1',669123,2750),(115972,42,0,'n','1',669123,2853),(115973,42,1,'n','1',669123,2801),(115974,42,2,'e','1',669123,2790),(115975,42,3,'n','1',669123,2782),(115976,43,0,'e','1',669123,2751),(115977,43,1,'e','1',669123,2846),(115978,43,2,'s','1',669123,2854),(115979,43,3,'w','1',669123,2750),(115980,44,0,'s','1',669123,2855),(115981,44,1,'x','0',669123,2725),(115982,44,2,'s','1',669123,2751),(115983,44,3,'n','1',669123,2730),(115984,44,4,'n','1',669123,2831),(115985,45,0,'n','1',669123,2775),(115986,45,1,'s','1',669123,2856),(115987,45,2,'e','1',669123,2751),(115988,45,3,'e','1',669123,2840),(115989,46,0,'n','1',669123,2857),(115990,46,1,'w','1',669123,2851),(115991,46,2,'n','1',669123,2785),(115992,46,3,'e','1',669123,2858),(115993,47,0,'s','1',669123,2769),(115994,47,1,'w','1',669123,2859),(115995,47,2,'w','1',669123,2860),(115996,48,0,'n','1',669123,2861),(115997,48,1,'w','1',669123,2762),(115998,48,2,'w','1',669123,2795),(115999,48,3,'s','1',669123,2856),(116000,49,0,'e','1',669123,2862),(116001,49,1,'e','1',669123,2750),(116002,49,2,'n','1',669123,2846),(116003,49,3,'n','1',669123,2833),(116004,50,0,'w','1',669123,2777),(116005,50,1,'x','0',669123,2778),(116006,50,2,'w','1',669123,2861),(116007,50,3,'w','1',669123,2863),(116008,50,4,'n','1',669123,2749),(116009,51,0,'s','1',669123,2860),(116010,51,1,'w','1',669123,2765),(116011,51,2,'n','1',669123,2789),(116012,51,3,'n','1',669123,2795),(116013,52,0,'n','1',669123,2785),(116014,52,1,'n','1',669123,2864),(116015,52,2,'e','1',669123,2767),(116016,52,3,'n','1',669123,2859),(116017,53,0,'w','1',669123,2859),(116018,53,1,'w','1',669123,2793),(116019,53,2,'n','1',669123,2862),(116020,53,3,'n','1',669123,2830),(116021,54,0,'n','1',669123,2862),(116022,54,1,'n','1',669123,2830),(116023,54,2,'w','1',669123,2865),(116024,54,3,'n','1',669123,2866),(116025,2,0,'n','1',669123,2721),(116026,2,1,'n','1',669123,2754),(116027,2,2,'n','1',669123,2810),(116028,2,3,'n','1',669123,2811),(116029,3,0,'w','1',669123,2812),(116030,3,1,'w','1',669123,2813),(116031,3,2,'w','1',669123,2814),(116032,3,3,'n','1',669123,2815),(116033,4,0,'w','1',669123,2777),(116034,4,1,'w','1',669123,2778),(116035,4,2,'n','1',669123,2816),(116036,4,3,'n','1',669123,2732),(116037,5,0,'e','1',669123,2817),(116038,5,1,'n','1',669123,2818),(116039,5,2,'n','1',669123,2723),(116040,5,3,'n','1',669123,2819),(116041,6,0,'e','1',669123,2749),(116042,6,1,'e','1',669123,2734),(116043,6,2,'w','1',669123,2738),(116044,6,3,'s','1',669123,2806),(116045,7,0,'s','1',669123,2820),(116046,7,1,'s','1',669123,2821),(116047,7,2,'w','1',669123,2754),(116048,7,3,'s','1',669123,2745),(116049,8,0,'e','1',669123,2734),(116050,8,1,'w','1',669123,2738),(116051,8,2,'s','1',669123,2806),(116052,8,3,'w','1',669123,2822),(116053,9,0,'n','1',669123,2724),(116054,9,1,'w','1',669123,2734),(116055,9,2,'n','1',669123,2749),(116056,9,3,'n','1',669123,2782),(116057,10,0,'n','1',669123,2736),(116058,10,1,'w','1',669123,2823),(116059,10,2,'w','1',669123,2824),(116060,10,3,'x','0',669123,2762),(116061,10,4,'s','1',669123,2737),(116062,11,0,'n','1',669123,2736),(116063,11,1,'n','1',669123,2737),(116064,11,2,'n','1',669123,2825),(116065,11,3,'n','1',669123,2759),(116066,12,0,'w','1',669123,2806),(116067,12,1,'w','1',669123,2826),(116068,12,2,'n','1',669123,2807),(116069,12,3,'e','1',669123,2765),(116070,13,0,'w','1',669123,2827),(116071,13,1,'n','1',669123,2828),(116072,13,2,'w','1',669123,2735),(116073,13,3,'e','1',669123,2744),(116074,14,0,'n','1',669123,2829),(116075,14,1,'w','1',669123,2830),(116076,14,2,'w','1',669123,2831),(116077,14,3,'w','1',669123,2725),(116078,15,0,'w','1',669123,2741),(116079,15,1,'s','1',669123,2742),(116080,15,2,'e','1',669123,2743),(116081,15,3,'e','1',669123,2744),(116082,16,0,'w','1',669123,2741),(116083,16,1,'s','1',669123,2742),(116084,16,2,'s','1',669123,2743),(116085,16,3,'e','1',669123,2744),(116086,17,0,'w','1',669123,2741),(116087,17,1,'w','1',669123,2832),(116088,17,2,'s','1',669123,2744),(116089,17,3,'e','1',669123,2781),(116090,18,0,'n','1',669123,2734),(116091,18,1,'s','1',669123,2833),(116092,18,2,'w','1',669123,2744),(116093,18,3,'n','1',669123,2834),(116094,19,0,'s','1',669123,2835),(116095,19,1,'s','1',669123,2836),(116096,19,2,'n','1',669123,2837),(116097,19,3,'e','1',669123,2807),(116098,20,0,'s','1',669123,2806),(116099,20,1,'s','1',669123,2759),(116100,20,2,'n','1',669123,2838),(116101,20,3,'s','1',669123,2765),(116102,21,0,'e','1',669123,2749),(116103,21,1,'e','1',669123,2740),(116104,21,2,'s','1',669123,2839),(116105,21,3,'s','1',669123,2737),(116106,22,0,'n','1',669123,2719),(116107,22,1,'w','1',669123,2840),(116108,22,2,'s','1',669123,2759),(116109,22,3,'e','1',669123,2734),(116110,23,0,'s','1',669123,2738),(116111,23,1,'s','1',669123,2837),(116112,23,2,'n','1',669123,2841),(116113,23,3,'n','1',669123,2753),(116114,24,0,'w','1',669123,2842),(116115,24,1,'s','1',669123,2843),(116116,24,2,'n','1',669123,2733),(116117,24,3,'w','1',669123,2734),(116118,25,0,'e','1',669123,2736),(116119,25,1,'s','1',669123,2729),(116120,25,2,'w','1',669123,2824),(116121,25,3,'w','1',669123,2754),(116122,26,0,'e','1',669123,2749),(116123,26,1,'s','1',669123,2734),(116124,26,2,'s','1',669123,2844),(116125,26,3,'n','1',669123,2845),(116126,27,0,'n','1',669123,2846),(116127,27,1,'e','1',669123,2847),(116128,27,2,'e','1',669123,2848),(116129,27,3,'n','1',669123,2785),(116130,28,0,'n','1',669123,2733),(116131,28,1,'s','1',669123,2734),(116132,28,2,'w','1',669123,2804),(116133,28,3,'s','1',669123,2769),(116134,29,0,'n','1',669123,2733),(116135,29,1,'s','1',669123,2734),(116136,29,2,'w','1',669123,2804),(116137,29,3,'n','1',669123,2846),(116138,30,0,'n','1',669123,2733),(116139,30,1,'w','1',669123,2849),(116140,30,2,'w','1',669123,2850),(116141,30,3,'s','1',669123,2734),(116142,31,0,'n','1',669123,2733),(116143,31,1,'w','1',669123,2849),(116144,31,2,'w','1',669123,2850),(116145,31,3,'s','1',669123,2734),(116146,32,0,'n','1',669123,2758),(116147,32,1,'n','1',669123,2733),(116148,32,2,'s','1',669123,2734),(116149,32,3,'w','1',669123,2804),(116150,33,0,'n','1',669123,2849),(116151,33,1,'e','1',669123,2733),(116152,33,2,'e','1',669123,2804),(116153,33,3,'n','1',669123,2842),(116154,34,0,'w','1',669123,2738),(116155,34,1,'e','1',669123,2761),(116156,34,2,'s','1',669123,2734),(116157,34,3,'n','1',669123,2779),(116158,35,0,'n','1',669123,2733),(116159,35,1,'w','1',669123,2849),(116160,35,2,'w','1',669123,2850),(116161,35,3,'s','1',669123,2734),(116162,36,0,'e','1',669123,2736),(116163,36,1,'w','1',669123,2754),(116164,36,2,'s','1',669123,2745),(116165,36,3,'s','1',669123,2830),(116166,37,0,'n','1',669123,2780),(116167,37,1,'e','1',669123,2848),(116168,37,2,'n','1',669123,2785),(116169,37,3,'n','1',669123,2733),(116170,38,0,'e','1',669123,2781),(116171,38,1,'e','1',669123,2785),(116172,38,2,'s','1',669123,2851),(116173,38,3,'w','1',669123,2831),(116174,39,0,'w','1',669123,2734),(116175,39,1,'e','1',669123,2749),(116176,39,2,'s','1',669123,2852),(116177,40,0,'e','1',669123,2783),(116178,40,1,'s','1',669123,2798),(116179,40,2,'w','1',669123,2734),(116180,40,3,'w','1',669123,2749),(116181,41,0,'n','1',669123,2784),(116182,41,1,'n','1',669123,2785),(116183,41,2,'n','1',669123,2793),(116184,41,3,'w','1',669123,2750),(116185,42,0,'n','1',669123,2853),(116186,42,1,'n','1',669123,2801),(116187,42,2,'e','1',669123,2790),(116188,42,3,'n','1',669123,2782),(116189,43,0,'e','1',669123,2751),(116190,43,1,'e','1',669123,2846),(116191,43,2,'s','1',669123,2854),(116192,43,3,'w','1',669123,2750),(116193,44,0,'s','1',669123,2855),(116194,44,1,'x','0',669123,2725),(116195,44,2,'s','1',669123,2751),(116196,44,3,'n','1',669123,2730),(116197,44,4,'n','1',669123,2831),(116198,45,0,'n','1',669123,2775),(116199,45,1,'s','1',669123,2856),(116200,45,2,'e','1',669123,2751),(116201,45,3,'e','1',669123,2840),(116202,46,0,'n','1',669123,2857),(116203,46,1,'w','1',669123,2851),(116204,46,2,'n','1',669123,2785),(116205,46,3,'e','1',669123,2858),(116206,47,0,'s','1',669123,2769),(116207,47,1,'w','1',669123,2859),(116208,47,2,'w','1',669123,2860),(116209,48,0,'n','1',669123,2861),(116210,48,1,'w','1',669123,2762),(116211,48,2,'w','1',669123,2795),(116212,48,3,'s','1',669123,2856),(116213,49,0,'e','1',669123,2862),(116214,49,1,'e','1',669123,2750),(116215,49,2,'n','1',669123,2846),(116216,49,3,'n','1',669123,2833),(116217,50,0,'w','1',669123,2777),(116218,50,1,'x','0',669123,2778),(116219,50,2,'w','1',669123,2861),(116220,50,3,'w','1',669123,2863),(116221,50,4,'n','1',669123,2749),(116222,51,0,'s','1',669123,2860),(116223,51,1,'w','1',669123,2765),(116224,51,2,'n','1',669123,2789),(116225,51,3,'n','1',669123,2795),(116226,52,0,'n','1',669123,2785),(116227,52,1,'n','1',669123,2864),(116228,52,2,'e','1',669123,2767),(116229,52,3,'n','1',669123,2859),(116230,53,0,'w','1',669123,2859),(116231,53,1,'w','1',669123,2793),(116232,53,2,'n','1',669123,2862),(116233,53,3,'n','1',669123,2830),(116234,54,0,'n','1',669123,2862),(116235,54,1,'n','1',669123,2830),(116236,54,2,'w','1',669123,2865),(116237,54,3,'n','1',669123,2866),(116238,2,0,'n','1',669124,2867),(116239,2,1,'n','1',669124,2816),(116240,2,2,'n','1',669124,2732),(116241,2,3,'n','1',669124,2815),(116242,3,0,'n','1',669124,2749),(116243,3,1,'n','1',669124,2868),(116244,3,2,'w','1',669124,2765),(116245,3,3,'s','1',669124,2863),(116246,4,0,'n','1',669124,2869),(116247,4,1,'n','1',669124,2739),(116248,4,2,'n','1',669124,2870),(116249,4,3,'n','1',669124,2782),(116250,5,0,'s','1',669124,2768),(116251,5,1,'w','1',669124,2750),(116252,5,2,'w','1',669124,2751),(116253,5,3,'e','1',669124,2818),(116254,6,0,'e','1',669124,2871),(116255,6,1,'s','1',669124,2769),(116256,6,2,'e','1',669124,2751),(116257,6,3,'e','1',669124,2846),(116258,7,0,'w','1',669124,2750),(116259,7,1,'s','1',669124,2846),(116260,7,2,'w','1',669124,2751),(116261,7,3,'n','1',669124,2815),(116262,8,0,'e','1',669124,2872),(116263,8,1,'n','1',669124,2772),(116264,8,2,'s','1',669124,2845),(116265,8,3,'s','1',669124,2871),(116266,9,0,'e','1',669124,2719),(116267,9,1,'s','1',669124,2873),(116268,9,2,'e','1',669124,2725),(116269,9,3,'e','1',669124,2726),(116270,10,0,'e','1',669124,2727),(116271,10,1,'e','1',669124,2786),(116272,10,2,'x','0',669124,2803),(116273,10,3,'e','1',669124,2874),(116274,10,4,'n','1',669124,2875),(116275,11,0,'w','1',669124,2816),(116276,11,1,'n','1',669124,2874),(116277,11,2,'e','1',669124,2876),(116278,11,3,'n','1',669124,2731),(116279,12,0,'w','1',669124,2787),(116280,12,1,'e','1',669124,2818),(116281,12,2,'n','1',669124,2750),(116282,12,3,'w','1',669124,2822),(116283,13,0,'s','1',669124,2849),(116284,13,1,'s','1',669124,2768),(116285,13,2,'s','1',669124,2851),(116286,13,3,'n','1',669124,2750),(116287,14,0,'n','1',669124,2872),(116288,14,1,'n','1',669124,2877),(116289,14,2,'e','1',669124,2878),(116290,14,3,'n','1',669124,2879),(116291,15,0,'w','1',669124,2767),(116292,15,1,'n','1',669124,2880),(116293,15,2,'w','1',669124,2768),(116294,15,3,'n','1',669124,2834),(116295,16,0,'e','1',669124,2854),(116296,16,1,'s','1',669124,2881),(116297,16,2,'s','1',669124,2876),(116298,16,3,'e','1',669124,2751),(116299,17,0,'w','1',669124,2786),(116300,17,1,'n','1',669124,2857),(116301,17,2,'w','1',669124,2750),(116302,17,3,'n','1',669124,2882),(116303,18,0,'w','1',669124,2875),(116304,18,1,'w','1',669124,2883),(116305,18,2,'n','1',669124,2838),(116306,18,3,'n','1',669124,2779),(116307,19,0,'w','1',669124,2878),(116308,19,1,'w','1',669124,2751),(116309,19,2,'n','1',669124,2823),(116310,19,3,'n','1',669124,2745),(116311,20,0,'w','1',669124,2884),(116312,20,1,'w','1',669124,2735),(116313,20,2,'e','1',669124,2871),(116314,20,3,'s','1',669124,2862),(116315,21,0,'s','1',669124,2792),(116316,21,1,'n','1',669124,2751),(116317,21,2,'s','1',669124,2764),(116318,21,3,'e','1',669124,2881),(116319,22,0,'s','1',669124,2885),(116320,22,1,'w','1',669124,2886),(116321,22,2,'w','1',669124,2880),(116322,22,3,'w','1',669124,2785),(116323,23,0,'s','1',669124,2887),(116324,23,1,'w','1',669124,2725),(116325,23,2,'e','1',669124,2719),(116326,23,3,'e','1',669124,2725),(116327,24,0,'n','1',669124,2839),(116328,24,1,'n','1',669124,2797),(116329,24,2,'n','1',669124,2789),(116330,24,3,'n','1',669124,2795),(116331,25,0,'w','1',669124,2888),(116332,25,1,'e','1',669124,2735),(116333,25,2,'e','1',669124,2884),(116334,25,3,'e','1',669124,2883),(116335,26,0,'n','1',669124,2796),(116336,26,1,'n','1',669124,2798),(116337,26,2,'w','1',669124,2889),(116338,26,3,'n','1',669124,2739),(116339,27,0,'n','1',669124,2768),(116340,27,1,'n','1',669124,2890),(116341,27,2,'s','1',669124,2891),(116342,27,3,'e','1',669124,2892),(116343,28,0,'n','1',669124,2875),(116344,28,1,'n','1',669124,2849),(116345,28,2,'n','1',669124,2804),(116346,28,3,'w','1',669124,2890),(116347,29,0,'n','1',669124,2893),(116348,29,1,'e','1',669124,2894),(116349,29,2,'e','1',669124,2895),(116350,29,3,'s','1',669124,2896),(116351,30,0,'n','1',669124,2897),(116352,30,1,'s','1',669124,2898),(116353,30,2,'w','1',669124,2886),(116354,30,3,'s','1',669124,2899),(116355,31,0,'s','1',669124,2900),(116356,31,1,'w','1',669124,2859),(116357,31,2,'n','1',669124,2862),(116358,31,3,'n','1',669124,2878),(116359,32,0,'e','1',669124,2893),(116360,32,1,'e','1',669124,2752),(116361,32,2,'s','1',669124,2890),(116362,32,3,'n','1',669124,2901),(116363,33,0,'e','1',669124,2774),(116364,33,1,'e','1',669124,2768),(116365,33,2,'n','1',669124,2817),(116366,33,3,'n','1',669124,2824),(116367,34,0,'n','1',669124,2773),(116368,34,1,'w','1',669124,2765),(116369,34,2,'e','1',669124,2768),(116370,34,3,'n','1',669124,2729),(116371,35,0,'n','1',669124,2902),(116372,35,1,'n','1',669124,2858),(116373,35,2,'n','1',669124,2882),(116374,35,3,'n','1',669124,2821),(116375,36,0,'n','1',669124,2778),(116376,36,1,'n','1',669124,2775),(116377,36,2,'n','1',669124,2851),(116378,36,3,'e','1',669124,2903),(116379,37,0,'n','1',669124,2900),(116380,37,1,'s','1',669124,2899),(116381,37,2,'w','1',669124,2767),(116382,37,3,'n','1',669124,2901),(116383,38,0,'w','1',669124,2900),(116384,38,1,'e','1',669124,2904),(116385,38,2,'n','1',669124,2835),(116386,38,3,'n','1',669124,2817),(116387,39,0,'w','1',669124,2824),(116388,39,1,'w','1',669124,2897),(116389,39,2,'w','1',669124,2762),(116390,39,3,'w','1',669124,2856),(116391,40,0,'e','1',669124,2783),(116392,40,1,'e','1',669124,2784),(116393,40,2,'n','1',669124,2887),(116394,40,3,'e','1',669124,2795),(116395,41,0,'e','1',669124,2762),(116396,41,1,'e','1',669124,2905),(116397,41,2,'e','1',669124,2824),(116398,41,3,'w','1',669124,2817),(116399,42,0,'n','1',669124,2823),(116400,42,1,'e','1',669124,2798),(116401,42,2,'s','1',669124,2765),(116402,42,3,'w','1',669124,2757),(116403,43,0,'n','1',669124,2774),(116404,43,1,'n','1',669124,2906),(116405,43,2,'w','1',669124,2773),(116406,43,3,'n','1',669124,2907),(116407,44,0,'w','1',669124,2749),(116408,44,1,'s','1',669124,2750),(116409,44,2,'e','1',669124,2879),(116410,44,3,'n','1',669124,2794),(116411,45,0,'w','1',669124,2794),(116412,45,1,'e','1',669124,2775),(116413,45,2,'w','1',669124,2731),(116414,45,3,'s','1',669124,2748),(116415,46,0,'s','1',669124,2730),(116416,46,1,'s','1',669124,2879),(116417,46,2,'e','1',669124,2727),(116418,46,3,'s','1',669124,2771),(116419,46,4,'x','0',669124,2772),(116420,47,0,'n','1',669124,2786),(116421,47,1,'w','1',669124,2874),(116422,47,2,'s','1',669124,2770),(116423,47,3,'e','1',669124,2798),(116424,48,0,'n','1',669124,2831),(116425,48,1,'w','1',669124,2866),(116426,48,2,'n','1',669124,2900),(116427,48,3,'n','1',669124,2840),(116428,49,0,'w','1',669124,2886),(116429,49,1,'s','1',669124,2899),(116430,49,2,'n','1',669124,2727),(116431,49,3,'w','1',669124,2908),(116432,49,4,'x','0',669124,2772),(116433,50,0,'s','1',669124,2909),(116434,50,1,'e','1',669124,2730),(116435,50,2,'s','1',669124,2857),(116436,50,3,'s','1',669124,2731),(116437,51,0,'e','1',669124,2900),(116438,51,1,'w','1',669124,2880),(116439,51,2,'s','1',669124,2853),(116440,51,3,'x','0',669124,2910),(116441,51,4,'e','1',669124,2840),(116442,52,0,'n','1',669124,2857),(116443,52,1,'n','1',669124,2859),(116444,52,2,'e','1',669124,2787),(116445,52,3,'e','1',669124,2802),(116446,53,0,'n','1',669124,2911),(116447,53,1,'e','1',669124,2859),(116448,53,2,'e','1',669124,2773),(116449,53,3,'n','1',669124,2852),(116450,54,0,'s','1',669124,2742),(116451,54,1,'w','1',669124,2743),(116452,54,2,'n','1',669124,2852),(116453,54,3,'x','0',669124,2844),(116454,54,4,'n','1',669124,2912),(116455,2,0,'n','1',669124,2867),(116456,2,1,'n','1',669124,2816),(116457,2,2,'n','1',669124,2732),(116458,2,3,'n','1',669124,2815),(116459,3,0,'n','1',669124,2749),(116460,3,1,'n','1',669124,2868),(116461,3,2,'w','1',669124,2765),(116462,3,3,'s','1',669124,2863),(116463,4,0,'n','1',669124,2869),(116464,4,1,'n','1',669124,2739),(116465,4,2,'n','1',669124,2870),(116466,4,3,'n','1',669124,2782),(116467,5,0,'s','1',669124,2768),(116468,5,1,'w','1',669124,2750),(116469,5,2,'w','1',669124,2751),(116470,5,3,'e','1',669124,2818),(116471,6,0,'e','1',669124,2871),(116472,6,1,'s','1',669124,2769),(116473,6,2,'e','1',669124,2751),(116474,6,3,'e','1',669124,2846),(116475,7,0,'w','1',669124,2750),(116476,7,1,'s','1',669124,2846),(116477,7,2,'w','1',669124,2751),(116478,7,3,'n','1',669124,2815),(116479,8,0,'e','1',669124,2872),(116480,8,1,'n','1',669124,2772),(116481,8,2,'s','1',669124,2845),(116482,8,3,'s','1',669124,2871),(116483,9,0,'e','1',669124,2719),(116484,9,1,'s','1',669124,2873),(116485,9,2,'e','1',669124,2725),(116486,9,3,'e','1',669124,2726),(116487,10,0,'e','1',669124,2727),(116488,10,1,'e','1',669124,2786),(116489,10,2,'x','0',669124,2803),(116490,10,3,'e','1',669124,2874),(116491,10,4,'n','1',669124,2875),(116492,11,0,'w','1',669124,2816),(116493,11,1,'n','1',669124,2874),(116494,11,2,'e','1',669124,2876),(116495,11,3,'n','1',669124,2731),(116496,12,0,'w','1',669124,2787),(116497,12,1,'e','1',669124,2818),(116498,12,2,'n','1',669124,2750),(116499,12,3,'w','1',669124,2822),(116500,13,0,'s','1',669124,2849),(116501,13,1,'s','1',669124,2768),(116502,13,2,'s','1',669124,2851),(116503,13,3,'n','1',669124,2750),(116504,14,0,'n','1',669124,2872),(116505,14,1,'n','1',669124,2877),(116506,14,2,'e','1',669124,2878),(116507,14,3,'n','1',669124,2879),(116508,15,0,'w','1',669124,2767),(116509,15,1,'n','1',669124,2880),(116510,15,2,'w','1',669124,2768),(116511,15,3,'n','1',669124,2834),(116512,16,0,'e','1',669124,2854),(116513,16,1,'s','1',669124,2881),(116514,16,2,'s','1',669124,2876),(116515,16,3,'e','1',669124,2751),(116516,17,0,'w','1',669124,2786),(116517,17,1,'n','1',669124,2857),(116518,17,2,'w','1',669124,2750),(116519,17,3,'n','1',669124,2882),(116520,18,0,'w','1',669124,2875),(116521,18,1,'w','1',669124,2883),(116522,18,2,'n','1',669124,2838),(116523,18,3,'n','1',669124,2779),(116524,19,0,'w','1',669124,2878),(116525,19,1,'w','1',669124,2751),(116526,19,2,'n','1',669124,2823),(116527,19,3,'n','1',669124,2745),(116528,20,0,'w','1',669124,2884),(116529,20,1,'w','1',669124,2735),(116530,20,2,'e','1',669124,2871),(116531,20,3,'s','1',669124,2862),(116532,21,0,'s','1',669124,2792),(116533,21,1,'n','1',669124,2751),(116534,21,2,'s','1',669124,2764),(116535,21,3,'e','1',669124,2881),(116536,22,0,'s','1',669124,2885),(116537,22,1,'w','1',669124,2886),(116538,22,2,'w','1',669124,2880),(116539,22,3,'w','1',669124,2785),(116540,23,0,'s','1',669124,2887),(116541,23,1,'w','1',669124,2725),(116542,23,2,'e','1',669124,2719),(116543,23,3,'e','1',669124,2725),(116544,24,0,'n','1',669124,2839),(116545,24,1,'n','1',669124,2797),(116546,24,2,'n','1',669124,2789),(116547,24,3,'n','1',669124,2795),(116548,25,0,'w','1',669124,2888),(116549,25,1,'e','1',669124,2735),(116550,25,2,'e','1',669124,2884),(116551,25,3,'e','1',669124,2883),(116552,26,0,'n','1',669124,2796),(116553,26,1,'n','1',669124,2798),(116554,26,2,'w','1',669124,2889),(116555,26,3,'n','1',669124,2739),(116556,27,0,'n','1',669124,2768),(116557,27,1,'n','1',669124,2890),(116558,27,2,'s','1',669124,2891),(116559,27,3,'e','1',669124,2892),(116560,28,0,'n','1',669124,2875),(116561,28,1,'n','1',669124,2849),(116562,28,2,'n','1',669124,2804),(116563,28,3,'w','1',669124,2890),(116564,29,0,'n','1',669124,2893),(116565,29,1,'e','1',669124,2894),(116566,29,2,'e','1',669124,2895),(116567,29,3,'s','1',669124,2896),(116568,30,0,'n','1',669124,2897),(116569,30,1,'s','1',669124,2898),(116570,30,2,'w','1',669124,2886),(116571,30,3,'s','1',669124,2899),(116572,31,0,'s','1',669124,2900),(116573,31,1,'w','1',669124,2859),(116574,31,2,'n','1',669124,2862),(116575,31,3,'n','1',669124,2878),(116576,32,0,'e','1',669124,2893),(116577,32,1,'e','1',669124,2752),(116578,32,2,'s','1',669124,2890),(116579,32,3,'n','1',669124,2901),(116580,33,0,'e','1',669124,2774),(116581,33,1,'e','1',669124,2768),(116582,33,2,'n','1',669124,2817),(116583,33,3,'n','1',669124,2824),(116584,34,0,'n','1',669124,2773),(116585,34,1,'w','1',669124,2765),(116586,34,2,'e','1',669124,2768),(116587,34,3,'n','1',669124,2729),(116588,35,0,'n','1',669124,2902),(116589,35,1,'n','1',669124,2858),(116590,35,2,'n','1',669124,2882),(116591,35,3,'n','1',669124,2821),(116592,36,0,'n','1',669124,2778),(116593,36,1,'n','1',669124,2775),(116594,36,2,'n','1',669124,2851),(116595,36,3,'e','1',669124,2903),(116596,37,0,'n','1',669124,2900),(116597,37,1,'s','1',669124,2899),(116598,37,2,'w','1',669124,2767),(116599,37,3,'n','1',669124,2901),(116600,38,0,'w','1',669124,2900),(116601,38,1,'e','1',669124,2904),(116602,38,2,'n','1',669124,2835),(116603,38,3,'n','1',669124,2817),(116604,39,0,'w','1',669124,2824),(116605,39,1,'w','1',669124,2897),(116606,39,2,'w','1',669124,2762),(116607,39,3,'w','1',669124,2856),(116608,40,0,'e','1',669124,2783),(116609,40,1,'e','1',669124,2784),(116610,40,2,'n','1',669124,2887),(116611,40,3,'e','1',669124,2795),(116612,41,0,'e','1',669124,2762),(116613,41,1,'e','1',669124,2905),(116614,41,2,'e','1',669124,2824),(116615,41,3,'w','1',669124,2817),(116616,42,0,'n','1',669124,2823),(116617,42,1,'e','1',669124,2798),(116618,42,2,'s','1',669124,2765),(116619,42,3,'w','1',669124,2757),(116620,43,0,'n','1',669124,2774),(116621,43,1,'n','1',669124,2906),(116622,43,2,'w','1',669124,2773),(116623,43,3,'n','1',669124,2907),(116624,44,0,'w','1',669124,2749),(116625,44,1,'s','1',669124,2750),(116626,44,2,'e','1',669124,2879),(116627,44,3,'n','1',669124,2794),(116628,45,0,'w','1',669124,2794),(116629,45,1,'e','1',669124,2775),(116630,45,2,'w','1',669124,2731),(116631,45,3,'s','1',669124,2748),(116632,46,0,'s','1',669124,2730),(116633,46,1,'s','1',669124,2879),(116634,46,2,'e','1',669124,2727),(116635,46,3,'s','1',669124,2771),(116636,46,4,'x','0',669124,2772),(116637,47,0,'n','1',669124,2786),(116638,47,1,'w','1',669124,2874),(116639,47,2,'s','1',669124,2770),(116640,47,3,'e','1',669124,2798),(116641,48,0,'n','1',669124,2831),(116642,48,1,'w','1',669124,2866),(116643,48,2,'n','1',669124,2900),(116644,48,3,'n','1',669124,2840),(116645,49,0,'w','1',669124,2886),(116646,49,1,'s','1',669124,2899),(116647,49,2,'n','1',669124,2727),(116648,49,3,'w','1',669124,2908),(116649,49,4,'x','0',669124,2772),(116650,50,0,'s','1',669124,2909),(116651,50,1,'e','1',669124,2730),(116652,50,2,'s','1',669124,2857),(116653,50,3,'s','1',669124,2731),(116654,51,0,'e','1',669124,2900),(116655,51,1,'w','1',669124,2880),(116656,51,2,'s','1',669124,2853),(116657,51,3,'x','0',669124,2910),(116658,51,4,'e','1',669124,2840),(116659,52,0,'n','1',669124,2857),(116660,52,1,'n','1',669124,2859),(116661,52,2,'e','1',669124,2787),(116662,52,3,'e','1',669124,2802),(116663,53,0,'n','1',669124,2911),(116664,53,1,'e','1',669124,2859),(116665,53,2,'e','1',669124,2773),(116666,53,3,'n','1',669124,2852),(116667,54,0,'s','1',669124,2742),(116668,54,1,'w','1',669124,2743),(116669,54,2,'n','1',669124,2852),(116670,54,3,'x','0',669124,2844),(116671,54,4,'n','1',669124,2912),(116672,2,0,'n','1',669125,2913),(116673,2,1,'n','1',669125,2874),(116674,2,2,'n','1',669125,2731),(116675,2,3,'n','1',669125,2750),(116676,3,0,'n','1',669125,2721),(116677,3,1,'n','1',669125,2717),(116678,3,2,'n','1',669125,2815),(116679,3,3,'n','1',669125,2888),(116680,4,0,'w','1',669125,2754),(116681,4,1,'n','1',669125,2736),(116682,4,2,'n','1',669125,2737),(116683,4,3,'e','1',669125,2759),(116684,5,0,'e','1',669125,2719),(116685,5,1,'e','1',669125,2725),(116686,5,2,'e','1',669125,2735),(116687,5,3,'e','1',669125,2884),(116688,6,0,'s','1',669125,2768),(116689,6,1,'e','1',669125,2750),(116690,6,2,'e','1',669125,2883),(116691,6,3,'n','1',669125,2875),(116692,7,0,'e','1',669125,2749),(116693,7,1,'s','1',669125,2734),(116694,7,2,'n','1',669125,2882),(116695,7,3,'n','1',669125,2870),(116696,8,0,'s','1',669125,2849),(116697,8,1,'w','1',669125,2820),(116698,8,2,'w','1',669125,2875),(116699,8,3,'s','1',669125,2737),(116700,9,0,'e','1',669125,2733),(116701,9,1,'s','1',669125,2914),(116702,9,2,'e','1',669125,2759),(116703,9,3,'w','1',669125,2842),(116704,10,0,'e','1',669125,2733),(116705,10,1,'n','1',669125,2759),(116706,10,2,'n','1',669125,2806),(116707,10,3,'w','1',669125,2842),(116708,11,0,'w','1',669125,2883),(116709,11,1,'w','1',669125,2736),(116710,11,2,'x','0',669125,2760),(116711,11,3,'e','1',669125,2884),(116712,11,4,'e','1',669125,2883),(116713,12,0,'n','1',669125,2733),(116714,12,1,'e','1',669125,2818),(116715,12,2,'e','1',669125,2872),(116716,12,3,'e','1',669125,2772),(116717,13,0,'n','1',669125,2875),(116718,13,1,'e','1',669125,2849),(116719,13,2,'w','1',669125,2823),(116720,13,3,'n','1',669125,2915),(116721,14,0,'n','1',669125,2824),(116722,14,1,'n','1',669125,2916),(116723,14,2,'s','1',669125,2917),(116724,14,3,'s','1',669125,2918),(116725,15,0,'n','1',669125,2916),(116726,15,1,'n','1',669125,2729),(116727,15,2,'n','1',669125,2838),(116728,15,3,'n','1',669125,2839),(116729,16,0,'s','1',669125,2917),(116730,16,1,'s','1',669125,2918),(116731,16,2,'e','1',669125,2806),(116732,16,3,'n','1',669125,2901),(116733,17,0,'e','1',669125,2806),(116734,17,1,'s','1',669125,2916),(116735,17,2,'s','1',669125,2914),(116736,17,3,'s','1',669125,2805),(116737,18,0,'w','1',669125,2919),(116738,18,1,'s','1',669125,2920),(116739,18,2,'n','1',669125,2921),(116740,18,3,'e','1',669125,2843),(116741,19,0,'w','1',669125,2875),(116742,19,1,'w','1',669125,2922),(116743,19,2,'n','1',669125,2883),(116744,19,3,'w','1',669125,2923),(116745,19,4,'x','0',669125,2803),(116746,20,0,'s','1',669125,2850),(116747,20,1,'n','1',669125,2805),(116748,20,2,'n','1',669125,2924),(116749,20,3,'w','1',669125,2925),(116750,21,0,'n','1',669125,2821),(116751,21,1,'e','1',669125,2889),(116752,21,2,'s','1',669125,2826),(116753,21,3,'w','1',669125,2926),(116754,22,0,'w','1',669125,2734),(116755,22,1,'s','1',669125,2757),(116756,22,2,'s','1',669125,2758),(116757,22,3,'e','1',669125,2749),(116758,23,0,'e','1',669125,2883),(116759,23,1,'e','1',669125,2889),(116760,23,2,'n','1',669125,2927),(116761,23,3,'w','1',669125,2858),(116762,24,0,'s','1',669125,2786),(116763,24,1,'s','1',669125,2796),(116764,24,2,'e','1',669125,2795),(116765,24,3,'n','1',669125,2915),(116766,25,0,'n','1',669125,2875),(116767,25,1,'n','1',669125,2817),(116768,25,2,'n','1',669125,2849),(116769,25,3,'w','1',669125,2908),(116770,26,0,'n','1',669125,2806),(116771,26,1,'n','1',669125,2804),(116772,26,2,'w','1',669125,2928),(116773,26,3,'w','1',669125,2734),(116774,27,0,'n','1',669125,2749),(116775,27,1,'n','1',669125,2786),(116776,27,2,'n','1',669125,2797),(116777,27,3,'n','1',669125,2789),(116778,28,0,'n','1',669125,2787),(116779,28,1,'n','1',669125,2795),(116780,28,2,'n','1',669125,2739),(116781,28,3,'n','1',669125,2887),(116782,29,0,'n','1',669125,2905),(116783,29,1,'n','1',669125,2762),(116784,29,2,'n','1',669125,2761),(116785,29,3,'n','1',669125,2903),(116786,30,0,'n','1',669125,2758),(116787,30,1,'e','1',669125,2788),(116788,30,2,'e','1',669125,2796),(116789,30,3,'n','1',669125,2824),(116790,31,0,'n','1',669125,2772),(116791,31,1,'e','1',669125,2771),(116792,31,2,'e','1',669125,2770),(116793,31,3,'n','1',669125,2746),(116794,32,0,'s','1',669125,2773),(116795,32,1,'w','1',669125,2765),(116796,32,2,'n','1',669125,2755),(116797,32,3,'e','1',669125,2774),(116798,33,0,'n','1',669125,2909),(116799,33,1,'n','1',669125,2929),(116800,33,2,'w','1',669125,2862),(116801,33,3,'n','1',669125,2930),(116802,34,0,'s','1',669125,2931),(116803,34,1,'e','1',669125,2930),(116804,34,2,'e','1',669125,2932),(116805,34,3,'s','1',669125,2859),(116806,35,0,'s','1',669125,2798),(116807,35,1,'e','1',669125,2907),(116808,35,2,'e','1',669125,2768),(116809,35,3,'e','1',669125,2775),(116810,36,0,'s','1',669125,2786),(116811,36,1,'s','1',669125,2796),(116812,36,2,'e','1',669125,2795),(116813,36,3,'x','0',669125,2762),(116814,36,4,'n','1',669125,2915),(116815,37,0,'s','1',669125,2911),(116816,37,1,'w','1',669125,2765),(116817,37,2,'n','1',669125,2933),(116818,37,3,'w','1',669125,2786),(116819,38,0,'n','1',669125,2775),(116820,38,1,'e','1',669125,2851),(116821,38,2,'w','1',669125,2787),(116822,38,3,'s','1',669125,2933),(116823,39,0,'s','1',669125,2856),(116824,39,1,'e','1',669125,2851),(116825,39,2,'e','1',669125,2861),(116826,39,3,'x','0',669125,2934),(116827,39,4,'s','1',669125,2787),(116828,40,0,'s','1',669125,2935),(116829,40,1,'e','1',669125,2768),(116830,40,2,'w','1',669125,2786),(116831,40,3,'e','1',669125,2936),(116832,41,0,'w','1',669125,2765),(116833,41,1,'s','1',669125,2937),(116834,41,2,'e','1',669125,2938),(116835,41,3,'s','1',669125,2936),(116836,42,0,'w','1',669125,2775),(116837,42,1,'w','1',669125,2784),(116838,42,2,'w','1',669125,2774),(116839,42,3,'s','1',669125,2768),(116840,43,0,'s','1',669125,2750),(116841,43,1,'w','1',669125,2731),(116842,43,2,'w','1',669125,2848),(116843,43,3,'s','1',669125,2847),(116844,44,0,'s','1',669125,2730),(116845,44,1,'s','1',669125,2857),(116846,44,2,'w','1',669125,2727),(116847,44,3,'s','1',669125,2794),(116848,44,4,'x','0',669125,2778),(116849,45,0,'e','1',669125,2726),(116850,45,1,'e','1',669125,2939),(116851,45,2,'n','1',669125,2727),(116852,45,3,'e','1',669125,2719),(116853,45,4,'x','0',669125,2725),(116854,46,0,'n','1',669125,2730),(116855,46,1,'s','1',669125,2940),(116856,46,2,'w','1',669125,2826),(116857,46,3,'w','1',669125,2742),(116858,47,0,'s','1',669125,2751),(116859,47,1,'w','1',669125,2730),(116860,47,2,'s','1',669125,2873),(116861,47,3,'e','1',669125,2847),(116862,48,0,'n','1',669125,2779),(116863,48,1,'w','1',669125,2822),(116864,48,2,'s','1',669125,2726),(116865,48,3,'n','1',669125,2780),(116866,49,0,'n','1',669125,2781),(116867,49,1,'n','1',669125,2941),(116868,49,2,'n','1',669125,2942),(116869,49,3,'n','1',669125,2943),(116870,2,0,'n','1',669125,2913),(116871,2,1,'n','1',669125,2874),(116872,2,2,'n','1',669125,2731),(116873,2,3,'n','1',669125,2750),(116874,3,0,'n','1',669125,2721),(116875,3,1,'n','1',669125,2717),(116876,3,2,'n','1',669125,2815),(116877,3,3,'n','1',669125,2888),(116878,4,0,'w','1',669125,2754),(116879,4,1,'n','1',669125,2736),(116880,4,2,'n','1',669125,2737),(116881,4,3,'e','1',669125,2759),(116882,5,0,'e','1',669125,2719),(116883,5,1,'e','1',669125,2725),(116884,5,2,'e','1',669125,2735),(116885,5,3,'e','1',669125,2884),(116886,6,0,'s','1',669125,2768),(116887,6,1,'e','1',669125,2750),(116888,6,2,'e','1',669125,2883),(116889,6,3,'n','1',669125,2875),(116890,7,0,'e','1',669125,2749),(116891,7,1,'s','1',669125,2734),(116892,7,2,'n','1',669125,2882),(116893,7,3,'n','1',669125,2870),(116894,8,0,'s','1',669125,2849),(116895,8,1,'w','1',669125,2820),(116896,8,2,'w','1',669125,2875),(116897,8,3,'s','1',669125,2737),(116898,9,0,'e','1',669125,2733),(116899,9,1,'s','1',669125,2914),(116900,9,2,'e','1',669125,2759),(116901,9,3,'w','1',669125,2842),(116902,10,0,'e','1',669125,2733),(116903,10,1,'n','1',669125,2759),(116904,10,2,'n','1',669125,2806),(116905,10,3,'w','1',669125,2842),(116906,11,0,'w','1',669125,2883),(116907,11,1,'w','1',669125,2736),(116908,11,2,'x','0',669125,2760),(116909,11,3,'e','1',669125,2884),(116910,11,4,'e','1',669125,2883),(116911,12,0,'n','1',669125,2733),(116912,12,1,'e','1',669125,2818),(116913,12,2,'e','1',669125,2872),(116914,12,3,'e','1',669125,2772),(116915,13,0,'n','1',669125,2875),(116916,13,1,'e','1',669125,2849),(116917,13,2,'w','1',669125,2823),(116918,13,3,'n','1',669125,2915),(116919,14,0,'n','1',669125,2824),(116920,14,1,'n','1',669125,2916),(116921,14,2,'s','1',669125,2917),(116922,14,3,'s','1',669125,2918),(116923,15,0,'n','1',669125,2916),(116924,15,1,'n','1',669125,2729),(116925,15,2,'n','1',669125,2838),(116926,15,3,'n','1',669125,2839),(116927,16,0,'s','1',669125,2917),(116928,16,1,'s','1',669125,2918),(116929,16,2,'e','1',669125,2806),(116930,16,3,'n','1',669125,2901),(116931,17,0,'e','1',669125,2806),(116932,17,1,'s','1',669125,2916),(116933,17,2,'s','1',669125,2914),(116934,17,3,'s','1',669125,2805),(116935,18,0,'w','1',669125,2919),(116936,18,1,'s','1',669125,2920),(116937,18,2,'n','1',669125,2921),(116938,18,3,'e','1',669125,2843),(116939,19,0,'w','1',669125,2875),(116940,19,1,'w','1',669125,2922),(116941,19,2,'n','1',669125,2883),(116942,19,3,'w','1',669125,2923),(116943,19,4,'x','0',669125,2803),(116944,20,0,'s','1',669125,2850),(116945,20,1,'n','1',669125,2805),(116946,20,2,'n','1',669125,2924),(116947,20,3,'w','1',669125,2925),(116948,21,0,'n','1',669125,2821),(116949,21,1,'e','1',669125,2889),(116950,21,2,'s','1',669125,2826),(116951,21,3,'w','1',669125,2926),(116952,22,0,'w','1',669125,2734),(116953,22,1,'s','1',669125,2757),(116954,22,2,'s','1',669125,2758),(116955,22,3,'e','1',669125,2749),(116956,23,0,'e','1',669125,2883),(116957,23,1,'e','1',669125,2889),(116958,23,2,'n','1',669125,2927),(116959,23,3,'w','1',669125,2858),(116960,24,0,'s','1',669125,2786),(116961,24,1,'s','1',669125,2796),(116962,24,2,'e','1',669125,2795),(116963,24,3,'n','1',669125,2915),(116964,25,0,'n','1',669125,2875),(116965,25,1,'n','1',669125,2817),(116966,25,2,'n','1',669125,2849),(116967,25,3,'w','1',669125,2908),(116968,26,0,'n','1',669125,2806),(116969,26,1,'n','1',669125,2804),(116970,26,2,'w','1',669125,2928),(116971,26,3,'w','1',669125,2734),(116972,27,0,'n','1',669125,2749),(116973,27,1,'n','1',669125,2786),(116974,27,2,'n','1',669125,2797),(116975,27,3,'n','1',669125,2789),(116976,28,0,'n','1',669125,2787),(116977,28,1,'n','1',669125,2795),(116978,28,2,'n','1',669125,2739),(116979,28,3,'n','1',669125,2887),(116980,29,0,'n','1',669125,2905),(116981,29,1,'n','1',669125,2762),(116982,29,2,'n','1',669125,2761),(116983,29,3,'n','1',669125,2903),(116984,30,0,'n','1',669125,2758),(116985,30,1,'e','1',669125,2788),(116986,30,2,'e','1',669125,2796),(116987,30,3,'n','1',669125,2824),(116988,31,0,'n','1',669125,2772),(116989,31,1,'e','1',669125,2771),(116990,31,2,'e','1',669125,2770),(116991,31,3,'n','1',669125,2746),(116992,32,0,'s','1',669125,2773),(116993,32,1,'w','1',669125,2765),(116994,32,2,'n','1',669125,2755),(116995,32,3,'e','1',669125,2774),(116996,33,0,'n','1',669125,2909),(116997,33,1,'n','1',669125,2929),(116998,33,2,'w','1',669125,2862),(116999,33,3,'n','1',669125,2930),(117000,34,0,'s','1',669125,2931),(117001,34,1,'e','1',669125,2930),(117002,34,2,'e','1',669125,2932),(117003,34,3,'s','1',669125,2859),(117004,35,0,'s','1',669125,2798),(117005,35,1,'e','1',669125,2907),(117006,35,2,'e','1',669125,2768),(117007,35,3,'e','1',669125,2775),(117008,36,0,'s','1',669125,2786),(117009,36,1,'s','1',669125,2796),(117010,36,2,'e','1',669125,2795),(117011,36,3,'x','0',669125,2762),(117012,36,4,'n','1',669125,2915),(117013,37,0,'s','1',669125,2911),(117014,37,1,'w','1',669125,2765),(117015,37,2,'n','1',669125,2933),(117016,37,3,'w','1',669125,2786),(117017,38,0,'n','1',669125,2775),(117018,38,1,'e','1',669125,2851),(117019,38,2,'w','1',669125,2787),(117020,38,3,'s','1',669125,2933),(117021,39,0,'s','1',669125,2856),(117022,39,1,'e','1',669125,2851),(117023,39,2,'e','1',669125,2861),(117024,39,3,'x','0',669125,2934),(117025,39,4,'s','1',669125,2787),(117026,40,0,'s','1',669125,2935),(117027,40,1,'e','1',669125,2768),(117028,40,2,'w','1',669125,2786),(117029,40,3,'e','1',669125,2936),(117030,41,0,'w','1',669125,2765),(117031,41,1,'s','1',669125,2937),(117032,41,2,'e','1',669125,2938),(117033,41,3,'s','1',669125,2936),(117034,42,0,'w','1',669125,2775),(117035,42,1,'w','1',669125,2784),(117036,42,2,'w','1',669125,2774),(117037,42,3,'s','1',669125,2768),(117038,43,0,'s','1',669125,2750),(117039,43,1,'w','1',669125,2731),(117040,43,2,'w','1',669125,2848),(117041,43,3,'s','1',669125,2847),(117042,44,0,'s','1',669125,2730),(117043,44,1,'s','1',669125,2857),(117044,44,2,'w','1',669125,2727),(117045,44,3,'s','1',669125,2794),(117046,44,4,'x','0',669125,2778),(117047,45,0,'e','1',669125,2726),(117048,45,1,'e','1',669125,2939),(117049,45,2,'n','1',669125,2727),(117050,45,3,'e','1',669125,2719),(117051,45,4,'x','0',669125,2725),(117052,46,0,'n','1',669125,2730),(117053,46,1,'s','1',669125,2940),(117054,46,2,'w','1',669125,2826),(117055,46,3,'w','1',669125,2742),(117056,47,0,'s','1',669125,2751),(117057,47,1,'w','1',669125,2730),(117058,47,2,'s','1',669125,2873),(117059,47,3,'e','1',669125,2847),(117060,48,0,'n','1',669125,2779),(117061,48,1,'w','1',669125,2822),(117062,48,2,'s','1',669125,2726),(117063,48,3,'n','1',669125,2780),(117064,49,0,'n','1',669125,2781),(117065,49,1,'n','1',669125,2941),(117066,49,2,'n','1',669125,2942),(117067,49,3,'n','1',669125,2943),(117068,2,0,'n','1',669126,2913),(117069,2,1,'n','1',669126,2874),(117070,2,2,'n','1',669126,2731),(117071,2,3,'n','1',669126,2750),(117072,3,0,'n','1',669126,2721),(117073,3,1,'n','1',669126,2888),(117074,3,2,'s','1',669126,2768),(117075,3,3,'s','1',669126,2944),(117076,4,0,'w','1',669126,2750),(117077,4,1,'w','1',669126,2751),(117078,4,2,'e','1',669126,2871),(117079,4,3,'s','1',669126,2862),(117080,5,0,'e','1',669126,2751),(117081,5,1,'e','1',669126,2750),(117082,5,2,'e','1',669126,2749),(117083,5,3,'s','1',669126,2734),(117084,6,0,'n','1',669126,2717),(117085,6,1,'n','1',669126,2719),(117086,6,2,'s','1',669126,2845),(117087,6,3,'s','1',669126,2840),(117088,7,0,'n','1',669126,2815),(117089,7,1,'s','1',669126,2818),(117090,7,2,'s','1',669126,2781),(117091,7,3,'n','1',669126,2903),(117092,8,0,'e','1',669126,2733),(117093,8,1,'w','1',669126,2842),(117094,8,2,'n','1',669126,2736),(117095,8,3,'w','1',669126,2754),(117096,9,0,'s','1',669126,2719),(117097,9,1,'e','1',669126,2780),(117098,9,2,'e','1',669126,2829),(117099,9,3,'x','0',669126,2778),(117100,9,4,'n','1',669126,2717),(117101,10,0,'e','1',669126,2733),(117102,10,1,'w','1',669126,2842),(117103,10,2,'s','1',669126,2843),(117104,10,3,'n','1',669126,2882),(117105,11,0,'n','1',669126,2733),(117106,11,1,'w','1',669126,2729),(117107,11,2,'w','1',669126,2761),(117108,11,3,'s','1',669126,2734),(117109,12,0,'w','1',669126,2796),(117110,12,1,'w','1',669126,2733),(117111,12,2,'s','1',669126,2776),(117112,12,3,'w','1',669126,2732),(117113,13,0,'w','1',669126,2777),(117114,13,1,'x','0',669126,2778),(117115,13,2,'s','1',669126,2731),(117116,13,3,'n','1',669126,2874),(117117,13,4,'n','1',669126,2731),(117118,14,0,'e','1',669126,2750),(117119,14,1,'s','1',669126,2911),(117120,14,2,'s','1',669126,2907),(117121,14,3,'w','1',669126,2749),(117122,15,0,'n','1',669126,2736),(117123,15,1,'w','1',669126,2737),(117124,15,2,'n','1',669126,2838),(117125,15,3,'e','1',669126,2719),(117126,16,0,'e','1',669126,2725),(117127,16,1,'e','1',669126,2750),(117128,16,2,'e','1',669126,2746),(117129,16,3,'n','1',669126,2815),(117130,17,0,'n','1',669126,2887),(117131,17,1,'w','1',669126,2902),(117132,17,2,'s','1',669126,2725),(117133,17,3,'n','1',669126,2739),(117134,18,0,'e','1',669126,2945),(117135,18,1,'e','1',669126,2828),(117136,18,2,'e','1',669126,2827),(117137,18,3,'n','1',669126,2858),(117138,19,0,'e','1',669126,2740),(117139,19,1,'e','1',669126,2856),(117140,19,2,'s','1',669126,2897),(117141,19,3,'w','1',669126,2737),(117142,20,0,'e','1',669126,2775),(117143,20,1,'n','1',669126,2833),(117144,20,2,'n','1',669126,2749),(117145,20,3,'n','1',669126,2870),(117146,21,0,'n','1',669126,2927),(117147,21,1,'e','1',669126,2818),(117148,21,2,'e','1',669126,2929),(117149,21,3,'s','1',669126,2946),(117150,22,0,'e','1',669126,2786),(117151,22,1,'e','1',669126,2839),(117152,22,2,'e','1',669126,2803),(117153,22,3,'n','1',669126,2739),(117154,23,0,'n','1',669126,2947),(117155,23,1,'w','1',669126,2883),(117156,23,2,'n','1',669126,2903),(117157,23,3,'n','1',669126,2884),(117158,24,0,'e','1',669126,2775),(117159,24,1,'n','1',669126,2948),(117160,24,2,'n','1',669126,2756),(117161,24,3,'n','1',669126,2822),(117162,25,0,'e','1',669126,2826),(117163,25,1,'n','1',669126,2807),(117164,25,2,'w','1',669126,2764),(117165,25,3,'w','1',669126,2765),(117166,26,0,'e','1',669126,2864),(117167,26,1,'n','1',669126,2768),(117168,26,2,'s','1',669126,2890),(117169,26,3,'e','1',669126,2767),(117170,26,4,'x','0',669126,2880),(117171,27,0,'e','1',669126,2768),(117172,27,1,'s','1',669126,2944),(117173,27,2,'w','1',669126,2773),(117174,27,3,'x','0',669126,2859),(117175,27,4,'w','1',669126,2765),(117176,28,0,'e','1',669126,2768),(117177,28,1,'w','1',669126,2747),(117178,28,2,'w','1',669126,2765),(117179,28,3,'n','1',669126,2838),(117180,29,0,'e','1',669126,2768),(117181,29,1,'w','1',669126,2747),(117182,29,2,'s','1',669126,2876),(117183,29,3,'w','1',669126,2765),(117184,30,0,'e','1',669126,2768),(117185,30,1,'w','1',669126,2747),(117186,30,2,'s','1',669126,2876),(117187,30,3,'w','1',669126,2765),(117188,31,0,'e','1',669126,2768),(117189,31,1,'s','1',669126,2747),(117190,31,2,'s','1',669126,2765),(117191,31,3,'w','1',669126,2786),(117192,32,0,'w','1',669126,2839),(117193,32,1,'e','1',669126,2850),(117194,32,2,'s','1',669126,2849),(117195,32,3,'w','1',669126,2934),(117196,33,0,'n','1',669126,2905),(117197,33,1,'e','1',669126,2949),(117198,33,2,'n','1',669126,2829),(117199,33,3,'w','1',669126,2950),(117200,34,0,'n','1',669126,2901),(117201,34,1,'e','1',669126,2951),(117202,34,2,'e','1',669126,2775),(117203,34,3,'e','1',669126,2831),(117204,35,0,'e','1',669126,2756),(117205,35,1,'e','1',669126,2749),(117206,35,2,'w','1',669126,2761),(117207,35,3,'w','1',669126,2796),(117208,36,0,'e','1',669126,2759),(117209,36,1,'e','1',669126,2734),(117210,36,2,'s','1',669126,2897),(117211,36,3,'w','1',669126,2849),(117212,37,0,'e','1',669126,2776),(117213,37,1,'s','1',669126,2786),(117214,37,2,'w','1',669126,2915),(117215,37,3,'w','1',669126,2952),(117216,37,4,'x','0',669126,2814),(117217,38,0,'w','1',669126,2738),(117218,38,1,'w','1',669126,2921),(117219,38,2,'s','1',669126,2759),(117220,38,3,'e','1',669126,2734),(117221,39,0,'w','1',669126,2738),(117222,39,1,'w','1',669126,2734),(117223,39,2,'w','1',669126,2749),(117224,39,3,'w','1',669126,2750),(117225,40,0,'w','1',669126,2817),(117226,40,1,'s','1',669126,2850),(117227,40,2,'n','1',669126,2824),(117228,40,3,'e','1',669126,2883),(117229,41,0,'e','1',669126,2729),(117230,41,1,'w','1',669126,2751),(117231,41,2,'e','1',669126,2871),(117232,41,3,'s','1',669126,2769),(117233,42,0,'w','1',669126,2875),(117234,42,1,'w','1',669126,2823),(117235,42,2,'n','1',669126,2883),(117236,42,3,'w','1',669126,2824),(117237,42,4,'x','0',669126,2762),(117238,43,0,'e','1',669126,2739),(117239,43,1,'w','1',669126,2861),(117240,43,2,'n','1',669126,2915),(117241,43,3,'e','1',669126,2762),(117242,44,0,'s','1',669126,2850),(117243,44,1,'w','1',669126,2953),(117244,44,2,'s','1',669126,2883),(117245,44,3,'s','1',669126,2897),(117246,44,4,'x','0',669126,2934),(117247,45,0,'w','1',669126,2947),(117248,45,1,'w','1',669126,2827),(117249,45,2,'n','1',669126,2828),(117250,45,3,'n','1',669126,2797),(117251,46,0,'n','1',669126,2735),(117252,46,1,'e','1',669126,2954),(117253,46,2,'w','1',669126,2948),(117254,46,3,'s','1',669126,2755),(117255,47,0,'e','1',669126,2954),(117256,47,1,'e','1',669126,2948),(117257,47,2,'e','1',669126,2824),(117258,47,3,'e','1',669126,2762),(117259,48,0,'n','1',669126,2850),(117260,48,1,'w','1',669126,2737),(117261,48,2,'s','1',669126,2740),(117262,48,3,'x','0',669126,2760),(117263,48,4,'s','1',669126,2832),(117264,49,0,'w','1',669126,2751),(117265,49,1,'s','1',669126,2871),(117266,49,2,'n','1',669126,2873),(117267,49,3,'e','1',669126,2847),(117268,50,0,'n','1',669126,2786),(117269,50,1,'w','1',669126,2787),(117270,50,2,'n','1',669126,2851),(117271,50,3,'n','1',669126,2850),(117272,51,0,'n','1',669126,2792),(117273,51,1,'n','1',669126,2860),(117274,51,2,'w','1',669126,2852),(117275,51,3,'e','1',669126,2832),(117276,2,0,'n','1',669126,2913),(117277,2,1,'n','1',669126,2874),(117278,2,2,'n','1',669126,2731),(117279,2,3,'n','1',669126,2750),(117280,3,0,'n','1',669126,2721),(117281,3,1,'n','1',669126,2888),(117282,3,2,'s','1',669126,2768),(117283,3,3,'s','1',669126,2944),(117284,4,0,'w','1',669126,2750),(117285,4,1,'w','1',669126,2751),(117286,4,2,'e','1',669126,2871),(117287,4,3,'s','1',669126,2862),(117288,5,0,'e','1',669126,2751),(117289,5,1,'e','1',669126,2750),(117290,5,2,'e','1',669126,2749),(117291,5,3,'s','1',669126,2734),(117292,6,0,'n','1',669126,2717),(117293,6,1,'n','1',669126,2719),(117294,6,2,'s','1',669126,2845),(117295,6,3,'s','1',669126,2840),(117296,7,0,'n','1',669126,2815),(117297,7,1,'s','1',669126,2818),(117298,7,2,'s','1',669126,2781),(117299,7,3,'n','1',669126,2903),(117300,8,0,'e','1',669126,2733),(117301,8,1,'w','1',669126,2842),(117302,8,2,'n','1',669126,2736),(117303,8,3,'w','1',669126,2754),(117304,9,0,'s','1',669126,2719),(117305,9,1,'e','1',669126,2780),(117306,9,2,'e','1',669126,2829),(117307,9,3,'x','0',669126,2778),(117308,9,4,'n','1',669126,2717),(117309,10,0,'e','1',669126,2733),(117310,10,1,'w','1',669126,2842),(117311,10,2,'s','1',669126,2843),(117312,10,3,'n','1',669126,2882),(117313,11,0,'n','1',669126,2733),(117314,11,1,'w','1',669126,2729),(117315,11,2,'w','1',669126,2761),(117316,11,3,'s','1',669126,2734),(117317,12,0,'w','1',669126,2796),(117318,12,1,'w','1',669126,2733),(117319,12,2,'s','1',669126,2776),(117320,12,3,'w','1',669126,2732),(117321,13,0,'w','1',669126,2777),(117322,13,1,'x','0',669126,2778),(117323,13,2,'s','1',669126,2731),(117324,13,3,'n','1',669126,2874),(117325,13,4,'n','1',669126,2731),(117326,14,0,'e','1',669126,2750),(117327,14,1,'s','1',669126,2911),(117328,14,2,'s','1',669126,2907),(117329,14,3,'w','1',669126,2749),(117330,15,0,'n','1',669126,2736),(117331,15,1,'w','1',669126,2737),(117332,15,2,'n','1',669126,2838),(117333,15,3,'e','1',669126,2719),(117334,16,0,'e','1',669126,2725),(117335,16,1,'e','1',669126,2750),(117336,16,2,'e','1',669126,2746),(117337,16,3,'n','1',669126,2815),(117338,17,0,'n','1',669126,2887),(117339,17,1,'w','1',669126,2902),(117340,17,2,'s','1',669126,2725),(117341,17,3,'n','1',669126,2739),(117342,18,0,'e','1',669126,2945),(117343,18,1,'e','1',669126,2828),(117344,18,2,'e','1',669126,2827),(117345,18,3,'n','1',669126,2858),(117346,19,0,'e','1',669126,2740),(117347,19,1,'e','1',669126,2856),(117348,19,2,'s','1',669126,2897),(117349,19,3,'w','1',669126,2737),(117350,20,0,'e','1',669126,2775),(117351,20,1,'n','1',669126,2833),(117352,20,2,'n','1',669126,2749),(117353,20,3,'n','1',669126,2870),(117354,21,0,'n','1',669126,2927),(117355,21,1,'e','1',669126,2818),(117356,21,2,'e','1',669126,2929),(117357,21,3,'s','1',669126,2946),(117358,22,0,'e','1',669126,2786),(117359,22,1,'e','1',669126,2839),(117360,22,2,'e','1',669126,2803),(117361,22,3,'n','1',669126,2739),(117362,23,0,'n','1',669126,2947),(117363,23,1,'w','1',669126,2883),(117364,23,2,'n','1',669126,2903),(117365,23,3,'n','1',669126,2884),(117366,24,0,'e','1',669126,2775),(117367,24,1,'n','1',669126,2948),(117368,24,2,'n','1',669126,2756),(117369,24,3,'n','1',669126,2822),(117370,25,0,'e','1',669126,2826),(117371,25,1,'n','1',669126,2807),(117372,25,2,'w','1',669126,2764),(117373,25,3,'w','1',669126,2765),(117374,26,0,'e','1',669126,2864),(117375,26,1,'n','1',669126,2768),(117376,26,2,'s','1',669126,2890),(117377,26,3,'e','1',669126,2767),(117378,26,4,'x','0',669126,2880),(117379,27,0,'e','1',669126,2768),(117380,27,1,'s','1',669126,2944),(117381,27,2,'w','1',669126,2773),(117382,27,3,'x','0',669126,2859),(117383,27,4,'w','1',669126,2765),(117384,28,0,'e','1',669126,2768),(117385,28,1,'w','1',669126,2747),(117386,28,2,'w','1',669126,2765),(117387,28,3,'n','1',669126,2838),(117388,29,0,'e','1',669126,2768),(117389,29,1,'w','1',669126,2747),(117390,29,2,'s','1',669126,2876),(117391,29,3,'w','1',669126,2765),(117392,30,0,'e','1',669126,2768),(117393,30,1,'w','1',669126,2747),(117394,30,2,'s','1',669126,2876),(117395,30,3,'w','1',669126,2765),(117396,31,0,'e','1',669126,2768),(117397,31,1,'s','1',669126,2747),(117398,31,2,'s','1',669126,2765),(117399,31,3,'w','1',669126,2786),(117400,32,0,'w','1',669126,2839),(117401,32,1,'e','1',669126,2850),(117402,32,2,'s','1',669126,2849),(117403,32,3,'w','1',669126,2934),(117404,33,0,'n','1',669126,2905),(117405,33,1,'e','1',669126,2949),(117406,33,2,'n','1',669126,2829),(117407,33,3,'w','1',669126,2950),(117408,34,0,'n','1',669126,2901),(117409,34,1,'e','1',669126,2951),(117410,34,2,'e','1',669126,2775),(117411,34,3,'e','1',669126,2831),(117412,35,0,'e','1',669126,2756),(117413,35,1,'e','1',669126,2749),(117414,35,2,'w','1',669126,2761),(117415,35,3,'w','1',669126,2796),(117416,36,0,'e','1',669126,2759),(117417,36,1,'e','1',669126,2734),(117418,36,2,'s','1',669126,2897),(117419,36,3,'w','1',669126,2849),(117420,37,0,'e','1',669126,2776),(117421,37,1,'s','1',669126,2786),(117422,37,2,'w','1',669126,2915),(117423,37,3,'w','1',669126,2952),(117424,37,4,'x','0',669126,2814),(117425,38,0,'w','1',669126,2738),(117426,38,1,'w','1',669126,2921),(117427,38,2,'s','1',669126,2759),(117428,38,3,'e','1',669126,2734),(117429,39,0,'w','1',669126,2738),(117430,39,1,'w','1',669126,2734),(117431,39,2,'w','1',669126,2749),(117432,39,3,'w','1',669126,2750),(117433,40,0,'w','1',669126,2817),(117434,40,1,'s','1',669126,2850),(117435,40,2,'n','1',669126,2824),(117436,40,3,'e','1',669126,2883),(117437,41,0,'e','1',669126,2729),(117438,41,1,'w','1',669126,2751),(117439,41,2,'e','1',669126,2871),(117440,41,3,'s','1',669126,2769),(117441,42,0,'w','1',669126,2875),(117442,42,1,'w','1',669126,2823),(117443,42,2,'n','1',669126,2883),(117444,42,3,'w','1',669126,2824),(117445,42,4,'x','0',669126,2762),(117446,43,0,'e','1',669126,2739),(117447,43,1,'w','1',669126,2861),(117448,43,2,'n','1',669126,2915),(117449,43,3,'e','1',669126,2762),(117450,44,0,'s','1',669126,2850),(117451,44,1,'w','1',669126,2953),(117452,44,2,'s','1',669126,2883),(117453,44,3,'s','1',669126,2897),(117454,44,4,'x','0',669126,2934),(117455,45,0,'w','1',669126,2947),(117456,45,1,'w','1',669126,2827),(117457,45,2,'n','1',669126,2828),(117458,45,3,'n','1',669126,2797),(117459,46,0,'n','1',669126,2735),(117460,46,1,'e','1',669126,2954),(117461,46,2,'w','1',669126,2948),(117462,46,3,'s','1',669126,2755),(117463,47,0,'e','1',669126,2954),(117464,47,1,'e','1',669126,2948),(117465,47,2,'e','1',669126,2824),(117466,47,3,'e','1',669126,2762),(117467,48,0,'n','1',669126,2850),(117468,48,1,'w','1',669126,2737),(117469,48,2,'s','1',669126,2740),(117470,48,3,'x','0',669126,2760),(117471,48,4,'s','1',669126,2832),(117472,49,0,'w','1',669126,2751),(117473,49,1,'s','1',669126,2871),(117474,49,2,'n','1',669126,2873),(117475,49,3,'e','1',669126,2847),(117476,50,0,'n','1',669126,2786),(117477,50,1,'w','1',669126,2787),(117478,50,2,'n','1',669126,2851),(117479,50,3,'n','1',669126,2850),(117480,51,0,'n','1',669126,2792),(117481,51,1,'n','1',669126,2860),(117482,51,2,'w','1',669126,2852),(117483,51,3,'e','1',669126,2832),(117484,2,0,'n','1',669127,2827),(117485,2,1,'n','1',669127,2955),(117486,2,2,'n','1',669127,2728),(117487,2,3,'n','1',669127,2956),(117488,3,0,'e','1',669127,2957),(117489,3,1,'n','1',669127,2841),(117490,4,0,'n','1',669127,2913),(117491,4,1,'n','1',669127,2790),(117492,4,2,'n','1',669127,2815),(117493,5,0,'n','1',669127,2949),(117494,5,1,'w','1',669127,2948),(117495,5,2,'w','1',669127,2905),(117496,6,0,'e','1',669127,2789),(117497,6,1,'e','1',669127,2818),(117498,7,0,'n','1',669127,2874),(117499,7,1,'w','1',669127,2731),(117500,7,2,'n','1',669127,2730),(117501,7,3,'n','1',669127,2723),(117502,8,0,'w','1',669127,2751),(117503,8,1,'e','1',669127,2871),(117504,8,2,'s','1',669127,2900),(117505,8,3,'n','1',669127,2819),(117506,9,0,'n','1',669127,2934),(117507,9,1,'n','1',669127,2736),(117508,9,2,'n','1',669127,2958),(117509,9,3,'n','1',669127,2905),(117510,10,0,'e','1',669127,2751),(117511,10,1,'e','1',669127,2878),(117512,10,2,'n','1',669127,2879),(117513,10,3,'w','1',669127,2750),(117514,11,0,'e','1',669127,2751),(117515,11,1,'s','1',669127,2747),(117516,11,2,'e','1',669127,2750),(117517,11,3,'w','1',669127,2737),(117518,12,0,'n','1',669127,2800),(117519,12,1,'e','1',669127,2749),(117520,12,2,'e','1',669127,2734),(117521,12,3,'n','1',669127,2740),(117522,13,0,'n','1',669127,2762),(117523,13,1,'n','1',669127,2923),(117524,13,2,'w','1',669127,2834),(117525,13,3,'n','1',669127,2817),(117526,14,0,'w','1',669127,2791),(117527,14,1,'n','1',669127,2903),(117528,14,2,'w','1',669127,2888),(117529,14,3,'n','1',669127,2901),(117530,15,0,'w','1',669127,2832),(117531,15,1,'w','1',669127,2738),(117532,15,2,'n','1',669127,2959),(117533,15,3,'n','1',669127,2905),(117534,16,0,'w','1',669127,2747),(117535,16,1,'w','1',669127,2734),(117536,16,2,'s','1',669127,2960),(117537,16,3,'s','1',669127,2825),(117538,17,0,'e','1',669127,2833),(117539,17,1,'x','0',669127,2799),(117540,17,2,'n','1',669127,2749),(117541,17,3,'w','1',669127,2889),(117542,17,4,'n','1',669127,2959),(117543,18,0,'w','1',669127,2961),(117544,18,1,'w','1',669127,2960),(117545,18,2,'s','1',669127,2933),(117546,18,3,'s','1',669127,2765),(117547,19,0,'n','1',669127,2824),(117548,19,1,'e','1',669127,2762),(117549,19,2,'w','1',669127,2856),(117550,19,3,'s','1',669127,2749),(117551,20,0,'n','1',669127,2732),(117552,20,1,'w','1',669127,2749),(117553,20,2,'w','1',669127,2756),(117554,20,3,'e','1',669127,2822),(117555,21,0,'w','1',669127,2761),(117556,21,1,'e','1',669127,2750),(117557,21,2,'n','1',669127,2729),(117558,21,3,'n','1',669127,2824),(117559,22,0,'e','1',669127,2756),(117560,22,1,'e','1',669127,2749),(117561,22,2,'s','1',669127,2734),(117562,22,3,'n','1',669127,2817),(117563,23,0,'n','1',669127,2756),(117564,23,1,'n','1',669127,2733),(117565,23,2,'e','1',669127,2734),(117566,23,3,'e','1',669127,2798),(117567,24,0,'e','1',669127,2858),(117568,24,1,'e','1',669127,2790),(117569,24,2,'e','1',669127,2797),(117570,24,3,'w','1',669127,2738),(117571,2,0,'n','1',669127,2827),(117572,2,1,'n','1',669127,2955),(117573,2,2,'n','1',669127,2728),(117574,2,3,'n','1',669127,2956),(117575,3,0,'e','1',669127,2957),(117576,3,1,'n','1',669127,2841),(117577,4,0,'n','1',669127,2913),(117578,4,1,'n','1',669127,2790),(117579,4,2,'n','1',669127,2815),(117580,5,0,'n','1',669127,2949),(117581,5,1,'w','1',669127,2948),(117582,5,2,'w','1',669127,2905),(117583,6,0,'e','1',669127,2789),(117584,6,1,'e','1',669127,2818),(117585,7,0,'n','1',669127,2874),(117586,7,1,'w','1',669127,2731),(117587,7,2,'n','1',669127,2730),(117588,7,3,'n','1',669127,2723),(117589,8,0,'w','1',669127,2751),(117590,8,1,'e','1',669127,2871),(117591,8,2,'s','1',669127,2900),(117592,8,3,'n','1',669127,2819),(117593,9,0,'n','1',669127,2934),(117594,9,1,'n','1',669127,2736),(117595,9,2,'n','1',669127,2958),(117596,9,3,'n','1',669127,2905),(117597,10,0,'e','1',669127,2751),(117598,10,1,'e','1',669127,2878),(117599,10,2,'n','1',669127,2879),(117600,10,3,'w','1',669127,2750),(117601,11,0,'e','1',669127,2751),(117602,11,1,'s','1',669127,2747),(117603,11,2,'e','1',669127,2750),(117604,11,3,'w','1',669127,2737),(117605,12,0,'n','1',669127,2800),(117606,12,1,'e','1',669127,2749),(117607,12,2,'e','1',669127,2734),(117608,12,3,'n','1',669127,2740),(117609,13,0,'n','1',669127,2762),(117610,13,1,'n','1',669127,2923),(117611,13,2,'w','1',669127,2834),(117612,13,3,'n','1',669127,2817),(117613,14,0,'w','1',669127,2791),(117614,14,1,'n','1',669127,2903),(117615,14,2,'w','1',669127,2888),(117616,14,3,'n','1',669127,2901),(117617,15,0,'w','1',669127,2832),(117618,15,1,'w','1',669127,2738),(117619,15,2,'n','1',669127,2959),(117620,15,3,'n','1',669127,2905),(117621,16,0,'w','1',669127,2747),(117622,16,1,'w','1',669127,2734),(117623,16,2,'s','1',669127,2960),(117624,16,3,'s','1',669127,2825),(117625,17,0,'e','1',669127,2833),(117626,17,1,'x','0',669127,2799),(117627,17,2,'n','1',669127,2749),(117628,17,3,'w','1',669127,2889),(117629,17,4,'n','1',669127,2959),(117630,18,0,'w','1',669127,2961),(117631,18,1,'w','1',669127,2960),(117632,18,2,'s','1',669127,2933),(117633,18,3,'s','1',669127,2765),(117634,19,0,'n','1',669127,2824),(117635,19,1,'e','1',669127,2762),(117636,19,2,'w','1',669127,2856),(117637,19,3,'s','1',669127,2749),(117638,20,0,'n','1',669127,2732),(117639,20,1,'w','1',669127,2749),(117640,20,2,'w','1',669127,2756),(117641,20,3,'e','1',669127,2822),(117642,21,0,'w','1',669127,2761),(117643,21,1,'e','1',669127,2750),(117644,21,2,'n','1',669127,2729),(117645,21,3,'n','1',669127,2824),(117646,22,0,'e','1',669127,2756),(117647,22,1,'e','1',669127,2749),(117648,22,2,'s','1',669127,2734),(117649,22,3,'n','1',669127,2817),(117650,23,0,'n','1',669127,2756),(117651,23,1,'n','1',669127,2733),(117652,23,2,'e','1',669127,2734),(117653,23,3,'e','1',669127,2798),(117654,24,0,'e','1',669127,2858),(117655,24,1,'e','1',669127,2790),(117656,24,2,'e','1',669127,2797),(117657,24,3,'w','1',669127,2738),(117658,2,0,'n','1',669128,2834),(117659,2,1,'n','1',669128,2779),(117660,2,2,'n','1',669128,2823),(117661,2,3,'n','1',669128,2745),(117662,3,0,'n','1',669128,2780),(117663,3,1,'n','1',669128,2888),(117664,3,2,'n','1',669128,2781),(117665,3,3,'n','1',669128,2941),(117666,4,0,'n','1',669128,2834),(117667,4,1,'n','1',669128,2927),(117668,4,2,'n','1',669128,2823),(117669,4,3,'n','1',669128,2745),(117670,5,0,'n','1',669128,2821),(117671,5,1,'n','1',669128,2779),(117672,5,2,'n','1',669128,2780),(117673,5,3,'n','1',669128,2781),(117674,6,0,'n','1',669128,2868),(117675,6,1,'n','1',669128,2901),(117676,6,2,'n','1',669128,2875),(117677,6,3,'n','1',669128,2849),(117678,7,0,'e','1',669128,2817),(117679,7,1,'n','1',669128,2834),(117680,7,2,'n','1',669128,2823),(117681,7,3,'n','1',669128,2745),(117682,8,0,'n','1',669128,2867),(117683,8,1,'n','1',669128,2816),(117684,8,2,'n','1',669128,2732),(117685,8,3,'n','1',669128,2749),(117686,9,0,'e','1',669128,2903),(117687,9,1,'n','1',669128,2901),(117688,9,2,'n','1',669128,2817),(117689,9,3,'n','1',669128,2824),(117690,10,0,'n','1',669128,2729),(117691,10,1,'w','1',669128,2962),(117692,10,2,'w','1',669128,2843),(117693,10,3,'n','1',669128,2758),(117694,11,0,'s','1',669128,2765),(117695,11,1,'n','1',669128,2749),(117696,11,2,'w','1',669128,2800),(117697,11,3,'n','1',669128,2761),(117698,12,0,'s','1',669128,2765),(117699,12,1,'n','1',669128,2800),(117700,12,2,'e','1',669128,2749),(117701,12,3,'e','1',669128,2761),(117702,13,0,'w','1',669128,2729),(117703,13,1,'w','1',669128,2761),(117704,13,2,'n','1',669128,2796),(117705,13,3,'n','1',669128,2798),(117706,14,0,'n','1',669128,2927),(117707,14,1,'n','1',669128,2779),(117708,14,2,'n','1',669128,2780),(117709,14,3,'n','1',669128,2781),(117710,15,0,'e','1',669128,2963),(117711,15,1,'e','1',669128,2734),(117712,15,2,'w','1',669128,2806),(117713,15,3,'n','1',669128,2738),(117714,16,0,'s','1',669128,2804),(117715,16,1,'s','1',669128,2741),(117716,16,2,'w','1',669128,2849),(117717,16,3,'s','1',669128,2738),(117718,17,0,'s','1',669128,2964),(117719,17,1,'n','1',669128,2842),(117720,17,2,'n','1',669128,2756),(117721,17,3,'w','1',669128,2738),(117722,18,0,'n','1',669128,2965),(117723,18,1,'n','1',669128,2966),(117724,18,2,'n','1',669128,2950),(117725,18,3,'n','1',669128,2946),(117726,19,0,'n','1',669128,2967),(117727,19,1,'w','1',669128,2964),(117728,19,2,'n','1',669128,2815),(117729,19,3,'n','1',669128,2818),(117730,20,0,'e','1',669128,2968),(117731,20,1,'n','1',669128,2858),(117732,20,2,'e','1',669128,2877),(117733,20,3,'n','1',669128,2771),(117734,21,0,'n','1',669128,2870),(117735,21,1,'n','1',669128,2739),(117736,21,2,'n','1',669128,2902),(117737,21,3,'n','1',669128,2778),(117738,22,0,'s','1',669128,2784),(117739,22,1,'w','1',669128,2777),(117740,22,2,'x','0',669128,2778),(117741,22,3,'e','1',669128,2794),(117742,22,4,'n','1',669128,2776),(117743,23,0,'e','1',669128,2969),(117744,23,1,'w','1',669128,2821),(117745,23,2,'n','1',669128,2739),(117746,23,3,'n','1',669128,2775),(117747,24,0,'s','1',669128,2933),(117748,24,1,'w','1',669128,2734),(117749,24,2,'e','1',669128,2970),(117750,24,3,'n','1',669128,2749),(117751,25,0,'n','1',669128,2911),(117752,25,1,'w','1',669128,2765),(117753,25,2,'w','1',669128,2768),(117754,25,3,'e','1',669128,2857),(117755,25,4,'x','0',669128,2881),(117756,26,0,'e','1',669128,2971),(117757,26,1,'e','1',669128,2956),(117758,26,2,'w','1',669128,2972),(117759,26,3,'n','1',669128,2956),(117760,27,0,'w','1',669128,2958),(117761,27,1,'n','1',669128,2789),(117762,27,2,'w','1',669128,2973),(117763,27,3,'w','1',669128,2915),(117764,2,0,'n','1',669128,2834),(117765,2,1,'n','1',669128,2779),(117766,2,2,'n','1',669128,2823),(117767,2,3,'n','1',669128,2745),(117768,3,0,'n','1',669128,2780),(117769,3,1,'n','1',669128,2888),(117770,3,2,'n','1',669128,2781),(117771,3,3,'n','1',669128,2941),(117772,4,0,'n','1',669128,2834),(117773,4,1,'n','1',669128,2927),(117774,4,2,'n','1',669128,2823),(117775,4,3,'n','1',669128,2745),(117776,5,0,'n','1',669128,2821),(117777,5,1,'n','1',669128,2779),(117778,5,2,'n','1',669128,2780),(117779,5,3,'n','1',669128,2781),(117780,6,0,'n','1',669128,2868),(117781,6,1,'n','1',669128,2901),(117782,6,2,'n','1',669128,2875),(117783,6,3,'n','1',669128,2849),(117784,7,0,'e','1',669128,2817),(117785,7,1,'n','1',669128,2834),(117786,7,2,'n','1',669128,2823),(117787,7,3,'n','1',669128,2745),(117788,8,0,'n','1',669128,2867),(117789,8,1,'n','1',669128,2816),(117790,8,2,'n','1',669128,2732),(117791,8,3,'n','1',669128,2749),(117792,9,0,'e','1',669128,2903),(117793,9,1,'n','1',669128,2901),(117794,9,2,'n','1',669128,2817),(117795,9,3,'n','1',669128,2824),(117796,10,0,'n','1',669128,2729),(117797,10,1,'w','1',669128,2962),(117798,10,2,'w','1',669128,2843),(117799,10,3,'n','1',669128,2758),(117800,11,0,'s','1',669128,2765),(117801,11,1,'n','1',669128,2749),(117802,11,2,'w','1',669128,2800),(117803,11,3,'n','1',669128,2761),(117804,12,0,'s','1',669128,2765),(117805,12,1,'n','1',669128,2800),(117806,12,2,'e','1',669128,2749),(117807,12,3,'e','1',669128,2761),(117808,13,0,'w','1',669128,2729),(117809,13,1,'w','1',669128,2761),(117810,13,2,'n','1',669128,2796),(117811,13,3,'n','1',669128,2798),(117812,14,0,'n','1',669128,2927),(117813,14,1,'n','1',669128,2779),(117814,14,2,'n','1',669128,2780),(117815,14,3,'n','1',669128,2781),(117816,15,0,'e','1',669128,2963),(117817,15,1,'e','1',669128,2734),(117818,15,2,'w','1',669128,2806),(117819,15,3,'n','1',669128,2738),(117820,16,0,'s','1',669128,2804),(117821,16,1,'s','1',669128,2741),(117822,16,2,'w','1',669128,2849),(117823,16,3,'s','1',669128,2738),(117824,17,0,'s','1',669128,2964),(117825,17,1,'n','1',669128,2842),(117826,17,2,'n','1',669128,2756),(117827,17,3,'w','1',669128,2738),(117828,18,0,'n','1',669128,2965),(117829,18,1,'n','1',669128,2966),(117830,18,2,'n','1',669128,2950),(117831,18,3,'n','1',669128,2946),(117832,19,0,'n','1',669128,2967),(117833,19,1,'w','1',669128,2964),(117834,19,2,'n','1',669128,2815),(117835,19,3,'n','1',669128,2818),(117836,20,0,'e','1',669128,2968),(117837,20,1,'n','1',669128,2858),(117838,20,2,'e','1',669128,2877),(117839,20,3,'n','1',669128,2771),(117840,21,0,'n','1',669128,2870),(117841,21,1,'n','1',669128,2739),(117842,21,2,'n','1',669128,2902),(117843,21,3,'n','1',669128,2778),(117844,22,0,'s','1',669128,2784),(117845,22,1,'w','1',669128,2777),(117846,22,2,'x','0',669128,2778),(117847,22,3,'e','1',669128,2794),(117848,22,4,'n','1',669128,2776),(117849,23,0,'e','1',669128,2969),(117850,23,1,'w','1',669128,2821),(117851,23,2,'n','1',669128,2739),(117852,23,3,'n','1',669128,2775),(117853,24,0,'s','1',669128,2933),(117854,24,1,'w','1',669128,2734),(117855,24,2,'e','1',669128,2970),(117856,24,3,'n','1',669128,2749),(117857,25,0,'n','1',669128,2911),(117858,25,1,'w','1',669128,2765),(117859,25,2,'w','1',669128,2768),(117860,25,3,'e','1',669128,2857),(117861,25,4,'x','0',669128,2881),(117862,26,0,'e','1',669128,2971),(117863,26,1,'e','1',669128,2956),(117864,26,2,'w','1',669128,2972),(117865,26,3,'n','1',669128,2956),(117866,27,0,'w','1',669128,2958),(117867,27,1,'n','1',669128,2789),(117868,27,2,'w','1',669128,2973),(117869,27,3,'w','1',669128,2915),(117870,2,0,'n','1',669129,2964),(117871,2,1,'n','1',669129,2718),(117872,2,2,'e','1',669129,2869),(117873,2,3,'n','1',669129,2974),(117874,3,0,'w','1',669129,2872),(117875,3,1,'n','1',669129,2720),(117876,3,2,'n','1',669129,2726),(117877,3,3,'n','1',669129,2967),(117878,4,0,'n','1',669129,2873),(117879,4,1,'n','1',669129,2871),(117880,4,2,'n','1',669129,2964),(117881,4,3,'n','1',669129,2975),(117882,5,0,'n','1',669129,2972),(117883,5,1,'w','1',669129,2919),(117884,5,2,'n','1',669129,2976),(117885,5,3,'n','1',669129,2922),(117886,6,0,'s','1',669129,2977),(117887,6,1,'e','1',669129,2904),(117888,6,2,'e','1',669129,2900),(117889,6,3,'n','1',669129,2871),(117890,7,0,'w','1',669129,2977),(117891,7,1,'s','1',669129,2894),(117892,7,2,'s','1',669129,2769),(117893,7,3,'e','1',669129,2978),(117894,8,0,'w','1',669129,2977),(117895,8,1,'s','1',669129,2978),(117896,8,2,'s','1',669129,2979),(117897,8,3,'n','1',669129,2875),(117898,9,0,'n','1',669129,2980),(117899,9,1,'n','1',669129,2900),(117900,9,2,'e','1',669129,2978),(117901,9,3,'n','1',669129,2818),(117902,10,0,'s','1',669129,2977),(117903,10,1,'e','1',669129,2871),(117904,10,2,'w','1',669129,2751),(117905,10,3,'s','1',669129,2766),(117906,11,0,'e','1',669129,2871),(117907,11,1,'e','1',669129,2751),(117908,11,2,'w','1',669129,2750),(117909,11,3,'s','1',669129,2860),(117910,12,0,'e','1',669129,2751),(117911,12,1,'w','1',669129,2860),(117912,12,2,'n','1',669129,2750),(117913,12,3,'s','1',669129,2849),(117914,13,0,'n','1',669129,2768),(117915,13,1,'s','1',669129,2767),(117916,13,2,'w','1',669129,2890),(117917,13,3,'e','1',669129,2893),(117918,14,0,'n','1',669129,2968),(117919,14,1,'w','1',669129,2890),(117920,14,2,'e','1',669129,2981),(117921,14,3,'e','1',669129,2878),(117922,15,0,'s','1',669129,2879),(117923,15,1,'s','1',669129,2859),(117924,15,2,'e','1',669129,2857),(117925,15,3,'n','1',669129,2771),(117926,16,0,'s','1',669129,2879),(117927,16,1,'s','1',669129,2801),(117928,16,2,'e','1',669129,2771),(117929,16,3,'s','1',669129,2793),(117930,17,0,'s','1',669129,2982),(117931,17,1,'w','1',669129,2893),(117932,17,2,'e','1',669129,2931),(117933,17,3,'s','1',669129,2983),(117934,18,0,'s','1',669129,2830),(117935,18,1,'s','1',669129,2977),(117936,18,2,'e','1',669129,2857),(117937,18,3,'e','1',669129,2871),(117938,19,0,'s','1',669129,2774),(117939,19,1,'e','1',669129,2751),(117940,19,2,'s','1',669129,2755),(117941,19,3,'s','1',669129,2746),(117942,20,0,'s','1',669129,2872),(117943,20,1,'s','1',669129,2848),(117944,20,2,'e','1',669129,2783),(117945,20,3,'x','0',669129,2784),(117946,20,4,'n','1',669129,2964),(117947,21,0,'e','1',669129,2750),(117948,21,1,'e','1',669129,2749),(117949,21,2,'e','1',669129,2734),(117950,21,3,'e','1',669129,2817),(117951,22,0,'s','1',669129,2918),(117952,22,1,'s','1',669129,2984),(117953,22,2,'s','1',669129,2914),(117954,22,3,'s','1',669129,2985),(117955,23,0,'n','1',669129,2955),(117956,23,1,'w','1',669129,2915),(117957,23,2,'s','1',669129,2920),(117958,23,3,'s','1',669129,2821),(117959,24,0,'w','1',669129,2738),(117960,24,1,'w','1',669129,2734),(117961,24,2,'w','1',669129,2749),(117962,24,3,'s','1',669129,2970),(117963,25,0,'w','1',669129,2986),(117964,25,1,'s','1',669129,2755),(117965,25,2,'e','1',669129,2750),(117966,25,3,'n','1',669129,2782),(117967,26,0,'e','1',669129,2749),(117968,26,1,'s','1',669129,2740),(117969,26,2,'s','1',669129,2734),(117970,26,3,'n','1',669129,2797),(117971,27,0,'n','1',669129,2733),(117972,27,1,'s','1',669129,2734),(117973,27,2,'e','1',669129,2747),(117974,28,0,'n','1',669129,2745),(117975,28,1,'n','1',669129,2922),(117976,28,2,'n','1',669129,2733),(117977,28,3,'w','1',669129,2920),(117978,29,0,'n','1',669129,2872),(117979,29,1,'s','1',669129,2877),(117980,29,2,'e','1',669129,2781),(117981,29,3,'e','1',669129,2789),(117982,30,0,'w','1',669129,2734),(117983,30,1,'w','1',669129,2749),(117984,30,2,'s','1',669129,2833),(117985,30,3,'w','1',669129,2750),(117986,31,0,'n','1',669129,2908),(117987,31,1,'n','1',669129,2770),(117988,31,2,'n','1',669129,2748),(117989,31,3,'e','1',669129,2764),(117990,32,0,'e','1',669129,2751),(117991,32,1,'e','1',669129,2846),(117992,32,2,'e','1',669129,2950),(117993,32,3,'n','1',669129,2959),(117994,33,0,'e','1',669129,2750),(117995,33,1,'s','1',669129,2752),(117996,33,2,'n','1',669129,2970),(117997,33,3,'n','1',669129,2749),(117998,34,0,'w','1',669129,2875),(117999,34,1,'e','1',669129,2761),(118000,34,2,'w','1',669129,2883),(118001,34,3,'n','1',669129,2838),(118002,35,0,'e','1',669129,2826),(118003,35,1,'e','1',669129,2936),(118004,35,2,'s','1',669129,2844),(118005,35,3,'e','1',669129,2765),(118006,36,0,'w','1',669129,2987),(118007,36,1,'w','1',669129,2744),(118008,36,2,'s','1',669129,2821),(118009,36,3,'e','1',669129,2960),(118010,37,0,'s','1',669129,2765),(118011,37,1,'n','1',669129,2749),(118012,37,2,'w','1',669129,2832),(118013,37,3,'e','1',669129,2839),(118014,38,0,'n','1',669129,2765),(118015,38,1,'w','1',669129,2844),(118016,38,2,'w','1',669129,2987),(118017,38,3,'s','1',669129,2988),(118018,39,0,'e','1',669129,2765),(118019,39,1,'s','1',669129,2832),(118020,39,2,'s','1',669129,2744),(118021,39,3,'w','1',669129,2989),(118022,40,0,'s','1',669129,2734),(118023,40,1,'w','1',669129,2843),(118024,40,2,'w','1',669129,2914),(118025,40,3,'n','1',669129,2745),(118026,41,0,'n','1',669129,2758),(118027,41,1,'n','1',669129,2733),(118028,41,2,'s','1',669129,2804),(118029,41,3,'e','1',669129,2734),(118030,42,0,'w','1',669129,2832),(118031,42,1,'w','1',669129,2738),(118032,42,2,'s','1',669129,2747),(118033,42,3,'w','1',669129,2734),(118034,43,0,'w','1',669129,2745),(118035,43,1,'s','1',669129,2914),(118036,43,2,'w','1',669129,2749),(118037,43,3,'s','1',669129,2833),(118038,44,0,'w','1',669129,2729),(118039,44,1,'w','1',669129,2920),(118040,44,2,'s','1',669129,2761),(118041,44,3,'x','0',669129,2762),(118042,44,4,'w','1',669129,2959),(118043,45,0,'w','1',669129,2750),(118044,45,1,'s','1',669129,2878),(118045,45,2,'s','1',669129,2877),(118046,45,3,'e','1',669129,2781),(118047,46,0,'e','1',669129,2751),(118048,46,1,'n','1',669129,2750),(118049,46,2,'e','1',669129,2768),(118050,46,3,'e','1',669129,2802),(118051,47,0,'n','1',669129,2884),(118052,47,1,'w','1',669129,2948),(118053,47,2,'w','1',669129,2954),(118054,47,3,'w','1',669129,2855),(118055,48,0,'w','1',669129,2765),(118056,48,1,'n','1',669129,2768),(118057,48,2,'s','1',669129,2853),(118058,48,3,'x','0',669129,2910),(118059,48,4,'w','1',669129,2890),(118060,49,0,'n','1',669129,2990),(118061,49,1,'s','1',669129,2855),(118062,49,2,'s','1',669129,2872),(118063,49,3,'w','1',669129,2725),(118064,2,0,'n','1',669129,2964),(118065,2,1,'n','1',669129,2718),(118066,2,2,'e','1',669129,2869),(118067,2,3,'n','1',669129,2974),(118068,3,0,'w','1',669129,2872),(118069,3,1,'n','1',669129,2720),(118070,3,2,'n','1',669129,2726),(118071,3,3,'n','1',669129,2967),(118072,4,0,'n','1',669129,2873),(118073,4,1,'n','1',669129,2871),(118074,4,2,'n','1',669129,2964),(118075,4,3,'n','1',669129,2975),(118076,5,0,'n','1',669129,2972),(118077,5,1,'w','1',669129,2919),(118078,5,2,'n','1',669129,2976),(118079,5,3,'n','1',669129,2922),(118080,6,0,'s','1',669129,2977),(118081,6,1,'e','1',669129,2904),(118082,6,2,'e','1',669129,2900),(118083,6,3,'n','1',669129,2871),(118084,7,0,'w','1',669129,2977),(118085,7,1,'s','1',669129,2894),(118086,7,2,'s','1',669129,2769),(118087,7,3,'e','1',669129,2978),(118088,8,0,'w','1',669129,2977),(118089,8,1,'s','1',669129,2978),(118090,8,2,'s','1',669129,2979),(118091,8,3,'n','1',669129,2875),(118092,9,0,'n','1',669129,2980),(118093,9,1,'n','1',669129,2900),(118094,9,2,'e','1',669129,2978),(118095,9,3,'n','1',669129,2818),(118096,10,0,'s','1',669129,2977),(118097,10,1,'e','1',669129,2871),(118098,10,2,'w','1',669129,2751),(118099,10,3,'s','1',669129,2766),(118100,11,0,'e','1',669129,2871),(118101,11,1,'e','1',669129,2751),(118102,11,2,'w','1',669129,2750),(118103,11,3,'s','1',669129,2860),(118104,12,0,'e','1',669129,2751),(118105,12,1,'w','1',669129,2860),(118106,12,2,'n','1',669129,2750),(118107,12,3,'s','1',669129,2849),(118108,13,0,'n','1',669129,2768),(118109,13,1,'s','1',669129,2767),(118110,13,2,'w','1',669129,2890),(118111,13,3,'e','1',669129,2893),(118112,14,0,'n','1',669129,2968),(118113,14,1,'w','1',669129,2890),(118114,14,2,'e','1',669129,2981),(118115,14,3,'e','1',669129,2878),(118116,15,0,'s','1',669129,2879),(118117,15,1,'s','1',669129,2859),(118118,15,2,'e','1',669129,2857),(118119,15,3,'n','1',669129,2771),(118120,16,0,'s','1',669129,2879),(118121,16,1,'s','1',669129,2801),(118122,16,2,'e','1',669129,2771),(118123,16,3,'s','1',669129,2793),(118124,17,0,'s','1',669129,2982),(118125,17,1,'w','1',669129,2893),(118126,17,2,'e','1',669129,2931),(118127,17,3,'s','1',669129,2983),(118128,18,0,'s','1',669129,2830),(118129,18,1,'s','1',669129,2977),(118130,18,2,'e','1',669129,2857),(118131,18,3,'e','1',669129,2871),(118132,19,0,'s','1',669129,2774),(118133,19,1,'e','1',669129,2751),(118134,19,2,'s','1',669129,2755),(118135,19,3,'s','1',669129,2746),(118136,20,0,'s','1',669129,2872),(118137,20,1,'s','1',669129,2848),(118138,20,2,'e','1',669129,2783),(118139,20,3,'x','0',669129,2784),(118140,20,4,'n','1',669129,2964),(118141,21,0,'e','1',669129,2750),(118142,21,1,'e','1',669129,2749),(118143,21,2,'e','1',669129,2734),(118144,21,3,'e','1',669129,2817),(118145,22,0,'s','1',669129,2918),(118146,22,1,'s','1',669129,2984),(118147,22,2,'s','1',669129,2914),(118148,22,3,'s','1',669129,2985),(118149,23,0,'n','1',669129,2955),(118150,23,1,'w','1',669129,2915),(118151,23,2,'s','1',669129,2920),(118152,23,3,'s','1',669129,2821),(118153,24,0,'w','1',669129,2738),(118154,24,1,'w','1',669129,2734),(118155,24,2,'w','1',669129,2749),(118156,24,3,'s','1',669129,2970),(118157,25,0,'w','1',669129,2986),(118158,25,1,'s','1',669129,2755),(118159,25,2,'e','1',669129,2750),(118160,25,3,'n','1',669129,2782),(118161,26,0,'e','1',669129,2749),(118162,26,1,'s','1',669129,2740),(118163,26,2,'s','1',669129,2734),(118164,26,3,'n','1',669129,2797),(118165,27,0,'n','1',669129,2733),(118166,27,1,'s','1',669129,2734),(118167,27,2,'e','1',669129,2747),(118168,28,0,'n','1',669129,2745),(118169,28,1,'n','1',669129,2922),(118170,28,2,'n','1',669129,2733),(118171,28,3,'w','1',669129,2920),(118172,29,0,'n','1',669129,2872),(118173,29,1,'s','1',669129,2877),(118174,29,2,'e','1',669129,2781),(118175,29,3,'e','1',669129,2789),(118176,30,0,'w','1',669129,2734),(118177,30,1,'w','1',669129,2749),(118178,30,2,'s','1',669129,2833),(118179,30,3,'w','1',669129,2750),(118180,31,0,'n','1',669129,2908),(118181,31,1,'n','1',669129,2770),(118182,31,2,'n','1',669129,2748),(118183,31,3,'e','1',669129,2764),(118184,32,0,'e','1',669129,2751),(118185,32,1,'e','1',669129,2846),(118186,32,2,'e','1',669129,2950),(118187,32,3,'n','1',669129,2959),(118188,33,0,'e','1',669129,2750),(118189,33,1,'s','1',669129,2752),(118190,33,2,'n','1',669129,2970),(118191,33,3,'n','1',669129,2749),(118192,34,0,'w','1',669129,2875),(118193,34,1,'e','1',669129,2761),(118194,34,2,'w','1',669129,2883),(118195,34,3,'n','1',669129,2838),(118196,35,0,'e','1',669129,2826),(118197,35,1,'e','1',669129,2936),(118198,35,2,'s','1',669129,2844),(118199,35,3,'e','1',669129,2765),(118200,36,0,'w','1',669129,2987),(118201,36,1,'w','1',669129,2744),(118202,36,2,'s','1',669129,2821),(118203,36,3,'e','1',669129,2960),(118204,37,0,'s','1',669129,2765),(118205,37,1,'n','1',669129,2749),(118206,37,2,'w','1',669129,2832),(118207,37,3,'e','1',669129,2839),(118208,38,0,'n','1',669129,2765),(118209,38,1,'w','1',669129,2844),(118210,38,2,'w','1',669129,2987),(118211,38,3,'s','1',669129,2988),(118212,39,0,'e','1',669129,2765),(118213,39,1,'s','1',669129,2832),(118214,39,2,'s','1',669129,2744),(118215,39,3,'w','1',669129,2989),(118216,40,0,'s','1',669129,2734),(118217,40,1,'w','1',669129,2843),(118218,40,2,'w','1',669129,2914),(118219,40,3,'n','1',669129,2745),(118220,41,0,'n','1',669129,2758),(118221,41,1,'n','1',669129,2733),(118222,41,2,'s','1',669129,2804),(118223,41,3,'e','1',669129,2734),(118224,42,0,'w','1',669129,2832),(118225,42,1,'w','1',669129,2738),(118226,42,2,'s','1',669129,2747),(118227,42,3,'w','1',669129,2734),(118228,43,0,'w','1',669129,2745),(118229,43,1,'s','1',669129,2914),(118230,43,2,'w','1',669129,2749),(118231,43,3,'s','1',669129,2833),(118232,44,0,'w','1',669129,2729),(118233,44,1,'w','1',669129,2920),(118234,44,2,'s','1',669129,2761),(118235,44,3,'x','0',669129,2762),(118236,44,4,'w','1',669129,2959),(118237,45,0,'w','1',669129,2750),(118238,45,1,'s','1',669129,2878),(118239,45,2,'s','1',669129,2877),(118240,45,3,'e','1',669129,2781),(118241,46,0,'e','1',669129,2751),(118242,46,1,'n','1',669129,2750),(118243,46,2,'e','1',669129,2768),(118244,46,3,'e','1',669129,2802),(118245,47,0,'n','1',669129,2884),(118246,47,1,'w','1',669129,2948),(118247,47,2,'w','1',669129,2954),(118248,47,3,'w','1',669129,2855),(118249,48,0,'w','1',669129,2765),(118250,48,1,'n','1',669129,2768),(118251,48,2,'s','1',669129,2853),(118252,48,3,'x','0',669129,2910),(118253,48,4,'w','1',669129,2890),(118254,49,0,'n','1',669129,2990),(118255,49,1,'s','1',669129,2855),(118256,49,2,'s','1',669129,2872),(118257,49,3,'w','1',669129,2725),(118258,2,0,'n','1',669130,2728),(118259,2,1,'n','1',669130,2991),(118260,2,2,'w','1',669130,2722),(118261,2,3,'n','1',669130,2717),(118262,3,0,'n','1',669130,2736),(118263,3,1,'n','1',669130,2992),(118264,3,2,'n','1',669130,2993),(118265,3,3,'e','1',669130,2737),(118266,4,0,'n','1',669130,2813),(118267,4,1,'n','1',669130,2728),(118268,4,2,'n','1',669130,2842),(118269,4,3,'n','1',669130,2738),(118270,5,0,'s','1',669130,2741),(118271,5,1,'s','1',669130,2742),(118272,5,2,'w','1',669130,2738),(118273,5,3,'s','1',669130,2743),(118274,6,0,'e','1',669130,2734),(118275,6,1,'n','1',669130,2791),(118276,6,2,'n','1',669130,2777),(118277,6,3,'w','1',669130,2774),(118278,7,0,'n','1',669130,2719),(118279,7,1,'n','1',669130,2845),(118280,7,2,'n','1',669130,2846),(118281,7,3,'n','1',669130,2724),(118282,8,0,'e','1',669130,2769),(118283,8,1,'w','1',669130,2766),(118284,8,2,'s','1',669130,2767),(118285,8,3,'x','0',669130,2859),(118286,8,4,'n','1',669130,2753),(118287,9,0,'w','1',669130,2738),(118288,9,1,'e','1',669130,2734),(118289,9,2,'s','1',669130,2844),(118290,9,3,'n','1',669130,2794),(118291,10,0,'w','1',669130,2738),(118292,10,1,'w','1',669130,2734),(118293,10,2,'n','1',669130,2749),(118294,10,3,'w','1',669130,2820),(118295,11,0,'w','1',669130,2860),(118296,11,1,'w','1',669130,2765),(118297,11,2,'w','1',669130,2737),(118298,11,3,'w','1',669130,2740),(118299,12,0,'n','1',669130,2963),(118300,12,1,'n','1',669130,2915),(118301,12,2,'n','1',669130,2754),(118302,12,3,'w','1',669130,2776),(118303,13,0,'s','1',669130,2792),(118304,13,1,'s','1',669130,2768),(118305,13,2,'e','1',669130,2750),(118306,13,3,'e','1',669130,2749),(118307,2,0,'n','1',669130,2728),(118308,2,1,'n','1',669130,2991),(118309,2,2,'w','1',669130,2722),(118310,2,3,'n','1',669130,2717),(118311,3,0,'n','1',669130,2736),(118312,3,1,'n','1',669130,2992),(118313,3,2,'n','1',669130,2993),(118314,3,3,'e','1',669130,2737),(118315,4,0,'n','1',669130,2813),(118316,4,1,'n','1',669130,2728),(118317,4,2,'n','1',669130,2842),(118318,4,3,'n','1',669130,2738),(118319,5,0,'s','1',669130,2741),(118320,5,1,'s','1',669130,2742),(118321,5,2,'w','1',669130,2738),(118322,5,3,'s','1',669130,2743),(118323,6,0,'e','1',669130,2734),(118324,6,1,'n','1',669130,2791),(118325,6,2,'n','1',669130,2777),(118326,6,3,'w','1',669130,2774),(118327,7,0,'n','1',669130,2719),(118328,7,1,'n','1',669130,2845),(118329,7,2,'n','1',669130,2846),(118330,7,3,'n','1',669130,2724),(118331,8,0,'e','1',669130,2769),(118332,8,1,'w','1',669130,2766),(118333,8,2,'s','1',669130,2767),(118334,8,3,'x','0',669130,2859),(118335,8,4,'n','1',669130,2753),(118336,9,0,'w','1',669130,2738),(118337,9,1,'e','1',669130,2734),(118338,9,2,'s','1',669130,2844),(118339,9,3,'n','1',669130,2794),(118340,10,0,'w','1',669130,2738),(118341,10,1,'w','1',669130,2734),(118342,10,2,'n','1',669130,2749),(118343,10,3,'w','1',669130,2820),(118344,11,0,'w','1',669130,2860),(118345,11,1,'w','1',669130,2765),(118346,11,2,'w','1',669130,2737),(118347,11,3,'w','1',669130,2740),(118348,12,0,'n','1',669130,2963),(118349,12,1,'n','1',669130,2915),(118350,12,2,'n','1',669130,2754),(118351,12,3,'w','1',669130,2776),(118352,13,0,'s','1',669130,2792),(118353,13,1,'s','1',669130,2768),(118354,13,2,'e','1',669130,2750),(118355,13,3,'e','1',669130,2749),(118356,2,0,'n','1',669131,2867),(118357,2,1,'n','1',669131,2816),(118358,2,2,'n','1',669131,2732),(118359,2,3,'n','1',669131,2749),(118360,3,0,'n','1',669131,2717),(118361,3,1,'e','1',669131,2719),(118362,3,2,'e','1',669131,2725),(118363,3,3,'n','1',669131,2721),(118364,4,0,'e','1',669131,2735),(118365,4,1,'e','1',669131,2884),(118366,4,2,'e','1',669131,2883),(118367,4,3,'n','1',669131,2888),(118368,5,0,'n','1',669131,2875),(118369,5,1,'e','1',669131,2849),(118370,5,2,'w','1',669131,2916),(118371,5,3,'s','1',669131,2921),(118372,6,0,'e','1',669131,2815),(118373,6,1,'w','1',669131,2849),(118374,6,2,'w','1',669131,2820),(118375,6,3,'n','1',669131,2754),(118376,7,0,'n','1',669131,2739),(118377,7,1,'s','1',669131,2737),(118378,7,2,'e','1',669131,2850),(118379,7,3,'n','1',669131,2963),(118380,8,0,'w','1',669131,2736),(118381,8,1,'x','0',669131,2760),(118382,8,2,'s','1',669131,2849),(118383,8,3,'w','1',669131,2915),(118384,8,4,'w','1',669131,2905),(118385,9,0,'n','1',669131,2875),(118386,9,1,'n','1',669131,2849),(118387,9,2,'s','1',669131,2804),(118388,9,3,'s','1',669131,2806),(118389,10,0,'n','1',669131,2820),(118390,10,1,'n','1',669131,2921),(118391,10,2,'n','1',669131,2837),(118392,10,3,'w','1',669131,2805),(118393,11,0,'e','1',669131,2765),(118394,11,1,'w','1',669131,2744),(118395,11,2,'s','1',669131,2826),(118396,11,3,'x','0',669131,2757),(118397,11,4,'n','1',669131,2903),(118398,12,0,'e','1',669131,2849),(118399,12,1,'n','1',669131,2916),(118400,12,2,'s','1',669131,2917),(118401,12,3,'s','1',669131,2805),(118402,13,0,'s','1',669131,2916),(118403,13,1,'s','1',669131,2921),(118404,13,2,'w','1',669131,2919),(118405,13,3,'s','1',669131,2820),(118406,14,0,'n','1',669131,2838),(118407,14,1,'s','1',669131,2820),(118408,14,2,'e','1',669131,2849),(118409,14,3,'w','1',669131,2778),(118410,15,0,'n','1',669131,2756),(118411,15,1,'n','1',669131,2807),(118412,15,2,'n','1',669131,2789),(118413,15,3,'e','1',669131,2815),(118414,16,0,'w','1',669131,2836),(118415,16,1,'s','1',669131,2994),(118416,16,2,'e','1',669131,2826),(118417,16,3,'e','1',669131,2936),(118418,17,0,'n','1',669131,2905),(118419,17,1,'n','1',669131,2762),(118420,17,2,'n','1',669131,2761),(118421,17,3,'n','1',669131,2901),(118422,18,0,'n','1',669131,2927),(118423,18,1,'n','1',669131,2775),(118424,18,2,'n','1',669131,2739),(118425,18,3,'e','1',669131,2851),(118426,19,0,'e','1',669131,2934),(118427,19,1,'w','1',669131,2765),(118428,19,2,'n','1',669131,2787),(118429,19,3,'n','1',669131,2788),(118430,20,0,'n','1',669131,2834),(118431,20,1,'w','1',669131,2823),(118432,20,2,'s','1',669131,2768),(118433,20,3,'s','1',669131,2750),(118434,21,0,'w','1',669131,2783),(118435,21,1,'n','1',669131,2964),(118436,21,2,'n','1',669131,2778),(118437,21,3,'w','1',669131,2794),(118438,22,0,'n','1',669131,2772),(118439,22,1,'n','1',669131,2771),(118440,22,2,'w','1',669131,2731),(118441,22,3,'e','1',669131,2879),(118442,23,0,'s','1',669131,2833),(118443,23,1,'s','1',669131,2912),(118444,23,2,'e','1',669131,2852),(118445,23,3,'n','1',669131,2788),(118446,24,0,'e','1',669131,2739),(118447,24,1,'e','1',669131,2730),(118448,24,2,'s','1',669131,2735),(118449,24,3,'s','1',669131,2731),(118450,25,0,'s','1',669131,2748),(118451,25,1,'w','1',669131,2770),(118452,25,2,'w','1',669131,2831),(118453,25,3,'s','1',669131,2771),(118454,26,0,'w','1',669131,2783),(118455,26,1,'w','1',669131,2772),(118456,26,2,'s','1',669131,2874),(118457,26,3,'e','1',669131,2915),(118458,27,0,'n','1',669131,2913),(118459,27,1,'e','1',669131,2995),(118460,27,2,'e','1',669131,2965),(118461,27,3,'s','1',669131,2874),(118462,28,0,'e','1',669131,2822),(118463,28,1,'w','1',669131,2953),(118464,28,2,'s','1',669131,2897),(118465,28,3,'n','1',669131,2795),(118466,29,0,'e','1',669131,2913),(118467,29,1,'n','1',669131,2934),(118468,29,2,'e','1',669131,2795),(118469,29,3,'n','1',669131,2867),(118470,30,0,'s','1',669131,2816),(118471,30,1,'s','1',669131,2996),(118472,30,2,'e','1',669131,2867),(118473,30,3,'e','1',669131,2902),(118474,31,0,'w','1',669131,2797),(118475,31,1,'n','1',669131,2796),(118476,31,2,'w','1',669131,2833),(118477,31,3,'s','1',669131,2872),(118478,32,0,'e','1',669131,2858),(118479,32,1,'n','1',669131,2798),(118480,32,2,'e','1',669131,2852),(118481,32,3,'w','1',669131,2997),(118482,33,0,'e','1',669131,2860),(118483,33,1,'w','1',669131,2833),(118484,33,2,'s','1',669131,2998),(118485,33,3,'w','1',669131,2836),(118486,34,0,'w','1',669131,2790),(118487,34,1,'n','1',669131,2757),(118488,34,2,'e','1',669131,2935),(118489,34,3,'x','0',669131,2809),(118490,34,4,'s','1',669131,2936),(118491,35,0,'s','1',669131,2743),(118492,35,1,'s','1',669131,2999),(118493,35,2,'w','1',669131,2837),(118494,35,3,'x','0',669131,2757),(118495,35,4,'n','1',669131,2804),(118496,36,0,'e','1',669131,2858),(118497,36,1,'w','1',669131,2743),(118498,36,2,'s','1',669131,3000),(118499,36,3,'e','1',669131,2826),(118500,37,0,'n','1',669131,2844),(118501,37,1,'w','1',669131,3001),(118502,37,2,'x','0',669131,2799),(118503,37,3,'w','1',669131,2790),(118504,37,4,'e','1',669131,2858),(118505,38,0,'s','1',669131,3002),(118506,38,1,'s','1',669131,2994),(118507,38,2,'e','1',669131,2844),(118508,38,3,'s','1',669131,2826),(118509,38,4,'x','0',669131,2757),(118510,2,0,'n','1',669131,2867),(118511,2,1,'n','1',669131,2816),(118512,2,2,'n','1',669131,2732),(118513,2,3,'n','1',669131,2749),(118514,3,0,'n','1',669131,2717),(118515,3,1,'e','1',669131,2719),(118516,3,2,'e','1',669131,2725),(118517,3,3,'n','1',669131,2721),(118518,4,0,'e','1',669131,2735),(118519,4,1,'e','1',669131,2884),(118520,4,2,'e','1',669131,2883),(118521,4,3,'n','1',669131,2888),(118522,5,0,'n','1',669131,2875),(118523,5,1,'e','1',669131,2849),(118524,5,2,'w','1',669131,2916),(118525,5,3,'s','1',669131,2921),(118526,6,0,'e','1',669131,2815),(118527,6,1,'w','1',669131,2849),(118528,6,2,'w','1',669131,2820),(118529,6,3,'n','1',669131,2754),(118530,7,0,'n','1',669131,2739),(118531,7,1,'s','1',669131,2737),(118532,7,2,'e','1',669131,2850),(118533,7,3,'n','1',669131,2963),(118534,8,0,'w','1',669131,2736),(118535,8,1,'x','0',669131,2760),(118536,8,2,'s','1',669131,2849),(118537,8,3,'w','1',669131,2915),(118538,8,4,'w','1',669131,2905),(118539,9,0,'n','1',669131,2875),(118540,9,1,'n','1',669131,2849),(118541,9,2,'s','1',669131,2804),(118542,9,3,'s','1',669131,2806),(118543,10,0,'n','1',669131,2820),(118544,10,1,'n','1',669131,2921),(118545,10,2,'n','1',669131,2837),(118546,10,3,'w','1',669131,2805),(118547,11,0,'e','1',669131,2765),(118548,11,1,'w','1',669131,2744),(118549,11,2,'s','1',669131,2826),(118550,11,3,'x','0',669131,2757),(118551,11,4,'n','1',669131,2903),(118552,12,0,'e','1',669131,2849),(118553,12,1,'n','1',669131,2916),(118554,12,2,'s','1',669131,2917),(118555,12,3,'s','1',669131,2805),(118556,13,0,'s','1',669131,2916),(118557,13,1,'s','1',669131,2921),(118558,13,2,'w','1',669131,2919),(118559,13,3,'s','1',669131,2820),(118560,14,0,'n','1',669131,2838),(118561,14,1,'s','1',669131,2820),(118562,14,2,'e','1',669131,2849),(118563,14,3,'w','1',669131,2778),(118564,15,0,'n','1',669131,2756),(118565,15,1,'n','1',669131,2807),(118566,15,2,'n','1',669131,2789),(118567,15,3,'e','1',669131,2815),(118568,16,0,'w','1',669131,2836),(118569,16,1,'s','1',669131,2994),(118570,16,2,'e','1',669131,2826),(118571,16,3,'e','1',669131,2936),(118572,17,0,'n','1',669131,2905),(118573,17,1,'n','1',669131,2762),(118574,17,2,'n','1',669131,2761),(118575,17,3,'n','1',669131,2901),(118576,18,0,'n','1',669131,2927),(118577,18,1,'n','1',669131,2775),(118578,18,2,'n','1',669131,2739),(118579,18,3,'e','1',669131,2851),(118580,19,0,'e','1',669131,2934),(118581,19,1,'w','1',669131,2765),(118582,19,2,'n','1',669131,2787),(118583,19,3,'n','1',669131,2788),(118584,20,0,'n','1',669131,2834),(118585,20,1,'w','1',669131,2823),(118586,20,2,'s','1',669131,2768),(118587,20,3,'s','1',669131,2750),(118588,21,0,'w','1',669131,2783),(118589,21,1,'n','1',669131,2964),(118590,21,2,'n','1',669131,2778),(118591,21,3,'w','1',669131,2794),(118592,22,0,'n','1',669131,2772),(118593,22,1,'n','1',669131,2771),(118594,22,2,'w','1',669131,2731),(118595,22,3,'e','1',669131,2879),(118596,23,0,'s','1',669131,2833),(118597,23,1,'s','1',669131,2912),(118598,23,2,'e','1',669131,2852),(118599,23,3,'n','1',669131,2788),(118600,24,0,'e','1',669131,2739),(118601,24,1,'e','1',669131,2730),(118602,24,2,'s','1',669131,2735),(118603,24,3,'s','1',669131,2731),(118604,25,0,'s','1',669131,2748),(118605,25,1,'w','1',669131,2770),(118606,25,2,'w','1',669131,2831),(118607,25,3,'s','1',669131,2771),(118608,26,0,'w','1',669131,2783),(118609,26,1,'w','1',669131,2772),(118610,26,2,'s','1',669131,2874),(118611,26,3,'e','1',669131,2915),(118612,27,0,'n','1',669131,2913),(118613,27,1,'e','1',669131,2995),(118614,27,2,'e','1',669131,2965),(118615,27,3,'s','1',669131,2874),(118616,28,0,'e','1',669131,2822),(118617,28,1,'w','1',669131,2953),(118618,28,2,'s','1',669131,2897),(118619,28,3,'n','1',669131,2795),(118620,29,0,'e','1',669131,2913),(118621,29,1,'n','1',669131,2934),(118622,29,2,'e','1',669131,2795),(118623,29,3,'n','1',669131,2867),(118624,30,0,'s','1',669131,2816),(118625,30,1,'s','1',669131,2996),(118626,30,2,'e','1',669131,2867),(118627,30,3,'e','1',669131,2902),(118628,31,0,'w','1',669131,2797),(118629,31,1,'n','1',669131,2796),(118630,31,2,'w','1',669131,2833),(118631,31,3,'s','1',669131,2872),(118632,32,0,'e','1',669131,2858),(118633,32,1,'n','1',669131,2798),(118634,32,2,'e','1',669131,2852),(118635,32,3,'w','1',669131,2997),(118636,33,0,'e','1',669131,2860),(118637,33,1,'w','1',669131,2833),(118638,33,2,'s','1',669131,2998),(118639,33,3,'w','1',669131,2836),(118640,34,0,'w','1',669131,2790),(118641,34,1,'n','1',669131,2757),(118642,34,2,'e','1',669131,2935),(118643,34,3,'x','0',669131,2809),(118644,34,4,'s','1',669131,2936),(118645,35,0,'s','1',669131,2743),(118646,35,1,'s','1',669131,2999),(118647,35,2,'w','1',669131,2837),(118648,35,3,'x','0',669131,2757),(118649,35,4,'n','1',669131,2804),(118650,36,0,'e','1',669131,2858),(118651,36,1,'w','1',669131,2743),(118652,36,2,'s','1',669131,3000),(118653,36,3,'e','1',669131,2826),(118654,37,0,'n','1',669131,2844),(118655,37,1,'w','1',669131,3001),(118656,37,2,'x','0',669131,2799),(118657,37,3,'w','1',669131,2790),(118658,37,4,'e','1',669131,2858),(118659,38,0,'s','1',669131,3002),(118660,38,1,'s','1',669131,2994),(118661,38,2,'e','1',669131,2844),(118662,38,3,'s','1',669131,2826),(118663,38,4,'x','0',669131,2757),(118664,2,0,'n','1',669132,2728),(118665,2,1,'n','1',669132,3003),(118666,2,2,'n','1',669132,2814),(118667,2,3,'n','1',669132,2733),(118668,3,0,'n','1',669132,2721),(118669,3,1,'n','1',669132,2754),(118670,3,2,'n','1',669132,2903),(118671,3,3,'n','1',669132,2782),(118672,4,0,'n','1',669132,2717),(118673,4,1,'n','1',669132,2882),(118674,4,2,'w','1',669132,2858),(118675,4,3,'w','1',669132,2790),(118676,5,0,'e','1',669132,2734),(118677,5,1,'n','1',669132,2738),(118678,5,2,'n','1',669132,2779),(118679,5,3,'n','1',669132,2723),(118680,6,0,'s','1',669132,2741),(118681,6,1,'w','1',669132,2805),(118682,6,2,'w','1',669132,2738),(118683,6,3,'s','1',669132,2806),(118684,7,0,'e','1',669132,2734),(118685,7,1,'w','1',669132,2743),(118686,7,2,'n','1',669132,2738),(118687,7,3,'s','1',669132,2741),(118688,8,0,'w','1',669132,2738),(118689,8,1,'w','1',669132,2921),(118690,8,2,'w','1',669132,2734),(118691,8,3,'w','1',669132,2759),(118692,9,0,'e','1',669132,2749),(118693,9,1,'e','1',669132,2734),(118694,9,2,'w','1',669132,2743),(118695,9,3,'n','1',669132,2738),(118696,10,0,'n','1',669132,2741),(118697,10,1,'s','1',669132,2826),(118698,10,2,'w','1',669132,3004),(118699,10,3,'e','1',669132,3005),(118700,11,0,'s','1',669132,2837),(118701,11,1,'s','1',669132,3004),(118702,11,2,'s','1',669132,2843),(118703,11,3,'s','1',669132,2741),(118704,12,0,'w','1',669132,2729),(118705,12,1,'s','1',669132,2738),(118706,12,2,'s','1',669132,2761),(118707,12,3,'w','1',669132,2842),(118708,13,0,'w','1',669132,2796),(118709,13,1,'w','1',669132,2776),(118710,13,2,'w','1',669132,2794),(118711,13,3,'w','1',669132,2831),(118712,14,0,'n','1',669132,2733),(118713,14,1,'w','1',669132,2734),(118714,14,2,'w','1',669132,2749),(118715,14,3,'s','1',669132,2987),(118716,15,0,'e','1',669132,2750),(118717,15,1,'w','1',669132,2987),(118718,15,2,'n','1',669132,2749),(118719,15,3,'w','1',669132,2820),(118720,16,0,'w','1',669132,2765),(118721,16,1,'e','1',669132,2737),(118722,16,2,'e','1',669132,2768),(118723,16,3,'s','1',669132,2864),(118724,17,0,'s','1',669132,2765),(118725,17,1,'e','1',669132,2749),(118726,17,2,'e','1',669132,2734),(118727,17,3,'n','1',669132,2780),(118728,18,0,'w','1',669132,2738),(118729,18,1,'w','1',669132,2921),(118730,18,2,'s','1',669132,2759),(118731,18,3,'e','1',669132,2734),(118732,19,0,'n','1',669132,2719),(118733,19,1,'n','1',669132,2845),(118734,19,2,'e','1',669132,2900),(118735,19,3,'n','1',669132,2846),(118736,20,0,'w','1',669132,2738),(118737,20,1,'s','1',669132,2734),(118738,20,2,'s','1',669132,2844),(118739,20,3,'n','1',669132,2819),(118740,21,0,'n','1',669132,2733),(118741,21,1,'e','1',669132,2734),(118742,21,2,'e','1',669132,3006),(118743,21,3,'n','1',669132,2783),(118744,22,0,'w','1',669132,2738),(118745,22,1,'s','1',669132,2734),(118746,22,2,'n','1',669132,2848),(118747,22,3,'n','1',669132,2887),(118748,23,0,'e','1',669132,2830),(118749,23,1,'n','1',669132,2793),(118750,23,2,'e','1',669132,2767),(118751,23,3,'n','1',669132,2801),(118752,24,0,'e','1',669132,2769),(118753,24,1,'s','1',669132,2793),(118754,24,2,'s','1',669132,2766),(118755,24,3,'e','1',669132,2942),(118756,25,0,'w','1',669132,2854),(118757,25,1,'e','1',669132,2846),(118758,25,2,'s','1',669132,2931),(118759,25,3,'e','1',669132,2942),(118760,26,0,'w','1',669132,3007),(118761,26,1,'n','1',669132,2859),(118762,26,2,'s','1',669132,2931),(118763,26,3,'s','1',669132,3008),(118764,2,0,'n','1',669132,2728),(118765,2,1,'n','1',669132,3003),(118766,2,2,'n','1',669132,2814),(118767,2,3,'n','1',669132,2733),(118768,3,0,'n','1',669132,2721),(118769,3,1,'n','1',669132,2754),(118770,3,2,'n','1',669132,2903),(118771,3,3,'n','1',669132,2782),(118772,4,0,'n','1',669132,2717),(118773,4,1,'n','1',669132,2882),(118774,4,2,'w','1',669132,2858),(118775,4,3,'w','1',669132,2790),(118776,5,0,'e','1',669132,2734),(118777,5,1,'n','1',669132,2738),(118778,5,2,'n','1',669132,2779),(118779,5,3,'n','1',669132,2723),(118780,6,0,'s','1',669132,2741),(118781,6,1,'w','1',669132,2805),(118782,6,2,'w','1',669132,2738),(118783,6,3,'s','1',669132,2806),(118784,7,0,'e','1',669132,2734),(118785,7,1,'w','1',669132,2743),(118786,7,2,'n','1',669132,2738),(118787,7,3,'s','1',669132,2741),(118788,8,0,'w','1',669132,2738),(118789,8,1,'w','1',669132,2921),(118790,8,2,'w','1',669132,2734),(118791,8,3,'w','1',669132,2759),(118792,9,0,'e','1',669132,2749),(118793,9,1,'e','1',669132,2734),(118794,9,2,'w','1',669132,2743),(118795,9,3,'n','1',669132,2738),(118796,10,0,'n','1',669132,2741),(118797,10,1,'s','1',669132,2826),(118798,10,2,'w','1',669132,3004),(118799,10,3,'e','1',669132,3005),(118800,11,0,'s','1',669132,2837),(118801,11,1,'s','1',669132,3004),(118802,11,2,'s','1',669132,2843),(118803,11,3,'s','1',669132,2741),(118804,12,0,'w','1',669132,2729),(118805,12,1,'s','1',669132,2738),(118806,12,2,'s','1',669132,2761),(118807,12,3,'w','1',669132,2842),(118808,13,0,'w','1',669132,2796),(118809,13,1,'w','1',669132,2776),(118810,13,2,'w','1',669132,2794),(118811,13,3,'w','1',669132,2831),(118812,14,0,'n','1',669132,2733),(118813,14,1,'w','1',669132,2734),(118814,14,2,'w','1',669132,2749),(118815,14,3,'s','1',669132,2987),(118816,15,0,'e','1',669132,2750),(118817,15,1,'w','1',669132,2987),(118818,15,2,'n','1',669132,2749),(118819,15,3,'w','1',669132,2820),(118820,16,0,'w','1',669132,2765),(118821,16,1,'e','1',669132,2737),(118822,16,2,'e','1',669132,2768),(118823,16,3,'s','1',669132,2864),(118824,17,0,'s','1',669132,2765),(118825,17,1,'e','1',669132,2749),(118826,17,2,'e','1',669132,2734),(118827,17,3,'n','1',669132,2780),(118828,18,0,'w','1',669132,2738),(118829,18,1,'w','1',669132,2921),(118830,18,2,'s','1',669132,2759),(118831,18,3,'e','1',669132,2734),(118832,19,0,'n','1',669132,2719),(118833,19,1,'n','1',669132,2845),(118834,19,2,'e','1',669132,2900),(118835,19,3,'n','1',669132,2846),(118836,20,0,'w','1',669132,2738),(118837,20,1,'s','1',669132,2734),(118838,20,2,'s','1',669132,2844),(118839,20,3,'n','1',669132,2819),(118840,21,0,'n','1',669132,2733),(118841,21,1,'e','1',669132,2734),(118842,21,2,'e','1',669132,3006),(118843,21,3,'n','1',669132,2783),(118844,22,0,'w','1',669132,2738),(118845,22,1,'s','1',669132,2734),(118846,22,2,'n','1',669132,2848),(118847,22,3,'n','1',669132,2887),(118848,23,0,'e','1',669132,2830),(118849,23,1,'n','1',669132,2793),(118850,23,2,'e','1',669132,2767),(118851,23,3,'n','1',669132,2801),(118852,24,0,'e','1',669132,2769),(118853,24,1,'s','1',669132,2793),(118854,24,2,'s','1',669132,2766),(118855,24,3,'e','1',669132,2942),(118856,25,0,'w','1',669132,2854),(118857,25,1,'e','1',669132,2846),(118858,25,2,'s','1',669132,2931),(118859,25,3,'e','1',669132,2942),(118860,26,0,'w','1',669132,3007),(118861,26,1,'n','1',669132,2859),(118862,26,2,'s','1',669132,2931),(118863,26,3,'s','1',669132,3008),(118864,2,0,'n','1',669133,2867),(118865,2,1,'n','1',669133,2816),(118866,2,2,'n','1',669133,2732),(118867,2,3,'n','1',669133,2749),(118868,3,0,'n','1',669133,2721),(118869,3,1,'n','1',669133,2717),(118870,3,2,'e','1',669133,2719),(118871,3,3,'e','1',669133,2725),(118872,4,0,'n','1',669133,2963),(118873,4,1,'n','1',669133,2888),(118874,4,2,'n','1',669133,2882),(118875,4,3,'e','1',669133,2735),(118876,5,0,'w','1',669133,2765),(118877,5,1,'e','1',669133,2768),(118878,5,2,'s','1',669133,2944),(118879,5,3,'n','1',669133,2739),(118880,6,0,'s','1',669133,2773),(118881,6,1,'w','1',669133,2765),(118882,6,2,'s','1',669133,2774),(118883,6,3,'s','1',669133,2768),(118884,7,0,'e','1',669133,2750),(118885,7,1,'s','1',669133,2948),(118886,7,2,'s','1',669133,2775),(118887,7,3,'e','1',669133,2884),(118888,8,0,'s','1',669133,2749),(118889,8,1,'s','1',669133,2850),(118890,8,2,'w','1',669133,2883),(118891,8,3,'n','1',669133,2739),(118892,9,0,'n','1',669133,2815),(118893,9,1,'s','1',669133,2818),(118894,9,2,'s','1',669133,2781),(118895,10,0,'w','1',669133,2732),(118896,10,1,'w','1',669133,2731),(118897,10,2,'e','1',669133,2884),(118898,10,3,'e','1',669133,2883),(118899,11,0,'n','1',669133,2754),(118900,11,1,'n','1',669133,2780),(118901,11,2,'n','1',669133,2815),(118902,11,3,'w','1',669133,2887),(118903,12,0,'e','1',669133,2851),(118904,12,1,'e','1',669133,2787),(118905,12,2,'s','1',669133,2802),(118906,12,3,'n','1',669133,2875),(118907,13,0,'s','1',669133,2730),(118908,13,1,'s','1',669133,2719),(118909,13,2,'w','1',669133,2727),(118910,13,3,'n','1',669133,2820),(118911,14,0,'n','1',669133,2781),(118912,14,1,'n','1',669133,2818),(118913,14,2,'e','1',669133,2968),(118914,14,3,'n','1',669133,2838),(118915,15,0,'n','1',669133,2849),(118916,15,1,'s','1',669133,2804),(118917,15,2,'s','1',669133,2806),(118918,15,3,'n','1',669133,2803),(118919,16,0,'e','1',669133,2849),(118920,16,1,'s','1',669133,2759),(118921,16,2,'s','1',669133,2916),(118922,16,3,'e','1',669133,2737),(118923,17,0,'w','1',669133,2858),(118924,17,1,'n','1',669133,2839),(118925,17,2,'w','1',669133,2919),(118926,17,3,'s','1',669133,2820),(118927,18,0,'e','1',669133,2877),(118928,18,1,'e','1',669133,2726),(118929,18,2,'s','1',669133,2966),(118930,18,3,'s','1',669133,2727),(118931,19,0,'s','1',669133,2771),(118932,19,1,'w','1',669133,2829),(118933,19,2,'w','1',669133,2772),(118934,19,3,'e','1',669133,2791),(118935,20,0,'e','1',669133,2957),(118936,20,1,'w','1',669133,2913),(118937,20,2,'s','1',669133,2908),(118938,20,3,'w','1',669133,2786),(118939,21,0,'n','1',669133,2789),(118940,21,1,'n','1',669133,2795),(118941,21,2,'s','1',669133,2850),(118942,21,3,'e','1',669133,2883),(118943,22,0,'s','1',669133,2850),(118944,22,1,'e','1',669133,2883),(118945,22,2,'w','1',669133,2903),(118946,22,3,'n','1',669133,2797),(118947,23,0,'s','1',669133,2850),(118948,23,1,'e','1',669133,2883),(118949,23,2,'n','1',669133,2789),(118950,24,0,'s','1',669133,2875),(118951,24,1,'w','1',669133,2754),(118952,24,2,'w','1',669133,2736),(118953,24,3,'x','0',669133,2760),(118954,24,4,'n','1',669133,2868),(118955,25,0,'n','1',669133,2875),(118956,25,1,'e','1',669133,2759),(118957,25,2,'s','1',669133,2849),(118958,25,3,'n','1',669133,2834),(118959,26,0,'n','1',669133,2823),(118960,26,1,'w','1',669133,2745),(118961,26,2,'n','1',669133,2821),(118962,26,3,'e','1',669133,2759),(118963,27,0,'n','1',669133,2957),(118964,27,1,'s','1',669133,2727),(118965,27,2,'s','1',669133,2794),(118966,27,3,'x','0',669133,2778),(118967,27,4,'e','1',669133,2729),(118968,28,0,'s','1',669133,2875),(118969,28,1,'n','1',669133,2905),(118970,28,2,'w','1',669133,2868),(118971,28,3,'e','1',669133,2762),(118972,29,0,'n','1',669133,2947),(118973,29,1,'n','1',669133,2883),(118974,29,2,'n','1',669133,2872),(118975,29,3,'w','1',669133,2784),(118976,30,0,'e','1',669133,2778),(118977,30,1,'s','1',669133,2850),(118978,30,2,'w','1',669133,2901),(118979,30,3,'n','1',669133,2903),(118980,31,0,'w','1',669133,2921),(118981,31,1,'n','1',669133,2759),(118982,31,2,'n','1',669133,2745),(118983,31,3,'n','1',669133,2883),(118984,32,0,'w','1',669133,2905),(118985,32,1,'w','1',669133,2789),(118986,32,2,'e','1',669133,2790),(118987,32,3,'n','1',669133,2797),(118988,33,0,'e','1',669133,2789),(118989,33,1,'n','1',669133,2824),(118990,33,2,'s','1',669133,2850),(118991,33,3,'w','1',669133,2883),(118992,34,0,'w','1',669133,2729),(118993,34,1,'w','1',669133,2905),(118994,34,2,'s','1',669133,2883),(118995,34,3,'n','1',669133,2877),(118996,35,0,'s','1',669133,2806),(118997,35,1,'e','1',669133,2729),(118998,35,2,'s','1',669133,2759),(118999,35,3,'s','1',669133,2737),(119000,2,0,'n','1',669133,2867),(119001,2,1,'n','1',669133,2816),(119002,2,2,'n','1',669133,2732),(119003,2,3,'n','1',669133,2749),(119004,3,0,'n','1',669133,2721),(119005,3,1,'n','1',669133,2717),(119006,3,2,'e','1',669133,2719),(119007,3,3,'e','1',669133,2725),(119008,4,0,'n','1',669133,2963),(119009,4,1,'n','1',669133,2888),(119010,4,2,'n','1',669133,2882),(119011,4,3,'e','1',669133,2735),(119012,5,0,'w','1',669133,2765),(119013,5,1,'e','1',669133,2768),(119014,5,2,'s','1',669133,2944),(119015,5,3,'n','1',669133,2739),(119016,6,0,'s','1',669133,2773),(119017,6,1,'w','1',669133,2765),(119018,6,2,'s','1',669133,2774),(119019,6,3,'s','1',669133,2768),(119020,7,0,'e','1',669133,2750),(119021,7,1,'s','1',669133,2948),(119022,7,2,'s','1',669133,2775),(119023,7,3,'e','1',669133,2884),(119024,8,0,'s','1',669133,2749),(119025,8,1,'s','1',669133,2850),(119026,8,2,'w','1',669133,2883),(119027,8,3,'n','1',669133,2739),(119028,9,0,'n','1',669133,2815),(119029,9,1,'s','1',669133,2818),(119030,9,2,'s','1',669133,2781),(119031,10,0,'w','1',669133,2732),(119032,10,1,'w','1',669133,2731),(119033,10,2,'e','1',669133,2884),(119034,10,3,'e','1',669133,2883),(119035,11,0,'n','1',669133,2754),(119036,11,1,'n','1',669133,2780),(119037,11,2,'n','1',669133,2815),(119038,11,3,'w','1',669133,2887),(119039,12,0,'e','1',669133,2851),(119040,12,1,'e','1',669133,2787),(119041,12,2,'s','1',669133,2802),(119042,12,3,'n','1',669133,2875),(119043,13,0,'s','1',669133,2730),(119044,13,1,'s','1',669133,2719),(119045,13,2,'w','1',669133,2727),(119046,13,3,'n','1',669133,2820),(119047,14,0,'n','1',669133,2781),(119048,14,1,'n','1',669133,2818),(119049,14,2,'e','1',669133,2968),(119050,14,3,'n','1',669133,2838),(119051,15,0,'n','1',669133,2849),(119052,15,1,'s','1',669133,2804),(119053,15,2,'s','1',669133,2806),(119054,15,3,'n','1',669133,2803),(119055,16,0,'e','1',669133,2849),(119056,16,1,'s','1',669133,2759),(119057,16,2,'s','1',669133,2916),(119058,16,3,'e','1',669133,2737),(119059,17,0,'w','1',669133,2858),(119060,17,1,'n','1',669133,2839),(119061,17,2,'w','1',669133,2919),(119062,17,3,'s','1',669133,2820),(119063,18,0,'e','1',669133,2877),(119064,18,1,'e','1',669133,2726),(119065,18,2,'s','1',669133,2966),(119066,18,3,'s','1',669133,2727),(119067,19,0,'s','1',669133,2771),(119068,19,1,'w','1',669133,2829),(119069,19,2,'w','1',669133,2772),(119070,19,3,'e','1',669133,2791),(119071,20,0,'e','1',669133,2957),(119072,20,1,'w','1',669133,2913),(119073,20,2,'s','1',669133,2908),(119074,20,3,'w','1',669133,2786),(119075,21,0,'n','1',669133,2789),(119076,21,1,'n','1',669133,2795),(119077,21,2,'s','1',669133,2850),(119078,21,3,'e','1',669133,2883),(119079,22,0,'s','1',669133,2850),(119080,22,1,'e','1',669133,2883),(119081,22,2,'w','1',669133,2903),(119082,22,3,'n','1',669133,2797),(119083,23,0,'s','1',669133,2850),(119084,23,1,'e','1',669133,2883),(119085,23,2,'n','1',669133,2789),(119086,24,0,'s','1',669133,2875),(119087,24,1,'w','1',669133,2754),(119088,24,2,'w','1',669133,2736),(119089,24,3,'x','0',669133,2760),(119090,24,4,'n','1',669133,2868),(119091,25,0,'n','1',669133,2875),(119092,25,1,'e','1',669133,2759),(119093,25,2,'s','1',669133,2849),(119094,25,3,'n','1',669133,2834),(119095,26,0,'n','1',669133,2823),(119096,26,1,'w','1',669133,2745),(119097,26,2,'n','1',669133,2821),(119098,26,3,'e','1',669133,2759),(119099,27,0,'n','1',669133,2957),(119100,27,1,'s','1',669133,2727),(119101,27,2,'s','1',669133,2794),(119102,27,3,'x','0',669133,2778),(119103,27,4,'e','1',669133,2729),(119104,28,0,'s','1',669133,2875),(119105,28,1,'n','1',669133,2905),(119106,28,2,'w','1',669133,2868),(119107,28,3,'e','1',669133,2762),(119108,29,0,'n','1',669133,2947),(119109,29,1,'n','1',669133,2883),(119110,29,2,'n','1',669133,2872),(119111,29,3,'w','1',669133,2784),(119112,30,0,'e','1',669133,2778),(119113,30,1,'s','1',669133,2850),(119114,30,2,'w','1',669133,2901),(119115,30,3,'n','1',669133,2903),(119116,31,0,'w','1',669133,2921),(119117,31,1,'n','1',669133,2759),(119118,31,2,'n','1',669133,2745),(119119,31,3,'n','1',669133,2883),(119120,32,0,'w','1',669133,2905),(119121,32,1,'w','1',669133,2789),(119122,32,2,'e','1',669133,2790),(119123,32,3,'n','1',669133,2797),(119124,33,0,'e','1',669133,2789),(119125,33,1,'n','1',669133,2824),(119126,33,2,'s','1',669133,2850),(119127,33,3,'w','1',669133,2883),(119128,34,0,'w','1',669133,2729),(119129,34,1,'w','1',669133,2905),(119130,34,2,'s','1',669133,2883),(119131,34,3,'n','1',669133,2877),(119132,35,0,'s','1',669133,2806),(119133,35,1,'e','1',669133,2729),(119134,35,2,'s','1',669133,2759),(119135,35,3,'s','1',669133,2737),(119136,2,0,'n','1',669134,2721),(119137,2,1,'n','1',669134,2810),(119138,2,2,'w','1',669134,2754),(119139,2,3,'n','1',669134,2811),(119140,3,0,'n','1',669134,2815),(119141,3,1,'n','1',669134,3009),(119142,3,2,'n','1',669134,2812),(119143,3,3,'n','1',669134,3010),(119144,4,0,'n','1',669134,3011),(119145,4,1,'w','1',669134,3012),(119146,4,2,'n','1',669134,2736),(119147,4,3,'n','1',669134,2737),(119148,5,0,'w','1',669134,2759),(119149,5,1,'w','1',669134,2741),(119150,5,2,'s','1',669134,2833),(119151,5,3,'w','1',669134,2744),(119152,6,0,'e','1',669134,2756),(119153,6,1,'e','1',669134,2788),(119154,6,2,'s','1',669134,2800),(119155,6,3,'w','1',669134,2759),(119156,7,0,'s','1',669134,2807),(119157,7,1,'s','1',669134,2756),(119158,7,2,'s','1',669134,2959),(119159,7,3,'e','1',669134,2740),(119160,8,0,'w','1',669134,2923),(119161,8,1,'x','0',669134,2803),(119162,8,2,'s','1',669134,2737),(119163,8,3,'s','1',669134,2860),(119164,8,4,'w','1',669134,2765),(119165,9,0,'w','1',669134,2736),(119166,9,1,'w','1',669134,2760),(119167,9,2,'w','1',669134,2986),(119168,9,3,'n','1',669134,3013),(119169,10,0,'e','1',669134,2817),(119170,10,1,'s','1',669134,2792),(119171,10,2,'s','1',669134,2768),(119172,10,3,'w','1',669134,2750),(119173,11,0,'s','1',669134,2792),(119174,11,1,'e','1',669134,2751),(119175,11,2,'w','1',669134,2878),(119176,11,3,'n','1',669134,2981),(119177,12,0,'n','1',669134,2915),(119178,12,1,'n','1',669134,2797),(119179,12,2,'e','1',669134,2750),(119180,12,3,'n','1',669134,2717),(119181,13,0,'e','1',669134,2832),(119182,13,1,'e','1',669134,2749),(119183,13,2,'n','1',669134,2956),(119184,13,3,'n','1',669134,2958),(119185,14,0,'n','1',669134,2791),(119186,14,1,'n','1',669134,2790),(119187,14,2,'e','1',669134,2858),(119188,14,3,'e','1',669134,2790),(119189,15,0,'n','1',669134,2777),(119190,15,1,'e','1',669134,2772),(119191,15,2,'n','1',669134,2904),(119192,15,3,'e','1',669134,2776),(119193,16,0,'n','1',669134,2908),(119194,16,1,'n','1',669134,2791),(119195,16,2,'w','1',669134,2789),(119196,16,3,'e','1',669134,2719),(119197,17,0,'e','1',669134,2802),(119198,17,1,'s','1',669134,2734),(119199,17,2,'n','1',669134,2725),(119200,17,3,'n','1',669134,2855),(119201,18,0,'w','1',669134,2803),(119202,18,1,'s','1',669134,2733),(119203,18,2,'e','1',669134,2814),(119204,18,3,'n','1',669134,2778),(119205,19,0,'w','1',669134,2854),(119206,19,1,'e','1',669134,2755),(119207,19,2,'n','1',669134,2796),(119208,19,3,'n','1',669134,2798),(119209,20,0,'e','1',669134,3014),(119210,20,1,'n','1',669134,2909),(119211,20,2,'w','1',669134,2846),(119212,20,3,'n','1',669134,2929),(119213,21,0,'w','1',669134,2813),(119214,21,1,'n','1',669134,2728),(119215,21,2,'n','1',669134,2814),(119216,21,3,'w','1',669134,2736),(119217,21,4,'x','0',669134,2760),(119218,22,0,'w','1',669134,2733),(119219,22,1,'w','1',669134,2959),(119220,22,2,'s','1',669134,2802),(119221,22,3,'x','0',669134,2803),(119222,22,4,'s','1',669134,2756),(119223,23,0,'n','1',669134,2740),(119224,23,1,'e','1',669134,2756),(119225,23,2,'e','1',669134,2825),(119226,23,3,'n','1',669134,2759),(119227,24,0,'n','1',669134,2732),(119228,24,1,'e','1',669134,2749),(119229,24,2,'w','1',669134,2734),(119230,24,3,'s','1',669134,2844),(119231,25,0,'e','1',669134,2749),(119232,25,1,'s','1',669134,2804),(119233,25,2,'e','1',669134,2734),(119234,25,3,'n','1',669134,2956),(119235,26,0,'n','1',669134,2791),(119236,26,1,'n','1',669134,2777),(119237,26,2,'n','1',669134,2776),(119238,26,3,'n','1',669134,2774),(119239,2,0,'n','1',669134,2721),(119240,2,1,'n','1',669134,2810),(119241,2,2,'w','1',669134,2754),(119242,2,3,'n','1',669134,2811),(119243,3,0,'n','1',669134,2815),(119244,3,1,'n','1',669134,3009),(119245,3,2,'n','1',669134,2812),(119246,3,3,'n','1',669134,3010),(119247,4,0,'n','1',669134,3011),(119248,4,1,'w','1',669134,3012),(119249,4,2,'n','1',669134,2736),(119250,4,3,'n','1',669134,2737),(119251,5,0,'w','1',669134,2759),(119252,5,1,'w','1',669134,2741),(119253,5,2,'s','1',669134,2833),(119254,5,3,'w','1',669134,2744),(119255,6,0,'e','1',669134,2756),(119256,6,1,'e','1',669134,2788),(119257,6,2,'s','1',669134,2800),(119258,6,3,'w','1',669134,2759),(119259,7,0,'s','1',669134,2807),(119260,7,1,'s','1',669134,2756),(119261,7,2,'s','1',669134,2959),(119262,7,3,'e','1',669134,2740),(119263,8,0,'w','1',669134,2923),(119264,8,1,'x','0',669134,2803),(119265,8,2,'s','1',669134,2737),(119266,8,3,'s','1',669134,2860),(119267,8,4,'w','1',669134,2765),(119268,9,0,'w','1',669134,2736),(119269,9,1,'w','1',669134,2760),(119270,9,2,'w','1',669134,2986),(119271,9,3,'n','1',669134,3013),(119272,10,0,'e','1',669134,2817),(119273,10,1,'s','1',669134,2792),(119274,10,2,'s','1',669134,2768),(119275,10,3,'w','1',669134,2750),(119276,11,0,'s','1',669134,2792),(119277,11,1,'e','1',669134,2751),(119278,11,2,'w','1',669134,2878),(119279,11,3,'n','1',669134,2981),(119280,12,0,'n','1',669134,2915),(119281,12,1,'n','1',669134,2797),(119282,12,2,'e','1',669134,2750),(119283,12,3,'n','1',669134,2717),(119284,13,0,'e','1',669134,2832),(119285,13,1,'e','1',669134,2749),(119286,13,2,'n','1',669134,2956),(119287,13,3,'n','1',669134,2958),(119288,14,0,'n','1',669134,2791),(119289,14,1,'n','1',669134,2790),(119290,14,2,'e','1',669134,2858),(119291,14,3,'e','1',669134,2790),(119292,15,0,'n','1',669134,2777),(119293,15,1,'e','1',669134,2772),(119294,15,2,'n','1',669134,2904),(119295,15,3,'e','1',669134,2776),(119296,16,0,'n','1',669134,2908),(119297,16,1,'n','1',669134,2791),(119298,16,2,'w','1',669134,2789),(119299,16,3,'e','1',669134,2719),(119300,17,0,'e','1',669134,2802),(119301,17,1,'s','1',669134,2734),(119302,17,2,'n','1',669134,2725),(119303,17,3,'n','1',669134,2855),(119304,18,0,'w','1',669134,2803),(119305,18,1,'s','1',669134,2733),(119306,18,2,'e','1',669134,2814),(119307,18,3,'n','1',669134,2778),(119308,19,0,'w','1',669134,2854),(119309,19,1,'e','1',669134,2755),(119310,19,2,'n','1',669134,2796),(119311,19,3,'n','1',669134,2798),(119312,20,0,'e','1',669134,3014),(119313,20,1,'n','1',669134,2909),(119314,20,2,'w','1',669134,2846),(119315,20,3,'n','1',669134,2929),(119316,21,0,'w','1',669134,2813),(119317,21,1,'n','1',669134,2728),(119318,21,2,'n','1',669134,2814),(119319,21,3,'w','1',669134,2736),(119320,21,4,'x','0',669134,2760),(119321,22,0,'w','1',669134,2733),(119322,22,1,'w','1',669134,2959),(119323,22,2,'s','1',669134,2802),(119324,22,3,'x','0',669134,2803),(119325,22,4,'s','1',669134,2756),(119326,23,0,'n','1',669134,2740),(119327,23,1,'e','1',669134,2756),(119328,23,2,'e','1',669134,2825),(119329,23,3,'n','1',669134,2759),(119330,24,0,'n','1',669134,2732),(119331,24,1,'e','1',669134,2749),(119332,24,2,'w','1',669134,2734),(119333,24,3,'s','1',669134,2844),(119334,25,0,'e','1',669134,2749),(119335,25,1,'s','1',669134,2804),(119336,25,2,'e','1',669134,2734),(119337,25,3,'n','1',669134,2956),(119338,26,0,'n','1',669134,2791),(119339,26,1,'n','1',669134,2777),(119340,26,2,'n','1',669134,2776),(119341,26,3,'n','1',669134,2774),(119342,2,0,'n','1',669135,2867),(119343,2,1,'n','1',669135,2816),(119344,2,2,'n','1',669135,2732),(119345,2,3,'n','1',669135,2749),(119346,3,0,'n','1',669135,2717),(119347,3,1,'e','1',669135,2719),(119348,3,2,'e','1',669135,2725),(119349,3,3,'e','1',669135,2735),(119350,4,0,'w','1',669135,2765),(119351,4,1,'e','1',669135,2768),(119352,4,2,'s','1',669135,2944),(119353,4,3,'n','1',669135,2721),(119354,5,0,'n','1',669135,2963),(119355,5,1,'e','1',669135,2884),(119356,5,2,'e','1',669135,2883),(119357,5,3,'s','1',669135,2765),(119358,6,0,'e','1',669135,2838),(119359,6,1,'s','1',669135,2875),(119360,6,2,'e','1',669135,2815),(119361,6,3,'n','1',669135,2964),(119362,7,0,'e','1',669135,2749),(119363,7,1,'n','1',669135,2882),(119364,7,2,'e','1',669135,2872),(119365,7,3,'n','1',669135,2915),(119366,8,0,'s','1',669135,2740),(119367,8,1,'e','1',669135,2760),(119368,8,2,'e','1',669135,2736),(119369,8,3,'w','1',669135,2734),(119370,9,0,'e','1',669135,2803),(119371,9,1,'w','1',669135,2749),(119372,10,0,'n','1',669135,2754),(119373,10,1,'s','1',669135,2959),(119374,10,2,'e','1',669135,2923),(119375,10,3,'n','1',669135,2868),(119376,11,0,'w','1',669135,3015),(119377,11,1,'s','1',669135,2922),(119378,11,2,'w','1',669135,2875),(119379,11,3,'e','1',669135,2750),(119380,12,0,'e','1',669135,2749),(119381,12,1,'w','1',669135,2883),(119382,12,2,'e','1',669135,2772),(119383,12,3,'n','1',669135,2927),(119384,13,0,'s','1',669135,2759),(119385,13,1,'w','1',669135,2734),(119386,13,2,'s','1',669135,2948),(119387,13,3,'e','1',669135,2749),(119388,14,0,'w','1',669135,2734),(119389,14,1,'s','1',669135,2948),(119390,14,2,'e','1',669135,2884),(119391,14,3,'e','1',669135,2883),(119392,15,0,'e','1',669135,2749),(119393,15,1,'w','1',669135,2875),(119394,15,2,'w','1',669135,2858),(119395,15,3,'w','1',669135,2903),(119396,16,0,'n','1',669135,2908),(119397,16,1,'e','1',669135,2770),(119398,16,2,'n','1',669135,2746),(119399,16,3,'n','1',669135,2755),(119400,17,0,'n','1',669135,2734),(119401,17,1,'s','1',669135,2744),(119402,17,2,'w','1',669135,2806),(119403,17,3,'n','1',669135,2759),(119404,18,0,'e','1',669135,2734),(119405,18,1,'s','1',669135,2807),(119406,18,2,'s','1',669135,2756),(119407,18,3,'w','1',669135,2738),(119408,19,0,'w','1',669135,2883),(119409,19,1,'s','1',669135,2740),(119410,19,2,'x','0',669135,2760),(119411,19,3,'w','1',669135,2884),(119412,19,4,'w','1',669135,2739),(119413,20,0,'n','1',669135,2734),(119414,20,1,'s','1',669135,2744),(119415,20,2,'s','1',669135,2826),(119416,20,3,'n','1',669135,2790),(119417,21,0,'n','1',669135,2735),(119418,21,1,'n','1',669135,2794),(119419,21,2,'w','1',669135,2954),(119420,21,3,'n','1',669135,2838),(119421,22,0,'n','1',669135,2887),(119422,22,1,'n','1',669135,2806),(119423,22,2,'w','1',669135,2826),(119424,22,3,'x','0',669135,2757),(119425,22,4,'w','1',669135,2926),(119426,23,0,'s','1',669135,2909),(119427,23,1,'n','1',669135,2905),(119428,23,2,'n','1',669135,2762),(119429,23,3,'w','1',669135,2734),(119430,24,0,'e','1',669135,3016),(119431,24,1,'n','1',669135,2761),(119432,24,2,'n','1',669135,2758),(119433,24,3,'n','1',669135,2749),(119434,2,0,'n','1',669135,2867),(119435,2,1,'n','1',669135,2816),(119436,2,2,'n','1',669135,2732),(119437,2,3,'n','1',669135,2749),(119438,3,0,'n','1',669135,2717),(119439,3,1,'e','1',669135,2719),(119440,3,2,'e','1',669135,2725),(119441,3,3,'e','1',669135,2735),(119442,4,0,'w','1',669135,2765),(119443,4,1,'e','1',669135,2768),(119444,4,2,'s','1',669135,2944),(119445,4,3,'n','1',669135,2721),(119446,5,0,'n','1',669135,2963),(119447,5,1,'e','1',669135,2884),(119448,5,2,'e','1',669135,2883),(119449,5,3,'s','1',669135,2765),(119450,6,0,'e','1',669135,2838),(119451,6,1,'s','1',669135,2875),(119452,6,2,'e','1',669135,2815),(119453,6,3,'n','1',669135,2964),(119454,7,0,'e','1',669135,2749),(119455,7,1,'n','1',669135,2882),(119456,7,2,'e','1',669135,2872),(119457,7,3,'n','1',669135,2915),(119458,8,0,'s','1',669135,2740),(119459,8,1,'e','1',669135,2760),(119460,8,2,'e','1',669135,2736),(119461,8,3,'w','1',669135,2734),(119462,9,0,'e','1',669135,2803),(119463,9,1,'w','1',669135,2749),(119464,10,0,'n','1',669135,2754),(119465,10,1,'s','1',669135,2959),(119466,10,2,'e','1',669135,2923),(119467,10,3,'n','1',669135,2868),(119468,11,0,'w','1',669135,3015),(119469,11,1,'s','1',669135,2922),(119470,11,2,'w','1',669135,2875),(119471,11,3,'e','1',669135,2750),(119472,12,0,'e','1',669135,2749),(119473,12,1,'w','1',669135,2883),(119474,12,2,'e','1',669135,2772),(119475,12,3,'n','1',669135,2927),(119476,13,0,'s','1',669135,2759),(119477,13,1,'w','1',669135,2734),(119478,13,2,'s','1',669135,2948),(119479,13,3,'e','1',669135,2749),(119480,14,0,'w','1',669135,2734),(119481,14,1,'s','1',669135,2948),(119482,14,2,'e','1',669135,2884),(119483,14,3,'e','1',669135,2883),(119484,15,0,'e','1',669135,2749),(119485,15,1,'w','1',669135,2875),(119486,15,2,'w','1',669135,2858),(119487,15,3,'w','1',669135,2903),(119488,16,0,'n','1',669135,2908),(119489,16,1,'e','1',669135,2770),(119490,16,2,'n','1',669135,2746),(119491,16,3,'n','1',669135,2755),(119492,17,0,'n','1',669135,2734),(119493,17,1,'s','1',669135,2744),(119494,17,2,'w','1',669135,2806),(119495,17,3,'n','1',669135,2759),(119496,18,0,'e','1',669135,2734),(119497,18,1,'s','1',669135,2807),(119498,18,2,'s','1',669135,2756),(119499,18,3,'w','1',669135,2738),(119500,19,0,'w','1',669135,2883),(119501,19,1,'s','1',669135,2740),(119502,19,2,'x','0',669135,2760),(119503,19,3,'w','1',669135,2884),(119504,19,4,'w','1',669135,2739),(119505,20,0,'n','1',669135,2734),(119506,20,1,'s','1',669135,2744),(119507,20,2,'s','1',669135,2826),(119508,20,3,'n','1',669135,2790),(119509,21,0,'n','1',669135,2735),(119510,21,1,'n','1',669135,2794),(119511,21,2,'w','1',669135,2954),(119512,21,3,'n','1',669135,2838),(119513,22,0,'n','1',669135,2887),(119514,22,1,'n','1',669135,2806),(119515,22,2,'w','1',669135,2826),(119516,22,3,'x','0',669135,2757),(119517,22,4,'w','1',669135,2926),(119518,23,0,'s','1',669135,2909),(119519,23,1,'n','1',669135,2905),(119520,23,2,'n','1',669135,2762),(119521,23,3,'w','1',669135,2734),(119522,24,0,'e','1',669135,3016),(119523,24,1,'n','1',669135,2761),(119524,24,2,'n','1',669135,2758),(119525,24,3,'n','1',669135,2749),(119526,2,0,'n','1',669136,2868),(119527,2,1,'n','1',669136,2721),(119528,2,2,'n','1',669136,2810),(119529,2,3,'w','1',669136,2811),(119530,3,0,'n','1',669136,2754),(119531,3,1,'e','1',669136,2875),(119532,3,2,'n','1',669136,2992),(119533,3,3,'n','1',669136,2956),(119534,4,0,'n','1',669136,2813),(119535,4,1,'w','1',669136,2842),(119536,4,2,'n','1',669136,2733),(119537,4,3,'n','1',669136,2958),(119538,5,0,'w','1',669136,2734),(119539,5,1,'w','1',669136,2749),(119540,5,2,'w','1',669136,2750),(119541,5,3,'w','1',669136,2751),(119542,6,0,'n','1',669136,2964),(119543,6,1,'e','1',669136,2871),(119544,6,2,'e','1',669136,2751),(119545,6,3,'s','1',669136,2766),(119546,7,0,'w','1',669136,2750),(119547,7,1,'e','1',669136,2751),(119548,7,2,'s','1',669136,2766),(119549,7,3,'n','1',669136,2724),(119550,8,0,'w','1',669136,2750),(119551,8,1,'e','1',669136,2751),(119552,8,2,'s','1',669136,2766),(119553,8,3,'n','1',669136,2820),(119554,9,0,'w','1',669136,2750),(119555,9,1,'s','1',669136,2751),(119556,9,2,'s','1',669136,2859),(119557,9,3,'w','1',669136,2730),(119558,10,0,'e','1',669136,2873),(119559,10,1,'s','1',669136,2846),(119560,10,2,'n','1',669136,2921),(119561,10,3,'n','1',669136,2919),(119562,11,0,'n','1',669136,2916),(119563,11,1,'w','1',669136,2917),(119564,11,2,'s','1',669136,2804),(119565,11,3,'s','1',669136,2806),(119566,12,0,'w','1',669136,2730),(119567,12,1,'e','1',669136,2849),(119568,12,2,'s','1',669136,2759),(119569,12,3,'s','1',669136,2873),(119570,13,0,'e','1',669136,2726),(119571,13,1,'e','1',669136,2818),(119572,13,2,'n','1',669136,2727),(119573,13,3,'e','1',669136,2872),(119574,13,4,'x','0',669136,2772),(119575,14,0,'n','1',669136,2779),(119576,14,1,'n','1',669136,2780),(119577,14,2,'s','1',669136,2930),(119578,14,3,'e','1',669136,2981),(119579,2,0,'n','1',669136,2868),(119580,2,1,'n','1',669136,2721),(119581,2,2,'n','1',669136,2810),(119582,2,3,'w','1',669136,2811),(119583,3,0,'n','1',669136,2754),(119584,3,1,'e','1',669136,2875),(119585,3,2,'n','1',669136,2992),(119586,3,3,'n','1',669136,2956),(119587,4,0,'n','1',669136,2813),(119588,4,1,'w','1',669136,2842),(119589,4,2,'n','1',669136,2733),(119590,4,3,'n','1',669136,2958),(119591,5,0,'w','1',669136,2734),(119592,5,1,'w','1',669136,2749),(119593,5,2,'w','1',669136,2750),(119594,5,3,'w','1',669136,2751),(119595,6,0,'n','1',669136,2964),(119596,6,1,'e','1',669136,2871),(119597,6,2,'e','1',669136,2751),(119598,6,3,'s','1',669136,2766),(119599,7,0,'w','1',669136,2750),(119600,7,1,'e','1',669136,2751),(119601,7,2,'s','1',669136,2766),(119602,7,3,'n','1',669136,2724),(119603,8,0,'w','1',669136,2750),(119604,8,1,'e','1',669136,2751),(119605,8,2,'s','1',669136,2766),(119606,8,3,'n','1',669136,2820),(119607,9,0,'w','1',669136,2750),(119608,9,1,'s','1',669136,2751),(119609,9,2,'s','1',669136,2859),(119610,9,3,'w','1',669136,2730),(119611,10,0,'e','1',669136,2873),(119612,10,1,'s','1',669136,2846),(119613,10,2,'n','1',669136,2921),(119614,10,3,'n','1',669136,2919),(119615,11,0,'n','1',669136,2916),(119616,11,1,'w','1',669136,2917),(119617,11,2,'s','1',669136,2804),(119618,11,3,'s','1',669136,2806),(119619,12,0,'w','1',669136,2730),(119620,12,1,'e','1',669136,2849),(119621,12,2,'s','1',669136,2759),(119622,12,3,'s','1',669136,2873),(119623,13,0,'e','1',669136,2726),(119624,13,1,'e','1',669136,2818),(119625,13,2,'n','1',669136,2727),(119626,13,3,'e','1',669136,2872),(119627,13,4,'x','0',669136,2772),(119628,14,0,'n','1',669136,2779),(119629,14,1,'n','1',669136,2780),(119630,14,2,'s','1',669136,2930),(119631,14,3,'e','1',669136,2981),(119632,2,0,'n','1',669137,2867),(119633,2,1,'n','1',669137,2816),(119634,2,2,'n','1',669137,2732),(119635,2,3,'n','1',669137,2717),(119636,3,0,'n','1',669137,2749),(119637,3,1,'w','1',669137,2765),(119638,3,2,'e','1',669137,2768),(119639,3,3,'s','1',669137,2944),(119640,4,0,'n','1',669137,2721),(119641,4,1,'n','1',669137,2888),(119642,4,2,'s','1',669137,2765),(119643,4,3,'s','1',669137,2749),(119644,5,0,'e','1',669137,2732),(119645,5,1,'e','1',669137,2733),(119646,5,2,'w','1',669137,2842),(119647,5,3,'n','1',669137,2736),(119648,6,0,'e','1',669137,2733),(119649,6,1,'w','1',669137,2842),(119650,6,2,'n','1',669137,2736),(119651,6,3,'w','1',669137,2754),(119652,7,0,'n','1',669137,2733),(119653,7,1,'w','1',669137,2734),(119654,7,2,'w','1',669137,2960),(119655,7,3,'n','1',669137,2903),(119656,8,0,'s','1',669137,2800),(119657,8,1,'e','1',669137,2749),(119658,8,2,'s','1',669137,2802),(119659,8,3,'s','1',669137,2734),(119660,9,0,'e','1',669137,2963),(119661,9,1,'w','1',669137,2736),(119662,9,2,'e','1',669137,2760),(119663,9,3,'n','1',669137,2973),(119664,10,0,'e','1',669137,2719),(119665,10,1,'e','1',669137,2725),(119666,10,2,'e','1',669137,2735),(119667,10,3,'n','1',669137,2739),(119668,11,0,'n','1',669137,2948),(119669,11,1,'e','1',669137,2747),(119670,11,2,'e','1',669137,2832),(119671,11,3,'e','1',669137,2815),(119672,12,0,'e','1',669137,2775),(119673,12,1,'n','1',669137,2964),(119674,12,2,'n','1',669137,2882),(119675,12,3,'n','1',669137,2733),(119676,13,0,'n','1',669137,2820),(119677,13,1,'n','1',669137,2921),(119678,13,2,'w','1',669137,2805),(119679,13,3,'e','1',669137,2804),(119680,14,0,'n','1',669137,2734),(119681,14,1,'n','1',669137,2970),(119682,14,2,'w','1',669137,2744),(119683,14,3,'w','1',669137,2971),(119684,15,0,'e','1',669137,2765),(119685,15,1,'w','1',669137,2744),(119686,15,2,'s','1',669137,2826),(119687,15,3,'x','0',669137,2757),(119688,15,4,'w','1',669137,2789),(119689,16,0,'s','1',669137,2765),(119690,16,1,'s','1',669137,2936),(119691,16,2,'e','1',669137,2970),(119692,16,3,'x','0',669137,2807),(119693,16,4,'n','1',669137,2749),(119694,17,0,'e','1',669137,2791),(119695,17,1,'n','1',669137,2789),(119696,17,2,'n','1',669137,2963),(119697,17,3,'n','1',669137,2795),(119698,18,0,'s','1',669137,2765),(119699,18,1,'e','1',669137,2773),(119700,18,2,'e','1',669137,2852),(119701,18,3,'x','0',669137,2757),(119702,18,4,'n','1',669137,2749),(119703,19,0,'s','1',669137,2765),(119704,19,1,'s','1',669137,2749),(119705,19,2,'n','1',669137,2776),(119706,19,3,'e','1',669137,2774),(119707,20,0,'w','1',669137,2732),(119708,20,1,'e','1',669137,2908),(119709,20,2,'s','1',669137,2731),(119710,20,3,'s','1',669137,2917),(119711,21,0,'s','1',669137,2874),(119712,21,1,'n','1',669137,2945),(119713,21,2,'x','0',669137,2725),(119714,21,3,'w','1',669137,2913),(119715,21,4,'e','1',669137,2957),(119716,22,0,'n','1',669137,2913),(119717,22,1,'n','1',669137,2874),(119718,22,2,'w','1',669137,2986),(119719,22,3,'n','1',669137,2790),(119720,23,0,'s','1',669137,2731),(119721,23,1,'e','1',669137,2798),(119722,23,2,'e','1',669137,2758),(119723,23,3,'n','1',669137,2843),(119724,24,0,'n','1',669137,2874),(119725,24,1,'n','1',669137,2965),(119726,24,2,'w','1',669137,2908),(119727,24,3,'x','0',669137,2772),(119728,24,4,'s','1',669137,2731),(119729,25,0,'e','1',669137,2874),(119730,25,1,'s','1',669137,2816),(119731,25,2,'n','1',669137,2837),(119732,25,3,'e','1',669137,2790),(119733,26,0,'e','1',669137,2797),(119734,26,1,'e','1',669137,2858),(119735,26,2,'n','1',669137,2887),(119736,26,3,'n','1',669137,2927),(119737,27,0,'s','1',669137,2867),(119738,27,1,'e','1',669137,3017),(119739,27,2,'w','1',669137,2905),(119740,27,3,'n','1',669137,3018),(119741,28,0,'w','1',669137,2789),(119742,28,1,'w','1',669137,2791),(119743,28,2,'n','1',669137,2790),(119744,28,3,'n','1',669137,2791),(119745,29,0,'n','1',669137,2834),(119746,29,1,'e','1',669137,2817),(119747,29,2,'e','1',669137,3003),(119748,29,3,'n','1',669137,2779),(119749,30,0,'w','1',669137,2992),(119750,30,1,'s','1',669137,2923),(119751,30,2,'s','1',669137,2958),(119752,30,3,'e','1',669137,3003),(119753,31,0,'e','1',669137,2909),(119754,31,1,'e','1',669137,2950),(119755,31,2,'n','1',669137,2990),(119756,31,3,'n','1',669137,2906),(119757,32,0,'w','1',669137,2902),(119758,32,1,'n','1',669137,2907),(119759,32,2,'e','1',669137,2911),(119760,32,3,'n','1',669137,2935),(119761,33,0,'w','1',669137,2998),(119762,33,1,'s','1',669137,2767),(119763,33,2,'x','0',669137,2859),(119764,33,3,'w','1',669137,3019),(119765,33,4,'e','1',669137,2853),(119766,34,0,'s','1',669137,3019),(119767,34,1,'s','1',669137,2911),(119768,34,2,'s','1',669137,2907),(119769,34,3,'s','1',669137,2906),(119770,35,0,'n','1',669137,2822),(119771,35,1,'n','1',669137,2823),(119772,35,2,'n','1',669137,2745),(119773,35,3,'n','1',669137,2821),(119774,36,0,'w','1',669137,2992),(119775,36,1,'w','1',669137,2834),(119776,36,2,'n','1',669137,2817),(119777,36,3,'e','1',669137,3003),(119778,37,0,'w','1',669137,2992),(119779,37,1,'w','1',669137,3003),(119780,37,2,'n','1',669137,2791),(119781,37,3,'w','1',669137,2867),(119782,2,0,'n','1',669137,2867),(119783,2,1,'n','1',669137,2816),(119784,2,2,'n','1',669137,2732),(119785,2,3,'n','1',669137,2717),(119786,3,0,'n','1',669137,2749),(119787,3,1,'w','1',669137,2765),(119788,3,2,'e','1',669137,2768),(119789,3,3,'s','1',669137,2944),(119790,4,0,'n','1',669137,2721),(119791,4,1,'n','1',669137,2888),(119792,4,2,'s','1',669137,2765),(119793,4,3,'s','1',669137,2749),(119794,5,0,'e','1',669137,2732),(119795,5,1,'e','1',669137,2733),(119796,5,2,'w','1',669137,2842),(119797,5,3,'n','1',669137,2736),(119798,6,0,'e','1',669137,2733),(119799,6,1,'w','1',669137,2842),(119800,6,2,'n','1',669137,2736),(119801,6,3,'w','1',669137,2754),(119802,7,0,'n','1',669137,2733),(119803,7,1,'w','1',669137,2734),(119804,7,2,'w','1',669137,2960),(119805,7,3,'n','1',669137,2903),(119806,8,0,'s','1',669137,2800),(119807,8,1,'e','1',669137,2749),(119808,8,2,'s','1',669137,2802),(119809,8,3,'s','1',669137,2734),(119810,9,0,'e','1',669137,2963),(119811,9,1,'w','1',669137,2736),(119812,9,2,'e','1',669137,2760),(119813,9,3,'n','1',669137,2973),(119814,10,0,'e','1',669137,2719),(119815,10,1,'e','1',669137,2725),(119816,10,2,'e','1',669137,2735),(119817,10,3,'n','1',669137,2739),(119818,11,0,'n','1',669137,2948),(119819,11,1,'e','1',669137,2747),(119820,11,2,'e','1',669137,2832),(119821,11,3,'e','1',669137,2815),(119822,12,0,'e','1',669137,2775),(119823,12,1,'n','1',669137,2964),(119824,12,2,'n','1',669137,2882),(119825,12,3,'n','1',669137,2733),(119826,13,0,'n','1',669137,2820),(119827,13,1,'n','1',669137,2921),(119828,13,2,'w','1',669137,2805),(119829,13,3,'e','1',669137,2804),(119830,14,0,'n','1',669137,2734),(119831,14,1,'n','1',669137,2970),(119832,14,2,'w','1',669137,2744),(119833,14,3,'w','1',669137,2971),(119834,15,0,'e','1',669137,2765),(119835,15,1,'w','1',669137,2744),(119836,15,2,'s','1',669137,2826),(119837,15,3,'x','0',669137,2757),(119838,15,4,'w','1',669137,2789),(119839,16,0,'s','1',669137,2765),(119840,16,1,'s','1',669137,2936),(119841,16,2,'e','1',669137,2970),(119842,16,3,'x','0',669137,2807),(119843,16,4,'n','1',669137,2749),(119844,17,0,'e','1',669137,2791),(119845,17,1,'n','1',669137,2789),(119846,17,2,'n','1',669137,2963),(119847,17,3,'n','1',669137,2795),(119848,18,0,'s','1',669137,2765),(119849,18,1,'e','1',669137,2773),(119850,18,2,'e','1',669137,2852),(119851,18,3,'x','0',669137,2757),(119852,18,4,'n','1',669137,2749),(119853,19,0,'s','1',669137,2765),(119854,19,1,'s','1',669137,2749),(119855,19,2,'n','1',669137,2776),(119856,19,3,'e','1',669137,2774),(119857,20,0,'w','1',669137,2732),(119858,20,1,'e','1',669137,2908),(119859,20,2,'s','1',669137,2731),(119860,20,3,'s','1',669137,2917),(119861,21,0,'s','1',669137,2874),(119862,21,1,'n','1',669137,2945),(119863,21,2,'x','0',669137,2725),(119864,21,3,'w','1',669137,2913),(119865,21,4,'e','1',669137,2957),(119866,22,0,'n','1',669137,2913),(119867,22,1,'n','1',669137,2874),(119868,22,2,'w','1',669137,2986),(119869,22,3,'n','1',669137,2790),(119870,23,0,'s','1',669137,2731),(119871,23,1,'e','1',669137,2798),(119872,23,2,'e','1',669137,2758),(119873,23,3,'n','1',669137,2843),(119874,24,0,'n','1',669137,2874),(119875,24,1,'n','1',669137,2965),(119876,24,2,'w','1',669137,2908),(119877,24,3,'x','0',669137,2772),(119878,24,4,'s','1',669137,2731),(119879,25,0,'e','1',669137,2874),(119880,25,1,'s','1',669137,2816),(119881,25,2,'n','1',669137,2837),(119882,25,3,'e','1',669137,2790),(119883,26,0,'e','1',669137,2797),(119884,26,1,'e','1',669137,2858),(119885,26,2,'n','1',669137,2887),(119886,26,3,'n','1',669137,2927),(119887,27,0,'s','1',669137,2867),(119888,27,1,'e','1',669137,3017),(119889,27,2,'w','1',669137,2905),(119890,27,3,'n','1',669137,3018),(119891,28,0,'w','1',669137,2789),(119892,28,1,'w','1',669137,2791),(119893,28,2,'n','1',669137,2790),(119894,28,3,'n','1',669137,2791),(119895,29,0,'n','1',669137,2834),(119896,29,1,'e','1',669137,2817),(119897,29,2,'e','1',669137,3003),(119898,29,3,'n','1',669137,2779),(119899,30,0,'w','1',669137,2992),(119900,30,1,'s','1',669137,2923),(119901,30,2,'s','1',669137,2958),(119902,30,3,'e','1',669137,3003),(119903,31,0,'e','1',669137,2909),(119904,31,1,'e','1',669137,2950),(119905,31,2,'n','1',669137,2990),(119906,31,3,'n','1',669137,2906),(119907,32,0,'w','1',669137,2902),(119908,32,1,'n','1',669137,2907),(119909,32,2,'e','1',669137,2911),(119910,32,3,'n','1',669137,2935),(119911,33,0,'w','1',669137,2998),(119912,33,1,'s','1',669137,2767),(119913,33,2,'x','0',669137,2859),(119914,33,3,'w','1',669137,3019),(119915,33,4,'e','1',669137,2853),(119916,34,0,'s','1',669137,3019),(119917,34,1,'s','1',669137,2911),(119918,34,2,'s','1',669137,2907),(119919,34,3,'s','1',669137,2906),(119920,35,0,'n','1',669137,2822),(119921,35,1,'n','1',669137,2823),(119922,35,2,'n','1',669137,2745),(119923,35,3,'n','1',669137,2821),(119924,36,0,'w','1',669137,2992),(119925,36,1,'w','1',669137,2834),(119926,36,2,'n','1',669137,2817),(119927,36,3,'e','1',669137,3003),(119928,37,0,'w','1',669137,2992),(119929,37,1,'w','1',669137,3003),(119930,37,2,'n','1',669137,2791),(119931,37,3,'w','1',669137,2867),(119932,2,0,'n','1',669138,2728),(119933,2,1,'n','1',669138,3003),(119934,2,2,'n','1',669138,2814),(119935,2,3,'n','1',669138,2733),(119936,3,0,'n','1',669138,2903),(119937,3,1,'n','1',669138,2815),(119938,3,2,'n','1',669138,2723),(119939,3,3,'n','1',669138,2782),(119940,4,0,'e','1',669138,2736),(119941,4,1,'n','1',669138,2754),(119942,4,2,'n','1',669138,2820),(119943,4,3,'n','1',669138,2838),(119944,5,0,'w','1',669138,2921),(119945,5,1,'n','1',669138,2759),(119946,5,2,'e','1',669138,2828),(119947,5,3,'e','1',669138,2795),(119948,6,0,'w','1',669138,2734),(119949,6,1,'n','1',669138,2749),(119950,6,2,'n','1',669138,2762),(119951,6,3,'n','1',669138,2761),(119952,7,0,'w','1',669138,2765),(119953,7,1,'s','1',669138,2863),(119954,7,2,'s','1',669138,2833),(119955,7,3,'e','1',669138,2768),(119956,8,0,'w','1',669138,2765),(119957,8,1,'s','1',669138,2863),(119958,8,2,'s','1',669138,2833),(119959,8,3,'e','1',669138,2768),(119960,9,0,'w','1',669138,2765),(119961,9,1,'s','1',669138,2863),(119962,9,2,'s','1',669138,2833),(119963,9,3,'e','1',669138,2768),(119964,10,0,'w','1',669138,2839),(119965,10,1,'e','1',669138,2761),(119966,10,2,'e','1',669138,2934),(119967,10,3,'e','1',669138,2759),(119968,11,0,'n','1',669138,2921),(119969,11,1,'s','1',669138,2805),(119970,11,2,'s','1',669138,2984),(119971,11,3,'n','1',669138,2870),(119972,12,0,'s','1',669138,2921),(119973,12,1,'s','1',669138,2985),(119974,12,2,'s','1',669138,2820),(119975,12,3,'s','1',669138,2821),(119976,13,0,'w','1',669138,2745),(119977,13,1,'n','1',669138,2754),(119978,13,2,'w','1',669138,2729),(119979,13,3,'w','1',669138,2820),(119980,14,0,'s','1',669138,2765),(119981,14,1,'x','0',669138,2757),(119982,14,2,'w','1',669138,2749),(119983,14,3,'w','1',669138,2750),(119984,14,4,'s','1',669138,2751),(119985,15,0,'e','1',669138,2822),(119986,15,1,'w','1',669138,2730),(119987,15,2,'e','1',669138,2873),(119988,15,3,'n','1',669138,2872),(119989,16,0,'w','1',669138,2730),(119990,16,1,'n','1',669138,2873),(119991,16,2,'e','1',669138,2968),(119992,16,3,'e','1',669138,2778),(119993,17,0,'e','1',669138,2818),(119994,17,1,'s','1',669138,2761),(119995,17,2,'x','0',669138,2762),(119996,17,3,'w','1',669138,2737),(119997,17,4,'e','1',669138,2740),(119998,18,0,'w','1',669138,2871),(119999,18,1,'s','1',669138,2769),(120000,18,2,'n','1',669138,2980),(120001,18,3,'w','1',669138,2846),(120002,19,0,'e','1',669138,2978),(120003,19,1,'n','1',669138,3020),(120004,19,2,'w','1',669138,2840),(120005,19,3,'s','1',669138,2977),(120006,20,0,'e','1',669138,2819),(120007,20,1,'s','1',669138,2871),(120008,20,2,'n','1',669138,2873),(120009,20,3,'e','1',669138,2968),(120010,21,0,'s','1',669138,2871),(120011,21,1,'s','1',669138,2968),(120012,21,2,'w','1',669138,2873),(120013,21,3,'n','1',669138,2737),(120014,22,0,'n','1',669138,3021),(120015,22,1,'e','1',669138,2980),(120016,22,2,'w','1',669138,2862),(120017,22,3,'e','1',669138,2871),(120018,23,0,'n','1',669138,2827),(120019,23,1,'w','1',669138,2884),(120020,23,2,'w','1',669138,2735),(120021,23,3,'w','1',669138,2725),(120022,24,0,'w','1',669138,2878),(120023,24,1,'e','1',669138,2725),(120024,24,2,'w','1',669138,2751),(120025,24,3,'n','1',669138,2834),(120026,25,0,'e','1',669138,2871),(120027,25,1,'s','1',669138,2769),(120028,25,2,'s','1',669138,2846),(120029,25,3,'w','1',669138,2751),(120030,26,0,'n','1',669138,2905),(120031,26,1,'s','1',669138,2884),(120032,26,2,'n','1',669138,2753),(120033,26,3,'n','1',669138,2882),(120034,27,0,'s','1',669138,2871),(120035,27,1,'w','1',669138,2872),(120036,27,2,'s','1',669138,2873),(120037,27,3,'n','1',669138,2726),(120038,28,0,'w','1',669138,2791),(120039,28,1,'w','1',669138,2827),(120040,28,2,'n','1',669138,2887),(120041,28,3,'n','1',669138,2797),(120042,29,0,'e','1',669138,2789),(120043,29,1,'e','1',669138,2828),(120044,29,2,'n','1',669138,2873),(120045,29,3,'n','1',669138,2870),(120046,30,0,'e','1',669138,2871),(120047,30,1,'e','1',669138,2981),(120048,30,2,'s','1',669138,2878),(120049,30,3,'n','1',669138,2877),(120050,31,0,'s','1',669138,2878),(120051,31,1,'w','1',669138,2751),(120052,31,2,'s','1',669138,2909),(120053,31,3,'s','1',669138,2877),(120054,32,0,'n','1',669138,2739),(120055,32,1,'w','1',669138,2827),(120056,32,2,'e','1',669138,2858),(120057,32,3,'w','1',669138,2762),(120058,33,0,'e','1',669138,2828),(120059,33,1,'s','1',669138,2775),(120060,33,2,'w','1',669138,2795),(120061,33,3,'e','1',669138,2877),(120062,34,0,'e','1',669138,2879),(120063,34,1,'e','1',669138,2748),(120064,34,2,'e','1',669138,2833),(120065,34,3,'n','1',669138,2755),(120066,35,0,'s','1',669138,2970),(120067,35,1,'e','1',669138,2755),(120068,35,2,'s','1',669138,2756),(120069,35,3,'s','1',669138,2799),(120070,36,0,'s','1',669138,2740),(120071,36,1,'s','1',669138,2800),(120072,36,2,'w','1',669138,2760),(120073,36,3,'s','1',669138,2802),(120074,36,4,'x','0',669138,2803),(120075,37,0,'e','1',669138,2871),(120076,37,1,'e','1',669138,2751),(120077,37,2,'e','1',669138,2750),(120078,37,3,'w','1',669138,2887),(120079,38,0,'e','1',669138,2749),(120080,38,1,'e','1',669138,2734),(120081,38,2,'s','1',669138,2807),(120082,38,3,'w','1',669138,2790),(120083,39,0,'w','1',669138,2737),(120084,39,1,'n','1',669138,2740),(120085,39,2,'n','1',669138,2738),(120086,39,3,'n','1',669138,2823),(120087,40,0,'s','1',669138,2739),(120088,40,1,'w','1',669138,2827),(120089,40,2,'n','1',669138,2902),(120090,40,3,'w','1',669138,2828),(120091,41,0,'s','1',669138,2964),(120092,41,1,'w','1',669138,2945),(120093,41,2,'n','1',669138,2858),(120094,41,3,'n','1',669138,2870),(120095,42,0,'s','1',669138,2798),(120096,42,1,'w','1',669138,2756),(120097,42,2,'n','1',669138,2833),(120098,42,3,'n','1',669138,2755),(120099,43,0,'e','1',669138,2970),(120100,43,1,'n','1',669138,2826),(120101,43,2,'n','1',669138,2807),(120102,43,3,'n','1',669138,3013),(120103,44,0,'s','1',669138,2986),(120104,44,1,'s','1',669138,2796),(120105,44,2,'e','1',669138,2795),(120106,44,3,'x','0',669138,2762),(120107,44,4,'n','1',669138,3022),(120108,45,0,'s','1',669138,2741),(120109,45,1,'s','1',669138,2756),(120110,45,2,'w','1',669138,2738),(120111,45,3,'n','1',669138,2986),(120112,46,0,'s','1',669138,2740),(120113,46,1,'x','0',669138,2760),(120114,46,2,'s','1',669138,2734),(120115,46,3,'n','1',669138,2733),(120116,46,4,'n','1',669138,3014),(120117,47,0,'s','1',669138,2831),(120118,47,1,'e','1',669138,3023),(120119,47,2,'e','1',669138,2829),(120120,47,3,'x','0',669138,2778),(120121,47,4,'s','1',669138,2929),(120122,48,0,'w','1',669138,2734),(120123,48,1,'w','1',669138,2749),(120124,48,2,'s','1',669138,2987),(120125,48,3,'n','1',669138,2745),(120126,49,0,'e','1',669138,2750),(120127,49,1,'e','1',669138,2832),(120128,49,2,'e','1',669138,2749),(120129,49,3,'e','1',669138,2740),(120130,50,0,'e','1',669138,2734),(120131,50,1,'w','1',669138,2825),(120132,50,2,'n','1',669138,2738),(120133,50,3,'n','1',669138,2737),(120134,51,0,'w','1',669138,2759),(120135,51,1,'w','1',669138,2745),(120136,51,2,'n','1',669138,2729),(120137,51,3,'n','1',669138,2839),(120138,52,0,'s','1',669138,2997),(120139,52,1,'e','1',669138,2741),(120140,52,2,'n','1',669138,2843),(120141,52,3,'n','1',669138,2953),(120142,53,0,'n','1',669138,2756),(120143,53,1,'w','1',669138,2808),(120144,53,2,'n','1',669138,2807),(120145,53,3,'w','1',669138,2889),(120146,54,0,'n','1',669138,2836),(120147,54,1,'w','1',669138,2999),(120148,54,2,'n','1',669138,2837),(120149,54,3,'x','0',669138,2809),(120150,54,4,'n','1',669138,2999),(120151,2,0,'n','1',669138,2728),(120152,2,1,'n','1',669138,3003),(120153,2,2,'n','1',669138,2814),(120154,2,3,'n','1',669138,2733),(120155,3,0,'n','1',669138,2903),(120156,3,1,'n','1',669138,2815),(120157,3,2,'n','1',669138,2723),(120158,3,3,'n','1',669138,2782),(120159,4,0,'e','1',669138,2736),(120160,4,1,'n','1',669138,2754),(120161,4,2,'n','1',669138,2820),(120162,4,3,'n','1',669138,2838),(120163,5,0,'w','1',669138,2921),(120164,5,1,'n','1',669138,2759),(120165,5,2,'e','1',669138,2828),(120166,5,3,'e','1',669138,2795),(120167,6,0,'w','1',669138,2734),(120168,6,1,'n','1',669138,2749),(120169,6,2,'n','1',669138,2762),(120170,6,3,'n','1',669138,2761),(120171,7,0,'w','1',669138,2765),(120172,7,1,'s','1',669138,2863),(120173,7,2,'s','1',669138,2833),(120174,7,3,'e','1',669138,2768),(120175,8,0,'w','1',669138,2765),(120176,8,1,'s','1',669138,2863),(120177,8,2,'s','1',669138,2833),(120178,8,3,'e','1',669138,2768),(120179,9,0,'w','1',669138,2765),(120180,9,1,'s','1',669138,2863),(120181,9,2,'s','1',669138,2833),(120182,9,3,'e','1',669138,2768),(120183,10,0,'w','1',669138,2839),(120184,10,1,'e','1',669138,2761),(120185,10,2,'e','1',669138,2934),(120186,10,3,'e','1',669138,2759),(120187,11,0,'n','1',669138,2921),(120188,11,1,'s','1',669138,2805),(120189,11,2,'s','1',669138,2984),(120190,11,3,'n','1',669138,2870),(120191,12,0,'s','1',669138,2921),(120192,12,1,'s','1',669138,2985),(120193,12,2,'s','1',669138,2820),(120194,12,3,'s','1',669138,2821),(120195,13,0,'w','1',669138,2745),(120196,13,1,'n','1',669138,2754),(120197,13,2,'w','1',669138,2729),(120198,13,3,'w','1',669138,2820),(120199,14,0,'s','1',669138,2765),(120200,14,1,'x','0',669138,2757),(120201,14,2,'w','1',669138,2749),(120202,14,3,'w','1',669138,2750),(120203,14,4,'s','1',669138,2751),(120204,15,0,'e','1',669138,2822),(120205,15,1,'w','1',669138,2730),(120206,15,2,'e','1',669138,2873),(120207,15,3,'n','1',669138,2872),(120208,16,0,'w','1',669138,2730),(120209,16,1,'n','1',669138,2873),(120210,16,2,'e','1',669138,2968),(120211,16,3,'e','1',669138,2778),(120212,17,0,'e','1',669138,2818),(120213,17,1,'s','1',669138,2761),(120214,17,2,'x','0',669138,2762),(120215,17,3,'w','1',669138,2737),(120216,17,4,'e','1',669138,2740),(120217,18,0,'w','1',669138,2871),(120218,18,1,'s','1',669138,2769),(120219,18,2,'n','1',669138,2980),(120220,18,3,'w','1',669138,2846),(120221,19,0,'e','1',669138,2978),(120222,19,1,'n','1',669138,3020),(120223,19,2,'w','1',669138,2840),(120224,19,3,'s','1',669138,2977),(120225,20,0,'e','1',669138,2819),(120226,20,1,'s','1',669138,2871),(120227,20,2,'n','1',669138,2873),(120228,20,3,'e','1',669138,2968),(120229,21,0,'s','1',669138,2871),(120230,21,1,'s','1',669138,2968),(120231,21,2,'w','1',669138,2873),(120232,21,3,'n','1',669138,2737),(120233,22,0,'n','1',669138,3021),(120234,22,1,'e','1',669138,2980),(120235,22,2,'w','1',669138,2862),(120236,22,3,'e','1',669138,2871),(120237,23,0,'n','1',669138,2827),(120238,23,1,'w','1',669138,2884),(120239,23,2,'w','1',669138,2735),(120240,23,3,'w','1',669138,2725),(120241,24,0,'w','1',669138,2878),(120242,24,1,'e','1',669138,2725),(120243,24,2,'w','1',669138,2751),(120244,24,3,'n','1',669138,2834),(120245,25,0,'e','1',669138,2871),(120246,25,1,'s','1',669138,2769),(120247,25,2,'s','1',669138,2846),(120248,25,3,'w','1',669138,2751),(120249,26,0,'n','1',669138,2905),(120250,26,1,'s','1',669138,2884),(120251,26,2,'n','1',669138,2753),(120252,26,3,'n','1',669138,2882),(120253,27,0,'s','1',669138,2871),(120254,27,1,'w','1',669138,2872),(120255,27,2,'s','1',669138,2873),(120256,27,3,'n','1',669138,2726),(120257,28,0,'w','1',669138,2791),(120258,28,1,'w','1',669138,2827),(120259,28,2,'n','1',669138,2887),(120260,28,3,'n','1',669138,2797),(120261,29,0,'e','1',669138,2789),(120262,29,1,'e','1',669138,2828),(120263,29,2,'n','1',669138,2873),(120264,29,3,'n','1',669138,2870),(120265,30,0,'e','1',669138,2871),(120266,30,1,'e','1',669138,2981),(120267,30,2,'s','1',669138,2878),(120268,30,3,'n','1',669138,2877),(120269,31,0,'s','1',669138,2878),(120270,31,1,'w','1',669138,2751),(120271,31,2,'s','1',669138,2909),(120272,31,3,'s','1',669138,2877),(120273,32,0,'n','1',669138,2739),(120274,32,1,'w','1',669138,2827),(120275,32,2,'e','1',669138,2858),(120276,32,3,'w','1',669138,2762),(120277,33,0,'e','1',669138,2828),(120278,33,1,'s','1',669138,2775),(120279,33,2,'w','1',669138,2795),(120280,33,3,'e','1',669138,2877),(120281,34,0,'e','1',669138,2879),(120282,34,1,'e','1',669138,2748),(120283,34,2,'e','1',669138,2833),(120284,34,3,'n','1',669138,2755),(120285,35,0,'s','1',669138,2970),(120286,35,1,'e','1',669138,2755),(120287,35,2,'s','1',669138,2756),(120288,35,3,'s','1',669138,2799),(120289,36,0,'s','1',669138,2740),(120290,36,1,'s','1',669138,2800),(120291,36,2,'w','1',669138,2760),(120292,36,3,'s','1',669138,2802),(120293,36,4,'x','0',669138,2803),(120294,37,0,'e','1',669138,2871),(120295,37,1,'e','1',669138,2751),(120296,37,2,'e','1',669138,2750),(120297,37,3,'w','1',669138,2887),(120298,38,0,'e','1',669138,2749),(120299,38,1,'e','1',669138,2734),(120300,38,2,'s','1',669138,2807),(120301,38,3,'w','1',669138,2790),(120302,39,0,'w','1',669138,2737),(120303,39,1,'n','1',669138,2740),(120304,39,2,'n','1',669138,2738),(120305,39,3,'n','1',669138,2823),(120306,40,0,'s','1',669138,2739),(120307,40,1,'w','1',669138,2827),(120308,40,2,'n','1',669138,2902),(120309,40,3,'w','1',669138,2828),(120310,41,0,'s','1',669138,2964),(120311,41,1,'w','1',669138,2945),(120312,41,2,'n','1',669138,2858),(120313,41,3,'n','1',669138,2870),(120314,42,0,'s','1',669138,2798),(120315,42,1,'w','1',669138,2756),(120316,42,2,'n','1',669138,2833),(120317,42,3,'n','1',669138,2755),(120318,43,0,'e','1',669138,2970),(120319,43,1,'n','1',669138,2826),(120320,43,2,'n','1',669138,2807),(120321,43,3,'n','1',669138,3013),(120322,44,0,'s','1',669138,2986),(120323,44,1,'s','1',669138,2796),(120324,44,2,'e','1',669138,2795),(120325,44,3,'x','0',669138,2762),(120326,44,4,'n','1',669138,3022),(120327,45,0,'s','1',669138,2741),(120328,45,1,'s','1',669138,2756),(120329,45,2,'w','1',669138,2738),(120330,45,3,'n','1',669138,2986),(120331,46,0,'s','1',669138,2740),(120332,46,1,'x','0',669138,2760),(120333,46,2,'s','1',669138,2734),(120334,46,3,'n','1',669138,2733),(120335,46,4,'n','1',669138,3014),(120336,47,0,'s','1',669138,2831),(120337,47,1,'e','1',669138,3023),(120338,47,2,'e','1',669138,2829),(120339,47,3,'x','0',669138,2778),(120340,47,4,'s','1',669138,2929),(120341,48,0,'w','1',669138,2734),(120342,48,1,'w','1',669138,2749),(120343,48,2,'s','1',669138,2987),(120344,48,3,'n','1',669138,2745),(120345,49,0,'e','1',669138,2750),(120346,49,1,'e','1',669138,2832),(120347,49,2,'e','1',669138,2749),(120348,49,3,'e','1',669138,2740),(120349,50,0,'e','1',669138,2734),(120350,50,1,'w','1',669138,2825),(120351,50,2,'n','1',669138,2738),(120352,50,3,'n','1',669138,2737),(120353,51,0,'w','1',669138,2759),(120354,51,1,'w','1',669138,2745),(120355,51,2,'n','1',669138,2729),(120356,51,3,'n','1',669138,2839),(120357,52,0,'s','1',669138,2997),(120358,52,1,'e','1',669138,2741),(120359,52,2,'n','1',669138,2843),(120360,52,3,'n','1',669138,2953),(120361,53,0,'n','1',669138,2756),(120362,53,1,'w','1',669138,2808),(120363,53,2,'n','1',669138,2807),(120364,53,3,'w','1',669138,2889),(120365,54,0,'n','1',669138,2836),(120366,54,1,'w','1',669138,2999),(120367,54,2,'n','1',669138,2837),(120368,54,3,'x','0',669138,2809),(120369,54,4,'n','1',669138,2999),(120370,2,0,'n','1',669139,2867),(120371,2,1,'n','1',669139,2816),(120372,2,2,'n','1',669139,2732),(120373,2,3,'n','1',669139,2717),(120374,3,0,'e','1',669139,2719),(120375,3,1,'e','1',669139,2725),(120376,3,2,'e','1',669139,2735),(120377,3,3,'e','1',669139,2884),(120378,4,0,'n','1',669139,2728),(120379,4,1,'n','1',669139,2965),(120380,4,2,'w','1',669139,2908),(120381,4,3,'w','1',669139,2772),(120382,5,0,'s','1',669139,2749),(120383,5,1,'s','1',669139,2850),(120384,5,2,'n','1',669139,2901),(120385,5,3,'e','1',669139,2903),(120386,6,0,'s','1',669139,2850),(120387,6,1,'n','1',669139,2962),(120388,6,2,'w','1',669139,2858),(120389,6,3,'n','1',669139,2963),(120390,7,0,'s','1',669139,2850),(120391,7,1,'w','1',669139,2975),(120392,7,2,'n','1',669139,2915),(120393,7,3,'n','1',669139,2779),(120394,8,0,'e','1',669139,2850),(120395,8,1,'e','1',669139,2732),(120396,8,2,'n','1',669139,2834),(120397,8,3,'n','1',669139,2823),(120398,9,0,'e','1',669139,2733),(120399,9,1,'e','1',669139,2804),(120400,9,2,'n','1',669139,2917),(120401,9,3,'n','1',669139,2842),(120402,10,0,'e','1',669139,2738),(120403,10,1,'s','1',669139,2806),(120404,10,2,'s','1',669139,2759),(120405,10,3,'w','1',669139,3011),(120406,11,0,'n','1',669139,2780),(120407,11,1,'s','1',669139,2877),(120408,11,2,'w','1',669139,2738),(120409,11,3,'n','1',669139,2888),(120410,12,0,'s','1',669139,2734),(120411,12,1,'n','1',669139,2733),(120412,12,2,'w','1',669139,2737),(120413,12,3,'s','1',669139,2877),(120414,13,0,'s','1',669139,2877),(120415,13,1,'s','1',669139,2740),(120416,13,2,'x','0',669139,2760),(120417,13,3,'s','1',669139,2734),(120418,13,4,'n','1',669139,2733),(120419,14,0,'n','1',669139,2745),(120420,14,1,'n','1',669139,2984),(120421,14,2,'n','1',669139,2997),(120422,14,3,'n','1',669139,2834),(120423,15,0,'w','1',669139,2734),(120424,15,1,'e','1',669139,2749),(120425,15,2,'s','1',669139,2970),(120426,15,3,'n','1',669139,2736),(120427,16,0,'e','1',669139,2734),(120428,16,1,'e','1',669139,2755),(120429,16,2,'s','1',669139,2756),(120430,16,3,'w','1',669139,2738),(120431,17,0,'n','1',669139,2822),(120432,17,1,'n','1',669139,2829),(120433,17,2,'e','1',669139,2878),(120434,17,3,'e','1',669139,2879),(120435,18,0,'n','1',669139,2962),(120436,18,1,'n','1',669139,2822),(120437,18,2,'e','1',669139,2831),(120438,18,3,'e','1',669139,2879),(120439,19,0,'w','1',669139,2786),(120440,19,1,'n','1',669139,2775),(120441,19,2,'e','1',669139,2748),(120442,19,3,'s','1',669139,2755),(120443,20,0,'s','1',669139,2740),(120444,20,1,'x','0',669139,2760),(120445,20,2,'s','1',669139,2734),(120446,20,3,'n','1',669139,2733),(120447,20,4,'w','1',669139,2857),(120448,21,0,'w','1',669139,2734),(120449,21,1,'n','1',669139,2792),(120450,21,2,'w','1',669139,2749),(120451,21,3,'w','1',669139,2763),(120452,22,0,'s','1',669139,2750),(120453,22,1,'s','1',669139,2794),(120454,22,2,'x','0',669139,2778),(120455,22,3,'w','1',669139,2731),(120456,22,4,'s','1',669139,2860),(120457,23,0,'s','1',669139,2851),(120458,23,1,'n','1',669139,2730),(120459,23,2,'s','1',669139,2876),(120460,23,3,'e','1',669139,2751),(120461,24,0,'w','1',669139,2954),(120462,24,1,'s','1',669139,2750),(120463,24,2,'s','1',669139,2855),(120464,24,3,'x','0',669139,2725),(120465,24,4,'w','1',669139,2731),(120466,25,0,'n','1',669139,2730),(120467,25,1,'e','1',669139,2751),(120468,25,2,'n','1',669139,2750),(120469,25,3,'w','1',669139,2746),(120470,26,0,'w','1',669139,2770),(120471,26,1,'w','1',669139,2771),(120472,26,2,'w','1',669139,2840),(120473,26,3,'n','1',669139,2877),(120474,27,0,'e','1',669139,2878),(120475,27,1,'s','1',669139,2862),(120476,27,2,'s','1',669139,2840),(120477,27,3,'w','1',669139,2879),(120478,28,0,'e','1',669139,2831),(120479,28,1,'s','1',669139,2878),(120480,28,2,'s','1',669139,2794),(120481,28,3,'x','0',669139,2778),(120482,28,4,'e','1',669139,2877),(120483,29,0,'w','1',669139,2969),(120484,29,1,'w','1',669139,2753),(120485,29,2,'n','1',669139,2819),(120486,29,3,'n','1',669139,3006),(120487,30,0,'n','1',669139,2847),(120488,30,1,'n','1',669139,2835),(120489,30,2,'n','1',669139,2771),(120490,30,3,'w','1',669139,2952),(120491,31,0,'w','1',669139,2775),(120492,31,1,'n','1',669139,2784),(120493,31,2,'w','1',669139,2785),(120494,31,3,'n','1',669139,2882),(120495,32,0,'w','1',669139,2840),(120496,32,1,'n','1',669139,2848),(120497,32,2,'e','1',669139,2887),(120498,32,3,'n','1',669139,2927),(120499,33,0,'w','1',669139,2737),(120500,33,1,'n','1',669139,2949),(120501,33,2,'n','1',669139,2861),(120502,33,3,'n','1',669139,2856),(120503,34,0,'e','1',669139,2852),(120504,34,1,'n','1',669139,2933),(120505,34,2,'w','1',669139,2758),(120506,34,3,'n','1',669139,2740),(120507,35,0,'e','1',669139,2879),(120508,35,1,'e','1',669139,2830),(120509,35,2,'n','1',669139,2829),(120510,35,3,'n','1',669139,2831),(120511,36,0,'s','1',669139,2748),(120512,36,1,'s','1',669139,2770),(120513,36,2,'e','1',669139,2908),(120514,36,3,'w','1',669139,2997),(120515,37,0,'n','1',669139,2758),(120516,37,1,'n','1',669139,2740),(120517,37,2,'n','1',669139,2817),(120518,37,3,'n','1',669139,2901),(120519,38,0,'e','1',669139,2796),(120520,38,1,'n','1',669139,2986),(120521,38,2,'s','1',669139,2761),(120522,38,3,'x','0',669139,2762),(120523,38,4,'e','1',669139,2746),(120524,39,0,'w','1',669139,2740),(120525,39,1,'w','1',669139,2746),(120526,39,2,'n','1',669139,2770),(120527,39,3,'w','1',669139,2817),(120528,40,0,'s','1',669139,2935),(120529,40,1,'e','1',669139,2768),(120530,40,2,'n','1',669139,2748),(120531,40,3,'n','1',669139,2824),(120532,41,0,'e','1',669139,2765),(120533,41,1,'n','1',669139,3024),(120534,41,2,'n','1',669139,2744),(120535,41,3,'n','1',669139,2729),(120536,42,0,'e','1',669139,2862),(120537,42,1,'e','1',669139,3025),(120538,42,2,'e','1',669139,2852),(120539,42,3,'n','1',669139,2933),(120540,43,0,'n','1',669139,2764),(120541,43,1,'n','1',669139,3007),(120542,43,2,'x','0',669139,2859),(120543,43,3,'w','1',669139,2938),(120544,43,4,'n','1',669139,2941),(120545,44,0,'e','1',669139,2885),(120546,44,1,'s','1',669139,3026),(120547,44,2,'s','1',669139,3007),(120548,44,3,'x','0',669139,2801),(120549,44,4,'w','1',669139,2938),(120550,45,0,'e','1',669139,2886),(120551,45,1,'s','1',669139,2982),(120552,45,2,'e','1',669139,2801),(120553,45,3,'e','1',669139,2931),(120554,45,4,'x','0',669139,2910),(120555,46,0,'e','1',669139,2793),(120556,46,1,'e','1',669139,2930),(120557,46,2,'n','1',669139,2932),(120558,46,3,'x','0',669139,2910),(120559,46,4,'w','1',669139,2792),(120560,47,0,'n','1',669139,2941),(120561,47,1,'n','1',669139,2942),(120562,47,2,'n','1',669139,2943),(120563,2,0,'n','1',669139,2867),(120564,2,1,'n','1',669139,2816),(120565,2,2,'n','1',669139,2732),(120566,2,3,'n','1',669139,2717),(120567,3,0,'e','1',669139,2719),(120568,3,1,'e','1',669139,2725),(120569,3,2,'e','1',669139,2735),(120570,3,3,'e','1',669139,2884),(120571,4,0,'n','1',669139,2728),(120572,4,1,'n','1',669139,2965),(120573,4,2,'w','1',669139,2908),(120574,4,3,'w','1',669139,2772),(120575,5,0,'s','1',669139,2749),(120576,5,1,'s','1',669139,2850),(120577,5,2,'n','1',669139,2901),(120578,5,3,'e','1',669139,2903),(120579,6,0,'s','1',669139,2850),(120580,6,1,'n','1',669139,2962),(120581,6,2,'w','1',669139,2858),(120582,6,3,'n','1',669139,2963),(120583,7,0,'s','1',669139,2850),(120584,7,1,'w','1',669139,2975),(120585,7,2,'n','1',669139,2915),(120586,7,3,'n','1',669139,2779),(120587,8,0,'e','1',669139,2850),(120588,8,1,'e','1',669139,2732),(120589,8,2,'n','1',669139,2834),(120590,8,3,'n','1',669139,2823),(120591,9,0,'e','1',669139,2733),(120592,9,1,'e','1',669139,2804),(120593,9,2,'n','1',669139,2917),(120594,9,3,'n','1',669139,2842),(120595,10,0,'e','1',669139,2738),(120596,10,1,'s','1',669139,2806),(120597,10,2,'s','1',669139,2759),(120598,10,3,'w','1',669139,3011),(120599,11,0,'n','1',669139,2780),(120600,11,1,'s','1',669139,2877),(120601,11,2,'w','1',669139,2738),(120602,11,3,'n','1',669139,2888),(120603,12,0,'s','1',669139,2734),(120604,12,1,'n','1',669139,2733),(120605,12,2,'w','1',669139,2737),(120606,12,3,'s','1',669139,2877),(120607,13,0,'s','1',669139,2877),(120608,13,1,'s','1',669139,2740),(120609,13,2,'x','0',669139,2760),(120610,13,3,'s','1',669139,2734),(120611,13,4,'n','1',669139,2733),(120612,14,0,'n','1',669139,2745),(120613,14,1,'n','1',669139,2984),(120614,14,2,'n','1',669139,2997),(120615,14,3,'n','1',669139,2834),(120616,15,0,'w','1',669139,2734),(120617,15,1,'e','1',669139,2749),(120618,15,2,'s','1',669139,2970),(120619,15,3,'n','1',669139,2736),(120620,16,0,'e','1',669139,2734),(120621,16,1,'e','1',669139,2755),(120622,16,2,'s','1',669139,2756),(120623,16,3,'w','1',669139,2738),(120624,17,0,'n','1',669139,2822),(120625,17,1,'n','1',669139,2829),(120626,17,2,'e','1',669139,2878),(120627,17,3,'e','1',669139,2879),(120628,18,0,'n','1',669139,2962),(120629,18,1,'n','1',669139,2822),(120630,18,2,'e','1',669139,2831),(120631,18,3,'e','1',669139,2879),(120632,19,0,'w','1',669139,2786),(120633,19,1,'n','1',669139,2775),(120634,19,2,'e','1',669139,2748),(120635,19,3,'s','1',669139,2755),(120636,20,0,'s','1',669139,2740),(120637,20,1,'x','0',669139,2760),(120638,20,2,'s','1',669139,2734),(120639,20,3,'n','1',669139,2733),(120640,20,4,'w','1',669139,2857),(120641,21,0,'w','1',669139,2734),(120642,21,1,'n','1',669139,2792),(120643,21,2,'w','1',669139,2749),(120644,21,3,'w','1',669139,2763),(120645,22,0,'s','1',669139,2750),(120646,22,1,'s','1',669139,2794),(120647,22,2,'x','0',669139,2778),(120648,22,3,'w','1',669139,2731),(120649,22,4,'s','1',669139,2860),(120650,23,0,'s','1',669139,2851),(120651,23,1,'n','1',669139,2730),(120652,23,2,'s','1',669139,2876),(120653,23,3,'e','1',669139,2751),(120654,24,0,'w','1',669139,2954),(120655,24,1,'s','1',669139,2750),(120656,24,2,'s','1',669139,2855),(120657,24,3,'x','0',669139,2725),(120658,24,4,'w','1',669139,2731),(120659,25,0,'n','1',669139,2730),(120660,25,1,'e','1',669139,2751),(120661,25,2,'n','1',669139,2750),(120662,25,3,'w','1',669139,2746),(120663,26,0,'w','1',669139,2770),(120664,26,1,'w','1',669139,2771),(120665,26,2,'w','1',669139,2840),(120666,26,3,'n','1',669139,2877),(120667,27,0,'e','1',669139,2878),(120668,27,1,'s','1',669139,2862),(120669,27,2,'s','1',669139,2840),(120670,27,3,'w','1',669139,2879),(120671,28,0,'e','1',669139,2831),(120672,28,1,'s','1',669139,2878),(120673,28,2,'s','1',669139,2794),(120674,28,3,'x','0',669139,2778),(120675,28,4,'e','1',669139,2877),(120676,29,0,'w','1',669139,2969),(120677,29,1,'w','1',669139,2753),(120678,29,2,'n','1',669139,2819),(120679,29,3,'n','1',669139,3006),(120680,30,0,'n','1',669139,2847),(120681,30,1,'n','1',669139,2835),(120682,30,2,'n','1',669139,2771),(120683,30,3,'w','1',669139,2952),(120684,31,0,'w','1',669139,2775),(120685,31,1,'n','1',669139,2784),(120686,31,2,'w','1',669139,2785),(120687,31,3,'n','1',669139,2882),(120688,32,0,'w','1',669139,2840),(120689,32,1,'n','1',669139,2848),(120690,32,2,'e','1',669139,2887),(120691,32,3,'n','1',669139,2927),(120692,33,0,'w','1',669139,2737),(120693,33,1,'n','1',669139,2949),(120694,33,2,'n','1',669139,2861),(120695,33,3,'n','1',669139,2856),(120696,34,0,'e','1',669139,2852),(120697,34,1,'n','1',669139,2933),(120698,34,2,'w','1',669139,2758),(120699,34,3,'n','1',669139,2740),(120700,35,0,'e','1',669139,2879),(120701,35,1,'e','1',669139,2830),(120702,35,2,'n','1',669139,2829),(120703,35,3,'n','1',669139,2831),(120704,36,0,'s','1',669139,2748),(120705,36,1,'s','1',669139,2770),(120706,36,2,'e','1',669139,2908),(120707,36,3,'w','1',669139,2997),(120708,37,0,'n','1',669139,2758),(120709,37,1,'n','1',669139,2740),(120710,37,2,'n','1',669139,2817),(120711,37,3,'n','1',669139,2901),(120712,38,0,'e','1',669139,2796),(120713,38,1,'n','1',669139,2986),(120714,38,2,'s','1',669139,2761),(120715,38,3,'x','0',669139,2762),(120716,38,4,'e','1',669139,2746),(120717,39,0,'w','1',669139,2740),(120718,39,1,'w','1',669139,2746),(120719,39,2,'n','1',669139,2770),(120720,39,3,'w','1',669139,2817),(120721,40,0,'s','1',669139,2935),(120722,40,1,'e','1',669139,2768),(120723,40,2,'n','1',669139,2748),(120724,40,3,'n','1',669139,2824),(120725,41,0,'e','1',669139,2765),(120726,41,1,'n','1',669139,3024),(120727,41,2,'n','1',669139,2744),(120728,41,3,'n','1',669139,2729),(120729,42,0,'e','1',669139,2862),(120730,42,1,'e','1',669139,3025),(120731,42,2,'e','1',669139,2852),(120732,42,3,'n','1',669139,2933),(120733,43,0,'n','1',669139,2764),(120734,43,1,'n','1',669139,3007),(120735,43,2,'x','0',669139,2859),(120736,43,3,'w','1',669139,2938),(120737,43,4,'n','1',669139,2941),(120738,44,0,'e','1',669139,2885),(120739,44,1,'s','1',669139,3026),(120740,44,2,'s','1',669139,3007),(120741,44,3,'x','0',669139,2801),(120742,44,4,'w','1',669139,2938),(120743,45,0,'e','1',669139,2886),(120744,45,1,'s','1',669139,2982),(120745,45,2,'e','1',669139,2801),(120746,45,3,'e','1',669139,2931),(120747,45,4,'x','0',669139,2910),(120748,46,0,'e','1',669139,2793),(120749,46,1,'e','1',669139,2930),(120750,46,2,'n','1',669139,2932),(120751,46,3,'x','0',669139,2910),(120752,46,4,'w','1',669139,2792),(120753,47,0,'n','1',669139,2941),(120754,47,1,'n','1',669139,2942),(120755,47,2,'n','1',669139,2943),(120756,2,0,'n','1',669140,2867),(120757,2,1,'n','1',669140,2816),(120758,2,2,'n','1',669140,2732),(120759,2,3,'w','1',669140,2749),(120760,3,0,'n','1',669140,2974),(120761,3,1,'n','1',669140,2919),(120762,3,2,'w','1',669140,2916),(120763,3,3,'n','1',669140,2964),(120764,4,0,'n','1',669140,2963),(120765,4,1,'n','1',669140,2915),(120766,4,2,'n','1',669140,2786),(120767,4,3,'w','1',669140,2787),(120768,5,0,'s','1',669140,2851),(120769,5,1,'s','1',669140,2750),(120770,5,2,'w','1',669140,2731),(120771,5,3,'s','1',669140,2877),(120772,6,0,'n','1',669140,2849),(120773,6,1,'s','1',669140,2804),(120774,6,2,'s','1',669140,2806),(120775,6,3,'n','1',669140,2888),(120776,7,0,'n','1',669140,2849),(120777,7,1,'s','1',669140,2804),(120778,7,2,'s','1',669140,2806),(120779,7,3,'n','1',669140,2962),(120780,8,0,'n','1',669140,2849),(120781,8,1,'s','1',669140,2804),(120782,8,2,'s','1',669140,2806),(120783,8,3,'s','1',669140,2849),(120784,9,0,'e','1',669140,2870),(120785,9,1,'n','1',669140,2963),(120786,9,2,'e','1',669140,2815),(120787,9,3,'n','1',669140,2927),(120788,10,0,'n','1',669140,2730),(120789,10,1,'e','1',669140,2751),(120790,10,2,'w','1',669140,2750),(120791,10,3,'s','1',669140,2860),(120792,11,0,'n','1',669140,2875),(120793,11,1,'e','1',669140,2849),(120794,11,2,'w','1',669140,2916),(120795,11,3,'s','1',669140,2821),(120796,12,0,'n','1',669140,2772),(120797,12,1,'e','1',669140,2771),(120798,12,2,'s','1',669140,2849),(120799,12,3,'w','1',669140,2745),(120800,13,0,'n','1',669140,2770),(120801,13,1,'w','1',669140,2911),(120802,13,2,'n','1',669140,2748),(120803,13,3,'n','1',669140,2875),(120804,14,0,'w','1',669140,2764),(120805,14,1,'s','1',669140,3019),(120806,14,2,'n','1',669140,2849),(120807,14,3,'w','1',669140,2745),(120808,15,0,'s','1',669140,2921),(120809,15,1,'e','1',669140,2804),(120810,15,2,'s','1',669140,2820),(120811,15,3,'s','1',669140,2917),(120812,16,0,'s','1',669140,2729),(120813,16,1,'w','1',669140,2916),(120814,16,2,'w','1',669140,2824),(120815,16,3,'x','0',669140,2762),(120816,16,4,'s','1',669140,2849),(120817,17,0,'w','1',669140,2875),(120818,17,1,'w','1',669140,2754),(120819,17,2,'w','1',669140,2883),(120820,17,3,'w','1',669140,2736),(120821,17,4,'x','0',669140,2760),(120822,18,0,'e','1',669140,2884),(120823,18,1,'e','1',669140,2883),(120824,18,2,'e','1',669140,2875),(120825,18,3,'w','1',669140,2751),(120826,18,4,'x','0',669140,2859),(120827,19,0,'e','1',669140,2871),(120828,19,1,'s','1',669140,2751),(120829,19,2,'s','1',669140,2730),(120830,19,3,'w','1',669140,2727),(120831,20,0,'w','1',669140,2919),(120832,20,1,'w','1',669140,2831),(120833,20,2,'n','1',669140,2834),(120834,20,3,'n','1',669140,2915),(120835,21,0,'n','1',669140,2875),(120836,21,1,'n','1',669140,2849),(120837,21,2,'s','1',669140,2804),(120838,21,3,'s','1',669140,2837),(120839,22,0,'s','1',669140,2849),(120840,22,1,'s','1',669140,2843),(120841,22,2,'n','1',669140,2823),(120842,22,3,'e','1',669140,2786),(120843,23,0,'w','1',669140,2729),(120844,23,1,'n','1',669140,2875),(120845,23,2,'w','1',669140,2803),(120846,23,3,'s','1',669140,2761),(120847,23,4,'x','0',669140,2762),(120848,24,0,'n','1',669140,2849),(120849,24,1,'n','1',669140,2804),(120850,24,2,'n','1',669140,2743),(120851,25,0,'s','1',669140,2742),(120852,25,1,'s','1',669140,2743),(120853,25,2,'s','1',669140,2804),(120854,25,3,'s','1',669140,2849),(120855,26,0,'n','1',669140,2726),(120856,26,1,'s','1',669140,2873),(120857,26,2,'s','1',669140,2878),(120858,26,3,'n','1',669140,2745),(120859,27,0,'n','1',669140,2726),(120860,27,1,'e','1',669140,2873),(120861,27,2,'w','1',669140,2964),(120862,27,3,'e','1',669140,2901),(120863,28,0,'w','1',669140,2730),(120864,28,1,'s','1',669140,2873),(120865,28,2,'e','1',669140,2781),(120866,28,3,'e','1',669140,2791),(120867,29,0,'n','1',669140,2875),(120868,29,1,'n','1',669140,2849),(120869,29,2,'n','1',669140,2804),(120870,29,3,'n','1',669140,2888),(120871,30,0,'e','1',669140,2851),(120872,30,1,'n','1',669140,2787),(120873,30,2,'e','1',669140,2788),(120874,30,3,'n','1',669140,2817),(120875,31,0,'s','1',669140,2726),(120876,31,1,'s','1',669140,2831),(120877,31,2,'n','1',669140,2789),(120878,31,3,'e','1',669140,2800),(120879,32,0,'n','1',669140,2960),(120880,32,1,'n','1',669140,3001),(120881,32,2,'w','1',669140,2985),(120882,32,3,'n','1',669140,2821),(120883,33,0,'n','1',669140,2815),(120884,33,1,'n','1',669140,2818),(120885,33,2,'n','1',669140,2968),(120886,33,3,'e','1',669140,2981),(120887,34,0,'e','1',669140,2829),(120888,34,1,'x','0',669140,2778),(120889,34,2,'n','1',669140,2720),(120890,34,3,'e','1',669140,2931),(120891,34,4,'n','1',669140,2878),(120892,35,0,'n','1',669140,2900),(120893,35,1,'n','1',669140,2767),(120894,35,2,'e','1',669140,2899),(120895,35,3,'w','1',669140,2885),(120896,36,0,'e','1',669140,2853),(120897,36,1,'e','1',669140,2899),(120898,36,2,'n','1',669140,3019),(120899,36,3,'e','1',669140,2885),(120900,37,0,'n','1',669140,2795),(120901,37,1,'w','1',669140,2796),(120902,37,2,'w','1',669140,2776),(120903,37,3,'w','1',669140,2794),(120904,38,0,'w','1',669140,2831),(120905,38,1,'n','1',669140,2781),(120906,38,2,'n','1',669140,2834),(120907,38,3,'n','1',669140,2823),(120908,39,0,'w','1',669140,2903),(120909,39,1,'n','1',669140,2797),(120910,39,2,'n','1',669140,2789),(120911,39,3,'n','1',669140,2795),(120912,40,0,'n','1',669140,2966),(120913,40,1,'e','1',669140,2950),(120914,40,2,'e','1',669140,2990),(120915,40,3,'e','1',669140,2861),(120916,41,0,'e','1',669140,2796),(120917,41,1,'n','1',669140,2761),(120918,41,2,'e','1',669140,2758),(120919,41,3,'n','1',669140,2934),(120920,42,0,'n','1',669140,2858),(120921,42,1,'n','1',669140,2902),(120922,42,2,'n','1',669140,2778),(120923,42,3,'n','1',669140,2794),(120924,43,0,'n','1',669140,2726),(120925,44,0,'w','1',669140,2873),(120926,45,0,'e','1',669140,3021),(120927,45,1,'s','1',669140,2873),(120928,45,2,'s','1',669140,2726),(120929,45,3,'e','1',669140,2720),(120930,46,0,'e','1',669140,2957),(120931,46,1,'e','1',669140,2913),(120932,46,2,'e','1',669140,2867),(120933,46,3,'e','1',669140,3003),(120934,47,0,'n','1',669140,2992),(120935,47,1,'w','1',669140,2959),(120936,47,2,'n','1',669140,2813),(120937,47,3,'n','1',669140,2842),(120938,48,0,'w','1',669140,2959),(120939,48,1,'s','1',669140,2738),(120940,49,0,'n','1',669140,2842),(120941,49,1,'w','1',669140,2738),(120942,49,2,'w','1',669140,2821),(120943,49,3,'n','1',669140,2745),(120944,2,0,'n','1',669140,2867),(120945,2,1,'n','1',669140,2816),(120946,2,2,'n','1',669140,2732),(120947,2,3,'w','1',669140,2749),(120948,3,0,'n','1',669140,2974),(120949,3,1,'n','1',669140,2919),(120950,3,2,'w','1',669140,2916),(120951,3,3,'n','1',669140,2964),(120952,4,0,'n','1',669140,2963),(120953,4,1,'n','1',669140,2915),(120954,4,2,'n','1',669140,2786),(120955,4,3,'w','1',669140,2787),(120956,5,0,'s','1',669140,2851),(120957,5,1,'s','1',669140,2750),(120958,5,2,'w','1',669140,2731),(120959,5,3,'s','1',669140,2877),(120960,6,0,'n','1',669140,2849),(120961,6,1,'s','1',669140,2804),(120962,6,2,'s','1',669140,2806),(120963,6,3,'n','1',669140,2888),(120964,7,0,'n','1',669140,2849),(120965,7,1,'s','1',669140,2804),(120966,7,2,'s','1',669140,2806),(120967,7,3,'n','1',669140,2962),(120968,8,0,'n','1',669140,2849),(120969,8,1,'s','1',669140,2804),(120970,8,2,'s','1',669140,2806),(120971,8,3,'s','1',669140,2849),(120972,9,0,'e','1',669140,2870),(120973,9,1,'n','1',669140,2963),(120974,9,2,'e','1',669140,2815),(120975,9,3,'n','1',669140,2927),(120976,10,0,'n','1',669140,2730),(120977,10,1,'e','1',669140,2751),(120978,10,2,'w','1',669140,2750),(120979,10,3,'s','1',669140,2860),(120980,11,0,'n','1',669140,2875),(120981,11,1,'e','1',669140,2849),(120982,11,2,'w','1',669140,2916),(120983,11,3,'s','1',669140,2821),(120984,12,0,'n','1',669140,2772),(120985,12,1,'e','1',669140,2771),(120986,12,2,'s','1',669140,2849),(120987,12,3,'w','1',669140,2745),(120988,13,0,'n','1',669140,2770),(120989,13,1,'w','1',669140,2911),(120990,13,2,'n','1',669140,2748),(120991,13,3,'n','1',669140,2875),(120992,14,0,'w','1',669140,2764),(120993,14,1,'s','1',669140,3019),(120994,14,2,'n','1',669140,2849),(120995,14,3,'w','1',669140,2745),(120996,15,0,'s','1',669140,2921),(120997,15,1,'e','1',669140,2804),(120998,15,2,'s','1',669140,2820),(120999,15,3,'s','1',669140,2917),(121000,16,0,'s','1',669140,2729),(121001,16,1,'w','1',669140,2916),(121002,16,2,'w','1',669140,2824),(121003,16,3,'x','0',669140,2762),(121004,16,4,'s','1',669140,2849),(121005,17,0,'w','1',669140,2875),(121006,17,1,'w','1',669140,2754),(121007,17,2,'w','1',669140,2883),(121008,17,3,'w','1',669140,2736),(121009,17,4,'x','0',669140,2760),(121010,18,0,'e','1',669140,2884),(121011,18,1,'e','1',669140,2883),(121012,18,2,'e','1',669140,2875),(121013,18,3,'w','1',669140,2751),(121014,18,4,'x','0',669140,2859),(121015,19,0,'e','1',669140,2871),(121016,19,1,'s','1',669140,2751),(121017,19,2,'s','1',669140,2730),(121018,19,3,'w','1',669140,2727),(121019,20,0,'w','1',669140,2919),(121020,20,1,'w','1',669140,2831),(121021,20,2,'n','1',669140,2834),(121022,20,3,'n','1',669140,2915),(121023,21,0,'n','1',669140,2875),(121024,21,1,'n','1',669140,2849),(121025,21,2,'s','1',669140,2804),(121026,21,3,'s','1',669140,2837),(121027,22,0,'s','1',669140,2849),(121028,22,1,'s','1',669140,2843),(121029,22,2,'n','1',669140,2823),(121030,22,3,'e','1',669140,2786),(121031,23,0,'w','1',669140,2729),(121032,23,1,'n','1',669140,2875),(121033,23,2,'w','1',669140,2803),(121034,23,3,'s','1',669140,2761),(121035,23,4,'x','0',669140,2762),(121036,24,0,'n','1',669140,2849),(121037,24,1,'n','1',669140,2804),(121038,24,2,'n','1',669140,2743),(121039,25,0,'s','1',669140,2742),(121040,25,1,'s','1',669140,2743),(121041,25,2,'s','1',669140,2804),(121042,25,3,'s','1',669140,2849),(121043,26,0,'n','1',669140,2726),(121044,26,1,'s','1',669140,2873),(121045,26,2,'s','1',669140,2878),(121046,26,3,'n','1',669140,2745),(121047,27,0,'n','1',669140,2726),(121048,27,1,'e','1',669140,2873),(121049,27,2,'w','1',669140,2964),(121050,27,3,'e','1',669140,2901),(121051,28,0,'w','1',669140,2730),(121052,28,1,'s','1',669140,2873),(121053,28,2,'e','1',669140,2781),(121054,28,3,'e','1',669140,2791),(121055,29,0,'n','1',669140,2875),(121056,29,1,'n','1',669140,2849),(121057,29,2,'n','1',669140,2804),(121058,29,3,'n','1',669140,2888),(121059,30,0,'e','1',669140,2851),(121060,30,1,'n','1',669140,2787),(121061,30,2,'e','1',669140,2788),(121062,30,3,'n','1',669140,2817),(121063,31,0,'s','1',669140,2726),(121064,31,1,'s','1',669140,2831),(121065,31,2,'n','1',669140,2789),(121066,31,3,'e','1',669140,2800),(121067,32,0,'n','1',669140,2960),(121068,32,1,'n','1',669140,3001),(121069,32,2,'w','1',669140,2985),(121070,32,3,'n','1',669140,2821),(121071,33,0,'n','1',669140,2815),(121072,33,1,'n','1',669140,2818),(121073,33,2,'n','1',669140,2968),(121074,33,3,'e','1',669140,2981),(121075,34,0,'e','1',669140,2829),(121076,34,1,'x','0',669140,2778),(121077,34,2,'n','1',669140,2720),(121078,34,3,'e','1',669140,2931),(121079,34,4,'n','1',669140,2878),(121080,35,0,'n','1',669140,2900),(121081,35,1,'n','1',669140,2767),(121082,35,2,'e','1',669140,2899),(121083,35,3,'w','1',669140,2885),(121084,36,0,'e','1',669140,2853),(121085,36,1,'e','1',669140,2899),(121086,36,2,'n','1',669140,3019),(121087,36,3,'e','1',669140,2885),(121088,37,0,'n','1',669140,2795),(121089,37,1,'w','1',669140,2796),(121090,37,2,'w','1',669140,2776),(121091,37,3,'w','1',669140,2794),(121092,38,0,'w','1',669140,2831),(121093,38,1,'n','1',669140,2781),(121094,38,2,'n','1',669140,2834),(121095,38,3,'n','1',669140,2823),(121096,39,0,'w','1',669140,2903),(121097,39,1,'n','1',669140,2797),(121098,39,2,'n','1',669140,2789),(121099,39,3,'n','1',669140,2795),(121100,40,0,'n','1',669140,2966),(121101,40,1,'e','1',669140,2950),(121102,40,2,'e','1',669140,2990),(121103,40,3,'e','1',669140,2861),(121104,41,0,'e','1',669140,2796),(121105,41,1,'n','1',669140,2761),(121106,41,2,'e','1',669140,2758),(121107,41,3,'n','1',669140,2934),(121108,42,0,'n','1',669140,2858),(121109,42,1,'n','1',669140,2902),(121110,42,2,'n','1',669140,2778),(121111,42,3,'n','1',669140,2794),(121112,43,0,'n','1',669140,2726),(121113,44,0,'w','1',669140,2873),(121114,45,0,'e','1',669140,3021),(121115,45,1,'s','1',669140,2873),(121116,45,2,'s','1',669140,2726),(121117,45,3,'e','1',669140,2720),(121118,46,0,'e','1',669140,2957),(121119,46,1,'e','1',669140,2913),(121120,46,2,'e','1',669140,2867),(121121,46,3,'e','1',669140,3003),(121122,47,0,'n','1',669140,2992),(121123,47,1,'w','1',669140,2959),(121124,47,2,'n','1',669140,2813),(121125,47,3,'n','1',669140,2842),(121126,48,0,'w','1',669140,2959),(121127,48,1,'s','1',669140,2738),(121128,49,0,'n','1',669140,2842),(121129,49,1,'w','1',669140,2738),(121130,49,2,'w','1',669140,2821),(121131,49,3,'n','1',669140,2745),(121132,2,0,'n','1',669141,2867),(121133,2,1,'n','1',669141,2816),(121134,2,2,'n','1',669141,2732),(121135,2,3,'n','1',669141,2717),(121136,3,0,'n','1',669141,2749),(121137,3,1,'w','1',669141,2765),(121138,3,2,'s','1',669141,2998),(121139,3,3,'n','1',669141,2962),(121140,4,0,'s','1',669141,2768),(121141,4,1,'w','1',669141,2750),(121142,4,2,'s','1',669141,2751),(121143,4,3,'s','1',669141,2845),(121144,5,0,'n','1',669141,2728),(121145,5,1,'n','1',669141,2965),(121146,5,2,'n','1',669141,2901),(121147,5,3,'e','1',669141,2903),(121148,6,0,'s','1',669141,2845),(121149,6,1,'n','1',669141,2779),(121150,6,2,'w','1',669141,2822),(121151,6,3,'w','1',669141,2858),(121152,7,0,'n','1',669141,2975),(121153,7,1,'w','1',669141,2908),(121154,7,2,'n','1',669141,2719),(121155,7,3,'w','1',669141,2772),(121156,8,0,'n','1',669141,2730),(121157,8,1,'e','1',669141,2845),(121158,8,2,'s','1',669141,2855),(121159,8,3,'n','1',669141,2962),(121160,9,0,'e','1',669141,2855),(121161,9,1,'s','1',669141,2954),(121162,9,2,'e','1',669141,2735),(121163,9,3,'e','1',669141,2872),(121164,10,0,'n','1',669141,2841),(121165,10,1,'w','1',669141,2772),(121166,10,2,'n','1',669141,2955),(121167,10,3,'n','1',669141,2780),(121168,11,0,'e','1',669141,2751),(121169,11,1,'s','1',669141,2750),(121170,11,2,'s','1',669141,2948),(121171,11,3,'n','1',669141,2779),(121172,12,0,'e','1',669141,2736),(121173,12,1,'e','1',669141,2883),(121174,12,2,'n','1',669141,2872),(121175,12,3,'w','1',669141,2822),(121176,13,0,'s','1',669141,2856),(121177,13,1,'n','1',669141,2877),(121178,13,2,'n','1',669141,2878),(121179,13,3,'n','1',669141,2781),(121180,14,0,'s','1',669141,2900),(121181,14,1,'s','1',669141,2866),(121182,14,2,'s','1',669141,2878),(121183,14,3,'s','1',669141,2862),(121184,15,0,'w','1',669141,2877),(121185,15,1,'e','1',669141,2968),(121186,15,2,'s','1',669141,2941),(121187,15,3,'w','1',669141,2969),(121188,16,0,'w','1',669141,2731),(121189,16,1,'w','1',669141,2730),(121190,16,2,'w','1',669141,2878),(121191,16,3,'n','1',669141,2753),(121192,17,0,'n','1',669141,2981),(121193,17,1,'s','1',669141,2904),(121194,17,2,'s','1',669141,2943),(121195,17,3,'s','1',669141,2861),(121196,18,0,'n','1',669141,2873),(121197,18,1,'e','1',669141,2871),(121198,18,2,'e','1',669141,2751),(121199,18,3,'s','1',669141,2906),(121200,19,0,'n','1',669141,2783),(121201,19,1,'e','1',669141,2886),(121202,19,2,'n','1',669141,2878),(121203,19,3,'n','1',669141,2900),(121204,20,0,'w','1',669141,2949),(121205,20,1,'w','1',669141,2955),(121206,20,2,'n','1',669141,2750),(121207,20,3,'e','1',669141,2927),(121208,21,0,'s','1',669141,2792),(121209,21,1,'s','1',669141,2767),(121210,21,2,'e','1',669141,2899),(121211,21,3,'n','1',669141,2962),(121212,22,0,'s','1',669141,2990),(121213,22,1,'s','1',669141,2851),(121214,22,2,'w','1',669141,2775),(121215,22,3,'w','1',669141,2784),(121216,23,0,'n','1',669141,2866),(121217,23,1,'w','1',669141,2885),(121218,23,2,'e','1',669141,2862),(121219,23,3,'s','1',669141,2899),(121220,24,0,'s','1',669141,2942),(121221,24,1,'w','1',669141,2900),(121222,24,2,'e','1',669141,2941),(121223,24,3,'s','1',669141,2904),(121224,25,0,'w','1',669141,2774),(121225,25,1,'s','1',669141,2768),(121226,25,2,'e','1',669141,2981),(121227,25,3,'w','1',669141,2973),(121228,26,0,'w','1',669141,2878),(121229,26,1,'e','1',669141,2981),(121230,26,2,'s','1',669141,2942),(121231,26,3,'n','1',669141,2915),(121232,27,0,'e','1',669141,2955),(121233,27,1,'e','1',669141,2949),(121234,27,2,'n','1',669141,2754),(121235,27,3,'n','1',669141,2834),(121236,28,0,'n','1',669141,2875),(121237,28,1,'n','1',669141,2849),(121238,28,2,'e','1',669141,2804),(121239,28,3,'n','1',669141,2917),(121240,29,0,'s','1',669141,2857),(121241,29,1,'e','1',669141,2878),(121242,29,2,'w','1',669141,2794),(121243,29,3,'s','1',669141,2879),(121244,30,0,'s','1',669141,2771),(121245,30,1,'e','1',669141,2969),(121246,30,2,'s','1',669141,2772),(121247,30,3,'n','1',669141,2888),(121248,31,0,'s','1',669141,2750),(121249,31,1,'s','1',669141,2794),(121250,31,2,'w','1',669141,2731),(121251,31,3,'n','1',669141,2817),(121252,32,0,'e','1',669141,2995),(121253,32,1,'n','1',669141,2763),(121254,32,2,'w','1',669141,2901),(121255,32,3,'e','1',669141,2952),(121256,33,0,'n','1',669141,2822),(121257,33,1,'n','1',669141,2857),(121258,33,2,'n','1',669141,2730),(121259,33,3,'w','1',669141,2903),(121260,34,0,'e','1',669141,2915),(121261,34,1,'e','1',669141,2965),(121262,34,2,'n','1',669141,2973),(121263,34,3,'x','0',669141,2803),(121264,34,4,'e','1',669141,3022),(121265,35,0,'w','1',669141,2794),(121266,35,1,'s','1',669141,2751),(121267,35,2,'w','1',669141,2797),(121268,35,3,'w','1',669141,2790),(121269,36,0,'n','1',669141,2730),(121270,36,1,'w','1',669141,2831),(121271,36,2,'s','1',669141,2830),(121272,36,3,'e','1',669141,2848),(121273,37,0,'w','1',669141,2858),(121274,37,1,'s','1',669141,2838),(121275,37,2,'w','1',669141,2782),(121276,37,3,'w','1',669141,2951),(121277,38,0,'w','1',669141,2786),(121278,38,1,'w','1',669141,2751),(121279,38,2,'s','1',669141,2871),(121280,38,3,'w','1',669141,2841),(121281,39,0,'e','1',669141,2902),(121282,39,1,'s','1',669141,2784),(121283,39,2,'w','1',669141,2996),(121284,39,3,'w','1',669141,2820),(121285,40,0,'e','1',669141,2872),(121286,40,1,'s','1',669141,2873),(121287,40,2,'n','1',669141,3022),(121288,40,3,'w','1',669141,2986),(121289,41,0,'s','1',669141,2997),(121290,41,1,'w','1',669141,2917),(121291,41,2,'s','1',669141,2804),(121292,41,3,'w','1',669141,2849),(121293,42,0,'w','1',669141,2908),(121294,42,1,'n','1',669141,2791),(121295,42,2,'n','1',669141,2772),(121296,42,3,'w','1',669141,2777),(121297,42,4,'x','0',669141,2778),(121298,43,0,'e','1',669141,2975),(121299,43,1,'e','1',669141,2841),(121300,43,2,'n','1',669141,2951),(121301,43,3,'e','1',669141,2726),(121302,2,0,'n','1',669141,2867),(121303,2,1,'n','1',669141,2816),(121304,2,2,'n','1',669141,2732),(121305,2,3,'n','1',669141,2717),(121306,3,0,'n','1',669141,2749),(121307,3,1,'w','1',669141,2765),(121308,3,2,'s','1',669141,2998),(121309,3,3,'n','1',669141,2962),(121310,4,0,'s','1',669141,2768),(121311,4,1,'w','1',669141,2750),(121312,4,2,'s','1',669141,2751),(121313,4,3,'s','1',669141,2845),(121314,5,0,'n','1',669141,2728),(121315,5,1,'n','1',669141,2965),(121316,5,2,'n','1',669141,2901),(121317,5,3,'e','1',669141,2903),(121318,6,0,'s','1',669141,2845),(121319,6,1,'n','1',669141,2779),(121320,6,2,'w','1',669141,2822),(121321,6,3,'w','1',669141,2858),(121322,7,0,'n','1',669141,2975),(121323,7,1,'w','1',669141,2908),(121324,7,2,'n','1',669141,2719),(121325,7,3,'w','1',669141,2772),(121326,8,0,'n','1',669141,2730),(121327,8,1,'e','1',669141,2845),(121328,8,2,'s','1',669141,2855),(121329,8,3,'n','1',669141,2962),(121330,9,0,'e','1',669141,2855),(121331,9,1,'s','1',669141,2954),(121332,9,2,'e','1',669141,2735),(121333,9,3,'e','1',669141,2872),(121334,10,0,'n','1',669141,2841),(121335,10,1,'w','1',669141,2772),(121336,10,2,'n','1',669141,2955),(121337,10,3,'n','1',669141,2780),(121338,11,0,'e','1',669141,2751),(121339,11,1,'s','1',669141,2750),(121340,11,2,'s','1',669141,2948),(121341,11,3,'n','1',669141,2779),(121342,12,0,'e','1',669141,2736),(121343,12,1,'e','1',669141,2883),(121344,12,2,'n','1',669141,2872),(121345,12,3,'w','1',669141,2822),(121346,13,0,'s','1',669141,2856),(121347,13,1,'n','1',669141,2877),(121348,13,2,'n','1',669141,2878),(121349,13,3,'n','1',669141,2781),(121350,14,0,'s','1',669141,2900),(121351,14,1,'s','1',669141,2866),(121352,14,2,'s','1',669141,2878),(121353,14,3,'s','1',669141,2862),(121354,15,0,'w','1',669141,2877),(121355,15,1,'e','1',669141,2968),(121356,15,2,'s','1',669141,2941),(121357,15,3,'w','1',669141,2969),(121358,16,0,'w','1',669141,2731),(121359,16,1,'w','1',669141,2730),(121360,16,2,'w','1',669141,2878),(121361,16,3,'n','1',669141,2753),(121362,17,0,'n','1',669141,2981),(121363,17,1,'s','1',669141,2904),(121364,17,2,'s','1',669141,2943),(121365,17,3,'s','1',669141,2861),(121366,18,0,'n','1',669141,2873),(121367,18,1,'e','1',669141,2871),(121368,18,2,'e','1',669141,2751),(121369,18,3,'s','1',669141,2906),(121370,19,0,'n','1',669141,2783),(121371,19,1,'e','1',669141,2886),(121372,19,2,'n','1',669141,2878),(121373,19,3,'n','1',669141,2900),(121374,20,0,'w','1',669141,2949),(121375,20,1,'w','1',669141,2955),(121376,20,2,'n','1',669141,2750),(121377,20,3,'e','1',669141,2927),(121378,21,0,'s','1',669141,2792),(121379,21,1,'s','1',669141,2767),(121380,21,2,'e','1',669141,2899),(121381,21,3,'n','1',669141,2962),(121382,22,0,'s','1',669141,2990),(121383,22,1,'s','1',669141,2851),(121384,22,2,'w','1',669141,2775),(121385,22,3,'w','1',669141,2784),(121386,23,0,'n','1',669141,2866),(121387,23,1,'w','1',669141,2885),(121388,23,2,'e','1',669141,2862),(121389,23,3,'s','1',669141,2899),(121390,24,0,'s','1',669141,2942),(121391,24,1,'w','1',669141,2900),(121392,24,2,'e','1',669141,2941),(121393,24,3,'s','1',669141,2904),(121394,25,0,'w','1',669141,2774),(121395,25,1,'s','1',669141,2768),(121396,25,2,'e','1',669141,2981),(121397,25,3,'w','1',669141,2973),(121398,26,0,'w','1',669141,2878),(121399,26,1,'e','1',669141,2981),(121400,26,2,'s','1',669141,2942),(121401,26,3,'n','1',669141,2915),(121402,27,0,'e','1',669141,2955),(121403,27,1,'e','1',669141,2949),(121404,27,2,'n','1',669141,2754),(121405,27,3,'n','1',669141,2834),(121406,28,0,'n','1',669141,2875),(121407,28,1,'n','1',669141,2849),(121408,28,2,'e','1',669141,2804),(121409,28,3,'n','1',669141,2917),(121410,29,0,'s','1',669141,2857),(121411,29,1,'e','1',669141,2878),(121412,29,2,'w','1',669141,2794),(121413,29,3,'s','1',669141,2879),(121414,30,0,'s','1',669141,2771),(121415,30,1,'e','1',669141,2969),(121416,30,2,'s','1',669141,2772),(121417,30,3,'n','1',669141,2888),(121418,31,0,'s','1',669141,2750),(121419,31,1,'s','1',669141,2794),(121420,31,2,'w','1',669141,2731),(121421,31,3,'n','1',669141,2817),(121422,32,0,'e','1',669141,2995),(121423,32,1,'n','1',669141,2763),(121424,32,2,'w','1',669141,2901),(121425,32,3,'e','1',669141,2952),(121426,33,0,'n','1',669141,2822),(121427,33,1,'n','1',669141,2857),(121428,33,2,'n','1',669141,2730),(121429,33,3,'w','1',669141,2903),(121430,34,0,'e','1',669141,2915),(121431,34,1,'e','1',669141,2965),(121432,34,2,'n','1',669141,2973),(121433,34,3,'x','0',669141,2803),(121434,34,4,'e','1',669141,3022),(121435,35,0,'w','1',669141,2794),(121436,35,1,'s','1',669141,2751),(121437,35,2,'w','1',669141,2797),(121438,35,3,'w','1',669141,2790),(121439,36,0,'n','1',669141,2730),(121440,36,1,'w','1',669141,2831),(121441,36,2,'s','1',669141,2830),(121442,36,3,'e','1',669141,2848),(121443,37,0,'w','1',669141,2858),(121444,37,1,'s','1',669141,2838),(121445,37,2,'w','1',669141,2782),(121446,37,3,'w','1',669141,2951),(121447,38,0,'w','1',669141,2786),(121448,38,1,'w','1',669141,2751),(121449,38,2,'s','1',669141,2871),(121450,38,3,'w','1',669141,2841),(121451,39,0,'e','1',669141,2902),(121452,39,1,'s','1',669141,2784),(121453,39,2,'w','1',669141,2996),(121454,39,3,'w','1',669141,2820),(121455,40,0,'e','1',669141,2872),(121456,40,1,'s','1',669141,2873),(121457,40,2,'n','1',669141,3022),(121458,40,3,'w','1',669141,2986),(121459,41,0,'s','1',669141,2997),(121460,41,1,'w','1',669141,2917),(121461,41,2,'s','1',669141,2804),(121462,41,3,'w','1',669141,2849),(121463,42,0,'w','1',669141,2908),(121464,42,1,'n','1',669141,2791),(121465,42,2,'n','1',669141,2772),(121466,42,3,'w','1',669141,2777),(121467,42,4,'x','0',669141,2778),(121468,43,0,'e','1',669141,2975),(121469,43,1,'e','1',669141,2841),(121470,43,2,'n','1',669141,2951),(121471,43,3,'e','1',669141,2726),(121472,2,0,'n','1',669142,2964),(121473,2,1,'n','1',669142,2728),(121474,2,2,'n','1',669142,2827),(121475,2,3,'n','1',669142,2841),(121476,3,0,'n','1',669142,2913),(121477,3,1,'n','1',669142,2874),(121478,3,2,'e','1',669142,2731),(121479,3,3,'e','1',669142,2732),(121480,4,0,'n','1',669142,2733),(121481,4,1,'e','1',669142,2759),(121482,4,2,'n','1',669142,2921),(121483,4,3,'s','1',669142,2734),(121484,5,0,'n','1',669142,2870),(121485,5,1,'w','1',669142,2733),(121486,5,2,'n','1',669142,2732),(121487,5,3,'n','1',669142,2749),(121488,6,0,'w','1',669142,2884),(121489,6,1,'w','1',669142,2735),(121490,6,2,'n','1',669142,2725),(121491,6,3,'s','1',669142,2877),(121492,7,0,'n','1',669142,2834),(121493,7,1,'n','1',669142,2823),(121494,7,2,'n','1',669142,2739),(121495,7,3,'w','1',669142,2855),(121496,8,0,'n','1',669142,2745),(121497,8,1,'e','1',669142,2872),(121498,8,2,'e','1',669142,2845),(121499,8,3,'n','1',669142,2855),(121500,9,0,'w','1',669142,2765),(121501,9,1,'w','1',669142,2768),(121502,9,2,'e','1',669142,2881),(121503,9,3,'e','1',669142,2900),(121504,10,0,'n','1',669142,2949),(121505,10,1,'w','1',669142,2768),(121506,10,2,'w','1',669142,2900),(121507,10,3,'w','1',669142,2881),(121508,11,0,'n','1',669142,2901),(121509,11,1,'n','1',669142,2866),(121510,11,2,'n','1',669142,2977),(121511,11,3,'s','1',669142,2983),(121512,12,0,'n','1',669142,2817),(121513,12,1,'n','1',669142,2977),(121514,12,2,'s','1',669142,3007),(121515,12,3,'e','1',669142,2983),(121516,13,0,'s','1',669142,2866),(121517,13,1,'w','1',669142,2893),(121518,13,2,'e','1',669142,2862),(121519,13,3,'s','1',669142,2983),(121520,14,0,'n','1',669142,2775),(121521,14,1,'e','1',669142,2772),(121522,14,2,'e','1',669142,2860),(121523,14,3,'n','1',669142,2876),(121524,15,0,'e','1',669142,2977),(121525,15,1,'s','1',669142,2857),(121526,15,2,'s','1',669142,2881),(121527,15,3,'n','1',669142,2840),(121528,16,0,'s','1',669142,2794),(121529,16,1,'x','0',669142,2778),(121530,16,2,'w','1',669142,2851),(121531,16,3,'n','1',669142,2752),(121532,16,4,'n','1',669142,3027),(121533,17,0,'s','1',669142,2785),(121534,17,1,'n','1',669142,2908),(121535,17,2,'e','1',669142,2784),(121536,17,3,'n','1',669142,2770),(121537,18,0,'n','1',669142,2962),(121538,18,1,'n','1',669142,2822),(121539,18,2,'n','1',669142,2829),(121540,18,3,'n','1',669142,2831),(121541,19,0,'w','1',669142,2858),(121542,19,1,'e','1',669142,2748),(121543,19,2,'w','1',669142,2755),(121544,19,3,'s','1',669142,2833),(121545,20,0,'n','1',669142,2927),(121546,20,1,'e','1',669142,2903),(121547,20,2,'e','1',669142,2779),(121548,20,3,'n','1',669142,2822),(121549,21,0,'e','1',669142,2748),(121550,21,1,'e','1',669142,2755),(121551,21,2,'e','1',669142,2756),(121552,21,3,'s','1',669142,2799),(121553,22,0,'w','1',669142,2962),(121554,22,1,'n','1',669142,2778),(121555,22,2,'s','1',669142,2861),(121556,22,3,'w','1',669142,2969),(121557,23,0,'w','1',669142,2949),(121558,23,1,'s','1',669142,2969),(121559,23,2,'w','1',669142,2955),(121560,23,3,'w','1',669142,3016),(121561,24,0,'n','1',669142,2901),(121562,24,1,'w','1',669142,2759),(121563,24,2,'w','1',669142,2805),(121564,24,3,'n','1',669142,2821),(121565,25,0,'w','1',669142,2824),(121566,25,1,'n','1',669142,2817),(121567,25,2,'w','1',669142,2762),(121568,25,3,'n','1',669142,2763),(121569,26,0,'w','1',669142,2966),(121570,26,1,'e','1',669142,2887),(121571,26,2,'e','1',669142,2779),(121572,26,3,'n','1',669142,2927),(121573,27,0,'s','1',669142,2921),(121574,27,1,'w','1',669142,2820),(121575,27,2,'w','1',669142,2737),(121576,27,3,'n','1',669142,2740),(121577,28,0,'n','1',669142,2762),(121578,28,1,'n','1',669142,2824),(121579,28,2,'w','1',669142,2756),(121580,28,3,'w','1',669142,2755),(121581,29,0,'n','1',669142,2822),(121582,29,1,'n','1',669142,2724),(121583,29,2,'e','1',669142,2829),(121584,29,3,'x','0',669142,2778),(121585,29,4,'n','1',669142,2753),(121586,30,0,'s','1',669142,2783),(121587,30,1,'s','1',669142,2820),(121588,30,2,'e','1',669142,2729),(121589,30,3,'e','1',669142,2761),(121590,31,0,'w','1',669142,2831),(121591,31,1,'n','1',669142,2781),(121592,31,2,'e','1',669142,2775),(121593,31,3,'w','1',669142,2754),(121594,32,0,'n','1',669142,2888),(121595,32,1,'e','1',669142,2748),(121596,32,2,'w','1',669142,2755),(121597,32,3,'s','1',669142,2833),(121598,33,0,'s','1',669142,2748),(121599,33,1,'w','1',669142,2788),(121600,33,2,'s','1',669142,2770),(121601,33,3,'s','1',669142,2792),(121602,34,0,'n','1',669142,2908),(121603,34,1,'e','1',669142,2770),(121604,34,2,'w','1',669142,2746),(121605,34,3,'s','1',669142,2788),(121606,35,0,'w','1',669142,2834),(121607,35,1,'n','1',669142,2736),(121608,35,2,'s','1',669142,2737),(121609,35,3,'s','1',669142,2960),(121610,36,0,'e','1',669142,2736),(121611,36,1,'s','1',669142,2754),(121612,36,2,'s','1',669142,2920),(121613,36,3,'e','1',669142,2770),(121614,37,0,'e','1',669142,2751),(121615,37,1,'x','0',669142,2859),(121616,37,2,'e','1',669142,2755),(121617,37,3,'e','1',669142,2756),(121618,37,4,'e','1',669142,2750),(121619,38,0,'e','1',669142,2948),(121620,38,1,'s','1',669142,2749),(121621,38,2,'s','1',669142,2850),(121622,38,3,'x','0',669142,2883),(121623,38,4,'e','1',669142,2732),(121624,39,0,'w','1',669142,2786),(121625,39,1,'e','1',669142,2733),(121626,39,2,'e','1',669142,2759),(121627,39,3,'s','1',669142,2842),(121628,40,0,'e','1',669142,2775),(121629,40,1,'w','1',669142,2813),(121630,40,2,'n','1',669142,2814),(121631,40,3,'n','1',669142,2733),(121632,41,0,'w','1',669142,2922),(121633,41,1,'n','1',669142,2721),(121634,41,2,'w','1',669142,2923),(121635,41,3,'x','0',669142,2803),(121636,41,4,'w','1',669142,2754),(121637,42,0,'n','1',669142,2779),(121638,42,1,'n','1',669142,2780),(121639,42,2,'w','1',669142,2736),(121640,42,3,'n','1',669142,2760),(121641,43,0,'e','1',669142,2759),(121642,43,1,'w','1',669142,2734),(121643,43,2,'e','1',669142,2852),(121644,43,3,'n','1',669142,2749),(121645,44,0,'n','1',669142,2781),(121646,44,1,'n','1',669142,2941),(121647,44,2,'n','1',669142,2942),(121648,44,3,'n','1',669142,2943),(121649,2,0,'n','1',669142,2964),(121650,2,1,'n','1',669142,2728),(121651,2,2,'n','1',669142,2827),(121652,2,3,'n','1',669142,2841),(121653,3,0,'n','1',669142,2913),(121654,3,1,'n','1',669142,2874),(121655,3,2,'e','1',669142,2731),(121656,3,3,'e','1',669142,2732),(121657,4,0,'n','1',669142,2733),(121658,4,1,'e','1',669142,2759),(121659,4,2,'n','1',669142,2921),(121660,4,3,'s','1',669142,2734),(121661,5,0,'n','1',669142,2870),(121662,5,1,'w','1',669142,2733),(121663,5,2,'n','1',669142,2732),(121664,5,3,'n','1',669142,2749),(121665,6,0,'w','1',669142,2884),(121666,6,1,'w','1',669142,2735),(121667,6,2,'n','1',669142,2725),(121668,6,3,'s','1',669142,2877),(121669,7,0,'n','1',669142,2834),(121670,7,1,'n','1',669142,2823),(121671,7,2,'n','1',669142,2739),(121672,7,3,'w','1',669142,2855),(121673,8,0,'n','1',669142,2745),(121674,8,1,'e','1',669142,2872),(121675,8,2,'e','1',669142,2845),(121676,8,3,'n','1',669142,2855),(121677,9,0,'w','1',669142,2765),(121678,9,1,'w','1',669142,2768),(121679,9,2,'e','1',669142,2881),(121680,9,3,'e','1',669142,2900),(121681,10,0,'n','1',669142,2949),(121682,10,1,'w','1',669142,2768),(121683,10,2,'w','1',669142,2900),(121684,10,3,'w','1',669142,2881),(121685,11,0,'n','1',669142,2901),(121686,11,1,'n','1',669142,2866),(121687,11,2,'n','1',669142,2977),(121688,11,3,'s','1',669142,2983),(121689,12,0,'n','1',669142,2817),(121690,12,1,'n','1',669142,2977),(121691,12,2,'s','1',669142,3007),(121692,12,3,'e','1',669142,2983),(121693,13,0,'s','1',669142,2866),(121694,13,1,'w','1',669142,2893),(121695,13,2,'e','1',669142,2862),(121696,13,3,'s','1',669142,2983),(121697,14,0,'n','1',669142,2775),(121698,14,1,'e','1',669142,2772),(121699,14,2,'e','1',669142,2860),(121700,14,3,'n','1',669142,2876),(121701,15,0,'e','1',669142,2977),(121702,15,1,'s','1',669142,2857),(121703,15,2,'s','1',669142,2881),(121704,15,3,'n','1',669142,2840),(121705,16,0,'s','1',669142,2794),(121706,16,1,'x','0',669142,2778),(121707,16,2,'w','1',669142,2851),(121708,16,3,'n','1',669142,2752),(121709,16,4,'n','1',669142,3027),(121710,17,0,'s','1',669142,2785),(121711,17,1,'n','1',669142,2908),(121712,17,2,'e','1',669142,2784),(121713,17,3,'n','1',669142,2770),(121714,18,0,'n','1',669142,2962),(121715,18,1,'n','1',669142,2822),(121716,18,2,'n','1',669142,2829),(121717,18,3,'n','1',669142,2831),(121718,19,0,'w','1',669142,2858),(121719,19,1,'e','1',669142,2748),(121720,19,2,'w','1',669142,2755),(121721,19,3,'s','1',669142,2833),(121722,20,0,'n','1',669142,2927),(121723,20,1,'e','1',669142,2903),(121724,20,2,'e','1',669142,2779),(121725,20,3,'n','1',669142,2822),(121726,21,0,'e','1',669142,2748),(121727,21,1,'e','1',669142,2755),(121728,21,2,'e','1',669142,2756),(121729,21,3,'s','1',669142,2799),(121730,22,0,'w','1',669142,2962),(121731,22,1,'n','1',669142,2778),(121732,22,2,'s','1',669142,2861),(121733,22,3,'w','1',669142,2969),(121734,23,0,'w','1',669142,2949),(121735,23,1,'s','1',669142,2969),(121736,23,2,'w','1',669142,2955),(121737,23,3,'w','1',669142,3016),(121738,24,0,'n','1',669142,2901),(121739,24,1,'w','1',669142,2759),(121740,24,2,'w','1',669142,2805),(121741,24,3,'n','1',669142,2821),(121742,25,0,'w','1',669142,2824),(121743,25,1,'n','1',669142,2817),(121744,25,2,'w','1',669142,2762),(121745,25,3,'n','1',669142,2763),(121746,26,0,'w','1',669142,2966),(121747,26,1,'e','1',669142,2887),(121748,26,2,'e','1',669142,2779),(121749,26,3,'n','1',669142,2927),(121750,27,0,'s','1',669142,2921),(121751,27,1,'w','1',669142,2820),(121752,27,2,'w','1',669142,2737),(121753,27,3,'n','1',669142,2740),(121754,28,0,'n','1',669142,2762),(121755,28,1,'n','1',669142,2824),(121756,28,2,'w','1',669142,2756),(121757,28,3,'w','1',669142,2755),(121758,29,0,'n','1',669142,2822),(121759,29,1,'n','1',669142,2724),(121760,29,2,'e','1',669142,2829),(121761,29,3,'x','0',669142,2778),(121762,29,4,'n','1',669142,2753),(121763,30,0,'s','1',669142,2783),(121764,30,1,'s','1',669142,2820),(121765,30,2,'e','1',669142,2729),(121766,30,3,'e','1',669142,2761),(121767,31,0,'w','1',669142,2831),(121768,31,1,'n','1',669142,2781),(121769,31,2,'e','1',669142,2775),(121770,31,3,'w','1',669142,2754),(121771,32,0,'n','1',669142,2888),(121772,32,1,'e','1',669142,2748),(121773,32,2,'w','1',669142,2755),(121774,32,3,'s','1',669142,2833),(121775,33,0,'s','1',669142,2748),(121776,33,1,'w','1',669142,2788),(121777,33,2,'s','1',669142,2770),(121778,33,3,'s','1',669142,2792),(121779,34,0,'n','1',669142,2908),(121780,34,1,'e','1',669142,2770),(121781,34,2,'w','1',669142,2746),(121782,34,3,'s','1',669142,2788),(121783,35,0,'w','1',669142,2834),(121784,35,1,'n','1',669142,2736),(121785,35,2,'s','1',669142,2737),(121786,35,3,'s','1',669142,2960),(121787,36,0,'e','1',669142,2736),(121788,36,1,'s','1',669142,2754),(121789,36,2,'s','1',669142,2920),(121790,36,3,'e','1',669142,2770),(121791,37,0,'e','1',669142,2751),(121792,37,1,'x','0',669142,2859),(121793,37,2,'e','1',669142,2755),(121794,37,3,'e','1',669142,2756),(121795,37,4,'e','1',669142,2750),(121796,38,0,'e','1',669142,2948),(121797,38,1,'s','1',669142,2749),(121798,38,2,'s','1',669142,2850),(121799,38,3,'x','0',669142,2883),(121800,38,4,'e','1',669142,2732),(121801,39,0,'w','1',669142,2786),(121802,39,1,'e','1',669142,2733),(121803,39,2,'e','1',669142,2759),(121804,39,3,'s','1',669142,2842),(121805,40,0,'e','1',669142,2775),(121806,40,1,'w','1',669142,2813),(121807,40,2,'n','1',669142,2814),(121808,40,3,'n','1',669142,2733),(121809,41,0,'w','1',669142,2922),(121810,41,1,'n','1',669142,2721),(121811,41,2,'w','1',669142,2923),(121812,41,3,'x','0',669142,2803),(121813,41,4,'w','1',669142,2754),(121814,42,0,'n','1',669142,2779),(121815,42,1,'n','1',669142,2780),(121816,42,2,'w','1',669142,2736),(121817,42,3,'n','1',669142,2760),(121818,43,0,'e','1',669142,2759),(121819,43,1,'w','1',669142,2734),(121820,43,2,'e','1',669142,2852),(121821,43,3,'n','1',669142,2749),(121822,44,0,'n','1',669142,2781),(121823,44,1,'n','1',669142,2941),(121824,44,2,'n','1',669142,2942),(121825,44,3,'n','1',669142,2943),(121826,2,0,'n','1',669143,2913),(121827,2,1,'n','1',669143,2874),(121828,2,2,'n','1',669143,2731),(121829,2,3,'n','1',669143,2964),(121830,3,0,'n','1',669143,2872),(121831,3,1,'n','1',669143,2877),(121832,3,2,'n','1',669143,2878),(121833,3,3,'n','1',669143,2750),(121834,4,0,'n','1',669143,2779),(121835,4,1,'n','1',669143,2728),(121836,4,2,'w','1',669143,2736),(121837,4,3,'w','1',669143,2760),(121838,5,0,'w','1',669143,2986),(121839,5,1,'n','1',669143,2827),(121840,5,2,'e','1',669143,2884),(121841,5,3,'e','1',669143,2883),(121842,6,0,'n','1',669143,2969),(121843,6,1,'w','1',669143,2784),(121844,6,2,'w','1',669143,2973),(121845,6,3,'w','1',669143,2834),(121846,7,0,'w','1',669143,2915),(121847,7,1,'w','1',669143,2739),(121848,7,2,'n','1',669143,2841),(121849,7,3,'e','1',669143,2949),(121850,8,0,'e','1',669143,2768),(121851,8,1,'s','1',669143,3019),(121852,8,2,'s','1',669143,2911),(121853,8,3,'w','1',669143,2765),(121854,9,0,'w','1',669143,2907),(121855,9,1,'s','1',669143,2768),(121856,9,2,'s','1',669143,2932),(121857,9,3,'w','1',669143,2750),(121858,10,0,'s','1',669143,2946),(121859,10,1,'x','0',669143,2950),(121860,10,2,'s','1',669143,2751),(121861,10,3,'n','1',669143,2730),(121862,10,4,'n','1',669143,2780),(121863,11,0,'e','1',669143,2751),(121864,11,1,'n','1',669143,2750),(121865,11,2,'n','1',669143,2781),(121866,11,3,'e','1',669143,2975),(121867,12,0,'n','1',669143,2768),(121868,12,1,'w','1',669143,2970),(121869,12,2,'s','1',669143,2764),(121870,12,3,'s','1',669143,2890),(121871,13,0,'e','1',669143,2904),(121872,13,1,'e','1',669143,2900),(121873,13,2,'e','1',669143,3007),(121874,13,3,'n','1',669143,2880),(121875,14,0,'n','1',669143,2783),(121876,14,1,'w','1',669143,2840),(121877,14,2,'n','1',669143,2848),(121878,15,0,'n','1',669143,2768),(121879,15,1,'s','1',669143,3007),(121880,15,2,'w','1',669143,2890),(121881,15,3,'e','1',669143,2830),(121882,16,0,'e','1',669143,2893),(121883,16,1,'w','1',669143,2860),(121884,16,2,'s','1',669143,2890),(121885,16,3,'s','1',669143,2792),(121886,17,0,'w','1',669143,2851),(121887,17,1,'w','1',669143,2785),(121888,17,2,'w','1',669143,2848),(121889,17,3,'e','1',669143,2941),(121890,18,0,'n','1',669143,2847),(121891,18,1,'s','1',669143,2835),(121892,18,2,'s','1',669143,2942),(121893,19,0,'e','1',669143,2847),(121894,19,1,'s','1',669143,2941),(121895,19,2,'s','1',669143,2781),(121896,19,3,'w','1',669143,2848),(121897,20,0,'n','1',669143,2847),(121898,20,1,'s','1',669143,2835),(121899,20,2,'s','1',669143,2942),(121900,21,0,'e','1',669143,2780),(121901,21,1,'s','1',669143,2847),(121902,21,2,'e','1',669143,2829),(121903,21,3,'x','0',669143,2778),(121904,21,4,'e','1',669143,3006),(121905,22,0,'w','1',669143,2783),(121906,22,1,'n','1',669143,3006),(121907,22,2,'e','1',669143,2847),(121908,22,3,'s','1',669143,2941),(121909,23,0,'s','1',669143,2781),(121910,23,1,'w','1',669143,2848),(121911,23,2,'w','1',669143,2908),(121912,23,3,'n','1',669143,2772),(121913,24,0,'w','1',669143,2771),(121914,24,1,'n','1',669143,2877),(121915,24,2,'e','1',669143,2878),(121916,24,3,'s','1',669143,2886),(121917,25,0,'w','1',669143,2879),(121918,25,1,'e','1',669143,2780),(121919,25,2,'s','1',669143,2847),(121920,26,0,'e','1',669143,2829),(121921,26,1,'x','0',669143,2778),(121922,26,2,'e','1',669143,3006),(121923,26,3,'s','1',669143,2835),(121924,26,4,'w','1',669143,2878),(121925,27,0,'n','1',669143,2768),(121926,27,1,'n','1',669143,2890),(121927,27,2,'w','1',669143,3028),(121928,27,3,'w','1',669143,2898),(121929,28,0,'s','1',669143,2891),(121930,28,1,'s','1',669143,2890),(121931,28,2,'e','1',669143,2981),(121932,28,3,'w','1',669143,2841),(121933,29,0,'e','1',669143,2862),(121934,29,1,'x','0',669143,2859),(121935,29,2,'n','1',669143,2878),(121936,29,3,'n','1',669143,2975),(121937,29,4,'n','1',669143,2955),(121938,30,0,'n','1',669143,2990),(121939,30,1,'w','1',669143,2875),(121940,30,2,'w','1',669143,2883),(121941,30,3,'w','1',669143,2884),(121942,31,0,'e','1',669143,2735),(121943,31,1,'s','1',669143,2768),(121944,31,2,'w','1',669143,2750),(121945,31,3,'n','1',669143,2888),(121946,32,0,'w','1',669143,2884),(121947,32,1,'s','1',669143,2735),(121948,32,2,'n','1',669143,2995),(121949,32,3,'x','0',669143,2772),(121950,32,4,'w','1',669143,2828),(121951,33,0,'e','1',669143,2945),(121952,33,1,'n','1',669143,2828),(121953,33,2,'e','1',669143,2735),(121954,33,3,'e','1',669143,3006),(121955,34,0,'n','1',669143,2884),(121956,34,1,'n','1',669143,2740),(121957,34,2,'e','1',669143,2948),(121958,34,3,'s','1',669143,2906),(121959,35,0,'e','1',669143,2850),(121960,35,1,'s','1',669143,2756),(121961,35,2,'w','1',669143,2740),(121962,35,3,'w','1',669143,2849),(121963,36,0,'w','1',669143,2850),(121964,36,1,'s','1',669143,2986),(121965,36,2,'s','1',669143,2948),(121966,36,3,'n','1',669143,2903),(121967,37,0,'w','1',669143,2901),(121968,37,1,'n','1',669143,2858),(121969,37,2,'n','1',669143,2902),(121970,37,3,'n','1',669143,2778),(121971,38,0,'w','1',669143,2990),(121972,38,1,'s','1',669143,2776),(121973,38,2,'s','1',669143,2950),(121974,38,3,'w','1',669143,2777),(121975,38,4,'x','0',669143,2778),(121976,39,0,'n','1',669143,2903),(121977,39,1,'n','1',669143,2884),(121978,39,2,'s','1',669143,2948),(121979,39,3,'w','1',669143,2802),(121980,40,0,'e','1',669143,2943),(121981,40,1,'s','1',669143,3029),(121982,40,2,'s','1',669143,2904),(121983,40,3,'e','1',669143,2781),(121984,41,0,'s','1',669143,2981),(121985,41,1,'s','1',669143,2968),(121986,41,2,'s','1',669143,2818),(121987,41,3,'e','1',669143,2815),(121988,42,0,'e','1',669143,2950),(121989,42,1,'n','1',669143,2969),(121990,42,2,'x','0',669143,2784),(121991,42,3,'e','1',669143,2964),(121992,42,4,'e','1',669143,2794),(121993,43,0,'e','1',669143,2762),(121994,43,1,'s','1',669143,2884),(121995,43,2,'n','1',669143,2827),(121996,43,3,'w','1',669143,2996),(121997,44,0,'n','1',669143,2762),(121998,44,1,'s','1',669143,2990),(121999,44,2,'n','1',669143,2884),(122000,44,3,'n','1',669143,3022),(122001,45,0,'w','1',669143,2986),(122002,45,1,'s','1',669143,2948),(122003,45,2,'e','1',669143,2955),(122004,45,3,'e','1',669143,2949),(122005,46,0,'w','1',669143,2908),(122006,46,1,'x','0',669143,2772),(122007,46,2,'w','1',669143,2884),(122008,46,3,'e','1',669143,2735),(122009,46,4,'w','1',669143,2831),(122010,47,0,'s','1',669143,2934),(122011,47,1,'e','1',669143,2751),(122012,47,2,'n','1',669143,2750),(122013,47,3,'n','1',669143,2781),(122014,48,0,'e','1',669143,2943),(122015,48,1,'n','1',669143,2904),(122016,48,2,'n','1',669143,3030),(122017,48,3,'w','1',669143,2776),(122018,49,0,'n','1',669143,2901),(122019,49,1,'e','1',669143,2903),(122020,49,2,'n','1',669143,2884),(122021,49,3,'e','1',669143,2948),(122022,50,0,'e','1',669143,2962),(122023,50,1,'e','1',669143,2858),(122024,50,2,'e','1',669143,2901),(122025,50,3,'e','1',669143,2790),(122026,51,0,'w','1',669143,2762),(122027,51,1,'s','1',669143,2850),(122028,51,2,'e','1',669143,2883),(122029,51,3,'e','1',669143,2995),(122030,52,0,'s','1',669143,2943),(122031,52,1,'s','1',669143,3029),(122032,52,2,'n','1',669143,3030),(122033,52,3,'n','1',669143,2965),(122034,53,0,'e','1',669143,3029),(122035,53,1,'e','1',669143,2898),(122036,53,2,'s','1',669143,2767),(122037,53,3,'s','1',669143,3028),(122038,54,0,'w','1',669143,2885),(122039,54,1,'e','1',669143,2862),(122040,54,2,'s','1',669143,2899),(122041,54,3,'w','1',669143,2840),(122042,55,0,'s','1',669143,2768),(122043,55,1,'w','1',669143,2794),(122044,55,2,'s','1',669143,2857),(122045,55,3,'w','1',669143,2750),(122046,56,0,'s','1',669143,2794),(122047,56,1,'x','0',669143,2778),(122048,56,2,'s','1',669143,2751),(122049,56,3,'n','1',669143,2730),(122050,56,4,'w','1',669143,2797),(122051,57,0,'w','1',669143,2875),(122052,57,1,'e','1',669143,2883),(122053,57,2,'s','1',669143,2802),(122054,57,3,'x','0',669143,2803),(122055,57,4,'e','1',669143,2831),(122056,58,0,'w','1',669143,2783),(122057,58,1,'n','1',669143,3006),(122058,58,2,'n','1',669143,2847),(122059,58,3,'w','1',669143,2790),(122060,59,0,'w','1',669143,2830),(122061,59,1,'s','1',669143,2835),(122062,59,2,'s','1',669143,2942),(122063,59,3,'w','1',669143,2858),(122064,60,0,'s','1',669143,2875),(122065,60,1,'w','1',669143,2823),(122066,60,2,'w','1',669143,2824),(122067,60,3,'x','0',669143,2762),(122068,60,4,'n','1',669143,2868),(122069,61,0,'e','1',669143,2751),(122070,61,1,'n','1',669143,2750),(122071,61,2,'s','1',669143,2847),(122072,61,3,'e','1',669143,3006),(122073,62,0,'e','1',669143,2794),(122074,62,1,'s','1',669143,2768),(122075,62,2,'s','1',669143,2857),(122076,62,3,'w','1',669143,2750),(122077,63,0,'s','1',669143,2794),(122078,63,1,'x','0',669143,2778),(122079,63,2,'s','1',669143,2751),(122080,63,3,'n','1',669143,2730),(122081,63,4,'w','1',669143,2831),(122082,64,0,'e','1',669143,2751),(122083,64,1,'n','1',669143,2750),(122084,64,2,'n','1',669143,2875),(122085,64,3,'e','1',669143,2776),(122086,65,0,'e','1',669143,2768),(122087,65,1,'w','1',669143,2765),(122088,65,2,'s','1',669143,2998),(122089,65,3,'n','1',669143,2849),(122090,66,0,'n','1',669143,2781),(122091,66,1,'n','1',669143,2904),(122092,66,2,'n','1',669143,3030),(122093,66,3,'w','1',669143,2796),(122094,67,0,'w','1',669143,2776),(122095,67,1,'w','1',669143,2794),(122096,67,2,'w','1',669143,2831),(122097,67,3,'n','1',669143,2781),(122098,68,0,'s','1',669143,2768),(122099,68,1,'n','1',669143,2750),(122100,68,2,'e','1',669143,2857),(122101,68,3,'n','1',669143,2941),(122102,69,0,'e','1',669143,2935),(122103,69,1,'x','0',669143,2809),(122104,69,2,'e','1',669143,2768),(122105,69,3,'w','1',669143,2765),(122106,69,4,'n','1',669143,2804),(122107,70,0,'e','1',669143,2840),(122108,70,1,'n','1',669143,2857),(122109,70,2,'n','1',669143,2859),(122110,70,3,'e','1',669143,3029),(122111,71,0,'e','1',669143,2862),(122112,71,1,'n','1',669143,2859),(122113,71,2,'n','1',669143,2768),(122114,71,3,'n','1',669143,2767),(122115,2,0,'n','1',669143,2913),(122116,2,1,'n','1',669143,2874),(122117,2,2,'n','1',669143,2731),(122118,2,3,'n','1',669143,2964),(122119,3,0,'n','1',669143,2872),(122120,3,1,'n','1',669143,2877),(122121,3,2,'n','1',669143,2878),(122122,3,3,'n','1',669143,2750),(122123,4,0,'n','1',669143,2779),(122124,4,1,'n','1',669143,2728),(122125,4,2,'w','1',669143,2736),(122126,4,3,'w','1',669143,2760),(122127,5,0,'w','1',669143,2986),(122128,5,1,'n','1',669143,2827),(122129,5,2,'e','1',669143,2884),(122130,5,3,'e','1',669143,2883),(122131,6,0,'n','1',669143,2969),(122132,6,1,'w','1',669143,2784),(122133,6,2,'w','1',669143,2973),(122134,6,3,'w','1',669143,2834),(122135,7,0,'w','1',669143,2915),(122136,7,1,'w','1',669143,2739),(122137,7,2,'n','1',669143,2841),(122138,7,3,'e','1',669143,2949),(122139,8,0,'e','1',669143,2768),(122140,8,1,'s','1',669143,3019),(122141,8,2,'s','1',669143,2911),(122142,8,3,'w','1',669143,2765),(122143,9,0,'w','1',669143,2907),(122144,9,1,'s','1',669143,2768),(122145,9,2,'s','1',669143,2932),(122146,9,3,'w','1',669143,2750),(122147,10,0,'s','1',669143,2946),(122148,10,1,'x','0',669143,2950),(122149,10,2,'s','1',669143,2751),(122150,10,3,'n','1',669143,2730),(122151,10,4,'n','1',669143,2780),(122152,11,0,'e','1',669143,2751),(122153,11,1,'n','1',669143,2750),(122154,11,2,'n','1',669143,2781),(122155,11,3,'e','1',669143,2975),(122156,12,0,'n','1',669143,2768),(122157,12,1,'w','1',669143,2970),(122158,12,2,'s','1',669143,2764),(122159,12,3,'s','1',669143,2890),(122160,13,0,'e','1',669143,2904),(122161,13,1,'e','1',669143,2900),(122162,13,2,'e','1',669143,3007),(122163,13,3,'n','1',669143,2880),(122164,14,0,'n','1',669143,2783),(122165,14,1,'w','1',669143,2840),(122166,14,2,'n','1',669143,2848),(122167,15,0,'n','1',669143,2768),(122168,15,1,'s','1',669143,3007),(122169,15,2,'w','1',669143,2890),(122170,15,3,'e','1',669143,2830),(122171,16,0,'e','1',669143,2893),(122172,16,1,'w','1',669143,2860),(122173,16,2,'s','1',669143,2890),(122174,16,3,'s','1',669143,2792),(122175,17,0,'w','1',669143,2851),(122176,17,1,'w','1',669143,2785),(122177,17,2,'w','1',669143,2848),(122178,17,3,'e','1',669143,2941),(122179,18,0,'n','1',669143,2847),(122180,18,1,'s','1',669143,2835),(122181,18,2,'s','1',669143,2942),(122182,19,0,'e','1',669143,2847),(122183,19,1,'s','1',669143,2941),(122184,19,2,'s','1',669143,2781),(122185,19,3,'w','1',669143,2848),(122186,20,0,'n','1',669143,2847),(122187,20,1,'s','1',669143,2835),(122188,20,2,'s','1',669143,2942),(122189,21,0,'e','1',669143,2780),(122190,21,1,'s','1',669143,2847),(122191,21,2,'e','1',669143,2829),(122192,21,3,'x','0',669143,2778),(122193,21,4,'e','1',669143,3006),(122194,22,0,'w','1',669143,2783),(122195,22,1,'n','1',669143,3006),(122196,22,2,'e','1',669143,2847),(122197,22,3,'s','1',669143,2941),(122198,23,0,'s','1',669143,2781),(122199,23,1,'w','1',669143,2848),(122200,23,2,'w','1',669143,2908),(122201,23,3,'n','1',669143,2772),(122202,24,0,'w','1',669143,2771),(122203,24,1,'n','1',669143,2877),(122204,24,2,'e','1',669143,2878),(122205,24,3,'s','1',669143,2886),(122206,25,0,'w','1',669143,2879),(122207,25,1,'e','1',669143,2780),(122208,25,2,'s','1',669143,2847),(122209,26,0,'e','1',669143,2829),(122210,26,1,'x','0',669143,2778),(122211,26,2,'e','1',669143,3006),(122212,26,3,'s','1',669143,2835),(122213,26,4,'w','1',669143,2878),(122214,27,0,'n','1',669143,2768),(122215,27,1,'n','1',669143,2890),(122216,27,2,'w','1',669143,3028),(122217,27,3,'w','1',669143,2898),(122218,28,0,'s','1',669143,2891),(122219,28,1,'s','1',669143,2890),(122220,28,2,'e','1',669143,2981),(122221,28,3,'w','1',669143,2841),(122222,29,0,'e','1',669143,2862),(122223,29,1,'x','0',669143,2859),(122224,29,2,'n','1',669143,2878),(122225,29,3,'n','1',669143,2975),(122226,29,4,'n','1',669143,2955),(122227,30,0,'n','1',669143,2990),(122228,30,1,'w','1',669143,2875),(122229,30,2,'w','1',669143,2883),(122230,30,3,'w','1',669143,2884),(122231,31,0,'e','1',669143,2735),(122232,31,1,'s','1',669143,2768),(122233,31,2,'w','1',669143,2750),(122234,31,3,'n','1',669143,2888),(122235,32,0,'w','1',669143,2884),(122236,32,1,'s','1',669143,2735),(122237,32,2,'n','1',669143,2995),(122238,32,3,'x','0',669143,2772),(122239,32,4,'w','1',669143,2828),(122240,33,0,'e','1',669143,2945),(122241,33,1,'n','1',669143,2828),(122242,33,2,'e','1',669143,2735),(122243,33,3,'e','1',669143,3006),(122244,34,0,'n','1',669143,2884),(122245,34,1,'n','1',669143,2740),(122246,34,2,'e','1',669143,2948),(122247,34,3,'s','1',669143,2906),(122248,35,0,'e','1',669143,2850),(122249,35,1,'s','1',669143,2756),(122250,35,2,'w','1',669143,2740),(122251,35,3,'w','1',669143,2849),(122252,36,0,'w','1',669143,2850),(122253,36,1,'s','1',669143,2986),(122254,36,2,'s','1',669143,2948),(122255,36,3,'n','1',669143,2903),(122256,37,0,'w','1',669143,2901),(122257,37,1,'n','1',669143,2858),(122258,37,2,'n','1',669143,2902),(122259,37,3,'n','1',669143,2778),(122260,38,0,'w','1',669143,2990),(122261,38,1,'s','1',669143,2776),(122262,38,2,'s','1',669143,2950),(122263,38,3,'w','1',669143,2777),(122264,38,4,'x','0',669143,2778),(122265,39,0,'n','1',669143,2903),(122266,39,1,'n','1',669143,2884),(122267,39,2,'s','1',669143,2948),(122268,39,3,'w','1',669143,2802),(122269,40,0,'e','1',669143,2943),(122270,40,1,'s','1',669143,3029),(122271,40,2,'s','1',669143,2904),(122272,40,3,'e','1',669143,2781),(122273,41,0,'s','1',669143,2981),(122274,41,1,'s','1',669143,2968),(122275,41,2,'s','1',669143,2818),(122276,41,3,'e','1',669143,2815),(122277,42,0,'e','1',669143,2950),(122278,42,1,'n','1',669143,2969),(122279,42,2,'x','0',669143,2784),(122280,42,3,'e','1',669143,2964),(122281,42,4,'e','1',669143,2794),(122282,43,0,'e','1',669143,2762),(122283,43,1,'s','1',669143,2884),(122284,43,2,'n','1',669143,2827),(122285,43,3,'w','1',669143,2996),(122286,44,0,'n','1',669143,2762),(122287,44,1,'s','1',669143,2990),(122288,44,2,'n','1',669143,2884),(122289,44,3,'n','1',669143,3022),(122290,45,0,'w','1',669143,2986),(122291,45,1,'s','1',669143,2948),(122292,45,2,'e','1',669143,2955),(122293,45,3,'e','1',669143,2949),(122294,46,0,'w','1',669143,2908),(122295,46,1,'x','0',669143,2772),(122296,46,2,'w','1',669143,2884),(122297,46,3,'e','1',669143,2735),(122298,46,4,'w','1',669143,2831),(122299,47,0,'s','1',669143,2934),(122300,47,1,'e','1',669143,2751),(122301,47,2,'n','1',669143,2750),(122302,47,3,'n','1',669143,2781),(122303,48,0,'e','1',669143,2943),(122304,48,1,'n','1',669143,2904),(122305,48,2,'n','1',669143,3030),(122306,48,3,'w','1',669143,2776),(122307,49,0,'n','1',669143,2901),(122308,49,1,'e','1',669143,2903),(122309,49,2,'n','1',669143,2884),(122310,49,3,'e','1',669143,2948),(122311,50,0,'e','1',669143,2962),(122312,50,1,'e','1',669143,2858),(122313,50,2,'e','1',669143,2901),(122314,50,3,'e','1',669143,2790),(122315,51,0,'w','1',669143,2762),(122316,51,1,'s','1',669143,2850),(122317,51,2,'e','1',669143,2883),(122318,51,3,'e','1',669143,2995),(122319,52,0,'s','1',669143,2943),(122320,52,1,'s','1',669143,3029),(122321,52,2,'n','1',669143,3030),(122322,52,3,'n','1',669143,2965),(122323,53,0,'e','1',669143,3029),(122324,53,1,'e','1',669143,2898),(122325,53,2,'s','1',669143,2767),(122326,53,3,'s','1',669143,3028),(122327,54,0,'w','1',669143,2885),(122328,54,1,'e','1',669143,2862),(122329,54,2,'s','1',669143,2899),(122330,54,3,'w','1',669143,2840),(122331,55,0,'s','1',669143,2768),(122332,55,1,'w','1',669143,2794),(122333,55,2,'s','1',669143,2857),(122334,55,3,'w','1',669143,2750),(122335,56,0,'s','1',669143,2794),(122336,56,1,'x','0',669143,2778),(122337,56,2,'s','1',669143,2751),(122338,56,3,'n','1',669143,2730),(122339,56,4,'w','1',669143,2797),(122340,57,0,'w','1',669143,2875),(122341,57,1,'e','1',669143,2883),(122342,57,2,'s','1',669143,2802),(122343,57,3,'x','0',669143,2803),(122344,57,4,'e','1',669143,2831),(122345,58,0,'w','1',669143,2783),(122346,58,1,'n','1',669143,3006),(122347,58,2,'n','1',669143,2847),(122348,58,3,'w','1',669143,2790),(122349,59,0,'w','1',669143,2830),(122350,59,1,'s','1',669143,2835),(122351,59,2,'s','1',669143,2942),(122352,59,3,'w','1',669143,2858),(122353,60,0,'s','1',669143,2875),(122354,60,1,'w','1',669143,2823),(122355,60,2,'w','1',669143,2824),(122356,60,3,'x','0',669143,2762),(122357,60,4,'n','1',669143,2868),(122358,61,0,'e','1',669143,2751),(122359,61,1,'n','1',669143,2750),(122360,61,2,'s','1',669143,2847),(122361,61,3,'e','1',669143,3006),(122362,62,0,'e','1',669143,2794),(122363,62,1,'s','1',669143,2768),(122364,62,2,'s','1',669143,2857),(122365,62,3,'w','1',669143,2750),(122366,63,0,'s','1',669143,2794),(122367,63,1,'x','0',669143,2778),(122368,63,2,'s','1',669143,2751),(122369,63,3,'n','1',669143,2730),(122370,63,4,'w','1',669143,2831),(122371,64,0,'e','1',669143,2751),(122372,64,1,'n','1',669143,2750),(122373,64,2,'n','1',669143,2875),(122374,64,3,'e','1',669143,2776),(122375,65,0,'e','1',669143,2768),(122376,65,1,'w','1',669143,2765),(122377,65,2,'s','1',669143,2998),(122378,65,3,'n','1',669143,2849),(122379,66,0,'n','1',669143,2781),(122380,66,1,'n','1',669143,2904),(122381,66,2,'n','1',669143,3030),(122382,66,3,'w','1',669143,2796),(122383,67,0,'w','1',669143,2776),(122384,67,1,'w','1',669143,2794),(122385,67,2,'w','1',669143,2831),(122386,67,3,'n','1',669143,2781),(122387,68,0,'s','1',669143,2768),(122388,68,1,'n','1',669143,2750),(122389,68,2,'e','1',669143,2857),(122390,68,3,'n','1',669143,2941),(122391,69,0,'e','1',669143,2935),(122392,69,1,'x','0',669143,2809),(122393,69,2,'e','1',669143,2768),(122394,69,3,'w','1',669143,2765),(122395,69,4,'n','1',669143,2804),(122396,70,0,'e','1',669143,2840),(122397,70,1,'n','1',669143,2857),(122398,70,2,'n','1',669143,2859),(122399,70,3,'e','1',669143,3029),(122400,71,0,'e','1',669143,2862),(122401,71,1,'n','1',669143,2859),(122402,71,2,'n','1',669143,2768),(122403,71,3,'n','1',669143,2767),(122404,2,0,'n','1',669144,2913),(122405,2,1,'n','1',669144,2874),(122406,2,2,'n','1',669144,2731),(122407,2,3,'n','1',669144,2750),(122408,3,0,'n','1',669144,2964),(122409,3,1,'n','1',669144,2728),(122410,3,2,'w','1',669144,2827),(122411,3,3,'s','1',669144,2768),(122412,4,0,'e','1',669144,2828),(122413,4,1,'n','1',669144,2975),(122414,4,2,'w','1',669144,2750),(122415,4,3,'w','1',669144,2751),(122416,5,0,'n','1',669144,2827),(122417,5,1,'e','1',669144,2772),(122418,5,2,'s','1',669144,2871),(122419,5,3,'s','1',669144,2900),(122420,6,0,'n','1',669144,2873),(122421,6,1,'e','1',669144,2871),(122422,6,2,'n','1',669144,2908),(122423,6,3,'w','1',669144,2770),(122424,7,0,'n','1',669144,2841),(122425,7,1,'e','1',669144,2751),(122426,7,2,'s','1',669144,2770),(122427,7,3,'s','1',669144,2750),(122428,8,0,'n','1',669144,2731),(122429,8,1,'n','1',669144,2750),(122430,8,2,'w','1',669144,2969),(122431,8,3,'w','1',669144,2955),(122432,9,0,'e','1',669144,2884),(122433,9,1,'s','1',669144,2768),(122434,9,2,'w','1',669144,2750),(122435,9,3,'s','1',669144,2751),(122436,10,0,'n','1',669144,2736),(122437,10,1,'w','1',669144,2730),(122438,10,2,'w','1',669144,2872),(122439,10,3,'s','1',669144,2873),(122440,11,0,'n','1',669144,2883),(122441,11,1,'s','1',669144,2737),(122442,11,2,'e','1',669144,2850),(122443,11,3,'s','1',669144,2965),(122444,12,0,'w','1',669144,2949),(122445,12,1,'e','1',669144,3031),(122446,12,2,'n','1',669144,3032),(122447,12,3,'s','1',669144,2955),(122448,13,0,'n','1',669144,2975),(122449,13,1,'e','1',669144,2973),(122450,13,2,'w','1',669144,2958),(122451,13,3,'w','1',669144,2903),(122452,14,0,'n','1',669144,3022),(122453,14,1,'w','1',669144,2973),(122454,14,2,'e','1',669144,2797),(122455,15,0,'n','1',669144,2986),(122456,15,1,'w','1',669144,2849),(122457,15,2,'e','1',669144,2915),(122458,15,3,'n','1',669144,2736),(122459,16,0,'s','1',669144,2746),(122460,16,1,'s','1',669144,2737),(122461,16,2,'e','1',669144,2850),(122462,16,3,'w','1',669144,2973),(122463,17,0,'e','1',669144,2986),(122464,17,1,'w','1',669144,2915),(122465,17,2,'s','1',669144,2760),(122466,17,3,'e','1',669144,2739),(122467,18,0,'e','1',669144,2950),(122468,18,1,'n','1',669144,2726),(122469,18,2,'e','1',669144,2785),(122470,18,3,'e','1',669144,2873),(122471,19,0,'s','1',669144,2950),(122472,19,1,'w','1',669144,2730),(122473,19,2,'s','1',669144,2873),(122474,19,3,'e','1',669144,2781),(122475,20,0,'e','1',669144,2950),(122476,20,1,'w','1',669144,2849),(122477,20,2,'w','1',669144,2915),(122478,21,0,'e','1',669144,2753),(122479,21,1,'e','1',669144,2850),(122480,21,2,'e','1',669144,2726),(122481,21,3,'n','1',669144,2727),(122482,22,0,'n','1',669144,2779),(122483,22,1,'e','1',669144,2780),(122484,22,2,'n','1',669144,2849),(122485,23,0,'w','1',669144,2902),(122486,23,1,'s','1',669144,2804),(122487,23,2,'w','1',669144,2739),(122488,23,3,'e','1',669144,2849),(122489,24,0,'w','1',669144,2730),(122490,24,1,'e','1',669144,2873),(122491,24,2,'n','1',669144,2872),(122492,24,3,'w','1',669144,2778),(122493,25,0,'n','1',669144,2730),(122494,25,1,'s','1',669144,2751),(122495,25,2,'e','1',669144,2830),(122496,25,3,'w','1',669144,2915),(122497,26,0,'n','1',669144,2831),(122498,26,1,'w','1',669144,2730),(122499,26,2,'e','1',669144,2873),(122500,26,3,'n','1',669144,2872),(122501,27,0,'e','1',669144,2793),(122502,27,1,'n','1',669144,2730),(122503,27,2,'s','1',669144,2751),(122504,28,0,'w','1',669144,2730),(122505,28,1,'s','1',669144,2793),(122506,28,2,'e','1',669144,2785),(122507,28,3,'e','1',669144,2873),(122508,29,0,'s','1',669144,2730),(122509,29,1,'n','1',669144,2727),(122510,29,2,'e','1',669144,2872),(122511,29,3,'e','1',669144,2780),(122512,30,0,'w','1',669144,2730),(122513,30,1,'w','1',669144,2916),(122514,30,2,'e','1',669144,2873),(122515,30,3,'n','1',669144,2872),(122516,31,0,'w','1',669144,2969),(122517,31,1,'w','1',669144,2996),(122518,31,2,'w','1',669144,2739),(122519,31,3,'e','1',669144,3022),(122520,32,0,'n','1',669144,2779),(122521,32,1,'w','1',669144,2753),(122522,32,2,'w','1',669144,2969),(122523,33,0,'e','1',669144,2780),(122524,33,1,'n','1',669144,2819),(122525,33,2,'n','1',669144,2829),(122526,33,3,'e','1',669144,3006),(122527,34,0,'n','1',669144,2730),(122528,34,1,'w','1',669144,2996),(122529,34,2,'w','1',669144,2739),(122530,34,3,'e','1',669144,3022),(122531,35,0,'s','1',669144,2751),(122532,35,1,'s','1',669144,2730),(122533,35,2,'s','1',669144,2872),(122534,35,3,'w','1',669144,2727),(122535,36,0,'w','1',669144,2848),(122536,36,1,'e','1',669144,2927),(122537,36,2,'e','1',669144,2849),(122538,36,3,'w','1',669144,2916),(122539,37,0,'n','1',669144,2848),(122540,37,1,'n','1',669144,2726),(122541,37,2,'s','1',669144,2873),(122542,37,3,'w','1',669144,2996),(122543,38,0,'w','1',669144,2903),(122544,38,1,'e','1',669144,3022),(122545,38,2,'w','1',669144,2797),(122546,38,3,'w','1',669144,2790),(122547,39,0,'n','1',669144,2726),(122548,39,1,'e','1',669144,2780),(122549,39,2,'e','1',669144,2829),(122550,39,3,'s','1',669144,2873),(122551,40,0,'w','1',669144,2726),(122552,40,1,'w','1',669144,2778),(122553,40,2,'n','1',669144,2829),(122554,40,3,'e','1',669144,3033),(122555,41,0,'w','1',669144,2996),(122556,41,1,'e','1',669144,2784),(122557,41,2,'w','1',669144,2849),(122558,42,0,'n','1',669144,2901),(122559,42,1,'e','1',669144,2850),(122560,42,2,'w','1',669144,2817),(122561,42,3,'w','1',669144,3022),(122562,43,0,'w','1',669144,2736),(122563,43,1,'w','1',669144,2888),(122564,43,2,'e','1',669144,2965),(122565,43,3,'w','1',669144,2760),(122566,44,0,'e','1',669144,2986),(122567,44,1,'w','1',669144,3022),(122568,44,2,'e','1',669144,2760),(122569,45,0,'e','1',669144,2778),(122570,45,1,'n','1',669144,2726),(122571,45,2,'n','1',669144,2964),(122572,45,3,'e','1',669144,2777),(122573,46,0,'w','1',669144,2795),(122574,46,1,'s','1',669144,2873),(122575,46,2,'e','1',669144,2781),(122576,46,3,'w','1',669144,3022),(122577,47,0,'e','1',669144,2831),(122578,47,1,'n','1',669144,2726),(122579,47,2,'n','1',669144,2794),(122580,47,3,'e','1',669144,2873),(122581,48,0,'w','1',669144,3022),(122582,48,1,'w','1',669144,2905),(122583,48,2,'w','1',669144,2965),(122584,48,3,'n','1',669144,2789),(122585,49,0,'n','1',669144,2849),(122586,49,1,'w','1',669144,2730),(122587,49,2,'e','1',669144,2873),(122588,49,3,'n','1',669144,2872),(122589,50,0,'n','1',669144,2857),(122590,50,1,'n','1',669144,2730),(122591,50,2,'s','1',669144,2751),(122592,50,3,'n','1',669144,2780),(122593,51,0,'n','1',669144,2995),(122594,51,1,'w','1',669144,2772),(122595,51,2,'e','1',669144,2776),(122596,51,3,'s','1',669144,2804),(122597,52,0,'n','1',669144,2730),(122598,52,1,'s','1',669144,2751),(122599,52,2,'e','1',669144,2840),(122600,52,3,'w','1',669144,2796),(122601,53,0,'n','1',669144,2857),(122602,53,1,'n','1',669144,2730),(122603,53,2,'s','1',669144,2751),(122604,54,0,'n','1',669144,2872),(122605,54,1,'s','1',669144,2877),(122606,54,2,'s','1',669144,2830),(122607,55,0,'n','1',669144,2730),(122608,55,1,'w','1',669144,2849),(122609,55,2,'w','1',669144,2850),(122610,55,3,'e','1',669144,2774),(122611,56,0,'e','1',669144,2785),(122612,56,1,'s','1',669144,2751),(122613,56,2,'e','1',669144,2948),(122614,56,3,'e','1',669144,2851),(122615,57,0,'e','1',669144,2851),(122616,57,1,'e','1',669144,2730),(122617,57,2,'n','1',669144,2872),(122618,57,3,'n','1',669144,2850),(122619,58,0,'n','1',669144,2840),(122620,58,1,'n','1',669144,2877),(122621,58,2,'e','1',669144,2731),(122622,58,3,'n','1',669144,2901),(122623,59,0,'n','1',669144,2732),(122624,59,1,'w','1',669144,2817),(122625,59,2,'s','1',669144,2749),(122626,59,3,'s','1',669144,2987),(122627,60,0,'n','1',669144,2862),(122628,60,1,'n','1',669144,2878),(122629,60,2,'e','1',669144,2832),(122630,61,0,'n','1',669144,2942),(122631,61,1,'w','1',669144,2900),(122632,61,2,'s','1',669144,2904),(122633,62,0,'w','1',669144,2732),(122634,62,1,'n','1',669144,2736),(122635,62,2,'e','1',669144,2762),(122636,62,3,'w','1',669144,2731),(122637,63,0,'e','1',669144,2981),(122638,63,1,'e','1',669144,2730),(122639,63,2,'n','1',669144,2787),(122640,63,3,'e','1',669144,2731),(122641,64,0,'e','1',669144,2862),(122642,64,1,'n','1',669144,2878),(122643,64,2,'s','1',669144,2900),(122644,64,3,'w','1',669144,2732),(122645,65,0,'w','1',669144,2731),(122646,65,1,'w','1',669144,2730),(122647,65,2,'w','1',669144,2762),(122648,65,3,'s','1',669144,2873),(122649,66,0,'w','1',669144,2796),(122650,66,1,'w','1',669144,2737),(122651,66,2,'w','1',669144,2740),(122652,66,3,'w','1',669144,2776),(122653,67,0,'w','1',669144,2878),(122654,67,1,'s','1',669144,2981),(122655,67,2,'s','1',669144,2942),(122656,67,3,'w','1',669144,2794),(122657,68,0,'n','1',669144,2746),(122658,68,1,'s','1',669144,2755),(122659,68,2,'s','1',669144,2833),(122660,69,0,'s','1',669144,2746),(122661,69,1,'s','1',669144,2804),(122662,69,2,'w','1',669144,2986),(122663,70,0,'n','1',669144,2849),(122664,70,1,'s','1',669144,2804),(122665,70,2,'s','1',669144,2837),(122666,71,0,'w','1',669144,2849),(122667,71,1,'s','1',669144,2843),(122668,71,2,'w','1',669144,2850),(122669,72,0,'s','1',669144,2770),(122670,72,1,'e','1',669144,2908),(122671,72,2,'e','1',669144,2986),(122672,72,3,'s','1',669144,2948),(122673,73,0,'s','1',669144,2760),(122674,73,1,'e','1',669144,2884),(122675,73,2,'e','1',669144,2883),(122676,74,0,'w','1',669144,2875),(122677,74,1,'w','1',669144,2823),(122678,74,2,'n','1',669144,2883),(122679,74,3,'w','1',669144,2824),(122680,74,4,'x','0',669144,2762),(122681,75,0,'n','1',669144,2834),(122682,75,1,'e','1',669144,2850),(122683,75,2,'w','1',669144,2996),(122684,76,0,'s','1',669144,3022),(122685,76,1,'w','1',669144,3032),(122686,76,2,'w','1',669144,2823),(122687,76,3,'n','1',669144,2968),(122688,77,0,'s','1',669144,2981),(122689,77,1,'w','1',669144,2840),(122690,77,2,'w','1',669144,2849),(122691,77,3,'e','1',669144,2850),(122692,78,0,'n','1',669144,2849),(122693,78,1,'n','1',669144,2941),(122694,78,2,'n','1',669144,2968),(122695,78,3,'s','1',669144,2804),(122696,79,0,'n','1',669144,2849),(122697,79,1,'s','1',669144,2981),(122698,79,2,'n','1',669144,2804),(122699,79,3,'s','1',669144,2743),(122700,80,0,'n','1',669144,2968),(122701,80,1,'n','1',669144,2780),(122702,80,2,'n','1',669144,2726),(122703,80,3,'n','1',669144,2804),(122704,81,0,'e','1',669144,2981),(122705,81,1,'n','1',669144,2781),(122706,81,2,'n','1',669144,2941),(122707,81,3,'w','1',669144,2878),(122708,82,0,'e','1',669144,2873),(122709,82,1,'s','1',669144,2846),(122710,82,2,'e','1',669144,2730),(122711,82,3,'e','1',669144,2845),(122712,83,0,'s','1',669144,2981),(122713,83,1,'s','1',669144,2968),(122714,83,2,'w','1',669144,2831),(122715,83,3,'s','1',669144,2743),(122716,84,0,'w','1',669144,2804),(122717,84,1,'w','1',669144,2731),(122718,84,2,'w','1',669144,2832),(122719,84,3,'w','1',669144,2730),(122720,85,0,'e','1',669144,2873),(122721,85,1,'n','1',669144,2719),(122722,85,2,'e','1',669144,2730),(122723,85,3,'e','1',669144,2845),(122724,86,0,'e','1',669144,2824),(122725,86,1,'s','1',669144,2731),(122726,86,2,'e','1',669144,2855),(122727,86,3,'s','1',669144,2874),(122728,87,0,'n','1',669144,2913),(122729,87,1,'e','1',669144,2995),(122730,87,2,'e','1',669144,2874),(122731,88,0,'w','1',669144,2816),(122732,88,1,'n','1',669144,2874),(122733,88,2,'w','1',669144,2823),(122734,88,3,'s','1',669144,2731),(122735,89,0,'s','1',669144,2874),(122736,89,1,'e','1',669144,2913),(122737,89,2,'n','1',669144,2905),(122738,89,3,'e','1',669144,2867),(122739,90,0,'n','1',669144,2762),(122740,90,1,'n','1',669144,3003),(122741,90,2,'n','1',669144,2761),(122742,90,3,'n','1',669144,2814),(122743,2,0,'n','1',669144,2913),(122744,2,1,'n','1',669144,2874),(122745,2,2,'n','1',669144,2731),(122746,2,3,'n','1',669144,2750),(122747,3,0,'n','1',669144,2964),(122748,3,1,'n','1',669144,2728),(122749,3,2,'w','1',669144,2827),(122750,3,3,'s','1',669144,2768),(122751,4,0,'e','1',669144,2828),(122752,4,1,'n','1',669144,2975),(122753,4,2,'w','1',669144,2750),(122754,4,3,'w','1',669144,2751),(122755,5,0,'n','1',669144,2827),(122756,5,1,'e','1',669144,2772),(122757,5,2,'s','1',669144,2871),(122758,5,3,'s','1',669144,2900),(122759,6,0,'n','1',669144,2873),(122760,6,1,'e','1',669144,2871),(122761,6,2,'n','1',669144,2908),(122762,6,3,'w','1',669144,2770),(122763,7,0,'n','1',669144,2841),(122764,7,1,'e','1',669144,2751),(122765,7,2,'s','1',669144,2770),(122766,7,3,'s','1',669144,2750),(122767,8,0,'n','1',669144,2731),(122768,8,1,'n','1',669144,2750),(122769,8,2,'w','1',669144,2969),(122770,8,3,'w','1',669144,2955),(122771,9,0,'e','1',669144,2884),(122772,9,1,'s','1',669144,2768),(122773,9,2,'w','1',669144,2750),(122774,9,3,'s','1',669144,2751),(122775,10,0,'n','1',669144,2736),(122776,10,1,'w','1',669144,2730),(122777,10,2,'w','1',669144,2872),(122778,10,3,'s','1',669144,2873),(122779,11,0,'n','1',669144,2883),(122780,11,1,'s','1',669144,2737),(122781,11,2,'e','1',669144,2850),(122782,11,3,'s','1',669144,2965),(122783,12,0,'w','1',669144,2949),(122784,12,1,'e','1',669144,3031),(122785,12,2,'n','1',669144,3032),(122786,12,3,'s','1',669144,2955),(122787,13,0,'n','1',669144,2975),(122788,13,1,'e','1',669144,2973),(122789,13,2,'w','1',669144,2958),(122790,13,3,'w','1',669144,2903),(122791,14,0,'n','1',669144,3022),(122792,14,1,'w','1',669144,2973),(122793,14,2,'e','1',669144,2797),(122794,15,0,'n','1',669144,2986),(122795,15,1,'w','1',669144,2849),(122796,15,2,'e','1',669144,2915),(122797,15,3,'n','1',669144,2736),(122798,16,0,'s','1',669144,2746),(122799,16,1,'s','1',669144,2737),(122800,16,2,'e','1',669144,2850),(122801,16,3,'w','1',669144,2973),(122802,17,0,'e','1',669144,2986),(122803,17,1,'w','1',669144,2915),(122804,17,2,'s','1',669144,2760),(122805,17,3,'e','1',669144,2739),(122806,18,0,'e','1',669144,2950),(122807,18,1,'n','1',669144,2726),(122808,18,2,'e','1',669144,2785),(122809,18,3,'e','1',669144,2873),(122810,19,0,'s','1',669144,2950),(122811,19,1,'w','1',669144,2730),(122812,19,2,'s','1',669144,2873),(122813,19,3,'e','1',669144,2781),(122814,20,0,'e','1',669144,2950),(122815,20,1,'w','1',669144,2849),(122816,20,2,'w','1',669144,2915),(122817,21,0,'e','1',669144,2753),(122818,21,1,'e','1',669144,2850),(122819,21,2,'e','1',669144,2726),(122820,21,3,'n','1',669144,2727),(122821,22,0,'n','1',669144,2779),(122822,22,1,'e','1',669144,2780),(122823,22,2,'n','1',669144,2849),(122824,23,0,'w','1',669144,2902),(122825,23,1,'s','1',669144,2804),(122826,23,2,'w','1',669144,2739),(122827,23,3,'e','1',669144,2849),(122828,24,0,'w','1',669144,2730),(122829,24,1,'e','1',669144,2873),(122830,24,2,'n','1',669144,2872),(122831,24,3,'w','1',669144,2778),(122832,25,0,'n','1',669144,2730),(122833,25,1,'s','1',669144,2751),(122834,25,2,'e','1',669144,2830),(122835,25,3,'w','1',669144,2915),(122836,26,0,'n','1',669144,2831),(122837,26,1,'w','1',669144,2730),(122838,26,2,'e','1',669144,2873),(122839,26,3,'n','1',669144,2872),(122840,27,0,'e','1',669144,2793),(122841,27,1,'n','1',669144,2730),(122842,27,2,'s','1',669144,2751),(122843,28,0,'w','1',669144,2730),(122844,28,1,'s','1',669144,2793),(122845,28,2,'e','1',669144,2785),(122846,28,3,'e','1',669144,2873),(122847,29,0,'s','1',669144,2730),(122848,29,1,'n','1',669144,2727),(122849,29,2,'e','1',669144,2872),(122850,29,3,'e','1',669144,2780),(122851,30,0,'w','1',669144,2730),(122852,30,1,'w','1',669144,2916),(122853,30,2,'e','1',669144,2873),(122854,30,3,'n','1',669144,2872),(122855,31,0,'w','1',669144,2969),(122856,31,1,'w','1',669144,2996),(122857,31,2,'w','1',669144,2739),(122858,31,3,'e','1',669144,3022),(122859,32,0,'n','1',669144,2779),(122860,32,1,'w','1',669144,2753),(122861,32,2,'w','1',669144,2969),(122862,33,0,'e','1',669144,2780),(122863,33,1,'n','1',669144,2819),(122864,33,2,'n','1',669144,2829),(122865,33,3,'e','1',669144,3006),(122866,34,0,'n','1',669144,2730),(122867,34,1,'w','1',669144,2996),(122868,34,2,'w','1',669144,2739),(122869,34,3,'e','1',669144,3022),(122870,35,0,'s','1',669144,2751),(122871,35,1,'s','1',669144,2730),(122872,35,2,'s','1',669144,2872),(122873,35,3,'w','1',669144,2727),(122874,36,0,'w','1',669144,2848),(122875,36,1,'e','1',669144,2927),(122876,36,2,'e','1',669144,2849),(122877,36,3,'w','1',669144,2916),(122878,37,0,'n','1',669144,2848),(122879,37,1,'n','1',669144,2726),(122880,37,2,'s','1',669144,2873),(122881,37,3,'w','1',669144,2996),(122882,38,0,'w','1',669144,2903),(122883,38,1,'e','1',669144,3022),(122884,38,2,'w','1',669144,2797),(122885,38,3,'w','1',669144,2790),(122886,39,0,'n','1',669144,2726),(122887,39,1,'e','1',669144,2780),(122888,39,2,'e','1',669144,2829),(122889,39,3,'s','1',669144,2873),(122890,40,0,'w','1',669144,2726),(122891,40,1,'w','1',669144,2778),(122892,40,2,'n','1',669144,2829),(122893,40,3,'e','1',669144,3033),(122894,41,0,'w','1',669144,2996),(122895,41,1,'e','1',669144,2784),(122896,41,2,'w','1',669144,2849),(122897,42,0,'n','1',669144,2901),(122898,42,1,'e','1',669144,2850),(122899,42,2,'w','1',669144,2817),(122900,42,3,'w','1',669144,3022),(122901,43,0,'w','1',669144,2736),(122902,43,1,'w','1',669144,2888),(122903,43,2,'e','1',669144,2965),(122904,43,3,'w','1',669144,2760),(122905,44,0,'e','1',669144,2986),(122906,44,1,'w','1',669144,3022),(122907,44,2,'e','1',669144,2760),(122908,45,0,'e','1',669144,2778),(122909,45,1,'n','1',669144,2726),(122910,45,2,'n','1',669144,2964),(122911,45,3,'e','1',669144,2777),(122912,46,0,'w','1',669144,2795),(122913,46,1,'s','1',669144,2873),(122914,46,2,'e','1',669144,2781),(122915,46,3,'w','1',669144,3022),(122916,47,0,'e','1',669144,2831),(122917,47,1,'n','1',669144,2726),(122918,47,2,'n','1',669144,2794),(122919,47,3,'e','1',669144,2873),(122920,48,0,'w','1',669144,3022),(122921,48,1,'w','1',669144,2905),(122922,48,2,'w','1',669144,2965),(122923,48,3,'n','1',669144,2789),(122924,49,0,'n','1',669144,2849),(122925,49,1,'w','1',669144,2730),(122926,49,2,'e','1',669144,2873),(122927,49,3,'n','1',669144,2872),(122928,50,0,'n','1',669144,2857),(122929,50,1,'n','1',669144,2730),(122930,50,2,'s','1',669144,2751),(122931,50,3,'n','1',669144,2780),(122932,51,0,'n','1',669144,2995),(122933,51,1,'w','1',669144,2772),(122934,51,2,'e','1',669144,2776),(122935,51,3,'s','1',669144,2804),(122936,52,0,'n','1',669144,2730),(122937,52,1,'s','1',669144,2751),(122938,52,2,'e','1',669144,2840),(122939,52,3,'w','1',669144,2796),(122940,53,0,'n','1',669144,2857),(122941,53,1,'n','1',669144,2730),(122942,53,2,'s','1',669144,2751),(122943,54,0,'n','1',669144,2872),(122944,54,1,'s','1',669144,2877),(122945,54,2,'s','1',669144,2830),(122946,55,0,'n','1',669144,2730),(122947,55,1,'w','1',669144,2849),(122948,55,2,'w','1',669144,2850),(122949,55,3,'e','1',669144,2774),(122950,56,0,'e','1',669144,2785),(122951,56,1,'s','1',669144,2751),(122952,56,2,'e','1',669144,2948),(122953,56,3,'e','1',669144,2851),(122954,57,0,'e','1',669144,2851),(122955,57,1,'e','1',669144,2730),(122956,57,2,'n','1',669144,2872),(122957,57,3,'n','1',669144,2850),(122958,58,0,'n','1',669144,2840),(122959,58,1,'n','1',669144,2877),(122960,58,2,'e','1',669144,2731),(122961,58,3,'n','1',669144,2901),(122962,59,0,'n','1',669144,2732),(122963,59,1,'w','1',669144,2817),(122964,59,2,'s','1',669144,2749),(122965,59,3,'s','1',669144,2987),(122966,60,0,'n','1',669144,2862),(122967,60,1,'n','1',669144,2878),(122968,60,2,'e','1',669144,2832),(122969,61,0,'n','1',669144,2942),(122970,61,1,'w','1',669144,2900),(122971,61,2,'s','1',669144,2904),(122972,62,0,'w','1',669144,2732),(122973,62,1,'n','1',669144,2736),(122974,62,2,'e','1',669144,2762),(122975,62,3,'w','1',669144,2731),(122976,63,0,'e','1',669144,2981),(122977,63,1,'e','1',669144,2730),(122978,63,2,'n','1',669144,2787),(122979,63,3,'e','1',669144,2731),(122980,64,0,'e','1',669144,2862),(122981,64,1,'n','1',669144,2878),(122982,64,2,'s','1',669144,2900),(122983,64,3,'w','1',669144,2732),(122984,65,0,'w','1',669144,2731),(122985,65,1,'w','1',669144,2730),(122986,65,2,'w','1',669144,2762),(122987,65,3,'s','1',669144,2873),(122988,66,0,'w','1',669144,2796),(122989,66,1,'w','1',669144,2737),(122990,66,2,'w','1',669144,2740),(122991,66,3,'w','1',669144,2776),(122992,67,0,'w','1',669144,2878),(122993,67,1,'s','1',669144,2981),(122994,67,2,'s','1',669144,2942),(122995,67,3,'w','1',669144,2794),(122996,68,0,'n','1',669144,2746),(122997,68,1,'s','1',669144,2755),(122998,68,2,'s','1',669144,2833),(122999,69,0,'s','1',669144,2746),(123000,69,1,'s','1',669144,2804),(123001,69,2,'w','1',669144,2986),(123002,70,0,'n','1',669144,2849),(123003,70,1,'s','1',669144,2804),(123004,70,2,'s','1',669144,2837),(123005,71,0,'w','1',669144,2849),(123006,71,1,'s','1',669144,2843),(123007,71,2,'w','1',669144,2850),(123008,72,0,'s','1',669144,2770),(123009,72,1,'e','1',669144,2908),(123010,72,2,'e','1',669144,2986),(123011,72,3,'s','1',669144,2948),(123012,73,0,'s','1',669144,2760),(123013,73,1,'e','1',669144,2884),(123014,73,2,'e','1',669144,2883),(123015,74,0,'w','1',669144,2875),(123016,74,1,'w','1',669144,2823),(123017,74,2,'n','1',669144,2883),(123018,74,3,'w','1',669144,2824),(123019,74,4,'x','0',669144,2762),(123020,75,0,'n','1',669144,2834),(123021,75,1,'e','1',669144,2850),(123022,75,2,'w','1',669144,2996),(123023,76,0,'s','1',669144,3022),(123024,76,1,'w','1',669144,3032),(123025,76,2,'w','1',669144,2823),(123026,76,3,'n','1',669144,2968),(123027,77,0,'s','1',669144,2981),(123028,77,1,'w','1',669144,2840),(123029,77,2,'w','1',669144,2849),(123030,77,3,'e','1',669144,2850),(123031,78,0,'n','1',669144,2849),(123032,78,1,'n','1',669144,2941),(123033,78,2,'n','1',669144,2968),(123034,78,3,'s','1',669144,2804),(123035,79,0,'n','1',669144,2849),(123036,79,1,'s','1',669144,2981),(123037,79,2,'n','1',669144,2804),(123038,79,3,'s','1',669144,2743),(123039,80,0,'n','1',669144,2968),(123040,80,1,'n','1',669144,2780),(123041,80,2,'n','1',669144,2726),(123042,80,3,'n','1',669144,2804),(123043,81,0,'e','1',669144,2981),(123044,81,1,'n','1',669144,2781),(123045,81,2,'n','1',669144,2941),(123046,81,3,'w','1',669144,2878),(123047,82,0,'e','1',669144,2873),(123048,82,1,'s','1',669144,2846),(123049,82,2,'e','1',669144,2730),(123050,82,3,'e','1',669144,2845),(123051,83,0,'s','1',669144,2981),(123052,83,1,'s','1',669144,2968),(123053,83,2,'w','1',669144,2831),(123054,83,3,'s','1',669144,2743),(123055,84,0,'w','1',669144,2804),(123056,84,1,'w','1',669144,2731),(123057,84,2,'w','1',669144,2832),(123058,84,3,'w','1',669144,2730),(123059,85,0,'e','1',669144,2873),(123060,85,1,'n','1',669144,2719),(123061,85,2,'e','1',669144,2730),(123062,85,3,'e','1',669144,2845),(123063,86,0,'e','1',669144,2824),(123064,86,1,'s','1',669144,2731),(123065,86,2,'e','1',669144,2855),(123066,86,3,'s','1',669144,2874),(123067,87,0,'n','1',669144,2913),(123068,87,1,'e','1',669144,2995),(123069,87,2,'e','1',669144,2874),(123070,88,0,'w','1',669144,2816),(123071,88,1,'n','1',669144,2874),(123072,88,2,'w','1',669144,2823),(123073,88,3,'s','1',669144,2731),(123074,89,0,'s','1',669144,2874),(123075,89,1,'e','1',669144,2913),(123076,89,2,'n','1',669144,2905),(123077,89,3,'e','1',669144,2867),(123078,90,0,'n','1',669144,2762),(123079,90,1,'n','1',669144,3003),(123080,90,2,'n','1',669144,2761),(123081,90,3,'n','1',669144,2814),(123082,2,0,'n','1',669145,2964),(123083,2,1,'n','1',669145,2718),(123084,2,2,'n','1',669145,2868),(123085,2,3,'n','1',669145,2956),(123086,3,0,'n','1',669145,2872),(123087,3,1,'n','1',669145,2720),(123088,3,2,'e','1',669145,2726),(123089,3,3,'n','1',669145,2727),(123090,4,0,'n','1',669145,2730),(123091,4,1,'n','1',669145,2877),(123092,4,2,'n','1',669145,2878),(123093,4,3,'n','1',669145,2751),(123094,5,0,'e','1',669145,2881),(123095,5,1,'s','1',669145,2767),(123096,5,2,'n','1',669145,2739),(123097,5,3,'n','1',669145,3031),(123098,6,0,'n','1',669145,2768),(123099,6,1,'e','1',669145,2890),(123100,6,2,'s','1',669145,2826),(123101,6,3,'x','0',669145,2757),(123102,6,4,'e','1',669145,2988),(123103,7,0,'w','1',669145,3005),(123104,7,1,'s','1',669145,2994),(123105,7,2,'s','1',669145,2826),(123106,7,3,'x','0',669145,2757),(123107,7,4,'e','1',669145,2988),(123108,8,0,'w','1',669145,3005),(123109,8,1,'w','1',669145,2988),(123110,8,2,'s','1',669145,2767),(123111,8,3,'w','1',669145,2890),(123112,9,0,'e','1',669145,2893),(123113,9,1,'s','1',669145,2773),(123114,9,2,'s','1',669145,2890),(123115,9,3,'e','1',669145,3009),(123116,10,0,'s','1',669145,2774),(123117,10,1,'s','1',669145,2768),(123118,10,2,'w','1',669145,2750),(123119,10,3,'w','1',669145,2751),(123120,11,0,'e','1',669145,2775),(123121,11,1,'s','1',669145,2776),(123122,11,2,'w','1',669145,2777),(123123,11,3,'x','0',669145,2778),(123124,11,4,'n','1',669145,2965),(123125,12,0,'n','1',669145,2871),(123126,12,1,'s','1',669145,3034),(123127,12,2,'w','1',669145,2977),(123128,12,3,'n','1',669145,2797),(123129,13,0,'s','1',669145,3020),(123130,13,1,'s','1',669145,2978),(123131,13,2,'e','1',669145,2763),(123132,13,3,'n','1',669145,2875),(123133,14,0,'s','1',669145,3035),(123134,14,1,'s','1',669145,2980),(123135,14,2,'e','1',669145,3021),(123136,14,3,'s','1',669145,2873),(123137,15,0,'n','1',669145,2849),(123138,15,1,'w','1',669145,2804),(123139,15,2,'e','1',669145,2832),(123140,15,3,'e','1',669145,2755),(123141,16,0,'w','1',669145,2804),(123142,16,1,'e','1',669145,2832),(123143,16,2,'e','1',669145,2755),(123144,16,3,'s','1',669145,2787),(123145,17,0,'w','1',669145,2804),(123146,17,1,'e','1',669145,2832),(123147,17,2,'e','1',669145,2755),(123148,17,3,'n','1',669145,2958),(123149,18,0,'w','1',669145,2804),(123150,18,1,'n','1',669145,2923),(123151,18,2,'n','1',669145,2959),(123152,18,3,'n','1',669145,2960),(123153,19,0,'n','1',669145,3001),(123154,19,1,'w','1',669145,2808),(123155,19,2,'w','1',669145,3000),(123156,19,3,'n','1',669145,2834),(123157,20,0,'n','1',669145,2823),(123158,20,1,'n','1',669145,2745),(123159,20,2,'w','1',669145,2821),(123160,20,3,'e','1',669145,2903),(123161,21,0,'s','1',669145,2755),(123162,21,1,'w','1',669145,2832),(123163,21,2,'w','1',669145,2833),(123164,21,3,'n','1',669145,2747),(123165,22,0,'e','1',669145,2987),(123166,22,1,'s','1',669145,2800),(123167,22,2,'s','1',669145,2844),(123168,22,3,'e','1',669145,2803),(123169,23,0,'n','1',669145,2832),(123170,23,1,'s','1',669145,2844),(123171,23,2,'w','1',669145,2837),(123172,23,3,'x','0',669145,2757),(123173,23,4,'n','1',669145,2843),(123174,24,0,'e','1',669145,2923),(123175,24,1,'n','1',669145,2922),(123176,24,2,'w','1',669145,2821),(123177,24,3,'n','1',669145,2920),(123178,25,0,'s','1',669145,3024),(123179,25,1,'w','1',669145,2799),(123180,25,2,'s','1',669145,2747),(123181,25,3,'s','1',669145,2948),(123182,26,0,'n','1',669145,2965),(123183,26,1,'w','1',669145,2908),(123184,26,2,'w','1',669145,2794),(123185,26,3,'n','1',669145,2772),(123186,27,0,'w','1',669145,2884),(123187,27,1,'s','1',669145,2735),(123188,27,2,'n','1',669145,2789),(123189,27,3,'e','1',669145,2975),(123190,28,0,'n','1',669145,2914),(123191,28,1,'w','1',669145,2837),(123192,28,2,'w','1',669145,2918),(123193,28,3,'n','1',669145,2757),(123194,29,0,'n','1',669145,2771),(123195,29,1,'e','1',669145,2879),(123196,29,2,'n','1',669145,2748),(123197,29,3,'n','1',669145,2795),(123198,30,0,'w','1',669145,2851),(123199,30,1,'n','1',669145,2785),(123200,30,2,'n','1',669145,2902),(123201,30,3,'w','1',669145,2828),(123202,31,0,'n','1',669145,2778),(123203,31,1,'w','1',669145,2793),(123204,31,2,'n','1',669145,2794),(123205,31,3,'n','1',669145,2830),(123206,32,0,'n','1',669145,2945),(123207,32,1,'n','1',669145,3036),(123208,32,2,'e','1',669145,2725),(123209,32,3,'n','1',669145,2995),(123210,32,4,'x','0',669145,2772),(123211,33,0,'w','1',669145,2796),(123212,33,1,'n','1',669145,2776),(123213,33,2,'n','1',669145,2735),(123214,33,3,'s','1',669145,2886),(123215,34,0,'e','1',669145,2954),(123216,34,1,'n','1',669145,2948),(123217,34,2,'s','1',669145,2747),(123218,34,3,'s','1',669145,2970),(123219,35,0,'e','1',669145,2755),(123220,35,1,'n','1',669145,2948),(123221,35,2,'s','1',669145,2756),(123222,35,3,'e','1',669145,2747),(123223,36,0,'e','1',669145,2747),(123224,36,1,'s','1',669145,2832),(123225,36,2,'n','1',669145,2850),(123226,36,3,'w','1',669145,2737),(123227,37,0,'e','1',669145,2747),(123228,37,1,'e','1',669145,2843),(123229,37,2,'e','1',669145,2832),(123230,37,3,'n','1',669145,2841),(123231,38,0,'s','1',669145,2737),(123232,38,1,'s','1',669145,2804),(123233,38,2,'w','1',669145,2736),(123234,38,3,'x','0',669145,2760),(123235,38,4,'s','1',669145,2849),(123236,39,0,'n','1',669145,2830),(123237,39,1,'w','1',669145,2932),(123238,39,2,'n','1',669145,2794),(123239,39,3,'n','1',669145,2774),(123240,40,0,'n','1',669145,2875),(123241,40,1,'n','1',669145,2849),(123242,40,2,'n','1',669145,2804),(123243,40,3,'n','1',669145,2761),(123244,41,0,'e','1',669145,2886),(123245,41,1,'n','1',669145,2930),(123246,41,2,'n','1',669145,2801),(123247,41,3,'e','1',669145,2931),(123248,41,4,'x','0',669145,2910),(123249,42,0,'n','1',669145,2794),(123250,42,1,'w','1',669145,2857),(123251,42,2,'n','1',669145,2840),(123252,42,3,'n','1',669145,2862),(123253,43,0,'s','1',669145,3007),(123254,43,1,'w','1',669145,3019),(123255,43,2,'w','1',669145,2801),(123256,43,3,'s','1',669145,2853),(123257,43,4,'x','0',669145,2910),(123258,44,0,'e','1',669145,2761),(123259,44,1,'n','1',669145,2729),(123260,44,2,'n','1',669145,2949),(123261,44,3,'n','1',669145,2861),(123262,2,0,'n','1',669145,2964),(123263,2,1,'n','1',669145,2718),(123264,2,2,'n','1',669145,2868),(123265,2,3,'n','1',669145,2956),(123266,3,0,'n','1',669145,2872),(123267,3,1,'n','1',669145,2720),(123268,3,2,'e','1',669145,2726),(123269,3,3,'n','1',669145,2727),(123270,4,0,'n','1',669145,2730),(123271,4,1,'n','1',669145,2877),(123272,4,2,'n','1',669145,2878),(123273,4,3,'n','1',669145,2751),(123274,5,0,'e','1',669145,2881),(123275,5,1,'s','1',669145,2767),(123276,5,2,'n','1',669145,2739),(123277,5,3,'n','1',669145,3031),(123278,6,0,'n','1',669145,2768),(123279,6,1,'e','1',669145,2890),(123280,6,2,'s','1',669145,2826),(123281,6,3,'x','0',669145,2757),(123282,6,4,'e','1',669145,2988),(123283,7,0,'w','1',669145,3005),(123284,7,1,'s','1',669145,2994),(123285,7,2,'s','1',669145,2826),(123286,7,3,'x','0',669145,2757),(123287,7,4,'e','1',669145,2988),(123288,8,0,'w','1',669145,3005),(123289,8,1,'w','1',669145,2988),(123290,8,2,'s','1',669145,2767),(123291,8,3,'w','1',669145,2890),(123292,9,0,'e','1',669145,2893),(123293,9,1,'s','1',669145,2773),(123294,9,2,'s','1',669145,2890),(123295,9,3,'e','1',669145,3009),(123296,10,0,'s','1',669145,2774),(123297,10,1,'s','1',669145,2768),(123298,10,2,'w','1',669145,2750),(123299,10,3,'w','1',669145,2751),(123300,11,0,'e','1',669145,2775),(123301,11,1,'s','1',669145,2776),(123302,11,2,'w','1',669145,2777),(123303,11,3,'x','0',669145,2778),(123304,11,4,'n','1',669145,2965),(123305,12,0,'n','1',669145,2871),(123306,12,1,'s','1',669145,3034),(123307,12,2,'w','1',669145,2977),(123308,12,3,'n','1',669145,2797),(123309,13,0,'s','1',669145,3020),(123310,13,1,'s','1',669145,2978),(123311,13,2,'e','1',669145,2763),(123312,13,3,'n','1',669145,2875),(123313,14,0,'s','1',669145,3035),(123314,14,1,'s','1',669145,2980),(123315,14,2,'e','1',669145,3021),(123316,14,3,'s','1',669145,2873),(123317,15,0,'n','1',669145,2849),(123318,15,1,'w','1',669145,2804),(123319,15,2,'e','1',669145,2832),(123320,15,3,'e','1',669145,2755),(123321,16,0,'w','1',669145,2804),(123322,16,1,'e','1',669145,2832),(123323,16,2,'e','1',669145,2755),(123324,16,3,'s','1',669145,2787),(123325,17,0,'w','1',669145,2804),(123326,17,1,'e','1',669145,2832),(123327,17,2,'e','1',669145,2755),(123328,17,3,'n','1',669145,2958),(123329,18,0,'w','1',669145,2804),(123330,18,1,'n','1',669145,2923),(123331,18,2,'n','1',669145,2959),(123332,18,3,'n','1',669145,2960),(123333,19,0,'n','1',669145,3001),(123334,19,1,'w','1',669145,2808),(123335,19,2,'w','1',669145,3000),(123336,19,3,'n','1',669145,2834),(123337,20,0,'n','1',669145,2823),(123338,20,1,'n','1',669145,2745),(123339,20,2,'w','1',669145,2821),(123340,20,3,'e','1',669145,2903),(123341,21,0,'s','1',669145,2755),(123342,21,1,'w','1',669145,2832),(123343,21,2,'w','1',669145,2833),(123344,21,3,'n','1',669145,2747),(123345,22,0,'e','1',669145,2987),(123346,22,1,'s','1',669145,2800),(123347,22,2,'s','1',669145,2844),(123348,22,3,'e','1',669145,2803),(123349,23,0,'n','1',669145,2832),(123350,23,1,'s','1',669145,2844),(123351,23,2,'w','1',669145,2837),(123352,23,3,'x','0',669145,2757),(123353,23,4,'n','1',669145,2843),(123354,24,0,'e','1',669145,2923),(123355,24,1,'n','1',669145,2922),(123356,24,2,'w','1',669145,2821),(123357,24,3,'n','1',669145,2920),(123358,25,0,'s','1',669145,3024),(123359,25,1,'w','1',669145,2799),(123360,25,2,'s','1',669145,2747),(123361,25,3,'s','1',669145,2948),(123362,26,0,'n','1',669145,2965),(123363,26,1,'w','1',669145,2908),(123364,26,2,'w','1',669145,2794),(123365,26,3,'n','1',669145,2772),(123366,27,0,'w','1',669145,2884),(123367,27,1,'s','1',669145,2735),(123368,27,2,'n','1',669145,2789),(123369,27,3,'e','1',669145,2975),(123370,28,0,'n','1',669145,2914),(123371,28,1,'w','1',669145,2837),(123372,28,2,'w','1',669145,2918),(123373,28,3,'n','1',669145,2757),(123374,29,0,'n','1',669145,2771),(123375,29,1,'e','1',669145,2879),(123376,29,2,'n','1',669145,2748),(123377,29,3,'n','1',669145,2795),(123378,30,0,'w','1',669145,2851),(123379,30,1,'n','1',669145,2785),(123380,30,2,'n','1',669145,2902),(123381,30,3,'w','1',669145,2828),(123382,31,0,'n','1',669145,2778),(123383,31,1,'w','1',669145,2793),(123384,31,2,'n','1',669145,2794),(123385,31,3,'n','1',669145,2830),(123386,32,0,'n','1',669145,2945),(123387,32,1,'n','1',669145,3036),(123388,32,2,'e','1',669145,2725),(123389,32,3,'n','1',669145,2995),(123390,32,4,'x','0',669145,2772),(123391,33,0,'w','1',669145,2796),(123392,33,1,'n','1',669145,2776),(123393,33,2,'n','1',669145,2735),(123394,33,3,'s','1',669145,2886),(123395,34,0,'e','1',669145,2954),(123396,34,1,'n','1',669145,2948),(123397,34,2,'s','1',669145,2747),(123398,34,3,'s','1',669145,2970),(123399,35,0,'e','1',669145,2755),(123400,35,1,'n','1',669145,2948),(123401,35,2,'s','1',669145,2756),(123402,35,3,'e','1',669145,2747),(123403,36,0,'e','1',669145,2747),(123404,36,1,'s','1',669145,2832),(123405,36,2,'n','1',669145,2850),(123406,36,3,'w','1',669145,2737),(123407,37,0,'e','1',669145,2747),(123408,37,1,'e','1',669145,2843),(123409,37,2,'e','1',669145,2832),(123410,37,3,'n','1',669145,2841),(123411,38,0,'s','1',669145,2737),(123412,38,1,'s','1',669145,2804),(123413,38,2,'w','1',669145,2736),(123414,38,3,'x','0',669145,2760),(123415,38,4,'s','1',669145,2849),(123416,39,0,'n','1',669145,2830),(123417,39,1,'w','1',669145,2932),(123418,39,2,'n','1',669145,2794),(123419,39,3,'n','1',669145,2774),(123420,40,0,'n','1',669145,2875),(123421,40,1,'n','1',669145,2849),(123422,40,2,'n','1',669145,2804),(123423,40,3,'n','1',669145,2761),(123424,41,0,'e','1',669145,2886),(123425,41,1,'n','1',669145,2930),(123426,41,2,'n','1',669145,2801),(123427,41,3,'e','1',669145,2931),(123428,41,4,'x','0',669145,2910),(123429,42,0,'n','1',669145,2794),(123430,42,1,'w','1',669145,2857),(123431,42,2,'n','1',669145,2840),(123432,42,3,'n','1',669145,2862),(123433,43,0,'s','1',669145,3007),(123434,43,1,'w','1',669145,3019),(123435,43,2,'w','1',669145,2801),(123436,43,3,'s','1',669145,2853),(123437,43,4,'x','0',669145,2910),(123438,44,0,'e','1',669145,2761),(123439,44,1,'n','1',669145,2729),(123440,44,2,'n','1',669145,2949),(123441,44,3,'n','1',669145,2861),(123442,2,0,'n','1',669146,2867),(123443,2,1,'n','1',669146,2816),(123444,2,2,'n','1',669146,2732),(123445,2,3,'n','1',669146,2749),(123446,3,0,'n','1',669146,2721),(123447,3,1,'n','1',669146,2888),(123448,3,2,'n','1',669146,2963),(123449,3,3,'n','1',669146,2717),(123450,4,0,'e','1',669146,2719),(123451,4,1,'e','1',669146,2815),(123452,4,2,'e','1',669146,2725),(123453,4,3,'n','1',669146,2754),(123454,5,0,'w','1',669146,2820),(123455,5,1,'n','1',669146,2737),(123456,5,2,'e','1',669146,2735),(123457,5,3,'n','1',669146,2927),(123458,6,0,'s','1',669146,2765),(123459,6,1,'e','1',669146,2749),(123460,6,2,'e','1',669146,2884),(123461,6,3,'e','1',669146,2883),(123462,7,0,'e','1',669146,2759),(123463,7,1,'n','1',669146,2964),(123464,7,2,'n','1',669146,2882),(123465,7,3,'e','1',669146,2872),(123466,8,0,'n','1',669146,2838),(123467,8,1,'n','1',669146,2834),(123468,8,2,'n','1',669146,2823),(123469,8,3,'n','1',669146,2901),(123470,9,0,'w','1',669146,2839),(123471,9,1,'n','1',669146,2817),(123472,9,2,'n','1',669146,2915),(123473,9,3,'n','1',669146,2786),(123474,10,0,'s','1',669146,2787),(123475,10,1,'w','1',669146,2850),(123476,10,2,'n','1',669146,2934),(123477,10,3,'e','1',669146,2786),(123478,11,0,'e','1',669146,2772),(123479,11,1,'w','1',669146,2803),(123480,11,2,'n','1',669146,2905),(123481,11,3,'n','1',669146,2903),(123482,12,0,'n','1',669146,2921),(123483,12,1,'n','1',669146,2882),(123484,12,2,'w','1',669146,2858),(123485,12,3,'w','1',669146,2778),(123486,13,0,'w','1',669146,2948),(123487,13,1,'w','1',669146,2954),(123488,13,2,'w','1',669146,2908),(123489,13,3,'n','1',669146,2739),(123490,14,0,'n','1',669146,2783),(123491,14,1,'w','1',669146,2772),(123492,14,2,'s','1',669146,2855),(123493,14,3,'n','1',669146,2745),(123494,15,0,'e','1',669146,2734),(123495,15,1,'x','0',669146,2809),(123496,15,2,'w','1',669146,2738),(123497,15,3,'s','1',669146,2806),(123498,15,4,'w','1',669146,2805),(123499,16,0,'w','1',669146,2734),(123500,16,1,'w','1',669146,2749),(123501,16,2,'w','1',669146,2750),(123502,16,3,'s','1',669146,2751),(123503,17,0,'n','1',669146,2730),(123504,17,1,'n','1',669146,2725),(123505,17,2,'e','1',669146,2824),(123506,17,3,'e','1',669146,2762),(123507,18,0,'e','1',669146,2855),(123508,18,1,'s','1',669146,2751),(123509,18,2,'e','1',669146,2954),(123510,18,3,'s','1',669146,2730),(123511,19,0,'n','1',669146,2739),(123512,19,1,'n','1',669146,2775),(123513,19,2,'e','1',669146,2948),(123514,19,3,'e','1',669146,2850),(123515,20,0,'s','1',669146,2945),(123516,20,1,'s','1',669146,2727),(123517,20,2,'n','1',669146,2803),(123518,20,3,'n','1',669146,2802),(123519,21,0,'n','1',669146,2957),(123520,21,1,'s','1',669146,2727),(123521,21,2,'s','1',669146,2946),(123522,21,3,'x','0',669146,2950),(123523,21,4,'n','1',669146,2823),(123524,22,0,'n','1',669146,2957),(123525,22,1,'e','1',669146,2887),(123526,22,2,'e','1',669146,2966),(123527,22,3,'s','1',669146,2727),(123528,23,0,'n','1',669146,2848),(123529,23,1,'n','1',669146,2872),(123530,23,2,'e','1',669146,2780),(123531,23,3,'e','1',669146,2790),(123532,24,0,'w','1',669146,2849),(123533,24,1,'n','1',669146,2800),(123534,24,2,'w','1',669146,2826),(123535,24,3,'n','1',669146,2799),(123536,25,0,'n','1',669146,2777),(123537,25,1,'n','1',669146,2955),(123538,25,2,'n','1',669146,2779),(123539,25,3,'n','1',669146,2797),(123540,26,0,'e','1',669146,2830),(123541,26,1,'n','1',669146,2877),(123542,26,2,'n','1',669146,2829),(123543,26,3,'n','1',669146,2878),(123544,27,0,'s','1',669146,2990),(123545,27,1,'e','1',669146,2778),(123546,27,2,'e','1',669146,2777),(123547,27,3,'n','1',669146,2955),(123548,2,0,'n','1',669146,2867),(123549,2,1,'n','1',669146,2816),(123550,2,2,'n','1',669146,2732),(123551,2,3,'n','1',669146,2749),(123552,3,0,'n','1',669146,2721),(123553,3,1,'n','1',669146,2888),(123554,3,2,'n','1',669146,2963),(123555,3,3,'n','1',669146,2717),(123556,4,0,'e','1',669146,2719),(123557,4,1,'e','1',669146,2815),(123558,4,2,'e','1',669146,2725),(123559,4,3,'n','1',669146,2754),(123560,5,0,'w','1',669146,2820),(123561,5,1,'n','1',669146,2737),(123562,5,2,'e','1',669146,2735),(123563,5,3,'n','1',669146,2927),(123564,6,0,'s','1',669146,2765),(123565,6,1,'e','1',669146,2749),(123566,6,2,'e','1',669146,2884),(123567,6,3,'e','1',669146,2883),(123568,7,0,'e','1',669146,2759),(123569,7,1,'n','1',669146,2964),(123570,7,2,'n','1',669146,2882),(123571,7,3,'e','1',669146,2872),(123572,8,0,'n','1',669146,2838),(123573,8,1,'n','1',669146,2834),(123574,8,2,'n','1',669146,2823),(123575,8,3,'n','1',669146,2901),(123576,9,0,'w','1',669146,2839),(123577,9,1,'n','1',669146,2817),(123578,9,2,'n','1',669146,2915),(123579,9,3,'n','1',669146,2786),(123580,10,0,'s','1',669146,2787),(123581,10,1,'w','1',669146,2850),(123582,10,2,'n','1',669146,2934),(123583,10,3,'e','1',669146,2786),(123584,11,0,'e','1',669146,2772),(123585,11,1,'w','1',669146,2803),(123586,11,2,'n','1',669146,2905),(123587,11,3,'n','1',669146,2903),(123588,12,0,'n','1',669146,2921),(123589,12,1,'n','1',669146,2882),(123590,12,2,'w','1',669146,2858),(123591,12,3,'w','1',669146,2778),(123592,13,0,'w','1',669146,2948),(123593,13,1,'w','1',669146,2954),(123594,13,2,'w','1',669146,2908),(123595,13,3,'n','1',669146,2739),(123596,14,0,'n','1',669146,2783),(123597,14,1,'w','1',669146,2772),(123598,14,2,'s','1',669146,2855),(123599,14,3,'n','1',669146,2745),(123600,15,0,'e','1',669146,2734),(123601,15,1,'x','0',669146,2809),(123602,15,2,'w','1',669146,2738),(123603,15,3,'s','1',669146,2806),(123604,15,4,'w','1',669146,2805),(123605,16,0,'w','1',669146,2734),(123606,16,1,'w','1',669146,2749),(123607,16,2,'w','1',669146,2750),(123608,16,3,'s','1',669146,2751),(123609,17,0,'n','1',669146,2730),(123610,17,1,'n','1',669146,2725),(123611,17,2,'e','1',669146,2824),(123612,17,3,'e','1',669146,2762),(123613,18,0,'e','1',669146,2855),(123614,18,1,'s','1',669146,2751),(123615,18,2,'e','1',669146,2954),(123616,18,3,'s','1',669146,2730),(123617,19,0,'n','1',669146,2739),(123618,19,1,'n','1',669146,2775),(123619,19,2,'e','1',669146,2948),(123620,19,3,'e','1',669146,2850),(123621,20,0,'s','1',669146,2945),(123622,20,1,'s','1',669146,2727),(123623,20,2,'n','1',669146,2803),(123624,20,3,'n','1',669146,2802),(123625,21,0,'n','1',669146,2957),(123626,21,1,'s','1',669146,2727),(123627,21,2,'s','1',669146,2946),(123628,21,3,'x','0',669146,2950),(123629,21,4,'n','1',669146,2823),(123630,22,0,'n','1',669146,2957),(123631,22,1,'e','1',669146,2887),(123632,22,2,'e','1',669146,2966),(123633,22,3,'s','1',669146,2727),(123634,23,0,'n','1',669146,2848),(123635,23,1,'n','1',669146,2872),(123636,23,2,'e','1',669146,2780),(123637,23,3,'e','1',669146,2790),(123638,24,0,'w','1',669146,2849),(123639,24,1,'n','1',669146,2800),(123640,24,2,'w','1',669146,2826),(123641,24,3,'n','1',669146,2799),(123642,25,0,'n','1',669146,2777),(123643,25,1,'n','1',669146,2955),(123644,25,2,'n','1',669146,2779),(123645,25,3,'n','1',669146,2797),(123646,26,0,'e','1',669146,2830),(123647,26,1,'n','1',669146,2877),(123648,26,2,'n','1',669146,2829),(123649,26,3,'n','1',669146,2878),(123650,27,0,'s','1',669146,2990),(123651,27,1,'e','1',669146,2778),(123652,27,2,'e','1',669146,2777),(123653,27,3,'n','1',669146,2955),(123654,2,0,'n','1',669147,2728),(123655,2,1,'n','1',669147,2991),(123656,2,2,'n','1',669147,2828),(123657,2,3,'n','1',669147,2815),(123658,3,0,'n','1',669147,2975),(123659,3,1,'w','1',669147,2735),(123660,3,2,'w','1',669147,2725),(123661,3,3,'w','1',669147,3037),(123662,4,0,'n','1',669147,2822),(123663,4,1,'e','1',669147,2845),(123664,4,2,'s','1',669147,2855),(123665,4,3,'n','1',669147,2736),(123666,5,0,'n','1',669147,2992),(123667,5,1,'w','1',669147,2813),(123668,5,2,'n','1',669147,2814),(123669,5,3,'n','1',669147,2733),(123670,6,0,'w','1',669147,2734),(123671,6,1,'w','1',669147,2749),(123672,6,2,'n','1',669147,2750),(123673,6,3,'n','1',669147,2737),(123674,7,0,'n','1',669147,2768),(123675,7,1,'s','1',669147,2767),(123676,7,2,'w','1',669147,2890),(123677,7,3,'n','1',669147,2759),(123678,8,0,'w','1',669147,2893),(123679,8,1,'s','1',669147,2769),(123680,8,2,'x','0',669147,2859),(123681,8,3,'s','1',669147,2983),(123682,8,4,'n','1',669147,2904),(123683,9,0,'s','1',669147,2846),(123684,9,1,'s','1',669147,2977),(123685,9,2,'w','1',669147,2829),(123686,9,3,'w','1',669147,2725),(123687,10,0,'e','1',669147,3030),(123688,10,1,'e','1',669147,2899),(123689,10,2,'s','1',669147,2944),(123690,10,3,'e','1',669147,2885),(123691,11,0,'n','1',669147,3007),(123692,11,1,'w','1',669147,2938),(123693,11,2,'e','1',669147,2885),(123694,11,3,'n','1',669147,2724),(123695,12,0,'n','1',669147,3007),(123696,12,1,'w','1',669147,2938),(123697,12,2,'e','1',669147,2885),(123698,12,3,'n','1',669147,2723),(123699,13,0,'n','1',669147,2863),(123700,13,1,'e','1',669147,2938),(123701,13,2,'s','1',669147,2826),(123702,13,3,'e','1',669147,2936),(123703,14,0,'w','1',669147,2836),(123704,14,1,'e','1',669147,2936),(123705,14,2,'n','1',669147,2833),(123706,14,3,'n','1',669147,2782),(123707,15,0,'s','1',669147,2871),(123708,15,1,'n','1',669147,2873),(123709,15,2,'e','1',669147,3035),(123710,15,3,'n','1',669147,2780),(123711,16,0,'e','1',669147,2845),(123712,16,1,'s','1',669147,2871),(123713,16,2,'s','1',669147,2855),(123714,16,3,'e','1',669147,2873),(123715,17,0,'n','1',669147,2789),(123716,17,1,'w','1',669147,2836),(123717,17,2,'s','1',669147,2833),(123718,17,3,'s','1',669147,2936),(123719,18,0,'w','1',669147,2788),(123720,18,1,'s','1',669147,2970),(123721,18,2,'s','1',669147,2755),(123722,18,3,'e','1',669147,2746),(123723,19,0,'n','1',669147,2834),(123724,19,1,'e','1',669147,2838),(123725,19,2,'n','1',669147,2823),(123726,19,3,'n','1',669147,3015),(123727,20,0,'e','1',669147,2903),(123728,20,1,'e','1',669147,2901),(123729,20,2,'n','1',669147,2888),(123730,20,3,'n','1',669147,2797),(123731,21,0,'n','1',669147,2758),(123732,21,1,'n','1',669147,2740),(123733,21,2,'s','1',669147,2756),(123734,21,3,'e','1',669147,2788),(123735,22,0,'e','1',669147,2905),(123736,22,1,'s','1',669147,2934),(123737,22,2,'e','1',669147,2795),(123738,22,3,'n','1',669147,2789),(123739,23,0,'w','1',669147,2740),(123740,23,1,'e','1',669147,2746),(123741,23,2,'s','1',669147,2788),(123742,23,3,'w','1',669147,2758),(123743,24,0,'e','1',669147,2758),(123744,24,1,'n','1',669147,2740),(123745,24,2,'n','1',669147,2762),(123746,24,3,'e','1',669147,2761),(123747,25,0,'n','1',669147,2819),(123748,25,1,'s','1',669147,2756),(123749,25,2,'w','1',669147,2843),(123750,25,3,'w','1',669147,2758),(123751,26,0,'n','1',669147,2719),(123752,26,1,'e','1',669147,3006),(123753,26,2,'e','1',669147,2930),(123754,26,3,'n','1',669147,2845),(123755,27,0,'n','1',669147,2846),(123756,27,1,'n','1',669147,2769),(123757,27,2,'e','1',669147,2894),(123758,27,3,'e','1',669147,2895),(123759,28,0,'n','1',669147,2932),(123760,28,1,'n','1',669147,2730),(123761,28,2,'e','1',669147,3027),(123762,28,3,'n','1',669147,2773),(123763,28,4,'x','0',669147,2910),(123764,29,0,'s','1',669147,3006),(123765,29,1,'w','1',669147,2751),(123766,29,2,'s','1',669147,2871),(123767,29,3,'e','1',669147,2981),(123768,30,0,'n','1',669147,2777),(123769,30,1,'n','1',669147,2955),(123770,30,2,'e','1',669147,2753),(123771,30,3,'e','1',669147,2819),(123772,31,0,'e','1',669147,2969),(123773,31,1,'n','1',669147,2789),(123774,31,2,'n','1',669147,2858),(123775,31,3,'e','1',669147,2739),(123776,32,0,'n','1',669147,2873),(123777,32,1,'e','1',669147,2900),(123778,32,2,'x','0',669147,2880),(123779,32,3,'n','1',669147,2871),(123780,32,4,'s','1',669147,2977),(123781,33,0,'s','1',669147,2871),(123782,33,1,'e','1',669147,2941),(123783,33,2,'n','1',669147,2781),(123784,33,3,'w','1',669147,2873),(123785,2,0,'n','1',669147,2728),(123786,2,1,'n','1',669147,2991),(123787,2,2,'n','1',669147,2828),(123788,2,3,'n','1',669147,2815),(123789,3,0,'n','1',669147,2975),(123790,3,1,'w','1',669147,2735),(123791,3,2,'w','1',669147,2725),(123792,3,3,'w','1',669147,3037),(123793,4,0,'n','1',669147,2822),(123794,4,1,'e','1',669147,2845),(123795,4,2,'s','1',669147,2855),(123796,4,3,'n','1',669147,2736),(123797,5,0,'n','1',669147,2992),(123798,5,1,'w','1',669147,2813),(123799,5,2,'n','1',669147,2814),(123800,5,3,'n','1',669147,2733),(123801,6,0,'w','1',669147,2734),(123802,6,1,'w','1',669147,2749),(123803,6,2,'n','1',669147,2750),(123804,6,3,'n','1',669147,2737),(123805,7,0,'n','1',669147,2768),(123806,7,1,'s','1',669147,2767),(123807,7,2,'w','1',669147,2890),(123808,7,3,'n','1',669147,2759),(123809,8,0,'w','1',669147,2893),(123810,8,1,'s','1',669147,2769),(123811,8,2,'x','0',669147,2859),(123812,8,3,'s','1',669147,2983),(123813,8,4,'n','1',669147,2904),(123814,9,0,'s','1',669147,2846),(123815,9,1,'s','1',669147,2977),(123816,9,2,'w','1',669147,2829),(123817,9,3,'w','1',669147,2725),(123818,10,0,'e','1',669147,3030),(123819,10,1,'e','1',669147,2899),(123820,10,2,'s','1',669147,2944),(123821,10,3,'e','1',669147,2885),(123822,11,0,'n','1',669147,3007),(123823,11,1,'w','1',669147,2938),(123824,11,2,'e','1',669147,2885),(123825,11,3,'n','1',669147,2724),(123826,12,0,'n','1',669147,3007),(123827,12,1,'w','1',669147,2938),(123828,12,2,'e','1',669147,2885),(123829,12,3,'n','1',669147,2723),(123830,13,0,'n','1',669147,2863),(123831,13,1,'e','1',669147,2938),(123832,13,2,'s','1',669147,2826),(123833,13,3,'e','1',669147,2936),(123834,14,0,'w','1',669147,2836),(123835,14,1,'e','1',669147,2936),(123836,14,2,'n','1',669147,2833),(123837,14,3,'n','1',669147,2782),(123838,15,0,'s','1',669147,2871),(123839,15,1,'n','1',669147,2873),(123840,15,2,'e','1',669147,3035),(123841,15,3,'n','1',669147,2780),(123842,16,0,'e','1',669147,2845),(123843,16,1,'s','1',669147,2871),(123844,16,2,'s','1',669147,2855),(123845,16,3,'e','1',669147,2873),(123846,17,0,'n','1',669147,2789),(123847,17,1,'w','1',669147,2836),(123848,17,2,'s','1',669147,2833),(123849,17,3,'s','1',669147,2936),(123850,18,0,'w','1',669147,2788),(123851,18,1,'s','1',669147,2970),(123852,18,2,'s','1',669147,2755),(123853,18,3,'e','1',669147,2746),(123854,19,0,'n','1',669147,2834),(123855,19,1,'e','1',669147,2838),(123856,19,2,'n','1',669147,2823),(123857,19,3,'n','1',669147,3015),(123858,20,0,'e','1',669147,2903),(123859,20,1,'e','1',669147,2901),(123860,20,2,'n','1',669147,2888),(123861,20,3,'n','1',669147,2797),(123862,21,0,'n','1',669147,2758),(123863,21,1,'n','1',669147,2740),(123864,21,2,'s','1',669147,2756),(123865,21,3,'e','1',669147,2788),(123866,22,0,'e','1',669147,2905),(123867,22,1,'s','1',669147,2934),(123868,22,2,'e','1',669147,2795),(123869,22,3,'n','1',669147,2789),(123870,23,0,'w','1',669147,2740),(123871,23,1,'e','1',669147,2746),(123872,23,2,'s','1',669147,2788),(123873,23,3,'w','1',669147,2758),(123874,24,0,'e','1',669147,2758),(123875,24,1,'n','1',669147,2740),(123876,24,2,'n','1',669147,2762),(123877,24,3,'e','1',669147,2761),(123878,25,0,'n','1',669147,2819),(123879,25,1,'s','1',669147,2756),(123880,25,2,'w','1',669147,2843),(123881,25,3,'w','1',669147,2758),(123882,26,0,'n','1',669147,2719),(123883,26,1,'e','1',669147,3006),(123884,26,2,'e','1',669147,2930),(123885,26,3,'n','1',669147,2845),(123886,27,0,'n','1',669147,2846),(123887,27,1,'n','1',669147,2769),(123888,27,2,'e','1',669147,2894),(123889,27,3,'e','1',669147,2895),(123890,28,0,'n','1',669147,2932),(123891,28,1,'n','1',669147,2730),(123892,28,2,'e','1',669147,3027),(123893,28,3,'n','1',669147,2773),(123894,28,4,'x','0',669147,2910),(123895,29,0,'s','1',669147,3006),(123896,29,1,'w','1',669147,2751),(123897,29,2,'s','1',669147,2871),(123898,29,3,'e','1',669147,2981),(123899,30,0,'n','1',669147,2777),(123900,30,1,'n','1',669147,2955),(123901,30,2,'e','1',669147,2753),(123902,30,3,'e','1',669147,2819),(123903,31,0,'e','1',669147,2969),(123904,31,1,'n','1',669147,2789),(123905,31,2,'n','1',669147,2858),(123906,31,3,'e','1',669147,2739),(123907,32,0,'n','1',669147,2873),(123908,32,1,'e','1',669147,2900),(123909,32,2,'x','0',669147,2880),(123910,32,3,'n','1',669147,2871),(123911,32,4,'s','1',669147,2977),(123912,33,0,'s','1',669147,2871),(123913,33,1,'e','1',669147,2941),(123914,33,2,'n','1',669147,2781),(123915,33,3,'w','1',669147,2873),(123916,2,0,'n','1',669148,2721),(123917,2,1,'n','1',669148,2754),(123918,2,2,'n','1',669148,2810),(123919,2,3,'n','1',669148,2811),(123920,3,0,'w','1',669148,2812),(123921,3,1,'w','1',669148,2813),(123922,3,2,'w','1',669148,2814),(123923,3,3,'n','1',669148,2815),(123924,4,0,'n','1',669148,2816),(123925,4,1,'n','1',669148,2732),(123926,4,2,'n','1',669148,2749),(123927,4,3,'e','1',669148,2818),(123928,5,0,'w','1',669148,2863),(123929,5,1,'n','1',669148,2765),(123930,5,2,'s','1',669148,2988),(123931,5,3,'s','1',669148,3038),(123932,6,0,'w','1',669148,2765),(123933,6,1,'s','1',669148,2768),(123934,6,2,'w','1',669148,2954),(123935,6,3,'s','1',669148,2855),(123936,7,0,'e','1',669148,2750),(123937,7,1,'e','1',669148,2749),(123938,7,2,'s','1',669148,2734),(123939,7,3,'w','1',669148,2820),(123940,8,0,'w','1',669148,2817),(123941,8,1,'w','1',669148,2872),(123942,8,2,'w','1',669148,2725),(123943,8,3,'n','1',669148,2737),(123944,9,0,'e','1',669148,2733),(123945,9,1,'w','1',669148,2842),(123946,9,2,'n','1',669148,2736),(123947,9,3,'n','1',669148,2782),(123948,10,0,'e','1',669148,2762),(123949,10,1,'n','1',669148,2733),(123950,10,2,'w','1',669148,2737),(123951,10,3,'n','1',669148,2797),(123952,11,0,'e','1',669148,2825),(123953,11,1,'n','1',669148,2759),(123954,11,2,'n','1',669148,2798),(123955,11,3,'w','1',669148,2734),(123956,12,0,'e','1',669148,2852),(123957,12,1,'n','1',669148,2749),(123958,12,2,'e','1',669148,2719),(123959,12,3,'e','1',669148,2725),(123960,13,0,'n','1',669148,2824),(123961,13,1,'n','1',669148,2759),(123962,13,2,'n','1',669148,2838),(123963,13,3,'n','1',669148,2870),(123964,14,0,'s','1',669148,2764),(123965,14,1,'w','1',669148,2765),(123966,14,2,'w','1',669148,2757),(123967,14,3,'n','1',669148,2839),(123968,15,0,'s','1',669148,2768),(123969,15,1,'s','1',669148,2854),(123970,15,2,'w','1',669148,2750),(123971,15,3,'n','1',669148,2818),(123972,16,0,'w','1',669148,2725),(123973,16,1,'s','1',669148,2855),(123974,16,2,'s','1',669148,2751),(123975,16,3,'n','1',669148,2789),(123976,17,0,'n','1',669148,2968),(123977,17,1,'n','1',669148,2981),(123978,17,2,'e','1',669148,2904),(123979,17,3,'s','1',669148,2943),(123980,18,0,'n','1',669148,2982),(123981,18,1,'n','1',669148,2900),(123982,18,2,'e','1',669148,2767),(123983,18,3,'e','1',669148,2899),(123984,19,0,'e','1',669148,2885),(123985,19,1,'w','1',669148,2773),(123986,19,2,'s','1',669148,2938),(123987,19,3,'n','1',669148,2927),(123988,20,0,'s','1',669148,2833),(123989,20,1,'e','1',669148,2764),(123990,20,2,'s','1',669148,2788),(123991,20,3,'s','1',669148,2970),(123992,21,0,'e','1',669148,2739),(123993,21,1,'e','1',669148,2902),(123994,21,2,'e','1',669148,2822),(123995,21,3,'n','1',669148,2724),(123996,22,0,'s','1',669148,2953),(123997,22,1,'n','1',669148,2852),(123998,22,2,'n','1',669148,2755),(123999,22,3,'s','1',669148,2970),(124000,23,0,'s','1',669148,2915),(124001,23,1,'e','1',669148,2903),(124002,23,2,'n','1',669148,2963),(124003,24,0,'w','1',669148,2787),(124004,24,1,'s','1',669148,2755),(124005,24,2,'e','1',669148,2746),(124006,24,3,'e','1',669148,2901),(124007,25,0,'n','1',669148,2823),(124008,25,1,'e','1',669148,2839),(124009,25,2,'n','1',669148,2745),(124010,25,3,'n','1',669148,2989),(124011,26,0,'n','1',669148,2730),(124012,26,1,'w','1',669148,2851),(124013,26,2,'w','1',669148,2785),(124014,26,3,'s','1',669148,2751),(124015,27,0,'w','1',669148,2719),(124016,27,1,'e','1',669148,2939),(124017,27,2,'s','1',669148,2781),(124018,28,0,'n','1',669148,2795),(124019,28,1,'w','1',669148,2762),(124020,28,2,'n','1',669148,2888),(124021,28,3,'n','1',669148,2989),(124022,29,0,'e','1',669148,2915),(124023,29,1,'e','1',669148,2740),(124024,29,2,'w','1',669148,2737),(124025,29,3,'w','1',669148,3039),(124026,30,0,'e','1',669148,2953),(124027,30,1,'e','1',669148,2740),(124028,30,2,'n','1',669148,2934),(124029,31,0,'n','1',669148,2806),(124030,31,1,'x','0',669148,2757),(124031,31,2,'n','1',669148,2843),(124032,31,3,'e','1',669148,2926),(124033,31,4,'n','1',669148,2837),(124034,2,0,'n','1',669148,2721),(124035,2,1,'n','1',669148,2754),(124036,2,2,'n','1',669148,2810),(124037,2,3,'n','1',669148,2811),(124038,3,0,'w','1',669148,2812),(124039,3,1,'w','1',669148,2813),(124040,3,2,'w','1',669148,2814),(124041,3,3,'n','1',669148,2815),(124042,4,0,'n','1',669148,2816),(124043,4,1,'n','1',669148,2732),(124044,4,2,'n','1',669148,2749),(124045,4,3,'e','1',669148,2818),(124046,5,0,'w','1',669148,2863),(124047,5,1,'n','1',669148,2765),(124048,5,2,'s','1',669148,2988),(124049,5,3,'s','1',669148,3038),(124050,6,0,'w','1',669148,2765),(124051,6,1,'s','1',669148,2768),(124052,6,2,'w','1',669148,2954),(124053,6,3,'s','1',669148,2855),(124054,7,0,'e','1',669148,2750),(124055,7,1,'e','1',669148,2749),(124056,7,2,'s','1',669148,2734),(124057,7,3,'w','1',669148,2820),(124058,8,0,'w','1',669148,2817),(124059,8,1,'w','1',669148,2872),(124060,8,2,'w','1',669148,2725),(124061,8,3,'n','1',669148,2737),(124062,9,0,'e','1',669148,2733),(124063,9,1,'w','1',669148,2842),(124064,9,2,'n','1',669148,2736),(124065,9,3,'n','1',669148,2782),(124066,10,0,'e','1',669148,2762),(124067,10,1,'n','1',669148,2733),(124068,10,2,'w','1',669148,2737),(124069,10,3,'n','1',669148,2797),(124070,11,0,'e','1',669148,2825),(124071,11,1,'n','1',669148,2759),(124072,11,2,'n','1',669148,2798),(124073,11,3,'w','1',669148,2734),(124074,12,0,'e','1',669148,2852),(124075,12,1,'n','1',669148,2749),(124076,12,2,'e','1',669148,2719),(124077,12,3,'e','1',669148,2725),(124078,13,0,'n','1',669148,2824),(124079,13,1,'n','1',669148,2759),(124080,13,2,'n','1',669148,2838),(124081,13,3,'n','1',669148,2870),(124082,14,0,'s','1',669148,2764),(124083,14,1,'w','1',669148,2765),(124084,14,2,'w','1',669148,2757),(124085,14,3,'n','1',669148,2839),(124086,15,0,'s','1',669148,2768),(124087,15,1,'s','1',669148,2854),(124088,15,2,'w','1',669148,2750),(124089,15,3,'n','1',669148,2818),(124090,16,0,'w','1',669148,2725),(124091,16,1,'s','1',669148,2855),(124092,16,2,'s','1',669148,2751),(124093,16,3,'n','1',669148,2789),(124094,17,0,'n','1',669148,2968),(124095,17,1,'n','1',669148,2981),(124096,17,2,'e','1',669148,2904),(124097,17,3,'s','1',669148,2943),(124098,18,0,'n','1',669148,2982),(124099,18,1,'n','1',669148,2900),(124100,18,2,'e','1',669148,2767),(124101,18,3,'e','1',669148,2899),(124102,19,0,'e','1',669148,2885),(124103,19,1,'w','1',669148,2773),(124104,19,2,'s','1',669148,2938),(124105,19,3,'n','1',669148,2927),(124106,20,0,'s','1',669148,2833),(124107,20,1,'e','1',669148,2764),(124108,20,2,'s','1',669148,2788),(124109,20,3,'s','1',669148,2970),(124110,21,0,'e','1',669148,2739),(124111,21,1,'e','1',669148,2902),(124112,21,2,'e','1',669148,2822),(124113,21,3,'n','1',669148,2724),(124114,22,0,'s','1',669148,2953),(124115,22,1,'n','1',669148,2852),(124116,22,2,'n','1',669148,2755),(124117,22,3,'s','1',669148,2970),(124118,23,0,'s','1',669148,2915),(124119,23,1,'e','1',669148,2903),(124120,23,2,'n','1',669148,2963),(124121,24,0,'w','1',669148,2787),(124122,24,1,'s','1',669148,2755),(124123,24,2,'e','1',669148,2746),(124124,24,3,'e','1',669148,2901),(124125,25,0,'n','1',669148,2823),(124126,25,1,'e','1',669148,2839),(124127,25,2,'n','1',669148,2745),(124128,25,3,'n','1',669148,2989),(124129,26,0,'n','1',669148,2730),(124130,26,1,'w','1',669148,2851),(124131,26,2,'w','1',669148,2785),(124132,26,3,'s','1',669148,2751),(124133,27,0,'w','1',669148,2719),(124134,27,1,'e','1',669148,2939),(124135,27,2,'s','1',669148,2781),(124136,28,0,'n','1',669148,2795),(124137,28,1,'w','1',669148,2762),(124138,28,2,'n','1',669148,2888),(124139,28,3,'n','1',669148,2989),(124140,29,0,'e','1',669148,2915),(124141,29,1,'e','1',669148,2740),(124142,29,2,'w','1',669148,2737),(124143,29,3,'w','1',669148,3039),(124144,30,0,'e','1',669148,2953),(124145,30,1,'e','1',669148,2740),(124146,30,2,'n','1',669148,2934),(124147,31,0,'n','1',669148,2806),(124148,31,1,'x','0',669148,2757),(124149,31,2,'n','1',669148,2843),(124150,31,3,'e','1',669148,2926),(124151,31,4,'n','1',669148,2837),(124152,2,0,'n','1',669149,2867),(124153,2,1,'n','1',669149,2816),(124154,2,2,'n','1',669149,2732),(124155,2,3,'n','1',669149,2749),(124156,3,0,'n','1',669149,2721),(124157,3,1,'n','1',669149,2754),(124158,3,2,'n','1',669149,2820),(124159,3,3,'n','1',669149,2717),(124160,4,0,'w','1',669149,2921),(124161,4,1,'e','1',669149,2719),(124162,4,2,'e','1',669149,2725),(124163,4,3,'e','1',669149,2735),(124164,5,0,'w','1',669149,2765),(124165,5,1,'e','1',669149,2768),(124166,5,2,'s','1',669149,2944),(124167,5,3,'e','1',669149,2759),(124168,6,0,'e','1',669149,2884),(124169,6,1,'e','1',669149,2883),(124170,6,2,'n','1',669149,2875),(124171,6,3,'e','1',669149,2759),(124172,7,0,'s','1',669149,2773),(124173,7,1,'w','1',669149,2765),(124174,7,2,'s','1',669149,2921),(124175,7,3,'s','1',669149,2849),(124176,8,0,'w','1',669149,2875),(124177,8,1,'s','1',669149,2774),(124178,8,2,'s','1',669149,2768),(124179,8,3,'n','1',669149,2739),(124180,9,0,'e','1',669149,2750),(124181,9,1,'e','1',669149,2749),(124182,9,2,'s','1',669149,2775),(124183,9,3,'s','1',669149,2776),(124184,10,0,'e','1',669149,2777),(124185,10,1,'n','1',669149,2739),(124186,10,2,'e','1',669149,2883),(124187,10,3,'e','1',669149,2795),(124188,10,4,'x','0',669149,2762),(124189,11,0,'w','1',669149,2775),(124190,11,1,'w','1',669149,2875),(124191,11,2,'w','1',669149,2883),(124192,11,3,'w','1',669149,2884),(124193,12,0,'s','1',669149,2759),(124194,12,1,'s','1',669149,2737),(124195,12,2,'w','1',669149,2734),(124196,12,3,'w','1',669149,2749),(124197,13,0,'n','1',669149,2946),(124198,13,1,'n','1',669149,2784),(124199,13,2,'e','1',669149,2750),(124200,13,3,'e','1',669149,2948),(124201,14,0,'e','1',669149,2832),(124202,14,1,'e','1',669149,2804),(124203,14,2,'w','1',669149,2820),(124204,14,3,'s','1',669149,2917),(124205,15,0,'s','1',669149,2749),(124206,15,1,'w','1',669149,2732),(124207,15,2,'s','1',669149,2731),(124208,15,3,'w','1',669149,2874),(124209,16,0,'e','1',669149,2727),(124210,16,1,'e','1',669149,2719),(124211,16,2,'x','0',669149,2725),(124212,16,3,'w','1',669149,2785),(124213,16,4,'s','1',669149,2932),(124214,17,0,'s','1',669149,2946),(124215,17,1,'x','0',669149,2950),(124216,17,2,'e','1',669149,2848),(124217,17,3,'n','1',669149,2874),(124218,17,4,'n','1',669149,2731),(124219,18,0,'e','1',669149,2815),(124220,18,1,'n','1',669149,2964),(124221,18,2,'n','1',669149,2750),(124222,18,3,'n','1',669149,2790),(124223,19,0,'s','1',669149,2768),(124224,19,1,'s','1',669149,2944),(124225,19,2,'s','1',669149,2793),(124226,19,3,'s','1',669149,2785),(124227,20,0,'e','1',669149,2784),(124228,20,1,'n','1',669149,2963),(124229,20,2,'w','1',669149,2750),(124230,20,3,'s','1',669149,2773),(124231,21,0,'n','1',669149,2915),(124232,21,1,'n','1',669149,2786),(124233,21,2,'s','1',669149,2851),(124234,21,3,'s','1',669149,2774),(124235,22,0,'e','1',669149,2775),(124236,22,1,'s','1',669149,2776),(124237,22,2,'w','1',669149,2777),(124238,22,3,'w','1',669149,2786),(124239,23,0,'e','1',669149,2872),(124240,23,1,'w','1',669149,2772),(124241,23,2,'n','1',669149,2902),(124242,23,3,'n','1',669149,2858),(124243,24,0,'s','1',669149,2787),(124244,24,1,'e','1',669149,2751),(124245,24,2,'n','1',669149,2750),(124246,24,3,'n','1',669149,2768),(124247,25,0,'s','1',669149,2890),(124248,25,1,'e','1',669149,2767),(124249,25,2,'s','1',669149,2768),(124250,25,3,'s','1',669149,2944),(124251,26,0,'e','1',669149,2773),(124252,26,1,'n','1',669149,2750),(124253,26,2,'n','1',669149,2736),(124254,26,3,'n','1',669149,2737),(124255,27,0,'n','1',669149,2786),(124256,27,1,'n','1',669149,2787),(124257,27,2,'s','1',669149,2788),(124258,27,3,'s','1',669149,2852),(124259,28,0,'e','1',669149,2768),(124260,28,1,'x','0',669149,2859),(124261,28,2,'e','1',669149,2798),(124262,28,3,'s','1',669149,2765),(124263,29,0,'w','1',669149,2851),(124264,29,1,'s','1',669149,2785),(124265,29,2,'n','1',669149,2838),(124266,29,3,'n','1',669149,2888),(124267,30,0,'n','1',669149,2784),(124268,30,1,'s','1',669149,2851),(124269,30,2,'s','1',669149,2785),(124270,30,3,'e','1',669149,2775),(124271,31,0,'n','1',669149,2784),(124272,31,1,'s','1',669149,2851),(124273,31,2,'e','1',669149,2775),(124274,31,3,'s','1',669149,2785),(124275,32,0,'n','1',669149,2905),(124276,32,1,'n','1',669149,2749),(124277,32,2,'n','1',669149,2903),(124278,33,0,'n','1',669149,2784),(124279,33,1,'s','1',669149,2851),(124280,33,2,'e','1',669149,2775),(124281,33,3,'s','1',669149,2785),(124282,34,0,'s','1',669149,2759),(124283,34,1,'e','1',669149,2758),(124284,34,2,'e','1',669149,2737),(124285,34,3,'s','1',669149,2843),(124286,35,0,'s','1',669149,2839),(124287,35,1,'s','1',669149,2820),(124288,35,2,'w','1',669149,2754),(124289,35,3,'n','1',669149,2834),(124290,36,0,'e','1',669149,2765),(124291,36,1,'w','1',669149,2744),(124292,36,2,'s','1',669149,2826),(124293,36,3,'e','1',669149,2775),(124294,37,0,'n','1',669149,2872),(124295,37,1,'n','1',669149,2877),(124296,37,2,'n','1',669149,2822),(124297,38,0,'w','1',669149,2878),(124298,38,1,'n','1',669149,2981),(124299,38,2,'n','1',669149,2943),(124300,38,3,'n','1',669149,2904),(124301,39,0,'n','1',669149,2982),(124302,39,1,'e','1',669149,3030),(124303,39,2,'e','1',669149,2784),(124304,39,3,'n','1',669149,2882),(124305,40,0,'e','1',669149,3040),(124306,40,1,'n','1',669149,2899),(124307,40,2,'n','1',669149,2736),(124308,40,3,'n','1',669149,2838),(124309,41,0,'w','1',669149,2737),(124310,41,1,'n','1',669149,2740),(124311,41,2,'w','1',669149,2765),(124312,41,3,'w','1',669149,2757),(124313,42,0,'n','1',669149,2934),(124314,42,1,'e','1',669149,2897),(124315,42,2,'n','1',669149,2901),(124316,42,3,'e','1',669149,2787),(124317,43,0,'e','1',669149,2802),(124318,43,1,'n','1',669149,2817),(124319,43,2,'n','1',669149,2905),(124320,43,3,'n','1',669149,2762),(124321,44,0,'w','1',669149,2824),(124322,44,1,'s','1',669149,2959),(124323,44,2,'w','1',669149,2745),(124324,44,3,'n','1',669149,2823),(124325,45,0,'w','1',669149,2762),(124326,45,1,'n','1',669149,2795),(124327,45,2,'n','1',669149,2796),(124328,45,3,'n','1',669149,2829),(124329,46,0,'s','1',669149,2923),(124330,46,1,'s','1',669149,2729),(124331,46,2,'w','1',669149,2824),(124332,46,3,'x','0',669149,2762),(124333,46,4,'n','1',669149,2958),(124334,47,0,'s','1',669149,2898),(124335,47,1,'e','1',669149,2899),(124336,47,2,'w','1',669149,2761),(124337,47,3,'e','1',669149,2775),(124338,48,0,'w','1',669149,2831),(124339,48,1,'n','1',669149,2781),(124340,48,2,'n','1',669149,2887),(124341,48,3,'n','1',669149,2791),(124342,49,0,'e','1',669149,2756),(124343,49,1,'n','1',669149,2837),(124344,49,2,'n','1',669149,2759),(124345,49,3,'n','1',669149,2928),(124346,50,0,'s','1',669149,2768),(124347,50,1,'w','1',669149,2852),(124348,50,2,'n','1',669149,2773),(124349,50,3,'n','1',669149,2750),(124350,51,0,'s','1',669149,2768),(124351,51,1,'w','1',669149,2852),(124352,51,2,'n','1',669149,2773),(124353,51,3,'n','1',669149,2750),(124354,52,0,'n','1',669149,2798),(124355,52,1,'w','1',669149,2912),(124356,52,2,'n','1',669149,2852),(124357,52,3,'w','1',669149,2745),(124358,53,0,'w','1',669149,2796),(124359,53,1,'n','1',669149,2776),(124360,53,2,'w','1',669149,2774),(124361,53,3,'n','1',669149,2909),(124362,54,0,'n','1',669149,2777),(124363,54,1,'w','1',669149,2776),(124364,54,2,'n','1',669149,2794),(124365,54,3,'s','1',669149,2929),(124366,55,0,'e','1',669149,2729),(124367,55,1,'n','1',669149,2745),(124368,55,2,'n','1',669149,2984),(124369,55,3,'n','1',669149,3041),(124370,56,0,'w','1',669149,2923),(124371,56,1,'n','1',669149,2803),(124372,56,2,'e','1',669149,2909),(124373,56,3,'e','1',669149,2950),(124374,2,0,'n','1',669149,2867),(124375,2,1,'n','1',669149,2816),(124376,2,2,'n','1',669149,2732),(124377,2,3,'n','1',669149,2749),(124378,3,0,'n','1',669149,2721),(124379,3,1,'n','1',669149,2754),(124380,3,2,'n','1',669149,2820),(124381,3,3,'n','1',669149,2717),(124382,4,0,'w','1',669149,2921),(124383,4,1,'e','1',669149,2719),(124384,4,2,'e','1',669149,2725),(124385,4,3,'e','1',669149,2735),(124386,5,0,'w','1',669149,2765),(124387,5,1,'e','1',669149,2768),(124388,5,2,'s','1',669149,2944),(124389,5,3,'e','1',669149,2759),(124390,6,0,'e','1',669149,2884),(124391,6,1,'e','1',669149,2883),(124392,6,2,'n','1',669149,2875),(124393,6,3,'e','1',669149,2759),(124394,7,0,'s','1',669149,2773),(124395,7,1,'w','1',669149,2765),(124396,7,2,'s','1',669149,2921),(124397,7,3,'s','1',669149,2849),(124398,8,0,'w','1',669149,2875),(124399,8,1,'s','1',669149,2774),(124400,8,2,'s','1',669149,2768),(124401,8,3,'n','1',669149,2739),(124402,9,0,'e','1',669149,2750),(124403,9,1,'e','1',669149,2749),(124404,9,2,'s','1',669149,2775),(124405,9,3,'s','1',669149,2776),(124406,10,0,'e','1',669149,2777),(124407,10,1,'n','1',669149,2739),(124408,10,2,'e','1',669149,2883),(124409,10,3,'e','1',669149,2795),(124410,10,4,'x','0',669149,2762),(124411,11,0,'w','1',669149,2775),(124412,11,1,'w','1',669149,2875),(124413,11,2,'w','1',669149,2883),(124414,11,3,'w','1',669149,2884),(124415,12,0,'s','1',669149,2759),(124416,12,1,'s','1',669149,2737),(124417,12,2,'w','1',669149,2734),(124418,12,3,'w','1',669149,2749),(124419,13,0,'n','1',669149,2946),(124420,13,1,'n','1',669149,2784),(124421,13,2,'e','1',669149,2750),(124422,13,3,'e','1',669149,2948),(124423,14,0,'e','1',669149,2832),(124424,14,1,'e','1',669149,2804),(124425,14,2,'w','1',669149,2820),(124426,14,3,'s','1',669149,2917),(124427,15,0,'s','1',669149,2749),(124428,15,1,'w','1',669149,2732),(124429,15,2,'s','1',669149,2731),(124430,15,3,'w','1',669149,2874),(124431,16,0,'e','1',669149,2727),(124432,16,1,'e','1',669149,2719),(124433,16,2,'x','0',669149,2725),(124434,16,3,'w','1',669149,2785),(124435,16,4,'s','1',669149,2932),(124436,17,0,'s','1',669149,2946),(124437,17,1,'x','0',669149,2950),(124438,17,2,'e','1',669149,2848),(124439,17,3,'n','1',669149,2874),(124440,17,4,'n','1',669149,2731),(124441,18,0,'e','1',669149,2815),(124442,18,1,'n','1',669149,2964),(124443,18,2,'n','1',669149,2750),(124444,18,3,'n','1',669149,2790),(124445,19,0,'s','1',669149,2768),(124446,19,1,'s','1',669149,2944),(124447,19,2,'s','1',669149,2793),(124448,19,3,'s','1',669149,2785),(124449,20,0,'e','1',669149,2784),(124450,20,1,'n','1',669149,2963),(124451,20,2,'w','1',669149,2750),(124452,20,3,'s','1',669149,2773),(124453,21,0,'n','1',669149,2915),(124454,21,1,'n','1',669149,2786),(124455,21,2,'s','1',669149,2851),(124456,21,3,'s','1',669149,2774),(124457,22,0,'e','1',669149,2775),(124458,22,1,'s','1',669149,2776),(124459,22,2,'w','1',669149,2777),(124460,22,3,'w','1',669149,2786),(124461,23,0,'e','1',669149,2872),(124462,23,1,'w','1',669149,2772),(124463,23,2,'n','1',669149,2902),(124464,23,3,'n','1',669149,2858),(124465,24,0,'s','1',669149,2787),(124466,24,1,'e','1',669149,2751),(124467,24,2,'n','1',669149,2750),(124468,24,3,'n','1',669149,2768),(124469,25,0,'s','1',669149,2890),(124470,25,1,'e','1',669149,2767),(124471,25,2,'s','1',669149,2768),(124472,25,3,'s','1',669149,2944),(124473,26,0,'e','1',669149,2773),(124474,26,1,'n','1',669149,2750),(124475,26,2,'n','1',669149,2736),(124476,26,3,'n','1',669149,2737),(124477,27,0,'n','1',669149,2786),(124478,27,1,'n','1',669149,2787),(124479,27,2,'s','1',669149,2788),(124480,27,3,'s','1',669149,2852),(124481,28,0,'e','1',669149,2768),(124482,28,1,'x','0',669149,2859),(124483,28,2,'e','1',669149,2798),(124484,28,3,'s','1',669149,2765),(124485,29,0,'w','1',669149,2851),(124486,29,1,'s','1',669149,2785),(124487,29,2,'n','1',669149,2838),(124488,29,3,'n','1',669149,2888),(124489,30,0,'n','1',669149,2784),(124490,30,1,'s','1',669149,2851),(124491,30,2,'s','1',669149,2785),(124492,30,3,'e','1',669149,2775),(124493,31,0,'n','1',669149,2784),(124494,31,1,'s','1',669149,2851),(124495,31,2,'e','1',669149,2775),(124496,31,3,'s','1',669149,2785),(124497,32,0,'n','1',669149,2905),(124498,32,1,'n','1',669149,2749),(124499,32,2,'n','1',669149,2903),(124500,33,0,'n','1',669149,2784),(124501,33,1,'s','1',669149,2851),(124502,33,2,'e','1',669149,2775),(124503,33,3,'s','1',669149,2785),(124504,34,0,'s','1',669149,2759),(124505,34,1,'e','1',669149,2758),(124506,34,2,'e','1',669149,2737),(124507,34,3,'s','1',669149,2843),(124508,35,0,'s','1',669149,2839),(124509,35,1,'s','1',669149,2820),(124510,35,2,'w','1',669149,2754),(124511,35,3,'n','1',669149,2834),(124512,36,0,'e','1',669149,2765),(124513,36,1,'w','1',669149,2744),(124514,36,2,'s','1',669149,2826),(124515,36,3,'e','1',669149,2775),(124516,37,0,'n','1',669149,2872),(124517,37,1,'n','1',669149,2877),(124518,37,2,'n','1',669149,2822),(124519,38,0,'w','1',669149,2878),(124520,38,1,'n','1',669149,2981),(124521,38,2,'n','1',669149,2943),(124522,38,3,'n','1',669149,2904),(124523,39,0,'n','1',669149,2982),(124524,39,1,'e','1',669149,3030),(124525,39,2,'e','1',669149,2784),(124526,39,3,'n','1',669149,2882),(124527,40,0,'e','1',669149,3040),(124528,40,1,'n','1',669149,2899),(124529,40,2,'n','1',669149,2736),(124530,40,3,'n','1',669149,2838),(124531,41,0,'w','1',669149,2737),(124532,41,1,'n','1',669149,2740),(124533,41,2,'w','1',669149,2765),(124534,41,3,'w','1',669149,2757),(124535,42,0,'n','1',669149,2934),(124536,42,1,'e','1',669149,2897),(124537,42,2,'n','1',669149,2901),(124538,42,3,'e','1',669149,2787),(124539,43,0,'e','1',669149,2802),(124540,43,1,'n','1',669149,2817),(124541,43,2,'n','1',669149,2905),(124542,43,3,'n','1',669149,2762),(124543,44,0,'w','1',669149,2824),(124544,44,1,'s','1',669149,2959),(124545,44,2,'w','1',669149,2745),(124546,44,3,'n','1',669149,2823),(124547,45,0,'w','1',669149,2762),(124548,45,1,'n','1',669149,2795),(124549,45,2,'n','1',669149,2796),(124550,45,3,'n','1',669149,2829),(124551,46,0,'s','1',669149,2923),(124552,46,1,'s','1',669149,2729),(124553,46,2,'w','1',669149,2824),(124554,46,3,'x','0',669149,2762),(124555,46,4,'n','1',669149,2958),(124556,47,0,'s','1',669149,2898),(124557,47,1,'e','1',669149,2899),(124558,47,2,'w','1',669149,2761),(124559,47,3,'e','1',669149,2775),(124560,48,0,'w','1',669149,2831),(124561,48,1,'n','1',669149,2781),(124562,48,2,'n','1',669149,2887),(124563,48,3,'n','1',669149,2791),(124564,49,0,'e','1',669149,2756),(124565,49,1,'n','1',669149,2837),(124566,49,2,'n','1',669149,2759),(124567,49,3,'n','1',669149,2928),(124568,50,0,'s','1',669149,2768),(124569,50,1,'w','1',669149,2852),(124570,50,2,'n','1',669149,2773),(124571,50,3,'n','1',669149,2750),(124572,51,0,'s','1',669149,2768),(124573,51,1,'w','1',669149,2852),(124574,51,2,'n','1',669149,2773),(124575,51,3,'n','1',669149,2750),(124576,52,0,'n','1',669149,2798),(124577,52,1,'w','1',669149,2912),(124578,52,2,'n','1',669149,2852),(124579,52,3,'w','1',669149,2745),(124580,53,0,'w','1',669149,2796),(124581,53,1,'n','1',669149,2776),(124582,53,2,'w','1',669149,2774),(124583,53,3,'n','1',669149,2909),(124584,54,0,'n','1',669149,2777),(124585,54,1,'w','1',669149,2776),(124586,54,2,'n','1',669149,2794),(124587,54,3,'s','1',669149,2929),(124588,55,0,'e','1',669149,2729),(124589,55,1,'n','1',669149,2745),(124590,55,2,'n','1',669149,2984),(124591,55,3,'n','1',669149,3041),(124592,56,0,'w','1',669149,2923),(124593,56,1,'n','1',669149,2803),(124594,56,2,'e','1',669149,2909),(124595,56,3,'e','1',669149,2950),(124596,2,0,'n','1',669150,3022),(124597,2,1,'n','1',669150,3017),(124598,2,2,'n','1',669150,2815),(124599,2,3,'n','1',669150,2723),(124600,3,0,'e','1',669150,2986),(124601,3,1,'n','1',669150,2867),(124602,3,2,'n','1',669150,2816),(124603,3,3,'e','1',669150,2760),(124604,4,0,'e','1',669150,2818),(124605,4,1,'n','1',669150,2736),(124606,4,2,'n','1',669150,2737),(124607,4,3,'n','1',669150,2759),(124608,5,0,'n','1',669150,2732),(124609,5,1,'n','1',669150,2749),(124610,5,2,'e','1',669150,2822),(124611,5,3,'n','1',669150,2868),(124612,6,0,'w','1',669150,2806),(124613,6,1,'e','1',669150,2807),(124614,6,2,'s','1',669150,2826),(124615,6,3,'n','1',669150,2956),(124616,7,0,'n','1',669150,2834),(124617,7,1,'n','1',669150,2823),(124618,7,2,'n','1',669150,2745),(124619,7,3,'n','1',669150,3037),(124620,8,0,'s','1',669150,2759),(124621,8,1,'e','1',669150,2872),(124622,8,2,'e','1',669150,2772),(124623,8,3,'n','1',669150,3015),(124624,9,0,'s','1',669150,2765),(124625,9,1,'w','1',669150,2749),(124626,9,2,'w','1',669150,2750),(124627,9,3,'w','1',669150,2751),(124628,10,0,'e','1',669150,2871),(124629,10,1,'s','1',669150,2769),(124630,10,2,'s','1',669150,2846),(124631,10,3,'w','1',669150,2751),(124632,11,0,'n','1',669150,2737),(124633,11,1,'w','1',669150,2759),(124634,11,2,'n','1',669150,2875),(124635,11,3,'n','1',669150,2849),(124636,12,0,'s','1',669150,2804),(124637,12,1,'s','1',669150,2806),(124638,12,2,'e','1',669150,2871),(124639,12,3,'s','1',669150,2751),(124640,13,0,'e','1',669150,2756),(124641,13,1,'w','1',669150,2825),(124642,13,2,'n','1',669150,2759),(124643,13,3,'n','1',669150,2849),(124644,14,0,'w','1',669150,2989),(124645,14,1,'s','1',669150,2921),(124646,14,2,'e','1',669150,2804),(124647,14,3,'n','1',669150,2806),(124648,15,0,'n','1',669150,2819),(124649,15,1,'e','1',669150,3006),(124650,15,2,'n','1',669150,2730),(124651,15,3,'w','1',669150,2751),(124652,16,0,'w','1',669150,2825),(124653,16,1,'s','1',669150,2926),(124654,16,2,'e','1',669150,2871),(124655,16,3,'s','1',669150,2769),(124656,17,0,'e','1',669150,2751),(124657,17,1,'n','1',669150,2750),(124658,17,2,'s','1',669150,2852),(124659,17,3,'e','1',669150,2768),(124660,18,0,'w','1',669150,2839),(124661,18,1,'w','1',669150,2850),(124662,18,2,'s','1',669150,2948),(124663,18,3,'s','1',669150,2798),(124664,19,0,'w','1',669150,2884),(124665,19,1,'s','1',669150,2796),(124666,19,2,'w','1',669150,2735),(124667,19,3,'w','1',669150,2725),(124668,20,0,'n','1',669150,2965),(124669,20,1,'n','1',669150,2908),(124670,20,2,'s','1',669150,2785),(124671,20,3,'s','1',669150,2770),(124672,21,0,'n','1',669150,2908),(124673,21,1,'s','1',669150,2785),(124674,21,2,'e','1',669150,2934),(124675,21,3,'e','1',669150,2795),(124676,21,4,'x','0',669150,2762),(124677,22,0,'e','1',669150,2770),(124678,22,1,'e','1',669150,2746),(124679,22,2,'w','1',669150,2839),(124680,22,3,'e','1',669150,2740),(124681,23,0,'e','1',669150,2719),(124682,23,1,'e','1',669150,2785),(124683,23,2,'s','1',669150,2851),(124684,23,3,'w','1',669150,2725),(124685,24,0,'w','1',669150,2765),(124686,24,1,'s','1',669150,2863),(124687,24,2,'s','1',669150,2833),(124688,24,3,'e','1',669150,2768),(124689,25,0,'e','1',669150,2765),(124690,25,1,'w','1',669150,2744),(124691,25,2,'s','1',669150,2808),(124692,25,3,'n','1',669150,2958),(124693,26,0,'w','1',669150,2902),(124694,26,1,'w','1',669150,2822),(124695,26,2,'e','1',669150,3009),(124696,26,3,'n','1',669150,2882),(124697,27,0,'n','1',669150,2934),(124698,27,1,'e','1',669150,2887),(124699,27,2,'w','1',669150,2858),(124700,27,3,'n','1',669150,2962),(124701,28,0,'w','1',669150,2822),(124702,28,1,'w','1',669150,2966),(124703,28,2,'w','1',669150,2790),(124704,28,3,'n','1',669150,2858),(124705,29,0,'e','1',669150,2775),(124706,29,1,'n','1',669150,2786),(124707,29,2,'n','1',669150,2787),(124708,29,3,'n','1',669150,2789),(124709,30,0,'e','1',669150,2719),(124710,30,1,'n','1',669150,2725),(124711,30,2,'n','1',669150,2855),(124712,30,3,'n','1',669150,2887),(124713,31,0,'w','1',669150,2923),(124714,31,1,'n','1',669150,2795),(124715,31,2,'n','1',669150,2737),(124716,31,3,'w','1',669150,2803),(124717,32,0,'w','1',669150,2786),(124718,32,1,'w','1',669150,2903),(124719,32,2,'w','1',669150,2797),(124720,32,3,'w','1',669150,2790),(124721,33,0,'n','1',669150,2950),(124722,33,1,'w','1',669150,2946),(124723,33,2,'n','1',669150,2779),(124724,33,3,'w','1',669150,2858),(124725,34,0,'n','1',669150,2962),(124726,34,1,'w','1',669150,2775),(124727,34,2,'n','1',669150,2784),(124728,35,0,'s','1',669150,2807),(124729,35,1,'s','1',669150,2808),(124730,35,2,'w','1',669150,2756),(124731,35,3,'s','1',669150,2809),(124732,36,0,'e','1',669150,2897),(124733,36,1,'s','1',669150,2961),(124734,36,2,'w','1',669150,2759),(124735,36,3,'s','1',669150,2851),(124736,37,0,'s','1',669150,2860),(124737,37,1,'w','1',669150,2765),(124738,37,2,'n','1',669150,2755),(124739,37,3,'n','1',669150,2953),(124740,38,0,'w','1',669150,2768),(124741,38,1,'e','1',669150,2881),(124742,38,2,'s','1',669150,2767),(124743,38,3,'x','0',669150,2859),(124744,38,4,'s','1',669150,2854),(124745,39,0,'w','1',669150,2768),(124746,39,1,'w','1',669150,2881),(124747,39,2,'s','1',669150,3007),(124748,39,3,'x','0',669150,2801),(124749,39,4,'w','1',669150,2786),(124750,40,0,'s','1',669150,2897),(124751,40,1,'x','0',669150,2934),(124752,40,2,'s','1',669150,2756),(124753,40,3,'n','1',669150,2740),(124754,40,4,'n','1',669150,2766),(124755,41,0,'s','1',669150,2977),(124756,41,1,'s','1',669150,2871),(124757,41,2,'e','1',669150,2895),(124758,41,3,'n','1',669150,2796),(124759,2,0,'n','1',669150,3022),(124760,2,1,'n','1',669150,3017),(124761,2,2,'n','1',669150,2815),(124762,2,3,'n','1',669150,2723),(124763,3,0,'e','1',669150,2986),(124764,3,1,'n','1',669150,2867),(124765,3,2,'n','1',669150,2816),(124766,3,3,'e','1',669150,2760),(124767,4,0,'e','1',669150,2818),(124768,4,1,'n','1',669150,2736),(124769,4,2,'n','1',669150,2737),(124770,4,3,'n','1',669150,2759),(124771,5,0,'n','1',669150,2732),(124772,5,1,'n','1',669150,2749),(124773,5,2,'e','1',669150,2822),(124774,5,3,'n','1',669150,2868),(124775,6,0,'w','1',669150,2806),(124776,6,1,'e','1',669150,2807),(124777,6,2,'s','1',669150,2826),(124778,6,3,'n','1',669150,2956),(124779,7,0,'n','1',669150,2834),(124780,7,1,'n','1',669150,2823),(124781,7,2,'n','1',669150,2745),(124782,7,3,'n','1',669150,3037),(124783,8,0,'s','1',669150,2759),(124784,8,1,'e','1',669150,2872),(124785,8,2,'e','1',669150,2772),(124786,8,3,'n','1',669150,3015),(124787,9,0,'s','1',669150,2765),(124788,9,1,'w','1',669150,2749),(124789,9,2,'w','1',669150,2750),(124790,9,3,'w','1',669150,2751),(124791,10,0,'e','1',669150,2871),(124792,10,1,'s','1',669150,2769),(124793,10,2,'s','1',669150,2846),(124794,10,3,'w','1',669150,2751),(124795,11,0,'n','1',669150,2737),(124796,11,1,'w','1',669150,2759),(124797,11,2,'n','1',669150,2875),(124798,11,3,'n','1',669150,2849),(124799,12,0,'s','1',669150,2804),(124800,12,1,'s','1',669150,2806),(124801,12,2,'e','1',669150,2871),(124802,12,3,'s','1',669150,2751),(124803,13,0,'e','1',669150,2756),(124804,13,1,'w','1',669150,2825),(124805,13,2,'n','1',669150,2759),(124806,13,3,'n','1',669150,2849),(124807,14,0,'w','1',669150,2989),(124808,14,1,'s','1',669150,2921),(124809,14,2,'e','1',669150,2804),(124810,14,3,'n','1',669150,2806),(124811,15,0,'n','1',669150,2819),(124812,15,1,'e','1',669150,3006),(124813,15,2,'n','1',669150,2730),(124814,15,3,'w','1',669150,2751),(124815,16,0,'w','1',669150,2825),(124816,16,1,'s','1',669150,2926),(124817,16,2,'e','1',669150,2871),(124818,16,3,'s','1',669150,2769),(124819,17,0,'e','1',669150,2751),(124820,17,1,'n','1',669150,2750),(124821,17,2,'s','1',669150,2852),(124822,17,3,'e','1',669150,2768),(124823,18,0,'w','1',669150,2839),(124824,18,1,'w','1',669150,2850),(124825,18,2,'s','1',669150,2948),(124826,18,3,'s','1',669150,2798),(124827,19,0,'w','1',669150,2884),(124828,19,1,'s','1',669150,2796),(124829,19,2,'w','1',669150,2735),(124830,19,3,'w','1',669150,2725),(124831,20,0,'n','1',669150,2965),(124832,20,1,'n','1',669150,2908),(124833,20,2,'s','1',669150,2785),(124834,20,3,'s','1',669150,2770),(124835,21,0,'n','1',669150,2908),(124836,21,1,'s','1',669150,2785),(124837,21,2,'e','1',669150,2934),(124838,21,3,'e','1',669150,2795),(124839,21,4,'x','0',669150,2762),(124840,22,0,'e','1',669150,2770),(124841,22,1,'e','1',669150,2746),(124842,22,2,'w','1',669150,2839),(124843,22,3,'e','1',669150,2740),(124844,23,0,'e','1',669150,2719),(124845,23,1,'e','1',669150,2785),(124846,23,2,'s','1',669150,2851),(124847,23,3,'w','1',669150,2725),(124848,24,0,'w','1',669150,2765),(124849,24,1,'s','1',669150,2863),(124850,24,2,'s','1',669150,2833),(124851,24,3,'e','1',669150,2768),(124852,25,0,'e','1',669150,2765),(124853,25,1,'w','1',669150,2744),(124854,25,2,'s','1',669150,2808),(124855,25,3,'n','1',669150,2958),(124856,26,0,'w','1',669150,2902),(124857,26,1,'w','1',669150,2822),(124858,26,2,'e','1',669150,3009),(124859,26,3,'n','1',669150,2882),(124860,27,0,'n','1',669150,2934),(124861,27,1,'e','1',669150,2887),(124862,27,2,'w','1',669150,2858),(124863,27,3,'n','1',669150,2962),(124864,28,0,'w','1',669150,2822),(124865,28,1,'w','1',669150,2966),(124866,28,2,'w','1',669150,2790),(124867,28,3,'n','1',669150,2858),(124868,29,0,'e','1',669150,2775),(124869,29,1,'n','1',669150,2786),(124870,29,2,'n','1',669150,2787),(124871,29,3,'n','1',669150,2789),(124872,30,0,'e','1',669150,2719),(124873,30,1,'n','1',669150,2725),(124874,30,2,'n','1',669150,2855),(124875,30,3,'n','1',669150,2887),(124876,31,0,'w','1',669150,2923),(124877,31,1,'n','1',669150,2795),(124878,31,2,'n','1',669150,2737),(124879,31,3,'w','1',669150,2803),(124880,32,0,'w','1',669150,2786),(124881,32,1,'w','1',669150,2903),(124882,32,2,'w','1',669150,2797),(124883,32,3,'w','1',669150,2790),(124884,33,0,'n','1',669150,2950),(124885,33,1,'w','1',669150,2946),(124886,33,2,'n','1',669150,2779),(124887,33,3,'w','1',669150,2858),(124888,34,0,'n','1',669150,2962),(124889,34,1,'w','1',669150,2775),(124890,34,2,'n','1',669150,2784),(124891,35,0,'s','1',669150,2807),(124892,35,1,'s','1',669150,2808),(124893,35,2,'w','1',669150,2756),(124894,35,3,'s','1',669150,2809),(124895,36,0,'e','1',669150,2897),(124896,36,1,'s','1',669150,2961),(124897,36,2,'w','1',669150,2759),(124898,36,3,'s','1',669150,2851),(124899,37,0,'s','1',669150,2860),(124900,37,1,'w','1',669150,2765),(124901,37,2,'n','1',669150,2755),(124902,37,3,'n','1',669150,2953),(124903,38,0,'w','1',669150,2768),(124904,38,1,'e','1',669150,2881),(124905,38,2,'s','1',669150,2767),(124906,38,3,'x','0',669150,2859),(124907,38,4,'s','1',669150,2854),(124908,39,0,'w','1',669150,2768),(124909,39,1,'w','1',669150,2881),(124910,39,2,'s','1',669150,3007),(124911,39,3,'x','0',669150,2801),(124912,39,4,'w','1',669150,2786),(124913,40,0,'s','1',669150,2897),(124914,40,1,'x','0',669150,2934),(124915,40,2,'s','1',669150,2756),(124916,40,3,'n','1',669150,2740),(124917,40,4,'n','1',669150,2766),(124918,41,0,'s','1',669150,2977),(124919,41,1,'s','1',669150,2871),(124920,41,2,'e','1',669150,2895),(124921,41,3,'n','1',669150,2796),(124922,2,0,'n','1',669151,2867),(124923,2,1,'n','1',669151,2816),(124924,2,2,'n','1',669151,2732),(124925,2,3,'n','1',669151,2749),(124926,3,0,'n','1',669151,2721),(124927,3,1,'n','1',669151,2754),(124928,3,2,'n','1',669151,2820),(124929,3,3,'w','1',669151,2921),(124930,4,0,'w','1',669151,2759),(124931,4,1,'n','1',669151,2756),(124932,4,2,'s','1',669151,2807),(124933,4,3,'s','1',669151,2826),(124934,5,0,'s','1',669151,2765),(124935,5,1,'s','1',669151,2756),(124936,5,2,'e','1',669151,2749),(124937,5,3,'e','1',669151,2740),(124938,6,0,'n','1',669151,2717),(124939,6,1,'e','1',669151,2719),(124940,6,2,'e','1',669151,2725),(124941,6,3,'e','1',669151,2735),(124942,7,0,'w','1',669151,2734),(124943,7,1,'n','1',669151,2735),(124944,7,2,'e','1',669151,2954),(124945,7,3,'e','1',669151,2948),(124946,8,0,'n','1',669151,2749),(124947,8,1,'e','1',669151,2765),(124948,8,2,'w','1',669151,2744),(124949,8,3,'s','1',669151,2826),(124950,9,0,'n','1',669151,2963),(124951,9,1,'n','1',669151,2915),(124952,9,2,'n','1',669151,2739),(124953,9,3,'n','1',669151,2790),(124954,10,0,'w','1',669151,3015),(124955,10,1,'n','1',669151,2838),(124956,10,2,'n','1',669151,2888),(124957,10,3,'n','1',669151,2834),(124958,11,0,'e','1',669151,2815),(124959,11,1,'n','1',669151,2964),(124960,12,0,'s','1',669151,2765),(124961,12,1,'e','1',669151,2759),(124962,12,2,'e','1',669151,2832),(124963,12,3,'e','1',669151,2749),(124964,13,0,'n','1',669151,2921),(124965,13,1,'e','1',669151,2804),(124966,13,2,'w','1',669151,2734),(124967,13,3,'n','1',669151,2882),(124968,14,0,'s','1',669151,2756),(124969,14,1,'s','1',669151,2749),(124970,14,2,'w','1',669151,2732),(124971,15,0,'n','1',669151,2785),(124972,15,1,'w','1',669151,2731),(124973,15,2,'n','1',669151,2823),(124974,16,0,'e','1',669151,2730),(124975,16,1,'e','1',669151,2731),(124976,16,2,'n','1',669151,2732),(124977,16,3,'n','1',669151,2749),(124978,17,0,'n','1',669151,2786),(124979,17,1,'s','1',669151,2740),(124980,17,2,'w','1',669151,2729),(124981,17,3,'n','1',669151,2789),(124982,18,0,'n','1',669151,2789),(124983,18,1,'s','1',669151,2839),(124984,18,2,'e','1',669151,2760),(124985,18,3,'s','1',669151,2761),(124986,19,0,'n','1',669151,2787),(124987,19,1,'e','1',669151,2788),(124988,19,2,'n','1',669151,2736),(124989,19,3,'n','1',669151,2838),(124990,20,0,'n','1',669151,2762),(124991,20,1,'w','1',669151,2839),(124992,20,2,'w','1',669151,2761),(124993,20,3,'n','1',669151,2934),(124994,2,0,'n','1',669151,2867),(124995,2,1,'n','1',669151,2816),(124996,2,2,'n','1',669151,2732),(124997,2,3,'n','1',669151,2749),(124998,3,0,'n','1',669151,2721),(124999,3,1,'n','1',669151,2754),(125000,3,2,'n','1',669151,2820),(125001,3,3,'w','1',669151,2921),(125002,4,0,'w','1',669151,2759),(125003,4,1,'n','1',669151,2756),(125004,4,2,'s','1',669151,2807),(125005,4,3,'s','1',669151,2826),(125006,5,0,'s','1',669151,2765),(125007,5,1,'s','1',669151,2756),(125008,5,2,'e','1',669151,2749),(125009,5,3,'e','1',669151,2740),(125010,6,0,'n','1',669151,2717),(125011,6,1,'e','1',669151,2719),(125012,6,2,'e','1',669151,2725),(125013,6,3,'e','1',669151,2735),(125014,7,0,'w','1',669151,2734),(125015,7,1,'n','1',669151,2735),(125016,7,2,'e','1',669151,2954),(125017,7,3,'e','1',669151,2948),(125018,8,0,'n','1',669151,2749),(125019,8,1,'e','1',669151,2765),(125020,8,2,'w','1',669151,2744),(125021,8,3,'s','1',669151,2826),(125022,9,0,'n','1',669151,2963),(125023,9,1,'n','1',669151,2915),(125024,9,2,'n','1',669151,2739),(125025,9,3,'n','1',669151,2790),(125026,10,0,'w','1',669151,3015),(125027,10,1,'n','1',669151,2838),(125028,10,2,'n','1',669151,2888),(125029,10,3,'n','1',669151,2834),(125030,11,0,'e','1',669151,2815),(125031,11,1,'n','1',669151,2964),(125032,12,0,'s','1',669151,2765),(125033,12,1,'e','1',669151,2759),(125034,12,2,'e','1',669151,2832),(125035,12,3,'e','1',669151,2749),(125036,13,0,'n','1',669151,2921),(125037,13,1,'e','1',669151,2804),(125038,13,2,'w','1',669151,2734),(125039,13,3,'n','1',669151,2882),(125040,14,0,'s','1',669151,2756),(125041,14,1,'s','1',669151,2749),(125042,14,2,'w','1',669151,2732),(125043,15,0,'n','1',669151,2785),(125044,15,1,'w','1',669151,2731),(125045,15,2,'n','1',669151,2823),(125046,16,0,'e','1',669151,2730),(125047,16,1,'e','1',669151,2731),(125048,16,2,'n','1',669151,2732),(125049,16,3,'n','1',669151,2749),(125050,17,0,'n','1',669151,2786),(125051,17,1,'s','1',669151,2740),(125052,17,2,'w','1',669151,2729),(125053,17,3,'n','1',669151,2789),(125054,18,0,'n','1',669151,2789),(125055,18,1,'s','1',669151,2839),(125056,18,2,'e','1',669151,2760),(125057,18,3,'s','1',669151,2761),(125058,19,0,'n','1',669151,2787),(125059,19,1,'e','1',669151,2788),(125060,19,2,'n','1',669151,2736),(125061,19,3,'n','1',669151,2838),(125062,20,0,'n','1',669151,2762),(125063,20,1,'w','1',669151,2839),(125064,20,2,'w','1',669151,2761),(125065,20,3,'n','1',669151,2934),(125066,2,0,'n','1',669152,2721),(125067,2,1,'e','1',669152,2817),(125068,2,2,'n','1',669152,2991),(125069,2,3,'n','1',669152,2992),(125070,3,0,'n','1',669152,2815),(125071,3,1,'n','1',669152,2723),(125072,3,2,'n','1',669152,2813),(125073,3,3,'n','1',669152,2842),(125074,4,0,'w','1',669152,2738),(125075,4,1,'w','1',669152,2734),(125076,4,2,'w','1',669152,2749),(125077,4,3,'w','1',669152,2750),(125078,5,0,'w','1',669152,2751),(125079,5,1,'e','1',669152,2818),(125080,5,2,'e','1',669152,2769),(125081,5,3,'n','1',669152,2871),(125082,6,0,'s','1',669152,2977),(125083,6,1,'e','1',669152,2871),(125084,6,2,'e','1',669152,2751),(125085,6,3,'s','1',669152,2766),(125086,7,0,'w','1',669152,2750),(125087,7,1,'s','1',669152,2751),(125088,7,2,'e','1',669152,2846),(125089,7,3,'w','1',669152,2754),(125090,8,0,'n','1',669152,2730),(125091,8,1,'s','1',669152,2751),(125092,8,2,'e','1',669152,2846),(125093,8,3,'w','1',669152,2962),(125094,9,0,'s','1',669152,2877),(125095,9,1,'n','1',669152,2730),(125096,9,2,'s','1',669152,2751),(125097,9,3,'e','1',669152,2846),(125098,10,0,'w','1',669152,2730),(125099,10,1,'e','1',669152,2873),(125100,10,2,'e','1',669152,2968),(125101,10,3,'n','1',669152,2818),(125102,2,0,'n','1',669152,2721),(125103,2,1,'e','1',669152,2817),(125104,2,2,'n','1',669152,2991),(125105,2,3,'n','1',669152,2992),(125106,3,0,'n','1',669152,2815),(125107,3,1,'n','1',669152,2723),(125108,3,2,'n','1',669152,2813),(125109,3,3,'n','1',669152,2842),(125110,4,0,'w','1',669152,2738),(125111,4,1,'w','1',669152,2734),(125112,4,2,'w','1',669152,2749),(125113,4,3,'w','1',669152,2750),(125114,5,0,'w','1',669152,2751),(125115,5,1,'e','1',669152,2818),(125116,5,2,'e','1',669152,2769),(125117,5,3,'n','1',669152,2871),(125118,6,0,'s','1',669152,2977),(125119,6,1,'e','1',669152,2871),(125120,6,2,'e','1',669152,2751),(125121,6,3,'s','1',669152,2766),(125122,7,0,'w','1',669152,2750),(125123,7,1,'s','1',669152,2751),(125124,7,2,'e','1',669152,2846),(125125,7,3,'w','1',669152,2754),(125126,8,0,'n','1',669152,2730),(125127,8,1,'s','1',669152,2751),(125128,8,2,'e','1',669152,2846),(125129,8,3,'w','1',669152,2962),(125130,9,0,'s','1',669152,2877),(125131,9,1,'n','1',669152,2730),(125132,9,2,'s','1',669152,2751),(125133,9,3,'e','1',669152,2846),(125134,10,0,'w','1',669152,2730),(125135,10,1,'e','1',669152,2873),(125136,10,2,'e','1',669152,2968),(125137,10,3,'n','1',669152,2818),(125138,2,0,'n','1',669153,2728),(125139,2,1,'w','1',669153,2721),(125140,2,2,'n','1',669153,2810),(125141,2,3,'n','1',669153,2811),(125142,3,0,'n','1',669153,3042),(125143,3,1,'e','1',669153,2939),(125144,3,2,'n','1',669153,3009),(125145,3,3,'n','1',669153,3013),(125146,4,0,'n','1',669153,2812),(125147,4,1,'n','1',669153,3010),(125148,4,2,'n','1',669153,3011),(125149,4,3,'w','1',669153,3012),(125150,5,0,'s','1',669153,2741),(125151,5,1,'s','1',669153,2742),(125152,5,2,'e','1',669153,2738),(125153,5,3,'s','1',669153,2743),(125154,6,0,'w','1',669153,3011),(125155,6,1,'w','1',669153,2738),(125156,6,2,'e','1',669153,2734),(125157,6,3,'s','1',669153,2844),(125158,7,0,'w','1',669153,2738),(125159,7,1,'w','1',669153,2734),(125160,7,2,'e','1',669153,2749),(125161,7,3,'s','1',669153,2987),(125162,8,0,'w','1',669153,2734),(125163,8,1,'e','1',669153,2749),(125164,8,2,'s','1',669153,2987),(125165,8,3,'w','1',669153,2822),(125166,9,0,'w','1',669153,2734),(125167,9,1,'e','1',669153,2987),(125168,9,2,'n','1',669153,2749),(125169,9,3,'n','1',669153,2724),(125170,10,0,'s','1',669153,2765),(125171,10,1,'e','1',669153,2749),(125172,10,2,'w','1',669153,2734),(125173,10,3,'w','1',669153,2759),(125174,11,0,'e','1',669153,2749),(125175,11,1,'e','1',669153,2734),(125176,11,2,'n','1',669153,3014),(125177,11,3,'n','1',669153,2779),(125178,12,0,'s','1',669153,2738),(125179,12,1,'w','1',669153,2921),(125180,12,2,'w','1',669153,2842),(125181,12,3,'s','1',669153,2759),(125182,13,0,'n','1',669153,2733),(125183,13,1,'w','1',669153,2734),(125184,13,2,'w','1',669153,2804),(125185,13,3,'n','1',669153,2780),(125186,14,0,'e','1',669153,2749),(125187,14,1,'e','1',669153,2734),(125188,14,2,'e','1',669153,2738),(125189,14,3,'s','1',669153,2743),(125190,15,0,'w','1',669153,2804),(125191,15,1,'w','1',669153,3011),(125192,15,2,'s','1',669153,2832),(125193,15,3,'w','1',669153,2738),(125194,16,0,'w','1',669153,2734),(125195,16,1,'w','1',669153,2804),(125196,16,2,'s','1',669153,2737),(125197,16,3,'n','1',669153,2790),(125198,17,0,'e','1',669153,2749),(125199,17,1,'s','1',669153,2833),(125200,17,2,'e','1',669153,2734),(125201,17,3,'e','1',669153,2788),(125202,18,0,'s','1',669153,2738),(125203,18,1,'n','1',669153,2842),(125204,18,2,'w','1',669153,2820),(125205,19,0,'w','1',669153,2738),(125206,19,1,'e','1',669153,2734),(125207,19,2,'s','1',669153,2809),(125208,20,0,'w','1',669153,2738),(125209,20,1,'e','1',669153,2734),(125210,20,2,'s','1',669153,2809),(125211,20,3,'w','1',669153,2797),(125212,21,0,'s','1',669153,2961),(125213,21,1,'w','1',669153,2738),(125214,21,2,'s','1',669153,2897),(125215,21,3,'x','0',669153,2934),(125216,21,4,'s','1',669153,2734),(125217,22,0,'n','1',669153,2733),(125218,22,1,'w','1',669153,2734),(125219,22,2,'e','1',669153,2833),(125220,22,3,'n','1',669153,2749),(125221,23,0,'n','1',669153,2765),(125222,23,1,'e','1',669153,2860),(125223,23,2,'s','1',669153,2833),(125224,23,3,'s','1',669153,2988),(125225,24,0,'n','1',669153,2765),(125226,24,1,'e','1',669153,2860),(125227,24,2,'s','1',669153,2833),(125228,24,3,'s','1',669153,2988),(125229,25,0,'s','1',669153,2765),(125230,25,1,'e','1',669153,2749),(125231,25,2,'e','1',669153,2734),(125232,25,3,'s','1',669153,2799),(125233,26,0,'w','1',669153,2738),(125234,26,1,'w','1',669153,2734),(125235,26,2,'s','1',669153,2799),(125236,26,3,'n','1',669153,2719),(125237,27,0,'e','1',669153,2749),(125238,27,1,'e','1',669153,2734),(125239,27,2,'w','1',669153,2738),(125240,27,3,'s','1',669153,2743),(125241,28,0,'e','1',669153,2734),(125242,28,1,'s','1',669153,2845),(125243,28,2,'e','1',669153,3001),(125244,28,3,'n','1',669153,2738),(125245,29,0,'n','1',669153,2719),(125246,29,1,'n','1',669153,2845),(125247,29,2,'e','1',669153,2900),(125248,29,3,'x','0',669153,2880),(125249,29,4,'n','1',669153,2846),(125250,30,0,'w','1',669153,2736),(125251,30,1,'n','1',669153,2760),(125252,30,2,'n','1',669153,2740),(125253,30,3,'n','1',669153,2756),(125254,31,0,'n','1',669153,2753),(125255,31,1,'s','1',669153,2807),(125256,31,2,'s','1',669153,2826),(125257,31,3,'x','0',669153,2757),(125258,31,4,'n','1',669153,2783),(125259,2,0,'n','1',669153,2728),(125260,2,1,'w','1',669153,2721),(125261,2,2,'n','1',669153,2810),(125262,2,3,'n','1',669153,2811),(125263,3,0,'n','1',669153,3042),(125264,3,1,'e','1',669153,2939),(125265,3,2,'n','1',669153,3009),(125266,3,3,'n','1',669153,3013),(125267,4,0,'n','1',669153,2812),(125268,4,1,'n','1',669153,3010),(125269,4,2,'n','1',669153,3011),(125270,4,3,'w','1',669153,3012),(125271,5,0,'s','1',669153,2741),(125272,5,1,'s','1',669153,2742),(125273,5,2,'e','1',669153,2738),(125274,5,3,'s','1',669153,2743),(125275,6,0,'w','1',669153,3011),(125276,6,1,'w','1',669153,2738),(125277,6,2,'e','1',669153,2734),(125278,6,3,'s','1',669153,2844),(125279,7,0,'w','1',669153,2738),(125280,7,1,'w','1',669153,2734),(125281,7,2,'e','1',669153,2749),(125282,7,3,'s','1',669153,2987),(125283,8,0,'w','1',669153,2734),(125284,8,1,'e','1',669153,2749),(125285,8,2,'s','1',669153,2987),(125286,8,3,'w','1',669153,2822),(125287,9,0,'w','1',669153,2734),(125288,9,1,'e','1',669153,2987),(125289,9,2,'n','1',669153,2749),(125290,9,3,'n','1',669153,2724),(125291,10,0,'s','1',669153,2765),(125292,10,1,'e','1',669153,2749),(125293,10,2,'w','1',669153,2734),(125294,10,3,'w','1',669153,2759),(125295,11,0,'e','1',669153,2749),(125296,11,1,'e','1',669153,2734),(125297,11,2,'n','1',669153,3014),(125298,11,3,'n','1',669153,2779),(125299,12,0,'s','1',669153,2738),(125300,12,1,'w','1',669153,2921),(125301,12,2,'w','1',669153,2842),(125302,12,3,'s','1',669153,2759),(125303,13,0,'n','1',669153,2733),(125304,13,1,'w','1',669153,2734),(125305,13,2,'w','1',669153,2804),(125306,13,3,'n','1',669153,2780),(125307,14,0,'e','1',669153,2749),(125308,14,1,'e','1',669153,2734),(125309,14,2,'e','1',669153,2738),(125310,14,3,'s','1',669153,2743),(125311,15,0,'w','1',669153,2804),(125312,15,1,'w','1',669153,3011),(125313,15,2,'s','1',669153,2832),(125314,15,3,'w','1',669153,2738),(125315,16,0,'w','1',669153,2734),(125316,16,1,'w','1',669153,2804),(125317,16,2,'s','1',669153,2737),(125318,16,3,'n','1',669153,2790),(125319,17,0,'e','1',669153,2749),(125320,17,1,'s','1',669153,2833),(125321,17,2,'e','1',669153,2734),(125322,17,3,'e','1',669153,2788),(125323,18,0,'s','1',669153,2738),(125324,18,1,'n','1',669153,2842),(125325,18,2,'w','1',669153,2820),(125326,19,0,'w','1',669153,2738),(125327,19,1,'e','1',669153,2734),(125328,19,2,'s','1',669153,2809),(125329,20,0,'w','1',669153,2738),(125330,20,1,'e','1',669153,2734),(125331,20,2,'s','1',669153,2809),(125332,20,3,'w','1',669153,2797),(125333,21,0,'s','1',669153,2961),(125334,21,1,'w','1',669153,2738),(125335,21,2,'s','1',669153,2897),(125336,21,3,'x','0',669153,2934),(125337,21,4,'s','1',669153,2734),(125338,22,0,'n','1',669153,2733),(125339,22,1,'w','1',669153,2734),(125340,22,2,'e','1',669153,2833),(125341,22,3,'n','1',669153,2749),(125342,23,0,'n','1',669153,2765),(125343,23,1,'e','1',669153,2860),(125344,23,2,'s','1',669153,2833),(125345,23,3,'s','1',669153,2988),(125346,24,0,'n','1',669153,2765),(125347,24,1,'e','1',669153,2860),(125348,24,2,'s','1',669153,2833),(125349,24,3,'s','1',669153,2988),(125350,25,0,'s','1',669153,2765),(125351,25,1,'e','1',669153,2749),(125352,25,2,'e','1',669153,2734),(125353,25,3,'s','1',669153,2799),(125354,26,0,'w','1',669153,2738),(125355,26,1,'w','1',669153,2734),(125356,26,2,'s','1',669153,2799),(125357,26,3,'n','1',669153,2719),(125358,27,0,'e','1',669153,2749),(125359,27,1,'e','1',669153,2734),(125360,27,2,'w','1',669153,2738),(125361,27,3,'s','1',669153,2743),(125362,28,0,'e','1',669153,2734),(125363,28,1,'s','1',669153,2845),(125364,28,2,'e','1',669153,3001),(125365,28,3,'n','1',669153,2738),(125366,29,0,'n','1',669153,2719),(125367,29,1,'n','1',669153,2845),(125368,29,2,'e','1',669153,2900),(125369,29,3,'x','0',669153,2880),(125370,29,4,'n','1',669153,2846),(125371,30,0,'w','1',669153,2736),(125372,30,1,'n','1',669153,2760),(125373,30,2,'n','1',669153,2740),(125374,30,3,'n','1',669153,2756),(125375,31,0,'n','1',669153,2753),(125376,31,1,'s','1',669153,2807),(125377,31,2,'s','1',669153,2826),(125378,31,3,'x','0',669153,2757),(125379,31,4,'n','1',669153,2783),(125380,2,0,'n','1',669154,2728),(125381,2,1,'n','1',669154,2721),(125382,2,2,'n','1',669154,2810),(125383,2,3,'w','1',669154,2811),(125384,3,0,'n','1',669154,2717),(125385,3,1,'n','1',669154,2882),(125386,3,2,'w','1',669154,2736),(125387,3,3,'n','1',669154,2992),(125388,4,0,'n','1',669154,2813),(125389,4,1,'n','1',669154,2842),(125390,4,2,'n','1',669154,2738),(125391,4,3,'n','1',669154,2760),(125392,5,0,'n','1',669154,2973),(125393,5,1,'n','1',669154,2951),(125394,5,2,'n','1',669154,2740),(125395,5,3,'n','1',669154,2756),(125396,6,0,'n','1',669154,2719),(125397,6,1,'n','1',669154,2845),(125398,6,2,'n','1',669154,2846),(125399,6,3,'n','1',669154,2887),(125400,7,0,'n','1',669154,2776),(125401,7,1,'n','1',669154,2803),(125402,7,2,'n','1',669154,2802),(125403,7,3,'w','1',669154,2774),(125404,8,0,'w','1',669154,2755),(125405,8,1,'n','1',669154,2793),(125406,8,2,'w','1',669154,2748),(125407,8,3,'n','1',669154,2779),(125408,9,0,'n','1',669154,2879),(125409,9,1,'e','1',669154,2880),(125410,9,2,'s','1',669154,2767),(125411,9,3,'x','0',669154,2859),(125412,9,4,'n','1',669154,2794),(125413,10,0,'n','1',669154,2857),(125414,10,1,'n','1',669154,2902),(125415,10,2,'n','1',669154,2778),(125416,10,3,'n','1',669154,2794),(125417,11,0,'s','1',669154,2800),(125418,11,1,'s','1',669154,2757),(125419,11,2,'e','1',669154,2802),(125420,11,3,'s','1',669154,2758),(125421,12,0,'s','1',669154,2761),(125422,12,1,'x','0',669154,2762),(125423,12,2,'w','1',669154,2959),(125424,12,3,'n','1',669154,2802),(125425,12,4,'w','1',669154,2754),(125426,13,0,'n','1',669154,2800),(125427,13,1,'w','1',669154,2826),(125428,13,2,'n','1',669154,2799),(125429,13,3,'w','1',669154,2736),(125430,14,0,'w','1',669154,2741),(125431,14,1,'s','1',669154,2833),(125432,14,2,'w','1',669154,2744),(125433,14,3,'w','1',669154,2760),(125434,15,0,'n','1',669154,2986),(125435,15,1,'s','1',669154,2746),(125436,15,2,'s','1',669154,2788),(125437,15,3,'n','1',669154,2956),(125438,16,0,'s','1',669154,2860),(125439,16,1,'w','1',669154,2765),(125440,16,2,'s','1',669154,2792),(125441,16,3,'s','1',669154,2768),(125442,17,0,'e','1',669154,2860),(125443,17,1,'n','1',669154,2750),(125444,17,2,'w','1',669154,2986),(125445,17,3,'n','1',669154,2858),(125446,18,0,'n','1',669154,2769),(125447,18,1,'w','1',669154,2859),(125448,18,2,'s','1',669154,2853),(125449,18,3,'x','0',669154,2910),(125450,18,4,'e','1',669154,2894),(125451,19,0,'e','1',669154,2908),(125452,19,1,'n','1',669154,2986),(125453,19,2,'n','1',669154,2746),(125454,19,3,'n','1',669154,2789),(125455,20,0,'e','1',669154,2755),(125456,20,1,'e','1',669154,2768),(125457,20,2,'s','1',669154,3027),(125458,20,3,'s','1',669154,2937),(125459,21,0,'w','1',669154,2752),(125460,21,1,'w','1',669154,2765),(125461,21,2,'s','1',669154,2863),(125462,21,3,'e','1',669154,2938),(125463,22,0,'e','1',669154,2756),(125464,22,1,'s','1',669154,2799),(125465,22,2,'s','1',669154,2800),(125466,22,3,'w','1',669154,2759),(125467,23,0,'s','1',669154,2826),(125468,23,1,'e','1',669154,2936),(125469,23,2,'e','1',669154,3043),(125470,23,3,'n','1',669154,3000),(125471,24,0,'s','1',669154,3044),(125472,24,1,'e','1',669154,3000),(125473,24,2,'n','1',669154,2837),(125474,24,3,'s','1',669154,3045),(125475,2,0,'n','1',669154,2728),(125476,2,1,'n','1',669154,2721),(125477,2,2,'n','1',669154,2810),(125478,2,3,'w','1',669154,2811),(125479,3,0,'n','1',669154,2717),(125480,3,1,'n','1',669154,2882),(125481,3,2,'w','1',669154,2736),(125482,3,3,'n','1',669154,2992),(125483,4,0,'n','1',669154,2813),(125484,4,1,'n','1',669154,2842),(125485,4,2,'n','1',669154,2738),(125486,4,3,'n','1',669154,2760),(125487,5,0,'n','1',669154,2973),(125488,5,1,'n','1',669154,2951),(125489,5,2,'n','1',669154,2740),(125490,5,3,'n','1',669154,2756),(125491,6,0,'n','1',669154,2719),(125492,6,1,'n','1',669154,2845),(125493,6,2,'n','1',669154,2846),(125494,6,3,'n','1',669154,2887),(125495,7,0,'n','1',669154,2776),(125496,7,1,'n','1',669154,2803),(125497,7,2,'n','1',669154,2802),(125498,7,3,'w','1',669154,2774),(125499,8,0,'w','1',669154,2755),(125500,8,1,'n','1',669154,2793),(125501,8,2,'w','1',669154,2748),(125502,8,3,'n','1',669154,2779),(125503,9,0,'n','1',669154,2879),(125504,9,1,'e','1',669154,2880),(125505,9,2,'s','1',669154,2767),(125506,9,3,'x','0',669154,2859),(125507,9,4,'n','1',669154,2794),(125508,10,0,'n','1',669154,2857),(125509,10,1,'n','1',669154,2902),(125510,10,2,'n','1',669154,2778),(125511,10,3,'n','1',669154,2794),(125512,11,0,'s','1',669154,2800),(125513,11,1,'s','1',669154,2757),(125514,11,2,'e','1',669154,2802),(125515,11,3,'s','1',669154,2758),(125516,12,0,'s','1',669154,2761),(125517,12,1,'x','0',669154,2762),(125518,12,2,'w','1',669154,2959),(125519,12,3,'n','1',669154,2802),(125520,12,4,'w','1',669154,2754),(125521,13,0,'n','1',669154,2800),(125522,13,1,'w','1',669154,2826),(125523,13,2,'n','1',669154,2799),(125524,13,3,'w','1',669154,2736),(125525,14,0,'w','1',669154,2741),(125526,14,1,'s','1',669154,2833),(125527,14,2,'w','1',669154,2744),(125528,14,3,'w','1',669154,2760),(125529,15,0,'n','1',669154,2986),(125530,15,1,'s','1',669154,2746),(125531,15,2,'s','1',669154,2788),(125532,15,3,'n','1',669154,2956),(125533,16,0,'s','1',669154,2860),(125534,16,1,'w','1',669154,2765),(125535,16,2,'s','1',669154,2792),(125536,16,3,'s','1',669154,2768),(125537,17,0,'e','1',669154,2860),(125538,17,1,'n','1',669154,2750),(125539,17,2,'w','1',669154,2986),(125540,17,3,'n','1',669154,2858),(125541,18,0,'n','1',669154,2769),(125542,18,1,'w','1',669154,2859),(125543,18,2,'s','1',669154,2853),(125544,18,3,'x','0',669154,2910),(125545,18,4,'e','1',669154,2894),(125546,19,0,'e','1',669154,2908),(125547,19,1,'n','1',669154,2986),(125548,19,2,'n','1',669154,2746),(125549,19,3,'n','1',669154,2789),(125550,20,0,'e','1',669154,2755),(125551,20,1,'e','1',669154,2768),(125552,20,2,'s','1',669154,3027),(125553,20,3,'s','1',669154,2937),(125554,21,0,'w','1',669154,2752),(125555,21,1,'w','1',669154,2765),(125556,21,2,'s','1',669154,2863),(125557,21,3,'e','1',669154,2938),(125558,22,0,'e','1',669154,2756),(125559,22,1,'s','1',669154,2799),(125560,22,2,'s','1',669154,2800),(125561,22,3,'w','1',669154,2759),(125562,23,0,'s','1',669154,2826),(125563,23,1,'e','1',669154,2936),(125564,23,2,'e','1',669154,3043),(125565,23,3,'n','1',669154,3000),(125566,24,0,'s','1',669154,3044),(125567,24,1,'e','1',669154,3000),(125568,24,2,'n','1',669154,2837),(125569,24,3,'s','1',669154,3045),(125570,2,0,'n','1',669155,2721),(125571,2,1,'n','1',669155,2810),(125572,2,2,'w','1',669155,2754),(125573,2,3,'n','1',669155,2811),(125574,3,0,'n','1',669155,2815),(125575,3,1,'e','1',669155,2818),(125576,3,2,'n','1',669155,2812),(125577,3,3,'n','1',669155,3010),(125578,4,0,'n','1',669155,2736),(125579,4,1,'n','1',669155,2737),(125580,4,2,'n','1',669155,2759),(125581,4,3,'w','1',669155,3011),(125582,5,0,'e','1',669155,2872),(125583,5,1,'n','1',669155,2717),(125584,5,2,'e','1',669155,2772),(125585,5,3,'e','1',669155,2806),(125586,6,0,'w','1',669155,2738),(125587,6,1,'w','1',669155,2734),(125588,6,2,'n','1',669155,2749),(125589,6,3,'n','1',669155,2817),(125590,7,0,'n','1',669155,2863),(125591,7,1,'n','1',669155,2765),(125592,7,2,'s','1',669155,2988),(125593,7,3,'w','1',669155,2808),(125594,7,4,'x','0',669155,2744),(125595,2,0,'n','1',669155,2721),(125596,2,1,'n','1',669155,2810),(125597,2,2,'w','1',669155,2754),(125598,2,3,'n','1',669155,2811),(125599,3,0,'n','1',669155,2815),(125600,3,1,'e','1',669155,2818),(125601,3,2,'n','1',669155,2812),(125602,3,3,'n','1',669155,3010),(125603,4,0,'n','1',669155,2736),(125604,4,1,'n','1',669155,2737),(125605,4,2,'n','1',669155,2759),(125606,4,3,'w','1',669155,3011),(125607,5,0,'e','1',669155,2872),(125608,5,1,'n','1',669155,2717),(125609,5,2,'e','1',669155,2772),(125610,5,3,'e','1',669155,2806),(125611,6,0,'w','1',669155,2738),(125612,6,1,'w','1',669155,2734),(125613,6,2,'n','1',669155,2749),(125614,6,3,'n','1',669155,2817),(125615,7,0,'n','1',669155,2863),(125616,7,1,'n','1',669155,2765),(125617,7,2,'s','1',669155,2988),(125618,7,3,'w','1',669155,2808),(125619,7,4,'x','0',669155,2744),(125620,2,0,'n','1',669156,2867),(125621,2,1,'n','1',669156,2816),(125622,2,2,'n','1',669156,2732),(125623,2,3,'n','1',669156,2749),(125624,3,0,'w','1',669156,2765),(125625,3,1,'e','1',669156,2768),(125626,3,2,'s','1',669156,2944),(125627,3,3,'n','1',669156,2721),(125628,4,0,'n','1',669156,2717),(125629,4,1,'e','1',669156,2815),(125630,4,2,'e','1',669156,2719),(125631,4,3,'n','1',669156,2963),(125632,5,0,'n','1',669156,2765),(125633,5,1,'s','1',669156,2988),(125634,5,2,'s','1',669156,3038),(125635,5,3,'n','1',669156,2888),(125636,6,0,'n','1',669156,2964),(125637,6,1,'n','1',669156,2872),(125638,6,2,'s','1',669156,2855),(125639,6,3,'s','1',669156,2877),(125640,7,0,'n','1',669156,2872),(125641,7,1,'s','1',669156,2855),(125642,7,2,'s','1',669156,2877),(125643,7,3,'n','1',669156,2754),(125644,8,0,'s','1',669156,2765),(125645,8,1,'n','1',669156,2735),(125646,8,2,'e','1',669156,2954),(125647,8,3,'e','1',669156,2948),(125648,9,0,'e','1',669156,2832),(125649,9,1,'s','1',669156,2804),(125650,9,2,'s','1',669156,2849),(125651,9,3,'n','1',669156,2882),(125652,10,0,'w','1',669156,2883),(125653,10,1,'w','1',669156,2749),(125654,10,2,'w','1',669156,2750),(125655,10,3,'w','1',669156,2751),(125656,11,0,'e','1',669156,2871),(125657,11,1,'e','1',669156,3020),(125658,11,2,'s','1',669156,2846),(125659,11,3,'w','1',669156,2751),(125660,12,0,'n','1',669156,2739),(125661,12,1,'n','1',669156,2775),(125662,12,2,'s','1',669156,2948),(125663,12,3,'s','1',669156,2851),(125664,13,0,'e','1',669156,2845),(125665,13,1,'s','1',669156,2871),(125666,13,2,'s','1',669156,2855),(125667,13,3,'x','0',669156,2725),(125668,13,4,'e','1',669156,2873),(125669,14,0,'n','1',669156,2872),(125670,14,1,'n','1',669156,2877),(125671,14,2,'w','1',669156,2862),(125672,14,3,'n','1',669156,2878),(125673,15,0,'e','1',669156,2730),(125674,15,1,'e','1',669156,2948),(125675,15,2,'e','1',669156,2731),(125676,15,3,'n','1',669156,2732),(125677,16,0,'e','1',669156,2832),(125678,16,1,'e','1',669156,2804),(125679,16,2,'n','1',669156,2915),(125680,16,3,'s','1',669156,2917),(125681,17,0,'s','1',669156,2916),(125682,17,1,'w','1',669156,2919),(125683,17,2,'n','1',669156,2834),(125684,17,3,'n','1',669156,2823),(125685,18,0,'e','1',669156,2749),(125686,18,1,'e','1',669156,2804),(125687,18,2,'n','1',669156,2838),(125688,18,3,'n','1',669156,2901),(125689,19,0,'s','1',669156,2953),(125690,19,1,'w','1',669156,2745),(125691,19,2,'s','1',669156,2917),(125692,19,3,'s','1',669156,2916),(125693,20,0,'e','1',669156,2843),(125694,20,1,'n','1',669156,2934),(125695,20,2,'n','1',669156,2775),(125696,20,3,'w','1',669156,2851),(125697,21,0,'n','1',669156,2785),(125698,21,1,'n','1',669156,2887),(125699,21,2,'n','1',669156,2927),(125700,21,3,'n','1',669156,2779),(125701,22,0,'n','1',669156,2934),(125702,22,1,'n','1',669156,2780),(125703,22,2,'n','1',669156,2781),(125704,22,3,'n','1',669156,2790),(125705,23,0,'n','1',669156,2934),(125706,23,1,'e','1',669156,2897),(125707,23,2,'s','1',669156,2734),(125708,23,3,'e','1',669156,2953),(125709,24,0,'n','1',669156,2733),(125710,24,1,'e','1',669156,2843),(125711,24,2,'s','1',669156,2734),(125712,24,3,'s','1',669156,2919),(125713,25,0,'s','1',669156,2974),(125714,25,1,'n','1',669156,2733),(125715,25,2,'e','1',669156,2843),(125716,25,3,'s','1',669156,2734),(125717,26,0,'w','1',669156,3046),(125718,26,1,'w','1',669156,2903),(125719,26,2,'e','1',669156,2817),(125720,26,3,'w','1',669156,3047),(125721,27,0,'e','1',669156,3048),(125722,27,1,'s','1',669156,2996),(125723,27,2,'e','1',669156,2789),(125724,27,3,'n','1',669156,2733),(125725,28,0,'w','1',669156,2734),(125726,28,1,'s','1',669156,2748),(125727,28,2,'w','1',669156,2749),(125728,28,3,'e','1',669156,2791),(125729,29,0,'s','1',669156,2770),(125730,29,1,'s','1',669156,2750),(125731,29,2,'w','1',669156,2908),(125732,29,3,'x','0',669156,2772),(125733,29,4,'s','1',669156,2731),(125734,30,0,'e','1',669156,2874),(125735,30,1,'e','1',669156,2789),(125736,30,2,'e','1',669156,2797),(125737,30,3,'e','1',669156,2858),(125738,31,0,'n','1',669156,2834),(125739,31,1,'w','1',669156,3046),(125740,31,2,'e','1',669156,2817),(125741,31,3,'n','1',669156,3047),(125742,32,0,'e','1',669156,2793),(125743,32,1,'s','1',669156,2859),(125744,32,2,'s','1',669156,2857),(125745,32,3,'w','1',669156,2792),(125746,33,0,'e','1',669156,2797),(125747,33,1,'e','1',669156,2790),(125748,33,2,'e','1',669156,2903),(125749,33,3,'n','1',669156,2901),(125750,34,0,'s','1',669156,2794),(125751,34,1,'x','0',669156,2778),(125752,34,2,'s','1',669156,2793),(125753,34,3,'e','1',669156,2909),(125754,34,4,'e','1',669156,2950),(125755,35,0,'e','1',669156,2797),(125756,35,1,'s','1',669156,2827),(125757,35,2,'e','1',669156,2903),(125758,35,3,'e','1',669156,3049),(125759,36,0,'n','1',669156,2816),(125760,36,1,'e','1',669156,2732),(125761,36,2,'e','1',669156,2990),(125762,36,3,'e','1',669156,2861),(125763,37,0,'n','1',669156,3048),(125764,37,1,'n','1',669156,2947),(125765,37,2,'w','1',669156,2817),(125766,37,3,'w','1',669156,2834),(125767,38,0,'w','1',669156,2785),(125768,38,1,'w','1',669156,2856),(125769,38,2,'n','1',669156,2733),(125770,38,3,'n','1',669156,2883),(125771,39,0,'w','1',669156,2785),(125772,39,1,'w','1',669156,2906),(125773,39,2,'n','1',669156,2821),(125774,39,3,'n','1',669156,3039),(125775,40,0,'w','1',669156,2734),(125776,40,1,'s','1',669156,2749),(125777,40,2,'w','1',669156,2906),(125778,40,3,'e','1',669156,2901),(125779,2,0,'n','1',669156,2867),(125780,2,1,'n','1',669156,2816),(125781,2,2,'n','1',669156,2732),(125782,2,3,'n','1',669156,2749),(125783,3,0,'w','1',669156,2765),(125784,3,1,'e','1',669156,2768),(125785,3,2,'s','1',669156,2944),(125786,3,3,'n','1',669156,2721),(125787,4,0,'n','1',669156,2717),(125788,4,1,'e','1',669156,2815),(125789,4,2,'e','1',669156,2719),(125790,4,3,'n','1',669156,2963),(125791,5,0,'n','1',669156,2765),(125792,5,1,'s','1',669156,2988),(125793,5,2,'s','1',669156,3038),(125794,5,3,'n','1',669156,2888),(125795,6,0,'n','1',669156,2964),(125796,6,1,'n','1',669156,2872),(125797,6,2,'s','1',669156,2855),(125798,6,3,'s','1',669156,2877),(125799,7,0,'n','1',669156,2872),(125800,7,1,'s','1',669156,2855),(125801,7,2,'s','1',669156,2877),(125802,7,3,'n','1',669156,2754),(125803,8,0,'s','1',669156,2765),(125804,8,1,'n','1',669156,2735),(125805,8,2,'e','1',669156,2954),(125806,8,3,'e','1',669156,2948),(125807,9,0,'e','1',669156,2832),(125808,9,1,'s','1',669156,2804),(125809,9,2,'s','1',669156,2849),(125810,9,3,'n','1',669156,2882),(125811,10,0,'w','1',669156,2883),(125812,10,1,'w','1',669156,2749),(125813,10,2,'w','1',669156,2750),(125814,10,3,'w','1',669156,2751),(125815,11,0,'e','1',669156,2871),(125816,11,1,'e','1',669156,3020),(125817,11,2,'s','1',669156,2846),(125818,11,3,'w','1',669156,2751),(125819,12,0,'n','1',669156,2739),(125820,12,1,'n','1',669156,2775),(125821,12,2,'s','1',669156,2948),(125822,12,3,'s','1',669156,2851),(125823,13,0,'e','1',669156,2845),(125824,13,1,'s','1',669156,2871),(125825,13,2,'s','1',669156,2855),(125826,13,3,'x','0',669156,2725),(125827,13,4,'e','1',669156,2873),(125828,14,0,'n','1',669156,2872),(125829,14,1,'n','1',669156,2877),(125830,14,2,'w','1',669156,2862),(125831,14,3,'n','1',669156,2878),(125832,15,0,'e','1',669156,2730),(125833,15,1,'e','1',669156,2948),(125834,15,2,'e','1',669156,2731),(125835,15,3,'n','1',669156,2732),(125836,16,0,'e','1',669156,2832),(125837,16,1,'e','1',669156,2804),(125838,16,2,'n','1',669156,2915),(125839,16,3,'s','1',669156,2917),(125840,17,0,'s','1',669156,2916),(125841,17,1,'w','1',669156,2919),(125842,17,2,'n','1',669156,2834),(125843,17,3,'n','1',669156,2823),(125844,18,0,'e','1',669156,2749),(125845,18,1,'e','1',669156,2804),(125846,18,2,'n','1',669156,2838),(125847,18,3,'n','1',669156,2901),(125848,19,0,'s','1',669156,2953),(125849,19,1,'w','1',669156,2745),(125850,19,2,'s','1',669156,2917),(125851,19,3,'s','1',669156,2916),(125852,20,0,'e','1',669156,2843),(125853,20,1,'n','1',669156,2934),(125854,20,2,'n','1',669156,2775),(125855,20,3,'w','1',669156,2851),(125856,21,0,'n','1',669156,2785),(125857,21,1,'n','1',669156,2887),(125858,21,2,'n','1',669156,2927),(125859,21,3,'n','1',669156,2779),(125860,22,0,'n','1',669156,2934),(125861,22,1,'n','1',669156,2780),(125862,22,2,'n','1',669156,2781),(125863,22,3,'n','1',669156,2790),(125864,23,0,'n','1',669156,2934),(125865,23,1,'e','1',669156,2897),(125866,23,2,'s','1',669156,2734),(125867,23,3,'e','1',669156,2953),(125868,24,0,'n','1',669156,2733),(125869,24,1,'e','1',669156,2843),(125870,24,2,'s','1',669156,2734),(125871,24,3,'s','1',669156,2919),(125872,25,0,'s','1',669156,2974),(125873,25,1,'n','1',669156,2733),(125874,25,2,'e','1',669156,2843),(125875,25,3,'s','1',669156,2734),(125876,26,0,'w','1',669156,3046),(125877,26,1,'w','1',669156,2903),(125878,26,2,'e','1',669156,2817),(125879,26,3,'w','1',669156,3047),(125880,27,0,'e','1',669156,3048),(125881,27,1,'s','1',669156,2996),(125882,27,2,'e','1',669156,2789),(125883,27,3,'n','1',669156,2733),(125884,28,0,'w','1',669156,2734),(125885,28,1,'s','1',669156,2748),(125886,28,2,'w','1',669156,2749),(125887,28,3,'e','1',669156,2791),(125888,29,0,'s','1',669156,2770),(125889,29,1,'s','1',669156,2750),(125890,29,2,'w','1',669156,2908),(125891,29,3,'x','0',669156,2772),(125892,29,4,'s','1',669156,2731),(125893,30,0,'e','1',669156,2874),(125894,30,1,'e','1',669156,2789),(125895,30,2,'e','1',669156,2797),(125896,30,3,'e','1',669156,2858),(125897,31,0,'n','1',669156,2834),(125898,31,1,'w','1',669156,3046),(125899,31,2,'e','1',669156,2817),(125900,31,3,'n','1',669156,3047),(125901,32,0,'e','1',669156,2793),(125902,32,1,'s','1',669156,2859),(125903,32,2,'s','1',669156,2857),(125904,32,3,'w','1',669156,2792),(125905,33,0,'e','1',669156,2797),(125906,33,1,'e','1',669156,2790),(125907,33,2,'e','1',669156,2903),(125908,33,3,'n','1',669156,2901),(125909,34,0,'s','1',669156,2794),(125910,34,1,'x','0',669156,2778),(125911,34,2,'s','1',669156,2793),(125912,34,3,'e','1',669156,2909),(125913,34,4,'e','1',669156,2950),(125914,35,0,'e','1',669156,2797),(125915,35,1,'s','1',669156,2827),(125916,35,2,'e','1',669156,2903),(125917,35,3,'e','1',669156,3049),(125918,36,0,'n','1',669156,2816),(125919,36,1,'e','1',669156,2732),(125920,36,2,'e','1',669156,2990),(125921,36,3,'e','1',669156,2861),(125922,37,0,'n','1',669156,3048),(125923,37,1,'n','1',669156,2947),(125924,37,2,'w','1',669156,2817),(125925,37,3,'w','1',669156,2834),(125926,38,0,'w','1',669156,2785),(125927,38,1,'w','1',669156,2856),(125928,38,2,'n','1',669156,2733),(125929,38,3,'n','1',669156,2883),(125930,39,0,'w','1',669156,2785),(125931,39,1,'w','1',669156,2906),(125932,39,2,'n','1',669156,2821),(125933,39,3,'n','1',669156,3039),(125934,40,0,'w','1',669156,2734),(125935,40,1,'s','1',669156,2749),(125936,40,2,'w','1',669156,2906),(125937,40,3,'e','1',669156,2901),(125938,2,0,'n','1',669157,2867),(125939,2,1,'n','1',669157,2816),(125940,2,2,'n','1',669157,2732),(125941,2,3,'n','1',669157,2749),(125942,3,0,'n','1',669157,2963),(125943,3,1,'n','1',669157,2717),(125944,3,2,'n','1',669157,2882),(125945,3,3,'n','1',669157,2721),(125946,4,0,'w','1',669157,2754),(125947,4,1,'n','1',669157,2736),(125948,4,2,'n','1',669157,2737),(125949,4,3,'e','1',669157,2759),(125950,5,0,'e','1',669157,2719),(125951,5,1,'e','1',669157,2725),(125952,5,2,'e','1',669157,2735),(125953,5,3,'n','1',669157,2739),(125954,6,0,'s','1',669157,2765),(125955,6,1,'e','1',669157,2749),(125956,6,2,'s','1',669157,2759),(125957,6,3,'e','1',669157,2734),(125958,7,0,'e','1',669157,2884),(125959,7,1,'e','1',669157,2883),(125960,7,2,'w','1',669157,3015),(125961,7,3,'s','1',669157,2921),(125962,8,0,'n','1',669157,2888),(125963,8,1,'n','1',669157,2815),(125964,8,2,'e','1',669157,2818),(125965,8,3,'e','1',669157,2872),(125966,9,0,'w','1',669157,2875),(125967,9,1,'s','1',669157,2737),(125968,9,2,'e','1',669157,2736),(125969,9,3,'e','1',669157,2883),(125970,2,0,'n','1',669157,2867),(125971,2,1,'n','1',669157,2816),(125972,2,2,'n','1',669157,2732),(125973,2,3,'n','1',669157,2749),(125974,3,0,'n','1',669157,2963),(125975,3,1,'n','1',669157,2717),(125976,3,2,'n','1',669157,2882),(125977,3,3,'n','1',669157,2721),(125978,4,0,'w','1',669157,2754),(125979,4,1,'n','1',669157,2736),(125980,4,2,'n','1',669157,2737),(125981,4,3,'e','1',669157,2759),(125982,5,0,'e','1',669157,2719),(125983,5,1,'e','1',669157,2725),(125984,5,2,'e','1',669157,2735),(125985,5,3,'n','1',669157,2739),(125986,6,0,'s','1',669157,2765),(125987,6,1,'e','1',669157,2749),(125988,6,2,'s','1',669157,2759),(125989,6,3,'e','1',669157,2734),(125990,7,0,'e','1',669157,2884),(125991,7,1,'e','1',669157,2883),(125992,7,2,'w','1',669157,3015),(125993,7,3,'s','1',669157,2921),(125994,8,0,'n','1',669157,2888),(125995,8,1,'n','1',669157,2815),(125996,8,2,'e','1',669157,2818),(125997,8,3,'e','1',669157,2872),(125998,9,0,'w','1',669157,2875),(125999,9,1,'s','1',669157,2737),(126000,9,2,'e','1',669157,2736),(126001,9,3,'e','1',669157,2883),(126002,2,0,'n','1',669158,2992),(126003,2,1,'n','1',669158,2813),(126004,2,2,'n','1',669158,2842),(126005,2,3,'n','1',669158,2738),(126006,3,0,'s','1',669158,2741),(126007,3,1,'w','1',669158,2805),(126008,3,2,'w','1',669158,2738),(126009,3,3,'s','1',669158,2806),(126010,4,0,'n','1',669158,2721),(126011,4,1,'w','1',669158,2754),(126012,4,2,'n','1',669158,2717),(126013,4,3,'n','1',669158,2967),(126014,5,0,'s','1',669158,2734),(126015,5,1,'s','1',669158,2733),(126016,5,2,'n','1',669158,2790),(126017,5,3,'e','1',669158,2858),(126018,6,0,'e','1',669158,2719),(126019,6,1,'e','1',669158,2725),(126020,6,2,'e','1',669158,2735),(126021,6,3,'n','1',669158,2814),(126022,7,0,'w','1',669158,2733),(126023,7,1,'n','1',669158,2732),(126024,7,2,'n','1',669158,2749),(126025,7,3,'w','1',669158,2765),(126026,8,0,'n','1',669158,2905),(126027,8,1,'n','1',669158,2903),(126028,8,2,'e','1',669158,2797),(126029,8,3,'n','1',669158,2964),(126030,9,0,'n','1',669158,2725),(126031,9,1,'n','1',669158,2855),(126032,9,2,'n','1',669158,2854),(126033,9,3,'w','1',669158,2774),(126034,10,0,'w','1',669158,2767),(126035,10,1,'n','1',669158,2766),(126036,10,2,'w','1',669158,2768),(126037,10,3,'e','1',669158,2723),(126038,11,0,'n','1',669158,2872),(126039,11,1,'w','1',669158,2877),(126040,11,2,'s','1',669158,2968),(126041,11,3,'s','1',669158,3050),(126042,12,0,'e','1',669158,2818),(126043,12,1,'s','1',669158,3023),(126044,12,2,'w','1',669158,2769),(126045,12,3,'w','1',669158,2881),(126046,13,0,'e','1',669158,2872),(126047,13,1,'e','1',669158,3014),(126048,13,2,'e','1',669158,2772),(126049,13,3,'e','1',669158,2909),(126050,13,4,'x','0',669158,2950),(126051,14,0,'s','1',669158,3034),(126052,14,1,'w','1',669158,2977),(126053,14,2,'s','1',669158,3020),(126054,14,3,'s','1',669158,2978),(126055,15,0,'e','1',669158,2892),(126056,15,1,'n','1',669158,2895),(126057,15,2,'s','1',669158,3035),(126058,15,3,'s','1',669158,2980),(126059,16,0,'e','1',669158,2939),(126060,16,1,'s','1',669158,3021),(126061,16,2,'e','1',669158,2719),(126062,16,3,'x','0',669158,2725),(126063,16,4,'e','1',669158,3033),(126064,17,0,'n','1',669158,2726),(126065,17,1,'n','1',669158,2873),(126066,17,2,'e','1',669158,2862),(126067,17,3,'n','1',669158,2871),(126068,18,0,'s','1',669158,2977),(126069,18,1,'s','1',669158,2871),(126070,18,2,'e','1',669158,2873),(126071,18,3,'w','1',669158,2857),(126072,19,0,'w','1',669158,2908),(126073,19,1,'w','1',669158,2772),(126074,19,2,'n','1',669158,2730),(126075,19,3,'n','1',669158,2872),(126076,20,0,'w','1',669158,2751),(126077,20,1,'s','1',669158,2859),(126078,20,2,'s','1',669158,2857),(126079,20,3,'e','1',669158,2871),(126080,21,0,'w','1',669158,2840),(126081,21,1,'s','1',669158,2794),(126082,21,2,'s','1',669158,2751),(126083,21,3,'s','1',669158,2877),(126084,22,0,'n','1',669158,2872),(126085,22,1,'n','1',669158,2877),(126086,22,2,'e','1',669158,2886),(126087,22,3,'n','1',669158,2878),(126088,23,0,'n','1',669158,2724),(126089,23,1,'n','1',669158,2753),(126090,23,2,'n','1',669158,2730),(126091,23,3,'w','1',669158,2790),(126092,24,0,'e','1',669158,2751),(126093,24,1,'e','1',669158,2750),(126094,24,2,'s','1',669158,2860),(126095,24,3,'s','1',669158,2749),(126096,25,0,'s','1',669158,2783),(126097,25,1,'e','1',669158,2780),(126098,25,2,'e','1',669158,2829),(126099,25,3,'x','0',669158,2778),(126100,25,4,'n','1',669158,2753),(126101,26,0,'n','1',669158,2740),(126102,26,1,'e','1',669158,2732),(126103,26,2,'n','1',669158,2736),(126104,26,3,'n','1',669158,2737),(126105,27,0,'e','1',669158,2762),(126106,27,1,'s','1',669158,2733),(126107,27,2,'e','1',669158,2996),(126108,27,3,'s','1',669158,2814),(126109,28,0,'w','1',669158,2837),(126110,28,1,'n','1',669158,2759),(126111,28,2,'n','1',669158,3037),(126112,28,3,'e','1',669158,2782),(126113,29,0,'n','1',669158,3015),(126114,29,1,'n','1',669158,2989),(126115,29,2,'w','1',669158,3039),(126116,29,3,'w','1',669158,2953),(126117,30,0,'n','1',669158,3003),(126118,30,1,'e','1',669158,2897),(126119,30,2,'n','1',669158,2814),(126120,30,3,'n','1',669158,2903),(126121,31,0,'s','1',669158,2801),(126122,31,1,'e','1',669158,2900),(126123,31,2,'s','1',669158,2793),(126124,31,3,'s','1',669158,2880),(126125,32,0,'w','1',669158,2879),(126126,32,1,'e','1',669158,2878),(126127,32,2,'s','1',669158,2862),(126128,32,3,'e','1',669158,2942),(126129,2,0,'n','1',669158,2992),(126130,2,1,'n','1',669158,2813),(126131,2,2,'n','1',669158,2842),(126132,2,3,'n','1',669158,2738),(126133,3,0,'s','1',669158,2741),(126134,3,1,'w','1',669158,2805),(126135,3,2,'w','1',669158,2738),(126136,3,3,'s','1',669158,2806),(126137,4,0,'n','1',669158,2721),(126138,4,1,'w','1',669158,2754),(126139,4,2,'n','1',669158,2717),(126140,4,3,'n','1',669158,2967),(126141,5,0,'s','1',669158,2734),(126142,5,1,'s','1',669158,2733),(126143,5,2,'n','1',669158,2790),(126144,5,3,'e','1',669158,2858),(126145,6,0,'e','1',669158,2719),(126146,6,1,'e','1',669158,2725),(126147,6,2,'e','1',669158,2735),(126148,6,3,'n','1',669158,2814),(126149,7,0,'w','1',669158,2733),(126150,7,1,'n','1',669158,2732),(126151,7,2,'n','1',669158,2749),(126152,7,3,'w','1',669158,2765),(126153,8,0,'n','1',669158,2905),(126154,8,1,'n','1',669158,2903),(126155,8,2,'e','1',669158,2797),(126156,8,3,'n','1',669158,2964),(126157,9,0,'n','1',669158,2725),(126158,9,1,'n','1',669158,2855),(126159,9,2,'n','1',669158,2854),(126160,9,3,'w','1',669158,2774),(126161,10,0,'w','1',669158,2767),(126162,10,1,'n','1',669158,2766),(126163,10,2,'w','1',669158,2768),(126164,10,3,'e','1',669158,2723),(126165,11,0,'n','1',669158,2872),(126166,11,1,'w','1',669158,2877),(126167,11,2,'s','1',669158,2968),(126168,11,3,'s','1',669158,3050),(126169,12,0,'e','1',669158,2818),(126170,12,1,'s','1',669158,3023),(126171,12,2,'w','1',669158,2769),(126172,12,3,'w','1',669158,2881),(126173,13,0,'e','1',669158,2872),(126174,13,1,'e','1',669158,3014),(126175,13,2,'e','1',669158,2772),(126176,13,3,'e','1',669158,2909),(126177,13,4,'x','0',669158,2950),(126178,14,0,'s','1',669158,3034),(126179,14,1,'w','1',669158,2977),(126180,14,2,'s','1',669158,3020),(126181,14,3,'s','1',669158,2978),(126182,15,0,'e','1',669158,2892),(126183,15,1,'n','1',669158,2895),(126184,15,2,'s','1',669158,3035),(126185,15,3,'s','1',669158,2980),(126186,16,0,'e','1',669158,2939),(126187,16,1,'s','1',669158,3021),(126188,16,2,'e','1',669158,2719),(126189,16,3,'x','0',669158,2725),(126190,16,4,'e','1',669158,3033),(126191,17,0,'n','1',669158,2726),(126192,17,1,'n','1',669158,2873),(126193,17,2,'e','1',669158,2862),(126194,17,3,'n','1',669158,2871),(126195,18,0,'s','1',669158,2977),(126196,18,1,'s','1',669158,2871),(126197,18,2,'e','1',669158,2873),(126198,18,3,'w','1',669158,2857),(126199,19,0,'w','1',669158,2908),(126200,19,1,'w','1',669158,2772),(126201,19,2,'n','1',669158,2730),(126202,19,3,'n','1',669158,2872),(126203,20,0,'w','1',669158,2751),(126204,20,1,'s','1',669158,2859),(126205,20,2,'s','1',669158,2857),(126206,20,3,'e','1',669158,2871),(126207,21,0,'w','1',669158,2840),(126208,21,1,'s','1',669158,2794),(126209,21,2,'s','1',669158,2751),(126210,21,3,'s','1',669158,2877),(126211,22,0,'n','1',669158,2872),(126212,22,1,'n','1',669158,2877),(126213,22,2,'e','1',669158,2886),(126214,22,3,'n','1',669158,2878),(126215,23,0,'n','1',669158,2724),(126216,23,1,'n','1',669158,2753),(126217,23,2,'n','1',669158,2730),(126218,23,3,'w','1',669158,2790),(126219,24,0,'e','1',669158,2751),(126220,24,1,'e','1',669158,2750),(126221,24,2,'s','1',669158,2860),(126222,24,3,'s','1',669158,2749),(126223,25,0,'s','1',669158,2783),(126224,25,1,'e','1',669158,2780),(126225,25,2,'e','1',669158,2829),(126226,25,3,'x','0',669158,2778),(126227,25,4,'n','1',669158,2753),(126228,26,0,'n','1',669158,2740),(126229,26,1,'e','1',669158,2732),(126230,26,2,'n','1',669158,2736),(126231,26,3,'n','1',669158,2737),(126232,27,0,'e','1',669158,2762),(126233,27,1,'s','1',669158,2733),(126234,27,2,'e','1',669158,2996),(126235,27,3,'s','1',669158,2814),(126236,28,0,'w','1',669158,2837),(126237,28,1,'n','1',669158,2759),(126238,28,2,'n','1',669158,3037),(126239,28,3,'e','1',669158,2782),(126240,29,0,'n','1',669158,3015),(126241,29,1,'n','1',669158,2989),(126242,29,2,'w','1',669158,3039),(126243,29,3,'w','1',669158,2953),(126244,30,0,'n','1',669158,3003),(126245,30,1,'e','1',669158,2897),(126246,30,2,'n','1',669158,2814),(126247,30,3,'n','1',669158,2903),(126248,31,0,'s','1',669158,2801),(126249,31,1,'e','1',669158,2900),(126250,31,2,'s','1',669158,2793),(126251,31,3,'s','1',669158,2880),(126252,32,0,'w','1',669158,2879),(126253,32,1,'e','1',669158,2878),(126254,32,2,'s','1',669158,2862),(126255,32,3,'e','1',669158,2942),(126256,2,0,'n','1',669159,2964),(126257,2,1,'n','1',669159,2815),(126258,2,2,'n','1',669159,3051),(126259,2,3,'n','1',669159,2724),(126260,3,0,'n','1',669159,2818),(126261,3,1,'n','1',669159,3052),(126262,3,2,'e','1',669159,2968),(126263,3,3,'n','1',669159,3033),(126264,4,0,'n','1',669159,3021),(126265,4,1,'n','1',669159,2980),(126266,4,2,'e','1',669159,2978),(126267,4,3,'n','1',669159,2868),(126268,5,0,'n','1',669159,2877),(126269,5,1,'e','1',669159,2878),(126270,5,2,'n','1',669159,2879),(126271,5,3,'n','1',669159,2956),(126272,6,0,'s','1',669159,2880),(126273,6,1,'w','1',669159,2860),(126274,6,2,'n','1',669159,2834),(126275,6,3,'n','1',669159,2823),(126276,7,0,'s','1',669159,2860),(126277,7,1,'e','1',669159,2880),(126278,7,2,'s','1',669159,2792),(126279,7,3,'s','1',669159,2764),(126280,8,0,'s','1',669159,2977),(126281,8,1,'s','1',669159,2871),(126282,8,2,'e','1',669159,2873),(126283,8,3,'n','1',669159,2875),(126284,9,0,'w','1',669159,2730),(126285,9,1,'w','1',669159,2851),(126286,9,2,'s','1',669159,2785),(126287,9,3,'x','0',669159,2784),(126288,9,4,'e','1',669159,2873),(126289,10,0,'n','1',669159,2730),(126290,10,1,'w','1',669159,2751),(126291,10,2,'w','1',669159,2871),(126292,10,3,'s','1',669159,2769),(126293,11,0,'n','1',669159,2980),(126294,11,1,'s','1',669159,2900),(126295,11,2,'e','1',669159,2978),(126296,11,3,'s','1',669159,2849),(126297,12,0,'e','1',669159,2878),(126298,12,1,'s','1',669159,2977),(126299,12,2,'e','1',669159,2879),(126300,12,3,'e','1',669159,2871),(126301,13,0,'w','1',669159,2858),(126302,13,1,'w','1',669159,2751),(126303,13,2,'w','1',669159,2962),(126304,13,3,'n','1',669159,2927),(126305,14,0,'e','1',669159,2871),(126306,14,1,'e','1',669159,2751),(126307,14,2,'s','1',669159,2766),(126308,14,3,'w','1',669159,2790),(126309,15,0,'w','1',669159,2750),(126310,15,1,'e','1',669159,2751),(126311,15,2,'s','1',669159,2766),(126312,15,3,'n','1',669159,2888),(126313,16,0,'w','1',669159,2750),(126314,16,1,'w','1',669159,2751),(126315,16,2,'s','1',669159,2766),(126316,17,0,'e','1',669159,2871),(126317,17,1,'e','1',669159,2751),(126318,17,2,'s','1',669159,2766),(126319,17,3,'n','1',669159,2750),(126320,18,0,'w','1',669159,2841),(126321,18,1,'w','1',669159,2951),(126322,18,2,'s','1',669159,2768),(126323,18,3,'n','1',669159,2841),(126324,19,0,'n','1',669159,2949),(126325,19,1,'w','1',669159,2750),(126326,19,2,'w','1',669159,2751),(126327,19,3,'e','1',669159,2975),(126328,20,0,'e','1',669159,2871),(126329,20,1,'s','1',669159,2751),(126330,20,2,'s','1',669159,2766),(126331,20,3,'n','1',669159,2791),(126332,21,0,'n','1',669159,2730),(126333,21,1,'w','1',669159,2751),(126334,21,2,'e','1',669159,2871),(126335,21,3,'s','1',669159,2769),(126336,22,0,'n','1',669159,2774),(126337,22,1,'n','1',669159,2773),(126338,22,2,'w','1',669159,2751),(126339,22,3,'w','1',669159,2861),(126340,23,0,'n','1',669159,2871),(126341,23,1,'e','1',669159,2941),(126342,23,2,'s','1',669159,2840),(126343,23,3,'s','1',669159,2977),(126344,24,0,'e','1',669159,2871),(126345,24,1,'e','1',669159,2751),(126346,24,2,'e','1',669159,2750),(126347,24,3,'s','1',669159,2860),(126348,25,0,'n','1',669159,2872),(126349,25,1,'s','1',669159,2877),(126350,25,2,'e','1',669159,2781),(126351,25,3,'w','1',669159,2749),(126352,26,0,'w','1',669159,2750),(126353,26,1,'s','1',669159,2751),(126354,26,2,'e','1',669159,2846),(126355,26,3,'n','1',669159,2745),(126356,27,0,'n','1',669159,2730),(126357,27,1,'n','1',669159,2751),(126358,27,2,'s','1',669159,2881),(126359,27,3,'s','1',669159,2767),(126360,28,0,'w','1',669159,2821),(126361,28,1,'n','1',669159,2875),(126362,28,2,'w','1',669159,2843),(126363,28,3,'n','1',669159,2849),(126364,29,0,'w','1',669159,2751),(126365,29,1,'s','1',669159,2859),(126366,29,2,'n','1',669159,2958),(126367,29,3,'n','1',669159,2923),(126368,30,0,'s','1',669159,2753),(126369,30,1,'n','1',669159,2804),(126370,30,2,'w','1',669159,2959),(126371,30,3,'e','1',669159,2758),(126372,31,0,'e','1',669159,2841),(126373,31,1,'e','1',669159,2951),(126374,31,2,'n','1',669159,2782),(126375,31,3,'n','1',669159,2838),(126376,32,0,'s','1',669159,2857),(126377,32,1,'e','1',669159,2871),(126378,32,2,'s','1',669159,2794),(126379,32,3,'s','1',669159,2751),(126380,33,0,'e','1',669159,2843),(126381,33,1,'s','1',669159,2743),(126382,33,2,'w','1',669159,2839),(126383,33,3,'w','1',669159,2934),(126384,34,0,'w','1',669159,2804),(126385,34,1,'w','1',669159,2832),(126386,34,2,'n','1',669159,2970),(126387,34,3,'n','1',669159,2747),(126388,35,0,'e','1',669159,2802),(126389,35,1,'n','1',669159,2959),(126390,35,2,'n','1',669159,2960),(126391,35,3,'n','1',669159,2730),(126392,36,0,'w','1',669159,2821),(126393,36,1,'w','1',669159,2843),(126394,36,2,'s','1',669159,2774),(126395,36,3,'e','1',669159,2751),(126396,37,0,'e','1',669159,2905),(126397,37,1,'n','1',669159,2861),(126398,37,2,'n','1',669159,2955),(126399,37,3,'e','1',669159,2856),(126400,38,0,'n','1',669159,2872),(126401,38,1,'s','1',669159,2877),(126402,38,2,'e','1',669159,2781),(126403,38,3,'e','1',669159,2897),(126404,39,0,'w','1',669159,2750),(126405,39,1,'s','1',669159,2773),(126406,39,2,'w','1',669159,2751),(126407,39,3,'e','1',669159,2858),(126408,40,0,'s','1',669159,2990),(126409,40,1,'e','1',669159,2778),(126410,40,2,'e','1',669159,2871),(126411,40,3,'s','1',669159,2751),(126412,41,0,'e','1',669159,2777),(126413,41,1,'w','1',669159,2953),(126414,41,2,'n','1',669159,2897),(126415,41,3,'s','1',669159,2872),(126416,42,0,'n','1',669159,2791),(126417,42,1,'e','1',669159,2966),(126418,42,2,'w','1',669159,2777),(126419,42,3,'x','0',669159,2778),(126420,42,4,'n','1',669159,2955),(126421,43,0,'n','1',669159,2795),(126422,43,1,'n','1',669159,2990),(126423,43,2,'n','1',669159,2796),(126424,43,3,'e','1',669159,2906),(126425,44,0,'e','1',669159,2964),(126426,44,1,'e','1',669159,2995),(126427,44,2,'e','1',669159,2790),(126428,44,3,'e','1',669159,2797),(126429,45,0,'n','1',669159,2730),(126430,45,1,'e','1',669159,2831),(126431,45,2,'s','1',669159,2794),(126432,45,3,'x','0',669159,2778),(126433,45,4,'s','1',669159,2751),(126434,46,0,'n','1',669159,2903),(126435,46,1,'s','1',669159,2856),(126436,46,2,'n','1',669159,2965),(126437,46,3,'n','1',669159,2730),(126438,47,0,'n','1',669159,2724),(126439,47,1,'n','1',669159,2753),(126440,47,2,'s','1',669159,2751),(126441,47,3,'w','1',669159,2774),(126442,48,0,'s','1',669159,2730),(126443,48,1,'s','1',669159,2857),(126444,48,2,'s','1',669159,2727),(126445,48,3,'s','1',669159,2794),(126446,48,4,'x','0',669159,2778),(126447,49,0,'e','1',669159,2783),(126448,49,1,'e','1',669159,2908),(126449,49,2,'e','1',669159,2986),(126450,49,3,'e','1',669159,2760),(126451,50,0,'e','1',669159,2784),(126452,50,1,'e','1',669159,2775),(126453,50,2,'e','1',669159,2786),(126454,51,0,'e','1',669159,2957),(126455,51,1,'n','1',669159,3036),(126456,51,2,'n','1',669159,2995),(126457,51,3,'x','0',669159,2772),(126458,51,4,'w','1',669159,2913),(126459,52,0,'e','1',669159,2957),(126460,52,1,'n','1',669159,2913),(126461,52,2,'n','1',669159,2874),(126462,52,3,'n','1',669159,2731),(126463,53,0,'e','1',669159,2750),(126464,53,1,'e','1',669159,2749),(126465,53,2,'s','1',669159,2734),(126466,53,3,'s','1',669159,2733),(126467,54,0,'n','1',669159,2901),(126468,54,1,'n','1',669159,2817),(126469,54,2,'e','1',669159,2737),(126470,55,0,'e','1',669159,2927),(126471,55,1,'e','1',669159,2962),(126472,55,2,'e','1',669159,2858),(126473,55,3,'e','1',669159,2790),(126474,56,0,'n','1',669159,2789),(126475,56,1,'n','1',669159,2795),(126476,56,2,'n','1',669159,2796),(126477,56,3,'e','1',669159,2798),(126478,57,0,'e','1',669159,2797),(126479,57,1,'e','1',669159,2903),(126480,58,0,'w','1',669159,2817),(126481,58,1,'w','1',669159,2905),(126482,58,2,'w','1',669159,2789),(126483,58,3,'w','1',669159,2791),(126484,59,0,'e','1',669159,2902),(126485,59,1,'e','1',669159,2791),(126486,59,2,'e','1',669159,2789),(126487,59,3,'e','1',669159,2905),(126488,60,0,'w','1',669159,2817),(126489,60,1,'w','1',669159,2905),(126490,60,2,'w','1',669159,2789),(126491,61,0,'n','1',669159,2791),(126492,61,1,'n','1',669159,2777),(126493,62,0,'w','1',669159,2776),(126494,63,0,'w','1',669159,2776),(126495,63,1,'n','1',669159,2794),(126496,63,2,'w','1',669159,2857),(126497,63,3,'n','1',669159,2840),(126498,64,0,'w','1',669159,2834),(126499,65,0,'w','1',669159,2857),(126500,66,0,'w','1',669159,2857),(126501,67,0,'w','1',669159,2857),(126502,68,0,'e','1',669159,2817),(126503,69,0,'w','1',669159,2834),(126504,69,1,'n','1',669159,2817),(126505,69,2,'n','1',669159,2824),(126506,70,0,'e','1',669159,2729),(126507,70,1,'n','1',669159,2745),(126508,70,2,'n','1',669159,2821),(126509,70,3,'n','1',669159,2985),(126510,2,0,'n','1',669159,2964),(126511,2,1,'n','1',669159,2815),(126512,2,2,'n','1',669159,3051),(126513,2,3,'n','1',669159,2724),(126514,3,0,'n','1',669159,2818),(126515,3,1,'n','1',669159,3052),(126516,3,2,'e','1',669159,2968),(126517,3,3,'n','1',669159,3033),(126518,4,0,'n','1',669159,3021),(126519,4,1,'n','1',669159,2980),(126520,4,2,'e','1',669159,2978),(126521,4,3,'n','1',669159,2868),(126522,5,0,'n','1',669159,2877),(126523,5,1,'e','1',669159,2878),(126524,5,2,'n','1',669159,2879),(126525,5,3,'n','1',669159,2956),(126526,6,0,'s','1',669159,2880),(126527,6,1,'w','1',669159,2860),(126528,6,2,'n','1',669159,2834),(126529,6,3,'n','1',669159,2823),(126530,7,0,'s','1',669159,2860),(126531,7,1,'e','1',669159,2880),(126532,7,2,'s','1',669159,2792),(126533,7,3,'s','1',669159,2764),(126534,8,0,'s','1',669159,2977),(126535,8,1,'s','1',669159,2871),(126536,8,2,'e','1',669159,2873),(126537,8,3,'n','1',669159,2875),(126538,9,0,'w','1',669159,2730),(126539,9,1,'w','1',669159,2851),(126540,9,2,'s','1',669159,2785),(126541,9,3,'x','0',669159,2784),(126542,9,4,'e','1',669159,2873),(126543,10,0,'n','1',669159,2730),(126544,10,1,'w','1',669159,2751),(126545,10,2,'w','1',669159,2871),(126546,10,3,'s','1',669159,2769),(126547,11,0,'n','1',669159,2980),(126548,11,1,'s','1',669159,2900),(126549,11,2,'e','1',669159,2978),(126550,11,3,'s','1',669159,2849),(126551,12,0,'e','1',669159,2878),(126552,12,1,'s','1',669159,2977),(126553,12,2,'e','1',669159,2879),(126554,12,3,'e','1',669159,2871),(126555,13,0,'w','1',669159,2858),(126556,13,1,'w','1',669159,2751),(126557,13,2,'w','1',669159,2962),(126558,13,3,'n','1',669159,2927),(126559,14,0,'e','1',669159,2871),(126560,14,1,'e','1',669159,2751),(126561,14,2,'s','1',669159,2766),(126562,14,3,'w','1',669159,2790),(126563,15,0,'w','1',669159,2750),(126564,15,1,'e','1',669159,2751),(126565,15,2,'s','1',669159,2766),(126566,15,3,'n','1',669159,2888),(126567,16,0,'w','1',669159,2750),(126568,16,1,'w','1',669159,2751),(126569,16,2,'s','1',669159,2766),(126570,17,0,'e','1',669159,2871),(126571,17,1,'e','1',669159,2751),(126572,17,2,'s','1',669159,2766),(126573,17,3,'n','1',669159,2750),(126574,18,0,'w','1',669159,2841),(126575,18,1,'w','1',669159,2951),(126576,18,2,'s','1',669159,2768),(126577,18,3,'n','1',669159,2841),(126578,19,0,'n','1',669159,2949),(126579,19,1,'w','1',669159,2750),(126580,19,2,'w','1',669159,2751),(126581,19,3,'e','1',669159,2975),(126582,20,0,'e','1',669159,2871),(126583,20,1,'s','1',669159,2751),(126584,20,2,'s','1',669159,2766),(126585,20,3,'n','1',669159,2791),(126586,21,0,'n','1',669159,2730),(126587,21,1,'w','1',669159,2751),(126588,21,2,'e','1',669159,2871),(126589,21,3,'s','1',669159,2769),(126590,22,0,'n','1',669159,2774),(126591,22,1,'n','1',669159,2773),(126592,22,2,'w','1',669159,2751),(126593,22,3,'w','1',669159,2861),(126594,23,0,'n','1',669159,2871),(126595,23,1,'e','1',669159,2941),(126596,23,2,'s','1',669159,2840),(126597,23,3,'s','1',669159,2977),(126598,24,0,'e','1',669159,2871),(126599,24,1,'e','1',669159,2751),(126600,24,2,'e','1',669159,2750),(126601,24,3,'s','1',669159,2860),(126602,25,0,'n','1',669159,2872),(126603,25,1,'s','1',669159,2877),(126604,25,2,'e','1',669159,2781),(126605,25,3,'w','1',669159,2749),(126606,26,0,'w','1',669159,2750),(126607,26,1,'s','1',669159,2751),(126608,26,2,'e','1',669159,2846),(126609,26,3,'n','1',669159,2745),(126610,27,0,'n','1',669159,2730),(126611,27,1,'n','1',669159,2751),(126612,27,2,'s','1',669159,2881),(126613,27,3,'s','1',669159,2767),(126614,28,0,'w','1',669159,2821),(126615,28,1,'n','1',669159,2875),(126616,28,2,'w','1',669159,2843),(126617,28,3,'n','1',669159,2849),(126618,29,0,'w','1',669159,2751),(126619,29,1,'s','1',669159,2859),(126620,29,2,'n','1',669159,2958),(126621,29,3,'n','1',669159,2923),(126622,30,0,'s','1',669159,2753),(126623,30,1,'n','1',669159,2804),(126624,30,2,'w','1',669159,2959),(126625,30,3,'e','1',669159,2758),(126626,31,0,'e','1',669159,2841),(126627,31,1,'e','1',669159,2951),(126628,31,2,'n','1',669159,2782),(126629,31,3,'n','1',669159,2838),(126630,32,0,'s','1',669159,2857),(126631,32,1,'e','1',669159,2871),(126632,32,2,'s','1',669159,2794),(126633,32,3,'s','1',669159,2751),(126634,33,0,'e','1',669159,2843),(126635,33,1,'s','1',669159,2743),(126636,33,2,'w','1',669159,2839),(126637,33,3,'w','1',669159,2934),(126638,34,0,'w','1',669159,2804),(126639,34,1,'w','1',669159,2832),(126640,34,2,'n','1',669159,2970),(126641,34,3,'n','1',669159,2747),(126642,35,0,'e','1',669159,2802),(126643,35,1,'n','1',669159,2959),(126644,35,2,'n','1',669159,2960),(126645,35,3,'n','1',669159,2730),(126646,36,0,'w','1',669159,2821),(126647,36,1,'w','1',669159,2843),(126648,36,2,'s','1',669159,2774),(126649,36,3,'e','1',669159,2751),(126650,37,0,'e','1',669159,2905),(126651,37,1,'n','1',669159,2861),(126652,37,2,'n','1',669159,2955),(126653,37,3,'e','1',669159,2856),(126654,38,0,'n','1',669159,2872),(126655,38,1,'s','1',669159,2877),(126656,38,2,'e','1',669159,2781),(126657,38,3,'e','1',669159,2897),(126658,39,0,'w','1',669159,2750),(126659,39,1,'s','1',669159,2773),(126660,39,2,'w','1',669159,2751),(126661,39,3,'e','1',669159,2858),(126662,40,0,'s','1',669159,2990),(126663,40,1,'e','1',669159,2778),(126664,40,2,'e','1',669159,2871),(126665,40,3,'s','1',669159,2751),(126666,41,0,'e','1',669159,2777),(126667,41,1,'w','1',669159,2953),(126668,41,2,'n','1',669159,2897),(126669,41,3,'s','1',669159,2872),(126670,42,0,'n','1',669159,2791),(126671,42,1,'e','1',669159,2966),(126672,42,2,'w','1',669159,2777),(126673,42,3,'x','0',669159,2778),(126674,42,4,'n','1',669159,2955),(126675,43,0,'n','1',669159,2795),(126676,43,1,'n','1',669159,2990),(126677,43,2,'n','1',669159,2796),(126678,43,3,'e','1',669159,2906),(126679,44,0,'e','1',669159,2964),(126680,44,1,'e','1',669159,2995),(126681,44,2,'e','1',669159,2790),(126682,44,3,'e','1',669159,2797),(126683,45,0,'n','1',669159,2730),(126684,45,1,'e','1',669159,2831),(126685,45,2,'s','1',669159,2794),(126686,45,3,'x','0',669159,2778),(126687,45,4,'s','1',669159,2751),(126688,46,0,'n','1',669159,2903),(126689,46,1,'s','1',669159,2856),(126690,46,2,'n','1',669159,2965),(126691,46,3,'n','1',669159,2730),(126692,47,0,'n','1',669159,2724),(126693,47,1,'n','1',669159,2753),(126694,47,2,'s','1',669159,2751),(126695,47,3,'w','1',669159,2774),(126696,48,0,'s','1',669159,2730),(126697,48,1,'s','1',669159,2857),(126698,48,2,'s','1',669159,2727),(126699,48,3,'s','1',669159,2794),(126700,48,4,'x','0',669159,2778),(126701,49,0,'e','1',669159,2783),(126702,49,1,'e','1',669159,2908),(126703,49,2,'e','1',669159,2986),(126704,49,3,'e','1',669159,2760),(126705,50,0,'e','1',669159,2784),(126706,50,1,'e','1',669159,2775),(126707,50,2,'e','1',669159,2786),(126708,51,0,'e','1',669159,2957),(126709,51,1,'n','1',669159,3036),(126710,51,2,'n','1',669159,2995),(126711,51,3,'x','0',669159,2772),(126712,51,4,'w','1',669159,2913),(126713,52,0,'e','1',669159,2957),(126714,52,1,'n','1',669159,2913),(126715,52,2,'n','1',669159,2874),(126716,52,3,'n','1',669159,2731),(126717,53,0,'e','1',669159,2750),(126718,53,1,'e','1',669159,2749),(126719,53,2,'s','1',669159,2734),(126720,53,3,'s','1',669159,2733),(126721,54,0,'n','1',669159,2901),(126722,54,1,'n','1',669159,2817),(126723,54,2,'e','1',669159,2737),(126724,55,0,'e','1',669159,2927),(126725,55,1,'e','1',669159,2962),(126726,55,2,'e','1',669159,2858),(126727,55,3,'e','1',669159,2790),(126728,56,0,'n','1',669159,2789),(126729,56,1,'n','1',669159,2795),(126730,56,2,'n','1',669159,2796),(126731,56,3,'e','1',669159,2798),(126732,57,0,'e','1',669159,2797),(126733,57,1,'e','1',669159,2903),(126734,58,0,'w','1',669159,2817),(126735,58,1,'w','1',669159,2905),(126736,58,2,'w','1',669159,2789),(126737,58,3,'w','1',669159,2791),(126738,59,0,'e','1',669159,2902),(126739,59,1,'e','1',669159,2791),(126740,59,2,'e','1',669159,2789),(126741,59,3,'e','1',669159,2905),(126742,60,0,'w','1',669159,2817),(126743,60,1,'w','1',669159,2905),(126744,60,2,'w','1',669159,2789),(126745,61,0,'n','1',669159,2791),(126746,61,1,'n','1',669159,2777),(126747,62,0,'w','1',669159,2776),(126748,63,0,'w','1',669159,2776),(126749,63,1,'n','1',669159,2794),(126750,63,2,'w','1',669159,2857),(126751,63,3,'n','1',669159,2840),(126752,64,0,'w','1',669159,2834),(126753,65,0,'w','1',669159,2857),(126754,66,0,'w','1',669159,2857),(126755,67,0,'w','1',669159,2857),(126756,68,0,'e','1',669159,2817),(126757,69,0,'w','1',669159,2834),(126758,69,1,'n','1',669159,2817),(126759,69,2,'n','1',669159,2824),(126760,70,0,'e','1',669159,2729),(126761,70,1,'n','1',669159,2745),(126762,70,2,'n','1',669159,2821),(126763,70,3,'n','1',669159,2985),(126764,2,0,'n','1',669160,2913),(126765,2,1,'n','1',669160,2827),(126766,2,2,'n','1',669160,2815),(126767,2,3,'n','1',669160,2964),(126768,3,0,'n','1',669160,2874),(126769,3,1,'n','1',669160,2969),(126770,3,2,'n','1',669160,2784),(126771,3,3,'n','1',669160,2927),(126772,4,0,'n','1',669160,2731),(126773,4,1,'e','1',669160,2750),(126774,4,2,'w','1',669160,2749),(126775,4,3,'s','1',669160,2970),(126776,2,0,'n','1',669160,2913),(126777,2,1,'n','1',669160,2827),(126778,2,2,'n','1',669160,2815),(126779,2,3,'n','1',669160,2964),(126780,3,0,'n','1',669160,2874),(126781,3,1,'n','1',669160,2969),(126782,3,2,'n','1',669160,2784),(126783,3,3,'n','1',669160,2927),(126784,4,0,'n','1',669160,2731),(126785,4,1,'e','1',669160,2750),(126786,4,2,'w','1',669160,2749),(126787,4,3,'s','1',669160,2970),(126788,2,0,'n','1',669161,2867),(126789,2,1,'n','1',669161,2828),(126790,2,2,'n','1',669161,2815),(126791,2,3,'n','1',669161,2753),(126792,3,0,'n','1',669161,2958),(126793,3,1,'n','1',669161,3015),(126794,3,2,'n','1',669161,2816),(126795,3,3,'n','1',669161,2790),(126796,4,0,'n','1',669161,2732),(126797,4,1,'n','1',669161,2749),(126798,4,2,'s','1',669161,2765),(126799,4,3,'s','1',669161,3053),(126800,5,0,'s','1',669161,2749),(126801,5,1,'s','1',669161,2987),(126802,5,2,'n','1',669161,2725),(126803,5,3,'e','1',669161,2855),(126804,6,0,'e','1',669161,2732),(126805,6,1,'w','1',669161,2733),(126806,6,2,'s','1',669161,2756),(126807,6,3,'n','1',669161,2954),(126808,7,0,'e','1',669161,2732),(126809,7,1,'n','1',669161,2879),(126810,7,2,'w','1',669161,2876),(126811,7,3,'e','1',669161,2854),(126812,8,0,'w','1',669161,2733),(126813,8,1,'s','1',669161,2832),(126814,8,2,'s','1',669161,2850),(126815,8,3,'x','0',669161,2883),(126816,8,4,'e','1',669161,2732),(126817,9,0,'w','1',669161,2733),(126818,9,1,'w','1',669161,2737),(126819,9,2,'s','1',669161,2740),(126820,9,3,'x','0',669161,2760),(126821,9,4,'e','1',669161,2732),(126822,10,0,'w','1',669161,2733),(126823,10,1,'n','1',669161,2995),(126824,10,2,'e','1',669161,2772),(126825,10,3,'n','1',669161,2927),(126826,11,0,'e','1',669161,2753),(126827,11,1,'n','1',669161,2818),(126828,11,2,'n','1',669161,2968),(126829,11,3,'e','1',669161,2981),(126830,12,0,'e','1',669161,2878),(126831,12,1,'s','1',669161,2931),(126832,12,2,'s','1',669161,2879),(126833,12,3,'e','1',669161,2930),(126834,13,0,'s','1',669161,2784),(126835,13,1,'n','1',669161,2952),(126836,13,2,'n','1',669161,2934),(126837,13,3,'n','1',669161,2779),(126838,14,0,'w','1',669161,2986),(126839,14,1,'w','1',669161,2771),(126840,14,2,'n','1',669161,2784),(126841,14,3,'n','1',669161,2877),(126842,15,0,'e','1',669161,2772),(126843,15,1,'n','1',669161,2962),(126844,15,2,'n','1',669161,2790),(126845,15,3,'n','1',669161,2797),(126846,16,0,'e','1',669161,2772),(126847,16,1,'s','1',669161,2835),(126848,16,2,'w','1',669161,2878),(126849,16,3,'n','1',669161,2789),(126850,17,0,'n','1',669161,2946),(126851,17,1,'n','1',669161,2784),(126852,17,2,'n','1',669161,2903),(126853,17,3,'n','1',669161,2901),(126854,18,0,'e','1',669161,2981),(126855,18,1,'n','1',669161,2946),(126856,18,2,'e','1',669161,2848),(126857,18,3,'s','1',669161,2878),(126858,19,0,'n','1',669161,2732),(126859,19,1,'e','1',669161,2852),(126860,19,2,'n','1',669161,2749),(126861,19,3,'s','1',669161,2765),(126862,20,0,'n','1',669161,2795),(126863,20,1,'w','1',669161,2749),(126864,20,2,'n','1',669161,2796),(126865,20,3,'n','1',669161,2798),(126866,21,0,'n','1',669161,2852),(126867,21,1,'n','1',669161,2912),(126868,2,0,'n','1',669161,2867),(126869,2,1,'n','1',669161,2828),(126870,2,2,'n','1',669161,2815),(126871,2,3,'n','1',669161,2753),(126872,3,0,'n','1',669161,2958),(126873,3,1,'n','1',669161,3015),(126874,3,2,'n','1',669161,2816),(126875,3,3,'n','1',669161,2790),(126876,4,0,'n','1',669161,2732),(126877,4,1,'n','1',669161,2749),(126878,4,2,'s','1',669161,2765),(126879,4,3,'s','1',669161,3053),(126880,5,0,'s','1',669161,2749),(126881,5,1,'s','1',669161,2987),(126882,5,2,'n','1',669161,2725),(126883,5,3,'e','1',669161,2855),(126884,6,0,'e','1',669161,2732),(126885,6,1,'w','1',669161,2733),(126886,6,2,'s','1',669161,2756),(126887,6,3,'n','1',669161,2954),(126888,7,0,'e','1',669161,2732),(126889,7,1,'n','1',669161,2879),(126890,7,2,'w','1',669161,2876),(126891,7,3,'e','1',669161,2854),(126892,8,0,'w','1',669161,2733),(126893,8,1,'s','1',669161,2832),(126894,8,2,'s','1',669161,2850),(126895,8,3,'x','0',669161,2883),(126896,8,4,'e','1',669161,2732),(126897,9,0,'w','1',669161,2733),(126898,9,1,'w','1',669161,2737),(126899,9,2,'s','1',669161,2740),(126900,9,3,'x','0',669161,2760),(126901,9,4,'e','1',669161,2732),(126902,10,0,'w','1',669161,2733),(126903,10,1,'n','1',669161,2995),(126904,10,2,'e','1',669161,2772),(126905,10,3,'n','1',669161,2927),(126906,11,0,'e','1',669161,2753),(126907,11,1,'n','1',669161,2818),(126908,11,2,'n','1',669161,2968),(126909,11,3,'e','1',669161,2981),(126910,12,0,'e','1',669161,2878),(126911,12,1,'s','1',669161,2931),(126912,12,2,'s','1',669161,2879),(126913,12,3,'e','1',669161,2930),(126914,13,0,'s','1',669161,2784),(126915,13,1,'n','1',669161,2952),(126916,13,2,'n','1',669161,2934),(126917,13,3,'n','1',669161,2779),(126918,14,0,'w','1',669161,2986),(126919,14,1,'w','1',669161,2771),(126920,14,2,'n','1',669161,2784),(126921,14,3,'n','1',669161,2877),(126922,15,0,'e','1',669161,2772),(126923,15,1,'n','1',669161,2962),(126924,15,2,'n','1',669161,2790),(126925,15,3,'n','1',669161,2797),(126926,16,0,'e','1',669161,2772),(126927,16,1,'s','1',669161,2835),(126928,16,2,'w','1',669161,2878),(126929,16,3,'n','1',669161,2789),(126930,17,0,'n','1',669161,2946),(126931,17,1,'n','1',669161,2784),(126932,17,2,'n','1',669161,2903),(126933,17,3,'n','1',669161,2901),(126934,18,0,'e','1',669161,2981),(126935,18,1,'n','1',669161,2946),(126936,18,2,'e','1',669161,2848),(126937,18,3,'s','1',669161,2878),(126938,19,0,'n','1',669161,2732),(126939,19,1,'e','1',669161,2852),(126940,19,2,'n','1',669161,2749),(126941,19,3,'s','1',669161,2765),(126942,20,0,'n','1',669161,2795),(126943,20,1,'w','1',669161,2749),(126944,20,2,'n','1',669161,2796),(126945,20,3,'n','1',669161,2798),(126946,21,0,'n','1',669161,2852),(126947,21,1,'n','1',669161,2912),(126948,2,0,'n','1',669162,2867),(126949,2,1,'n','1',669162,2816),(126950,2,2,'n','1',669162,2732),(126951,2,3,'n','1',669162,2749),(126952,3,0,'n','1',669162,2963),(126953,3,1,'n','1',669162,2717),(126954,3,2,'n','1',669162,2815),(126955,3,3,'n','1',669162,2882),(126956,4,0,'n','1',669162,2818),(126957,4,1,'e','1',669162,2719),(126958,4,2,'n','1',669162,2721),(126959,4,3,'n','1',669162,2888),(126960,5,0,'e','1',669162,2968),(126961,5,1,'s','1',669162,2855),(126962,5,2,'n','1',669162,2877),(126963,5,3,'n','1',669162,2878),(126964,6,0,'n','1',669162,2739),(126965,6,1,'n','1',669162,2775),(126966,6,2,'n','1',669162,2851),(126967,6,3,'n','1',669162,2792),(126968,7,0,'s','1',669162,2862),(126969,7,1,'w','1',669162,2880),(126970,7,2,'w','1',669162,2860),(126971,7,3,'w','1',669162,2765),(126972,8,0,'s','1',669162,2801),(126973,8,1,'s','1',669162,2767),(126974,8,2,'e','1',669162,2793),(126975,8,3,'s','1',669162,2859),(126976,9,0,'s','1',669162,2792),(126977,9,1,'s','1',669162,2851),(126978,9,2,'w','1',669162,2754),(126979,9,3,'w','1',669162,2725),(126980,10,0,'n','1',669162,2887),(126981,10,1,'w','1',669162,2845),(126982,10,2,'s','1',669162,2840),(126983,10,3,'n','1',669162,2927),(126984,11,0,'s','1',669162,2768),(126985,11,1,'s','1',669162,2851),(126986,11,2,'s','1',669162,3035),(126987,11,3,'s','1',669162,2941),(126988,12,0,'n','1',669162,2750),(126989,12,1,'s','1',669162,2909),(126990,12,2,'s','1',669162,2831),(126991,12,3,'n','1',669162,2915),(126992,13,0,'s','1',669162,2768),(126993,13,1,'e','1',669162,2750),(126994,13,2,'e','1',669162,2749),(126995,13,3,'e','1',669162,2734),(126996,14,0,'s','1',669162,2738),(126997,14,1,'w','1',669162,2875),(126998,14,2,'x','0',669162,2883),(126999,14,3,'s','1',669162,2842),(127000,14,4,'n','1',669162,2813),(127001,15,0,'e','1',669162,2829),(127002,15,1,'x','0',669162,2778),(127003,15,2,'e','1',669162,2939),(127004,15,3,'n','1',669162,2842),(127005,15,4,'w','1',669162,2754),(127006,16,0,'w','1',669162,2738),(127007,16,1,'s','1',669162,2806),(127008,16,2,'s','1',669162,2759),(127009,16,3,'e','1',669162,2734),(127010,17,0,'w','1',669162,2905),(127011,17,1,'s','1',669162,2803),(127012,17,2,'s','1',669162,2792),(127013,17,3,'s','1',669162,2851),(127014,18,0,'e','1',669162,2719),(127015,18,1,'s','1',669162,2775),(127016,18,2,'w','1',669162,2725),(127017,18,3,'w','1',669162,2738),(127018,19,0,'n','1',669162,2736),(127019,19,1,'e','1',669162,2762),(127020,19,2,'w','1',669162,2734),(127021,19,3,'w','1',669162,2759),(127022,20,0,'e','1',669162,2749),(127023,20,1,'w','1',669162,2719),(127024,20,2,'e','1',669162,2939),(127025,20,3,'s','1',669162,2781),(127026,21,0,'s','1',669162,2734),(127027,21,1,'w','1',669162,2759),(127028,21,2,'s','1',669162,2746),(127029,21,3,'e','1',669162,2986),(127030,22,0,'n','1',669162,2733),(127031,22,1,'n','1',669162,2760),(127032,22,2,'e','1',669162,2740),(127033,22,3,'n','1',669162,2739),(127034,23,0,'n','1',669162,2887),(127035,23,1,'w','1',669162,2845),(127036,23,2,'w','1',669162,2734),(127037,23,3,'w','1',669162,2759),(127038,24,0,'e','1',669162,2749),(127039,24,1,'w','1',669162,2734),(127040,24,2,'s','1',669162,2799),(127041,24,3,'n','1',669162,2737),(127042,25,0,'w','1',669162,2950),(127043,25,1,'w','1',669162,2858),(127044,25,2,'s','1',669162,2800),(127045,25,3,'w','1',669162,2759),(127046,26,0,'s','1',669162,2802),(127047,26,1,'x','0',669162,2803),(127048,26,2,'s','1',669162,2756),(127049,26,3,'n','1',669162,2950),(127050,26,4,'w','1',669162,2749),(127051,27,0,'s','1',669162,3035),(127052,27,1,'w','1',669162,2962),(127053,27,2,'w','1',669162,2790),(127054,27,3,'w','1',669162,2750),(127055,28,0,'w','1',669162,2946),(127056,28,1,'s','1',669162,2751),(127057,28,2,'s','1',669162,2730),(127058,28,3,'s','1',669162,2727),(127059,29,0,'e','1',669162,2829),(127060,29,1,'s','1',669162,2929),(127061,29,2,'s','1',669162,2909),(127062,29,3,'w','1',669162,2778),(127063,30,0,'s','1',669162,2909),(127064,30,1,'w','1',669162,2778),(127065,30,2,'e','1',669162,2740),(127066,30,3,'n','1',669162,2737),(127067,31,0,'s','1',669162,2909),(127068,31,1,'w','1',669162,2778),(127069,31,2,'n','1',669162,2834),(127070,31,3,'n','1',669162,2823),(127071,32,0,'s','1',669162,2909),(127072,32,1,'w','1',669162,2778),(127073,32,2,'n','1',669162,2973),(127074,32,3,'n','1',669162,2903),(127075,33,0,'s','1',669162,2909),(127076,33,1,'w','1',669162,2778),(127077,33,2,'n','1',669162,2824),(127078,33,3,'n','1',669162,2838),(127079,34,0,'s','1',669162,2909),(127080,34,1,'w','1',669162,2778),(127081,34,2,'e','1',669162,2759),(127082,34,3,'n','1',669162,2921),(127083,35,0,'s','1',669162,2909),(127084,35,1,'w','1',669162,2778),(127085,35,2,'n','1',669162,2805),(127086,35,3,'w','1',669162,2925),(127087,36,0,'s','1',669162,2909),(127088,36,1,'w','1',669162,2778),(127089,36,2,'w','1',669162,2826),(127090,36,3,'w','1',669162,2926),(127091,37,0,'s','1',669162,2909),(127092,37,1,'w','1',669162,2778),(127093,37,2,'n','1',669162,2803),(127094,37,3,'n','1',669162,2745),(127095,38,0,'s','1',669162,2909),(127096,38,1,'w','1',669162,2778),(127097,38,2,'e','1',669162,2729),(127098,38,3,'n','1',669162,2901),(127099,39,0,'s','1',669162,2909),(127100,39,1,'w','1',669162,2778),(127101,39,2,'n','1',669162,2839),(127102,39,3,'n','1',669162,2817),(127103,40,0,'s','1',669162,2887),(127104,40,1,'e','1',669162,2779),(127105,40,2,'n','1',669162,2822),(127106,40,3,'n','1',669162,2882),(127107,41,0,'n','1',669162,2775),(127108,41,1,'e','1',669162,2778),(127109,41,2,'e','1',669162,2829),(127110,41,3,'x','0',669162,2778),(127111,41,4,'n','1',669162,2887),(127112,42,0,'n','1',669162,2957),(127113,42,1,'n','1',669162,3036),(127114,42,2,'n','1',669162,2727),(127115,42,3,'n','1',669162,2995),(127116,42,4,'x','0',669162,2772),(127117,43,0,'e','1',669162,2836),(127118,43,1,'s','1',669162,2802),(127119,43,2,'n','1',669162,2730),(127120,43,3,'e','1',669162,2751),(127121,44,0,'n','1',669162,2750),(127122,44,1,'s','1',669162,2852),(127123,44,2,'e','1',669162,2768),(127124,44,3,'e','1',669162,2851),(127125,45,0,'n','1',669162,2821),(127126,45,1,'n','1',669162,2745),(127127,45,2,'n','1',669162,2985),(127128,45,3,'n','1',669162,2821),(127129,46,0,'w','1',669162,2808),(127130,46,1,'w','1',669162,2926),(127131,46,2,'e','1',669162,2836),(127132,46,3,'s','1',669162,2994),(127133,47,0,'s','1',669162,2787),(127134,47,1,'s','1',669162,2798),(127135,47,2,'s','1',669162,2786),(127136,47,3,'s','1',669162,2796),(127137,48,0,'n','1',669162,2777),(127138,48,1,'w','1',669162,2795),(127139,48,2,'n','1',669162,2915),(127140,48,3,'n','1',669162,2953),(127141,49,0,'s','1',669162,2758),(127142,49,1,'e','1',669162,2788),(127143,49,2,'s','1',669162,2761),(127144,49,3,'x','0',669162,2762),(127145,49,4,'s','1',669162,2800),(127146,50,0,'w','1',669162,2791),(127147,50,1,'w','1',669162,2777),(127148,50,2,'w','1',669162,2786),(127149,50,3,'n','1',669162,2927),(127150,51,0,'w','1',669162,2775),(127151,51,1,'w','1',669162,2784),(127152,51,2,'w','1',669162,2808),(127153,51,3,'w','1',669162,2926),(127154,52,0,'e','1',669162,2779),(127155,52,1,'n','1',669162,2780),(127156,52,2,'w','1',669162,2783),(127157,52,3,'n','1',669162,2790),(127158,53,0,'e','1',669162,2765),(127159,53,1,'s','1',669162,2998),(127160,53,2,'e','1',669162,2744),(127161,53,3,'e','1',669162,2935),(127162,53,4,'x','0',669162,2809),(127163,54,0,'s','1',669162,3006),(127164,54,1,'s','1',669162,2781),(127165,54,2,'e','1',669162,2780),(127166,54,3,'n','1',669162,2819),(127167,55,0,'e','1',669162,2829),(127168,55,1,'x','0',669162,2778),(127169,55,2,'e','1',669162,3006),(127170,55,3,'w','1',669162,2822),(127171,55,4,'n','1',669162,2779),(127172,56,0,'w','1',669162,2926),(127173,56,1,'n','1',669162,2741),(127174,56,2,'n','1',669162,2836),(127175,56,3,'w','1',669162,3004),(127176,57,0,'e','1',669162,3005),(127177,57,1,'w','1',669162,3004),(127178,57,2,'s','1',669162,3054),(127179,57,3,'n','1',669162,2780),(127180,58,0,'e','1',669162,2953),(127181,58,1,'n','1',669162,3039),(127182,58,2,'w','1',669162,3055),(127183,58,3,'n','1',669162,3005),(127184,59,0,'e','1',669162,2826),(127185,59,1,'e','1',669162,2936),(127186,59,2,'w','1',669162,2985),(127187,59,3,'w','1',669162,2928),(127188,60,0,'w','1',669162,2836),(127189,60,1,'n','1',669162,2802),(127190,60,2,'n','1',669162,2800),(127191,60,3,'n','1',669162,2799),(127192,61,0,'s','1',669162,2936),(127193,61,1,'s','1',669162,2970),(127194,61,2,'s','1',669162,2755),(127195,61,3,'w','1',669162,2746),(127196,62,0,'n','1',669162,2783),(127197,62,1,'n','1',669162,2848),(127198,62,2,'n','1',669162,2830),(127199,2,0,'n','1',669162,2867),(127200,2,1,'n','1',669162,2816),(127201,2,2,'n','1',669162,2732),(127202,2,3,'n','1',669162,2749),(127203,3,0,'n','1',669162,2963),(127204,3,1,'n','1',669162,2717),(127205,3,2,'n','1',669162,2815),(127206,3,3,'n','1',669162,2882),(127207,4,0,'n','1',669162,2818),(127208,4,1,'e','1',669162,2719),(127209,4,2,'n','1',669162,2721),(127210,4,3,'n','1',669162,2888),(127211,5,0,'e','1',669162,2968),(127212,5,1,'s','1',669162,2855),(127213,5,2,'n','1',669162,2877),(127214,5,3,'n','1',669162,2878),(127215,6,0,'n','1',669162,2739),(127216,6,1,'n','1',669162,2775),(127217,6,2,'n','1',669162,2851),(127218,6,3,'n','1',669162,2792),(127219,7,0,'s','1',669162,2862),(127220,7,1,'w','1',669162,2880),(127221,7,2,'w','1',669162,2860),(127222,7,3,'w','1',669162,2765),(127223,8,0,'s','1',669162,2801),(127224,8,1,'s','1',669162,2767),(127225,8,2,'e','1',669162,2793),(127226,8,3,'s','1',669162,2859),(127227,9,0,'s','1',669162,2792),(127228,9,1,'s','1',669162,2851),(127229,9,2,'w','1',669162,2754),(127230,9,3,'w','1',669162,2725),(127231,10,0,'n','1',669162,2887),(127232,10,1,'w','1',669162,2845),(127233,10,2,'s','1',669162,2840),(127234,10,3,'n','1',669162,2927),(127235,11,0,'s','1',669162,2768),(127236,11,1,'s','1',669162,2851),(127237,11,2,'s','1',669162,3035),(127238,11,3,'s','1',669162,2941),(127239,12,0,'n','1',669162,2750),(127240,12,1,'s','1',669162,2909),(127241,12,2,'s','1',669162,2831),(127242,12,3,'n','1',669162,2915),(127243,13,0,'s','1',669162,2768),(127244,13,1,'e','1',669162,2750),(127245,13,2,'e','1',669162,2749),(127246,13,3,'e','1',669162,2734),(127247,14,0,'s','1',669162,2738),(127248,14,1,'w','1',669162,2875),(127249,14,2,'x','0',669162,2883),(127250,14,3,'s','1',669162,2842),(127251,14,4,'n','1',669162,2813),(127252,15,0,'e','1',669162,2829),(127253,15,1,'x','0',669162,2778),(127254,15,2,'e','1',669162,2939),(127255,15,3,'n','1',669162,2842),(127256,15,4,'w','1',669162,2754),(127257,16,0,'w','1',669162,2738),(127258,16,1,'s','1',669162,2806),(127259,16,2,'s','1',669162,2759),(127260,16,3,'e','1',669162,2734),(127261,17,0,'w','1',669162,2905),(127262,17,1,'s','1',669162,2803),(127263,17,2,'s','1',669162,2792),(127264,17,3,'s','1',669162,2851),(127265,18,0,'e','1',669162,2719),(127266,18,1,'s','1',669162,2775),(127267,18,2,'w','1',669162,2725),(127268,18,3,'w','1',669162,2738),(127269,19,0,'n','1',669162,2736),(127270,19,1,'e','1',669162,2762),(127271,19,2,'w','1',669162,2734),(127272,19,3,'w','1',669162,2759),(127273,20,0,'e','1',669162,2749),(127274,20,1,'w','1',669162,2719),(127275,20,2,'e','1',669162,2939),(127276,20,3,'s','1',669162,2781),(127277,21,0,'s','1',669162,2734),(127278,21,1,'w','1',669162,2759),(127279,21,2,'s','1',669162,2746),(127280,21,3,'e','1',669162,2986),(127281,22,0,'n','1',669162,2733),(127282,22,1,'n','1',669162,2760),(127283,22,2,'e','1',669162,2740),(127284,22,3,'n','1',669162,2739),(127285,23,0,'n','1',669162,2887),(127286,23,1,'w','1',669162,2845),(127287,23,2,'w','1',669162,2734),(127288,23,3,'w','1',669162,2759),(127289,24,0,'e','1',669162,2749),(127290,24,1,'w','1',669162,2734),(127291,24,2,'s','1',669162,2799),(127292,24,3,'n','1',669162,2737),(127293,25,0,'w','1',669162,2950),(127294,25,1,'w','1',669162,2858),(127295,25,2,'s','1',669162,2800),(127296,25,3,'w','1',669162,2759),(127297,26,0,'s','1',669162,2802),(127298,26,1,'x','0',669162,2803),(127299,26,2,'s','1',669162,2756),(127300,26,3,'n','1',669162,2950),(127301,26,4,'w','1',669162,2749),(127302,27,0,'s','1',669162,3035),(127303,27,1,'w','1',669162,2962),(127304,27,2,'w','1',669162,2790),(127305,27,3,'w','1',669162,2750),(127306,28,0,'w','1',669162,2946),(127307,28,1,'s','1',669162,2751),(127308,28,2,'s','1',669162,2730),(127309,28,3,'s','1',669162,2727),(127310,29,0,'e','1',669162,2829),(127311,29,1,'s','1',669162,2929),(127312,29,2,'s','1',669162,2909),(127313,29,3,'w','1',669162,2778),(127314,30,0,'s','1',669162,2909),(127315,30,1,'w','1',669162,2778),(127316,30,2,'e','1',669162,2740),(127317,30,3,'n','1',669162,2737),(127318,31,0,'s','1',669162,2909),(127319,31,1,'w','1',669162,2778),(127320,31,2,'n','1',669162,2834),(127321,31,3,'n','1',669162,2823),(127322,32,0,'s','1',669162,2909),(127323,32,1,'w','1',669162,2778),(127324,32,2,'n','1',669162,2973),(127325,32,3,'n','1',669162,2903),(127326,33,0,'s','1',669162,2909),(127327,33,1,'w','1',669162,2778),(127328,33,2,'n','1',669162,2824),(127329,33,3,'n','1',669162,2838),(127330,34,0,'s','1',669162,2909),(127331,34,1,'w','1',669162,2778),(127332,34,2,'e','1',669162,2759),(127333,34,3,'n','1',669162,2921),(127334,35,0,'s','1',669162,2909),(127335,35,1,'w','1',669162,2778),(127336,35,2,'n','1',669162,2805),(127337,35,3,'w','1',669162,2925),(127338,36,0,'s','1',669162,2909),(127339,36,1,'w','1',669162,2778),(127340,36,2,'w','1',669162,2826),(127341,36,3,'w','1',669162,2926),(127342,37,0,'s','1',669162,2909),(127343,37,1,'w','1',669162,2778),(127344,37,2,'n','1',669162,2803),(127345,37,3,'n','1',669162,2745),(127346,38,0,'s','1',669162,2909),(127347,38,1,'w','1',669162,2778),(127348,38,2,'e','1',669162,2729),(127349,38,3,'n','1',669162,2901),(127350,39,0,'s','1',669162,2909),(127351,39,1,'w','1',669162,2778),(127352,39,2,'n','1',669162,2839),(127353,39,3,'n','1',669162,2817),(127354,40,0,'s','1',669162,2887),(127355,40,1,'e','1',669162,2779),(127356,40,2,'n','1',669162,2822),(127357,40,3,'n','1',669162,2882),(127358,41,0,'n','1',669162,2775),(127359,41,1,'e','1',669162,2778),(127360,41,2,'e','1',669162,2829),(127361,41,3,'x','0',669162,2778),(127362,41,4,'n','1',669162,2887),(127363,42,0,'n','1',669162,2957),(127364,42,1,'n','1',669162,3036),(127365,42,2,'n','1',669162,2727),(127366,42,3,'n','1',669162,2995),(127367,42,4,'x','0',669162,2772),(127368,43,0,'e','1',669162,2836),(127369,43,1,'s','1',669162,2802),(127370,43,2,'n','1',669162,2730),(127371,43,3,'e','1',669162,2751),(127372,44,0,'n','1',669162,2750),(127373,44,1,'s','1',669162,2852),(127374,44,2,'e','1',669162,2768),(127375,44,3,'e','1',669162,2851),(127376,45,0,'n','1',669162,2821),(127377,45,1,'n','1',669162,2745),(127378,45,2,'n','1',669162,2985),(127379,45,3,'n','1',669162,2821),(127380,46,0,'w','1',669162,2808),(127381,46,1,'w','1',669162,2926),(127382,46,2,'e','1',669162,2836),(127383,46,3,'s','1',669162,2994),(127384,47,0,'s','1',669162,2787),(127385,47,1,'s','1',669162,2798),(127386,47,2,'s','1',669162,2786),(127387,47,3,'s','1',669162,2796),(127388,48,0,'n','1',669162,2777),(127389,48,1,'w','1',669162,2795),(127390,48,2,'n','1',669162,2915),(127391,48,3,'n','1',669162,2953),(127392,49,0,'s','1',669162,2758),(127393,49,1,'e','1',669162,2788),(127394,49,2,'s','1',669162,2761),(127395,49,3,'x','0',669162,2762),(127396,49,4,'s','1',669162,2800),(127397,50,0,'w','1',669162,2791),(127398,50,1,'w','1',669162,2777),(127399,50,2,'w','1',669162,2786),(127400,50,3,'n','1',669162,2927),(127401,51,0,'w','1',669162,2775),(127402,51,1,'w','1',669162,2784),(127403,51,2,'w','1',669162,2808),(127404,51,3,'w','1',669162,2926),(127405,52,0,'e','1',669162,2779),(127406,52,1,'n','1',669162,2780),(127407,52,2,'w','1',669162,2783),(127408,52,3,'n','1',669162,2790),(127409,53,0,'e','1',669162,2765),(127410,53,1,'s','1',669162,2998),(127411,53,2,'e','1',669162,2744),(127412,53,3,'e','1',669162,2935),(127413,53,4,'x','0',669162,2809),(127414,54,0,'s','1',669162,3006),(127415,54,1,'s','1',669162,2781),(127416,54,2,'e','1',669162,2780),(127417,54,3,'n','1',669162,2819),(127418,55,0,'e','1',669162,2829),(127419,55,1,'x','0',669162,2778),(127420,55,2,'e','1',669162,3006),(127421,55,3,'w','1',669162,2822),(127422,55,4,'n','1',669162,2779),(127423,56,0,'w','1',669162,2926),(127424,56,1,'n','1',669162,2741),(127425,56,2,'n','1',669162,2836),(127426,56,3,'w','1',669162,3004),(127427,57,0,'e','1',669162,3005),(127428,57,1,'w','1',669162,3004),(127429,57,2,'s','1',669162,3054),(127430,57,3,'n','1',669162,2780),(127431,58,0,'e','1',669162,2953),(127432,58,1,'n','1',669162,3039),(127433,58,2,'w','1',669162,3055),(127434,58,3,'n','1',669162,3005),(127435,59,0,'e','1',669162,2826),(127436,59,1,'e','1',669162,2936),(127437,59,2,'w','1',669162,2985),(127438,59,3,'w','1',669162,2928),(127439,60,0,'w','1',669162,2836),(127440,60,1,'n','1',669162,2802),(127441,60,2,'n','1',669162,2800),(127442,60,3,'n','1',669162,2799),(127443,61,0,'s','1',669162,2936),(127444,61,1,'s','1',669162,2970),(127445,61,2,'s','1',669162,2755),(127446,61,3,'w','1',669162,2746),(127447,62,0,'n','1',669162,2783),(127448,62,1,'n','1',669162,2848),(127449,62,2,'n','1',669162,2830),(127450,2,0,'n','1',669163,2721),(127451,2,1,'n','1',669163,2810),(127452,2,2,'w','1',669163,2754),(127453,2,3,'n','1',669163,2811),(127454,3,0,'n','1',669163,2736),(127455,3,1,'n','1',669163,2737),(127456,3,2,'n','1',669163,2759),(127457,3,3,'w','1',669163,2812),(127458,4,0,'n','1',669163,2813),(127459,4,1,'n','1',669163,2842),(127460,4,2,'w','1',669163,2738),(127461,4,3,'n','1',669163,2817),(127462,5,0,'w','1',669163,2734),(127463,5,1,'n','1',669163,2749),(127464,5,2,'n','1',669163,2796),(127465,5,3,'e','1',669163,2798),(127466,6,0,'n','1',669163,2828),(127467,6,1,'n','1',669163,2870),(127468,6,2,'n','1',669163,2815),(127469,6,3,'n','1',669163,2927),(127470,7,0,'w','1',669163,2765),(127471,7,1,'s','1',669163,2863),(127472,7,2,'e','1',669163,2833),(127473,7,3,'e','1',669163,2768),(127474,8,0,'w','1',669163,2759),(127475,8,1,'e','1',669163,2756),(127476,8,2,'s','1',669163,2799),(127477,8,3,'s','1',669163,2765),(127478,9,0,'e','1',669163,2739),(127479,9,1,'n','1',669163,2915),(127480,9,2,'n','1',669163,2749),(127481,9,3,'n','1',669163,2956),(127482,10,0,'n','1',669163,2824),(127483,10,1,'e','1',669163,2759),(127484,10,2,'n','1',669163,2921),(127485,10,3,'n','1',669163,2958),(127486,11,0,'s','1',669163,2805),(127487,11,1,'s','1',669163,2921),(127488,11,2,'s','1',669163,2820),(127489,12,0,'w','1',669163,2798),(127490,12,1,'w','1',669163,2765),(127491,12,2,'w','1',669163,2774),(127492,12,3,'n','1',669163,2754),(127493,13,0,'e','1',669163,2818),(127494,13,1,'e','1',669163,2872),(127495,13,2,'n','1',669163,2772),(127496,13,3,'n','1',669163,2771),(127497,14,0,'e','1',669163,2879),(127498,14,1,'e','1',669163,2748),(127499,14,2,'s','1',669163,2787),(127500,14,3,'n','1',669163,2755),(127501,15,0,'n','1',669163,2822),(127502,15,1,'n','1',669163,2735),(127503,15,2,'n','1',669163,2954),(127504,15,3,'w','1',669163,2876),(127505,16,0,'s','1',669163,2768),(127506,16,1,'e','1',669163,2859),(127507,16,2,'e','1',669163,2750),(127508,16,3,'e','1',669163,2749),(127509,17,0,'w','1',669163,2854),(127510,17,1,'w','1',669163,2846),(127511,17,2,'s','1',669163,3020),(127512,17,3,'s','1',669163,2904),(127513,18,0,'n','1',669163,2820),(127514,18,1,'w','1',669163,2921),(127515,18,2,'e','1',669163,3035),(127516,18,3,'e','1',669163,2763),(127517,19,0,'w','1',669163,2734),(127518,19,1,'x','0',669163,2757),(127519,19,2,'w','1',669163,2749),(127520,19,3,'e','1',669163,2864),(127521,19,4,'n','1',669163,2764),(127522,20,0,'w','1',669163,2750),(127523,20,1,'w','1',669163,2751),(127524,20,2,'e','1',669163,2871),(127525,20,3,'s','1',669163,2769),(127526,21,0,'n','1',669163,2845),(127527,21,1,'w','1',669163,2900),(127528,21,2,'n','1',669163,2846),(127529,21,3,'n','1',669163,2829),(127530,22,0,'n','1',669163,2751),(127531,22,1,'s','1',669163,2881),(127532,22,2,'s','1',669163,2767),(127533,22,3,'x','0',669163,2859),(127534,22,4,'e','1',669163,2831),(127535,23,0,'n','1',669163,2975),(127536,23,1,'w','1',669163,2786),(127537,23,2,'n','1',669163,2775),(127538,23,3,'n','1',669163,2955),(127539,24,0,'n','1',669163,2751),(127540,24,1,'n','1',669163,2794),(127541,24,2,'w','1',669163,2881),(127542,24,3,'s','1',669163,2767),(127543,24,4,'x','0',669163,2859),(127544,25,0,'w','1',669163,2759),(127545,25,1,'e','1',669163,2857),(127546,25,2,'e','1',669163,2774),(127547,25,3,'e','1',669163,2987),(127548,26,0,'n','1',669163,2977),(127549,26,1,'s','1',669163,2853),(127550,26,2,'x','0',669163,2910),(127551,26,3,'e','1',669163,2983),(127552,26,4,'e','1',669163,2851),(127553,27,0,'n','1',669163,2902),(127554,27,1,'n','1',669163,2778),(127555,27,2,'n','1',669163,2794),(127556,27,3,'e','1',669163,2857),(127557,28,0,'s','1',669163,2923),(127558,28,1,'w','1',669163,2893),(127559,28,2,'s','1',669163,2983),(127560,28,3,'s','1',669163,3056),(127561,29,0,'n','1',669163,2990),(127562,29,1,'w','1',669163,2774),(127563,29,2,'w','1',669163,2798),(127564,29,3,'n','1',669163,2787),(127565,30,0,'n','1',669163,2797),(127566,30,1,'n','1',669163,2789),(127567,30,2,'n','1',669163,2795),(127568,30,3,'n','1',669163,2779),(127569,31,0,'w','1',669163,2899),(127570,31,1,'n','1',669163,2977),(127571,31,2,'e','1',669163,2767),(127572,31,3,'e','1',669163,2983),(127573,32,0,'n','1',669163,2906),(127574,32,1,'w','1',669163,2907),(127575,32,2,'w','1',669163,2893),(127576,32,3,'n','1',669163,2859),(127577,2,0,'n','1',669163,2721),(127578,2,1,'n','1',669163,2810),(127579,2,2,'w','1',669163,2754),(127580,2,3,'n','1',669163,2811),(127581,3,0,'n','1',669163,2736),(127582,3,1,'n','1',669163,2737),(127583,3,2,'n','1',669163,2759),(127584,3,3,'w','1',669163,2812),(127585,4,0,'n','1',669163,2813),(127586,4,1,'n','1',669163,2842),(127587,4,2,'w','1',669163,2738),(127588,4,3,'n','1',669163,2817),(127589,5,0,'w','1',669163,2734),(127590,5,1,'n','1',669163,2749),(127591,5,2,'n','1',669163,2796),(127592,5,3,'e','1',669163,2798),(127593,6,0,'n','1',669163,2828),(127594,6,1,'n','1',669163,2870),(127595,6,2,'n','1',669163,2815),(127596,6,3,'n','1',669163,2927),(127597,7,0,'w','1',669163,2765),(127598,7,1,'s','1',669163,2863),(127599,7,2,'e','1',669163,2833),(127600,7,3,'e','1',669163,2768),(127601,8,0,'w','1',669163,2759),(127602,8,1,'e','1',669163,2756),(127603,8,2,'s','1',669163,2799),(127604,8,3,'s','1',669163,2765),(127605,9,0,'e','1',669163,2739),(127606,9,1,'n','1',669163,2915),(127607,9,2,'n','1',669163,2749),(127608,9,3,'n','1',669163,2956),(127609,10,0,'n','1',669163,2824),(127610,10,1,'e','1',669163,2759),(127611,10,2,'n','1',669163,2921),(127612,10,3,'n','1',669163,2958),(127613,11,0,'s','1',669163,2805),(127614,11,1,'s','1',669163,2921),(127615,11,2,'s','1',669163,2820),(127616,12,0,'w','1',669163,2798),(127617,12,1,'w','1',669163,2765),(127618,12,2,'w','1',669163,2774),(127619,12,3,'n','1',669163,2754),(127620,13,0,'e','1',669163,2818),(127621,13,1,'e','1',669163,2872),(127622,13,2,'n','1',669163,2772),(127623,13,3,'n','1',669163,2771),(127624,14,0,'e','1',669163,2879),(127625,14,1,'e','1',669163,2748),(127626,14,2,'s','1',669163,2787),(127627,14,3,'n','1',669163,2755),(127628,15,0,'n','1',669163,2822),(127629,15,1,'n','1',669163,2735),(127630,15,2,'n','1',669163,2954),(127631,15,3,'w','1',669163,2876),(127632,16,0,'s','1',669163,2768),(127633,16,1,'e','1',669163,2859),(127634,16,2,'e','1',669163,2750),(127635,16,3,'e','1',669163,2749),(127636,17,0,'w','1',669163,2854),(127637,17,1,'w','1',669163,2846),(127638,17,2,'s','1',669163,3020),(127639,17,3,'s','1',669163,2904),(127640,18,0,'n','1',669163,2820),(127641,18,1,'w','1',669163,2921),(127642,18,2,'e','1',669163,3035),(127643,18,3,'e','1',669163,2763),(127644,19,0,'w','1',669163,2734),(127645,19,1,'x','0',669163,2757),(127646,19,2,'w','1',669163,2749),(127647,19,3,'e','1',669163,2864),(127648,19,4,'n','1',669163,2764),(127649,20,0,'w','1',669163,2750),(127650,20,1,'w','1',669163,2751),(127651,20,2,'e','1',669163,2871),(127652,20,3,'s','1',669163,2769),(127653,21,0,'n','1',669163,2845),(127654,21,1,'w','1',669163,2900),(127655,21,2,'n','1',669163,2846),(127656,21,3,'n','1',669163,2829),(127657,22,0,'n','1',669163,2751),(127658,22,1,'s','1',669163,2881),(127659,22,2,'s','1',669163,2767),(127660,22,3,'x','0',669163,2859),(127661,22,4,'e','1',669163,2831),(127662,23,0,'n','1',669163,2975),(127663,23,1,'w','1',669163,2786),(127664,23,2,'n','1',669163,2775),(127665,23,3,'n','1',669163,2955),(127666,24,0,'n','1',669163,2751),(127667,24,1,'n','1',669163,2794),(127668,24,2,'w','1',669163,2881),(127669,24,3,'s','1',669163,2767),(127670,24,4,'x','0',669163,2859),(127671,25,0,'w','1',669163,2759),(127672,25,1,'e','1',669163,2857),(127673,25,2,'e','1',669163,2774),(127674,25,3,'e','1',669163,2987),(127675,26,0,'n','1',669163,2977),(127676,26,1,'s','1',669163,2853),(127677,26,2,'x','0',669163,2910),(127678,26,3,'e','1',669163,2983),(127679,26,4,'e','1',669163,2851),(127680,27,0,'n','1',669163,2902),(127681,27,1,'n','1',669163,2778),(127682,27,2,'n','1',669163,2794),(127683,27,3,'e','1',669163,2857),(127684,28,0,'s','1',669163,2923),(127685,28,1,'w','1',669163,2893),(127686,28,2,'s','1',669163,2983),(127687,28,3,'s','1',669163,3056),(127688,29,0,'n','1',669163,2990),(127689,29,1,'w','1',669163,2774),(127690,29,2,'w','1',669163,2798),(127691,29,3,'n','1',669163,2787),(127692,30,0,'n','1',669163,2797),(127693,30,1,'n','1',669163,2789),(127694,30,2,'n','1',669163,2795),(127695,30,3,'n','1',669163,2779),(127696,31,0,'w','1',669163,2899),(127697,31,1,'n','1',669163,2977),(127698,31,2,'e','1',669163,2767),(127699,31,3,'e','1',669163,2983),(127700,32,0,'n','1',669163,2906),(127701,32,1,'w','1',669163,2907),(127702,32,2,'w','1',669163,2893),(127703,32,3,'n','1',669163,2859),(127704,2,0,'n','1',669164,2721),(127705,2,1,'e','1',669164,2817),(127706,2,2,'n','1',669164,2991),(127707,2,3,'n','1',669164,2992),(127708,3,0,'n','1',669164,2813),(127709,3,1,'w','1',669164,2842),(127710,3,2,'n','1',669164,2733),(127711,3,3,'w','1',669164,2754),(127712,4,0,'n','1',669164,2717),(127713,4,1,'w','1',669164,2734),(127714,4,2,'n','1',669164,2749),(127715,4,3,'n','1',669164,2779),(127716,5,0,'n','1',669164,2736),(127717,5,1,'n','1',669164,2737),(127718,5,2,'n','1',669164,2759),(127719,5,3,'n','1',669164,3022),(127720,6,0,'n','1',669164,2719),(127721,6,1,'n','1',669164,2845),(127722,6,2,'n','1',669164,2846),(127723,6,3,'n','1',669164,2774),(127724,7,0,'s','1',669164,2765),(127725,7,1,'e','1',669164,2860),(127726,7,2,'e','1',669164,2833),(127727,7,3,'n','1',669164,2749),(127728,8,0,'n','1',669164,2860),(127729,8,1,'w','1',669164,2765),(127730,8,2,'n','1',669164,2806),(127731,8,3,'w','1',669164,2774),(127732,9,0,'e','1',669164,2769),(127733,9,1,'w','1',669164,2766),(127734,9,2,'s','1',669164,2767),(127735,9,3,'x','0',669164,2859),(127736,9,4,'w','1',669164,2972),(127737,10,0,'n','1',669164,2882),(127738,10,1,'n','1',669164,2887),(127739,10,2,'n','1',669164,2956),(127740,10,3,'n','1',669164,2780),(127741,11,0,'w','1',669164,2794),(127742,11,1,'e','1',669164,2833),(127743,11,2,'e','1',669164,2768),(127744,11,3,'n','1',669164,2765),(127745,12,0,'s','1',669164,2833),(127746,12,1,'s','1',669164,2988),(127747,12,2,'w','1',669164,2765),(127748,12,3,'n','1',669164,2986),(127749,13,0,'e','1',669164,2852),(127750,13,1,'e','1',669164,2768),(127751,13,2,'w','1',669164,2765),(127752,13,3,'n','1',669164,2790),(127753,14,0,'e','1',669164,2852),(127754,14,1,'e','1',669164,2768),(127755,14,2,'w','1',669164,2765),(127756,14,3,'e','1',669164,2723),(127757,15,0,'e','1',669164,2852),(127758,15,1,'e','1',669164,2768),(127759,15,2,'w','1',669164,2765),(127760,15,3,'n','1',669164,2791),(127761,16,0,'e','1',669164,2852),(127762,16,1,'e','1',669164,2768),(127763,16,2,'w','1',669164,2765),(127764,16,3,'n','1',669164,2724),(127765,17,0,'e','1',669164,2852),(127766,17,1,'e','1',669164,2768),(127767,17,2,'w','1',669164,2765),(127768,18,0,'e','1',669164,2852),(127769,18,1,'e','1',669164,2768),(127770,18,2,'w','1',669164,2746),(127771,18,3,'w','1',669164,2765),(127772,19,0,'w','1',669164,2770),(127773,19,1,'n','1',669164,2771),(127774,19,2,'e','1',669164,2852),(127775,19,3,'e','1',669164,2768),(127776,20,0,'s','1',669164,2860),(127777,20,1,'w','1',669164,2765),(127778,20,2,'e','1',669164,2768),(127779,20,3,'e','1',669164,2859),(127780,21,0,'n','1',669164,2765),(127781,21,1,'w','1',669164,2988),(127782,21,2,'e','1',669164,2911),(127783,21,3,'s','1',669164,2890),(127784,22,0,'e','1',669164,2909),(127785,22,1,'n','1',669164,2794),(127786,22,2,'n','1',669164,2950),(127787,22,3,'n','1',669164,2902),(127788,23,0,'e','1',669164,3019),(127789,23,1,'n','1',669164,2768),(127790,23,2,'s','1',669164,2890),(127791,23,3,'e','1',669164,2753),(127792,24,0,'e','1',669164,2946),(127793,24,1,'e','1',669164,2906),(127794,24,2,'s','1',669164,2856),(127795,24,3,'s','1',669164,2798),(127796,25,0,'w','1',669164,2778),(127797,25,1,'w','1',669164,2969),(127798,25,2,'w','1',669164,2753),(127799,25,3,'n','1',669164,2819),(127800,26,0,'s','1',669164,3006),(127801,26,1,'s','1',669164,2781),(127802,26,2,'s','1',669164,2958),(127803,26,3,'n','1',669164,2858),(127804,27,0,'n','1',669164,2834),(127805,27,1,'w','1',669164,2823),(127806,27,2,'w','1',669164,2824),(127807,27,3,'n','1',669164,2762),(127808,28,0,'n','1',669164,2956),(127809,28,1,'n','1',669164,2958),(127810,28,2,'e','1',669164,2903),(127811,28,3,'e','1',669164,2901),(127812,29,0,'e','1',669164,3019),(127813,29,1,'n','1',669164,2768),(127814,29,2,'s','1',669164,2890),(127815,29,3,'w','1',669164,2789),(127816,30,0,'e','1',669164,2861),(127817,30,1,'e','1',669164,2777),(127818,30,2,'n','1',669164,2791),(127819,30,3,'n','1',669164,2841),(127820,31,0,'e','1',669164,2795),(127821,31,1,'e','1',669164,2777),(127822,31,2,'w','1',669164,2949),(127823,31,3,'n','1',669164,2955),(127824,32,0,'s','1',669164,2990),(127825,32,1,'s','1',669164,2776),(127826,32,2,'w','1',669164,2777),(127827,32,3,'x','0',669164,2778),(127828,32,4,'n','1',669164,2955),(127829,33,0,'e','1',669164,2795),(127830,33,1,'e','1',669164,2990),(127831,33,2,'n','1',669164,2780),(127832,33,3,'n','1',669164,2819),(127833,34,0,'e','1',669164,2829),(127834,34,1,'e','1',669164,2794),(127835,34,2,'w','1',669164,2778),(127836,34,3,'e','1',669164,2776),(127837,35,0,'e','1',669164,2762),(127838,35,1,'n','1',669164,2796),(127839,35,2,'e','1',669164,2798),(127840,35,3,'e','1',669164,2960),(127841,36,0,'n','1',669164,2888),(127842,36,1,'n','1',669164,2834),(127843,36,2,'w','1',669164,2824),(127844,36,3,'w','1',669164,2823),(127845,37,0,'e','1',669164,2824),(127846,37,1,'e','1',669164,2762),(127847,37,2,'n','1',669164,2823),(127848,38,0,'w','1',669164,2745),(127849,38,1,'s','1',669164,2861),(127850,38,2,'e','1',669164,2902),(127851,38,3,'s','1',669164,2949),(127852,2,0,'n','1',669164,2721),(127853,2,1,'e','1',669164,2817),(127854,2,2,'n','1',669164,2991),(127855,2,3,'n','1',669164,2992),(127856,3,0,'n','1',669164,2813),(127857,3,1,'w','1',669164,2842),(127858,3,2,'n','1',669164,2733),(127859,3,3,'w','1',669164,2754),(127860,4,0,'n','1',669164,2717),(127861,4,1,'w','1',669164,2734),(127862,4,2,'n','1',669164,2749),(127863,4,3,'n','1',669164,2779),(127864,5,0,'n','1',669164,2736),(127865,5,1,'n','1',669164,2737),(127866,5,2,'n','1',669164,2759),(127867,5,3,'n','1',669164,3022),(127868,6,0,'n','1',669164,2719),(127869,6,1,'n','1',669164,2845),(127870,6,2,'n','1',669164,2846),(127871,6,3,'n','1',669164,2774),(127872,7,0,'s','1',669164,2765),(127873,7,1,'e','1',669164,2860),(127874,7,2,'e','1',669164,2833),(127875,7,3,'n','1',669164,2749),(127876,8,0,'n','1',669164,2860),(127877,8,1,'w','1',669164,2765),(127878,8,2,'n','1',669164,2806),(127879,8,3,'w','1',669164,2774),(127880,9,0,'e','1',669164,2769),(127881,9,1,'w','1',669164,2766),(127882,9,2,'s','1',669164,2767),(127883,9,3,'x','0',669164,2859),(127884,9,4,'w','1',669164,2972),(127885,10,0,'n','1',669164,2882),(127886,10,1,'n','1',669164,2887),(127887,10,2,'n','1',669164,2956),(127888,10,3,'n','1',669164,2780),(127889,11,0,'w','1',669164,2794),(127890,11,1,'e','1',669164,2833),(127891,11,2,'e','1',669164,2768),(127892,11,3,'n','1',669164,2765),(127893,12,0,'s','1',669164,2833),(127894,12,1,'s','1',669164,2988),(127895,12,2,'w','1',669164,2765),(127896,12,3,'n','1',669164,2986),(127897,13,0,'e','1',669164,2852),(127898,13,1,'e','1',669164,2768),(127899,13,2,'w','1',669164,2765),(127900,13,3,'n','1',669164,2790),(127901,14,0,'e','1',669164,2852),(127902,14,1,'e','1',669164,2768),(127903,14,2,'w','1',669164,2765),(127904,14,3,'e','1',669164,2723),(127905,15,0,'e','1',669164,2852),(127906,15,1,'e','1',669164,2768),(127907,15,2,'w','1',669164,2765),(127908,15,3,'n','1',669164,2791),(127909,16,0,'e','1',669164,2852),(127910,16,1,'e','1',669164,2768),(127911,16,2,'w','1',669164,2765),(127912,16,3,'n','1',669164,2724),(127913,17,0,'e','1',669164,2852),(127914,17,1,'e','1',669164,2768),(127915,17,2,'w','1',669164,2765),(127916,18,0,'e','1',669164,2852),(127917,18,1,'e','1',669164,2768),(127918,18,2,'w','1',669164,2746),(127919,18,3,'w','1',669164,2765),(127920,19,0,'w','1',669164,2770),(127921,19,1,'n','1',669164,2771),(127922,19,2,'e','1',669164,2852),(127923,19,3,'e','1',669164,2768),(127924,20,0,'s','1',669164,2860),(127925,20,1,'w','1',669164,2765),(127926,20,2,'e','1',669164,2768),(127927,20,3,'e','1',669164,2859),(127928,21,0,'n','1',669164,2765),(127929,21,1,'w','1',669164,2988),(127930,21,2,'e','1',669164,2911),(127931,21,3,'s','1',669164,2890),(127932,22,0,'e','1',669164,2909),(127933,22,1,'n','1',669164,2794),(127934,22,2,'n','1',669164,2950),(127935,22,3,'n','1',669164,2902),(127936,23,0,'e','1',669164,3019),(127937,23,1,'n','1',669164,2768),(127938,23,2,'s','1',669164,2890),(127939,23,3,'e','1',669164,2753),(127940,24,0,'e','1',669164,2946),(127941,24,1,'e','1',669164,2906),(127942,24,2,'s','1',669164,2856),(127943,24,3,'s','1',669164,2798),(127944,25,0,'w','1',669164,2778),(127945,25,1,'w','1',669164,2969),(127946,25,2,'w','1',669164,2753),(127947,25,3,'n','1',669164,2819),(127948,26,0,'s','1',669164,3006),(127949,26,1,'s','1',669164,2781),(127950,26,2,'s','1',669164,2958),(127951,26,3,'n','1',669164,2858),(127952,27,0,'n','1',669164,2834),(127953,27,1,'w','1',669164,2823),(127954,27,2,'w','1',669164,2824),(127955,27,3,'n','1',669164,2762),(127956,28,0,'n','1',669164,2956),(127957,28,1,'n','1',669164,2958),(127958,28,2,'e','1',669164,2903),(127959,28,3,'e','1',669164,2901),(127960,29,0,'e','1',669164,3019),(127961,29,1,'n','1',669164,2768),(127962,29,2,'s','1',669164,2890),(127963,29,3,'w','1',669164,2789),(127964,30,0,'e','1',669164,2861),(127965,30,1,'e','1',669164,2777),(127966,30,2,'n','1',669164,2791),(127967,30,3,'n','1',669164,2841),(127968,31,0,'e','1',669164,2795),(127969,31,1,'e','1',669164,2777),(127970,31,2,'w','1',669164,2949),(127971,31,3,'n','1',669164,2955),(127972,32,0,'s','1',669164,2990),(127973,32,1,'s','1',669164,2776),(127974,32,2,'w','1',669164,2777),(127975,32,3,'x','0',669164,2778),(127976,32,4,'n','1',669164,2955),(127977,33,0,'e','1',669164,2795),(127978,33,1,'e','1',669164,2990),(127979,33,2,'n','1',669164,2780),(127980,33,3,'n','1',669164,2819),(127981,34,0,'e','1',669164,2829),(127982,34,1,'e','1',669164,2794),(127983,34,2,'w','1',669164,2778),(127984,34,3,'e','1',669164,2776),(127985,35,0,'e','1',669164,2762),(127986,35,1,'n','1',669164,2796),(127987,35,2,'e','1',669164,2798),(127988,35,3,'e','1',669164,2960),(127989,36,0,'n','1',669164,2888),(127990,36,1,'n','1',669164,2834),(127991,36,2,'w','1',669164,2824),(127992,36,3,'w','1',669164,2823),(127993,37,0,'e','1',669164,2824),(127994,37,1,'e','1',669164,2762),(127995,37,2,'n','1',669164,2823),(127996,38,0,'w','1',669164,2745),(127997,38,1,'s','1',669164,2861),(127998,38,2,'e','1',669164,2902),(127999,38,3,'s','1',669164,2949),(128000,2,0,'n','1',669165,2913),(128001,2,1,'n','1',669165,2874),(128002,2,2,'n','1',669165,2731),(128003,2,3,'n','1',669165,2750),(128004,3,0,'n','1',669165,2717),(128005,3,1,'n','1',669165,2719),(128006,3,2,'n','1',669165,2845),(128007,3,3,'n','1',669165,2846),(128008,4,0,'e','1',669165,2769),(128009,4,1,'s','1',669165,2766),(128010,4,2,'s','1',669165,2767),(128011,4,3,'x','0',669165,2859),(128012,4,4,'e','1',669165,2854),(128013,5,0,'e','1',669165,2876),(128014,5,1,'s','1',669165,2747),(128015,5,2,'e','1',669165,2948),(128016,5,3,'e','1',669165,2850),(128017,6,0,'e','1',669165,2768),(128018,6,1,'n','1',669165,2765),(128019,6,2,'s','1',669165,2988),(128020,6,3,'w','1',669165,2826),(128021,6,4,'x','0',669165,2807),(128022,7,0,'s','1',669165,2765),(128023,7,1,'s','1',669165,2749),(128024,7,2,'n','1',669165,2761),(128025,7,3,'e','1',669165,2732),(128026,8,0,'w','1',669165,2736),(128027,8,1,'s','1',669165,2849),(128028,8,2,'n','1',669165,2721),(128029,8,3,'n','1',669165,2870),(128030,9,0,'w','1',669165,2733),(128031,9,1,'w','1',669165,2732),(128032,9,2,'s','1',669165,2731),(128033,9,3,'w','1',669165,2874),(128034,10,0,'s','1',669165,2719),(128035,10,1,'w','1',669165,2727),(128036,10,2,'n','1',669165,2903),(128037,10,3,'n','1',669165,2875),(128038,11,0,'w','1',669165,2761),(128039,11,1,'w','1',669165,2849),(128040,11,2,'e','1',669165,2762),(128041,11,3,'n','1',669165,2754),(128042,12,0,'s','1',669165,2850),(128043,12,1,'n','1',669165,2815),(128044,12,2,'w','1',669165,2820),(128045,12,3,'n','1',669165,2888),(128046,13,0,'n','1',669165,2818),(128047,13,1,'n','1',669165,2834),(128048,13,2,'n','1',669165,2823),(128049,13,3,'w','1',669165,2775),(128050,14,0,'n','1',669165,2737),(128051,14,1,'n','1',669165,2759),(128052,14,2,'n','1',669165,2924),(128053,14,3,'n','1',669165,2806),(128054,15,0,'s','1',669165,2887),(128055,15,1,'s','1',669165,2826),(128056,15,2,'w','1',669165,2926),(128057,15,3,'n','1',669165,2968),(128058,16,0,'e','1',669165,2784),(128059,16,1,'s','1',669165,2794),(128060,16,2,'w','1',669165,2797),(128061,16,3,'s','1',669165,2981),(128062,17,0,'e','1',669165,2968),(128063,17,1,'w','1',669165,2726),(128064,17,2,'e','1',669165,3033),(128065,17,3,'n','1',669165,3042),(128066,18,0,'n','1',669165,2882),(128067,18,1,'n','1',669165,2902),(128068,18,2,'e','1',669165,2887),(128069,18,3,'n','1',669165,2786),(128070,19,0,'n','1',669165,2726),(128071,19,1,'e','1',669165,2878),(128072,19,2,'s','1',669165,2879),(128073,19,3,'w','1',669165,2858),(128074,20,0,'e','1',669165,2771),(128075,20,1,'e','1',669165,2873),(128076,20,2,'n','1',669165,2770),(128077,20,3,'e','1',669165,2748),(128078,21,0,'e','1',669165,2755),(128079,21,1,'e','1',669165,2756),(128080,21,2,'n','1',669165,2883),(128081,21,3,'n','1',669165,2850),(128082,22,0,'s','1',669165,2836),(128083,22,1,'n','1',669165,2837),(128084,22,2,'e','1',669165,2807),(128085,22,3,'n','1',669165,2745),(128086,23,0,'w','1',669165,2832),(128087,23,1,'s','1',669165,2757),(128088,23,2,'s','1',669165,2758),(128089,23,3,'e','1',669165,2747),(128090,24,0,'s','1',669165,2759),(128091,24,1,'s','1',669165,2761),(128092,24,2,'x','0',669165,2762),(128093,24,3,'w','1',669165,2737),(128094,24,4,'s','1',669165,2806),(128095,25,0,'s','1',669165,2915),(128096,25,1,'w','1',669165,2763),(128097,25,2,'w','1',669165,2790),(128098,25,3,'w','1',669165,2963),(128099,26,0,'s','1',669165,2740),(128100,26,1,'s','1',669165,2786),(128101,26,2,'s','1',669165,2832),(128102,26,3,'e','1',669165,2850),(128103,27,0,'w','1',669165,2822),(128104,27,1,'n','1',669165,2882),(128105,27,2,'w','1',669165,2829),(128106,27,3,'n','1',669165,2887),(128107,28,0,'n','1',669165,2821),(128108,28,1,'e','1',669165,2759),(128109,28,2,'w','1',669165,2902),(128110,28,3,'s','1',669165,2950),(128111,29,0,'e','1',669165,2759),(128112,29,1,'n','1',669165,2849),(128113,29,2,'w','1',669165,2804),(128114,29,3,'n','1',669165,2760),(128115,30,0,'w','1',669165,2763),(128116,30,1,'n','1',669165,2779),(128117,30,2,'w','1',669165,2822),(128118,30,3,'n','1',669165,2882),(128119,31,0,'n','1',669165,2780),(128120,31,1,'w','1',669165,2829),(128121,31,2,'n','1',669165,2887),(128122,31,3,'s','1',669165,2730),(128123,32,0,'s','1',669165,2995),(128124,32,1,'s','1',669165,2727),(128125,32,2,'n','1',669165,2791),(128126,32,3,'n','1',669165,2915),(128127,33,0,'n','1',669165,2957),(128128,33,1,'s','1',669165,2727),(128129,33,2,'s','1',669165,2946),(128130,33,3,'x','0',669165,2950),(128131,33,4,'s','1',669165,2921),(128132,34,0,'s','1',669165,2909),(128133,34,1,'w','1',669165,2778),(128134,34,2,'n','1',669165,2957),(128135,34,3,'n','1',669165,2727),(128136,35,0,'n','1',669165,2820),(128137,35,1,'s','1',669165,2759),(128138,35,2,'s','1',669165,2921),(128139,35,3,'w','1',669165,2737),(128140,36,0,'w','1',669165,2740),(128141,36,1,'w','1',669165,2746),(128142,36,2,'n','1',669165,2829),(128143,36,3,'n','1',669165,2887),(128144,37,0,'w','1',669165,2829),(128145,37,1,'n','1',669165,2887),(128146,37,2,'w','1',669165,2820),(128147,37,3,'n','1',669165,2781),(128148,38,0,'w','1',669165,2870),(128149,38,1,'n','1',669165,3016),(128150,38,2,'e','1',669165,2779),(128151,38,3,'n','1',669165,2927),(128152,39,0,'w','1',669165,2901),(128153,39,1,'w','1',669165,2903),(128154,39,2,'w','1',669165,2797),(128155,39,3,'s','1',669165,2770),(128156,40,0,'n','1',669165,2986),(128157,40,1,'w','1',669165,2746),(128158,40,2,'n','1',669165,3016),(128159,40,3,'w','1',669165,2790),(128160,41,0,'n','1',669165,2986),(128161,41,1,'w','1',669165,2746),(128162,42,0,'n','1',669165,2857),(128163,42,1,'n','1',669165,2730),(128164,42,2,'e','1',669165,2751),(128165,42,3,'w','1',669165,2770),(128166,43,0,'w','1',669165,2879),(128167,43,1,'e','1',669165,2752),(128168,43,2,'n','1',669165,2750),(128169,43,3,'w','1',669165,2803),(128170,44,0,'w','1',669165,2831),(128171,44,1,'s','1',669165,2878),(128172,44,2,'s','1',669165,2877),(128173,44,3,'s','1',669165,2739),(128174,45,0,'n','1',669165,2786),(128175,45,1,'w','1',669165,2787),(128176,45,2,'w','1',669165,2851),(128177,45,3,'e','1',669165,2781),(128178,46,0,'w','1',669165,2829),(128179,46,1,'w','1',669165,2772),(128180,46,2,'w','1',669165,2737),(128181,46,3,'n','1',669165,2824),(128182,47,0,'e','1',669165,2851),(128183,47,1,'s','1',669165,2787),(128184,47,2,'e','1',669165,2768),(128185,47,3,'e','1',669165,2729),(128186,48,0,'s','1',669165,2765),(128187,48,1,'e','1',669165,2877),(128188,48,2,'w','1',669165,2990),(128189,48,3,'w','1',669165,2786),(128190,49,0,'w','1',669165,2858),(128191,49,1,'n','1',669165,2962),(128192,49,2,'w','1',669165,2745),(128193,49,3,'w','1',669165,2740),(128194,50,0,'e','1',669165,2771),(128195,50,1,'s','1',669165,2746),(128196,50,2,'s','1',669165,2749),(128197,50,3,'e','1',669165,2732),(128198,51,0,'e','1',669165,2729),(128199,51,1,'s','1',669165,2950),(128200,51,2,'w','1',669165,2775),(128201,51,3,'s','1',669165,2770),(128202,52,0,'w','1',669165,2908),(128203,52,1,'w','1',669165,2785),(128204,52,2,'n','1',669165,2733),(128205,52,3,'n','1',669165,2838),(128206,53,0,'e','1',669165,2848),(128207,53,1,'e','1',669165,2734),(128208,53,2,'e','1',669165,2743),(128209,53,3,'n','1',669165,2738),(128210,54,0,'w','1',669165,2785),(128211,54,1,'w','1',669165,2763),(128212,54,2,'e','1',669165,2986),(128213,54,3,'n','1',669165,2760),(128214,55,0,'e','1',669165,2771),(128215,55,1,'s','1',669165,2770),(128216,55,2,'n','1',669165,2740),(128217,55,3,'n','1',669165,2756),(128218,56,0,'n','1',669165,2839),(128219,56,1,'w','1',669165,2953),(128220,56,2,'w','1',669165,2897),(128221,56,3,'s','1',669165,2770),(128222,57,0,'e','1',669165,2829),(128223,57,1,'e','1',669165,2908),(128224,57,2,'e','1',669165,2856),(128225,57,3,'w','1',669165,2778),(128226,58,0,'n','1',669165,2826),(128227,58,1,'n','1',669165,2807),(128228,58,2,'e','1',669165,2822),(128229,58,3,'n','1',669165,2882),(128230,59,0,'w','1',669165,2986),(128231,59,1,'s','1',669165,2741),(128232,59,2,'n','1',669165,2738),(128233,59,3,'w','1',669165,2928),(128234,60,0,'e','1',669165,2741),(128235,60,1,'n','1',669165,2889),(128236,60,2,'w','1',669165,2825),(128237,60,3,'x','0',669165,2809),(128238,60,4,'w','1',669165,3012),(128239,61,0,'e','1',669165,2870),(128240,61,1,'n','1',669165,2963),(128241,61,2,'n','1',669165,2915),(128242,61,3,'n','1',669165,2786),(128243,62,0,'s','1',669165,2908),(128244,62,1,'e','1',669165,2965),(128245,62,2,'e','1',669165,3022),(128246,62,3,'n','1',669165,2745),(128247,63,0,'e','1',669165,2941),(128248,63,1,'e','1',669165,2840),(128249,63,2,'n','1',669165,2792),(128250,63,3,'n','1',669165,2858),(128251,64,0,'e','1',669165,2902),(128252,64,1,'e','1',669165,2791),(128253,64,2,'e','1',669165,2887),(128254,64,3,'e','1',669165,2966),(128255,65,0,'n','1',669165,2789),(128256,65,1,'e','1',669165,2955),(128257,65,2,'s','1',669165,2949),(128258,65,3,'w','1',669165,2905),(128259,2,0,'n','1',669165,2913),(128260,2,1,'n','1',669165,2874),(128261,2,2,'n','1',669165,2731),(128262,2,3,'n','1',669165,2750),(128263,3,0,'n','1',669165,2717),(128264,3,1,'n','1',669165,2719),(128265,3,2,'n','1',669165,2845),(128266,3,3,'n','1',669165,2846),(128267,4,0,'e','1',669165,2769),(128268,4,1,'s','1',669165,2766),(128269,4,2,'s','1',669165,2767),(128270,4,3,'x','0',669165,2859),(128271,4,4,'e','1',669165,2854),(128272,5,0,'e','1',669165,2876),(128273,5,1,'s','1',669165,2747),(128274,5,2,'e','1',669165,2948),(128275,5,3,'e','1',669165,2850),(128276,6,0,'e','1',669165,2768),(128277,6,1,'n','1',669165,2765),(128278,6,2,'s','1',669165,2988),(128279,6,3,'w','1',669165,2826),(128280,6,4,'x','0',669165,2807),(128281,7,0,'s','1',669165,2765),(128282,7,1,'s','1',669165,2749),(128283,7,2,'n','1',669165,2761),(128284,7,3,'e','1',669165,2732),(128285,8,0,'w','1',669165,2736),(128286,8,1,'s','1',669165,2849),(128287,8,2,'n','1',669165,2721),(128288,8,3,'n','1',669165,2870),(128289,9,0,'w','1',669165,2733),(128290,9,1,'w','1',669165,2732),(128291,9,2,'s','1',669165,2731),(128292,9,3,'w','1',669165,2874),(128293,10,0,'s','1',669165,2719),(128294,10,1,'w','1',669165,2727),(128295,10,2,'n','1',669165,2903),(128296,10,3,'n','1',669165,2875),(128297,11,0,'w','1',669165,2761),(128298,11,1,'w','1',669165,2849),(128299,11,2,'e','1',669165,2762),(128300,11,3,'n','1',669165,2754),(128301,12,0,'s','1',669165,2850),(128302,12,1,'n','1',669165,2815),(128303,12,2,'w','1',669165,2820),(128304,12,3,'n','1',669165,2888),(128305,13,0,'n','1',669165,2818),(128306,13,1,'n','1',669165,2834),(128307,13,2,'n','1',669165,2823),(128308,13,3,'w','1',669165,2775),(128309,14,0,'n','1',669165,2737),(128310,14,1,'n','1',669165,2759),(128311,14,2,'n','1',669165,2924),(128312,14,3,'n','1',669165,2806),(128313,15,0,'s','1',669165,2887),(128314,15,1,'s','1',669165,2826),(128315,15,2,'w','1',669165,2926),(128316,15,3,'n','1',669165,2968),(128317,16,0,'e','1',669165,2784),(128318,16,1,'s','1',669165,2794),(128319,16,2,'w','1',669165,2797),(128320,16,3,'s','1',669165,2981),(128321,17,0,'e','1',669165,2968),(128322,17,1,'w','1',669165,2726),(128323,17,2,'e','1',669165,3033),(128324,17,3,'n','1',669165,3042),(128325,18,0,'n','1',669165,2882),(128326,18,1,'n','1',669165,2902),(128327,18,2,'e','1',669165,2887),(128328,18,3,'n','1',669165,2786),(128329,19,0,'n','1',669165,2726),(128330,19,1,'e','1',669165,2878),(128331,19,2,'s','1',669165,2879),(128332,19,3,'w','1',669165,2858),(128333,20,0,'e','1',669165,2771),(128334,20,1,'e','1',669165,2873),(128335,20,2,'n','1',669165,2770),(128336,20,3,'e','1',669165,2748),(128337,21,0,'e','1',669165,2755),(128338,21,1,'e','1',669165,2756),(128339,21,2,'n','1',669165,2883),(128340,21,3,'n','1',669165,2850),(128341,22,0,'s','1',669165,2836),(128342,22,1,'n','1',669165,2837),(128343,22,2,'e','1',669165,2807),(128344,22,3,'n','1',669165,2745),(128345,23,0,'w','1',669165,2832),(128346,23,1,'s','1',669165,2757),(128347,23,2,'s','1',669165,2758),(128348,23,3,'e','1',669165,2747),(128349,24,0,'s','1',669165,2759),(128350,24,1,'s','1',669165,2761),(128351,24,2,'x','0',669165,2762),(128352,24,3,'w','1',669165,2737),(128353,24,4,'s','1',669165,2806),(128354,25,0,'s','1',669165,2915),(128355,25,1,'w','1',669165,2763),(128356,25,2,'w','1',669165,2790),(128357,25,3,'w','1',669165,2963),(128358,26,0,'s','1',669165,2740),(128359,26,1,'s','1',669165,2786),(128360,26,2,'s','1',669165,2832),(128361,26,3,'e','1',669165,2850),(128362,27,0,'w','1',669165,2822),(128363,27,1,'n','1',669165,2882),(128364,27,2,'w','1',669165,2829),(128365,27,3,'n','1',669165,2887),(128366,28,0,'n','1',669165,2821),(128367,28,1,'e','1',669165,2759),(128368,28,2,'w','1',669165,2902),(128369,28,3,'s','1',669165,2950),(128370,29,0,'e','1',669165,2759),(128371,29,1,'n','1',669165,2849),(128372,29,2,'w','1',669165,2804),(128373,29,3,'n','1',669165,2760),(128374,30,0,'w','1',669165,2763),(128375,30,1,'n','1',669165,2779),(128376,30,2,'w','1',669165,2822),(128377,30,3,'n','1',669165,2882),(128378,31,0,'n','1',669165,2780),(128379,31,1,'w','1',669165,2829),(128380,31,2,'n','1',669165,2887),(128381,31,3,'s','1',669165,2730),(128382,32,0,'s','1',669165,2995),(128383,32,1,'s','1',669165,2727),(128384,32,2,'n','1',669165,2791),(128385,32,3,'n','1',669165,2915),(128386,33,0,'n','1',669165,2957),(128387,33,1,'s','1',669165,2727),(128388,33,2,'s','1',669165,2946),(128389,33,3,'x','0',669165,2950),(128390,33,4,'s','1',669165,2921),(128391,34,0,'s','1',669165,2909),(128392,34,1,'w','1',669165,2778),(128393,34,2,'n','1',669165,2957),(128394,34,3,'n','1',669165,2727),(128395,35,0,'n','1',669165,2820),(128396,35,1,'s','1',669165,2759),(128397,35,2,'s','1',669165,2921),(128398,35,3,'w','1',669165,2737),(128399,36,0,'w','1',669165,2740),(128400,36,1,'w','1',669165,2746),(128401,36,2,'n','1',669165,2829),(128402,36,3,'n','1',669165,2887),(128403,37,0,'w','1',669165,2829),(128404,37,1,'n','1',669165,2887),(128405,37,2,'w','1',669165,2820),(128406,37,3,'n','1',669165,2781),(128407,38,0,'w','1',669165,2870),(128408,38,1,'n','1',669165,3016),(128409,38,2,'e','1',669165,2779),(128410,38,3,'n','1',669165,2927),(128411,39,0,'w','1',669165,2901),(128412,39,1,'w','1',669165,2903),(128413,39,2,'w','1',669165,2797),(128414,39,3,'s','1',669165,2770),(128415,40,0,'n','1',669165,2986),(128416,40,1,'w','1',669165,2746),(128417,40,2,'n','1',669165,3016),(128418,40,3,'w','1',669165,2790),(128419,41,0,'n','1',669165,2986),(128420,41,1,'w','1',669165,2746),(128421,42,0,'n','1',669165,2857),(128422,42,1,'n','1',669165,2730),(128423,42,2,'e','1',669165,2751),(128424,42,3,'w','1',669165,2770),(128425,43,0,'w','1',669165,2879),(128426,43,1,'e','1',669165,2752),(128427,43,2,'n','1',669165,2750),(128428,43,3,'w','1',669165,2803),(128429,44,0,'w','1',669165,2831),(128430,44,1,'s','1',669165,2878),(128431,44,2,'s','1',669165,2877),(128432,44,3,'s','1',669165,2739),(128433,45,0,'n','1',669165,2786),(128434,45,1,'w','1',669165,2787),(128435,45,2,'w','1',669165,2851),(128436,45,3,'e','1',669165,2781),(128437,46,0,'w','1',669165,2829),(128438,46,1,'w','1',669165,2772),(128439,46,2,'w','1',669165,2737),(128440,46,3,'n','1',669165,2824),(128441,47,0,'e','1',669165,2851),(128442,47,1,'s','1',669165,2787),(128443,47,2,'e','1',669165,2768),(128444,47,3,'e','1',669165,2729),(128445,48,0,'s','1',669165,2765),(128446,48,1,'e','1',669165,2877),(128447,48,2,'w','1',669165,2990),(128448,48,3,'w','1',669165,2786),(128449,49,0,'w','1',669165,2858),(128450,49,1,'n','1',669165,2962),(128451,49,2,'w','1',669165,2745),(128452,49,3,'w','1',669165,2740),(128453,50,0,'e','1',669165,2771),(128454,50,1,'s','1',669165,2746),(128455,50,2,'s','1',669165,2749),(128456,50,3,'e','1',669165,2732),(128457,51,0,'e','1',669165,2729),(128458,51,1,'s','1',669165,2950),(128459,51,2,'w','1',669165,2775),(128460,51,3,'s','1',669165,2770),(128461,52,0,'w','1',669165,2908),(128462,52,1,'w','1',669165,2785),(128463,52,2,'n','1',669165,2733),(128464,52,3,'n','1',669165,2838),(128465,53,0,'e','1',669165,2848),(128466,53,1,'e','1',669165,2734),(128467,53,2,'e','1',669165,2743),(128468,53,3,'n','1',669165,2738),(128469,54,0,'w','1',669165,2785),(128470,54,1,'w','1',669165,2763),(128471,54,2,'e','1',669165,2986),(128472,54,3,'n','1',669165,2760),(128473,55,0,'e','1',669165,2771),(128474,55,1,'s','1',669165,2770),(128475,55,2,'n','1',669165,2740),(128476,55,3,'n','1',669165,2756),(128477,56,0,'n','1',669165,2839),(128478,56,1,'w','1',669165,2953),(128479,56,2,'w','1',669165,2897),(128480,56,3,'s','1',669165,2770),(128481,57,0,'e','1',669165,2829),(128482,57,1,'e','1',669165,2908),(128483,57,2,'e','1',669165,2856),(128484,57,3,'w','1',669165,2778),(128485,58,0,'n','1',669165,2826),(128486,58,1,'n','1',669165,2807),(128487,58,2,'e','1',669165,2822),(128488,58,3,'n','1',669165,2882),(128489,59,0,'w','1',669165,2986),(128490,59,1,'s','1',669165,2741),(128491,59,2,'n','1',669165,2738),(128492,59,3,'w','1',669165,2928),(128493,60,0,'e','1',669165,2741),(128494,60,1,'n','1',669165,2889),(128495,60,2,'w','1',669165,2825),(128496,60,3,'x','0',669165,2809),(128497,60,4,'w','1',669165,3012),(128498,61,0,'e','1',669165,2870),(128499,61,1,'n','1',669165,2963),(128500,61,2,'n','1',669165,2915),(128501,61,3,'n','1',669165,2786),(128502,62,0,'s','1',669165,2908),(128503,62,1,'e','1',669165,2965),(128504,62,2,'e','1',669165,3022),(128505,62,3,'n','1',669165,2745),(128506,63,0,'e','1',669165,2941),(128507,63,1,'e','1',669165,2840),(128508,63,2,'n','1',669165,2792),(128509,63,3,'n','1',669165,2858),(128510,64,0,'e','1',669165,2902),(128511,64,1,'e','1',669165,2791),(128512,64,2,'e','1',669165,2887),(128513,64,3,'e','1',669165,2966),(128514,65,0,'n','1',669165,2789),(128515,65,1,'e','1',669165,2955),(128516,65,2,'s','1',669165,2949),(128517,65,3,'w','1',669165,2905),(128518,2,0,'n','1',669166,2913),(128519,2,1,'n','1',669166,2874),(128520,2,2,'n','1',669166,2731),(128521,2,3,'n','1',669166,2750),(128522,3,0,'n','1',669166,2717),(128523,3,1,'n','1',669166,2719),(128524,3,2,'n','1',669166,2845),(128525,3,3,'n','1',669166,2846),(128526,4,0,'e','1',669166,2769),(128527,4,1,'s','1',669166,2766),(128528,4,2,'s','1',669166,2767),(128529,4,3,'x','0',669166,2859),(128530,4,4,'e','1',669166,2854),(128531,5,0,'e','1',669166,2876),(128532,5,1,'s','1',669166,2747),(128533,5,2,'e','1',669166,2948),(128534,5,3,'e','1',669166,2850),(128535,6,0,'w','1',669166,2736),(128536,6,1,'x','0',669166,2760),(128537,6,2,'s','1',669166,2849),(128538,6,3,'s','1',669166,2768),(128539,6,4,'n','1',669166,2721),(128540,7,0,'w','1',669166,2750),(128541,7,1,'w','1',669166,2751),(128542,7,2,'e','1',669166,2871),(128543,7,3,'s','1',669166,2769),(128544,8,0,'w','1',669166,2751),(128545,8,1,'e','1',669166,2838),(128546,8,2,'s','1',669166,2875),(128547,8,3,'n','1',669166,2870),(128548,9,0,'e','1',669166,2871),(128549,9,1,'e','1',669166,2941),(128550,9,2,'e','1',669166,2751),(128551,9,3,'e','1',669166,2840),(128552,10,0,'w','1',669166,2754),(128553,10,1,'w','1',669166,2849),(128554,10,2,'s','1',669166,2850),(128555,10,3,'n','1',669166,2882),(128556,11,0,'n','1',669166,2915),(128557,11,1,'n','1',669166,2786),(128558,11,2,'s','1',669166,2850),(128559,11,3,'s','1',669166,2787),(128560,12,0,'n','1',669166,2786),(128561,12,1,'s','1',669166,2850),(128562,12,2,'s','1',669166,2787),(128563,12,3,'e','1',669166,2736),(128564,13,0,'n','1',669166,2786),(128565,13,1,'s','1',669166,2850),(128566,13,2,'s','1',669166,2787),(128567,13,3,'n','1',669166,2815),(128568,14,0,'e','1',669166,2818),(128569,14,1,'n','1',669166,2786),(128570,14,2,'s','1',669166,2850),(128571,14,3,'s','1',669166,2787),(128572,15,0,'n','1',669166,2786),(128573,15,1,'s','1',669166,2850),(128574,15,2,'s','1',669166,2787),(128575,15,3,'n','1',669166,2927),(128576,16,0,'n','1',669166,2786),(128577,16,1,'s','1',669166,2850),(128578,16,2,'s','1',669166,2787),(128579,16,3,'n','1',669166,2739),(128580,17,0,'n','1',669166,2750),(128581,17,1,'n','1',669166,2786),(128582,17,2,'s','1',669166,2850),(128583,17,3,'s','1',669166,2787),(128584,18,0,'n','1',669166,2786),(128585,18,1,'s','1',669166,2850),(128586,18,2,'s','1',669166,2787),(128587,18,3,'w','1',669166,2872),(128588,19,0,'n','1',669166,2786),(128589,19,1,'s','1',669166,2850),(128590,19,2,'s','1',669166,2787),(128591,19,3,'n','1',669166,2797),(128592,20,0,'n','1',669166,2786),(128593,20,1,'s','1',669166,2850),(128594,20,2,'s','1',669166,2787),(128595,20,3,'n','1',669166,2754),(128596,21,0,'n','1',669166,2786),(128597,21,1,'s','1',669166,2850),(128598,21,2,'s','1',669166,2787),(128599,21,3,'n','1',669166,3015),(128600,22,0,'n','1',669166,2786),(128601,22,1,'s','1',669166,2850),(128602,22,2,'s','1',669166,2787),(128603,22,3,'n','1',669166,2820),(128604,23,0,'s','1',669166,2768),(128605,23,1,'n','1',669166,2786),(128606,23,2,'s','1',669166,2850),(128607,23,3,'s','1',669166,2787),(128608,24,0,'e','1',669166,2786),(128609,24,1,'e','1',669166,2850),(128610,24,2,'s','1',669166,2849),(128611,24,3,'w','1',669166,2750),(128612,25,0,'s','1',669166,2751),(128613,25,1,'n','1',669166,2781),(128614,25,2,'n','1',669166,2818),(128615,25,3,'n','1',669166,2921),(128616,26,0,'n','1',669166,2875),(128617,26,1,'n','1',669166,2849),(128618,26,2,'s','1',669166,2804),(128619,26,3,'s','1',669166,2806),(128620,27,0,'s','1',669166,2849),(128621,27,1,'s','1',669166,2759),(128622,27,2,'w','1',669166,2803),(128623,27,3,'w','1',669166,2805),(128624,28,0,'n','1',669166,2924),(128625,28,1,'n','1',669166,2806),(128626,28,2,'s','1',669166,2875),(128627,28,3,'s','1',669166,2737),(128628,29,0,'n','1',669166,2888),(128629,29,1,'n','1',669166,2989),(128630,29,2,'e','1',669166,2736),(128631,29,3,'n','1',669166,2868),(128632,30,0,'w','1',669166,2826),(128633,30,1,'w','1',669166,2926),(128634,30,2,'e','1',669166,2851),(128635,30,3,'n','1',669166,2802),(128636,31,0,'w','1',669166,2788),(128637,31,1,'s','1',669166,2792),(128638,31,2,'n','1',669166,2901),(128639,31,3,'e','1',669166,2836),(128640,32,0,'n','1',669166,2875),(128641,32,1,'w','1',669166,2754),(128642,32,2,'w','1',669166,2736),(128643,32,3,'x','0',669166,2760),(128644,32,4,'s','1',669166,2849),(128645,33,0,'n','1',669166,2909),(128646,33,1,'s','1',669166,2730),(128647,33,2,'w','1',669166,2727),(128648,33,3,'w','1',669166,2726),(128649,34,0,'e','1',669166,3033),(128650,34,1,'n','1',669166,3042),(128651,34,2,'w','1',669166,2875),(128652,34,3,'n','1',669166,2817),(128653,35,0,'e','1',669166,2726),(128654,35,1,'e','1',669166,2939),(128655,35,2,'n','1',669166,2727),(128656,35,3,'e','1',669166,2719),(128657,35,4,'x','0',669166,2725),(128658,36,0,'e','1',669166,2851),(128659,36,1,'s','1',669166,2850),(128660,36,2,'n','1',669166,2730),(128661,36,3,'e','1',669166,2751),(128662,37,0,'e','1',669166,2750),(128663,37,1,'n','1',669166,2833),(128664,37,2,'n','1',669166,2749),(128665,37,3,'n','1',669166,2791),(128666,38,0,'e','1',669166,2777),(128667,38,1,'n','1',669166,2787),(128668,38,2,'e','1',669166,2832),(128669,38,3,'n','1',669166,2834),(128670,39,0,'n','1',669166,2824),(128671,39,1,'w','1',669166,2917),(128672,39,2,'n','1',669166,2825),(128673,39,3,'n','1',669166,2804),(128674,40,0,'e','1',669166,2837),(128675,40,1,'e','1',669166,2844),(128676,40,2,'e','1',669166,2941),(128677,40,3,'n','1',669166,2968),(128678,41,0,'s','1',669166,2929),(128679,41,1,'s','1',669166,2840),(128680,41,2,'e','1',669166,2981),(128681,41,3,'n','1',669166,2729),(128682,42,0,'n','1',669166,2825),(128683,42,1,'e','1',669166,2844),(128684,42,2,'w','1',669166,3039),(128685,42,3,'n','1',669166,2823),(128686,43,0,'n','1',669166,2825),(128687,43,1,'e','1',669166,2844),(128688,43,2,'w','1',669166,2822),(128689,43,3,'n','1',669166,2779),(128690,44,0,'e','1',669166,2878),(128691,44,1,'s','1',669166,2879),(128692,44,2,'s','1',669166,2771),(128693,44,3,'e','1',669166,2772),(128694,45,0,'s','1',669166,2788),(128695,45,1,'w','1',669166,2776),(128696,45,2,'w','1',669166,2787),(128697,45,3,'n','1',669166,2745),(128698,46,0,'n','1',669166,2825),(128699,46,1,'e','1',669166,2844),(128700,46,2,'s','1',669166,2794),(128701,46,3,'x','0',669166,2778),(128702,46,4,'w','1',669166,2851),(128703,47,0,'n','1',669166,2908),(128704,47,1,'n','1',669166,2739),(128705,47,2,'w','1',669166,2775),(128706,47,3,'x','0',669166,2784),(128707,47,4,'s','1',669166,2770),(128708,48,0,'n','1',669166,2785),(128709,48,1,'w','1',669166,2793),(128710,48,2,'n','1',669166,2931),(128711,48,3,'n','1',669166,2830),(128712,49,0,'n','1',669166,2908),(128713,49,1,'n','1',669166,2770),(128714,49,2,'s','1',669166,2857),(128715,49,3,'w','1',669166,2748),(128716,50,0,'e','1',669166,2909),(128717,50,1,'w','1',669166,2950),(128718,50,2,'s','1',669166,2794),(128719,50,3,'x','0',669166,2778),(128720,50,4,'w','1',669166,2843),(128721,51,0,'n','1',669166,2765),(128722,51,1,'s','1',669166,2988),(128723,51,2,'w','1',669166,2826),(128724,51,3,'x','0',669166,2757),(128725,51,4,'e','1',669166,2858),(128726,52,0,'e','1',669166,2765),(128727,52,1,'w','1',669166,2744),(128728,52,2,'s','1',669166,2826),(128729,52,3,'x','0',669166,2757),(128730,52,4,'w','1',669166,2821),(128731,53,0,'w','1',669166,2743),(128732,53,1,'e','1',669166,2844),(128733,53,2,'s','1',669166,2826),(128734,53,3,'x','0',669166,2757),(128735,53,4,'n','1',669166,2780),(128736,54,0,'n','1',669166,2795),(128737,54,1,'w','1',669166,2796),(128738,54,2,'n','1',669166,2776),(128739,54,3,'n','1',669166,2774),(128740,55,0,'n','1',669166,2781),(128741,55,1,'n','1',669166,2941),(128742,55,2,'n','1',669166,2942),(128743,55,3,'n','1',669166,2943),(128744,2,0,'n','1',669166,2913),(128745,2,1,'n','1',669166,2874),(128746,2,2,'n','1',669166,2731),(128747,2,3,'n','1',669166,2750),(128748,3,0,'n','1',669166,2717),(128749,3,1,'n','1',669166,2719),(128750,3,2,'n','1',669166,2845),(128751,3,3,'n','1',669166,2846),(128752,4,0,'e','1',669166,2769),(128753,4,1,'s','1',669166,2766),(128754,4,2,'s','1',669166,2767),(128755,4,3,'x','0',669166,2859),(128756,4,4,'e','1',669166,2854),(128757,5,0,'e','1',669166,2876),(128758,5,1,'s','1',669166,2747),(128759,5,2,'e','1',669166,2948),(128760,5,3,'e','1',669166,2850),(128761,6,0,'w','1',669166,2736),(128762,6,1,'x','0',669166,2760),(128763,6,2,'s','1',669166,2849),(128764,6,3,'s','1',669166,2768),(128765,6,4,'n','1',669166,2721),(128766,7,0,'w','1',669166,2750),(128767,7,1,'w','1',669166,2751),(128768,7,2,'e','1',669166,2871),(128769,7,3,'s','1',669166,2769),(128770,8,0,'w','1',669166,2751),(128771,8,1,'e','1',669166,2838),(128772,8,2,'s','1',669166,2875),(128773,8,3,'n','1',669166,2870),(128774,9,0,'e','1',669166,2871),(128775,9,1,'e','1',669166,2941),(128776,9,2,'e','1',669166,2751),(128777,9,3,'e','1',669166,2840),(128778,10,0,'w','1',669166,2754),(128779,10,1,'w','1',669166,2849),(128780,10,2,'s','1',669166,2850),(128781,10,3,'n','1',669166,2882),(128782,11,0,'n','1',669166,2915),(128783,11,1,'n','1',669166,2786),(128784,11,2,'s','1',669166,2850),(128785,11,3,'s','1',669166,2787),(128786,12,0,'n','1',669166,2786),(128787,12,1,'s','1',669166,2850),(128788,12,2,'s','1',669166,2787),(128789,12,3,'e','1',669166,2736),(128790,13,0,'n','1',669166,2786),(128791,13,1,'s','1',669166,2850),(128792,13,2,'s','1',669166,2787),(128793,13,3,'n','1',669166,2815),(128794,14,0,'e','1',669166,2818),(128795,14,1,'n','1',669166,2786),(128796,14,2,'s','1',669166,2850),(128797,14,3,'s','1',669166,2787),(128798,15,0,'n','1',669166,2786),(128799,15,1,'s','1',669166,2850),(128800,15,2,'s','1',669166,2787),(128801,15,3,'n','1',669166,2927),(128802,16,0,'n','1',669166,2786),(128803,16,1,'s','1',669166,2850),(128804,16,2,'s','1',669166,2787),(128805,16,3,'n','1',669166,2739),(128806,17,0,'n','1',669166,2750),(128807,17,1,'n','1',669166,2786),(128808,17,2,'s','1',669166,2850),(128809,17,3,'s','1',669166,2787),(128810,18,0,'n','1',669166,2786),(128811,18,1,'s','1',669166,2850),(128812,18,2,'s','1',669166,2787),(128813,18,3,'w','1',669166,2872),(128814,19,0,'n','1',669166,2786),(128815,19,1,'s','1',669166,2850),(128816,19,2,'s','1',669166,2787),(128817,19,3,'n','1',669166,2797),(128818,20,0,'n','1',669166,2786),(128819,20,1,'s','1',669166,2850),(128820,20,2,'s','1',669166,2787),(128821,20,3,'n','1',669166,2754),(128822,21,0,'n','1',669166,2786),(128823,21,1,'s','1',669166,2850),(128824,21,2,'s','1',669166,2787),(128825,21,3,'n','1',669166,3015),(128826,22,0,'n','1',669166,2786),(128827,22,1,'s','1',669166,2850),(128828,22,2,'s','1',669166,2787),(128829,22,3,'n','1',669166,2820),(128830,23,0,'s','1',669166,2768),(128831,23,1,'n','1',669166,2786),(128832,23,2,'s','1',669166,2850),(128833,23,3,'s','1',669166,2787),(128834,24,0,'e','1',669166,2786),(128835,24,1,'e','1',669166,2850),(128836,24,2,'s','1',669166,2849),(128837,24,3,'w','1',669166,2750),(128838,25,0,'s','1',669166,2751),(128839,25,1,'n','1',669166,2781),(128840,25,2,'n','1',669166,2818),(128841,25,3,'n','1',669166,2921),(128842,26,0,'n','1',669166,2875),(128843,26,1,'n','1',669166,2849),(128844,26,2,'s','1',669166,2804),(128845,26,3,'s','1',669166,2806),(128846,27,0,'s','1',669166,2849),(128847,27,1,'s','1',669166,2759),(128848,27,2,'w','1',669166,2803),(128849,27,3,'w','1',669166,2805),(128850,28,0,'n','1',669166,2924),(128851,28,1,'n','1',669166,2806),(128852,28,2,'s','1',669166,2875),(128853,28,3,'s','1',669166,2737),(128854,29,0,'n','1',669166,2888),(128855,29,1,'n','1',669166,2989),(128856,29,2,'e','1',669166,2736),(128857,29,3,'n','1',669166,2868),(128858,30,0,'w','1',669166,2826),(128859,30,1,'w','1',669166,2926),(128860,30,2,'e','1',669166,2851),(128861,30,3,'n','1',669166,2802),(128862,31,0,'w','1',669166,2788),(128863,31,1,'s','1',669166,2792),(128864,31,2,'n','1',669166,2901),(128865,31,3,'e','1',669166,2836),(128866,32,0,'n','1',669166,2875),(128867,32,1,'w','1',669166,2754),(128868,32,2,'w','1',669166,2736),(128869,32,3,'x','0',669166,2760),(128870,32,4,'s','1',669166,2849),(128871,33,0,'n','1',669166,2909),(128872,33,1,'s','1',669166,2730),(128873,33,2,'w','1',669166,2727),(128874,33,3,'w','1',669166,2726),(128875,34,0,'e','1',669166,3033),(128876,34,1,'n','1',669166,3042),(128877,34,2,'w','1',669166,2875),(128878,34,3,'n','1',669166,2817),(128879,35,0,'e','1',669166,2726),(128880,35,1,'e','1',669166,2939),(128881,35,2,'n','1',669166,2727),(128882,35,3,'e','1',669166,2719),(128883,35,4,'x','0',669166,2725),(128884,36,0,'e','1',669166,2851),(128885,36,1,'s','1',669166,2850),(128886,36,2,'n','1',669166,2730),(128887,36,3,'e','1',669166,2751),(128888,37,0,'e','1',669166,2750),(128889,37,1,'n','1',669166,2833),(128890,37,2,'n','1',669166,2749),(128891,37,3,'n','1',669166,2791),(128892,38,0,'e','1',669166,2777),(128893,38,1,'n','1',669166,2787),(128894,38,2,'e','1',669166,2832),(128895,38,3,'n','1',669166,2834),(128896,39,0,'n','1',669166,2824),(128897,39,1,'w','1',669166,2917),(128898,39,2,'n','1',669166,2825),(128899,39,3,'n','1',669166,2804),(128900,40,0,'e','1',669166,2837),(128901,40,1,'e','1',669166,2844),(128902,40,2,'e','1',669166,2941),(128903,40,3,'n','1',669166,2968),(128904,41,0,'s','1',669166,2929),(128905,41,1,'s','1',669166,2840),(128906,41,2,'e','1',669166,2981),(128907,41,3,'n','1',669166,2729),(128908,42,0,'n','1',669166,2825),(128909,42,1,'e','1',669166,2844),(128910,42,2,'w','1',669166,3039),(128911,42,3,'n','1',669166,2823),(128912,43,0,'n','1',669166,2825),(128913,43,1,'e','1',669166,2844),(128914,43,2,'w','1',669166,2822),(128915,43,3,'n','1',669166,2779),(128916,44,0,'e','1',669166,2878),(128917,44,1,'s','1',669166,2879),(128918,44,2,'s','1',669166,2771),(128919,44,3,'e','1',669166,2772),(128920,45,0,'s','1',669166,2788),(128921,45,1,'w','1',669166,2776),(128922,45,2,'w','1',669166,2787),(128923,45,3,'n','1',669166,2745),(128924,46,0,'n','1',669166,2825),(128925,46,1,'e','1',669166,2844),(128926,46,2,'s','1',669166,2794),(128927,46,3,'x','0',669166,2778),(128928,46,4,'w','1',669166,2851),(128929,47,0,'n','1',669166,2908),(128930,47,1,'n','1',669166,2739),(128931,47,2,'w','1',669166,2775),(128932,47,3,'x','0',669166,2784),(128933,47,4,'s','1',669166,2770),(128934,48,0,'n','1',669166,2785),(128935,48,1,'w','1',669166,2793),(128936,48,2,'n','1',669166,2931),(128937,48,3,'n','1',669166,2830),(128938,49,0,'n','1',669166,2908),(128939,49,1,'n','1',669166,2770),(128940,49,2,'s','1',669166,2857),(128941,49,3,'w','1',669166,2748),(128942,50,0,'e','1',669166,2909),(128943,50,1,'w','1',669166,2950),(128944,50,2,'s','1',669166,2794),(128945,50,3,'x','0',669166,2778),(128946,50,4,'w','1',669166,2843),(128947,51,0,'n','1',669166,2765),(128948,51,1,'s','1',669166,2988),(128949,51,2,'w','1',669166,2826),(128950,51,3,'x','0',669166,2757),(128951,51,4,'e','1',669166,2858),(128952,52,0,'e','1',669166,2765),(128953,52,1,'w','1',669166,2744),(128954,52,2,'s','1',669166,2826),(128955,52,3,'x','0',669166,2757),(128956,52,4,'w','1',669166,2821),(128957,53,0,'w','1',669166,2743),(128958,53,1,'e','1',669166,2844),(128959,53,2,'s','1',669166,2826),(128960,53,3,'x','0',669166,2757),(128961,53,4,'n','1',669166,2780),(128962,54,0,'n','1',669166,2795),(128963,54,1,'w','1',669166,2796),(128964,54,2,'n','1',669166,2776),(128965,54,3,'n','1',669166,2774),(128966,55,0,'n','1',669166,2781),(128967,55,1,'n','1',669166,2941),(128968,55,2,'n','1',669166,2942),(128969,55,3,'n','1',669166,2943),(128970,2,0,'n','1',669167,2728),(128971,2,1,'n','1',669167,2991),(128972,2,2,'w','1',669167,2722),(128973,2,3,'n','1',669167,2717),(128974,3,0,'e','1',669167,2736),(128975,3,1,'n','1',669167,2992),(128976,3,2,'n','1',669167,2813),(128977,3,3,'n','1',669167,2842),(128978,4,0,'w','1',669167,2915),(128979,4,1,'e','1',669167,2777),(128980,4,2,'w','1',669167,2738),(128981,4,3,'w','1',669167,2734),(128982,5,0,'n','1',669167,2993),(128983,5,1,'n','1',669167,2728),(128984,5,2,'e','1',669167,2749),(128985,5,3,'e','1',669167,2734),(128986,6,0,'w','1',669167,2738),(128987,6,1,'w','1',669167,2798),(128988,6,2,'w','1',669167,2734),(128989,6,3,'e','1',669167,2971),(128990,7,0,'n','1',669167,2754),(128991,7,1,'w','1',669167,2749),(128992,7,2,'e','1',669167,2773),(128993,7,3,'e','1',669167,2750),(128994,8,0,'e','1',669167,2749),(128995,8,1,'e','1',669167,2734),(128996,8,2,'w','1',669167,2738),(128997,8,3,'s','1',669167,2806),(128998,9,0,'e','1',669167,2734),(128999,9,1,'n','1',669167,2956),(129000,9,2,'w','1',669167,2738),(129001,9,3,'w','1',669167,2921),(129002,10,0,'e','1',669167,2734),(129003,10,1,'n','1',669167,2738),(129004,10,2,'w','1',669167,2921),(129005,10,3,'n','1',669167,2739),(129006,11,0,'e','1',669167,2797),(129007,11,1,'w','1',669167,2820),(129008,11,2,'w','1',669167,2737),(129009,11,3,'w','1',669167,2740),(129010,12,0,'n','1',669167,2746),(129011,12,1,'s','1',669167,2755),(129012,12,2,'s','1',669167,2833),(129013,12,3,'e','1',669167,2790),(129014,13,0,'n','1',669167,2746),(129015,13,1,'s','1',669167,2755),(129016,13,2,'s','1',669167,2833),(129017,13,3,'n','1',669167,2779),(129018,14,0,'n','1',669167,2746),(129019,14,1,'s','1',669167,2755),(129020,14,2,'s','1',669167,2833),(129021,15,0,'n','1',669167,2746),(129022,15,1,'s','1',669167,2755),(129023,15,2,'s','1',669167,2852),(129024,15,3,'s','1',669167,2746),(129025,16,0,'e','1',669167,2741),(129026,16,1,'s','1',669167,2921),(129027,16,2,'s','1',669167,3012),(129028,16,3,'e','1',669167,2736),(129029,17,0,'s','1',669167,2843),(129030,17,1,'w','1',669167,3011),(129031,17,2,'e','1',669167,2986),(129032,17,3,'e','1',669167,2760),(129033,18,0,'w','1',669167,2738),(129034,18,1,'s','1',669167,2825),(129035,18,2,'w','1',669167,2734),(129036,18,3,'s','1',669167,2799),(129037,19,0,'n','1',669167,2749),(129038,19,1,'w','1',669167,2765),(129039,19,2,'w','1',669167,2844),(129040,19,3,'n','1',669167,2719),(129041,20,0,'s','1',669167,2845),(129042,20,1,'e','1',669167,2768),(129043,20,2,'w','1',669167,2765),(129044,20,3,'w','1',669167,2844),(129045,21,0,'n','1',669167,2719),(129046,21,1,'n','1',669167,2845),(129047,21,2,'w','1',669167,2900),(129048,21,3,'n','1',669167,2846),(129049,22,0,'w','1',669167,2736),(129050,22,1,'w','1',669167,2760),(129051,22,2,'s','1',669167,2761),(129052,22,3,'x','0',669167,2762),(129053,22,4,'w','1',669167,2754),(129054,23,0,'n','1',669167,2834),(129055,23,1,'n','1',669167,2775),(129056,23,2,'n','1',669167,2851),(129057,23,3,'w','1',669167,2792),(129058,24,0,'n','1',669167,2882),(129059,24,1,'n','1',669167,2887),(129060,24,2,'n','1',669167,2909),(129061,24,3,'e','1',669167,2830),(129062,25,0,'n','1',669167,2793),(129063,25,1,'n','1',669167,2801),(129064,25,2,'w','1',669167,2986),(129065,25,3,'n','1',669167,2780),(129066,26,0,'s','1',669167,2768),(129067,26,1,'w','1',669167,2750),(129068,26,2,'w','1',669167,2751),(129069,26,3,'n','1',669167,3009),(129070,27,0,'e','1',669167,2877),(129071,27,1,'s','1',669167,2871),(129072,27,2,'s','1',669167,2771),(129073,27,3,'x','0',669167,2772),(129074,27,4,'e','1',669167,2873),(129075,28,0,'n','1',669167,2730),(129076,28,1,'e','1',669167,2908),(129077,28,2,'n','1',669167,2909),(129078,28,3,'n','1',669167,2781),(129079,29,0,'e','1',669167,2751),(129080,29,1,'n','1',669167,2750),(129081,29,2,'n','1',669167,2929),(129082,29,3,'e','1',669167,3013),(129083,30,0,'n','1',669167,2956),(129084,30,1,'e','1',669167,2760),(129085,30,2,'e','1',669167,2930),(129086,30,3,'e','1',669167,2941),(129087,31,0,'n','1',669167,2903),(129088,31,1,'e','1',669167,2797),(129089,31,2,'w','1',669167,2840),(129090,31,3,'n','1',669167,2887),(129091,32,0,'e','1',669167,2902),(129092,32,1,'n','1',669167,2791),(129093,32,2,'n','1',669167,2777),(129094,32,3,'n','1',669167,2776),(129095,33,0,'e','1',669167,2789),(129096,33,1,'n','1',669167,2858),(129097,33,2,'e','1',669167,2768),(129098,33,3,'n','1',669167,2774),(129099,34,0,'s','1',669167,2765),(129100,34,1,'e','1',669167,2749),(129101,34,2,'e','1',669167,2825),(129102,34,3,'n','1',669167,2759),(129103,35,0,'s','1',669167,2804),(129104,35,1,'e','1',669167,2734),(129105,35,2,'e','1',669167,2774),(129106,35,3,'e','1',669167,2798),(129107,36,0,'w','1',669167,2849),(129108,36,1,'s','1',669167,2738),(129109,36,2,'w','1',669167,2850),(129110,36,3,'w','1',669167,2842),(129111,37,0,'w','1',669167,2986),(129112,37,1,'n','1',669167,2908),(129113,37,2,'w','1',669167,2762),(129114,37,3,'n','1',669167,2909),(129115,38,0,'n','1',669167,2733),(129116,38,1,'e','1',669167,2948),(129117,38,2,'s','1',669167,2850),(129118,38,3,'x','0',669167,2883),(129119,38,4,'s','1',669167,2734),(129120,39,0,'n','1',669167,2733),(129121,39,1,'s','1',669167,2759),(129122,39,2,'e','1',669167,2734),(129123,39,3,'e','1',669167,2770),(129124,40,0,'w','1',669167,2738),(129125,40,1,'w','1',669167,2746),(129126,40,2,'s','1',669167,2755),(129127,40,3,'w','1',669167,2734),(129128,41,0,'s','1',669167,2946),(129129,41,1,'w','1',669167,2950),(129130,41,2,'n','1',669167,2958),(129131,41,3,'s','1',669167,2770),(129132,42,0,'n','1',669167,2852),(129133,42,1,'n','1',669167,2749),(129134,42,2,'n','1',669167,2909),(129135,42,3,'n','1',669167,2929),(129136,43,0,'n','1',669167,2930),(129137,43,1,'s','1',669167,2806),(129138,43,2,'s','1',669167,2759),(129139,43,3,'e','1',669167,2800),(129140,44,0,'w','1',669167,2860),(129141,44,1,'w','1',669167,2765),(129142,44,2,'w','1',669167,2908),(129143,44,3,'w','1',669167,2772),(129144,45,0,'n','1',669167,2872),(129145,45,1,'n','1',669167,2877),(129146,45,2,'e','1',669167,2878),(129147,45,3,'s','1',669167,2886),(129148,46,0,'n','1',669167,2795),(129149,46,1,'n','1',669167,2796),(129150,46,2,'n','1',669167,2798),(129151,46,3,'n','1',669167,2852),(129152,2,0,'n','1',669167,2728),(129153,2,1,'n','1',669167,2991),(129154,2,2,'w','1',669167,2722),(129155,2,3,'n','1',669167,2717),(129156,3,0,'e','1',669167,2736),(129157,3,1,'n','1',669167,2992),(129158,3,2,'n','1',669167,2813),(129159,3,3,'n','1',669167,2842),(129160,4,0,'w','1',669167,2915),(129161,4,1,'e','1',669167,2777),(129162,4,2,'w','1',669167,2738),(129163,4,3,'w','1',669167,2734),(129164,5,0,'n','1',669167,2993),(129165,5,1,'n','1',669167,2728),(129166,5,2,'e','1',669167,2749),(129167,5,3,'e','1',669167,2734),(129168,6,0,'w','1',669167,2738),(129169,6,1,'w','1',669167,2798),(129170,6,2,'w','1',669167,2734),(129171,6,3,'e','1',669167,2971),(129172,7,0,'n','1',669167,2754),(129173,7,1,'w','1',669167,2749),(129174,7,2,'e','1',669167,2773),(129175,7,3,'e','1',669167,2750),(129176,8,0,'e','1',669167,2749),(129177,8,1,'e','1',669167,2734),(129178,8,2,'w','1',669167,2738),(129179,8,3,'s','1',669167,2806),(129180,9,0,'e','1',669167,2734),(129181,9,1,'n','1',669167,2956),(129182,9,2,'w','1',669167,2738),(129183,9,3,'w','1',669167,2921),(129184,10,0,'e','1',669167,2734),(129185,10,1,'n','1',669167,2738),(129186,10,2,'w','1',669167,2921),(129187,10,3,'n','1',669167,2739),(129188,11,0,'e','1',669167,2797),(129189,11,1,'w','1',669167,2820),(129190,11,2,'w','1',669167,2737),(129191,11,3,'w','1',669167,2740),(129192,12,0,'n','1',669167,2746),(129193,12,1,'s','1',669167,2755),(129194,12,2,'s','1',669167,2833),(129195,12,3,'e','1',669167,2790),(129196,13,0,'n','1',669167,2746),(129197,13,1,'s','1',669167,2755),(129198,13,2,'s','1',669167,2833),(129199,13,3,'n','1',669167,2779),(129200,14,0,'n','1',669167,2746),(129201,14,1,'s','1',669167,2755),(129202,14,2,'s','1',669167,2833),(129203,15,0,'n','1',669167,2746),(129204,15,1,'s','1',669167,2755),(129205,15,2,'s','1',669167,2852),(129206,15,3,'s','1',669167,2746),(129207,16,0,'e','1',669167,2741),(129208,16,1,'s','1',669167,2921),(129209,16,2,'s','1',669167,3012),(129210,16,3,'e','1',669167,2736),(129211,17,0,'s','1',669167,2843),(129212,17,1,'w','1',669167,3011),(129213,17,2,'e','1',669167,2986),(129214,17,3,'e','1',669167,2760),(129215,18,0,'w','1',669167,2738),(129216,18,1,'s','1',669167,2825),(129217,18,2,'w','1',669167,2734),(129218,18,3,'s','1',669167,2799),(129219,19,0,'n','1',669167,2749),(129220,19,1,'w','1',669167,2765),(129221,19,2,'w','1',669167,2844),(129222,19,3,'n','1',669167,2719),(129223,20,0,'s','1',669167,2845),(129224,20,1,'e','1',669167,2768),(129225,20,2,'w','1',669167,2765),(129226,20,3,'w','1',669167,2844),(129227,21,0,'n','1',669167,2719),(129228,21,1,'n','1',669167,2845),(129229,21,2,'w','1',669167,2900),(129230,21,3,'n','1',669167,2846),(129231,22,0,'w','1',669167,2736),(129232,22,1,'w','1',669167,2760),(129233,22,2,'s','1',669167,2761),(129234,22,3,'x','0',669167,2762),(129235,22,4,'w','1',669167,2754),(129236,23,0,'n','1',669167,2834),(129237,23,1,'n','1',669167,2775),(129238,23,2,'n','1',669167,2851),(129239,23,3,'w','1',669167,2792),(129240,24,0,'n','1',669167,2882),(129241,24,1,'n','1',669167,2887),(129242,24,2,'n','1',669167,2909),(129243,24,3,'e','1',669167,2830),(129244,25,0,'n','1',669167,2793),(129245,25,1,'n','1',669167,2801),(129246,25,2,'w','1',669167,2986),(129247,25,3,'n','1',669167,2780),(129248,26,0,'s','1',669167,2768),(129249,26,1,'w','1',669167,2750),(129250,26,2,'w','1',669167,2751),(129251,26,3,'n','1',669167,3009),(129252,27,0,'e','1',669167,2877),(129253,27,1,'s','1',669167,2871),(129254,27,2,'s','1',669167,2771),(129255,27,3,'x','0',669167,2772),(129256,27,4,'e','1',669167,2873),(129257,28,0,'n','1',669167,2730),(129258,28,1,'e','1',669167,2908),(129259,28,2,'n','1',669167,2909),(129260,28,3,'n','1',669167,2781),(129261,29,0,'e','1',669167,2751),(129262,29,1,'n','1',669167,2750),(129263,29,2,'n','1',669167,2929),(129264,29,3,'e','1',669167,3013),(129265,30,0,'n','1',669167,2956),(129266,30,1,'e','1',669167,2760),(129267,30,2,'e','1',669167,2930),(129268,30,3,'e','1',669167,2941),(129269,31,0,'n','1',669167,2903),(129270,31,1,'e','1',669167,2797),(129271,31,2,'w','1',669167,2840),(129272,31,3,'n','1',669167,2887),(129273,32,0,'e','1',669167,2902),(129274,32,1,'n','1',669167,2791),(129275,32,2,'n','1',669167,2777),(129276,32,3,'n','1',669167,2776),(129277,33,0,'e','1',669167,2789),(129278,33,1,'n','1',669167,2858),(129279,33,2,'e','1',669167,2768),(129280,33,3,'n','1',669167,2774),(129281,34,0,'s','1',669167,2765),(129282,34,1,'e','1',669167,2749),(129283,34,2,'e','1',669167,2825),(129284,34,3,'n','1',669167,2759),(129285,35,0,'s','1',669167,2804),(129286,35,1,'e','1',669167,2734),(129287,35,2,'e','1',669167,2774),(129288,35,3,'e','1',669167,2798),(129289,36,0,'w','1',669167,2849),(129290,36,1,'s','1',669167,2738),(129291,36,2,'w','1',669167,2850),(129292,36,3,'w','1',669167,2842),(129293,37,0,'w','1',669167,2986),(129294,37,1,'n','1',669167,2908),(129295,37,2,'w','1',669167,2762),(129296,37,3,'n','1',669167,2909),(129297,38,0,'n','1',669167,2733),(129298,38,1,'e','1',669167,2948),(129299,38,2,'s','1',669167,2850),(129300,38,3,'x','0',669167,2883),(129301,38,4,'s','1',669167,2734),(129302,39,0,'n','1',669167,2733),(129303,39,1,'s','1',669167,2759),(129304,39,2,'e','1',669167,2734),(129305,39,3,'e','1',669167,2770),(129306,40,0,'w','1',669167,2738),(129307,40,1,'w','1',669167,2746),(129308,40,2,'s','1',669167,2755),(129309,40,3,'w','1',669167,2734),(129310,41,0,'s','1',669167,2946),(129311,41,1,'w','1',669167,2950),(129312,41,2,'n','1',669167,2958),(129313,41,3,'s','1',669167,2770),(129314,42,0,'n','1',669167,2852),(129315,42,1,'n','1',669167,2749),(129316,42,2,'n','1',669167,2909),(129317,42,3,'n','1',669167,2929),(129318,43,0,'n','1',669167,2930),(129319,43,1,'s','1',669167,2806),(129320,43,2,'s','1',669167,2759),(129321,43,3,'e','1',669167,2800),(129322,44,0,'w','1',669167,2860),(129323,44,1,'w','1',669167,2765),(129324,44,2,'w','1',669167,2908),(129325,44,3,'w','1',669167,2772),(129326,45,0,'n','1',669167,2872),(129327,45,1,'n','1',669167,2877),(129328,45,2,'e','1',669167,2878),(129329,45,3,'s','1',669167,2886),(129330,46,0,'n','1',669167,2795),(129331,46,1,'n','1',669167,2796),(129332,46,2,'n','1',669167,2798),(129333,46,3,'n','1',669167,2852),(129334,2,0,'n','1',669168,2913),(129335,2,1,'n','1',669168,2874),(129336,2,2,'n','1',669168,2731),(129337,2,3,'n','1',669168,2750),(129338,3,0,'n','1',669168,2717),(129339,3,1,'n','1',669168,2719),(129340,3,2,'n','1',669168,2845),(129341,3,3,'n','1',669168,2846),(129342,4,0,'e','1',669168,2769),(129343,4,1,'s','1',669168,2766),(129344,4,2,'s','1',669168,2767),(129345,4,3,'x','0',669168,2859),(129346,4,4,'e','1',669168,2854),(129347,5,0,'e','1',669168,2876),(129348,5,1,'e','1',669168,2747),(129349,5,2,'s','1',669168,2832),(129350,5,3,'s','1',669168,2768),(129351,6,0,'w','1',669168,2750),(129352,6,1,'w','1',669168,2751),(129353,6,2,'e','1',669168,2769),(129354,6,3,'x','0',669168,2766),(129355,6,4,'n','1',669168,2871),(129356,7,0,'n','1',669168,2915),(129357,7,1,'s','1',669168,2977),(129358,7,2,'e','1',669168,2871),(129359,7,3,'e','1',669168,2751),(129360,8,0,'n','1',669168,2721),(129361,8,1,'n','1',669168,2888),(129362,8,2,'n','1',669168,2870),(129363,8,3,'n','1',669168,2739),(129364,9,0,'e','1',669168,2750),(129365,9,1,'w','1',669168,2787),(129366,9,2,'e','1',669168,2749),(129367,9,3,'s','1',669168,2734),(129368,10,0,'e','1',669168,2733),(129369,10,1,'w','1',669168,2842),(129370,10,2,'n','1',669168,2736),(129371,10,3,'w','1',669168,2754),(129372,11,0,'e','1',669168,2902),(129373,11,1,'n','1',669168,2858),(129374,11,2,'n','1',669168,2815),(129375,11,3,'e','1',669168,2818),(129376,12,0,'n','1',669168,2851),(129377,12,1,'n','1',669168,2792),(129378,12,2,'n','1',669168,2860),(129379,12,3,'n','1',669168,2882),(129380,13,0,'w','1',669168,2760),(129381,13,1,'e','1',669168,2733),(129382,13,2,'e','1',669168,2736),(129383,13,3,'s','1',669168,2842),(129384,14,0,'e','1',669168,2901),(129385,14,1,'n','1',669168,2986),(129386,14,2,'s','1',669168,2746),(129387,14,3,'w','1',669168,2761),(129388,15,0,'s','1',669168,2838),(129389,15,1,'s','1',669168,2813),(129390,15,2,'n','1',669168,2992),(129391,15,3,'e','1',669168,2996),(129392,16,0,'w','1',669168,2761),(129393,16,1,'n','1',669168,2760),(129394,16,2,'n','1',669168,2903),(129395,16,3,'n','1',669168,2775),(129396,17,0,'w','1',669168,2813),(129397,17,1,'e','1',669168,2814),(129398,17,2,'e','1',669168,2795),(129399,17,3,'x','0',669168,2762),(129400,17,4,'e','1',669168,2864),(129401,18,0,'w','1',669168,2760),(129402,18,1,'w','1',669168,2863),(129403,18,2,'w','1',669168,2767),(129404,18,3,'w','1',669168,2864),(129405,19,0,'n','1',669168,2760),(129406,19,1,'e','1',669168,2740),(129407,19,2,'w','1',669168,2792),(129408,19,3,'n','1',669168,2872),(129409,20,0,'w','1',669168,2840),(129410,20,1,'n','1',669168,2877),(129411,20,2,'n','1',669168,2886),(129412,20,3,'n','1',669168,2878),(129413,21,0,'s','1',669168,2900),(129414,21,1,'s','1',669168,2878),(129415,21,2,'s','1',669168,2877),(129416,21,3,'e','1',669168,2781),(129417,22,0,'n','1',669168,2793),(129418,22,1,'n','1',669168,2794),(129419,22,2,'w','1',669168,2801),(129420,22,3,'n','1',669168,2857),(129421,22,4,'x','0',669168,2859),(129422,23,0,'n','1',669168,2790),(129423,23,1,'n','1',669168,2791),(129424,23,2,'w','1',669168,2789),(129425,23,3,'n','1',669168,2927),(129426,24,0,'w','1',669168,2737),(129427,24,1,'w','1',669168,2740),(129428,24,2,'w','1',669168,2776),(129429,24,3,'n','1',669168,2779),(129430,25,0,'n','1',669168,2776),(129431,25,1,'n','1',669168,2774),(129432,25,2,'n','1',669168,2773),(129433,25,3,'n','1',669168,2872),(129434,26,0,'s','1',669168,2746),(129435,26,1,'w','1',669168,2986),(129436,26,2,'e','1',669168,2780),(129437,26,3,'w','1',669168,2887),(129438,27,0,'w','1',669168,2829),(129439,27,1,'s','1',669168,2877),(129440,27,2,'e','1',669168,2781),(129441,27,3,'s','1',669168,2872),(129442,28,0,'n','1',669168,2964),(129443,28,1,'w','1',669168,2969),(129444,28,2,'n','1',669168,2858),(129445,28,3,'n','1',669168,2780),(129446,29,0,'s','1',669168,3007),(129447,29,1,'s','1',669168,3057),(129448,29,2,'e','1',669168,2801),(129449,29,3,'s','1',669168,2853),(129450,29,4,'x','0',669168,2910),(129451,30,0,'e','1',669168,2860),(129452,30,1,'w','1',669168,2833),(129453,30,2,'s','1',669168,2912),(129454,30,3,'e','1',669168,2944),(129455,31,0,'e','1',669168,2860),(129456,31,1,'w','1',669168,2998),(129457,31,2,'n','1',669168,2833),(129458,31,3,'n','1',669168,2826),(129459,2,0,'n','1',669168,2913),(129460,2,1,'n','1',669168,2874),(129461,2,2,'n','1',669168,2731),(129462,2,3,'n','1',669168,2750),(129463,3,0,'n','1',669168,2717),(129464,3,1,'n','1',669168,2719),(129465,3,2,'n','1',669168,2845),(129466,3,3,'n','1',669168,2846),(129467,4,0,'e','1',669168,2769),(129468,4,1,'s','1',669168,2766),(129469,4,2,'s','1',669168,2767),(129470,4,3,'x','0',669168,2859),(129471,4,4,'e','1',669168,2854),(129472,5,0,'e','1',669168,2876),(129473,5,1,'e','1',669168,2747),(129474,5,2,'s','1',669168,2832),(129475,5,3,'s','1',669168,2768),(129476,6,0,'w','1',669168,2750),(129477,6,1,'w','1',669168,2751),(129478,6,2,'e','1',669168,2769),(129479,6,3,'x','0',669168,2766),(129480,6,4,'n','1',669168,2871),(129481,7,0,'n','1',669168,2915),(129482,7,1,'s','1',669168,2977),(129483,7,2,'e','1',669168,2871),(129484,7,3,'e','1',669168,2751),(129485,8,0,'n','1',669168,2721),(129486,8,1,'n','1',669168,2888),(129487,8,2,'n','1',669168,2870),(129488,8,3,'n','1',669168,2739),(129489,9,0,'e','1',669168,2750),(129490,9,1,'w','1',669168,2787),(129491,9,2,'e','1',669168,2749),(129492,9,3,'s','1',669168,2734),(129493,10,0,'e','1',669168,2733),(129494,10,1,'w','1',669168,2842),(129495,10,2,'n','1',669168,2736),(129496,10,3,'w','1',669168,2754),(129497,11,0,'e','1',669168,2902),(129498,11,1,'n','1',669168,2858),(129499,11,2,'n','1',669168,2815),(129500,11,3,'e','1',669168,2818),(129501,12,0,'n','1',669168,2851),(129502,12,1,'n','1',669168,2792),(129503,12,2,'n','1',669168,2860),(129504,12,3,'n','1',669168,2882),(129505,13,0,'w','1',669168,2760),(129506,13,1,'e','1',669168,2733),(129507,13,2,'e','1',669168,2736),(129508,13,3,'s','1',669168,2842),(129509,14,0,'e','1',669168,2901),(129510,14,1,'n','1',669168,2986),(129511,14,2,'s','1',669168,2746),(129512,14,3,'w','1',669168,2761),(129513,15,0,'s','1',669168,2838),(129514,15,1,'s','1',669168,2813),(129515,15,2,'n','1',669168,2992),(129516,15,3,'e','1',669168,2996),(129517,16,0,'w','1',669168,2761),(129518,16,1,'n','1',669168,2760),(129519,16,2,'n','1',669168,2903),(129520,16,3,'n','1',669168,2775),(129521,17,0,'w','1',669168,2813),(129522,17,1,'e','1',669168,2814),(129523,17,2,'e','1',669168,2795),(129524,17,3,'x','0',669168,2762),(129525,17,4,'e','1',669168,2864),(129526,18,0,'w','1',669168,2760),(129527,18,1,'w','1',669168,2863),(129528,18,2,'w','1',669168,2767),(129529,18,3,'w','1',669168,2864),(129530,19,0,'n','1',669168,2760),(129531,19,1,'e','1',669168,2740),(129532,19,2,'w','1',669168,2792),(129533,19,3,'n','1',669168,2872),(129534,20,0,'w','1',669168,2840),(129535,20,1,'n','1',669168,2877),(129536,20,2,'n','1',669168,2886),(129537,20,3,'n','1',669168,2878),(129538,21,0,'s','1',669168,2900),(129539,21,1,'s','1',669168,2878),(129540,21,2,'s','1',669168,2877),(129541,21,3,'e','1',669168,2781),(129542,22,0,'n','1',669168,2793),(129543,22,1,'n','1',669168,2794),(129544,22,2,'w','1',669168,2801),(129545,22,3,'n','1',669168,2857),(129546,22,4,'x','0',669168,2859),(129547,23,0,'n','1',669168,2790),(129548,23,1,'n','1',669168,2791),(129549,23,2,'w','1',669168,2789),(129550,23,3,'n','1',669168,2927),(129551,24,0,'w','1',669168,2737),(129552,24,1,'w','1',669168,2740),(129553,24,2,'w','1',669168,2776),(129554,24,3,'n','1',669168,2779),(129555,25,0,'n','1',669168,2776),(129556,25,1,'n','1',669168,2774),(129557,25,2,'n','1',669168,2773),(129558,25,3,'n','1',669168,2872),(129559,26,0,'s','1',669168,2746),(129560,26,1,'w','1',669168,2986),(129561,26,2,'e','1',669168,2780),(129562,26,3,'w','1',669168,2887),(129563,27,0,'w','1',669168,2829),(129564,27,1,'s','1',669168,2877),(129565,27,2,'e','1',669168,2781),(129566,27,3,'s','1',669168,2872),(129567,28,0,'n','1',669168,2964),(129568,28,1,'w','1',669168,2969),(129569,28,2,'n','1',669168,2858),(129570,28,3,'n','1',669168,2780),(129571,29,0,'s','1',669168,3007),(129572,29,1,'s','1',669168,3057),(129573,29,2,'e','1',669168,2801),(129574,29,3,'s','1',669168,2853),(129575,29,4,'x','0',669168,2910),(129576,30,0,'e','1',669168,2860),(129577,30,1,'w','1',669168,2833),(129578,30,2,'s','1',669168,2912),(129579,30,3,'e','1',669168,2944),(129580,31,0,'e','1',669168,2860),(129581,31,1,'w','1',669168,2998),(129582,31,2,'n','1',669168,2833),(129583,31,3,'n','1',669168,2826),(129584,2,0,'n','1',669169,2913),(129585,2,1,'n','1',669169,2874),(129586,2,2,'n','1',669169,2731),(129587,2,3,'n','1',669169,2721),(129588,3,0,'n','1',669169,2815),(129589,3,1,'n','1',669169,2818),(129590,3,2,'n','1',669169,2968),(129591,3,3,'n','1',669169,2750),(129592,4,0,'e','1',669169,2768),(129593,4,1,'s','1',669169,2864),(129594,4,2,'s','1',669169,2860),(129595,4,3,'w','1',669169,2765),(129596,5,0,'n','1',669169,2768),(129597,5,1,'s','1',669169,2890),(129598,5,2,'s','1',669169,3058),(129599,5,3,'s','1',669169,2981),(129600,6,0,'s','1',669169,2768),(129601,6,1,'s','1',669169,2944),(129602,6,2,'w','1',669169,2750),(129603,6,3,'s','1',669169,2773),(129604,7,0,'n','1',669169,2838),(129605,7,1,'n','1',669169,2839),(129606,7,2,'s','1',669169,2953),(129607,7,3,'s','1',669169,2843),(129608,8,0,'s','1',669169,2754),(129609,8,1,'s','1',669169,2745),(129610,8,2,'s','1',669169,2839),(129611,8,3,'w','1',669169,2823),(129612,9,0,'n','1',669169,2721),(129613,9,1,'n','1',669169,2824),(129614,9,2,'w','1',669169,2754),(129615,9,3,'w','1',669169,2736),(129616,10,0,'e','1',669169,2838),(129617,10,1,'n','1',669169,3015),(129618,10,2,'s','1',669169,2989),(129619,10,3,'s','1',669169,2745),(129620,11,0,'n','1',669169,2915),(129621,11,1,'n','1',669169,2901),(129622,11,2,'n','1',669169,2870),(129623,11,3,'n','1',669169,2927),(129624,12,0,'e','1',669169,2751),(129625,12,1,'e','1',669169,2750),(129626,12,2,'e','1',669169,2749),(129627,12,3,'e','1',669169,2734),(129628,13,0,'n','1',669169,2786),(129629,13,1,'w','1',669169,2760),(129630,13,2,'w','1',669169,2849),(129631,13,3,'s','1',669169,2738),(129632,14,0,'w','1',669169,2842),(129633,14,1,'n','1',669169,2739),(129634,14,2,'n','1',669169,2775),(129635,14,3,'n','1',669169,2717),(129636,2,0,'n','1',669169,2913),(129637,2,1,'n','1',669169,2874),(129638,2,2,'n','1',669169,2731),(129639,2,3,'n','1',669169,2721),(129640,3,0,'n','1',669169,2815),(129641,3,1,'n','1',669169,2818),(129642,3,2,'n','1',669169,2968),(129643,3,3,'n','1',669169,2750),(129644,4,0,'e','1',669169,2768),(129645,4,1,'s','1',669169,2864),(129646,4,2,'s','1',669169,2860),(129647,4,3,'w','1',669169,2765),(129648,5,0,'n','1',669169,2768),(129649,5,1,'s','1',669169,2890),(129650,5,2,'s','1',669169,3058),(129651,5,3,'s','1',669169,2981),(129652,6,0,'s','1',669169,2768),(129653,6,1,'s','1',669169,2944),(129654,6,2,'w','1',669169,2750),(129655,6,3,'s','1',669169,2773),(129656,7,0,'n','1',669169,2838),(129657,7,1,'n','1',669169,2839),(129658,7,2,'s','1',669169,2953),(129659,7,3,'s','1',669169,2843),(129660,8,0,'s','1',669169,2754),(129661,8,1,'s','1',669169,2745),(129662,8,2,'s','1',669169,2839),(129663,8,3,'w','1',669169,2823),(129664,9,0,'n','1',669169,2721),(129665,9,1,'n','1',669169,2824),(129666,9,2,'w','1',669169,2754),(129667,9,3,'w','1',669169,2736),(129668,10,0,'e','1',669169,2838),(129669,10,1,'n','1',669169,3015),(129670,10,2,'s','1',669169,2989),(129671,10,3,'s','1',669169,2745),(129672,11,0,'n','1',669169,2915),(129673,11,1,'n','1',669169,2901),(129674,11,2,'n','1',669169,2870),(129675,11,3,'n','1',669169,2927),(129676,12,0,'e','1',669169,2751),(129677,12,1,'e','1',669169,2750),(129678,12,2,'e','1',669169,2749),(129679,12,3,'e','1',669169,2734),(129680,13,0,'n','1',669169,2786),(129681,13,1,'w','1',669169,2760),(129682,13,2,'w','1',669169,2849),(129683,13,3,'s','1',669169,2738),(129684,14,0,'w','1',669169,2842),(129685,14,1,'n','1',669169,2739),(129686,14,2,'n','1',669169,2775),(129687,14,3,'n','1',669169,2717),(129688,2,0,'n','1',669170,2913),(129689,2,1,'n','1',669170,2874),(129690,2,2,'n','1',669170,2731),(129691,2,3,'n','1',669170,2750),(129692,3,0,'n','1',669170,2721),(129693,3,1,'n','1',669170,2888),(129694,3,2,'n','1',669170,2815),(129695,3,3,'n','1',669170,2818),(129696,4,0,'s','1',669170,2768),(129697,4,1,'s','1',669170,2750),(129698,4,2,'e','1',669170,2731),(129699,4,3,'e','1',669170,2732),(129700,5,0,'w','1',669170,2733),(129701,5,1,'s','1',669170,2786),(129702,5,2,'n','1',669170,2717),(129703,5,3,'e','1',669170,2732),(129704,6,0,'n','1',669170,2858),(129705,6,1,'w','1',669170,2719),(129706,6,2,'n','1',669170,2870),(129707,6,3,'n','1',669170,2739),(129708,7,0,'e','1',669170,2939),(129709,7,1,'e','1',669170,2733),(129710,7,2,'n','1',669170,2842),(129711,7,3,'w','1',669170,2820),(129712,8,0,'w','1',669170,2739),(129713,8,1,'w','1',669170,2719),(129714,8,2,'w','1',669170,2915),(129715,8,3,'n','1',669170,2739),(129716,9,0,'w','1',669170,2737),(129717,9,1,'s','1',669170,2738),(129718,9,2,'s','1',669170,2740),(129719,9,3,'x','0',669170,2760),(129720,9,4,'w','1',669170,2842),(129721,10,0,'e','1',669170,2939),(129722,10,1,'e','1',669170,2968),(129723,10,2,'s','1',669170,2785),(129724,10,3,'n','1',669170,2733),(129725,11,0,'w','1',669170,2734),(129726,11,1,'w','1',669170,2749),(129727,11,2,'w','1',669170,2750),(129728,11,3,'e','1',669170,2784),(129729,12,0,'w','1',669170,2878),(129730,12,1,'n','1',669170,2981),(129731,12,2,'w','1',669170,2790),(129732,12,3,'n','1',669170,2858),(129733,13,0,'s','1',669170,2904),(129734,13,1,'s','1',669170,3035),(129735,13,2,'s','1',669170,2939),(129736,13,3,'n','1',669170,2981),(129737,14,0,'w','1',669170,2915),(129738,14,1,'w','1',669170,2905),(129739,14,2,'n','1',669170,2903),(129740,14,3,'w','1',669170,2797),(129741,15,0,'n','1',669170,2858),(129742,15,1,'w','1',669170,2754),(129743,15,2,'w','1',669170,2736),(129744,15,3,'w','1',669170,2760),(129745,16,0,'e','1',669170,2751),(129746,16,1,'s','1',669170,2851),(129747,16,2,'e','1',669170,3042),(129748,16,3,'n','1',669170,2927),(129749,17,0,'e','1',669170,2851),(129750,17,1,'e','1',669170,2787),(129751,17,2,'s','1',669170,2802),(129752,17,3,'n','1',669170,2739),(129753,18,0,'n','1',669170,2717),(129754,18,1,'w','1',669170,2860),(129755,18,2,'n','1',669170,2750),(129756,18,3,'n','1',669170,2882),(129757,19,0,'n','1',669170,2779),(129758,19,1,'n','1',669170,2780),(129759,19,2,'s','1',669170,2845),(129760,19,3,'e','1',669170,2784),(129761,20,0,'e','1',669170,2768),(129762,20,1,'n','1',669170,2765),(129763,20,2,'s','1',669170,2988),(129764,20,3,'s','1',669170,3038),(129765,21,0,'w','1',669170,2725),(129766,21,1,'n','1',669170,2719),(129767,21,2,'w','1',669170,2840),(129768,21,3,'n','1',669170,2887),(129769,22,0,'w','1',669170,2775),(129770,22,1,'w','1',669170,2855),(129771,22,2,'s','1',669170,2765),(129772,22,3,'s','1',669170,2912),(129773,23,0,'w','1',669170,2749),(129774,23,1,'s','1',669170,2852),(129775,23,2,'w','1',669170,2855),(129776,23,3,'e','1',669170,2784),(129777,24,0,'w','1',669170,2775),(129778,24,1,'w','1',669170,2855),(129779,24,2,'s','1',669170,2798),(129780,24,3,'e','1',669170,2750),(129781,25,0,'s','1',669170,2785),(129782,25,1,'w','1',669170,2986),(129783,25,2,'s','1',669170,2796),(129784,26,0,'e','1',669170,2803),(129785,26,1,'e','1',669170,2795),(129786,26,2,'x','0',669170,2762),(129787,26,3,'n','1',669170,2749),(129788,26,4,'n','1',669170,2965),(129789,27,0,'s','1',669170,2860),(129790,27,1,'w','1',669170,2765),(129791,27,2,'e','1',669170,2954),(129792,27,3,'s','1',669170,2948),(129793,28,0,'s','1',669170,2768),(129794,28,1,'s','1',669170,2770),(129795,28,2,'n','1',669170,2793),(129796,28,3,'w','1',669170,2750),(129797,29,0,'w','1',669170,2923),(129798,29,1,'n','1',669170,2803),(129799,29,2,'s','1',669170,2948),(129800,29,3,'s','1',669170,2802),(129801,30,0,'n','1',669170,2803),(129802,30,1,'s','1',669170,2948),(129803,30,2,'s','1',669170,2802),(129804,30,3,'n','1',669170,2909),(129805,31,0,'n','1',669170,2803),(129806,31,1,'s','1',669170,2948),(129807,31,2,'s','1',669170,2802),(129808,31,3,'w','1',669170,2784),(129809,32,0,'e','1',669170,2751),(129810,32,1,'w','1',669170,2750),(129811,32,2,'s','1',669170,2860),(129812,32,3,'e','1',669170,2803),(129813,33,0,'w','1',669170,2908),(129814,33,1,'w','1',669170,2884),(129815,33,2,'s','1',669170,2735),(129816,33,3,'s','1',669170,2848),(129817,34,0,'n','1',669170,2828),(129818,34,1,'s','1',669170,2930),(129819,34,2,'n','1',669170,2772),(129820,34,3,'w','1',669170,2790),(129821,35,0,'s','1',669170,2930),(129822,35,1,'w','1',669170,2751),(129823,35,2,'e','1',669170,2871),(129824,35,3,'s','1',669170,2900),(129825,36,0,'n','1',669170,2772),(129826,36,1,'n','1',669170,2735),(129827,36,2,'n','1',669170,2902),(129828,36,3,'n','1',669170,2858),(129829,37,0,'n','1',669170,2789),(129830,37,1,'e','1',669170,3006),(129831,37,2,'w','1',669170,2840),(129832,38,0,'e','1',669170,2954),(129833,38,1,'e','1',669170,2771),(129834,38,2,'n','1',669170,2778),(129835,38,3,'n','1',669170,2902),(129836,39,0,'w','1',669170,2840),(129837,39,1,'w','1',669170,2751),(129838,39,2,'e','1',669170,2871),(129839,39,3,'s','1',669170,2900),(129840,40,0,'e','1',669170,2904),(129841,40,1,'e','1',669170,3006),(129842,40,2,'e','1',669170,2751),(129843,40,3,'e','1',669170,2948),(129844,41,0,'e','1',669170,2750),(129845,41,1,'e','1',669170,2749),(129846,41,2,'w','1',669170,2850),(129847,41,3,'s','1',669170,2734),(129848,42,0,'w','1',669170,2922),(129849,42,1,'s','1',669170,2733),(129850,42,2,'n','1',669170,2814),(129851,42,3,'n','1',669170,2947),(129852,42,4,'x','0',669170,2883),(129853,43,0,'w','1',669170,2794),(129854,43,1,'w','1',669170,2770),(129855,43,2,'w','1',669170,2900),(129856,43,3,'w','1',669170,2733),(129857,44,0,'w','1',669170,2732),(129858,44,1,'n','1',669170,2731),(129859,44,2,'w','1',669170,2750),(129860,44,3,'w','1',669170,2838),(129861,45,0,'e','1',669170,2778),(129862,45,1,'e','1',669170,2771),(129863,45,2,'e','1',669170,2770),(129864,45,3,'s','1',669170,2746),(129865,46,0,'n','1',669170,2923),(129866,46,1,'e','1',669170,2959),(129867,46,2,'n','1',669170,2920),(129868,46,3,'n','1',669170,2914),(129869,47,0,'w','1',669170,2984),(129870,47,1,'n','1',669170,2918),(129871,47,2,'n','1',669170,2834),(129872,47,3,'n','1',669170,2823),(129873,48,0,'w','1',669170,2986),(129874,48,1,'n','1',669170,2901),(129875,48,2,'e','1',669170,3023),(129876,48,3,'e','1',669170,2929),(129877,49,0,'s','1',669170,2924),(129878,49,1,'w','1',669170,3045),(129879,49,2,'n','1',669170,2789),(129880,49,3,'n','1',669170,2817),(129881,50,0,'n','1',669170,2908),(129882,50,1,'e','1',669170,2770),(129883,50,2,'e','1',669170,2746),(129884,50,3,'e','1',669170,2740),(129885,51,0,'e','1',669170,2751),(129886,51,1,'x','0',669170,2859),(129887,51,2,'n','1',669170,2860),(129888,51,3,'n','1',669170,2750),(129889,51,4,'e','1',669170,2840),(129890,52,0,'e','1',669170,2840),(129891,52,1,'n','1',669170,3000),(129892,52,2,'w','1',669170,3044),(129893,52,3,'w','1',669170,3059),(129894,53,0,'w','1',669170,3060),(129895,53,1,'w','1',669170,2892),(129896,53,2,'w','1',669170,3061),(129897,53,3,'w','1',669170,2903),(129898,54,0,'w','1',669170,2889),(129899,54,1,'n','1',669170,2737),(129900,54,2,'n','1',669170,2745),(129901,54,3,'e','1',669170,2840),(129902,55,0,'n','1',669170,2852),(129903,55,1,'e','1',669170,2768),(129904,55,2,'e','1',669170,2857),(129905,55,3,'s','1',669170,2759),(129906,56,0,'w','1',669170,2773),(129907,56,1,'w','1',669170,2765),(129908,56,2,'e','1',669170,2941),(129909,56,3,'s','1',669170,2904),(129910,57,0,'s','1',669170,2981),(129911,57,1,'e','1',669170,2968),(129912,57,2,'w','1',669170,2840),(129913,57,3,'n','1',669170,2877),(129914,58,0,'n','1',669170,2797),(129915,58,1,'e','1',669170,2795),(129916,58,2,'e','1',669170,2740),(129917,58,3,'n','1',669170,2789),(129918,59,0,'e','1',669170,2740),(129919,59,1,'n','1',669170,2783),(129920,59,2,'e','1',669170,2946),(129921,59,3,'s','1',669170,3026),(129922,60,0,'n','1',669170,3007),(129923,60,1,'n','1',669170,2859),(129924,60,2,'w','1',669170,2767),(129925,60,3,'s','1',669170,3026),(129926,61,0,'w','1',669170,2889),(129927,61,1,'n','1',669170,2737),(129928,61,2,'s','1',669170,2848),(129929,61,3,'n','1',669170,2795),(129930,62,0,'n','1',669170,2878),(129931,62,1,'n','1',669170,2990),(129932,62,2,'w','1',669170,2795),(129933,62,3,'w','1',669170,2762),(129934,63,0,'s','1',669170,2759),(129935,63,1,'w','1',669170,2737),(129936,63,2,'w','1',669170,2740),(129937,64,0,'w','1',669170,2777),(129938,64,1,'n','1',669170,2778),(129939,64,2,'w','1',669170,2786),(129940,64,3,'s','1',669170,2746),(129941,65,0,'w','1',669170,2775),(129942,65,1,'x','0',669170,2784),(129943,65,2,'w','1',669170,2986),(129944,65,3,'e','1',669170,2908),(129945,65,4,'n','1',669170,2986),(129946,66,0,'s','1',669170,2906),(129947,66,1,'e','1',669170,2746),(129948,66,2,'e','1',669170,2740),(129949,66,3,'w','1',669170,2762),(129950,67,0,'s','1',669170,2900),(129951,67,1,'w','1',669170,2859),(129952,67,2,'w','1',669170,2862),(129953,67,3,'n','1',669170,2878),(129954,68,0,'w','1',669170,2889),(129955,68,1,'n','1',669170,2737),(129956,68,2,'n','1',669170,2795),(129957,68,3,'n','1',669170,2796),(129958,69,0,'s','1',669170,2768),(129959,69,1,'w','1',669170,2852),(129960,69,2,'x','0',669170,2757),(129961,69,3,'e','1',669170,2773),(129962,69,4,'n','1',669170,2750),(129963,70,0,'w','1',669170,2759),(129964,70,1,'w','1',669170,2756),(129965,70,2,'s','1',669170,2856),(129966,70,3,'s','1',669170,2755),(129967,71,0,'e','1',669170,2861),(129968,71,1,'x','0',669170,2934),(129969,71,2,'s','1',669170,2746),(129970,71,3,'n','1',669170,2986),(129971,71,4,'n','1',669170,2746),(129972,72,0,'e','1',669170,2755),(129973,72,1,'e','1',669170,2756),(129974,72,2,'e','1',669170,2950),(129975,72,3,'w','1',669170,2761),(129976,73,0,'n','1',669170,3001),(129977,73,1,'n','1',669170,2759),(129978,73,2,'e','1',669170,2824),(129979,73,3,'n','1',669170,2823),(129980,74,0,'e','1',669170,2900),(129981,74,1,'e','1',669170,2942),(129982,74,2,'n','1',669170,2862),(129983,74,3,'w','1',669170,2880),(129984,75,0,'n','1',669170,2768),(129985,75,1,'s','1',669170,2885),(129986,75,2,'w','1',669170,2890),(129987,75,3,'n','1',669170,2941),(129988,76,0,'e','1',669170,2893),(129989,76,1,'e','1',669170,2866),(129990,76,2,'n','1',669170,2900),(129991,76,3,'n','1',669170,2745),(129992,77,0,'s','1',669170,2899),(129993,77,1,'s','1',669170,3056),(129994,77,2,'w','1',669170,3026),(129995,77,3,'n','1',669170,2767),(129996,2,0,'n','1',669170,2913),(129997,2,1,'n','1',669170,2874),(129998,2,2,'n','1',669170,2731),(129999,2,3,'n','1',669170,2750),(130000,3,0,'n','1',669170,2721),(130001,3,1,'n','1',669170,2888),(130002,3,2,'n','1',669170,2815),(130003,3,3,'n','1',669170,2818),(130004,4,0,'s','1',669170,2768),(130005,4,1,'s','1',669170,2750),(130006,4,2,'e','1',669170,2731),(130007,4,3,'e','1',669170,2732),(130008,5,0,'w','1',669170,2733),(130009,5,1,'s','1',669170,2786),(130010,5,2,'n','1',669170,2717),(130011,5,3,'e','1',669170,2732),(130012,6,0,'n','1',669170,2858),(130013,6,1,'w','1',669170,2719),(130014,6,2,'n','1',669170,2870),(130015,6,3,'n','1',669170,2739),(130016,7,0,'e','1',669170,2939),(130017,7,1,'e','1',669170,2733),(130018,7,2,'n','1',669170,2842),(130019,7,3,'w','1',669170,2820),(130020,8,0,'w','1',669170,2739),(130021,8,1,'w','1',669170,2719),(130022,8,2,'w','1',669170,2915),(130023,8,3,'n','1',669170,2739),(130024,9,0,'w','1',669170,2737),(130025,9,1,'s','1',669170,2738),(130026,9,2,'s','1',669170,2740),(130027,9,3,'x','0',669170,2760),(130028,9,4,'w','1',669170,2842),(130029,10,0,'e','1',669170,2939),(130030,10,1,'e','1',669170,2968),(130031,10,2,'s','1',669170,2785),(130032,10,3,'n','1',669170,2733),(130033,11,0,'w','1',669170,2734),(130034,11,1,'w','1',669170,2749),(130035,11,2,'w','1',669170,2750),(130036,11,3,'e','1',669170,2784),(130037,12,0,'w','1',669170,2878),(130038,12,1,'n','1',669170,2981),(130039,12,2,'w','1',669170,2790),(130040,12,3,'n','1',669170,2858),(130041,13,0,'s','1',669170,2904),(130042,13,1,'s','1',669170,3035),(130043,13,2,'s','1',669170,2939),(130044,13,3,'n','1',669170,2981),(130045,14,0,'w','1',669170,2915),(130046,14,1,'w','1',669170,2905),(130047,14,2,'n','1',669170,2903),(130048,14,3,'w','1',669170,2797),(130049,15,0,'n','1',669170,2858),(130050,15,1,'w','1',669170,2754),(130051,15,2,'w','1',669170,2736),(130052,15,3,'w','1',669170,2760),(130053,16,0,'e','1',669170,2751),(130054,16,1,'s','1',669170,2851),(130055,16,2,'e','1',669170,3042),(130056,16,3,'n','1',669170,2927),(130057,17,0,'e','1',669170,2851),(130058,17,1,'e','1',669170,2787),(130059,17,2,'s','1',669170,2802),(130060,17,3,'n','1',669170,2739),(130061,18,0,'n','1',669170,2717),(130062,18,1,'w','1',669170,2860),(130063,18,2,'n','1',669170,2750),(130064,18,3,'n','1',669170,2882),(130065,19,0,'n','1',669170,2779),(130066,19,1,'n','1',669170,2780),(130067,19,2,'s','1',669170,2845),(130068,19,3,'e','1',669170,2784),(130069,20,0,'e','1',669170,2768),(130070,20,1,'n','1',669170,2765),(130071,20,2,'s','1',669170,2988),(130072,20,3,'s','1',669170,3038),(130073,21,0,'w','1',669170,2725),(130074,21,1,'n','1',669170,2719),(130075,21,2,'w','1',669170,2840),(130076,21,3,'n','1',669170,2887),(130077,22,0,'w','1',669170,2775),(130078,22,1,'w','1',669170,2855),(130079,22,2,'s','1',669170,2765),(130080,22,3,'s','1',669170,2912),(130081,23,0,'w','1',669170,2749),(130082,23,1,'s','1',669170,2852),(130083,23,2,'w','1',669170,2855),(130084,23,3,'e','1',669170,2784),(130085,24,0,'w','1',669170,2775),(130086,24,1,'w','1',669170,2855),(130087,24,2,'s','1',669170,2798),(130088,24,3,'e','1',669170,2750),(130089,25,0,'s','1',669170,2785),(130090,25,1,'w','1',669170,2986),(130091,25,2,'s','1',669170,2796),(130092,26,0,'e','1',669170,2803),(130093,26,1,'e','1',669170,2795),(130094,26,2,'x','0',669170,2762),(130095,26,3,'n','1',669170,2749),(130096,26,4,'n','1',669170,2965),(130097,27,0,'s','1',669170,2860),(130098,27,1,'w','1',669170,2765),(130099,27,2,'e','1',669170,2954),(130100,27,3,'s','1',669170,2948),(130101,28,0,'s','1',669170,2768),(130102,28,1,'s','1',669170,2770),(130103,28,2,'n','1',669170,2793),(130104,28,3,'w','1',669170,2750),(130105,29,0,'w','1',669170,2923),(130106,29,1,'n','1',669170,2803),(130107,29,2,'s','1',669170,2948),(130108,29,3,'s','1',669170,2802),(130109,30,0,'n','1',669170,2803),(130110,30,1,'s','1',669170,2948),(130111,30,2,'s','1',669170,2802),(130112,30,3,'n','1',669170,2909),(130113,31,0,'n','1',669170,2803),(130114,31,1,'s','1',669170,2948),(130115,31,2,'s','1',669170,2802),(130116,31,3,'w','1',669170,2784),(130117,32,0,'e','1',669170,2751),(130118,32,1,'w','1',669170,2750),(130119,32,2,'s','1',669170,2860),(130120,32,3,'e','1',669170,2803),(130121,33,0,'w','1',669170,2908),(130122,33,1,'w','1',669170,2884),(130123,33,2,'s','1',669170,2735),(130124,33,3,'s','1',669170,2848),(130125,34,0,'n','1',669170,2828),(130126,34,1,'s','1',669170,2930),(130127,34,2,'n','1',669170,2772),(130128,34,3,'w','1',669170,2790),(130129,35,0,'s','1',669170,2930),(130130,35,1,'w','1',669170,2751),(130131,35,2,'e','1',669170,2871),(130132,35,3,'s','1',669170,2900),(130133,36,0,'n','1',669170,2772),(130134,36,1,'n','1',669170,2735),(130135,36,2,'n','1',669170,2902),(130136,36,3,'n','1',669170,2858),(130137,37,0,'n','1',669170,2789),(130138,37,1,'e','1',669170,3006),(130139,37,2,'w','1',669170,2840),(130140,38,0,'e','1',669170,2954),(130141,38,1,'e','1',669170,2771),(130142,38,2,'n','1',669170,2778),(130143,38,3,'n','1',669170,2902),(130144,39,0,'w','1',669170,2840),(130145,39,1,'w','1',669170,2751),(130146,39,2,'e','1',669170,2871),(130147,39,3,'s','1',669170,2900),(130148,40,0,'e','1',669170,2904),(130149,40,1,'e','1',669170,3006),(130150,40,2,'e','1',669170,2751),(130151,40,3,'e','1',669170,2948),(130152,41,0,'e','1',669170,2750),(130153,41,1,'e','1',669170,2749),(130154,41,2,'w','1',669170,2850),(130155,41,3,'s','1',669170,2734),(130156,42,0,'w','1',669170,2922),(130157,42,1,'s','1',669170,2733),(130158,42,2,'n','1',669170,2814),(130159,42,3,'n','1',669170,2947),(130160,42,4,'x','0',669170,2883),(130161,43,0,'w','1',669170,2794),(130162,43,1,'w','1',669170,2770),(130163,43,2,'w','1',669170,2900),(130164,43,3,'w','1',669170,2733),(130165,44,0,'w','1',669170,2732),(130166,44,1,'n','1',669170,2731),(130167,44,2,'w','1',669170,2750),(130168,44,3,'w','1',669170,2838),(130169,45,0,'e','1',669170,2778),(130170,45,1,'e','1',669170,2771),(130171,45,2,'e','1',669170,2770),(130172,45,3,'s','1',669170,2746),(130173,46,0,'n','1',669170,2923),(130174,46,1,'e','1',669170,2959),(130175,46,2,'n','1',669170,2920),(130176,46,3,'n','1',669170,2914),(130177,47,0,'w','1',669170,2984),(130178,47,1,'n','1',669170,2918),(130179,47,2,'n','1',669170,2834),(130180,47,3,'n','1',669170,2823),(130181,48,0,'w','1',669170,2986),(130182,48,1,'n','1',669170,2901),(130183,48,2,'e','1',669170,3023),(130184,48,3,'e','1',669170,2929),(130185,49,0,'s','1',669170,2924),(130186,49,1,'w','1',669170,3045),(130187,49,2,'n','1',669170,2789),(130188,49,3,'n','1',669170,2817),(130189,50,0,'n','1',669170,2908),(130190,50,1,'e','1',669170,2770),(130191,50,2,'e','1',669170,2746),(130192,50,3,'e','1',669170,2740),(130193,51,0,'e','1',669170,2751),(130194,51,1,'x','0',669170,2859),(130195,51,2,'n','1',669170,2860),(130196,51,3,'n','1',669170,2750),(130197,51,4,'e','1',669170,2840),(130198,52,0,'e','1',669170,2840),(130199,52,1,'n','1',669170,3000),(130200,52,2,'w','1',669170,3044),(130201,52,3,'w','1',669170,3059),(130202,53,0,'w','1',669170,3060),(130203,53,1,'w','1',669170,2892),(130204,53,2,'w','1',669170,3061),(130205,53,3,'w','1',669170,2903),(130206,54,0,'w','1',669170,2889),(130207,54,1,'n','1',669170,2737),(130208,54,2,'n','1',669170,2745),(130209,54,3,'e','1',669170,2840),(130210,55,0,'n','1',669170,2852),(130211,55,1,'e','1',669170,2768),(130212,55,2,'e','1',669170,2857),(130213,55,3,'s','1',669170,2759),(130214,56,0,'w','1',669170,2773),(130215,56,1,'w','1',669170,2765),(130216,56,2,'e','1',669170,2941),(130217,56,3,'s','1',669170,2904),(130218,57,0,'s','1',669170,2981),(130219,57,1,'e','1',669170,2968),(130220,57,2,'w','1',669170,2840),(130221,57,3,'n','1',669170,2877),(130222,58,0,'n','1',669170,2797),(130223,58,1,'e','1',669170,2795),(130224,58,2,'e','1',669170,2740),(130225,58,3,'n','1',669170,2789),(130226,59,0,'e','1',669170,2740),(130227,59,1,'n','1',669170,2783),(130228,59,2,'e','1',669170,2946),(130229,59,3,'s','1',669170,3026),(130230,60,0,'n','1',669170,3007),(130231,60,1,'n','1',669170,2859),(130232,60,2,'w','1',669170,2767),(130233,60,3,'s','1',669170,3026),(130234,61,0,'w','1',669170,2889),(130235,61,1,'n','1',669170,2737),(130236,61,2,'s','1',669170,2848),(130237,61,3,'n','1',669170,2795),(130238,62,0,'n','1',669170,2878),(130239,62,1,'n','1',669170,2990),(130240,62,2,'w','1',669170,2795),(130241,62,3,'w','1',669170,2762),(130242,63,0,'s','1',669170,2759),(130243,63,1,'w','1',669170,2737),(130244,63,2,'w','1',669170,2740),(130245,64,0,'w','1',669170,2777),(130246,64,1,'n','1',669170,2778),(130247,64,2,'w','1',669170,2786),(130248,64,3,'s','1',669170,2746),(130249,65,0,'w','1',669170,2775),(130250,65,1,'x','0',669170,2784),(130251,65,2,'w','1',669170,2986),(130252,65,3,'e','1',669170,2908),(130253,65,4,'n','1',669170,2986),(130254,66,0,'s','1',669170,2906),(130255,66,1,'e','1',669170,2746),(130256,66,2,'e','1',669170,2740),(130257,66,3,'w','1',669170,2762),(130258,67,0,'s','1',669170,2900),(130259,67,1,'w','1',669170,2859),(130260,67,2,'w','1',669170,2862),(130261,67,3,'n','1',669170,2878),(130262,68,0,'w','1',669170,2889),(130263,68,1,'n','1',669170,2737),(130264,68,2,'n','1',669170,2795),(130265,68,3,'n','1',669170,2796),(130266,69,0,'s','1',669170,2768),(130267,69,1,'w','1',669170,2852),(130268,69,2,'x','0',669170,2757),(130269,69,3,'e','1',669170,2773),(130270,69,4,'n','1',669170,2750),(130271,70,0,'w','1',669170,2759),(130272,70,1,'w','1',669170,2756),(130273,70,2,'s','1',669170,2856),(130274,70,3,'s','1',669170,2755),(130275,71,0,'e','1',669170,2861),(130276,71,1,'x','0',669170,2934),(130277,71,2,'s','1',669170,2746),(130278,71,3,'n','1',669170,2986),(130279,71,4,'n','1',669170,2746),(130280,72,0,'e','1',669170,2755),(130281,72,1,'e','1',669170,2756),(130282,72,2,'e','1',669170,2950),(130283,72,3,'w','1',669170,2761),(130284,73,0,'n','1',669170,3001),(130285,73,1,'n','1',669170,2759),(130286,73,2,'e','1',669170,2824),(130287,73,3,'n','1',669170,2823),(130288,74,0,'e','1',669170,2900),(130289,74,1,'e','1',669170,2942),(130290,74,2,'n','1',669170,2862),(130291,74,3,'w','1',669170,2880),(130292,75,0,'n','1',669170,2768),(130293,75,1,'s','1',669170,2885),(130294,75,2,'w','1',669170,2890),(130295,75,3,'n','1',669170,2941),(130296,76,0,'e','1',669170,2893),(130297,76,1,'e','1',669170,2866),(130298,76,2,'n','1',669170,2900),(130299,76,3,'n','1',669170,2745),(130300,77,0,'s','1',669170,2899),(130301,77,1,'s','1',669170,3056),(130302,77,2,'w','1',669170,3026),(130303,77,3,'n','1',669170,2767),(130304,2,0,'n','1',669171,2728),(130305,2,1,'n','1',669171,2991),(130306,2,2,'w','1',669171,2736),(130307,2,3,'n','1',669171,2992),(130308,3,0,'n','1',669171,2813),(130309,3,1,'n','1',669171,2842),(130310,3,2,'n','1',669171,2738),(130311,3,3,'n','1',669171,2721),(130312,4,0,'s','1',669171,2741),(130313,4,1,'s','1',669171,2742),(130314,4,2,'e','1',669171,2738),(130315,4,3,'s','1',669171,2743),(130316,5,0,'w','1',669171,2760),(130317,5,1,'w','1',669171,3011),(130318,5,2,'s','1',669171,2805),(130319,5,3,'n','1',669171,2717),(130320,6,0,'w','1',669171,2738),(130321,6,1,'w','1',669171,2734),(130322,6,2,'s','1',669171,2844),(130323,6,3,'n','1',669171,2819),(130324,7,0,'n','1',669171,2749),(130325,7,1,'n','1',669171,2719),(130326,7,2,'n','1',669171,2845),(130327,7,3,'n','1',669171,2846),(130328,8,0,'s','1',669171,2860),(130329,8,1,'w','1',669171,2765),(130330,8,2,'s','1',669171,2792),(130331,8,3,'s','1',669171,2768),(130332,9,0,'w','1',669171,2793),(130333,9,1,'w','1',669171,2750),(130334,9,2,'w','1',669171,2798),(130335,9,3,'n','1',669171,2774),(130336,10,0,'e','1',669171,2751),(130337,10,1,'e','1',669171,2750),(130338,10,2,'e','1',669171,2749),(130339,10,3,'e','1',669171,2734),(130340,11,0,'w','1',669171,2738),(130341,11,1,'e','1',669171,2734),(130342,11,2,'s','1',669171,2844),(130343,11,3,'w','1',669171,2754),(130344,12,0,'s','1',669171,2832),(130345,12,1,'w','1',669171,2738),(130346,12,2,'w','1',669171,2850),(130347,12,3,'s','1',669171,2734),(130348,13,0,'n','1',669171,2733),(130349,13,1,'e','1',669171,2948),(130350,13,2,'s','1',669171,2850),(130351,13,3,'x','0',669171,2883),(130352,13,4,'s','1',669171,2734),(130353,14,0,'n','1',669171,2733),(130354,14,1,'w','1',669171,2734),(130355,14,2,'n','1',669171,2749),(130356,14,3,'n','1',669171,2955),(130357,15,0,'n','1',669171,2736),(130358,15,1,'n','1',669171,2737),(130359,15,2,'e','1',669171,2825),(130360,15,3,'n','1',669171,2759),(130361,16,0,'n','1',669171,2905),(130362,16,1,'n','1',669171,2762),(130363,16,2,'e','1',669171,2789),(130364,16,3,'n','1',669171,2972),(130365,17,0,'n','1',669171,2986),(130366,17,1,'e','1',669171,2990),(130367,17,2,'e','1',669171,3006),(130368,17,3,'w','1',669171,2746),(130369,18,0,'e','1',669171,2770),(130370,18,1,'e','1',669171,2761),(130371,18,2,'n','1',669171,2759),(130372,18,3,'n','1',669171,2790),(130373,19,0,'n','1',669171,2905),(130374,19,1,'w','1',669171,2976),(130375,19,2,'w','1',669171,2958),(130376,19,3,'e','1',669171,2783),(130377,20,0,'e','1',669171,2762),(130378,20,1,'e','1',669171,2973),(130379,20,2,'e','1',669171,2824),(130380,20,3,'n','1',669171,2823),(130381,21,0,'w','1',669171,2746),(130382,21,1,'w','1',669171,2770),(130383,21,2,'w','1',669171,2958),(130384,21,3,'n','1',669171,2791),(130385,22,0,'n','1',669171,2861),(130386,22,1,'e','1',669171,2856),(130387,22,2,'e','1',669171,2777),(130388,22,3,'e','1',669171,2784),(130389,23,0,'n','1',669171,2882),(130390,23,1,'n','1',669171,2775),(130391,23,2,'n','1',669171,2851),(130392,23,3,'n','1',669171,2792),(130393,24,0,'n','1',669171,2902),(130394,24,1,'n','1',669171,2858),(130395,24,2,'n','1',669171,2771),(130396,24,3,'e','1',669171,2778),(130397,25,0,'e','1',669171,2795),(130398,25,1,'w','1',669171,2879),(130399,25,2,'e','1',669171,2762),(130400,26,0,'s','1',669171,2764),(130401,26,1,'w','1',669171,2765),(130402,26,2,'x','0',669171,2757),(130403,26,3,'w','1',669171,2767),(130404,26,4,'x','0',669171,2801),(130405,26,5,'w','1',669171,2864),(130406,27,0,'w','1',669171,2748),(130407,27,1,'s','1',669171,2768),(130408,27,2,'n','1',669171,2879),(130409,27,3,'x','0',669171,2880),(130410,27,4,'w','1',669171,2750),(130411,28,0,'e','1',669171,3007),(130412,28,1,'s','1',669171,3057),(130413,28,2,'s','1',669171,2853),(130414,28,3,'x','0',669171,2910),(130415,28,4,'w','1',669171,2864),(130416,29,0,'e','1',669171,2751),(130417,29,1,'e','1',669171,2750),(130418,29,2,'s','1',669171,2749),(130419,29,3,'e','1',669171,2732),(130420,30,0,'e','1',669171,2733),(130421,30,1,'s','1',669171,2842),(130422,30,2,'w','1',669171,2762),(130423,30,3,'n','1',669171,2878),(130424,31,0,'s','1',669171,2728),(130425,31,1,'s','1',669171,2813),(130426,31,2,'e','1',669171,2993),(130427,31,3,'s','1',669171,2992),(130428,32,0,'n','1',669171,2991),(130429,32,1,'n','1',669171,2834),(130430,32,2,'e','1',669171,2992),(130431,32,3,'n','1',669171,2887),(130432,33,0,'n','1',669171,2902),(130433,33,1,'n','1',669171,2778),(130434,33,2,'n','1',669171,2794),(130435,33,3,'n','1',669171,2857),(130436,34,0,'w','1',669171,2777),(130437,34,1,'n','1',669171,2778),(130438,34,2,'n','1',669171,2794),(130439,34,3,'w','1',669171,2795),(130440,35,0,'w','1',669171,2823),(130441,35,1,'n','1',669171,2811),(130442,35,2,'w','1',669171,2824),(130443,35,3,'x','0',669171,2762),(130444,35,4,'w','1',669171,2812),(130445,36,0,'w','1',669171,2973),(130446,36,1,'w','1',669171,2915),(130447,36,2,'w','1',669171,2739),(130448,36,3,'n','1',669171,2729),(130449,37,0,'n','1',669171,2797),(130450,37,1,'n','1',669171,2813),(130451,37,2,'n','1',669171,2789),(130452,37,3,'e','1',669171,2843),(130453,38,0,'n','1',669171,2969),(130454,38,1,'n','1',669171,2909),(130455,38,2,'w','1',669171,2784),(130456,38,3,'w','1',669171,2842),(130457,39,0,'e','1',669171,2900),(130458,39,1,'s','1',669171,2866),(130459,39,2,'s','1',669171,2862),(130460,39,3,'w','1',669171,2880),(130461,40,0,'n','1',669171,2900),(130462,40,1,'s','1',669171,2899),(130463,40,2,'w','1',669171,2767),(130464,40,3,'n','1',669171,2857),(130465,41,0,'n','1',669171,2777),(130466,41,1,'n','1',669171,2776),(130467,41,2,'n','1',669171,2774),(130468,41,3,'n','1',669171,2773),(130469,42,0,'e','1',669171,2859),(130470,42,1,'e','1',669171,2773),(130471,42,2,'n','1',669171,2852),(130472,42,3,'n','1',669171,2912),(130473,2,0,'n','1',669171,2728),(130474,2,1,'n','1',669171,2991),(130475,2,2,'w','1',669171,2736),(130476,2,3,'n','1',669171,2992),(130477,3,0,'n','1',669171,2813),(130478,3,1,'n','1',669171,2842),(130479,3,2,'n','1',669171,2738),(130480,3,3,'n','1',669171,2721),(130481,4,0,'s','1',669171,2741),(130482,4,1,'s','1',669171,2742),(130483,4,2,'e','1',669171,2738),(130484,4,3,'s','1',669171,2743),(130485,5,0,'w','1',669171,2760),(130486,5,1,'w','1',669171,3011),(130487,5,2,'s','1',669171,2805),(130488,5,3,'n','1',669171,2717),(130489,6,0,'w','1',669171,2738),(130490,6,1,'w','1',669171,2734),(130491,6,2,'s','1',669171,2844),(130492,6,3,'n','1',669171,2819),(130493,7,0,'n','1',669171,2749),(130494,7,1,'n','1',669171,2719),(130495,7,2,'n','1',669171,2845),(130496,7,3,'n','1',669171,2846),(130497,8,0,'s','1',669171,2860),(130498,8,1,'w','1',669171,2765),(130499,8,2,'s','1',669171,2792),(130500,8,3,'s','1',669171,2768),(130501,9,0,'w','1',669171,2793),(130502,9,1,'w','1',669171,2750),(130503,9,2,'w','1',669171,2798),(130504,9,3,'n','1',669171,2774),(130505,10,0,'e','1',669171,2751),(130506,10,1,'e','1',669171,2750),(130507,10,2,'e','1',669171,2749),(130508,10,3,'e','1',669171,2734),(130509,11,0,'w','1',669171,2738),(130510,11,1,'e','1',669171,2734),(130511,11,2,'s','1',669171,2844),(130512,11,3,'w','1',669171,2754),(130513,12,0,'s','1',669171,2832),(130514,12,1,'w','1',669171,2738),(130515,12,2,'w','1',669171,2850),(130516,12,3,'s','1',669171,2734),(130517,13,0,'n','1',669171,2733),(130518,13,1,'e','1',669171,2948),(130519,13,2,'s','1',669171,2850),(130520,13,3,'x','0',669171,2883),(130521,13,4,'s','1',669171,2734),(130522,14,0,'n','1',669171,2733),(130523,14,1,'w','1',669171,2734),(130524,14,2,'n','1',669171,2749),(130525,14,3,'n','1',669171,2955),(130526,15,0,'n','1',669171,2736),(130527,15,1,'n','1',669171,2737),(130528,15,2,'e','1',669171,2825),(130529,15,3,'n','1',669171,2759),(130530,16,0,'n','1',669171,2905),(130531,16,1,'n','1',669171,2762),(130532,16,2,'e','1',669171,2789),(130533,16,3,'n','1',669171,2972),(130534,17,0,'n','1',669171,2986),(130535,17,1,'e','1',669171,2990),(130536,17,2,'e','1',669171,3006),(130537,17,3,'w','1',669171,2746),(130538,18,0,'e','1',669171,2770),(130539,18,1,'e','1',669171,2761),(130540,18,2,'n','1',669171,2759),(130541,18,3,'n','1',669171,2790),(130542,19,0,'n','1',669171,2905),(130543,19,1,'w','1',669171,2976),(130544,19,2,'w','1',669171,2958),(130545,19,3,'e','1',669171,2783),(130546,20,0,'e','1',669171,2762),(130547,20,1,'e','1',669171,2973),(130548,20,2,'e','1',669171,2824),(130549,20,3,'n','1',669171,2823),(130550,21,0,'w','1',669171,2746),(130551,21,1,'w','1',669171,2770),(130552,21,2,'w','1',669171,2958),(130553,21,3,'n','1',669171,2791),(130554,22,0,'n','1',669171,2861),(130555,22,1,'e','1',669171,2856),(130556,22,2,'e','1',669171,2777),(130557,22,3,'e','1',669171,2784),(130558,23,0,'n','1',669171,2882),(130559,23,1,'n','1',669171,2775),(130560,23,2,'n','1',669171,2851),(130561,23,3,'n','1',669171,2792),(130562,24,0,'n','1',669171,2902),(130563,24,1,'n','1',669171,2858),(130564,24,2,'n','1',669171,2771),(130565,24,3,'e','1',669171,2778),(130566,25,0,'e','1',669171,2795),(130567,25,1,'w','1',669171,2879),(130568,25,2,'e','1',669171,2762),(130569,26,0,'s','1',669171,2764),(130570,26,1,'w','1',669171,2765),(130571,26,2,'x','0',669171,2757),(130572,26,3,'w','1',669171,2767),(130573,26,4,'x','0',669171,2801),(130574,26,5,'w','1',669171,2864),(130575,27,0,'w','1',669171,2748),(130576,27,1,'s','1',669171,2768),(130577,27,2,'n','1',669171,2879),(130578,27,3,'x','0',669171,2880),(130579,27,4,'w','1',669171,2750),(130580,28,0,'e','1',669171,3007),(130581,28,1,'s','1',669171,3057),(130582,28,2,'s','1',669171,2853),(130583,28,3,'x','0',669171,2910),(130584,28,4,'w','1',669171,2864),(130585,29,0,'e','1',669171,2751),(130586,29,1,'e','1',669171,2750),(130587,29,2,'s','1',669171,2749),(130588,29,3,'e','1',669171,2732),(130589,30,0,'e','1',669171,2733),(130590,30,1,'s','1',669171,2842),(130591,30,2,'w','1',669171,2762),(130592,30,3,'n','1',669171,2878),(130593,31,0,'s','1',669171,2728),(130594,31,1,'s','1',669171,2813),(130595,31,2,'e','1',669171,2993),(130596,31,3,'s','1',669171,2992),(130597,32,0,'n','1',669171,2991),(130598,32,1,'n','1',669171,2834),(130599,32,2,'e','1',669171,2992),(130600,32,3,'n','1',669171,2887),(130601,33,0,'n','1',669171,2902),(130602,33,1,'n','1',669171,2778),(130603,33,2,'n','1',669171,2794),(130604,33,3,'n','1',669171,2857),(130605,34,0,'w','1',669171,2777),(130606,34,1,'n','1',669171,2778),(130607,34,2,'n','1',669171,2794),(130608,34,3,'w','1',669171,2795),(130609,35,0,'w','1',669171,2823),(130610,35,1,'n','1',669171,2811),(130611,35,2,'w','1',669171,2824),(130612,35,3,'x','0',669171,2762),(130613,35,4,'w','1',669171,2812),(130614,36,0,'w','1',669171,2973),(130615,36,1,'w','1',669171,2915),(130616,36,2,'w','1',669171,2739),(130617,36,3,'n','1',669171,2729),(130618,37,0,'n','1',669171,2797),(130619,37,1,'n','1',669171,2813),(130620,37,2,'n','1',669171,2789),(130621,37,3,'e','1',669171,2843),(130622,38,0,'n','1',669171,2969),(130623,38,1,'n','1',669171,2909),(130624,38,2,'w','1',669171,2784),(130625,38,3,'w','1',669171,2842),(130626,39,0,'e','1',669171,2900),(130627,39,1,'s','1',669171,2866),(130628,39,2,'s','1',669171,2862),(130629,39,3,'w','1',669171,2880),(130630,40,0,'n','1',669171,2900),(130631,40,1,'s','1',669171,2899),(130632,40,2,'w','1',669171,2767),(130633,40,3,'n','1',669171,2857),(130634,41,0,'n','1',669171,2777),(130635,41,1,'n','1',669171,2776),(130636,41,2,'n','1',669171,2774),(130637,41,3,'n','1',669171,2773),(130638,42,0,'e','1',669171,2859),(130639,42,1,'e','1',669171,2773),(130640,42,2,'n','1',669171,2852),(130641,42,3,'n','1',669171,2912),(130642,2,0,'n','1',669172,2913),(130643,2,1,'n','1',669172,2874),(130644,2,2,'n','1',669172,2731),(130645,2,3,'n','1',669172,2750),(130646,3,0,'e','1',669172,2768),(130647,3,1,'s','1',669172,2864),(130648,3,2,'s','1',669172,2860),(130649,3,3,'w','1',669172,2765),(130650,4,0,'s','1',669172,2768),(130651,4,1,'w','1',669172,2750),(130652,4,2,'e','1',669172,2751),(130653,4,3,'s','1',669172,2801),(130654,5,0,'w','1',669172,2750),(130655,5,1,'w','1',669172,2751),(130656,5,2,'e','1',669172,2871),(130657,5,3,'s','1',669172,2769),(130658,6,0,'w','1',669172,2751),(130659,6,1,'w','1',669172,2769),(130660,6,2,'n','1',669172,2871),(130661,6,3,'n','1',669172,2721),(130662,7,0,'n','1',669172,2815),(130663,7,1,'e','1',669172,2818),(130664,7,2,'e','1',669172,2872),(130665,7,3,'e','1',669172,2772),(130666,8,0,'n','1',669172,2977),(130667,8,1,'s','1',669172,2767),(130668,8,2,'e','1',669172,2983),(130669,8,3,'e','1',669172,2893),(130670,9,0,'w','1',669172,2860),(130671,9,1,'s','1',669172,2890),(130672,9,2,'n','1',669172,2717),(130673,9,3,'w','1',669172,2754),(130674,10,0,'n','1',669172,2719),(130675,10,1,'s','1',669172,2771),(130676,10,2,'s','1',669172,2845),(130677,10,3,'e','1',669172,2772),(130678,11,0,'s','1',669172,2768),(130679,11,1,'w','1',669172,2750),(130680,11,2,'e','1',669172,2751),(130681,11,3,'s','1',669172,2801),(130682,12,0,'w','1',669172,2750),(130683,12,1,'w','1',669172,2751),(130684,12,2,'e','1',669172,2871),(130685,12,3,'s','1',669172,2769),(130686,13,0,'w','1',669172,2751),(130687,13,1,'w','1',669172,2871),(130688,13,2,'e','1',669172,2980),(130689,13,3,'s','1',669172,2942),(130690,14,0,'w','1',669172,2769),(130691,14,1,'n','1',669172,2871),(130692,14,2,'n','1',669172,2882),(130693,14,3,'w','1',669172,2719),(130694,15,0,'s','1',669172,2977),(130695,15,1,'s','1',669172,2941),(130696,15,2,'w','1',669172,2871),(130697,15,3,'e','1',669172,2980),(130698,16,0,'n','1',669172,2736),(130699,16,1,'n','1',669172,2737),(130700,16,2,'e','1',669172,2871),(130701,16,3,'e','1',669172,2751),(130702,17,0,'e','1',669172,2939),(130703,17,1,'s','1',669172,2781),(130704,17,2,'n','1',669172,2750),(130705,17,3,'e','1',669172,2768),(130706,18,0,'w','1',669172,2765),(130707,18,1,'s','1',669172,2863),(130708,18,2,'s','1',669172,2833),(130709,18,3,'e','1',669172,2768),(130710,19,0,'s','1',669172,2887),(130711,19,1,'e','1',669172,2765),(130712,19,2,'w','1',669172,2744),(130713,19,3,'s','1',669172,2808),(130714,20,0,'w','1',669172,2808),(130715,20,1,'n','1',669172,2807),(130716,20,2,'n','1',669172,2998),(130717,20,3,'w','1',669172,2836),(130718,21,0,'s','1',669172,2788),(130719,21,1,'s','1',669172,2765),(130720,21,2,'e','1',669172,2749),(130721,21,3,'e','1',669172,2908),(130722,22,0,'n','1',669172,2807),(130723,22,1,'s','1',669172,2734),(130724,22,2,'e','1',669172,2994),(130725,22,3,'n','1',669172,2836),(130726,23,0,'e','1',669172,2733),(130727,23,1,'n','1',669172,2790),(130728,23,2,'s','1',669172,2842),(130729,23,3,'w','1',669172,2986),(130730,24,0,'e','1',669172,2817),(130731,24,1,'e','1',669172,2905),(130732,24,2,'n','1',669172,2971),(130733,24,3,'n','1',669172,2927),(130734,25,0,'e','1',669172,2797),(130735,25,1,'s','1',669172,3054),(130736,25,2,'e','1',669172,3055),(130737,25,3,'e','1',669172,3062),(130738,26,0,'n','1',669172,2719),(130739,26,1,'e','1',669172,2780),(130740,26,2,'e','1',669172,2829),(130741,26,3,'x','0',669172,2778),(130742,26,4,'s','1',669172,2845),(130743,27,0,'n','1',669172,2908),(130744,27,1,'n','1',669172,2770),(130745,27,2,'w','1',669172,2860),(130746,27,3,'n','1',669172,2748),(130747,28,0,'w','1',669172,2813),(130748,28,1,'n','1',669172,2814),(130749,28,2,'n','1',669172,2973),(130750,28,3,'w','1',669172,2817),(130751,29,0,'w','1',669172,2999),(130752,29,1,'s','1',669172,3062),(130753,29,2,'e','1',669172,2926),(130754,29,3,'n','1',669172,2882),(130755,30,0,'n','1',669172,2733),(130756,30,1,'n','1',669172,2803),(130757,30,2,'s','1',669172,2887),(130758,30,3,'n','1',669172,2782),(130759,31,0,'e','1',669172,2759),(130760,31,1,'e','1',669172,2734),(130761,31,2,'w','1',669172,2738),(130762,31,3,'s','1',669172,2837),(130763,32,0,'e','1',669172,2843),(130764,32,1,'e','1',669172,2734),(130765,32,2,'e','1',669172,2737),(130766,32,3,'s','1',669172,2738),(130767,33,0,'n','1',669172,2842),(130768,33,1,'n','1',669172,2736),(130769,33,2,'n','1',669172,2738),(130770,33,3,'n','1',669172,2838),(130771,34,0,'n','1',669172,2915),(130772,34,1,'w','1',669172,2741),(130773,34,2,'w','1',669172,2826),(130774,34,3,'n','1',669172,2744),(130775,35,0,'e','1',669172,2719),(130776,35,1,'e','1',669172,2725),(130777,35,2,'e','1',669172,2791),(130778,35,3,'s','1',669172,2735),(130779,36,0,'n','1',669172,2905),(130780,36,1,'n','1',669172,2903),(130781,36,2,'n','1',669172,2742),(130782,36,3,'e','1',669172,3005),(130783,37,0,'n','1',669172,2826),(130784,37,1,'w','1',669172,3004),(130785,37,2,'w','1',669172,2925),(130786,37,3,'s','1',669172,2926),(130787,38,0,'s','1',669172,3005),(130788,38,1,'n','1',669172,2744),(130789,38,2,'n','1',669172,2756),(130790,38,3,'n','1',669172,2775),(130791,39,0,'n','1',669172,2779),(130792,39,1,'n','1',669172,2780),(130793,39,2,'n','1',669172,2781),(130794,40,0,'w','1',669172,2851),(130795,40,1,'w','1',669172,3005),(130796,40,2,'e','1',669172,2935),(130797,40,3,'s','1',669172,2988),(130798,41,0,'n','1',669172,2860),(130799,41,1,'w','1',669172,2765),(130800,41,2,'n','1',669172,2785),(130801,41,3,'n','1',669172,2793),(130802,42,0,'w','1',669172,2817),(130803,42,1,'n','1',669172,2828),(130804,42,2,'e','1',669172,2735),(130805,42,3,'e','1',669172,2884),(130806,43,0,'w','1',669172,2801),(130807,43,1,'w','1',669172,2782),(130808,43,2,'n','1',669172,2882),(130809,43,3,'n','1',669172,2887),(130810,44,0,'s','1',669172,2736),(130811,44,1,'e','1',669172,2883),(130812,44,2,'n','1',669172,2789),(130813,44,3,'n','1',669172,2795),(130814,45,0,'e','1',669172,2768),(130815,45,1,'s','1',669172,2765),(130816,45,2,'w','1',669172,2787),(130817,45,3,'s','1',669172,2749),(130818,46,0,'n','1',669172,2732),(130819,46,1,'n','1',669172,2749),(130820,46,2,'w','1',669172,2765),(130821,46,3,'n','1',669172,2909),(130822,47,0,'s','1',669172,2768),(130823,47,1,'n','1',669172,2929),(130824,47,2,'s','1',669172,2879),(130825,47,3,'w','1',669172,2750),(130826,48,0,'e','1',669172,2886),(130827,48,1,'n','1',669172,2767),(130828,48,2,'n','1',669172,2801),(130829,48,3,'n','1',669172,2930),(130830,49,0,'n','1',669172,2931),(130831,49,1,'e','1',669172,2942),(130832,49,2,'e','1',669172,2862),(130833,49,3,'x','0',669172,2859),(130834,49,4,'s','1',669172,2982),(130835,50,0,'w','1',669172,3007),(130836,50,1,'e','1',669172,3008),(130837,50,2,'e','1',669172,2979),(130838,50,3,'w','1',669172,2905),(130839,51,0,'n','1',669172,2941),(130840,51,1,'s','1',669172,2931),(130841,51,2,'e','1',669172,2942),(130842,51,3,'w','1',669172,2858),(130843,52,0,'n','1',669172,2751),(130844,52,1,'e','1',669172,2885),(130845,52,2,'n','1',669172,2881),(130846,52,3,'n','1',669172,2962),(130847,53,0,'e','1',669172,2930),(130848,53,1,'e','1',669172,2938),(130849,53,2,'e','1',669172,2893),(130850,53,3,'n','1',669172,2859),(130851,54,0,'s','1',669172,3056),(130852,54,1,'w','1',669172,3026),(130853,54,2,'n','1',669172,2767),(130854,2,0,'n','1',669172,2913),(130855,2,1,'n','1',669172,2874),(130856,2,2,'n','1',669172,2731),(130857,2,3,'n','1',669172,2750),(130858,3,0,'e','1',669172,2768),(130859,3,1,'s','1',669172,2864),(130860,3,2,'s','1',669172,2860),(130861,3,3,'w','1',669172,2765),(130862,4,0,'s','1',669172,2768),(130863,4,1,'w','1',669172,2750),(130864,4,2,'e','1',669172,2751),(130865,4,3,'s','1',669172,2801),(130866,5,0,'w','1',669172,2750),(130867,5,1,'w','1',669172,2751),(130868,5,2,'e','1',669172,2871),(130869,5,3,'s','1',669172,2769),(130870,6,0,'w','1',669172,2751),(130871,6,1,'w','1',669172,2769),(130872,6,2,'n','1',669172,2871),(130873,6,3,'n','1',669172,2721),(130874,7,0,'n','1',669172,2815),(130875,7,1,'e','1',669172,2818),(130876,7,2,'e','1',669172,2872),(130877,7,3,'e','1',669172,2772),(130878,8,0,'n','1',669172,2977),(130879,8,1,'s','1',669172,2767),(130880,8,2,'e','1',669172,2983),(130881,8,3,'e','1',669172,2893),(130882,9,0,'w','1',669172,2860),(130883,9,1,'s','1',669172,2890),(130884,9,2,'n','1',669172,2717),(130885,9,3,'w','1',669172,2754),(130886,10,0,'n','1',669172,2719),(130887,10,1,'s','1',669172,2771),(130888,10,2,'s','1',669172,2845),(130889,10,3,'e','1',669172,2772),(130890,11,0,'s','1',669172,2768),(130891,11,1,'w','1',669172,2750),(130892,11,2,'e','1',669172,2751),(130893,11,3,'s','1',669172,2801),(130894,12,0,'w','1',669172,2750),(130895,12,1,'w','1',669172,2751),(130896,12,2,'e','1',669172,2871),(130897,12,3,'s','1',669172,2769),(130898,13,0,'w','1',669172,2751),(130899,13,1,'w','1',669172,2871),(130900,13,2,'e','1',669172,2980),(130901,13,3,'s','1',669172,2942),(130902,14,0,'w','1',669172,2769),(130903,14,1,'n','1',669172,2871),(130904,14,2,'n','1',669172,2882),(130905,14,3,'w','1',669172,2719),(130906,15,0,'s','1',669172,2977),(130907,15,1,'s','1',669172,2941),(130908,15,2,'w','1',669172,2871),(130909,15,3,'e','1',669172,2980),(130910,16,0,'n','1',669172,2736),(130911,16,1,'n','1',669172,2737),(130912,16,2,'e','1',669172,2871),(130913,16,3,'e','1',669172,2751),(130914,17,0,'e','1',669172,2939),(130915,17,1,'s','1',669172,2781),(130916,17,2,'n','1',669172,2750),(130917,17,3,'e','1',669172,2768),(130918,18,0,'w','1',669172,2765),(130919,18,1,'s','1',669172,2863),(130920,18,2,'s','1',669172,2833),(130921,18,3,'e','1',669172,2768),(130922,19,0,'s','1',669172,2887),(130923,19,1,'e','1',669172,2765),(130924,19,2,'w','1',669172,2744),(130925,19,3,'s','1',669172,2808),(130926,20,0,'w','1',669172,2808),(130927,20,1,'n','1',669172,2807),(130928,20,2,'n','1',669172,2998),(130929,20,3,'w','1',669172,2836),(130930,21,0,'s','1',669172,2788),(130931,21,1,'s','1',669172,2765),(130932,21,2,'e','1',669172,2749),(130933,21,3,'e','1',669172,2908),(130934,22,0,'n','1',669172,2807),(130935,22,1,'s','1',669172,2734),(130936,22,2,'e','1',669172,2994),(130937,22,3,'n','1',669172,2836),(130938,23,0,'e','1',669172,2733),(130939,23,1,'n','1',669172,2790),(130940,23,2,'s','1',669172,2842),(130941,23,3,'w','1',669172,2986),(130942,24,0,'e','1',669172,2817),(130943,24,1,'e','1',669172,2905),(130944,24,2,'n','1',669172,2971),(130945,24,3,'n','1',669172,2927),(130946,25,0,'e','1',669172,2797),(130947,25,1,'s','1',669172,3054),(130948,25,2,'e','1',669172,3055),(130949,25,3,'e','1',669172,3062),(130950,26,0,'n','1',669172,2719),(130951,26,1,'e','1',669172,2780),(130952,26,2,'e','1',669172,2829),(130953,26,3,'x','0',669172,2778),(130954,26,4,'s','1',669172,2845),(130955,27,0,'n','1',669172,2908),(130956,27,1,'n','1',669172,2770),(130957,27,2,'w','1',669172,2860),(130958,27,3,'n','1',669172,2748),(130959,28,0,'w','1',669172,2813),(130960,28,1,'n','1',669172,2814),(130961,28,2,'n','1',669172,2973),(130962,28,3,'w','1',669172,2817),(130963,29,0,'w','1',669172,2999),(130964,29,1,'s','1',669172,3062),(130965,29,2,'e','1',669172,2926),(130966,29,3,'n','1',669172,2882),(130967,30,0,'n','1',669172,2733),(130968,30,1,'n','1',669172,2803),(130969,30,2,'s','1',669172,2887),(130970,30,3,'n','1',669172,2782),(130971,31,0,'e','1',669172,2759),(130972,31,1,'e','1',669172,2734),(130973,31,2,'w','1',669172,2738),(130974,31,3,'s','1',669172,2837),(130975,32,0,'e','1',669172,2843),(130976,32,1,'e','1',669172,2734),(130977,32,2,'e','1',669172,2737),(130978,32,3,'s','1',669172,2738),(130979,33,0,'n','1',669172,2842),(130980,33,1,'n','1',669172,2736),(130981,33,2,'n','1',669172,2738),(130982,33,3,'n','1',669172,2838),(130983,34,0,'n','1',669172,2915),(130984,34,1,'w','1',669172,2741),(130985,34,2,'w','1',669172,2826),(130986,34,3,'n','1',669172,2744),(130987,35,0,'e','1',669172,2719),(130988,35,1,'e','1',669172,2725),(130989,35,2,'e','1',669172,2791),(130990,35,3,'s','1',669172,2735),(130991,36,0,'n','1',669172,2905),(130992,36,1,'n','1',669172,2903),(130993,36,2,'n','1',669172,2742),(130994,36,3,'e','1',669172,3005),(130995,37,0,'n','1',669172,2826),(130996,37,1,'w','1',669172,3004),(130997,37,2,'w','1',669172,2925),(130998,37,3,'s','1',669172,2926),(130999,38,0,'s','1',669172,3005),(131000,38,1,'n','1',669172,2744),(131001,38,2,'n','1',669172,2756),(131002,38,3,'n','1',669172,2775),(131003,39,0,'n','1',669172,2779),(131004,39,1,'n','1',669172,2780),(131005,39,2,'n','1',669172,2781),(131006,40,0,'w','1',669172,2851),(131007,40,1,'w','1',669172,3005),(131008,40,2,'e','1',669172,2935),(131009,40,3,'s','1',669172,2988),(131010,41,0,'n','1',669172,2860),(131011,41,1,'w','1',669172,2765),(131012,41,2,'n','1',669172,2785),(131013,41,3,'n','1',669172,2793),(131014,42,0,'w','1',669172,2817),(131015,42,1,'n','1',669172,2828),(131016,42,2,'e','1',669172,2735),(131017,42,3,'e','1',669172,2884),(131018,43,0,'w','1',669172,2801),(131019,43,1,'w','1',669172,2782),(131020,43,2,'n','1',669172,2882),(131021,43,3,'n','1',669172,2887),(131022,44,0,'s','1',669172,2736),(131023,44,1,'e','1',669172,2883),(131024,44,2,'n','1',669172,2789),(131025,44,3,'n','1',669172,2795),(131026,45,0,'e','1',669172,2768),(131027,45,1,'s','1',669172,2765),(131028,45,2,'w','1',669172,2787),(131029,45,3,'s','1',669172,2749),(131030,46,0,'n','1',669172,2732),(131031,46,1,'n','1',669172,2749),(131032,46,2,'w','1',669172,2765),(131033,46,3,'n','1',669172,2909),(131034,47,0,'s','1',669172,2768),(131035,47,1,'n','1',669172,2929),(131036,47,2,'s','1',669172,2879),(131037,47,3,'w','1',669172,2750),(131038,48,0,'e','1',669172,2886),(131039,48,1,'n','1',669172,2767),(131040,48,2,'n','1',669172,2801),(131041,48,3,'n','1',669172,2930),(131042,49,0,'n','1',669172,2931),(131043,49,1,'e','1',669172,2942),(131044,49,2,'e','1',669172,2862),(131045,49,3,'x','0',669172,2859),(131046,49,4,'s','1',669172,2982),(131047,50,0,'w','1',669172,3007),(131048,50,1,'e','1',669172,3008),(131049,50,2,'e','1',669172,2979),(131050,50,3,'w','1',669172,2905),(131051,51,0,'n','1',669172,2941),(131052,51,1,'s','1',669172,2931),(131053,51,2,'e','1',669172,2942),(131054,51,3,'w','1',669172,2858),(131055,52,0,'n','1',669172,2751),(131056,52,1,'e','1',669172,2885),(131057,52,2,'n','1',669172,2881),(131058,52,3,'n','1',669172,2962),(131059,53,0,'e','1',669172,2930),(131060,53,1,'e','1',669172,2938),(131061,53,2,'e','1',669172,2893),(131062,53,3,'n','1',669172,2859),(131063,54,0,'s','1',669172,3056),(131064,54,1,'w','1',669172,3026),(131065,54,2,'n','1',669172,2767),(131066,2,0,'n','1',669173,2913),(131067,2,1,'n','1',669173,2874),(131068,2,2,'n','1',669173,2731),(131069,2,3,'n','1',669173,2750),(131070,3,0,'n','1',669173,2717),(131071,3,1,'n','1',669173,2719),(131072,3,2,'n','1',669173,2845),(131073,3,3,'n','1',669173,2846),(131074,4,0,'e','1',669173,2769),(131075,4,1,'s','1',669173,2766),(131076,4,2,'s','1',669173,2767),(131077,4,3,'x','0',669173,2859),(131078,4,4,'e','1',669173,2854),(131079,5,0,'e','1',669173,2876),(131080,5,1,'e','1',669173,2747),(131081,5,2,'e','1',669173,2832),(131082,5,3,'s','1',669173,2804),(131083,6,0,'s','1',669173,2849),(131084,6,1,'s','1',669173,2768),(131085,6,2,'e','1',669173,2750),(131086,6,3,'n','1',669173,2870),(131087,7,0,'e','1',669173,2749),(131088,7,1,'e','1',669173,2734),(131089,7,2,'n','1',669173,2739),(131090,7,3,'e','1',669173,2815),(131091,8,0,'n','1',669173,2721),(131092,8,1,'n','1',669173,2754),(131093,8,2,'e','1',669173,2736),(131094,8,3,'s','1',669173,2849),(131095,9,0,'s','1',669173,2738),(131096,9,1,'s','1',669173,2806),(131097,9,2,'s','1',669173,2820),(131098,9,3,'w','1',669173,2883),(131099,10,0,'n','1',669173,2842),(131100,10,1,'s','1',669173,2738),(131101,10,2,'s','1',669173,2837),(131102,10,3,'e','1',669173,2884),(131103,11,0,'w','1',669173,2842),(131104,11,1,'w','1',669173,2915),(131105,11,2,'s','1',669173,2986),(131106,11,3,'w','1',669173,2883),(131107,12,0,'n','1',669173,2884),(131108,12,1,'n','1',669173,3022),(131109,12,2,'e','1',669173,2986),(131110,12,3,'x','0',669173,2760),(131111,12,4,'s','1',669173,2948),(131112,13,0,'e','1',669173,2736),(131113,13,1,'n','1',669173,2733),(131114,13,2,'w','1',669173,2734),(131115,13,3,'n','1',669173,2927),(131116,14,0,'n','1',669173,2964),(131117,14,1,'e','1',669173,2872),(131118,14,2,'n','1',669173,2882),(131119,14,3,'w','1',669173,2858),(131120,15,0,'e','1',669173,2948),(131121,15,1,'e','1',669173,2850),(131122,15,2,'s','1',669173,2849),(131123,15,3,'n','1',669173,2749),(131124,16,0,'n','1',669173,2851),(131125,16,1,'n','1',669173,2792),(131126,16,2,'n','1',669173,2860),(131127,16,3,'w','1',669173,2875),(131128,17,0,'w','1',669173,2767),(131129,17,1,'w','1',669173,2864),(131130,17,2,'w','1',669173,2765),(131131,17,3,'w','1',669173,2754),(131132,18,0,'n','1',669173,2736),(131133,18,1,'s','1',669173,2850),(131134,18,2,'e','1',669173,2737),(131135,18,3,'e','1',669173,2883),(131136,19,0,'n','1',669173,2772),(131137,19,1,'n','1',669173,2739),(131138,19,2,'n','1',669173,2888),(131139,19,3,'n','1',669173,2834),(131140,20,0,'w','1',669173,2821),(131141,20,1,'n','1',669173,2820),(131142,20,2,'w','1',669173,2843),(131143,20,3,'w','1',669173,2921),(131144,21,0,'s','1',669173,2759),(131145,21,1,'n','1',669173,2797),(131146,21,2,'n','1',669173,2789),(131147,21,3,'w','1',669173,2746),(131148,22,0,'e','1',669173,2798),(131149,22,1,'n','1',669173,2746),(131150,22,2,'n','1',669173,2755),(131151,22,3,'w','1',669173,2758),(131152,23,0,'e','1',669173,2739),(131153,23,1,'w','1',669173,2962),(131154,23,2,'s','1',669173,2887),(131155,23,3,'w','1',669173,2737),(131156,24,0,'n','1',669173,2795),(131157,24,1,'s','1',669173,2915),(131158,24,2,'w','1',669173,2963),(131159,24,3,'w','1',669173,2870),(131160,25,0,'e','1',669173,2966),(131161,25,1,'w','1',669173,2905),(131162,25,2,'s','1',669173,2955),(131163,25,3,'w','1',669173,2838),(131164,26,0,'e','1',669173,2927),(131165,26,1,'e','1',669173,2798),(131166,26,2,'s','1',669173,2970),(131167,26,3,'w','1',669173,2755),(131168,27,0,'w','1',669173,3016),(131169,27,1,'n','1',669173,2779),(131170,27,2,'w','1',669173,2822),(131171,27,3,'n','1',669173,2724),(131172,28,0,'w','1',669173,2975),(131173,28,1,'w','1',669173,2903),(131174,28,2,'w','1',669173,2797),(131175,28,3,'w','1',669173,2748),(131176,29,0,'w','1',669173,2882),(131177,29,1,'s','1',669173,2753),(131178,29,2,'w','1',669173,2902),(131179,29,3,'s','1',669173,2768),(131180,30,0,'s','1',669173,2750),(131181,30,1,'s','1',669173,2731),(131182,30,2,'w','1',669173,2901),(131183,30,3,'w','1',669173,2903),(131184,2,0,'n','1',669173,2913),(131185,2,1,'n','1',669173,2874),(131186,2,2,'n','1',669173,2731),(131187,2,3,'n','1',669173,2750),(131188,3,0,'n','1',669173,2717),(131189,3,1,'n','1',669173,2719),(131190,3,2,'n','1',669173,2845),(131191,3,3,'n','1',669173,2846),(131192,4,0,'e','1',669173,2769),(131193,4,1,'s','1',669173,2766),(131194,4,2,'s','1',669173,2767),(131195,4,3,'x','0',669173,2859),(131196,4,4,'e','1',669173,2854),(131197,5,0,'e','1',669173,2876),(131198,5,1,'e','1',669173,2747),(131199,5,2,'e','1',669173,2832),(131200,5,3,'s','1',669173,2804),(131201,6,0,'s','1',669173,2849),(131202,6,1,'s','1',669173,2768),(131203,6,2,'e','1',669173,2750),(131204,6,3,'n','1',669173,2870),(131205,7,0,'e','1',669173,2749),(131206,7,1,'e','1',669173,2734),(131207,7,2,'n','1',669173,2739),(131208,7,3,'e','1',669173,2815),(131209,8,0,'n','1',669173,2721),(131210,8,1,'n','1',669173,2754),(131211,8,2,'e','1',669173,2736),(131212,8,3,'s','1',669173,2849),(131213,9,0,'s','1',669173,2738),(131214,9,1,'s','1',669173,2806),(131215,9,2,'s','1',669173,2820),(131216,9,3,'w','1',669173,2883),(131217,10,0,'n','1',669173,2842),(131218,10,1,'s','1',669173,2738),(131219,10,2,'s','1',669173,2837),(131220,10,3,'e','1',669173,2884),(131221,11,0,'w','1',669173,2842),(131222,11,1,'w','1',669173,2915),(131223,11,2,'s','1',669173,2986),(131224,11,3,'w','1',669173,2883),(131225,12,0,'n','1',669173,2884),(131226,12,1,'n','1',669173,3022),(131227,12,2,'e','1',669173,2986),(131228,12,3,'x','0',669173,2760),(131229,12,4,'s','1',669173,2948),(131230,13,0,'e','1',669173,2736),(131231,13,1,'n','1',669173,2733),(131232,13,2,'w','1',669173,2734),(131233,13,3,'n','1',669173,2927),(131234,14,0,'n','1',669173,2964),(131235,14,1,'e','1',669173,2872),(131236,14,2,'n','1',669173,2882),(131237,14,3,'w','1',669173,2858),(131238,15,0,'e','1',669173,2948),(131239,15,1,'e','1',669173,2850),(131240,15,2,'s','1',669173,2849),(131241,15,3,'n','1',669173,2749),(131242,16,0,'n','1',669173,2851),(131243,16,1,'n','1',669173,2792),(131244,16,2,'n','1',669173,2860),(131245,16,3,'w','1',669173,2875),(131246,17,0,'w','1',669173,2767),(131247,17,1,'w','1',669173,2864),(131248,17,2,'w','1',669173,2765),(131249,17,3,'w','1',669173,2754),(131250,18,0,'n','1',669173,2736),(131251,18,1,'s','1',669173,2850),(131252,18,2,'e','1',669173,2737),(131253,18,3,'e','1',669173,2883),(131254,19,0,'n','1',669173,2772),(131255,19,1,'n','1',669173,2739),(131256,19,2,'n','1',669173,2888),(131257,19,3,'n','1',669173,2834),(131258,20,0,'w','1',669173,2821),(131259,20,1,'n','1',669173,2820),(131260,20,2,'w','1',669173,2843),(131261,20,3,'w','1',669173,2921),(131262,21,0,'s','1',669173,2759),(131263,21,1,'n','1',669173,2797),(131264,21,2,'n','1',669173,2789),(131265,21,3,'w','1',669173,2746),(131266,22,0,'e','1',669173,2798),(131267,22,1,'n','1',669173,2746),(131268,22,2,'n','1',669173,2755),(131269,22,3,'w','1',669173,2758),(131270,23,0,'e','1',669173,2739),(131271,23,1,'w','1',669173,2962),(131272,23,2,'s','1',669173,2887),(131273,23,3,'w','1',669173,2737),(131274,24,0,'n','1',669173,2795),(131275,24,1,'s','1',669173,2915),(131276,24,2,'w','1',669173,2963),(131277,24,3,'w','1',669173,2870),(131278,25,0,'e','1',669173,2966),(131279,25,1,'w','1',669173,2905),(131280,25,2,'s','1',669173,2955),(131281,25,3,'w','1',669173,2838),(131282,26,0,'e','1',669173,2927),(131283,26,1,'e','1',669173,2798),(131284,26,2,'s','1',669173,2970),(131285,26,3,'w','1',669173,2755),(131286,27,0,'w','1',669173,3016),(131287,27,1,'n','1',669173,2779),(131288,27,2,'w','1',669173,2822),(131289,27,3,'n','1',669173,2724),(131290,28,0,'w','1',669173,2975),(131291,28,1,'w','1',669173,2903),(131292,28,2,'w','1',669173,2797),(131293,28,3,'w','1',669173,2748),(131294,29,0,'w','1',669173,2882),(131295,29,1,'s','1',669173,2753),(131296,29,2,'w','1',669173,2902),(131297,29,3,'s','1',669173,2768),(131298,30,0,'s','1',669173,2750),(131299,30,1,'s','1',669173,2731),(131300,30,2,'w','1',669173,2901),(131301,30,3,'w','1',669173,2903),(131302,2,0,'n','1',669174,2913),(131303,2,1,'n','1',669174,2874),(131304,2,2,'n','1',669174,2731),(131305,2,3,'n','1',669174,2750),(131306,3,0,'n','1',669174,2717),(131307,3,1,'n','1',669174,2719),(131308,3,2,'n','1',669174,2845),(131309,3,3,'n','1',669174,2846),(131310,4,0,'e','1',669174,2769),(131311,4,1,'s','1',669174,2766),(131312,4,2,'s','1',669174,2767),(131313,4,3,'x','0',669174,2859),(131314,4,4,'e','1',669174,2854),(131315,5,0,'s','1',669174,2876),(131316,5,1,'e','1',669174,2954),(131317,5,2,'e','1',669174,2948),(131318,5,3,'s','1',669174,2850),(131319,6,0,'e','1',669174,2883),(131320,6,1,'e','1',669174,2875),(131321,6,2,'w','1',669174,2919),(131322,6,3,'s','1',669174,2820),(131323,7,0,'n','1',669174,2875),(131324,7,1,'w','1',669174,2754),(131325,7,2,'w','1',669174,2736),(131326,7,3,'x','0',669174,2760),(131327,7,4,'s','1',669174,2849),(131328,8,0,'w','1',669174,2875),(131329,8,1,'n','1',669174,2915),(131330,8,2,'e','1',669174,2815),(131331,8,3,'n','1',669174,2721),(131332,9,0,'n','1',669174,2870),(131333,9,1,'n','1',669174,2786),(131334,9,2,'s','1',669174,2850),(131335,9,3,'s','1',669174,2787),(131336,10,0,'n','1',669174,2786),(131337,10,1,'s','1',669174,2850),(131338,10,2,'s','1',669174,2787),(131339,10,3,'n','1',669174,2888),(131340,11,0,'n','1',669174,2786),(131341,11,1,'s','1',669174,2850),(131342,11,2,'s','1',669174,2787),(131343,11,3,'n','1',669174,2927),(131344,12,0,'n','1',669174,2786),(131345,12,1,'s','1',669174,2850),(131346,12,2,'s','1',669174,2787),(131347,12,3,'n','1',669174,2754),(131348,13,0,'n','1',669174,2797),(131349,13,1,'e','1',669174,2786),(131350,13,2,'e','1',669174,2850),(131351,13,3,'s','1',669174,2849),(131352,14,0,'n','1',669174,2834),(131353,14,1,'n','1',669174,2820),(131354,14,2,'e','1',669174,2768),(131355,14,3,'n','1',669174,2739),(131356,15,0,'n','1',669174,2905),(131357,15,1,'n','1',669174,2903),(131358,15,2,'n','1',669174,2802),(131359,15,3,'e','1',669174,2759),(131360,16,0,'n','1',669174,2875),(131361,16,1,'n','1',669174,2849),(131362,16,2,'e','1',669174,2806),(131363,16,3,'n','1',669174,2804),(131364,17,0,'s','1',669174,2799),(131365,17,1,'s','1',669174,2826),(131366,17,2,'n','1',669174,2838),(131367,17,3,'n','1',669174,2839),(131368,18,0,'n','1',669174,2953),(131369,18,1,'n','1',669174,2901),(131370,18,2,'n','1',669174,2817),(131371,18,3,'n','1',669174,2824),(131372,19,0,'e','1',669174,2775),(131373,19,1,'n','1',669174,2964),(131374,19,2,'n','1',669174,2882),(131375,19,3,'w','1',669174,2823),(131376,20,0,'s','1',669174,2921),(131377,20,1,'e','1',669174,2889),(131378,20,2,'n','1',669174,2729),(131379,20,3,'n','1',669174,2824),(131380,21,0,'s','1',669174,2820),(131381,21,1,'e','1',669174,2729),(131382,21,2,'n','1',669174,2762),(131383,21,3,'e','1',669174,2761),(131384,22,0,'n','1',669174,2786),(131385,22,1,'n','1',669174,2789),(131386,22,2,'n','1',669174,2872),(131387,22,3,'n','1',669174,2887),(131388,23,0,'s','1',669174,2773),(131389,23,1,'w','1',669174,2765),(131390,23,2,'n','1',669174,2787),(131391,23,3,'n','1',669174,2788),(131392,24,0,'e','1',669174,2909),(131393,24,1,'e','1',669174,2950),(131394,24,2,'w','1',669174,2877),(131395,24,3,'w','1',669174,2754),(131396,25,0,'s','1',669174,2774),(131397,25,1,'s','1',669174,2768),(131398,25,2,'n','1',669174,2750),(131399,25,3,'e','1',669174,2779),(131400,26,0,'e','1',669174,2774),(131401,26,1,'s','1',669174,2768),(131402,26,2,'w','1',669174,2750),(131403,26,3,'n','1',669174,2990),(131404,27,0,'w','1',669174,2751),(131405,27,1,'s','1',669174,2981),(131406,27,2,'n','1',669174,2931),(131407,27,3,'n','1',669174,2871),(131408,28,0,'n','1',669174,2800),(131409,28,1,'w','1',669174,2736),(131410,28,2,'n','1',669174,2760),(131411,28,3,'n','1',669174,2740),(131412,29,0,'e','1',669174,2796),(131413,29,1,'e','1',669174,2906),(131414,29,2,'e','1',669174,2902),(131415,29,3,'n','1',669174,2858),(131416,30,0,'s','1',669174,2761),(131417,30,1,'x','0',669174,2762),(131418,30,2,'e','1',669174,2856),(131419,30,3,'e','1',669174,2968),(131420,30,4,'e','1',669174,2877),(131421,31,0,'n','1',669174,2795),(131422,31,1,'n','1',669174,2796),(131423,31,2,'n','1',669174,2791),(131424,31,3,'n','1',669174,2777),(131425,32,0,'w','1',669174,2771),(131426,32,1,'s','1',669174,2877),(131427,32,2,'s','1',669174,2840),(131428,32,3,'w','1',669174,2822),(131429,33,0,'s','1',669174,2977),(131430,33,1,'e','1',669174,2871),(131431,33,2,'w','1',669174,2897),(131432,33,3,'n','1',669174,2779),(131433,34,0,'s','1',669174,2756),(131434,34,1,'e','1',669174,2798),(131435,34,2,'e','1',669174,2774),(131436,34,3,'e','1',669174,2751),(131437,35,0,'s','1',669174,2954),(131438,35,1,'s','1',669174,2750),(131439,35,2,'w','1',669174,2735),(131440,35,3,'x','0',669174,2725),(131441,35,4,'s','1',669174,2731),(131442,36,0,'n','1',669174,2872),(131443,36,1,'n','1',669174,2877),(131444,36,2,'n','1',669174,2874),(131445,36,3,'w','1',669174,2794),(131446,37,0,'n','1',669174,2758),(131447,37,1,'n','1',669174,2740),(131448,37,2,'s','1',669174,2932),(131449,37,3,'e','1',669174,2878),(131450,38,0,'s','1',669174,2946),(131451,38,1,'x','0',669174,2950),(131452,38,2,'w','1',669174,2731),(131453,38,3,'s','1',669174,2774),(131454,38,4,'e','1',669174,2879),(131455,39,0,'w','1',669174,2748),(131456,39,1,'s','1',669174,2860),(131457,39,2,'x','0',669174,2801),(131458,39,3,'n','1',669174,2792),(131459,39,4,'e','1',669174,2879),(131460,40,0,'n','1',669174,2831),(131461,40,1,'w','1',669174,2840),(131462,40,2,'n','1',669174,2941),(131463,40,3,'n','1',669174,2942),(131464,41,0,'w','1',669174,2902),(131465,41,1,'n','1',669174,2730),(131466,41,2,'w','1',669174,2751),(131467,41,3,'n','1',669174,2871),(131468,42,0,'w','1',669174,2977),(131469,42,1,'n','1',669174,2943),(131470,2,0,'n','1',669174,2913),(131471,2,1,'n','1',669174,2874),(131472,2,2,'n','1',669174,2731),(131473,2,3,'n','1',669174,2750),(131474,3,0,'n','1',669174,2717),(131475,3,1,'n','1',669174,2719),(131476,3,2,'n','1',669174,2845),(131477,3,3,'n','1',669174,2846),(131478,4,0,'e','1',669174,2769),(131479,4,1,'s','1',669174,2766),(131480,4,2,'s','1',669174,2767),(131481,4,3,'x','0',669174,2859),(131482,4,4,'e','1',669174,2854),(131483,5,0,'s','1',669174,2876),(131484,5,1,'e','1',669174,2954),(131485,5,2,'e','1',669174,2948),(131486,5,3,'s','1',669174,2850),(131487,6,0,'e','1',669174,2883),(131488,6,1,'e','1',669174,2875),(131489,6,2,'w','1',669174,2919),(131490,6,3,'s','1',669174,2820),(131491,7,0,'n','1',669174,2875),(131492,7,1,'w','1',669174,2754),(131493,7,2,'w','1',669174,2736),(131494,7,3,'x','0',669174,2760),(131495,7,4,'s','1',669174,2849),(131496,8,0,'w','1',669174,2875),(131497,8,1,'n','1',669174,2915),(131498,8,2,'e','1',669174,2815),(131499,8,3,'n','1',669174,2721),(131500,9,0,'n','1',669174,2870),(131501,9,1,'n','1',669174,2786),(131502,9,2,'s','1',669174,2850),(131503,9,3,'s','1',669174,2787),(131504,10,0,'n','1',669174,2786),(131505,10,1,'s','1',669174,2850),(131506,10,2,'s','1',669174,2787),(131507,10,3,'n','1',669174,2888),(131508,11,0,'n','1',669174,2786),(131509,11,1,'s','1',669174,2850),(131510,11,2,'s','1',669174,2787),(131511,11,3,'n','1',669174,2927),(131512,12,0,'n','1',669174,2786),(131513,12,1,'s','1',669174,2850),(131514,12,2,'s','1',669174,2787),(131515,12,3,'n','1',669174,2754),(131516,13,0,'n','1',669174,2797),(131517,13,1,'e','1',669174,2786),(131518,13,2,'e','1',669174,2850),(131519,13,3,'s','1',669174,2849),(131520,14,0,'n','1',669174,2834),(131521,14,1,'n','1',669174,2820),(131522,14,2,'e','1',669174,2768),(131523,14,3,'n','1',669174,2739),(131524,15,0,'n','1',669174,2905),(131525,15,1,'n','1',669174,2903),(131526,15,2,'n','1',669174,2802),(131527,15,3,'e','1',669174,2759),(131528,16,0,'n','1',669174,2875),(131529,16,1,'n','1',669174,2849),(131530,16,2,'e','1',669174,2806),(131531,16,3,'n','1',669174,2804),(131532,17,0,'s','1',669174,2799),(131533,17,1,'s','1',669174,2826),(131534,17,2,'n','1',669174,2838),(131535,17,3,'n','1',669174,2839),(131536,18,0,'n','1',669174,2953),(131537,18,1,'n','1',669174,2901),(131538,18,2,'n','1',669174,2817),(131539,18,3,'n','1',669174,2824),(131540,19,0,'e','1',669174,2775),(131541,19,1,'n','1',669174,2964),(131542,19,2,'n','1',669174,2882),(131543,19,3,'w','1',669174,2823),(131544,20,0,'s','1',669174,2921),(131545,20,1,'e','1',669174,2889),(131546,20,2,'n','1',669174,2729),(131547,20,3,'n','1',669174,2824),(131548,21,0,'s','1',669174,2820),(131549,21,1,'e','1',669174,2729),(131550,21,2,'n','1',669174,2762),(131551,21,3,'e','1',669174,2761),(131552,22,0,'n','1',669174,2786),(131553,22,1,'n','1',669174,2789),(131554,22,2,'n','1',669174,2872),(131555,22,3,'n','1',669174,2887),(131556,23,0,'s','1',669174,2773),(131557,23,1,'w','1',669174,2765),(131558,23,2,'n','1',669174,2787),(131559,23,3,'n','1',669174,2788),(131560,24,0,'e','1',669174,2909),(131561,24,1,'e','1',669174,2950),(131562,24,2,'w','1',669174,2877),(131563,24,3,'w','1',669174,2754),(131564,25,0,'s','1',669174,2774),(131565,25,1,'s','1',669174,2768),(131566,25,2,'n','1',669174,2750),(131567,25,3,'e','1',669174,2779),(131568,26,0,'e','1',669174,2774),(131569,26,1,'s','1',669174,2768),(131570,26,2,'w','1',669174,2750),(131571,26,3,'n','1',669174,2990),(131572,27,0,'w','1',669174,2751),(131573,27,1,'s','1',669174,2981),(131574,27,2,'n','1',669174,2931),(131575,27,3,'n','1',669174,2871),(131576,28,0,'n','1',669174,2800),(131577,28,1,'w','1',669174,2736),(131578,28,2,'n','1',669174,2760),(131579,28,3,'n','1',669174,2740),(131580,29,0,'e','1',669174,2796),(131581,29,1,'e','1',669174,2906),(131582,29,2,'e','1',669174,2902),(131583,29,3,'n','1',669174,2858),(131584,30,0,'s','1',669174,2761),(131585,30,1,'x','0',669174,2762),(131586,30,2,'e','1',669174,2856),(131587,30,3,'e','1',669174,2968),(131588,30,4,'e','1',669174,2877),(131589,31,0,'n','1',669174,2795),(131590,31,1,'n','1',669174,2796),(131591,31,2,'n','1',669174,2791),(131592,31,3,'n','1',669174,2777),(131593,32,0,'w','1',669174,2771),(131594,32,1,'s','1',669174,2877),(131595,32,2,'s','1',669174,2840),(131596,32,3,'w','1',669174,2822),(131597,33,0,'s','1',669174,2977),(131598,33,1,'e','1',669174,2871),(131599,33,2,'w','1',669174,2897),(131600,33,3,'n','1',669174,2779),(131601,34,0,'s','1',669174,2756),(131602,34,1,'e','1',669174,2798),(131603,34,2,'e','1',669174,2774),(131604,34,3,'e','1',669174,2751),(131605,35,0,'s','1',669174,2954),(131606,35,1,'s','1',669174,2750),(131607,35,2,'w','1',669174,2735),(131608,35,3,'x','0',669174,2725),(131609,35,4,'s','1',669174,2731),(131610,36,0,'n','1',669174,2872),(131611,36,1,'n','1',669174,2877),(131612,36,2,'n','1',669174,2874),(131613,36,3,'w','1',669174,2794),(131614,37,0,'n','1',669174,2758),(131615,37,1,'n','1',669174,2740),(131616,37,2,'s','1',669174,2932),(131617,37,3,'e','1',669174,2878),(131618,38,0,'s','1',669174,2946),(131619,38,1,'x','0',669174,2950),(131620,38,2,'w','1',669174,2731),(131621,38,3,'s','1',669174,2774),(131622,38,4,'e','1',669174,2879),(131623,39,0,'w','1',669174,2748),(131624,39,1,'s','1',669174,2860),(131625,39,2,'x','0',669174,2801),(131626,39,3,'n','1',669174,2792),(131627,39,4,'e','1',669174,2879),(131628,40,0,'n','1',669174,2831),(131629,40,1,'w','1',669174,2840),(131630,40,2,'n','1',669174,2941),(131631,40,3,'n','1',669174,2942),(131632,41,0,'w','1',669174,2902),(131633,41,1,'n','1',669174,2730),(131634,41,2,'w','1',669174,2751),(131635,41,3,'n','1',669174,2871),(131636,42,0,'w','1',669174,2977),(131637,42,1,'n','1',669174,2943),(131638,2,0,'n','1',669175,2815),(131639,2,1,'n','1',669175,3051),(131640,2,2,'e','1',669175,2818),(131641,2,3,'n','1',669175,3052),(131642,3,0,'n','1',669175,2872),(131643,3,1,'n','1',669175,2877),(131644,3,2,'n','1',669175,2878),(131645,3,3,'e','1',669175,3033),(131646,4,0,'e','1',669175,2726),(131647,4,1,'n','1',669175,2727),(131648,4,2,'n','1',669175,2730),(131649,4,3,'n','1',669175,2868),(131650,5,0,'n','1',669175,2834),(131651,5,1,'n','1',669175,2722),(131652,5,2,'n','1',669175,2956),(131653,5,3,'n','1',669175,2822),(131654,6,0,'w','1',669175,2875),(131655,6,1,'w','1',669175,2883),(131656,6,2,'w','1',669175,2884),(131657,6,3,'w','1',669175,2735),(131658,7,0,'w','1',669175,2829),(131659,7,1,'w','1',669175,2725),(131660,7,2,'n','1',669175,2719),(131661,7,3,'n','1',669175,2780),(131662,8,0,'e','1',669175,2751),(131663,8,1,'e','1',669175,2750),(131664,8,2,'n','1',669175,2863),(131665,8,3,'n','1',669175,2970),(131666,9,0,'e','1',669175,2749),(131667,9,1,'e','1',669175,2734),(131668,9,2,'w','1',669175,2738),(131669,9,3,'s','1',669175,2743),(131670,10,0,'n','1',669175,2734),(131671,10,1,'w','1',669175,2826),(131672,10,2,'n','1',669175,2744),(131673,10,3,'n','1',669175,2958),(131674,11,0,'n','1',669175,2999),(131675,11,1,'e','1',669175,3005),(131676,11,2,'s','1',669175,2743),(131677,11,3,'s','1',669175,3004),(131678,12,0,'s','1',669175,2804),(131679,12,1,'s','1',669175,2741),(131680,12,2,'s','1',669175,2845),(131681,12,3,'w','1',669175,2721),(131682,13,0,'e','1',669175,2849),(131683,13,1,'s','1',669175,2738),(131684,13,2,'n','1',669175,2882),(131685,14,0,'s','1',669175,2887),(131686,14,1,'w','1',669175,2902),(131687,14,2,'n','1',669175,3016),(131688,14,3,'w','1',669175,2790),(131689,15,0,'n','1',669175,2969),(131690,15,1,'w','1',669175,2791),(131691,15,2,'e','1',669175,2784),(131692,15,3,'s','1',669175,2775),(131693,16,0,'e','1',669175,2781),(131694,16,1,'w','1',669175,2822),(131695,16,2,'s','1',669175,2719),(131696,17,0,'n','1',669175,2717),(131697,17,1,'n','1',669175,2719),(131698,17,2,'w','1',669175,2840),(131699,17,3,'n','1',669175,2779),(131700,18,0,'s','1',669175,2845),(131701,18,1,'e','1',669175,2719),(131702,18,2,'e','1',669175,2780),(131703,19,0,'n','1',669175,2789),(131704,19,1,'n','1',669175,2842),(131705,19,2,'s','1',669175,2738),(131706,19,3,'w','1',669175,2928),(131707,20,0,'n','1',669175,2889),(131708,20,1,'n','1',669175,2842),(131709,20,2,'w','1',669175,2738),(131710,20,3,'n','1',669175,2841),(131711,21,0,'e','1',669175,2734),(131712,21,1,'e','1',669175,2755),(131713,21,2,'s','1',669175,2756),(131714,21,3,'w','1',669175,2738),(131715,22,0,'e','1',669175,2734),(131716,22,1,'w','1',669175,2738),(131717,22,2,'w','1',669175,2917),(131718,22,3,'n','1',669175,2762),(131719,23,0,'w','1',669175,2761),(131720,23,1,'s','1',669175,2734),(131721,23,2,'w','1',669175,2796),(131722,23,3,'w','1',669175,2776),(131723,24,0,'e','1',669175,2733),(131724,24,1,'w','1',669175,2842),(131725,24,2,'n','1',669175,2736),(131726,24,3,'n','1',669175,2728),(131727,25,0,'s','1',669175,2922),(131728,25,1,'w','1',669175,2976),(131729,25,2,'w','1',669175,2829),(131730,25,3,'w','1',669175,2725),(131731,26,0,'n','1',669175,2733),(131732,26,1,'s','1',669175,2734),(131733,26,2,'w','1',669175,2804),(131734,26,3,'n','1',669175,2719),(131735,27,0,'n','1',669175,2845),(131736,27,1,'e','1',669175,2846),(131737,27,2,'s','1',669175,2900),(131738,27,3,'e','1',669175,2780),(131739,28,0,'w','1',669175,2854),(131740,28,1,'e','1',669175,2846),(131741,28,2,'s','1',669175,2900),(131742,28,3,'n','1',669175,2733),(131743,29,0,'w','1',669175,2734),(131744,29,1,'w','1',669175,2749),(131745,29,2,'w','1',669175,2878),(131746,29,3,'w','1',669175,2854),(131747,30,0,'n','1',669175,2949),(131748,30,1,'w','1',669175,2750),(131749,30,2,'s','1',669175,2860),(131750,30,3,'n','1',669175,2846),(131751,31,0,'e','1',669175,2956),(131752,31,1,'n','1',669175,2751),(131753,31,2,'n','1',669175,2773),(131754,31,3,'e','1',669175,2881),(131755,32,0,'w','1',669175,2792),(131756,32,1,'s','1',669175,2768),(131757,32,2,'s','1',669175,2793),(131758,32,3,'w','1',669175,2750),(131759,33,0,'s','1',669175,2751),(131760,33,1,'n','1',669175,2730),(131761,33,2,'e','1',669175,2877),(131762,33,3,'e','1',669175,2781),(131763,34,0,'n','1',669175,2762),(131764,34,1,'e','1',669175,2751),(131765,34,2,'w','1',669175,2773),(131766,34,3,'n','1',669175,2750),(131767,35,0,'s','1',669175,2861),(131768,35,1,'s','1',669175,2949),(131769,35,2,'e','1',669175,2903),(131770,35,3,'e','1',669175,2728),(131771,36,0,'w','1',669175,2901),(131772,36,1,'w','1',669175,2972),(131773,36,2,'s','1',669175,2721),(131774,37,0,'e','1',669175,2841),(131775,37,1,'e','1',669175,2858),(131776,37,2,'e','1',669175,2790),(131777,37,3,'e','1',669175,2882),(131778,38,0,'n','1',669175,2956),(131779,38,1,'w','1',669175,2722),(131780,38,2,'e','1',669175,2958),(131781,38,3,'w','1',669175,2993),(131782,39,0,'n','1',669175,2768),(131783,39,1,'s','1',669175,2767),(131784,39,2,'w','1',669175,2890),(131785,39,3,'e','1',669175,2893),(131786,2,0,'n','1',669175,2815),(131787,2,1,'n','1',669175,3051),(131788,2,2,'e','1',669175,2818),(131789,2,3,'n','1',669175,3052),(131790,3,0,'n','1',669175,2872),(131791,3,1,'n','1',669175,2877),(131792,3,2,'n','1',669175,2878),(131793,3,3,'e','1',669175,3033),(131794,4,0,'e','1',669175,2726),(131795,4,1,'n','1',669175,2727),(131796,4,2,'n','1',669175,2730),(131797,4,3,'n','1',669175,2868),(131798,5,0,'n','1',669175,2834),(131799,5,1,'n','1',669175,2722),(131800,5,2,'n','1',669175,2956),(131801,5,3,'n','1',669175,2822),(131802,6,0,'w','1',669175,2875),(131803,6,1,'w','1',669175,2883),(131804,6,2,'w','1',669175,2884),(131805,6,3,'w','1',669175,2735),(131806,7,0,'w','1',669175,2829),(131807,7,1,'w','1',669175,2725),(131808,7,2,'n','1',669175,2719),(131809,7,3,'n','1',669175,2780),(131810,8,0,'e','1',669175,2751),(131811,8,1,'e','1',669175,2750),(131812,8,2,'n','1',669175,2863),(131813,8,3,'n','1',669175,2970),(131814,9,0,'e','1',669175,2749),(131815,9,1,'e','1',669175,2734),(131816,9,2,'w','1',669175,2738),(131817,9,3,'s','1',669175,2743),(131818,10,0,'n','1',669175,2734),(131819,10,1,'w','1',669175,2826),(131820,10,2,'n','1',669175,2744),(131821,10,3,'n','1',669175,2958),(131822,11,0,'n','1',669175,2999),(131823,11,1,'e','1',669175,3005),(131824,11,2,'s','1',669175,2743),(131825,11,3,'s','1',669175,3004),(131826,12,0,'s','1',669175,2804),(131827,12,1,'s','1',669175,2741),(131828,12,2,'s','1',669175,2845),(131829,12,3,'w','1',669175,2721),(131830,13,0,'e','1',669175,2849),(131831,13,1,'s','1',669175,2738),(131832,13,2,'n','1',669175,2882),(131833,14,0,'s','1',669175,2887),(131834,14,1,'w','1',669175,2902),(131835,14,2,'n','1',669175,3016),(131836,14,3,'w','1',669175,2790),(131837,15,0,'n','1',669175,2969),(131838,15,1,'w','1',669175,2791),(131839,15,2,'e','1',669175,2784),(131840,15,3,'s','1',669175,2775),(131841,16,0,'e','1',669175,2781),(131842,16,1,'w','1',669175,2822),(131843,16,2,'s','1',669175,2719),(131844,17,0,'n','1',669175,2717),(131845,17,1,'n','1',669175,2719),(131846,17,2,'w','1',669175,2840),(131847,17,3,'n','1',669175,2779),(131848,18,0,'s','1',669175,2845),(131849,18,1,'e','1',669175,2719),(131850,18,2,'e','1',669175,2780),(131851,19,0,'n','1',669175,2789),(131852,19,1,'n','1',669175,2842),(131853,19,2,'s','1',669175,2738),(131854,19,3,'w','1',669175,2928),(131855,20,0,'n','1',669175,2889),(131856,20,1,'n','1',669175,2842),(131857,20,2,'w','1',669175,2738),(131858,20,3,'n','1',669175,2841),(131859,21,0,'e','1',669175,2734),(131860,21,1,'e','1',669175,2755),(131861,21,2,'s','1',669175,2756),(131862,21,3,'w','1',669175,2738),(131863,22,0,'e','1',669175,2734),(131864,22,1,'w','1',669175,2738),(131865,22,2,'w','1',669175,2917),(131866,22,3,'n','1',669175,2762),(131867,23,0,'w','1',669175,2761),(131868,23,1,'s','1',669175,2734),(131869,23,2,'w','1',669175,2796),(131870,23,3,'w','1',669175,2776),(131871,24,0,'e','1',669175,2733),(131872,24,1,'w','1',669175,2842),(131873,24,2,'n','1',669175,2736),(131874,24,3,'n','1',669175,2728),(131875,25,0,'s','1',669175,2922),(131876,25,1,'w','1',669175,2976),(131877,25,2,'w','1',669175,2829),(131878,25,3,'w','1',669175,2725),(131879,26,0,'n','1',669175,2733),(131880,26,1,'s','1',669175,2734),(131881,26,2,'w','1',669175,2804),(131882,26,3,'n','1',669175,2719),(131883,27,0,'n','1',669175,2845),(131884,27,1,'e','1',669175,2846),(131885,27,2,'s','1',669175,2900),(131886,27,3,'e','1',669175,2780),(131887,28,0,'w','1',669175,2854),(131888,28,1,'e','1',669175,2846),(131889,28,2,'s','1',669175,2900),(131890,28,3,'n','1',669175,2733),(131891,29,0,'w','1',669175,2734),(131892,29,1,'w','1',669175,2749),(131893,29,2,'w','1',669175,2878),(131894,29,3,'w','1',669175,2854),(131895,30,0,'n','1',669175,2949),(131896,30,1,'w','1',669175,2750),(131897,30,2,'s','1',669175,2860),(131898,30,3,'n','1',669175,2846),(131899,31,0,'e','1',669175,2956),(131900,31,1,'n','1',669175,2751),(131901,31,2,'n','1',669175,2773),(131902,31,3,'e','1',669175,2881),(131903,32,0,'w','1',669175,2792),(131904,32,1,'s','1',669175,2768),(131905,32,2,'s','1',669175,2793),(131906,32,3,'w','1',669175,2750),(131907,33,0,'s','1',669175,2751),(131908,33,1,'n','1',669175,2730),(131909,33,2,'e','1',669175,2877),(131910,33,3,'e','1',669175,2781),(131911,34,0,'n','1',669175,2762),(131912,34,1,'e','1',669175,2751),(131913,34,2,'w','1',669175,2773),(131914,34,3,'n','1',669175,2750),(131915,35,0,'s','1',669175,2861),(131916,35,1,'s','1',669175,2949),(131917,35,2,'e','1',669175,2903),(131918,35,3,'e','1',669175,2728),(131919,36,0,'w','1',669175,2901),(131920,36,1,'w','1',669175,2972),(131921,36,2,'s','1',669175,2721),(131922,37,0,'e','1',669175,2841),(131923,37,1,'e','1',669175,2858),(131924,37,2,'e','1',669175,2790),(131925,37,3,'e','1',669175,2882),(131926,38,0,'n','1',669175,2956),(131927,38,1,'w','1',669175,2722),(131928,38,2,'e','1',669175,2958),(131929,38,3,'w','1',669175,2993),(131930,39,0,'n','1',669175,2768),(131931,39,1,'s','1',669175,2767),(131932,39,2,'w','1',669175,2890),(131933,39,3,'e','1',669175,2893),(131934,2,0,'n','1',669176,2867),(131935,2,1,'n','1',669176,2816),(131936,2,2,'n','1',669176,2732),(131937,2,3,'n','1',669176,2815),(131938,3,0,'n','1',669176,2963),(131939,3,1,'n','1',669176,2749),(131940,3,2,'w','1',669176,2765),(131941,3,3,'s','1',669176,2863),(131942,4,0,'s','1',669176,2833),(131943,4,1,'e','1',669176,2768),(131944,4,2,'s','1',669176,2788),(131945,4,3,'s','1',669176,2765),(131946,5,0,'w','1',669176,2749),(131947,5,1,'w','1',669176,2851),(131948,5,2,'s','1',669176,2750),(131949,5,3,'e','1',669176,2818),(131950,6,0,'n','1',669176,2872),(131951,6,1,'s','1',669176,2785),(131952,6,2,'e','1',669176,2877),(131953,6,3,'n','1',669176,2717),(131954,7,0,'w','1',669176,2771),(131955,7,1,'w','1',669176,2822),(131956,7,2,'s','1',669176,2719),(131957,7,3,'e','1',669176,2731),(131958,8,0,'n','1',669176,2739),(131959,8,1,'e','1',669176,2969),(131960,8,2,'e','1',669176,2717),(131961,8,3,'n','1',669176,2732),(131962,9,0,'e','1',669176,2969),(131963,9,1,'e','1',669176,2717),(131964,9,2,'n','1',669176,2721),(131965,9,3,'n','1',669176,2888),(131966,10,0,'e','1',669176,2717),(131967,10,1,'n','1',669176,2882),(131968,10,2,'e','1',669176,2927),(131969,10,3,'n','1',669176,2915),(131970,11,0,'n','1',669176,2749),(131971,11,1,'w','1',669176,2765),(131972,11,2,'w','1',669176,2754),(131973,11,3,'w','1',669176,2903),(131974,12,0,'s','1',669176,2768),(131975,12,1,'w','1',669176,2879),(131976,12,2,'s','1',669176,2859),(131977,12,3,'s','1',669176,2786),(131978,13,0,'s','1',669176,2857),(131979,13,1,'w','1',669176,2750),(131980,13,2,'s','1',669176,2794),(131981,13,3,'s','1',669176,2751),(131982,14,0,'n','1',669176,2887),(131983,14,1,'e','1',669176,2730),(131984,14,2,'e','1',669176,2731),(131985,14,3,'e','1',669176,2732),(131986,15,0,'w','1',669176,2733),(131987,15,1,'n','1',669176,2732),(131988,15,2,'w','1',669176,2749),(131989,15,3,'w','1',669176,2750),(131990,16,0,'e','1',669176,2751),(131991,16,1,'e','1',669176,2750),(131992,16,2,'s','1',669176,2773),(131993,16,3,'w','1',669176,2786),(131994,17,0,'w','1',669176,2774),(131995,17,1,'w','1',669176,2749),(131996,17,2,'n','1',669176,2962),(131997,17,3,'w','1',669176,2858),(131998,18,0,'e','1',669176,2906),(131999,18,1,'s','1',669176,2856),(132000,18,2,'n','1',669176,2779),(132001,18,3,'n','1',669176,2780),(132002,19,0,'s','1',669176,2878),(132003,19,1,'w','1',669176,2857),(132004,19,2,'s','1',669176,2877),(132005,19,3,'s','1',669176,2840),(132006,20,0,'e','1',669176,2962),(132007,20,1,'e','1',669176,2831),(132008,20,2,'n','1',669176,2872),(132009,20,3,'w','1',669176,2784),(132010,21,0,'s','1',669176,2794),(132011,21,1,'e','1',669176,2877),(132012,21,2,'w','1',669176,2861),(132013,21,3,'n','1',669176,2915),(132014,22,0,'w','1',669176,2750),(132015,22,1,'w','1',669176,2751),(132016,22,2,'e','1',669176,2871),(132017,22,3,'s','1',669176,2900),(132018,23,0,'w','1',669176,2772),(132019,23,1,'w','1',669176,2751),(132020,23,2,'e','1',669176,2871),(132021,23,3,'s','1',669176,2900),(132022,24,0,'w','1',669176,2751),(132023,24,1,'e','1',669176,2871),(132024,24,2,'s','1',669176,2900),(132025,24,3,'w','1',669176,2858),(132026,25,0,'s','1',669176,2945),(132027,25,1,'w','1',669176,2739),(132028,25,2,'e','1',669176,2751),(132029,25,3,'e','1',669176,2750),(132030,26,0,'w','1',669176,2822),(132031,26,1,'w','1',669176,2969),(132032,26,2,'n','1',669176,3063),(132033,27,0,'e','1',669176,2945),(132034,27,1,'e','1',669176,2753),(132035,27,2,'n','1',669176,2969),(132036,27,3,'x','0',669176,2784),(132037,27,4,'w','1',669176,2828),(132038,28,0,'e','1',669176,2945),(132039,28,1,'e','1',669176,2828),(132040,28,2,'n','1',669176,2790),(132041,28,3,'w','1',669176,2791),(132042,29,0,'w','1',669176,2786),(132043,29,1,'n','1',669176,2827),(132044,29,2,'e','1',669176,2884),(132045,29,3,'n','1',669176,2872),(132046,30,0,'n','1',669176,2877),(132047,30,1,'n','1',669176,2878),(132048,30,2,'e','1',669176,3006),(132049,30,3,'n','1',669176,2779),(132050,31,0,'n','1',669176,2883),(132051,31,1,'e','1',669176,2850),(132052,31,2,'w','1',669176,2749),(132053,31,3,'n','1',669176,2780),(132054,32,0,'s','1',669176,2750),(132055,32,1,'w','1',669176,2731),(132056,32,2,'e','1',669176,2736),(132057,32,3,'n','1',669176,2781),(132058,2,0,'n','1',669176,2867),(132059,2,1,'n','1',669176,2816),(132060,2,2,'n','1',669176,2732),(132061,2,3,'n','1',669176,2815),(132062,3,0,'n','1',669176,2963),(132063,3,1,'n','1',669176,2749),(132064,3,2,'w','1',669176,2765),(132065,3,3,'s','1',669176,2863),(132066,4,0,'s','1',669176,2833),(132067,4,1,'e','1',669176,2768),(132068,4,2,'s','1',669176,2788),(132069,4,3,'s','1',669176,2765),(132070,5,0,'w','1',669176,2749),(132071,5,1,'w','1',669176,2851),(132072,5,2,'s','1',669176,2750),(132073,5,3,'e','1',669176,2818),(132074,6,0,'n','1',669176,2872),(132075,6,1,'s','1',669176,2785),(132076,6,2,'e','1',669176,2877),(132077,6,3,'n','1',669176,2717),(132078,7,0,'w','1',669176,2771),(132079,7,1,'w','1',669176,2822),(132080,7,2,'s','1',669176,2719),(132081,7,3,'e','1',669176,2731),(132082,8,0,'n','1',669176,2739),(132083,8,1,'e','1',669176,2969),(132084,8,2,'e','1',669176,2717),(132085,8,3,'n','1',669176,2732),(132086,9,0,'e','1',669176,2969),(132087,9,1,'e','1',669176,2717),(132088,9,2,'n','1',669176,2721),(132089,9,3,'n','1',669176,2888),(132090,10,0,'e','1',669176,2717),(132091,10,1,'n','1',669176,2882),(132092,10,2,'e','1',669176,2927),(132093,10,3,'n','1',669176,2915),(132094,11,0,'n','1',669176,2749),(132095,11,1,'w','1',669176,2765),(132096,11,2,'w','1',669176,2754),(132097,11,3,'w','1',669176,2903),(132098,12,0,'s','1',669176,2768),(132099,12,1,'w','1',669176,2879),(132100,12,2,'s','1',669176,2859),(132101,12,3,'s','1',669176,2786),(132102,13,0,'s','1',669176,2857),(132103,13,1,'w','1',669176,2750),(132104,13,2,'s','1',669176,2794),(132105,13,3,'s','1',669176,2751),(132106,14,0,'n','1',669176,2887),(132107,14,1,'e','1',669176,2730),(132108,14,2,'e','1',669176,2731),(132109,14,3,'e','1',669176,2732),(132110,15,0,'w','1',669176,2733),(132111,15,1,'n','1',669176,2732),(132112,15,2,'w','1',669176,2749),(132113,15,3,'w','1',669176,2750),(132114,16,0,'e','1',669176,2751),(132115,16,1,'e','1',669176,2750),(132116,16,2,'s','1',669176,2773),(132117,16,3,'w','1',669176,2786),(132118,17,0,'w','1',669176,2774),(132119,17,1,'w','1',669176,2749),(132120,17,2,'n','1',669176,2962),(132121,17,3,'w','1',669176,2858),(132122,18,0,'e','1',669176,2906),(132123,18,1,'s','1',669176,2856),(132124,18,2,'n','1',669176,2779),(132125,18,3,'n','1',669176,2780),(132126,19,0,'s','1',669176,2878),(132127,19,1,'w','1',669176,2857),(132128,19,2,'s','1',669176,2877),(132129,19,3,'s','1',669176,2840),(132130,20,0,'e','1',669176,2962),(132131,20,1,'e','1',669176,2831),(132132,20,2,'n','1',669176,2872),(132133,20,3,'w','1',669176,2784),(132134,21,0,'s','1',669176,2794),(132135,21,1,'e','1',669176,2877),(132136,21,2,'w','1',669176,2861),(132137,21,3,'n','1',669176,2915),(132138,22,0,'w','1',669176,2750),(132139,22,1,'w','1',669176,2751),(132140,22,2,'e','1',669176,2871),(132141,22,3,'s','1',669176,2900),(132142,23,0,'w','1',669176,2772),(132143,23,1,'w','1',669176,2751),(132144,23,2,'e','1',669176,2871),(132145,23,3,'s','1',669176,2900),(132146,24,0,'w','1',669176,2751),(132147,24,1,'e','1',669176,2871),(132148,24,2,'s','1',669176,2900),(132149,24,3,'w','1',669176,2858),(132150,25,0,'s','1',669176,2945),(132151,25,1,'w','1',669176,2739),(132152,25,2,'e','1',669176,2751),(132153,25,3,'e','1',669176,2750),(132154,26,0,'w','1',669176,2822),(132155,26,1,'w','1',669176,2969),(132156,26,2,'n','1',669176,3063),(132157,27,0,'e','1',669176,2945),(132158,27,1,'e','1',669176,2753),(132159,27,2,'n','1',669176,2969),(132160,27,3,'x','0',669176,2784),(132161,27,4,'w','1',669176,2828),(132162,28,0,'e','1',669176,2945),(132163,28,1,'e','1',669176,2828),(132164,28,2,'n','1',669176,2790),(132165,28,3,'w','1',669176,2791),(132166,29,0,'w','1',669176,2786),(132167,29,1,'n','1',669176,2827),(132168,29,2,'e','1',669176,2884),(132169,29,3,'n','1',669176,2872),(132170,30,0,'n','1',669176,2877),(132171,30,1,'n','1',669176,2878),(132172,30,2,'e','1',669176,3006),(132173,30,3,'n','1',669176,2779),(132174,31,0,'n','1',669176,2883),(132175,31,1,'e','1',669176,2850),(132176,31,2,'w','1',669176,2749),(132177,31,3,'n','1',669176,2780),(132178,32,0,'s','1',669176,2750),(132179,32,1,'w','1',669176,2731),(132180,32,2,'e','1',669176,2736),(132181,32,3,'n','1',669176,2781),(132182,2,0,'n','1',669177,2721),(132183,2,1,'n','1',669177,2810),(132184,2,2,'w','1',669177,2754),(132185,2,3,'n','1',669177,2811),(132186,3,0,'n','1',669177,2736),(132187,3,1,'n','1',669177,2812),(132188,3,2,'n','1',669177,3010),(132189,3,3,'n','1',669177,3011),(132190,4,0,'w','1',669177,3012),(132191,4,1,'n','1',669177,2737),(132192,4,2,'w','1',669177,2759),(132193,4,3,'n','1',669177,2717),(132194,5,0,'w','1',669177,2776),(132195,5,1,'n','1',669177,2724),(132196,5,2,'n','1',669177,2779),(132197,5,3,'n','1',669177,2975),(132198,6,0,'n','1',669177,2728),(132199,6,1,'n','1',669177,2956),(132200,6,2,'e','1',669177,2951),(132201,6,3,'e','1',669177,2797),(132202,7,0,'s','1',669177,2833),(132203,7,1,'w','1',669177,2807),(132204,7,2,'s','1',669177,2788),(132205,7,3,'s','1',669177,2970),(132206,8,0,'w','1',669177,2736),(132207,8,1,'w','1',669177,2760),(132208,8,2,'n','1',669177,2986),(132209,8,3,'n','1',669177,2958),(132210,9,0,'e','1',669177,2794),(132211,9,1,'n','1',669177,2746),(132212,9,2,'w','1',669177,2792),(132213,9,3,'w','1',669177,2755),(132214,10,0,'w','1',669177,2748),(132215,10,1,'n','1',669177,2776),(132216,10,2,'n','1',669177,2774),(132217,10,3,'n','1',669177,2719),(132218,11,0,'n','1',669177,2845),(132219,11,1,'w','1',669177,2886),(132220,11,2,'n','1',669177,2846),(132221,11,3,'n','1',669177,2753),(132222,12,0,'n','1',669177,2789),(132223,12,1,'n','1',669177,2795),(132224,12,2,'n','1',669177,2796),(132225,12,3,'n','1',669177,2798),(132226,13,0,'w','1',669177,2741),(132227,13,1,'s','1',669177,2924),(132228,13,2,'n','1',669177,2744),(132229,13,3,'w','1',669177,2825),(132230,13,4,'x','0',669177,2809),(132231,14,0,'w','1',669177,3005),(132232,14,1,'x','0',669177,2757),(132233,14,2,'s','1',669177,2987),(132234,14,3,'s','1',669177,2988),(132235,14,4,'s','1',669177,3064),(132236,15,0,'s','1',669177,2747),(132237,15,1,'s','1',669177,2765),(132238,15,2,'e','1',669177,2936),(132239,15,3,'n','1',669177,2955),(132240,16,0,'s','1',669177,2948),(132241,16,1,'s','1',669177,2749),(132242,16,2,'e','1',669177,2884),(132243,16,3,'x','0',669177,2883),(132244,16,4,'s','1',669177,2732),(132245,17,0,'n','1',669177,2816),(132246,17,1,'n','1',669177,2732),(132247,17,2,'s','1',669177,2758),(132248,17,3,'e','1',669177,2749),(132249,18,0,'n','1',669177,2879),(132250,18,1,'n','1',669177,2767),(132251,18,2,'n','1',669177,2880),(132252,18,3,'s','1',669177,2734),(132253,19,0,'n','1',669177,2733),(132254,19,1,'e','1',669177,2990),(132255,19,2,'n','1',669177,2905),(132256,19,3,'n','1',669177,2762),(132257,20,0,'e','1',669177,2734),(132258,20,1,'w','1',669177,2738),(132259,20,2,'n','1',669177,2737),(132260,20,3,'e','1',669177,2923),(132261,21,0,'e','1',669177,2734),(132262,21,1,'s','1',669177,2737),(132263,21,2,'s','1',669177,2738),(132264,21,3,'n','1',669177,2761),(132265,22,0,'w','1',669177,2773),(132266,22,1,'x','0',669177,2859),(132267,22,2,'w','1',669177,2970),(132268,22,3,'s','1',669177,2764),(132269,22,4,'n','1',669177,2903),(132270,2,0,'n','1',669177,2721),(132271,2,1,'n','1',669177,2810),(132272,2,2,'w','1',669177,2754),(132273,2,3,'n','1',669177,2811),(132274,3,0,'n','1',669177,2736),(132275,3,1,'n','1',669177,2812),(132276,3,2,'n','1',669177,3010),(132277,3,3,'n','1',669177,3011),(132278,4,0,'w','1',669177,3012),(132279,4,1,'n','1',669177,2737),(132280,4,2,'w','1',669177,2759),(132281,4,3,'n','1',669177,2717),(132282,5,0,'w','1',669177,2776),(132283,5,1,'n','1',669177,2724),(132284,5,2,'n','1',669177,2779),(132285,5,3,'n','1',669177,2975),(132286,6,0,'n','1',669177,2728),(132287,6,1,'n','1',669177,2956),(132288,6,2,'e','1',669177,2951),(132289,6,3,'e','1',669177,2797),(132290,7,0,'s','1',669177,2833),(132291,7,1,'w','1',669177,2807),(132292,7,2,'s','1',669177,2788),(132293,7,3,'s','1',669177,2970),(132294,8,0,'w','1',669177,2736),(132295,8,1,'w','1',669177,2760),(132296,8,2,'n','1',669177,2986),(132297,8,3,'n','1',669177,2958),(132298,9,0,'e','1',669177,2794),(132299,9,1,'n','1',669177,2746),(132300,9,2,'w','1',669177,2792),(132301,9,3,'w','1',669177,2755),(132302,10,0,'w','1',669177,2748),(132303,10,1,'n','1',669177,2776),(132304,10,2,'n','1',669177,2774),(132305,10,3,'n','1',669177,2719),(132306,11,0,'n','1',669177,2845),(132307,11,1,'w','1',669177,2886),(132308,11,2,'n','1',669177,2846),(132309,11,3,'n','1',669177,2753),(132310,12,0,'n','1',669177,2789),(132311,12,1,'n','1',669177,2795),(132312,12,2,'n','1',669177,2796),(132313,12,3,'n','1',669177,2798),(132314,13,0,'w','1',669177,2741),(132315,13,1,'s','1',669177,2924),(132316,13,2,'n','1',669177,2744),(132317,13,3,'w','1',669177,2825),(132318,13,4,'x','0',669177,2809),(132319,14,0,'w','1',669177,3005),(132320,14,1,'x','0',669177,2757),(132321,14,2,'s','1',669177,2987),(132322,14,3,'s','1',669177,2988),(132323,14,4,'s','1',669177,3064),(132324,15,0,'s','1',669177,2747),(132325,15,1,'s','1',669177,2765),(132326,15,2,'e','1',669177,2936),(132327,15,3,'n','1',669177,2955),(132328,16,0,'s','1',669177,2948),(132329,16,1,'s','1',669177,2749),(132330,16,2,'e','1',669177,2884),(132331,16,3,'x','0',669177,2883),(132332,16,4,'s','1',669177,2732),(132333,17,0,'n','1',669177,2816),(132334,17,1,'n','1',669177,2732),(132335,17,2,'s','1',669177,2758),(132336,17,3,'e','1',669177,2749),(132337,18,0,'n','1',669177,2879),(132338,18,1,'n','1',669177,2767),(132339,18,2,'n','1',669177,2880),(132340,18,3,'s','1',669177,2734),(132341,19,0,'n','1',669177,2733),(132342,19,1,'e','1',669177,2990),(132343,19,2,'n','1',669177,2905),(132344,19,3,'n','1',669177,2762),(132345,20,0,'e','1',669177,2734),(132346,20,1,'w','1',669177,2738),(132347,20,2,'n','1',669177,2737),(132348,20,3,'e','1',669177,2923),(132349,21,0,'e','1',669177,2734),(132350,21,1,'s','1',669177,2737),(132351,21,2,'s','1',669177,2738),(132352,21,3,'n','1',669177,2761),(132353,22,0,'w','1',669177,2773),(132354,22,1,'x','0',669177,2859),(132355,22,2,'w','1',669177,2970),(132356,22,3,'s','1',669177,2764),(132357,22,4,'n','1',669177,2903),(132358,2,0,'n','1',669178,2728),(132359,2,1,'n','1',669178,2913),(132360,2,2,'e','1',669178,2874),(132361,2,3,'n','1',669178,2887),(132362,3,0,'n','1',669178,2819),(132363,3,1,'n','1',669178,3006),(132364,3,2,'e','1',669178,2996),(132365,3,3,'e','1',669178,2827),(132366,4,0,'e','1',669178,2847),(132367,4,1,'n','1',669178,2848),(132368,4,2,'w','1',669178,2830),(132369,4,3,'s','1',669178,2931),(132370,5,0,'e','1',669178,2736),(132371,5,1,'n','1',669178,2728),(132372,5,2,'e','1',669178,2947),(132373,5,3,'n','1',669178,2754),(132374,6,0,'s','1',669178,2835),(132375,6,1,'e','1',669178,2847),(132376,6,2,'n','1',669178,2736),(132377,6,3,'n','1',669178,2868),(132378,7,0,'n','1',669178,2840),(132379,7,1,'n','1',669178,2848),(132380,7,2,'n','1',669178,2932),(132381,7,3,'e','1',669178,2830),(132382,8,0,'n','1',669178,2816),(132383,8,1,'w','1',669178,2732),(132384,8,2,'w','1',669178,2785),(132385,8,3,'w','1',669178,2731),(132386,9,0,'n','1',669178,2831),(132387,9,1,'w','1',669178,2730),(132388,9,2,'s','1',669178,2783),(132389,9,3,'s','1',669178,2873),(132390,10,0,'w','1',669178,2737),(132391,10,1,'s','1',669178,2740),(132392,10,2,'w','1',669178,2760),(132393,10,3,'w','1',669178,2820),(132394,11,0,'w','1',669178,2976),(132395,11,1,'w','1',669178,2958),(132396,11,2,'w','1',669178,2737),(132397,11,3,'w','1',669178,2740),(132398,12,0,'n','1',669178,2875),(132399,12,1,'n','1',669178,2849),(132400,12,2,'s','1',669178,2804),(132401,12,3,'s','1',669178,2806),(132402,13,0,'n','1',669178,2831),(132403,13,1,'n','1',669178,2726),(132404,13,2,'s','1',669178,2873),(132405,13,3,'w','1',669178,2855),(132406,14,0,'e','1',669178,2966),(132407,14,1,'s','1',669178,2950),(132408,14,2,'n','1',669178,2888),(132409,14,3,'n','1',669178,2834),(132410,15,0,'n','1',669178,2823),(132411,15,1,'n','1',669178,2849),(132412,15,2,'w','1',669178,2806),(132413,15,3,'n','1',669178,2804),(132414,16,0,'n','1',669178,2745),(132415,16,1,'n','1',669178,2821),(132416,16,2,'w','1',669178,2955),(132417,16,3,'n','1',669178,3022),(132418,17,0,'s','1',669178,2743),(132419,17,1,'s','1',669178,2999),(132420,17,2,'s','1',669178,2804),(132421,17,3,'s','1',669178,2837),(132422,18,0,'s','1',669178,2726),(132423,18,1,'x','0',669178,2950),(132424,18,2,'n','1',669178,2779),(132425,18,3,'w','1',669178,2720),(132426,18,4,'n','1',669178,2962),(132427,19,0,'e','1',669178,2843),(132428,19,1,'n','1',669178,2849),(132429,19,2,'e','1',669178,2973),(132430,19,3,'e','1',669178,2958),(132431,20,0,'n','1',669178,2804),(132432,20,1,'n','1',669178,3000),(132433,20,2,'n','1',669178,2743),(132434,20,3,'w','1',669178,2742),(132435,21,0,'e','1',669178,3002),(132436,21,1,'w','1',669178,3001),(132437,21,2,'s','1',669178,2742),(132438,21,3,'n','1',669178,2901),(132439,22,0,'n','1',669178,2999),(132440,22,1,'n','1',669178,2743),(132441,22,2,'s','1',669178,2742),(132442,22,3,'w','1',669178,2984),(132443,23,0,'e','1',669178,2927),(132444,23,1,'n','1',669178,2817),(132445,23,2,'e','1',669178,2824),(132446,23,3,'n','1',669178,2823),(132447,24,0,'w','1',669178,2976),(132448,24,1,'n','1',669178,2745),(132449,24,2,'w','1',669178,2843),(132450,24,3,'s','1',669178,2743),(132451,25,0,'n','1',669178,2804),(132452,25,1,'n','1',669178,2999),(132453,25,2,'n','1',669178,2743),(132454,25,3,'w','1',669178,2821),(132455,26,0,'w','1',669178,3001),(132456,26,1,'s','1',669178,2742),(132457,26,2,'e','1',669178,2843),(132458,26,3,'n','1',669178,2903),(132459,27,0,'n','1',669178,2999),(132460,27,1,'n','1',669178,2743),(132461,27,2,'w','1',669178,2742),(132462,27,3,'w','1',669178,2985),(132463,28,0,'w','1',669178,2821),(132464,28,1,'n','1',669178,2837),(132465,28,2,'n','1',669178,2843),(132466,28,3,'e','1',669178,2797),(132467,29,0,'n','1',669178,2837),(132468,29,1,'n','1',669178,3002),(132469,29,2,'s','1',669178,3065),(132470,29,3,'w','1',669178,3054),(132471,30,0,'n','1',669178,2999),(132472,30,1,'e','1',669178,3002),(132473,30,2,'e','1',669178,2742),(132474,30,3,'n','1',669178,2837),(132475,31,0,'w','1',669178,2926),(132476,31,1,'w','1',669178,3066),(132477,31,2,'s','1',669178,2836),(132478,31,3,'w','1',669178,2742),(132479,32,0,'e','1',669178,2903),(132480,32,1,'e','1',669178,2901),(132481,32,2,'n','1',669178,2888),(132482,32,3,'n','1',669178,2834),(132483,33,0,'n','1',669178,2823),(132484,33,1,'n','1',669178,2745),(132485,33,2,'n','1',669178,2821),(132486,33,3,'e','1',669178,3002),(132487,33,4,'x','0',669178,2757),(132488,34,0,'w','1',669178,3001),(132489,34,1,'s','1',669178,2742),(132490,34,2,'n','1',669178,2743),(132491,34,3,'n','1',669178,2843),(132492,35,0,'s','1',669178,3001),(132493,35,1,'s','1',669178,2742),(132494,35,2,'w','1',669178,2960),(132495,35,3,'s','1',669178,2743),(132496,36,0,'n','1',669178,2804),(132497,36,1,'n','1',669178,2999),(132498,36,2,'n','1',669178,2743),(132499,36,3,'e','1',669178,2790),(132500,37,0,'e','1',669178,2858),(132501,37,1,'e','1',669178,2797),(132502,37,2,'e','1',669178,2903),(132503,37,3,'w','1',669178,2790),(132504,2,0,'n','1',669178,2728),(132505,2,1,'n','1',669178,2913),(132506,2,2,'e','1',669178,2874),(132507,2,3,'n','1',669178,2887),(132508,3,0,'n','1',669178,2819),(132509,3,1,'n','1',669178,3006),(132510,3,2,'e','1',669178,2996),(132511,3,3,'e','1',669178,2827),(132512,4,0,'e','1',669178,2847),(132513,4,1,'n','1',669178,2848),(132514,4,2,'w','1',669178,2830),(132515,4,3,'s','1',669178,2931),(132516,5,0,'e','1',669178,2736),(132517,5,1,'n','1',669178,2728),(132518,5,2,'e','1',669178,2947),(132519,5,3,'n','1',669178,2754),(132520,6,0,'s','1',669178,2835),(132521,6,1,'e','1',669178,2847),(132522,6,2,'n','1',669178,2736),(132523,6,3,'n','1',669178,2868),(132524,7,0,'n','1',669178,2840),(132525,7,1,'n','1',669178,2848),(132526,7,2,'n','1',669178,2932),(132527,7,3,'e','1',669178,2830),(132528,8,0,'n','1',669178,2816),(132529,8,1,'w','1',669178,2732),(132530,8,2,'w','1',669178,2785),(132531,8,3,'w','1',669178,2731),(132532,9,0,'n','1',669178,2831),(132533,9,1,'w','1',669178,2730),(132534,9,2,'s','1',669178,2783),(132535,9,3,'s','1',669178,2873),(132536,10,0,'w','1',669178,2737),(132537,10,1,'s','1',669178,2740),(132538,10,2,'w','1',669178,2760),(132539,10,3,'w','1',669178,2820),(132540,11,0,'w','1',669178,2976),(132541,11,1,'w','1',669178,2958),(132542,11,2,'w','1',669178,2737),(132543,11,3,'w','1',669178,2740),(132544,12,0,'n','1',669178,2875),(132545,12,1,'n','1',669178,2849),(132546,12,2,'s','1',669178,2804),(132547,12,3,'s','1',669178,2806),(132548,13,0,'n','1',669178,2831),(132549,13,1,'n','1',669178,2726),(132550,13,2,'s','1',669178,2873),(132551,13,3,'w','1',669178,2855),(132552,14,0,'e','1',669178,2966),(132553,14,1,'s','1',669178,2950),(132554,14,2,'n','1',669178,2888),(132555,14,3,'n','1',669178,2834),(132556,15,0,'n','1',669178,2823),(132557,15,1,'n','1',669178,2849),(132558,15,2,'w','1',669178,2806),(132559,15,3,'n','1',669178,2804),(132560,16,0,'n','1',669178,2745),(132561,16,1,'n','1',669178,2821),(132562,16,2,'w','1',669178,2955),(132563,16,3,'n','1',669178,3022),(132564,17,0,'s','1',669178,2743),(132565,17,1,'s','1',669178,2999),(132566,17,2,'s','1',669178,2804),(132567,17,3,'s','1',669178,2837),(132568,18,0,'s','1',669178,2726),(132569,18,1,'x','0',669178,2950),(132570,18,2,'n','1',669178,2779),(132571,18,3,'w','1',669178,2720),(132572,18,4,'n','1',669178,2962),(132573,19,0,'e','1',669178,2843),(132574,19,1,'n','1',669178,2849),(132575,19,2,'e','1',669178,2973),(132576,19,3,'e','1',669178,2958),(132577,20,0,'n','1',669178,2804),(132578,20,1,'n','1',669178,3000),(132579,20,2,'n','1',669178,2743),(132580,20,3,'w','1',669178,2742),(132581,21,0,'e','1',669178,3002),(132582,21,1,'w','1',669178,3001),(132583,21,2,'s','1',669178,2742),(132584,21,3,'n','1',669178,2901),(132585,22,0,'n','1',669178,2999),(132586,22,1,'n','1',669178,2743),(132587,22,2,'s','1',669178,2742),(132588,22,3,'w','1',669178,2984),(132589,23,0,'e','1',669178,2927),(132590,23,1,'n','1',669178,2817),(132591,23,2,'e','1',669178,2824),(132592,23,3,'n','1',669178,2823),(132593,24,0,'w','1',669178,2976),(132594,24,1,'n','1',669178,2745),(132595,24,2,'w','1',669178,2843),(132596,24,3,'s','1',669178,2743),(132597,25,0,'n','1',669178,2804),(132598,25,1,'n','1',669178,2999),(132599,25,2,'n','1',669178,2743),(132600,25,3,'w','1',669178,2821),(132601,26,0,'w','1',669178,3001),(132602,26,1,'s','1',669178,2742),(132603,26,2,'e','1',669178,2843),(132604,26,3,'n','1',669178,2903),(132605,27,0,'n','1',669178,2999),(132606,27,1,'n','1',669178,2743),(132607,27,2,'w','1',669178,2742),(132608,27,3,'w','1',669178,2985),(132609,28,0,'w','1',669178,2821),(132610,28,1,'n','1',669178,2837),(132611,28,2,'n','1',669178,2843),(132612,28,3,'e','1',669178,2797),(132613,29,0,'n','1',669178,2837),(132614,29,1,'n','1',669178,3002),(132615,29,2,'s','1',669178,3065),(132616,29,3,'w','1',669178,3054),(132617,30,0,'n','1',669178,2999),(132618,30,1,'e','1',669178,3002),(132619,30,2,'e','1',669178,2742),(132620,30,3,'n','1',669178,2837),(132621,31,0,'w','1',669178,2926),(132622,31,1,'w','1',669178,3066),(132623,31,2,'s','1',669178,2836),(132624,31,3,'w','1',669178,2742),(132625,32,0,'e','1',669178,2903),(132626,32,1,'e','1',669178,2901),(132627,32,2,'n','1',669178,2888),(132628,32,3,'n','1',669178,2834),(132629,33,0,'n','1',669178,2823),(132630,33,1,'n','1',669178,2745),(132631,33,2,'n','1',669178,2821),(132632,33,3,'e','1',669178,3002),(132633,33,4,'x','0',669178,2757),(132634,34,0,'w','1',669178,3001),(132635,34,1,'s','1',669178,2742),(132636,34,2,'n','1',669178,2743),(132637,34,3,'n','1',669178,2843),(132638,35,0,'s','1',669178,3001),(132639,35,1,'s','1',669178,2742),(132640,35,2,'w','1',669178,2960),(132641,35,3,'s','1',669178,2743),(132642,36,0,'n','1',669178,2804),(132643,36,1,'n','1',669178,2999),(132644,36,2,'n','1',669178,2743),(132645,36,3,'e','1',669178,2790),(132646,37,0,'e','1',669178,2858),(132647,37,1,'e','1',669178,2797),(132648,37,2,'e','1',669178,2903),(132649,37,3,'w','1',669178,2790); +/*!40000 ALTER TABLE `Moves` ENABLE KEYS */; +UNLOCK TABLES; + +-- Remove duplicated move rows (keep the lowest `id` per logical move). +DELETE m1 +FROM `Moves` m1 +JOIN `Moves` m2 + ON m1.`matches_id` = m2.`matches_id` + AND m1.`turn` = m2.`turn` + AND m1.`sequence` = m2.`sequence` + AND m1.`direction` = m2.`direction` + AND m1.`status` = m2.`status` + AND m1.`position_id` = m2.`position_id` + AND m1.`id` > m2.`id`; + +-- +-- Dumping data for table `OpeningsByMatch` +-- + +LOCK TABLES `OpeningsByMatch` WRITE; +/*!40000 ALTER TABLE `OpeningsByMatch` DISABLE KEYS */; +INSERT INTO `OpeningsByMatch` VALUES (7297,669122,2723),(7298,669122,2718),(7299,669122,2763),(7300,669122,2790),(7301,669122,2797),(7302,669122,2903),(7303,669122,2782),(7304,669122,2722),(7305,669122,2779),(7306,669122,2717),(7307,669122,2902),(7308,669122,2739),(7309,669122,2789),(7310,669122,2905),(7311,669122,2817),(7312,669122,2721),(7313,669122,3067),(7314,669122,3068),(7315,669122,3069),(7316,669122,3070),(7317,669122,3071),(7318,669122,3072),(7319,669122,3073),(7320,669122,3074),(7321,669122,3075),(7322,669122,3076),(7323,669122,3077),(7324,669122,3078),(7325,669122,3079),(7326,669122,3080),(7327,669122,3081),(7328,669122,3082),(7329,669123,2723),(7330,669123,2724),(7331,669123,2858),(7332,669123,2790),(7333,669123,2841),(7334,669123,2903),(7335,669123,2782),(7336,669123,2810),(7337,669123,2815),(7338,669123,2822),(7339,669123,2902),(7340,669123,2791),(7341,669123,2827),(7342,669123,2905),(7343,669123,2817),(7344,669123,2721),(7345,669123,3083),(7346,669123,3084),(7347,669123,3069),(7348,669123,3070),(7349,669123,3071),(7350,669123,3085),(7351,669123,3086),(7352,669123,3073),(7353,669123,3075),(7354,669123,3076),(7355,669123,3077),(7356,669123,3078),(7357,669123,3079),(7358,669123,3081),(7359,669123,3087),(7360,669123,3082),(7361,669124,2869),(7362,669124,2882),(7363,669124,2858),(7364,669124,2870),(7365,669124,2797),(7366,669124,2903),(7367,669124,2782),(7368,669124,2888),(7369,669124,2815),(7370,669124,2822),(7371,669124,2902),(7372,669124,2739),(7373,669124,2867),(7374,669124,2905),(7375,669124,2868),(7376,669124,2834),(7377,669124,3088),(7378,669124,3084),(7379,669124,3069),(7380,669124,3070),(7381,669124,3072),(7382,669124,3089),(7383,669124,3086),(7384,669124,3073),(7385,669124,3075),(7386,669124,3076),(7387,669124,3077),(7388,669124,3078),(7389,669124,3080),(7390,669124,3081),(7391,669124,3087),(7392,669124,3082),(7393,669125,2913),(7394,669125,2717),(7395,669125,2815),(7396,669125,2721),(7397,669125,2870),(7398,669125,2915),(7399,669125,2882),(7400,669125,2838),(7401,669125,2927),(7402,669125,2858),(7403,669125,2797),(7404,669125,2903),(7405,669125,2901),(7406,669125,2888),(7407,669125,2902),(7408,669125,2905),(7409,669125,3090),(7410,669125,3091),(7411,669125,3075),(7412,669125,3088),(7413,669125,3072),(7414,669125,3076),(7415,669125,3092),(7416,669125,3070),(7417,669125,3077),(7418,669125,3073),(7419,669125,3078),(7420,669125,3079),(7421,669125,3080),(7422,669125,3081),(7423,669125,3074),(7424,669125,3093),(7425,669126,2913),(7426,669126,2717),(7427,669126,2815),(7428,669126,2721),(7429,669126,2870),(7430,669126,2915),(7431,669126,2882),(7432,669126,2838),(7433,669126,2927),(7434,669126,2858),(7435,669126,2797),(7436,669126,2903),(7437,669126,2901),(7438,669126,2888),(7439,669126,2902),(7440,669126,2905),(7441,669126,3094),(7442,669126,3084),(7443,669126,3075),(7444,669126,3095),(7445,669126,3083),(7446,669126,3076),(7447,669126,3096),(7448,669126,3070),(7449,669126,3097),(7450,669126,3098),(7451,669126,3099),(7452,669126,3079),(7453,669126,3085),(7454,669126,3081),(7455,669126,3074),(7456,669126,3082),(7457,669127,2723),(7458,669127,2962),(7459,669127,2858),(7460,669127,2790),(7461,669127,2841),(7462,669127,2903),(7463,669127,2956),(7464,669127,2888),(7465,669127,2815),(7466,669127,2822),(7467,669127,2957),(7468,669127,2955),(7469,669127,2827),(7470,669127,2905),(7471,669127,2728),(7472,669127,2834),(7473,669127,3100),(7474,669127,3101),(7475,669127,3102),(7476,669127,3088),(7477,669127,3103),(7478,669127,3104),(7479,669127,3086),(7480,669127,3105),(7481,669127,3077),(7482,669127,3106),(7483,669127,3078),(7484,669127,3079),(7485,669127,3080),(7486,669127,3081),(7487,669127,3087),(7488,669127,3082),(7489,669128,2779),(7490,669128,2964),(7491,669128,2966),(7492,669128,2965),(7493,669128,2867),(7494,669128,2952),(7495,669128,2868),(7496,669128,2834),(7497,669128,2927),(7498,669128,2962),(7499,669128,2858),(7500,669128,2870),(7501,669128,2963),(7502,669128,2903),(7503,669128,2901),(7504,669128,2888),(7505,669128,3094),(7506,669128,3101),(7507,669128,3107),(7508,669128,3108),(7509,669128,3083),(7510,669128,3104),(7511,669128,3092),(7512,669128,3109),(7513,669128,3077),(7514,669128,3106),(7515,669128,3078),(7516,669128,3110),(7517,669128,3111),(7518,669128,3081),(7519,669128,3087),(7520,669128,3082),(7521,669129,2869),(7522,669129,2718),(7523,669129,2858),(7524,669129,2975),(7525,669129,2797),(7526,669129,2903),(7527,669129,2782),(7528,669129,2972),(7529,669129,2779),(7530,669129,2964),(7531,669129,2902),(7532,669129,2791),(7533,669129,2915),(7534,669129,2905),(7535,669129,2817),(7536,669129,2974),(7537,669129,3088),(7538,669129,3084),(7539,669129,3069),(7540,669129,3092),(7541,669129,3072),(7542,669129,3089),(7543,669129,3112),(7544,669129,3074),(7545,669129,3075),(7546,669129,3076),(7547,669129,3109),(7548,669129,3106),(7549,669129,3078),(7550,669129,3080),(7551,669129,3081),(7552,669129,3082),(7553,669130,3009),(7554,669130,2724),(7555,669130,2763),(7556,669130,2790),(7557,669130,2963),(7558,669130,2903),(7559,669130,2991),(7560,669130,2722),(7561,669130,2779),(7562,669130,2717),(7563,669130,2902),(7564,669130,2791),(7565,669130,2789),(7566,669130,2905),(7567,669130,2728),(7568,669130,2834),(7569,669130,3083),(7570,669130,3068),(7571,669130,3069),(7572,669130,3070),(7573,669130,3071),(7574,669130,3085),(7575,669130,3113),(7576,669130,3074),(7577,669130,3075),(7578,669130,3076),(7579,669130,3077),(7580,669130,3106),(7581,669130,3078),(7582,669130,3079),(7583,669130,3081),(7584,669130,3082),(7585,669131,2867),(7586,669131,2717),(7587,669131,2815),(7588,669131,2721),(7589,669131,2963),(7590,669131,2739),(7591,669131,2882),(7592,669131,2838),(7593,669131,2927),(7594,669131,2858),(7595,669131,2790),(7596,669131,2903),(7597,669131,2901),(7598,669131,2888),(7599,669131,2902),(7600,669131,2905),(7601,669131,3090),(7602,669131,3091),(7603,669131,3075),(7604,669131,3114),(7605,669131,3083),(7606,669131,3076),(7607,669131,3096),(7608,669131,3070),(7609,669131,3112),(7610,669131,3098),(7611,669131,3078),(7612,669131,3079),(7613,669131,3080),(7614,669131,3081),(7615,669131,3115),(7616,669131,3116),(7617,669132,2723),(7618,669132,2882),(7619,669132,2858),(7620,669132,2790),(7621,669132,2797),(7622,669132,2903),(7623,669132,2782),(7624,669132,2888),(7625,669132,2779),(7626,669132,2717),(7627,669132,2902),(7628,669132,2739),(7629,669132,2789),(7630,669132,3003),(7631,669132,2728),(7632,669132,2721),(7633,669132,3083),(7634,669132,3068),(7635,669132,3069),(7636,669132,3070),(7637,669132,3071),(7638,669132,3085),(7639,669132,3113),(7640,669132,3074),(7641,669132,3075),(7642,669132,3076),(7643,669132,3077),(7644,669132,3106),(7645,669132,3078),(7646,669132,3079),(7647,669132,3081),(7648,669132,3082),(7649,669133,2867),(7650,669133,2717),(7651,669133,2815),(7652,669133,2721),(7653,669133,2963),(7654,669133,2739),(7655,669133,2882),(7656,669133,2838),(7657,669133,2927),(7658,669133,2858),(7659,669133,2790),(7660,669133,2903),(7661,669133,2901),(7662,669133,2888),(7663,669133,2902),(7664,669133,2905),(7665,669133,3094),(7666,669133,3084),(7667,669133,3075),(7668,669133,3095),(7669,669133,3083),(7670,669133,3076),(7671,669133,3096),(7672,669133,3070),(7673,669133,3117),(7674,669133,3073),(7675,669133,3078),(7676,669133,3110),(7677,669133,3080),(7678,669133,3081),(7679,669133,3115),(7680,669133,3116),(7681,669134,3009),(7682,669134,2882),(7683,669134,2858),(7684,669134,2790),(7685,669134,2797),(7686,669134,2903),(7687,669134,2956),(7688,669134,2810),(7689,669134,2815),(7690,669134,2717),(7691,669134,2902),(7692,669134,2791),(7693,669134,2915),(7694,669134,2905),(7695,669134,2817),(7696,669134,2721),(7697,669134,3067),(7698,669134,3068),(7699,669134,3069),(7700,669134,3070),(7701,669134,3071),(7702,669134,3072),(7703,669134,3073),(7704,669134,3074),(7705,669134,3075),(7706,669134,3076),(7707,669134,3077),(7708,669134,3078),(7709,669134,3079),(7710,669134,3080),(7711,669134,3081),(7712,669134,3082),(7713,669135,2867),(7714,669135,2717),(7715,669135,2815),(7716,669135,2721),(7717,669135,2963),(7718,669135,2739),(7719,669135,2882),(7720,669135,2838),(7721,669135,2927),(7722,669135,2858),(7723,669135,2790),(7724,669135,2903),(7725,669135,2901),(7726,669135,2888),(7727,669135,2902),(7728,669135,2905),(7729,669135,3094),(7730,669135,3084),(7731,669135,3075),(7732,669135,3095),(7733,669135,3083),(7734,669135,3076),(7735,669135,3096),(7736,669135,3070),(7737,669135,3117),(7738,669135,3098),(7739,669135,3078),(7740,669135,3110),(7741,669135,3080),(7742,669135,3081),(7743,669135,3074),(7744,669135,3116),(7745,669136,2927),(7746,669136,2724),(7747,669136,2858),(7748,669136,2790),(7749,669136,2841),(7750,669136,2903),(7751,669136,2956),(7752,669136,2810),(7753,669136,2779),(7754,669136,2964),(7755,669136,2902),(7756,669136,2791),(7757,669136,2949),(7758,669136,2905),(7759,669136,2868),(7760,669136,2721),(7761,669136,3083),(7762,669136,3084),(7763,669136,3069),(7764,669136,3070),(7765,669136,3071),(7766,669136,3085),(7767,669136,3086),(7768,669136,3073),(7769,669136,3075),(7770,669136,3076),(7771,669136,3077),(7772,669136,3078),(7773,669136,3079),(7774,669136,3081),(7775,669136,3087),(7776,669136,3082),(7777,669137,2867),(7778,669137,2717),(7779,669137,2815),(7780,669137,2721),(7781,669137,2963),(7782,669137,2739),(7783,669137,2882),(7784,669137,2838),(7785,669137,2927),(7786,669137,2858),(7787,669137,2790),(7788,669137,2903),(7789,669137,2901),(7790,669137,2888),(7791,669137,2902),(7792,669137,2905),(7793,669137,3094),(7794,669137,3084),(7795,669137,3075),(7796,669137,3095),(7797,669137,3118),(7798,669137,3076),(7799,669137,3119),(7800,669137,3070),(7801,669137,3117),(7802,669137,3073),(7803,669137,3099),(7804,669137,3079),(7805,669137,3080),(7806,669137,3081),(7807,669137,3115),(7808,669137,3082),(7809,669138,2723),(7810,669138,2882),(7811,669138,2858),(7812,669138,2870),(7813,669138,2797),(7814,669138,2903),(7815,669138,2782),(7816,669138,2888),(7817,669138,2815),(7818,669138,2822),(7819,669138,2902),(7820,669138,2828),(7821,669138,2789),(7822,669138,3003),(7823,669138,2728),(7824,669138,2834),(7825,669138,3083),(7826,669138,3084),(7827,669138,3069),(7828,669138,3070),(7829,669138,3071),(7830,669138,3085),(7831,669138,3086),(7832,669138,3073),(7833,669138,3075),(7834,669138,3076),(7835,669138,3077),(7836,669138,3078),(7837,669138,3079),(7838,669138,3081),(7839,669138,3087),(7840,669138,3082),(7841,669139,2927),(7842,669139,2962),(7843,669139,2858),(7844,669139,2975),(7845,669139,2963),(7846,669139,2903),(7847,669139,2901),(7848,669139,2888),(7849,669139,2779),(7850,669139,2717),(7851,669139,2969),(7852,669139,2965),(7853,669139,2867),(7854,669139,2952),(7855,669139,2728),(7856,669139,2834),(7857,669139,3090),(7858,669139,3113),(7859,669139,3075),(7860,669139,3088),(7861,669139,3118),(7862,669139,3076),(7863,669139,3092),(7864,669139,3120),(7865,669139,3077),(7866,669139,3106),(7867,669139,3078),(7868,669139,3089),(7869,669139,3111),(7870,669139,3081),(7871,669139,3087),(7872,669139,3082),(7873,669140,2815),(7874,669140,2964),(7875,669140,2966),(7876,669140,2791),(7877,669140,2867),(7878,669140,2952),(7879,669140,2817),(7880,669140,2974),(7881,669140,2927),(7882,669140,2962),(7883,669140,2858),(7884,669140,2870),(7885,669140,2963),(7886,669140,2903),(7887,669140,2901),(7888,669140,2888),(7889,669140,3069),(7890,669140,3084),(7891,669140,3121),(7892,669140,3071),(7893,669140,3122),(7894,669140,3104),(7895,669140,3092),(7896,669140,3109),(7897,669140,3077),(7898,669140,3106),(7899,669140,3099),(7900,669140,3079),(7901,669140,3080),(7902,669140,3081),(7903,669140,3087),(7904,669140,3082),(7905,669141,2927),(7906,669141,2962),(7907,669141,2858),(7908,669141,2975),(7909,669141,2841),(7910,669141,2903),(7911,669141,2901),(7912,669141,2888),(7913,669141,2779),(7914,669141,2717),(7915,669141,2969),(7916,669141,2965),(7917,669141,2867),(7918,669141,2973),(7919,669141,2728),(7920,669141,2834),(7921,669141,3100),(7922,669141,3101),(7923,669141,3075),(7924,669141,3088),(7925,669141,3122),(7926,669141,3076),(7927,669141,3068),(7928,669141,3070),(7929,669141,3077),(7930,669141,3106),(7931,669141,3078),(7932,669141,3089),(7933,669141,3111),(7934,669141,3081),(7935,669141,3087),(7936,669141,3082),(7937,669142,2913),(7938,669142,2827),(7939,669142,2964),(7940,669142,2728),(7941,669142,2969),(7942,669142,2870),(7943,669142,2952),(7944,669142,2841),(7945,669142,2779),(7946,669142,2834),(7947,669142,2927),(7948,669142,2962),(7949,669142,2858),(7950,669142,2903),(7951,669142,2901),(7952,669142,2888),(7953,669142,3094),(7954,669142,3084),(7955,669142,3075),(7956,669142,3071),(7957,669142,3072),(7958,669142,3076),(7959,669142,3119),(7960,669142,3109),(7961,669142,3077),(7962,669142,3123),(7963,669142,3078),(7964,669142,3110),(7965,669142,3111),(7966,669142,3081),(7967,669142,3124),(7968,669142,3082),(7969,669143,2927),(7970,669143,2962),(7971,669143,2858),(7972,669143,2975),(7973,669143,2841),(7974,669143,2903),(7975,669143,2901),(7976,669143,2888),(7977,669143,2779),(7978,669143,2964),(7979,669143,2969),(7980,669143,2913),(7981,669143,2827),(7982,669143,2973),(7983,669143,2728),(7984,669143,2834),(7985,669143,3094),(7986,669143,3125),(7987,669143,3102),(7988,669143,3126),(7989,669143,3083),(7990,669143,3127),(7991,669143,3128),(7992,669143,3109),(7993,669143,3077),(7994,669143,3106),(7995,669143,3078),(7996,669143,3110),(7997,669143,3111),(7998,669143,3081),(7999,669143,3087),(8000,669143,3082),(8001,669144,2779),(8002,669144,2964),(8003,669144,2969),(8004,669144,2913),(8005,669144,2827),(8006,669144,2973),(8007,669144,2728),(8008,669144,2834),(8009,669144,2927),(8010,669144,2962),(8011,669144,2858),(8012,669144,2975),(8013,669144,2841),(8014,669144,2903),(8015,669144,2901),(8016,669144,2888),(8017,669144,3094),(8018,669144,3101),(8019,669144,3107),(8020,669144,3108),(8021,669144,3083),(8022,669144,3104),(8023,669144,3092),(8024,669144,3109),(8025,669144,3077),(8026,669144,3106),(8027,669144,3078),(8028,669144,3110),(8029,669144,3111),(8030,669144,3081),(8031,669144,3087),(8032,669144,3082),(8033,669145,3009),(8034,669145,2718),(8035,669145,2763),(8036,669145,3031),(8037,669145,2797),(8038,669145,2903),(8039,669145,2956),(8040,669145,2888),(8041,669145,2779),(8042,669145,2964),(8043,669145,2902),(8044,669145,2739),(8045,669145,2789),(8046,669145,2905),(8047,669145,2868),(8048,669145,2834),(8049,669145,3083),(8050,669145,3108),(8051,669145,3069),(8052,669145,3070),(8053,669145,3089),(8054,669145,3085),(8055,669145,3113),(8056,669145,3086),(8057,669145,3075),(8058,669145,3076),(8059,669145,3077),(8060,669145,3106),(8061,669145,3078),(8062,669145,3081),(8063,669145,3087),(8064,669145,3082),(8065,669146,2867),(8066,669146,2717),(8067,669146,2815),(8068,669146,2721),(8069,669146,2963),(8070,669146,2739),(8071,669146,2882),(8072,669146,2838),(8073,669146,2927),(8074,669146,2858),(8075,669146,2790),(8076,669146,2903),(8077,669146,2901),(8078,669146,2888),(8079,669146,2902),(8080,669146,2905),(8081,669146,3090),(8082,669146,3091),(8083,669146,3075),(8084,669146,3071),(8085,669146,3083),(8086,669146,3076),(8087,669146,3096),(8088,669146,3070),(8089,669146,3112),(8090,669146,3098),(8091,669146,3078),(8092,669146,3079),(8093,669146,3080),(8094,669146,3081),(8095,669146,3074),(8096,669146,3116),(8097,669147,2723),(8098,669147,2724),(8099,669147,2858),(8100,669147,2975),(8101,669147,2797),(8102,669147,2903),(8103,669147,2991),(8104,669147,3037),(8105,669147,2815),(8106,669147,2822),(8107,669147,2902),(8108,669147,2828),(8109,669147,2789),(8110,669147,2905),(8111,669147,2728),(8112,669147,2834),(8113,669147,3088),(8114,669147,3084),(8115,669147,3069),(8116,669147,3070),(8117,669147,3072),(8118,669147,3089),(8119,669147,3086),(8120,669147,3073),(8121,669147,3075),(8122,669147,3076),(8123,669147,3077),(8124,669147,3078),(8125,669147,3080),(8126,669147,3081),(8127,669147,3087),(8128,669147,3082),(8129,669148,2927),(8130,669148,2724),(8131,669148,2763),(8132,669148,2870),(8133,669148,2797),(8134,669148,2903),(8135,669148,2782),(8136,669148,2810),(8137,669148,2815),(8138,669148,2822),(8139,669148,2902),(8140,669148,2828),(8141,669148,2789),(8142,669148,2905),(8143,669148,2817),(8144,669148,2721),(8145,669148,3088),(8146,669148,3084),(8147,669148,3069),(8148,669148,3070),(8149,669148,3072),(8150,669148,3089),(8151,669148,3086),(8152,669148,3073),(8153,669148,3075),(8154,669148,3076),(8155,669148,3077),(8156,669148,3078),(8157,669148,3080),(8158,669148,3081),(8159,669148,3087),(8160,669148,3082),(8161,669149,2867),(8162,669149,2717),(8163,669149,2815),(8164,669149,2721),(8165,669149,2963),(8166,669149,2739),(8167,669149,2882),(8168,669149,2838),(8169,669149,2927),(8170,669149,2858),(8171,669149,2790),(8172,669149,2903),(8173,669149,2901),(8174,669149,2888),(8175,669149,2902),(8176,669149,2905),(8177,669149,3094),(8178,669149,3084),(8179,669149,3075),(8180,669149,3095),(8181,669149,3083),(8182,669149,3076),(8183,669149,3096),(8184,669149,3070),(8185,669149,3117),(8186,669149,3073),(8187,669149,3099),(8188,669149,3079),(8189,669149,3080),(8190,669149,3081),(8191,669149,3115),(8192,669149,3116),(8193,669150,2723),(8194,669150,2882),(8195,669150,2858),(8196,669150,2790),(8197,669150,3017),(8198,669150,2903),(8199,669150,2956),(8200,669150,3037),(8201,669150,2815),(8202,669150,2822),(8203,669150,2902),(8204,669150,2791),(8205,669150,3022),(8206,669150,2905),(8207,669150,2868),(8208,669150,2834),(8209,669150,3088),(8210,669150,3084),(8211,669150,3069),(8212,669150,3070),(8213,669150,3072),(8214,669150,3089),(8215,669150,3086),(8216,669150,3073),(8217,669150,3075),(8218,669150,3076),(8219,669150,3077),(8220,669150,3078),(8221,669150,3080),(8222,669150,3081),(8223,669150,3087),(8224,669150,3082),(8225,669151,2867),(8226,669151,2717),(8227,669151,2815),(8228,669151,2721),(8229,669151,2963),(8230,669151,2739),(8231,669151,2882),(8232,669151,2838),(8233,669151,2927),(8234,669151,2858),(8235,669151,2790),(8236,669151,2903),(8237,669151,2901),(8238,669151,2888),(8239,669151,2902),(8240,669151,2905),(8241,669151,3094),(8242,669151,3084),(8243,669151,3075),(8244,669151,3071),(8245,669151,3083),(8246,669151,3076),(8247,669151,3096),(8248,669151,3070),(8249,669151,3077),(8250,669151,3098),(8251,669151,3078),(8252,669151,3110),(8253,669151,3080),(8254,669151,3081),(8255,669151,3074),(8256,669151,3116),(8257,669152,2723),(8258,669152,2962),(8259,669152,2763),(8260,669152,2790),(8261,669152,2963),(8262,669152,2903),(8263,669152,2991),(8264,669152,2888),(8265,669152,2815),(8266,669152,2822),(8267,669152,2902),(8268,669152,2828),(8269,669152,2949),(8270,669152,2905),(8271,669152,2817),(8272,669152,2721),(8273,669152,3088),(8274,669152,3084),(8275,669152,3069),(8276,669152,3070),(8277,669152,3072),(8278,669152,3089),(8279,669152,3086),(8280,669152,3073),(8281,669152,3075),(8282,669152,3076),(8283,669152,3077),(8284,669152,3078),(8285,669152,3080),(8286,669152,3081),(8287,669152,3087),(8288,669152,3082),(8289,669153,3009),(8290,669153,2724),(8291,669153,2858),(8292,669153,2790),(8293,669153,2797),(8294,669153,2903),(8295,669153,2956),(8296,669153,2810),(8297,669153,3042),(8298,669153,2822),(8299,669153,2902),(8300,669153,2791),(8301,669153,2949),(8302,669153,2905),(8303,669153,2728),(8304,669153,2721),(8305,669153,3088),(8306,669153,3068),(8307,669153,3069),(8308,669153,3070),(8309,669153,3072),(8310,669153,3089),(8311,669153,3113),(8312,669153,3074),(8313,669153,3075),(8314,669153,3076),(8315,669153,3077),(8316,669153,3106),(8317,669153,3078),(8318,669153,3080),(8319,669153,3081),(8320,669153,3082),(8321,669154,2927),(8322,669154,2882),(8323,669154,2858),(8324,669154,2790),(8325,669154,2797),(8326,669154,2951),(8327,669154,2956),(8328,669154,2810),(8329,669154,2779),(8330,669154,2717),(8331,669154,2902),(8332,669154,2791),(8333,669154,2789),(8334,669154,2973),(8335,669154,2728),(8336,669154,2721),(8337,669154,3088),(8338,669154,3068),(8339,669154,3069),(8340,669154,3070),(8341,669154,3072),(8342,669154,3089),(8343,669154,3113),(8344,669154,3074),(8345,669154,3075),(8346,669154,3076),(8347,669154,3077),(8348,669154,3106),(8349,669154,3078),(8350,669154,3080),(8351,669154,3081),(8352,669154,3082),(8353,669155,3009),(8354,669155,2882),(8355,669155,2858),(8356,669155,2790),(8357,669155,2797),(8358,669155,2971),(8359,669155,2956),(8360,669155,2810),(8361,669155,2815),(8362,669155,2717),(8363,669155,2902),(8364,669155,2791),(8365,669155,2789),(8366,669155,2905),(8367,669155,2817),(8368,669155,2721),(8369,669155,3083),(8370,669155,3084),(8371,669155,3092),(8372,669155,3070),(8373,669155,3071),(8374,669155,3085),(8375,669155,3129),(8376,669155,3073),(8377,669155,3094),(8378,669155,3075),(8379,669155,3077),(8380,669155,3078),(8381,669155,3079),(8382,669155,3081),(8383,669155,3087),(8384,669155,3082),(8385,669156,2867),(8386,669156,2717),(8387,669156,2815),(8388,669156,2721),(8389,669156,2963),(8390,669156,2739),(8391,669156,2882),(8392,669156,2838),(8393,669156,2927),(8394,669156,2858),(8395,669156,2790),(8396,669156,2903),(8397,669156,2901),(8398,669156,2888),(8399,669156,2902),(8400,669156,2905),(8401,669156,3090),(8402,669156,3091),(8403,669156,3075),(8404,669156,3095),(8405,669156,3083),(8406,669156,3076),(8407,669156,3096),(8408,669156,3070),(8409,669156,3117),(8410,669156,3073),(8411,669156,3078),(8412,669156,3089),(8413,669156,3080),(8414,669156,3081),(8415,669156,3074),(8416,669156,3116),(8417,669157,2867),(8418,669157,2717),(8419,669157,2815),(8420,669157,2721),(8421,669157,2963),(8422,669157,2739),(8423,669157,2882),(8424,669157,2838),(8425,669157,2927),(8426,669157,2858),(8427,669157,2790),(8428,669157,2903),(8429,669157,2901),(8430,669157,2888),(8431,669157,2902),(8432,669157,2905),(8433,669157,3094),(8434,669157,3084),(8435,669157,3075),(8436,669157,3071),(8437,669157,3083),(8438,669157,3076),(8439,669157,3092),(8440,669157,3070),(8441,669157,3077),(8442,669157,3073),(8443,669157,3078),(8444,669157,3079),(8445,669157,3080),(8446,669157,3081),(8447,669157,3115),(8448,669157,3130),(8449,669158,2723),(8450,669158,2967),(8451,669158,2858),(8452,669158,2790),(8453,669158,2797),(8454,669158,2903),(8455,669158,2782),(8456,669158,3037),(8457,669158,2779),(8458,669158,2717),(8459,669158,2902),(8460,669158,2791),(8461,669158,2915),(8462,669158,2905),(8463,669158,2992),(8464,669158,2721),(8465,669158,3088),(8466,669158,3084),(8467,669158,3092),(8468,669158,3070),(8469,669158,3072),(8470,669158,3089),(8471,669158,3131),(8472,669158,3129),(8473,669158,3075),(8474,669158,3077),(8475,669158,3106),(8476,669158,3078),(8477,669158,3080),(8478,669158,3081),(8479,669158,3087),(8480,669158,3082),(8481,669159,3051),(8482,669159,2724),(8483,669159,2858),(8484,669159,2790),(8485,669159,2841),(8486,669159,2951),(8487,669159,2956),(8488,669159,2888),(8489,669159,2815),(8490,669159,2964),(8491,669159,2902),(8492,669159,2791),(8493,669159,2789),(8494,669159,2905),(8495,669159,2868),(8496,669159,2834),(8497,669159,3083),(8498,669159,3084),(8499,669159,3069),(8500,669159,3070),(8501,669159,3071),(8502,669159,3085),(8503,669159,3086),(8504,669159,3073),(8505,669159,3075),(8506,669159,3076),(8507,669159,3077),(8508,669159,3078),(8509,669159,3079),(8510,669159,3081),(8511,669159,3087),(8512,669159,3082),(8513,669160,2815),(8514,669160,2964),(8515,669160,2969),(8516,669160,2913),(8517,669160,2827),(8518,669160,2952),(8519,669160,2958),(8520,669160,3015),(8521,669160,2927),(8522,669160,2962),(8523,669160,2858),(8524,669160,2790),(8525,669160,2797),(8526,669160,2903),(8527,669160,2901),(8528,669160,2888),(8529,669160,3131),(8530,669160,3101),(8531,669160,3107),(8532,669160,3108),(8533,669160,3118),(8534,669160,3129),(8535,669160,3119),(8536,669160,3120),(8537,669160,3077),(8538,669160,3106),(8539,669160,3078),(8540,669160,3079),(8541,669160,3080),(8542,669160,3081),(8543,669160,3087),(8544,669160,3082),(8545,669161,2815),(8546,669161,2753),(8547,669161,2995),(8548,669161,2828),(8549,669161,2867),(8550,669161,2952),(8551,669161,2958),(8552,669161,3015),(8553,669161,2927),(8554,669161,2962),(8555,669161,2858),(8556,669161,2790),(8557,669161,2797),(8558,669161,2903),(8559,669161,2901),(8560,669161,2888),(8561,669161,3100),(8562,669161,3113),(8563,669161,3102),(8564,669161,3088),(8565,669161,3103),(8566,669161,3132),(8567,669161,3086),(8568,669161,3120),(8569,669161,3077),(8570,669161,3106),(8571,669161,3078),(8572,669161,3079),(8573,669161,3080),(8574,669161,3081),(8575,669161,3087),(8576,669161,3082),(8577,669162,2867),(8578,669162,2717),(8579,669162,2815),(8580,669162,2721),(8581,669162,2963),(8582,669162,2739),(8583,669162,2882),(8584,669162,2838),(8585,669162,2927),(8586,669162,2858),(8587,669162,2790),(8588,669162,2903),(8589,669162,2901),(8590,669162,2888),(8591,669162,2902),(8592,669162,2905),(8593,669162,3094),(8594,669162,3091),(8595,669162,3075),(8596,669162,3088),(8597,669162,3072),(8598,669162,3076),(8599,669162,3092),(8600,669162,3133),(8601,669162,3112),(8602,669162,3123),(8603,669162,3078),(8604,669162,3079),(8605,669162,3111),(8606,669162,3081),(8607,669162,3115),(8608,669162,3082),(8609,669163,2927),(8610,669163,2882),(8611,669163,2763),(8612,669163,2870),(8613,669163,2797),(8614,669163,2903),(8615,669163,2956),(8616,669163,2810),(8617,669163,2815),(8618,669163,2822),(8619,669163,2902),(8620,669163,2828),(8621,669163,2789),(8622,669163,2905),(8623,669163,2817),(8624,669163,2721),(8625,669163,3083),(8626,669163,3084),(8627,669163,3069),(8628,669163,3070),(8629,669163,3071),(8630,669163,3085),(8631,669163,3086),(8632,669163,3073),(8633,669163,3075),(8634,669163,3076),(8635,669163,3077),(8636,669163,3078),(8637,669163,3079),(8638,669163,3081),(8639,669163,3087),(8640,669163,3082),(8641,669164,2723),(8642,669164,2882),(8643,669164,2858),(8644,669164,2790),(8645,669164,2841),(8646,669164,2903),(8647,669164,2991),(8648,669164,2972),(8649,669164,2779),(8650,669164,2717),(8651,669164,2902),(8652,669164,2791),(8653,669164,3022),(8654,669164,2905),(8655,669164,2817),(8656,669164,2721),(8657,669164,3088),(8658,669164,3103),(8659,669164,3069),(8660,669164,3070),(8661,669164,3089),(8662,669164,3085),(8663,669164,3113),(8664,669164,3086),(8665,669164,3075),(8666,669164,3076),(8667,669164,3077),(8668,669164,3106),(8669,669164,3078),(8670,669164,3081),(8671,669164,3087),(8672,669164,3082),(8673,669165,2913),(8674,669165,2717),(8675,669165,2815),(8676,669165,2721),(8677,669165,2870),(8678,669165,2915),(8679,669165,2882),(8680,669165,2838),(8681,669165,2927),(8682,669165,2858),(8683,669165,2797),(8684,669165,2903),(8685,669165,2901),(8686,669165,2888),(8687,669165,2902),(8688,669165,2905),(8689,669165,3090),(8690,669165,3091),(8691,669165,3075),(8692,669165,3088),(8693,669165,3134),(8694,669165,3076),(8695,669165,3096),(8696,669165,3070),(8697,669165,3112),(8698,669165,3098),(8699,669165,3078),(8700,669165,3089),(8701,669165,3080),(8702,669165,3081),(8703,669165,3074),(8704,669165,3116),(8705,669166,2913),(8706,669166,2717),(8707,669166,2815),(8708,669166,2721),(8709,669166,2870),(8710,669166,2915),(8711,669166,2882),(8712,669166,2838),(8713,669166,2927),(8714,669166,2858),(8715,669166,2797),(8716,669166,2903),(8717,669166,2901),(8718,669166,2888),(8719,669166,2902),(8720,669166,2905),(8721,669166,3090),(8722,669166,3091),(8723,669166,3075),(8724,669166,3088),(8725,669166,3072),(8726,669166,3076),(8727,669166,3096),(8728,669166,3070),(8729,669166,3077),(8730,669166,3073),(8731,669166,3078),(8732,669166,3089),(8733,669166,3080),(8734,669166,3081),(8735,669166,3074),(8736,669166,3116),(8737,669167,3009),(8738,669167,2882),(8739,669167,2858),(8740,669167,2790),(8741,669167,2797),(8742,669167,2971),(8743,669167,2991),(8744,669167,2722),(8745,669167,2779),(8746,669167,2717),(8747,669167,2902),(8748,669167,2791),(8749,669167,2915),(8750,669167,2905),(8751,669167,2728),(8752,669167,2834),(8753,669167,3088),(8754,669167,3127),(8755,669167,3069),(8756,669167,3070),(8757,669167,3072),(8758,669167,3089),(8759,669167,3113),(8760,669167,3086),(8761,669167,3075),(8762,669167,3077),(8763,669167,3106),(8764,669167,3078),(8765,669167,3080),(8766,669167,3081),(8767,669167,3087),(8768,669167,3082),(8769,669168,2913),(8770,669168,2717),(8771,669168,2815),(8772,669168,2721),(8773,669168,2870),(8774,669168,2915),(8775,669168,2882),(8776,669168,2838),(8777,669168,2927),(8778,669168,2858),(8779,669168,2797),(8780,669168,2903),(8781,669168,2901),(8782,669168,2888),(8783,669168,2902),(8784,669168,2905),(8785,669168,3094),(8786,669168,3084),(8787,669168,3075),(8788,669168,3088),(8789,669168,3072),(8790,669168,3076),(8791,669168,3096),(8792,669168,3070),(8793,669168,3112),(8794,669168,3098),(8795,669168,3078),(8796,669168,3079),(8797,669168,3080),(8798,669168,3081),(8799,669168,3074),(8800,669168,3116),(8801,669169,2913),(8802,669169,2717),(8803,669169,2815),(8804,669169,2721),(8805,669169,2870),(8806,669169,2915),(8807,669169,2882),(8808,669169,2838),(8809,669169,2927),(8810,669169,2858),(8811,669169,2797),(8812,669169,2903),(8813,669169,2901),(8814,669169,2888),(8815,669169,2902),(8816,669169,2905),(8817,669169,3069),(8818,669169,3091),(8819,669169,3075),(8820,669169,3071),(8821,669169,3083),(8822,669169,3076),(8823,669169,3068),(8824,669169,3109),(8825,669169,3097),(8826,669169,3073),(8827,669169,3078),(8828,669169,3079),(8829,669169,3085),(8830,669169,3081),(8831,669169,3074),(8832,669169,3082),(8833,669170,2913),(8834,669170,2717),(8835,669170,2815),(8836,669170,2721),(8837,669170,2870),(8838,669170,2915),(8839,669170,2882),(8840,669170,2838),(8841,669170,2927),(8842,669170,2858),(8843,669170,2797),(8844,669170,2903),(8845,669170,2901),(8846,669170,2888),(8847,669170,2902),(8848,669170,2905),(8849,669170,3069),(8850,669170,3091),(8851,669170,3075),(8852,669170,3071),(8853,669170,3083),(8854,669170,3076),(8855,669170,3068),(8856,669170,3070),(8857,669170,3077),(8858,669170,3073),(8859,669170,3078),(8860,669170,3089),(8861,669170,3080),(8862,669170,3081),(8863,669170,3074),(8864,669170,3082),(8865,669171,2927),(8866,669171,2882),(8867,669171,2858),(8868,669171,2790),(8869,669171,2797),(8870,669171,2903),(8871,669171,2991),(8872,669171,2972),(8873,669171,2819),(8874,669171,2717),(8875,669171,2902),(8876,669171,2955),(8877,669171,2789),(8878,669171,2905),(8879,669171,2728),(8880,669171,2721),(8881,669171,3083),(8882,669171,3068),(8883,669171,3069),(8884,669171,3070),(8885,669171,3071),(8886,669171,3085),(8887,669171,3113),(8888,669171,3074),(8889,669171,3075),(8890,669171,3076),(8891,669171,3077),(8892,669171,3106),(8893,669171,3078),(8894,669171,3079),(8895,669171,3081),(8896,669171,3082),(8897,669172,2927),(8898,669172,2882),(8899,669172,2858),(8900,669172,2790),(8901,669172,2797),(8902,669172,2971),(8903,669172,2782),(8904,669172,2888),(8905,669172,2815),(8906,669172,2717),(8907,669172,2902),(8908,669172,2913),(8909,669172,2915),(8910,669172,2905),(8911,669172,2817),(8912,669172,2721),(8913,669172,3083),(8914,669172,3084),(8915,669172,3092),(8916,669172,3070),(8917,669172,3071),(8918,669172,3085),(8919,669172,3131),(8920,669172,3129),(8921,669172,3075),(8922,669172,3077),(8923,669172,3106),(8924,669172,3078),(8925,669172,3079),(8926,669172,3081),(8927,669172,3087),(8928,669172,3082),(8929,669173,2913),(8930,669173,2717),(8931,669173,2815),(8932,669173,2721),(8933,669173,2870),(8934,669173,2915),(8935,669173,2882),(8936,669173,2838),(8937,669173,2927),(8938,669173,2858),(8939,669173,2797),(8940,669173,2903),(8941,669173,2901),(8942,669173,2888),(8943,669173,2902),(8944,669173,2905),(8945,669173,3090),(8946,669173,3125),(8947,669173,3075),(8948,669173,3088),(8949,669173,3134),(8950,669173,3076),(8951,669173,3096),(8952,669173,3070),(8953,669173,3077),(8954,669173,3073),(8955,669173,3078),(8956,669173,3079),(8957,669173,3085),(8958,669173,3081),(8959,669173,3074),(8960,669173,3116),(8961,669174,2913),(8962,669174,2717),(8963,669174,2815),(8964,669174,2721),(8965,669174,2870),(8966,669174,2915),(8967,669174,2882),(8968,669174,2838),(8969,669174,2927),(8970,669174,2858),(8971,669174,2797),(8972,669174,2903),(8973,669174,2901),(8974,669174,2888),(8975,669174,2902),(8976,669174,2905),(8977,669174,3090),(8978,669174,3091),(8979,669174,3075),(8980,669174,3088),(8981,669174,3072),(8982,669174,3076),(8983,669174,3092),(8984,669174,3070),(8985,669174,3077),(8986,669174,3073),(8987,669174,3078),(8988,669174,3079),(8989,669174,3085),(8990,669174,3081),(8991,669174,3074),(8992,669174,3082),(8993,669175,3051),(8994,669175,2882),(8995,669175,3016),(8996,669175,2790),(8997,669175,2841),(8998,669175,2903),(8999,669175,2956),(9000,669175,2722),(9001,669175,2815),(9002,669175,2822),(9003,669175,2902),(9004,669175,2791),(9005,669175,2789),(9006,669175,2905),(9007,669175,2868),(9008,669175,2834),(9009,669175,3083),(9010,669175,3068),(9011,669175,3069),(9012,669175,3101),(9013,669175,3071),(9014,669175,3085),(9015,669175,3135),(9016,669175,3105),(9017,669175,3076),(9018,669175,3077),(9019,669175,3106),(9020,669175,3078),(9021,669175,3079),(9022,669175,3081),(9023,669175,3087),(9024,669175,3082),(9025,669176,2867),(9026,669176,2717),(9027,669176,2815),(9028,669176,2721),(9029,669176,2963),(9030,669176,2739),(9031,669176,2882),(9032,669176,2838),(9033,669176,2927),(9034,669176,2858),(9035,669176,2790),(9036,669176,2903),(9037,669176,2901),(9038,669176,2888),(9039,669176,2902),(9040,669176,2905),(9041,669176,3094),(9042,669176,3091),(9043,669176,3075),(9044,669176,3088),(9045,669176,3072),(9046,669176,3076),(9047,669176,3096),(9048,669176,3133),(9049,669176,3112),(9050,669176,3123),(9051,669176,3078),(9052,669176,3079),(9053,669176,3111),(9054,669176,3081),(9055,669176,3115),(9056,669176,3116),(9057,669177,2927),(9058,669177,2724),(9059,669177,2858),(9060,669177,2975),(9061,669177,2797),(9062,669177,2951),(9063,669177,2956),(9064,669177,2810),(9065,669177,2779),(9066,669177,2717),(9067,669177,2902),(9068,669177,2791),(9069,669177,2789),(9070,669177,2905),(9071,669177,2728),(9072,669177,2721),(9073,669177,3088),(9074,669177,3068),(9075,669177,3069),(9076,669177,3070),(9077,669177,3072),(9078,669177,3089),(9079,669177,3113),(9080,669177,3074),(9081,669177,3075),(9082,669177,3076),(9083,669177,3077),(9084,669177,3106),(9085,669177,3078),(9086,669177,3080),(9087,669177,3081),(9088,669177,3082),(9089,669178,2927),(9090,669178,2962),(9091,669178,2858),(9092,669178,2790),(9093,669178,2797),(9094,669178,2903),(9095,669178,2901),(9096,669178,2888),(9097,669178,2819),(9098,669178,2887),(9099,669178,2966),(9100,669178,2913),(9101,669178,2827),(9102,669178,2996),(9103,669178,2728),(9104,669178,2976),(9105,669178,3100),(9106,669178,3113),(9107,669178,3135),(9108,669178,3108),(9109,669178,3083),(9110,669178,3104),(9111,669178,3092),(9112,669178,3070),(9113,669178,3077),(9114,669178,3106),(9115,669178,3078),(9116,669178,3079),(9117,669178,3080),(9118,669178,3081),(9119,669178,3087),(9120,669178,3082); +/*!40000 ALTER TABLE `OpeningsByMatch` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `OpeningsByPuzzle` +-- + +LOCK TABLES `OpeningsByPuzzle` WRITE; +/*!40000 ALTER TABLE `OpeningsByPuzzle` DISABLE KEYS */; +/*!40000 ALTER TABLE `OpeningsByPuzzle` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `Players` +-- + +LOCK TABLES `Players` WRITE; +/*!40000 ALTER TABLE `Players` DISABLE KEYS */; +INSERT INTO `Players` VALUES (371,'bot_ShallowBlue',NULL,'','2026-03-04 09:04:54',1252,31,0,1),(372,'bot_Arimaazilla',NULL,'','2026-03-04 09:04:54',1514,31,0,1),(2320,'bot_Bomb2005Fast',NULL,'','2026-03-04 09:04:54',2044,31,0,1),(4610,'bot_ArimaaScoreP2',NULL,'','2026-03-04 09:04:54',1272,32,0,1),(16866,'browni3141',NULL,'','2026-03-04 09:04:54',2540,30,0,1),(19291,'bot_Clueless2012P2',NULL,'','2026-03-04 09:04:54',1718,120,0,0),(51609,'KingDel',NULL,'','2026-03-04 09:04:54',2388,30,0,1),(57354,'bestaludulo',NULL,'','2026-03-04 09:04:54',1677,45,0,1),(60869,'bot_rusty_challenge',NULL,'','2026-03-04 09:04:54',1400,120,0,1),(63102,'Axo',NULL,'','2026-03-04 09:04:54',1194,104,0,0),(63152,'bot_dolores_v1',NULL,'','2026-03-04 09:04:54',2644,30,0,1),(63185,'bobmum',NULL,'','2026-03-04 09:04:54',1073,68,0,1),(63194,'Leonidas_05',NULL,'','2026-03-04 09:04:54',1375,109,0,0),(63196,'Jipbi',NULL,'','2026-03-04 09:04:54',1411,119,0,5); +/*!40000 ALTER TABLE `Players` ENABLE KEYS */; +UNLOCK TABLES; + + +-- +-- Dumping data for table `Position` +-- + +LOCK TABLES `Position` WRITE; +/*!40000 ALTER TABLE `Position` DISABLE KEYS */; +INSERT INTO `Position` VALUES (2717,'g','M','b2'),(2718,'g','E','b1'),(2719,'g','M','b3'),(2720,'g','E','b2'),(2721,'g','H','h2'),(2722,'g','H','h1'),(2723,'g','D','a1'),(2724,'g','D','b1'),(2725,'g','M','c3'),(2726,'g','E','b3'),(2727,'g','E','c3'),(2728,'g','H','g2'),(2729,'g','R','g4'),(2730,'g','E','c4'),(2731,'g','E','d4'),(2732,'g','E','e4'),(2733,'g','E','f4'),(2734,'g','E','f5'),(2735,'g','M','d3'),(2736,'g','H','g3'),(2737,'g','H','g4'),(2738,'g','E','g5'),(2739,'g','D','d2'),(2740,'g','H','f4'),(2741,'g','E','g6'),(2742,'g','m','g7'),(2743,'g','m','g6'),(2744,'g','E','f6'),(2745,'g','R','h4'),(2746,'g','H','e4'),(2747,'g','m','e5'),(2748,'g','H','d5'),(2749,'g','E','e5'),(2750,'g','E','d5'),(2751,'g','E','c5'),(2752,'g','m','d6'),(2753,'g','D','b2'),(2754,'g','H','h3'),(2755,'g','H','e5'),(2756,'g','H','f5'),(2757,'g','r','f6'),(2758,'g','r','f5'),(2759,'g','H','g5'),(2760,'g','H','f3'),(2761,'g','r','f4'),(2762,'g','r','f3'),(2763,'g','C','c1'),(2764,'g','h','d6'),(2765,'g','E','e6'),(2766,'g','M','c6'),(2767,'g','r','c7'),(2768,'g','E','d6'),(2769,'g','M','b6'),(2770,'g','h','d4'),(2771,'g','h','c4'),(2772,'g','h','c3'),(2773,'g','r','d6'),(2774,'g','r','d5'),(2775,'g','D','d3'),(2776,'g','r','d4'),(2777,'g','r','d3'),(2778,'g','r','c3'),(2779,'g','R','a2'),(2780,'g','R','a3'),(2781,'g','R','a4'),(2782,'g','C','g1'),(2783,'g','D','b3'),(2784,'g','D','c3'),(2785,'g','D','c4'),(2786,'g','D','e3'),(2787,'g','D','e4'),(2788,'g','D','e5'),(2789,'g','R','e2'),(2790,'g','R','d1'),(2791,'g','R','d2'),(2792,'g','D','d5'),(2793,'g','D','c5'),(2794,'g','R','c4'),(2795,'g','R','e3'),(2796,'g','R','e4'),(2797,'g','R','e1'),(2798,'g','R','e5'),(2799,'g','d','f6'),(2800,'g','d','f5'),(2801,'g','D','c6'),(2802,'g','d','f4'),(2803,'g','d','f3'),(2804,'g','m','g5'),(2805,'g','H','h6'),(2806,'g','H','g6'),(2807,'g','H','f6'),(2808,'g','c','f7'),(2809,'g','c','f6'),(2810,'g','E','h1'),(2811,'g','E','h2'),(2812,'g','E','h3'),(2813,'g','E','g3'),(2814,'g','E','f3'),(2815,'g','H','a2'),(2816,'g','E','e3'),(2817,'g','R','g2'),(2818,'g','H','a3'),(2819,'g','D','a2'),(2820,'g','H','h4'),(2821,'g','r','h5'),(2822,'g','R','b2'),(2823,'g','r','h3'),(2824,'g','r','g3'),(2825,'g','c','g6'),(2826,'g','r','f7'),(2827,'g','M','e2'),(2828,'g','M','d2'),(2829,'g','R','b3'),(2830,'g','D','b5'),(2831,'g','R','b4'),(2832,'g','m','f5'),(2833,'g','d','e6'),(2834,'g','R','h2'),(2835,'g','D','a5'),(2836,'g','H','f7'),(2837,'g','r','g6'),(2838,'g','C','g2'),(2839,'g','C','g3'),(2840,'g','R','b5'),(2841,'g','C','e1'),(2842,'g','E','g4'),(2843,'g','r','g5'),(2844,'g','m','f6'),(2845,'g','M','b4'),(2846,'g','M','b5'),(2847,'g','D','a4'),(2848,'g','D','b4'),(2849,'g','m','g4'),(2850,'g','m','f4'),(2851,'g','D','d4'),(2852,'g','r','e6'),(2853,'g','c','c7'),(2854,'g','m','c5'),(2855,'g','m','c4'),(2856,'g','C','e4'),(2857,'g','R','c5'),(2858,'g','R','c1'),(2859,'g','R','c6'),(2860,'g','D','d6'),(2861,'g','C','e3'),(2862,'g','R','b6'),(2863,'g','D','e7'),(2864,'g','D','d7'),(2865,'g','M','b8'),(2866,'g','R','b7'),(2867,'g','E','e2'),(2868,'g','M','g2'),(2869,'g','H','a1'),(2870,'g','D','d1'),(2871,'g','E','b5'),(2872,'g','H','b3'),(2873,'g','E','b4'),(2874,'g','E','d3'),(2875,'g','M','g3'),(2876,'g','m','d5'),(2877,'g','H','b4'),(2878,'g','H','b5'),(2879,'g','H','c5'),(2880,'g','H','c6'),(2881,'g','E','c6'),(2882,'g','C','b1'),(2883,'g','M','f3'),(2884,'g','M','e3'),(2885,'g','H','c7'),(2886,'g','d','b6'),(2887,'g','C','b2'),(2888,'g','R','h1'),(2889,'g','C','g5'),(2890,'g','E','d7'),(2891,'g','E','d8'),(2892,'g','r','c8'),(2893,'g','E','c7'),(2894,'g','m','b7'),(2895,'g','m','c7'),(2896,'g','E','c8'),(2897,'g','C','f4'),(2898,'g','H','b8'),(2899,'g','H','b7'),(2900,'g','H','b6'),(2901,'g','R','g1'),(2902,'g','R','c2'),(2903,'g','R','f1'),(2904,'g','H','a6'),(2905,'g','R','f2'),(2906,'g','C','d4'),(2907,'g','C','d5'),(2908,'g','h','d3'),(2909,'g','C','b3'),(2910,'g','c','c6'),(2911,'g','C','d6'),(2912,'g','R','e7'),(2913,'g','E','d2'),(2914,'g','d','h5'),(2915,'g','D','e2'),(2916,'g','M','h4'),(2917,'g','M','h5'),(2918,'g','d','h6'),(2919,'g','M','h3'),(2920,'g','d','h4'),(2921,'g','H','h5'),(2922,'g','d','h3'),(2923,'g','d','g3'),(2924,'g','c','g7'),(2925,'g','H','h7'),(2926,'g','H','g7'),(2927,'g','R','a1'),(2928,'g','C','h5'),(2929,'g','C','b4'),(2930,'g','C','b5'),(2931,'g','C','b6'),(2932,'g','C','c5'),(2933,'g','C','e5'),(2934,'g','c','f3'),(2935,'g','C','e6'),(2936,'g','H','e7'),(2937,'g','H','d8'),(2938,'g','H','d7'),(2939,'g','m','a3'),(2940,'g','M','g8'),(2941,'g','R','a5'),(2942,'g','R','a6'),(2943,'g','R','a7'),(2944,'g','r','d7'),(2945,'g','M','c2'),(2946,'g','C','c4'),(2947,'g','M','f2'),(2948,'g','M','e4'),(2949,'g','C','e2'),(2950,'g','C','c3'),(2951,'g','C','f1'),(2952,'g','c','f2'),(2953,'g','c','g4'),(2954,'g','M','d4'),(2955,'g','C','d2'),(2956,'g','D','g1'),(2957,'g','E','c2'),(2958,'g','D','g2'),(2959,'g','D','g4'),(2960,'g','D','g5'),(2961,'g','c','f5'),(2962,'g','R','b1'),(2963,'g','D','e1'),(2964,'g','H','b2'),(2965,'g','H','d2'),(2966,'g','C','c2'),(2967,'g','H','b1'),(2968,'g','H','a4'),(2969,'g','D','c2'),(2970,'g','h','e6'),(2971,'g','D','f1'),(2972,'g','D','h1'),(2973,'g','D','f2'),(2974,'g','M','h2'),(2975,'g','C','d1'),(2976,'g','D','h2'),(2977,'g','E','b6'),(2978,'g','E','a6'),(2979,'g','c','a7'),(2980,'g','E','a5'),(2981,'g','H','a5'),(2982,'g','c','b7'),(2983,'g','E','b7'),(2984,'g','r','h7'),(2985,'g','r','h6'),(2986,'g','H','e3'),(2987,'g','m','e6'),(2988,'g','E','e7'),(2989,'g','C','h3'),(2990,'g','C','d3'),(2991,'g','E','g1'),(2992,'g','E','g2'),(2993,'g','H','g1'),(2994,'g','r','f8'),(2995,'g','h','c2'),(2996,'g','h','f2'),(2997,'g','M','h6'),(2998,'g','c','e7'),(2999,'g','r','g7'),(3000,'g','d','g7'),(3001,'g','d','g6'),(3002,'g','M','f7'),(3003,'g','E','f2'),(3004,'g','E','g7'),(3005,'g','E','f7'),(3006,'g','D','a3'),(3007,'g','D','c7'),(3008,'g','D','b7'),(3009,'g','C','a1'),(3010,'g','E','h4'),(3011,'g','E','h5'),(3012,'g','E','h6'),(3013,'g','C','a2'),(3014,'g','C','a3'),(3015,'g','C','h2'),(3016,'g','D','c1'),(3017,'g','E','e1'),(3018,'g','E','f1'),(3019,'g','C','d7'),(3020,'g','m','a5'),(3021,'g','E','a4'),(3022,'g','H','e2'),(3023,'g','C','a4'),(3024,'g','d','f7'),(3025,'g','D','a6'),(3026,'g','d','c8'),(3027,'g','M','d7'),(3028,'g','H','c8'),(3029,'g','H','a8'),(3030,'g','H','a7'),(3031,'g','H','d1'),(3032,'g','H','e1'),(3033,'g','E','a3'),(3034,'g','m','a6'),(3035,'g','m','a4'),(3036,'g','h','c1'),(3037,'g','C','h1'),(3038,'g','r','e8'),(3039,'g','c','h4'),(3040,'g','c','b8'),(3041,'g','C','h6'),(3042,'g','M','a2'),(3043,'g','c','g8'),(3044,'g','D','g8'),(3045,'g','D','h7'),(3046,'g','M','h1'),(3047,'g','M','g1'),(3048,'g','M','f1'),(3049,'g','M','e1'),(3050,'g','c','a5'),(3051,'g','E','a1'),(3052,'g','E','a2'),(3053,'g','m','e7'),(3054,'g','r','g8'),(3055,'g','h','f8'),(3056,'g','r','b8'),(3057,'g','c','c8'),(3058,'g','r','d8'),(3059,'g','D','f8'),(3060,'g','D','e8'),(3061,'g','D','d8'),(3062,'g','H','g8'),(3063,'g','M','c1'),(3064,'g','H','e8'),(3065,'g','M','f8'),(3066,'g','M','h7'),(3067,'s','e','b7'),(3068,'s','m','g7'),(3069,'s','h','a7'),(3070,'s','h','h7'),(3071,'s','d','d7'),(3072,'s','d','e7'),(3073,'s','c','b8'),(3074,'s','c','g8'),(3075,'s','r','c7'),(3076,'s','r','f7'),(3077,'s','r','a8'),(3078,'s','r','c8'),(3079,'s','r','d8'),(3080,'s','r','e8'),(3081,'s','r','f8'),(3082,'s','r','h8'),(3083,'s','e','e7'),(3084,'s','m','b7'),(3085,'s','d','e8'),(3086,'s','c','g7'),(3087,'s','r','g8'),(3088,'s','e','d7'),(3089,'s','d','d8'),(3090,'s','m','a7'),(3091,'s','r','b7'),(3092,'s','h','g7'),(3093,'s','d','h8'),(3094,'s','r','a7'),(3095,'s','r','d7'),(3096,'s','r','g7'),(3097,'s','h','a8'),(3098,'s','d','b8'),(3099,'s','c','c8'),(3100,'s','d','a7'),(3101,'s','h','b7'),(3102,'s','h','c7'),(3103,'s','m','e7'),(3104,'s','d','f7'),(3105,'s','c','h7'),(3106,'s','r','b8'),(3107,'s','d','c7'),(3108,'s','m','d7'),(3109,'s','r','h7'),(3110,'s','c','d8'),(3111,'s','c','e8'),(3112,'s','c','a8'),(3113,'s','c','b7'),(3114,'s','c','d7'),(3115,'s','d','g8'),(3116,'s','h','h8'),(3117,'s','d','a8'),(3118,'s','h','e7'),(3119,'s','e','g7'),(3120,'s','d','h7'),(3121,'s','e','c7'),(3122,'s','c','e7'),(3123,'s','h','b8'),(3124,'s','h','g8'),(3125,'s','d','b7'),(3126,'s','h','d7'),(3127,'s','m','f7'),(3128,'s','d','g7'),(3129,'s','c','f7'),(3130,'s','c','h8'),(3131,'s','c','a7'),(3132,'s','h','f7'),(3133,'s','m','h7'),(3134,'s','r','e7'),(3135,'s','c','c7'); +/*!40000 ALTER TABLE `Position` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `Puzzles` +-- + +LOCK TABLES `Puzzles` WRITE; +/*!40000 ALTER TABLE `Puzzles` DISABLE KEYS */; +/*!40000 ALTER TABLE `Puzzles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `Solutions` +-- + +LOCK TABLES `Solutions` WRITE; +/*!40000 ALTER TABLE `Solutions` DISABLE KEYS */; +/*!40000 ALTER TABLE `Solutions` ENABLE KEYS */; +UNLOCK TABLES; +SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2026-03-04 11:14:55 diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_62_user.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_62_user.sql new file mode 100644 index 000000000..5d0dd9b3e --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_62_user.sql @@ -0,0 +1,94 @@ +-- ===================================================== +-- Migration: Refactor Players → Users + Players +-- +-- Phase 1: Add user_id column to existing Players table +-- Phase 2: Seed Users from Players, populate user_id +-- Phase 3: Enforce constraints, drop obsolete columns +-- ===================================================== + + +-- ───────────────────────────────────────────────────── +-- PHASE 1: Add user_id FK column to existing Players +-- (nullable for now, so existing rows don't +-- break before we populate it in Phase 2) +-- ───────────────────────────────────────────────────── + +ALTER TABLE `arimaadockermysqldb`.`Players` + ADD COLUMN `user_id` BIGINT NULL AFTER `id`; + + +-- ───────────────────────────────────────────────────── +-- PHASE 2: Create Users table, seed it from Players, +-- then back-fill user_id on every Player row +-- ───────────────────────────────────────────────────── + +CREATE TABLE IF NOT EXISTS `arimaadockermysqldb`.`Users` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `username` VARCHAR(50) NOT NULL, + `email` VARCHAR(254) NOT NULL, + `password` VARCHAR(100) NOT NULL, + `role` VARCHAR(50) NOT NULL, + `created_at` DATETIME(6) NOT NULL, + `updated_at` DATETIME(6) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `username_UNIQUE` (`username`), + UNIQUE INDEX `email_UNIQUE` (`email`) +) ENGINE = InnoDB; + +START TRANSACTION; + +-- Seed Users from every existing Player row. +-- Notes: +-- • email: was nullable in Players, NOT NULL in Users → placeholder used if missing +-- • password: copied as-is; re-hash with bcrypt/argon2 before going to production +-- • created_at/updated_at: seeded from Players.create_time +-- • role: defaulted to 'PLAYER'; adjust if your UserRole enum uses a different value +INSERT INTO `arimaadockermysqldb`.`Users` + (`username`, `email`, `password`, `role`, `created_at`, `updated_at`) +SELECT + `username`, + COALESCE(`email`, CONCAT(`username`, '@unknown.invalid')), + `password`, + 'PLAYER', + COALESCE(`create_time`, CURRENT_TIMESTAMP(6)), + COALESCE(`create_time`, CURRENT_TIMESTAMP(6)) +FROM `arimaadockermysqldb`.`Players`; + +-- Back-fill user_id on each Player by matching username +UPDATE `arimaadockermysqldb`.`Players` p + JOIN `arimaadockermysqldb`.`Users` u ON u.`username` = p.`username` +SET p.`user_id` = u.`id`; + +COMMIT; + + +-- ───────────────────────────────────────────────────── +-- PHASE 3: Enforce NOT NULL + FK on user_id, +-- then drop the columns now owned by Users +-- ───────────────────────────────────────────────────── + +-- Verify every Player has a user_id before locking it down. +-- Uncomment and run manually if you want a safety check first: +-- SELECT COUNT(*) AS missing_user_id +-- FROM `arimaadockermysqldb`.`Players` +-- WHERE `user_id` IS NULL; + +ALTER TABLE `arimaadockermysqldb`.`Players` + -- Lock down user_id + MODIFY COLUMN `user_id` BIGINT NOT NULL, + ADD UNIQUE INDEX `user_id_UNIQUE` (`user_id`), -- this line ensures that the user is indexed so lookup is O(log(n)) + ADD CONSTRAINT `fk_Players_Users` + FOREIGN KEY (`user_id`) + REFERENCES `arimaadockermysqldb`.`Users` (`id`) + ON DELETE CASCADE + ON UPDATE NO ACTION, + + -- Drop indexes that guarded the now-migrated columns + DROP INDEX `username_UNIQUE`, + DROP INDEX `email_UNIQUE`, + + -- Drop the columns that now live in Users + DROP COLUMN `username`, + DROP COLUMN `email`, + DROP COLUMN `password`, + DROP COLUMN `create_time`; \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_62b_default_user.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_62b_default_user.sql new file mode 100644 index 000000000..8f229bc7a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_62b_default_user.sql @@ -0,0 +1,10 @@ +USE `arimaadockermysqldb`; + +INSERT IGNORE INTO `Users` (`username`, `email`, `password`, `role`, `created_at`, `updated_at`) +VALUES + ('admin1', 'admin1@example.com', '$2a$10$a7Dii8pcWQMclYxLt9Kb1eWpbRNbAPTsMRlJkm7ZT.wYIemq4oiBi', 'ADMIN', NOW(), NOW()), + ('user1', 'user1@example.com', '$2a$10$DK1T8LJLPBcPLWhm7i/L1esnux0b7mV0HjMbB02CL794blj0M0lYG', 'USER', NOW(), NOW()) +ON DUPLICATE KEY UPDATE + `password` = VALUES(`password`), + `role` = VALUES(`role`), + `updated_at` = NOW(); \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_63_mandatory3.sql b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_63_mandatory3.sql new file mode 100644 index 000000000..15c2a1130 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/mysql/Sql_arimaa_63_mandatory3.sql @@ -0,0 +1,31 @@ +-- This script is now redundant for fresh installations as the columns are already in Sql_arimaa_10_init.sql. +-- Using a stored procedure to safely add columns only if they don't exist. +DELIMITER // + +CREATE PROCEDURE AddRatingsColumns() +BEGIN + IF NOT EXISTS ( + SELECT * FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = 'arimaadockermysqldb' + AND TABLE_NAME = 'Matches' + AND COLUMN_NAME = 'gold_rating' + ) THEN + ALTER TABLE `arimaadockermysqldb`.`Matches` + ADD COLUMN `gold_rating` INT NULL DEFAULT NULL AFTER `player_id_gold`; + END IF; + + IF NOT EXISTS ( + SELECT * FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = 'arimaadockermysqldb' + AND TABLE_NAME = 'Matches' + AND COLUMN_NAME = 'silver_rating' + ) THEN + ALTER TABLE `arimaadockermysqldb`.`Matches` + ADD COLUMN `silver_rating` INT NULL DEFAULT NULL AFTER `gold_rating`; + END IF; +END // + +DELIMITER ; + +CALL AddRatingsColumns(); +DROP PROCEDURE AddRatingsColumns; \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/mysql/db_model.mwb b/jdk_21_maven/cs/rest/arimaa/Database/mysql/db_model.mwb new file mode 100644 index 000000000..e47cd4c73 Binary files /dev/null and b/jdk_21_maven/cs/rest/arimaa/Database/mysql/db_model.mwb differ diff --git a/jdk_21_maven/cs/rest/arimaa/Database/neo4j/constraints.cypher b/jdk_21_maven/cs/rest/arimaa/Database/neo4j/constraints.cypher new file mode 100644 index 000000000..7e2746fb5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/neo4j/constraints.cypher @@ -0,0 +1,19 @@ +// Run in Neo4j Browser after first startup (or via cypher-shell). + +// Primary IDs (mirrors SQL PKs stored in `id`) +CREATE CONSTRAINT country_id IF NOT EXISTS FOR (n:Country) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT player_id IF NOT EXISTS FOR (n:Player) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT event_id IF NOT EXISTS FOR (n:Event) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT game_type_id IF NOT EXISTS FOR (n:GameType) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT match_id IF NOT EXISTS FOR (n:Match) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT position_id IF NOT EXISTS FOR (n:Position) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT move_id IF NOT EXISTS FOR (n:Move) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT puzzle_id IF NOT EXISTS FOR (n:Puzzle) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT solution_id IF NOT EXISTS FOR (n:Solution) REQUIRE n.id IS UNIQUE; +CREATE CONSTRAINT user_id IF NOT EXISTS FOR (n:User) REQUIRE n.id IS UNIQUE; + +// Uniques from SQL schema (identity lives on User, not Player) +CREATE CONSTRAINT country_name IF NOT EXISTS FOR (n:Country) REQUIRE n.name IS UNIQUE; +CREATE CONSTRAINT puzzle_name IF NOT EXISTS FOR (n:Puzzle) REQUIRE n.name IS UNIQUE; +CREATE CONSTRAINT user_username IF NOT EXISTS FOR (n:User) REQUIRE n.username IS UNIQUE; +CREATE CONSTRAINT user_email IF NOT EXISTS FOR (n:User) REQUIRE n.email IS UNIQUE; diff --git a/jdk_21_maven/cs/rest/arimaa/Database/neo4j/docker-compose.neo4j.yml b/jdk_21_maven/cs/rest/arimaa/Database/neo4j/docker-compose.neo4j.yml new file mode 100644 index 000000000..6019ca4b4 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/neo4j/docker-compose.neo4j.yml @@ -0,0 +1,24 @@ +# Neo4j (Graph DB) +services: + neo4jdb: + image: neo4j:5.26 + container_name: arimaadockerneo4jdb + ports: + - "7474:7474" # Browser / HTTP API + - "7687:7687" # Bolt + environment: + NEO4J_AUTH: ${SPRING_NEO4J_USERNAME}/${SPRING_NEO4J_PASSWORD} + volumes: + - neo4j_data:/data + - neo4j_logs:/logs + - neo4j_import:/import + hostname: arimaadockerneo4jdb + +volumes: + neo4j_data: + driver: local + neo4j_logs: + driver: local + neo4j_import: + driver: local + diff --git a/jdk_21_maven/cs/rest/arimaa/Database/scripts/check-databases.ps1 b/jdk_21_maven/cs/rest/arimaa/Database/scripts/check-databases.ps1 new file mode 100644 index 000000000..4bda160b8 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/scripts/check-databases.ps1 @@ -0,0 +1,71 @@ + +# check-databases.ps1 +# Checks status of MySQL, MongoDB, and Neo4j + + +Write-Host "Database Health Check" +Write-Host "=====================================`n" + +$services = @( + @{ + Name = "MySQL" + Container = "arimaadockermysqldb" + }, + @{ + Name = "MongoDB" + Container = "arimaadockermongodb" + }, + @{ + Name = "Neo4j" + Container = "arimaadockerneo4jdb" + } +) + +foreach ($svc in $services) { + Write-Host "Checking $($svc.Name)..." -ForegroundColor Yellow + + Start-Sleep -Milliseconds 800 + + $containerStatus = docker ps --filter "name=$($svc.Container)" --format "{{.Status}}" 2>$null + + if (-not $containerStatus) { + Write-Host " Container not found or not started yet" -ForegroundColor Red + } + elseif ($containerStatus -like "Up*") { + Write-Host " Container is running" -ForegroundColor Green + + switch ($svc.Name) { + "MySQL" { + $result = docker exec $svc.Container mysqladmin ping -h localhost -u root -p123456 --silent 2>&1 | Out-Null + if ($LASTEXITCODE -eq 0) { + Write-Host " MySQL is responsive" -ForegroundColor Green + } else { + Write-Host " MySQL running but still starting up" -ForegroundColor Yellow + } + } + "MongoDB" { + $result = docker exec $svc.Container mongosh --eval "db.runCommand({ ping: 1 })" --quiet 2>&1 + if ($LASTEXITCODE -eq 0 -and $result) { + Write-Host " MongoDB is responsive" -ForegroundColor Green + } else { + Write-Host " MongoDB running but still starting up" -ForegroundColor Yellow + } + } + "Neo4j" { + $result = docker exec $svc.Container cypher-shell -u neo4j -p arimaa123 "RETURN 'ready' AS status" 2>&1 + if ($LASTEXITCODE -eq 0 -and $result -like "*ready*") { + Write-Host " Neo4j is responsive" -ForegroundColor Green + } else { + Write-Host " Neo4j running but still starting up" -ForegroundColor Yellow + } + } + } + } + else { + Write-Host " Container exists but not running (Status: $containerStatus)" -ForegroundColor Red + } + + Write-Host "" +} + +Write-Host "Health check completed." -ForegroundColor Cyan \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/Database/scripts/debug-migration-neo4j.ps1 b/jdk_21_maven/cs/rest/arimaa/Database/scripts/debug-migration-neo4j.ps1 new file mode 100644 index 000000000..80aebdd7a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/scripts/debug-migration-neo4j.ps1 @@ -0,0 +1,22 @@ +# Script to run Neo4j migration in debug mode +# This script runs the application with the 'migration' profile and +# allows you to attach a debugger on port 5005. + +$ENABLED_STEPS = "user" +$DRY_RUN = "true" +$EXIT_ON_COMPLETE = "false" + +if ($args.Count -ge 1) { $ENABLED_STEPS = $args[0] } +if ($args.Count -ge 2) { $DRY_RUN = $args[1] } +if ($args.Count -ge 3) { $EXIT_ON_COMPLETE = $args[2] } + +Write-Host "Starting migration debug session..." +Write-Host "Enabled steps: $ENABLED_STEPS" +Write-Host "Dry run: $DRY_RUN" +Write-Host "Exit on complete: $EXIT_ON_COMPLETE" +Write-Host "Attach your debugger to localhost:5005" + +.\mvnw.cmd spring-boot:run ` + "-Dspring-boot.run.profiles=migration" ` + "-Dspring-boot.run.jvmArguments=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" ` + "-Dspring-boot.run.arguments=--migration.enabled-steps=$ENABLED_STEPS --migration.dry-run=$DRY_RUN --migration.exit-on-complete=$EXIT_ON_COMPLETE" diff --git a/jdk_21_maven/cs/rest/arimaa/Database/scripts/prepare-and-start.ps1 b/jdk_21_maven/cs/rest/arimaa/Database/scripts/prepare-and-start.ps1 new file mode 100644 index 000000000..7ff815ccc --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/scripts/prepare-and-start.ps1 @@ -0,0 +1,18 @@ +# ============================================= +# prepare-and-start.ps1 +# Restarts databases, performs migrations, and starts the program +# ============================================= + +$ErrorActionPreference = "Continue" # Don't stop on warnings from native commands + +# 1. Restart the databases +Write-Host "Step 1: Restarting all databases..." -ForegroundColor Cyan +& ".\Database\scripts\restart-all-dbs.ps1" + +# 2. Perform migrations +Write-Host "`nStep 2: Performing migrations..." -ForegroundColor Cyan +& ".\mvnw.cmd" spring-boot:run "-Dspring-boot.run.profiles=migration" + +# 3. Start the program +Write-Host "`nStep 3: Starting the program..." -ForegroundColor Cyan +& ".\mvnw.cmd" spring-boot:run diff --git a/jdk_21_maven/cs/rest/arimaa/Database/scripts/restart-all-dbs.ps1 b/jdk_21_maven/cs/rest/arimaa/Database/scripts/restart-all-dbs.ps1 new file mode 100644 index 000000000..401ceb0bd --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/Database/scripts/restart-all-dbs.ps1 @@ -0,0 +1,30 @@ +# ============================================= +# restart-all-dbs.ps1 +# Starts ALL three databases reliably +# ============================================= + +Write-Host "Restarting all 3 databases..." -ForegroundColor Cyan +Write-Host "=====================================`n" + +# Stop everything first (clean state) +Write-Host "Stopping all containers..." -ForegroundColor Yellow +docker compose --env-file .env -f .\Database\docker-compose.mysql.yml down -v --remove-orphans +docker compose --env-file .env -f .\Database\neo4j\docker-compose.neo4j.yml down -v --remove-orphans +docker compose --env-file .env -f .\Database\docker-compose.mongodb.yml down -v --remove-orphans + +Write-Host "`nStarting databases..." -ForegroundColor Green + +# Start them in a good order +docker compose --env-file .env -f .\Database\docker-compose.mysql.yml up -d +Start-Sleep -Seconds 3 +docker compose --env-file .env -f .\Database\docker-compose.mongodb.yml up -d +Start-Sleep -Seconds 2 +docker compose --env-file .env -f .\Database\neo4j\docker-compose.neo4j.yml up -d + +Write-Host "`nAll databases started." -ForegroundColor Green +Write-Host "Waiting 10 seconds for full initialization..." -ForegroundColor Gray +Start-Sleep -Seconds 10 + +# Run health check +.\Database\scripts\check-databases.ps1 + diff --git a/jdk_21_maven/cs/rest/arimaa/MIGRATION_SETUP.md b/jdk_21_maven/cs/rest/arimaa/MIGRATION_SETUP.md new file mode 100644 index 000000000..083863651 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/MIGRATION_SETUP.md @@ -0,0 +1,163 @@ +# Migration Setup Guide (MySQL -> Neo4j and MongoDB) + +This guide explains how the migration system works in this project and how to add new MongoDB migrations. + +The goal is simple: +- Read data from MySQL (source of truth) +- Write to one or more targets (Neo4j and/or MongoDB) +- Choose exactly which targets and steps to run + +--- + +## 1) How the migration architecture works + +### Core pieces + +- `MigrationRunner` + Runs all migration steps in order when profile `migration` is active. + +- `MigrationStep` (interface) + Every migration step implements this interface and provides: + - `stepName()` -> unique id used by config filtering + - `targets()` -> which store(s) this step writes to (`NEO4J`, `MONGODB`) + - `getOrder()` -> execution order (lower runs first) + - `migrate(context)` -> actual migration logic + +- `MigrationProperties` + Reads config from `migration.*` keys: + - `enabled-targets` + - `enabled-steps` + - `batch-size` + - `dry-run` + +- `MigrationTarget` enum + Supported values: + - `neo4j` + - `mongodb` (or `mongo`) + +### Folder structure + +- Neo4j steps: `src/main/java/com/example/arimaabackend/migration/steps/neo4j` +- MongoDB steps: `src/main/java/com/example/arimaabackend/migration/steps/mongodb` + +--- + +## 2) How step filtering works + +The runner applies two filters for each step: + +1. **Target filter** (`migration.enabled-targets`) + Step is skipped if its `targets()` does not match selected targets. + +2. **Step name filter** (`migration.enabled-steps`) + Step is skipped if `stepName()` is not listed. + +If either list is empty, it means "all" for that dimension. + +So: +- empty targets + empty steps -> run everything +- targets only -> run all steps for selected targets +- steps only -> run listed step names across all targets +- targets + steps -> run intersection + +--- + +## 3) Configuration examples + +Use `src/main/resources/application-migration.properties` (or CLI args). + +### Run all migrations + +No `enabled-targets` and no `enabled-steps` set. + +### Run only Neo4j migrations + +```properties +migration.enabled-targets[0]=neo4j +``` + +### Run only MongoDB migrations + +```properties +migration.enabled-targets[0]=mongodb +``` + +### Run only selected steps + +```properties +migration.enabled-steps[0]=country +migration.enabled-steps[1]=user-mongo +``` + +### Dry run + +```properties +migration.dry-run=true +``` + +Dry run should log counts and skip writes. + +--- + +## 4) How to add a new MongoDB migration + +Use `UserMongoMigration` as a reference. + +### Step-by-step + +1. Create a new class in: + - `migration/steps/mongodb` +2. Annotate with: + - `@Service` + - `@Profile("migration")` +3. Implement `MigrationStep` +4. Return a unique `stepName()` (example: `puzzle-mongo`) +5. Set target explicitly: + - `targets()` -> `EnumSet.of(MigrationTarget.MONGODB)` +6. Choose order (`getOrder()`) based on dependencies +7. Implement `migrate(MigrationContext context)`: + - read from SQL repository + - map entity -> Mongo document + - on `dryRun`, log count and return + - otherwise write via Mongo repository + +--- + +## 5) MySQL prerequisite + +The migrator reads the **current** JPA schema (`Users` + `Players.user_id`). That requires the Docker MySQL init scripts to have run through [`Database/mysql/Sql_arimaa_62_user.sql`](Database/mysql/Sql_arimaa_62_user.sql) (not `Sql_arimaa_10_init.sql` alone). + +Start MySQL with the project compose file so all init scripts apply in order. + +--- + +## 6) Step order and step ids + +### Neo4j (lower `getOrder()` runs first) + +`neo4j-schema` → `country` → `event` → `game-type` → `position` → `puzzle` → **`user`** → `player` → `match` → `move` → `solution` → `opening-by-match` → `opening-by-puzzle` + +`user` must run before `player` so `HAS_USER` edges can link to existing `:User` nodes. + +### MongoDB + +`user-mongo` (121) → `player-mongo` (122) → `match-mongo` (123) → `puzzle-mongo` (124) + +### All step ids + +`country`, `event`, `game-type`, `position`, `puzzle`, `user`, `player`, `match`, `move`, `solution`, `opening-by-match`, `opening-by-puzzle`, `neo4j-schema`, `user-mongo`, `player-mongo`, `match-mongo`, `puzzle-mongo` + +--- + +## 7) Common issues and fixes + +- **Bean conflict with same migration class name** + Usually caused by duplicate class/package names or stale `target/classes`. + Fix: keep only one class path + run `mvn clean`. + +- **Step not running** + Check `stepName()` matches `migration.enabled-steps[...]` exactly (case-insensitive, spelling still matters). + +- **Unexpected target execution** + Check `targets()` in the class and `migration.enabled-targets[...]` config. + diff --git a/jdk_21_maven/cs/rest/arimaa/README.md b/jdk_21_maven/cs/rest/arimaa/README.md new file mode 100644 index 000000000..ea222fbf1 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/README.md @@ -0,0 +1,385 @@ +## Arimaa Backend + +Simple Spring Boot backend with: +- Users API (create, get by id) +- MySQL → Neo4j modular migration (profile `migration`) + +## Requirements + +- a secrets file (.env), to be placed in the project root. Get it from the team. +- Java 21 +- Maven +- Databases running locally (defaults): see the .env file (not in git) + +Connection settings are in `src/main/resources/application.properties`. + +## Run the API + +From the project root: + +```bash +mvn spring-boot:run +``` +or, if you use the project's Maven wrapper: +```bash +.\mvnw.cmd spring-boot:run +``` + +Main endpoints: +- `POST /api/users` +- `GET /api/users/{id}` + +## Run the SQL -> Neo4j / MongoDB migration + +### 1) Start databases with Docker + +- From the project root: +restarts the database, perform the migration from mysql to mongo and neo4j +and finally run the program with .\mvnw.cmd spring-boot:run. +``` +.\Database\scripts\prepare-and-start.ps1 +``` +(the script can randomly fail the first time, by "freezing". If it happens, just run it again). +- if you need it later: check that the 3 databases are running: +``` +.\Database\scripts\check-databases.ps1 +``` + + +### 1B) Check that the mysql database is running correctly. +```powershell +docker compose --env-file .env -f .\Database\docker-compose.mysql.yml ps +``` +You should see information about the database. + + + +### 2) Apply Neo4j constraints once + +Run [Database/neo4j/constraints.cypher](Database/neo4j/constraints.cypher) in Neo4j Browser or via `cypher-shell`. + +### 3) Run migration in dry-run mode first + +```powershell +mvn spring-boot:run "-Dspring-boot.run.profiles=migration" "-Dspring-boot.run.arguments=--migration.dry-run=true" +``` +or +``` +.\mvnw.cmd spring-boot:run "-Dspring-boot.run.profiles=migration" "-Dspring-boot.run.arguments=--migration.dry-run=true" +``` + +### 4) Run the real migration + +```powershell +mvn spring-boot:run "-Dspring-boot.run.profiles=migration" "-Dspring-boot.run.arguments=--migration.dry-run=false" +``` +or +``` +.\mvnw.cmd spring-boot:run "-Dspring-boot.run.profiles=migration" "-Dspring-boot.run.arguments=--migration.dry-run=false" +``` + +You can still run from Bash (Git Bash, WSL, macOS, Linux): + +```bash +mvn spring-boot:run -Dspring-boot.run.profiles=migration +``` + +PowerShell note: quote the `-D` flags so the shell does not strip `spring-boot` and break the argument (otherwise Maven may report `Unknown lifecycle phase ".run.profiles=migration"`): + +```powershell +mvn spring-boot:run "-Dspring-boot.run.profiles=migration" +``` + +Or set the profile in the environment, then run without `-D`: + +```powershell +$env:SPRING_PROFILES_ACTIVE = "migration" +mvn spring-boot:run +``` + +This runs modular steps: orchestration in `com.example.arimaabackend.migration` (`MigrationRunner`, config, properties), each entity step in `com.example.arimaabackend.migration.steps` (countries, events, matches, moves, openings, `users` -> Neo4j, `user-mongo` -> MongoDB, etc.). + +Control what runs with: +- `migration.enabled-targets[0]=neo4j` and/or `migration.enabled-targets[1]=mongodb` +- `migration.enabled-steps[0]=...`, `migration.enabled-steps[1]=...` + +Set these keys in `src/main/resources/application-migration.properties` (or pass them via `-Dspring-boot.run.arguments`). + +If either list is omitted, it defaults to `ALL` for that dimension. +Use `migration.dry-run=true` to log counts without writing to target stores. + +**Dependency order** (enforced by each step’s order value): country → event → game-type → position → puzzle → user → player → match → move → solution → opening-by-match → opening-by-puzzle. If you enable only a subset, ensure upstream nodes already exist in Neo4j. + + + +### to work with neo4J + +RUn the docker compose script above. + +to go http://localhost:7474/ in a borwser + +login with the neo4j password (see the .env file (not in git)) + + +Check on the left side in the neo4j browser window, if there is data: +If you see this: +"Database information +Nodes (0)" +Then you need to run the migration script: + +PS C:\Users\CMLyk\IdeaProjects\arimaa-backend> .\mvnw.cmd spring-boot:run "-Dspring-boot.run.profiles=migration" + +--- To delete the database: +docker compose --env-file .env -f .\Database\neo4j\docker-compose.neo4j.yml down -v + +to delete mysql database: +docker compose --env-file .env -f .\Database\docker-compose.mysql.yml down -v + + +### Run Endpoints in postman: +- run docker desktop + +- remove database: docker compose --env-file .env -f .\Database\docker-compose.mysql.yml down -v +- add dataabase: docker compose --env-file .env -f .\Database\docker-compose.mysql.yml up -d + +the down command might fail by "hanging" on windows. If so, try pressing Ctrl+c and running this: +docker compose --env-file .env -f .\Database\docker-compose.mysql.yml down -v --remove-orphans + +verify MySQL: docker compose --env-file .env -f Database\docker-compose.mysql.yml ps + +- start the application: .\mvnw.cmd spring-boot:run + +- you can also try this online script: +docker compose --env-file .env -f .\Database\docker-compose.mysql.yml down -v --remove-orphans; docker compose --env-file .env -f .\Database\docker-compose.mysql.yml up -d ; sleep 20; .\mvnw.cmd spring-boot:run + +### Open the database in datagrip: +- Open docker desktop. +- Make sure the database is running (use the guides above), then verify with + docker compose --env-file .env -f .\Database\docker-compose.mysql.yml ps + +Host: localhost +Port: 5000 +Database: arimaadockermysqldb +User: root +Password: +JDBC URL: jdbc:mysql://localhost:5000/arimaadockermysqldb?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC + + +### Debug migrations + Neo4j + + +1. Create a migration debugging run configuration: + - Go to the top menu: **Run** > **Edit Configurations...** + - Click the **+** (Add New Configuration) button in the top-left corner. + - Select **Remote JVM Debug** from the list. + - Name it: `Migration Debug (5005)` + - In the configuration window, ensure these fields are set: + - **Debugger mode**: `Attach to remote JVM` + - **Host**: `localhost` + - **Port**: `5005` + - Click **OK** to save. + - Keep the new run configuration for later. + +2. Run debug script: +- stop anything that is running (press `Ctrl+C` in the terminal) +- Run the debug script: + ```powershell + .\Database\scripts\debug-migration-neo4j.ps1 user false true + ``` + (The first argument is the step name, the second is whether to dry-run, the third is whether to exit on complete).* + (If you set the second argument to `true` (dry-run), the migration will skip the actual processing logic. To hit breakpoints inside the migration logic (e.g., in `toNode` or after the `dryRun` check), you MUST run it with `false`: + +3. Use your new run configuration `Migration Debug (5005)` to attach the debugger: + - You can now click on the debug button next to the run configuration `Migration Debug (5005)`. + +4. Identify Completion: Look for these messages in the terminal where you ran the script: + - `Finished step 'user' in ... ms` (indicates the specific step finished). + - `Data migration completed.` (indicates the entire runner is done). + +5. you can now run the run the program: .\mvnw.cmd spring-boot:run +and run the neo4j tests. + +### How to verify migration success +Besides looking at the logs, you can verify that the data was correctly written to Neo4j: +1. Open Neo4j Browser: Go to [http://localhost:7474/](http://localhost:7474/). +2. Check Node Counts: Run this Cypher query to see how many nodes were created: + ```cypher + MATCH (n) RETURN labels(n), count(n) + ``` +3. Inspect Specific Nodes: To see the migrated users: + ```cypher + MATCH (u:User) RETURN u LIMIT 25 + ``` + +### Debug playwright tests +To debug the playwright tests here: +src/test/java/com/example/arimaabackend/playwright + +make sure that nothing is running on port 8080 +(in the terminal, press ctrl+C to close .\mvnw.cmd spring-boot:run which might be running) + +Then go to +src/main/java/com/example/arimaabackend/ArimaaBackendApplication.java +and run in debug mode. + +you can now debug the playwright tests and hit breakpoints in the services. +eg. +src/test/java/com/example/arimaabackend/playwright/MatchTest.java +void AsUser_UpdateMatch() throws JsonProcessingException { + +### Identify issues with dataloading +first run these: +- docker compose --env-file .env -f .\Database\docker-compose.mysql.yml down -v --remove-orphans +- docker compose --env-file .env -f .\Database\docker-compose.mysql.yml up -d + +if they dont raise errors, then run this: +- docker compose --env-file .env -f .\Database\docker-compose.mysql.yml logs -f --tail=50 + +# Cloud Deployment + +The project has a partial cloud deployment. + +MongoDB has been deployed using **MongoDB Atlas**, and Neo4j has been deployed using **Neo4j AuraDB**. Both cloud databases were populated using the existing migration application. + +MySQL was also attempted deployed using **Azure Database for MySQL Flexible Server**, but Azure blocked the deployment because of an Azure for Students subscription policy. Because of this, MySQL and the Spring Boot backend currently still run locally. + +## Deployment status + +| Component | Status | +|---|---| +| Spring Boot backend | Runs locally | +| MySQL | Runs locally with Docker | +| MongoDB | Deployed to MongoDB Atlas | +| Neo4j | Deployed to Neo4j AuraDB | +| Migrator | Used to migrate data to MongoDB Atlas and Neo4j AuraDB | +| Azure MySQL | Attempted, but blocked by Azure policy | + +## Access to the cloud databases + +The cloud databases are hosted in shared cloud project instances. + +Access to the MongoDB Atlas and Neo4j AuraDB browser interfaces is not automatic. A group member must either: + +- be invited to the shared MongoDB Atlas / Neo4j AuraDB project, or +- use the shared connection details from the internal group guide. + +Credentials and passwords are not included in this README. + +## MongoDB Atlas guide + +MongoDB Atlas is used for the cloud document database. + +The deployed MongoDB database is: + +```text +arimaadockermysqldb + + +# Watch MongoDO Data + +After running `.\Database\scripts\prepare-and-start.ps1`, +your MongoDB instance will be running in a Docker container on +`localhost:27017`. You can visualize and manage the data using several tools. +Suggestion: use the MongoDB compass desktop client. + +## Full list of viewing options: + +### 1. MongoDB Atlas (Cloud & Browser) +If you want to view your data in a web-based interface similar to Atlas, +you can use the **MongoDB Atlas** cloud service: +- **Atlas Cluster**: Create a free account at [mongodb.com/atlas](https://www.mongodb.com/cloud/atlas). +- **Atlas Compass**: While primarily a desktop app, it provides a "Browser" view for your Atlas clusters. +- **Data API**: Atlas provides a web-based Data Explorer that allows you to query and manage your data directly from your browser. + +*Note: To view your **local** Docker data in the Atlas web interface, +you would typically need to migrate it to a cloud cluster or use a tool like `mongodump`/`mongorestore`.* + +### 2. MongoDB Compass (Recommended Desktop Tool) +While not strictly "in the browser," **MongoDB Compass** is the most powerful GUI for MongoDB: +1. Download and install [MongoDB Compass](https://www.mongodb.com/try/download/compass). +2. Open Compass and use the default connection string: + ```text + mongodb://localhost:27017 + ``` +3. Click **Connect**. You should see the `arimaadockermysqldb` database. + +### 3. Mongo Express (True Browser Interface) +If you want a dedicated browser-based UI, you can add **Mongo Express** to your setup. + +#### Temporary Access (via Docker) +Run this command to start a web-based viewer on [http://localhost:8081](http://localhost:8081): +```powershell +docker run -it --rm --network host -e ME_CONFIG_MONGODB_SERVER=localhost -e ME_CONFIG_MONGODB_PORT=27017 mongo-express +``` + +#### Permanent Integration +To add it to the project permanently, add this service to `Database/docker-compose.mongodb.yml`: +```yaml + mongo-express: + image: mongo-express + container_name: arimaadockermongoexpress + restart: always + ports: + - "8081:8081" + environment: + - ME_CONFIG_MONGODB_SERVER=mongodb + - ME_CONFIG_MONGODB_PORT=27017 + depends_on: + - mongodb +``` +Then restart your databases: `.\Database\scripts\restart-all-dbs.ps1`. +Access the UI at: [http://localhost:8081/](http://localhost:8081/) + + + + + + + + + +# Watch Neo4J Data + +After running `.\Database\scripts\prepare-and-start.ps1`, +your Neo4j instance will be running in a Docker container. +You can visualize and manage the graph data using the following tools. + +Suggestion: go to http://localhost:7474 +- Protocol: neo4j:// +- Connect URL: localhost:7687 +- Database User: neo4j +- Password: arimaa123 + + + +## Full list of tools for viewing Neo4J data: + +## 1. Neo4j Browser (Web Interface) +The easiest way to view your data is through the built-in web interface: +1. Open your browser and go to: [http://localhost:7474](http://localhost:7474) +2. Connect using the following credentials: + - **Connect URL:** `bolt://localhost:7687` + - **Username:** `neo4j` + - **Password:** `arimaa123` +3. Once logged in, you can run Cypher queries (e.g., `MATCH (n) RETURN n LIMIT 25`) to visualize your nodes and relationships. + +## 2. Neo4j Desktop (Recommended Desktop Client) +For a more powerful development environment, you can use **Neo4j Desktop**: +1. Download and install [Neo4j Desktop](https://neo4j.com/download/). +2. Create a new project. +3. Click **Add** -> **Remote Connection**. +4. Enter the connection details: + - **Name:** Arimaa Backend + - **Connect URL:** `bolt://localhost:7687` + - **Authentication:** Username/Password (`neo4j` / `arimaa123`) +5. Click **Connect** and open the database to start exploring. + +## 3. Cypher Shell (CLI) +If you prefer the command line, you can access the shell directly through Docker: +```powershell +docker exec -it arimaadockerneo4jdb cypher-shell -u neo4j -p arimaa123 +``` + + + + diff --git a/jdk_21_maven/cs/rest/arimaa/mvnw b/jdk_21_maven/cs/rest/arimaa/mvnw new file mode 100644 index 000000000..bd8896bf2 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/jdk_21_maven/cs/rest/arimaa/mvnw.cmd b/jdk_21_maven/cs/rest/arimaa/mvnw.cmd new file mode 100644 index 000000000..92450f932 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/jdk_21_maven/cs/rest/arimaa/pom.xml b/jdk_21_maven/cs/rest/arimaa/pom.xml new file mode 100644 index 000000000..2a5bde4bb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/pom.xml @@ -0,0 +1,176 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 4.0.5 + + + com.example + arimaa-backend + 0.0.1-SNAPSHOT + arimaa-backend + arimaa-backend + + + + + + + + + + + + + + + 21 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-data-neo4j + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-docker-compose + runtime + true + + + com.mysql + mysql-connector-j + runtime + + + org.springframework.boot + spring-boot-starter-data-jdbc-test + test + + + org.springframework.boot + spring-boot-starter-jdbc-test + test + + + org.springframework.boot + spring-boot-starter-data-mongodb-test + test + + + org.springframework.boot + spring-boot-starter-data-neo4j-test + test + + + org.springframework.security + spring-security-crypto + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + org.springframework.boot + spring-boot-test-autoconfigure + test + + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-starter-data-jpa-test + test + + + com.h2database + h2 + test + + + com.microsoft.playwright + playwright + 1.59.0 + test + + + io.github.cdimascio + dotenv-java + 3.2.0 + test + + + com.fasterxml.jackson.core + jackson-databind + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.example.arimaabackend.ArimaaBackendApplication + + + + org.apache.maven.plugins + maven-surefire-plugin + + -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar + + + + + + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/ArimaaBackendApplication.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/ArimaaBackendApplication.java new file mode 100644 index 000000000..8256a8296 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/ArimaaBackendApplication.java @@ -0,0 +1,17 @@ +package com.example.arimaabackend; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +import com.example.arimaabackend.migration.MigrationProperties; + +@SpringBootApplication +@EnableConfigurationProperties(MigrationProperties.class) +public class ArimaaBackendApplication { + + public static void main(String[] args) { + SpringApplication.run(ArimaaBackendApplication.class, args); + } + +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/Neo4jTransactionManagerConfiguration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/Neo4jTransactionManagerConfiguration.java new file mode 100644 index 000000000..87cef9598 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/Neo4jTransactionManagerConfiguration.java @@ -0,0 +1,30 @@ +package com.example.arimaabackend.config; + +import org.neo4j.driver.Driver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; +import org.springframework.orm.jpa.JpaTransactionManager; + +import jakarta.persistence.EntityManagerFactory; + +/** + * The app uses both JPA (MySQL) and Neo4j. Declaring any {@code TransactionManager} causes Spring + * Boot's {@code @ConditionalOnMissingBean(TransactionManager.class)} to skip auto-config for the + * other store, so both managers must be registered explicitly here. + */ +@Configuration +public class Neo4jTransactionManagerConfiguration { + + @Bean(name = "transactionManager") + @Primary + JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } + + @Bean(name = "neo4jTransactionManager") + Neo4jTransactionManager neo4jTransactionManager(Driver driver) { + return new Neo4jTransactionManager(driver); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/PasswordEncoderConfig.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/PasswordEncoderConfig.java new file mode 100644 index 000000000..aa0105b41 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/PasswordEncoderConfig.java @@ -0,0 +1,15 @@ +package com.example.arimaabackend.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class PasswordEncoderConfig { + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/SecurityConfig.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/SecurityConfig.java new file mode 100644 index 000000000..6b3d9f367 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/config/SecurityConfig.java @@ -0,0 +1,80 @@ +package com.example.arimaabackend.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +import com.example.arimaabackend.security.UserDetailsServiceImpl; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity +public class SecurityConfig { + + private final UserDetailsServiceImpl userDetailsService; + private final PasswordEncoder passwordEncoder; + + public SecurityConfig(UserDetailsServiceImpl userDetailsService, PasswordEncoder passwordEncoder) { + this.userDetailsService = userDetailsService; + this.passwordEncoder = passwordEncoder; + } + + @Bean + public DaoAuthenticationProvider authenticationProvider() { + var provider = new DaoAuthenticationProvider(userDetailsService); + provider.setPasswordEncoder(passwordEncoder); + return provider; + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) { + try { + return config.getAuthenticationManager(); + } catch (Exception e) { + throw new RuntimeException("Could not get AuthenticationManager bean", e); + } + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) { + String localAdmin = "ADMIN"; + try { + http + .csrf(csrf -> csrf.disable()) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(auth -> auth + // Admin-only: create, get, delete users + .requestMatchers(HttpMethod.POST, "/api/users").hasRole(localAdmin) + .requestMatchers(HttpMethod.DELETE, "/api/users/**").hasRole(localAdmin) + .requestMatchers(HttpMethod.POST, "/api/mongo/users").hasRole(localAdmin) + .requestMatchers(HttpMethod.DELETE, "/api/mongo/users/**").hasRole(localAdmin) + .requestMatchers(HttpMethod.POST, "/api/neo4j/users").hasRole(localAdmin) + .requestMatchers(HttpMethod.DELETE, "/api/neo4j/users/**").hasRole(localAdmin) + .requestMatchers(HttpMethod.POST, "/api/mongo/players").hasRole(localAdmin) + .requestMatchers(HttpMethod.PUT, "/api/mongo/players/**").hasRole(localAdmin) + .requestMatchers(HttpMethod.DELETE, "/api/mongo/players/**").hasRole(localAdmin) + .requestMatchers(HttpMethod.POST, "/api/mongo/matches").hasRole(localAdmin) + .requestMatchers(HttpMethod.PUT, "/api/mongo/matches/**").hasRole(localAdmin) + .requestMatchers(HttpMethod.DELETE, "/api/mongo/matches/**").hasRole(localAdmin) + .requestMatchers("/api/admin/**").hasRole(localAdmin) + // Everything else requires authentication + .anyRequest().authenticated() + ) + .httpBasic(basic -> {}); + + return http.build(); + } catch (Exception e) { + throw new RuntimeException("Failed to build SecurityFilterChain", e); + } + } + +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/MatchController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/MatchController.java new file mode 100644 index 000000000..f767a3d3e --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/MatchController.java @@ -0,0 +1,46 @@ +package com.example.arimaabackend.controllers; + +import com.example.arimaabackend.dto.MatchResponse; +import com.example.arimaabackend.services.MatchService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/matches") +public class MatchController { + + private final MatchService matchService; + + public MatchController(MatchService matchService) { + this.matchService = matchService; + } + + @GetMapping("/{id}") + public ResponseEntity getMatch(@PathVariable Integer id) { + return matchService.getMatch(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @PreAuthorize("hasRole('ADMIN')") + public MatchResponse createMatch(@RequestBody String matchData) { + return matchService.createMatch(matchData); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public MatchResponse updateMatch(@PathVariable Integer id, @RequestBody String matchData) { + return matchService.updateMatch(id, matchData); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteMatch(@PathVariable Integer id) { + matchService.deleteMatch(id); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/PlayerController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/PlayerController.java new file mode 100644 index 000000000..d30f214b3 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/PlayerController.java @@ -0,0 +1,74 @@ +package com.example.arimaabackend.controllers; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.dto.PlayerUpdateRequest; +import com.example.arimaabackend.services.PlayerService; + +import jakarta.validation.Valid; + +@RestController +@RequestMapping("/api/players") +public class PlayerController { + + private final PlayerService playerService; + + public PlayerController(PlayerService playerService) { + this.playerService = playerService; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @PreAuthorize("hasRole('ADMIN')") + public PlayerResponse create(@Valid @RequestBody PlayerCreateRequest request) { + return playerService.create(request); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public PlayerResponse update(@PathVariable Integer id, @Valid @RequestBody PlayerUpdateRequest request) { + return playerService.update(id, request); + } + + @GetMapping() + public List getAll() { + return playerService.getAll(); + } + + @GetMapping("/by-username/{username}") + public PlayerResponse getByUsername(@PathVariable String username) { + return playerService.getByUsername(username); + } + + @GetMapping("/{id}") + public PlayerResponse getById(@PathVariable Integer id) { + return playerService.getById(id); + } + + @GetMapping("/by-country/{countryName}") + public List getByCountryName(@PathVariable String countryName) { + return playerService.getByCountryName(countryName); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteById(@PathVariable Integer id) { + playerService.deleteById(id); + } + +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/UserController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/UserController.java new file mode 100644 index 000000000..f1ffe778a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/UserController.java @@ -0,0 +1,58 @@ +package com.example.arimaabackend.controllers; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.example.arimaabackend.services.UserService; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/users") +public class UserController { + + private final UserService userService; + + public UserController(UserService userService) { + this.userService = userService; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public UserResponse create(@Valid @RequestBody UserCreateRequest request) { + return userService.create(request); + } + + @GetMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse getById(@PathVariable Long id) { + return userService.getById(id); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse update(@PathVariable Long id, @Valid @RequestBody UserUpdateRequest request) { + return userService.update(id, request); + } + + // Admin-only: delete a user account + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteById(@PathVariable Long id) { + userService.deleteById(id); + } + + +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/MatchMongoController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/MatchMongoController.java new file mode 100644 index 000000000..2457b94d0 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/MatchMongoController.java @@ -0,0 +1,46 @@ +package com.example.arimaabackend.controllers.mongo; + +import com.example.arimaabackend.dto.MatchResponse; +import com.example.arimaabackend.services.mongo.MatchMongoService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/mongo/matches") +public class MatchMongoController { + + private final MatchMongoService matchMongoService; + + public MatchMongoController(MatchMongoService matchMongoService) { + this.matchMongoService = matchMongoService; + } + + @GetMapping("/{id}") + public ResponseEntity getMatch(@PathVariable Integer id) { + return matchMongoService.getMatch(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @PreAuthorize("hasRole('ADMIN')") + public MatchResponse createMatch(@RequestBody String matchData) { + return matchMongoService.createMatch(matchData); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public MatchResponse updateMatch(@PathVariable Integer id, @RequestBody String matchData) { + return matchMongoService.updateMatch(id, matchData); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteMatch(@PathVariable Integer id) { + matchMongoService.deleteMatch(id); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/PlayerMongoController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/PlayerMongoController.java new file mode 100644 index 000000000..3460c33af --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/PlayerMongoController.java @@ -0,0 +1,73 @@ +package com.example.arimaabackend.controllers.mongo; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.dto.PlayerUpdateRequest; +import com.example.arimaabackend.services.mongo.PlayerMongoService; + +import jakarta.validation.Valid; + +@RestController +@RequestMapping("/api/mongo/players") +public class PlayerMongoController { + + private final PlayerMongoService playerMongoService; + + public PlayerMongoController(PlayerMongoService playerMongoService) { + this.playerMongoService = playerMongoService; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @PreAuthorize("hasRole('ADMIN')") + public PlayerResponse create(@Valid @RequestBody PlayerCreateRequest request) { + return playerMongoService.create(request); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public PlayerResponse update(@PathVariable Integer id, @Valid @RequestBody PlayerUpdateRequest request) { + return playerMongoService.update(id, request); + } + + @GetMapping() + public List getAll() { + return playerMongoService.getAll(); + } + + @GetMapping("/by-username/{username}") + public PlayerResponse getByUsername(@PathVariable String username) { + return playerMongoService.getByUsername(username); + } + + @GetMapping("/{id}") + public PlayerResponse getById(@PathVariable Integer id) { + return playerMongoService.getById(id); + } + + @GetMapping("/by-country/{countryName}") + public List getByCountryName(@PathVariable String countryName) { + return playerMongoService.getByCountryName(countryName); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteById(@PathVariable Integer id) { + playerMongoService.deleteById(id); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/UserMongoController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/UserMongoController.java new file mode 100644 index 000000000..21e8a1e12 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/mongo/UserMongoController.java @@ -0,0 +1,61 @@ +package com.example.arimaabackend.controllers.mongo; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.example.arimaabackend.services.mongo.UserMongoService; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/mongo/users") +public class UserMongoController { + + private final UserMongoService userMongoService; + + public UserMongoController(UserMongoService userMongoService) { + this.userMongoService = userMongoService; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @PreAuthorize("hasRole('ADMIN')") + public UserResponse create(@Valid @RequestBody UserCreateRequest request) { + return userMongoService.create(request); + } + + @GetMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse getById(@PathVariable Long id) { + return userMongoService.getById(id); + } + + @GetMapping("/by-username/{username}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse getByUsername(@PathVariable String username) { + return userMongoService.getByUsername(username); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse update(@PathVariable Long id, @Valid @RequestBody UserUpdateRequest request) { + return userMongoService.update(id, request); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteById(@PathVariable Long id) { + userMongoService.deleteById(id); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/MatchNeo4jController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/MatchNeo4jController.java new file mode 100644 index 000000000..f18d60521 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/MatchNeo4jController.java @@ -0,0 +1,28 @@ +package com.example.arimaabackend.controllers.neo4j; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.example.arimaabackend.dto.MatchResponse; +import com.example.arimaabackend.services.neo4j.MatchNeo4jService; + +@RestController +@RequestMapping("/api/neo4j/matches") +public class MatchNeo4jController { + + private final MatchNeo4jService matchNeo4jService; + + public MatchNeo4jController(MatchNeo4jService matchNeo4jService) { + this.matchNeo4jService = matchNeo4jService; + } + + @GetMapping("/{id}") + public ResponseEntity getMatch(@PathVariable Integer id) { + return matchNeo4jService.getMatch(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/PlayerNeo4jController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/PlayerNeo4jController.java new file mode 100644 index 000000000..035ab0e62 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/PlayerNeo4jController.java @@ -0,0 +1,32 @@ +package com.example.arimaabackend.controllers.neo4j; + +import java.util.List; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.services.neo4j.PlayerNeo4jService; + +@RestController +@RequestMapping("/api/neo4j/players") +public class PlayerNeo4jController { + + private final PlayerNeo4jService playerNeo4jService; + + public PlayerNeo4jController(PlayerNeo4jService playerNeo4jService) { + this.playerNeo4jService = playerNeo4jService; + } + + @GetMapping("/by-username/{username}") + public PlayerResponse getByUsername(@PathVariable String username) { + return playerNeo4jService.getByUsername(username); + } + + @GetMapping("/by-country/{countryName}") + public List getByCountryName(@PathVariable String countryName) { + return playerNeo4jService.getByCountryName(countryName); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/UserNeo4jController.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/UserNeo4jController.java new file mode 100644 index 000000000..6e12285a8 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/controllers/neo4j/UserNeo4jController.java @@ -0,0 +1,54 @@ +package com.example.arimaabackend.controllers.neo4j; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.example.arimaabackend.services.neo4j.UserNeo4jService; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/neo4j/users") +public class UserNeo4jController { + + private final UserNeo4jService userNeo4jService; + + public UserNeo4jController(UserNeo4jService userNeo4jService) { + this.userNeo4jService = userNeo4jService; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public UserResponse create(@Valid @RequestBody UserCreateRequest request) { + return userNeo4jService.create(request); + } + + @GetMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse getById(@PathVariable Long id) { + return userNeo4jService.getById(id); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + public UserResponse update(@PathVariable Long id, @Valid @RequestBody UserUpdateRequest request) { + return userNeo4jService.update(id, request); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("hasRole('ADMIN')") + public void deleteById(@PathVariable Long id) { + userNeo4jService.deleteById(id); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/EventSummary.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/EventSummary.java new file mode 100644 index 000000000..8ea3bb088 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/EventSummary.java @@ -0,0 +1,6 @@ +package com.example.arimaabackend.dto; + +public record EventSummary( + Integer id, + String name +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/GameTypeSummary.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/GameTypeSummary.java new file mode 100644 index 000000000..04b478b89 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/GameTypeSummary.java @@ -0,0 +1,9 @@ +package com.example.arimaabackend.dto; + +public record GameTypeSummary( + Integer id, + String name, + Integer timeIncrement, + Integer timeReserve +) {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/MatchResponse.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/MatchResponse.java new file mode 100644 index 000000000..37240d91e --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/MatchResponse.java @@ -0,0 +1,16 @@ +package com.example.arimaabackend.dto; + +import java.time.Instant; + +public record MatchResponse( + Integer id, + String terminationType, + PlayerSummary silverPlayer, + PlayerSummary goldPlayer, + Integer goldRating, + Integer silverRating, + String matchResult, + EventSummary event, + GameTypeSummary gameType, + Instant timestamp +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerCreateRequest.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerCreateRequest.java new file mode 100644 index 000000000..35a6c43ef --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerCreateRequest.java @@ -0,0 +1,18 @@ +package com.example.arimaabackend.dto; + +import jakarta.validation.constraints.NotNull; + +public record PlayerCreateRequest( + @NotNull + Long userId, + + Integer rating, + + Integer ru, + + Integer gamesPlayed, + + Integer countryId, + + String country +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerResponse.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerResponse.java new file mode 100644 index 000000000..69454edd9 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerResponse.java @@ -0,0 +1,14 @@ +package com.example.arimaabackend.dto; + +import java.time.Instant; + +public record PlayerResponse( + Integer id, + String username, + String email, + Integer rating, + Integer ru, + Integer gamesPlayed, + Instant createTime, + Integer countryId +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerSummary.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerSummary.java new file mode 100644 index 000000000..8338298c2 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerSummary.java @@ -0,0 +1,6 @@ +package com.example.arimaabackend.dto; + +public record PlayerSummary( + Integer id, + String username +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerUpdateRequest.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerUpdateRequest.java new file mode 100644 index 000000000..78c0b875b --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/PlayerUpdateRequest.java @@ -0,0 +1,21 @@ +package com.example.arimaabackend.dto; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +public record PlayerUpdateRequest( + @NotNull + Integer rating, + + @NotNull + Integer ru, + + @NotNull + Integer gamesPlayed, + + @NotNull + Integer countryId, + + @Valid + UserUpdateRequest userUpdate +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserCreateRequest.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserCreateRequest.java new file mode 100644 index 000000000..aac0b5fee --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserCreateRequest.java @@ -0,0 +1,17 @@ +package com.example.arimaabackend.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public record UserCreateRequest( + @NotBlank @Size(max = 50) + String username, + + @Email @NotBlank @Size(max = 254) + String email, + + @NotBlank @Size(min = 8, max = 100) + String password +) {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserResponse.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserResponse.java new file mode 100644 index 000000000..59babe29a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserResponse.java @@ -0,0 +1,13 @@ +package com.example.arimaabackend.dto; + +import java.time.Instant; + +public record UserResponse( + Long id, + String username, + String email, + String role, + Instant createdAt, + Instant updatedAt +) {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserUpdateRequest.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserUpdateRequest.java new file mode 100644 index 000000000..478e37fcb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/dto/UserUpdateRequest.java @@ -0,0 +1,16 @@ +package com.example.arimaabackend.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public record UserUpdateRequest( + @NotBlank @Size(max = 50) + String username, + + @Email @NotBlank @Size(max = 254) + String email, + + @Size(min = 8, max = 100) + String password +) {} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/enums/UserRole.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/enums/UserRole.java new file mode 100644 index 000000000..2455217e5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/enums/UserRole.java @@ -0,0 +1,5 @@ +package com.example.arimaabackend.enums; + +public enum UserRole { +USER, PLAYER, ADMIN +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationContext.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationContext.java new file mode 100644 index 000000000..7d03fdb4a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationContext.java @@ -0,0 +1,15 @@ +package com.example.arimaabackend.migration; + +/** + * Per-run migration settings passed into each {@link com.example.arimaabackend.migration.spi.MigrationStep}. + */ +public record MigrationContext(MigrationProperties properties) { + + public int batchSize() { + return properties.getBatchSize(); + } + + public boolean dryRun() { + return properties.isDryRun(); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationProperties.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationProperties.java new file mode 100644 index 000000000..03f9f7d01 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationProperties.java @@ -0,0 +1,129 @@ +package com.example.arimaabackend.migration; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import com.example.arimaabackend.migration.spi.MigrationTarget; + +/** + *

Configure under prefix {@code migration}.

+ *
    + *
  • {@code enabled-targets} — if non-empty, only those targets run ({@code neo4j}, {@code mongodb}).
  • + *
  • {@code enabled-steps} — if non-empty, only those steps run (see each migration's {@code stepName()}). + * Step ids are case-insensitive. If empty, all steps run in order.
  • + *
  • {@code batch-size} — page size for large JPA reads (default 500).
  • + *
  • {@code dry-run} — if true, steps log counts and skip target writes.
  • + *
+ */ +@ConfigurationProperties(prefix = "migration") +public class MigrationProperties { + + /** + * Target names to run; empty = all targets. + */ + private List enabledTargets = new ArrayList<>(); + + /** + * Step names to run; empty = all steps. + */ + private List enabledSteps = new ArrayList<>(); + + private int batchSize = 1000; + + private boolean dryRun = false; + + private boolean exitOnComplete = true; + + public List getEnabledTargets() { + return enabledTargets; + } + + public void setEnabledTargets(List enabledTargets) { + this.enabledTargets = enabledTargets != null ? enabledTargets : new ArrayList<>(); + } + + public List getEnabledSteps() { + return enabledSteps; + } + + public void setEnabledSteps(List enabledSteps) { + this.enabledSteps = enabledSteps != null ? enabledSteps : new ArrayList<>(); + } + + public int getBatchSize() { + return batchSize; + } + + public void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } + + public boolean isDryRun() { + return dryRun; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public boolean isExitOnComplete() { + return exitOnComplete; + } + + public void setExitOnComplete(boolean exitOnComplete) { + this.exitOnComplete = exitOnComplete; + } + + /** + * When {@link #enabledSteps} is empty, all steps run; otherwise only listed steps (case-insensitive). + */ + public boolean isStepEnabled(String stepName) { + if (enabledSteps == null || enabledSteps.isEmpty()) { + return true; + } + for (String s : enabledSteps) { + if (s != null && s.equalsIgnoreCase(stepName)) { + return true; + } + } + return false; + } + + /** + * When {@link #enabledTargets} is empty, all targets run; otherwise only listed targets. + */ + public boolean isTargetEnabled(MigrationTarget target) { + return getEnabledTargetSet().contains(target); + } + + /** + * Resolved set of enabled targets. Empty configuration means all targets. + */ + public Set getEnabledTargetSet() { + var resolved = EnumSet.noneOf(MigrationTarget.class); + resolved.addAll(getEnabledTargetOrder()); + return resolved; + } + + /** + * Resolved enabled targets in run order. + *

When empty, all targets are enabled in enum declaration order.

+ */ + public List getEnabledTargetOrder() { + if (enabledTargets == null || enabledTargets.isEmpty()) { + return List.of(MigrationTarget.values()); + } + var ordered = new ArrayList(); + for (String rawTarget : enabledTargets) { + var target = MigrationTarget.fromPropertyValue(rawTarget); + if (!ordered.contains(target)) { + ordered.add(target); + } + } + return ordered; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationRunner.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationRunner.java new file mode 100644 index 000000000..ed9896f55 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/MigrationRunner.java @@ -0,0 +1,124 @@ +package com.example.arimaabackend.migration; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; + +@Component +@Profile("migration") +public class MigrationRunner implements CommandLineRunner { + + private static final Logger log = LoggerFactory.getLogger(MigrationRunner.class); + + private final List migrations; + private final MigrationProperties migrationProperties; + private final ApplicationContext applicationContext; + + public MigrationRunner(List migrations, MigrationProperties migrationProperties, ApplicationContext applicationContext) { + this.migrations = new ArrayList<>(migrations); + this.migrations.sort(Comparator.comparingInt(MigrationStep::getOrder)); + this.migrationProperties = migrationProperties; + this.applicationContext = applicationContext; + } + + @Override + public void run(String... args) { + MigrationContext context = new MigrationContext(migrationProperties); + Set enabledTargets = migrationProperties.getEnabledTargetSet(); + List targetOrder = migrationProperties.getEnabledTargetOrder(); + + logStart(enabledTargets, targetOrder); + + List stepsEnabledByName = filterStepsByName(); + Set executedSteps = runByTargetGroups(context, targetOrder, stepsEnabledByName); + + logStepsSkippedByTarget(stepsEnabledByName, executedSteps); + log.info("Data migration completed."); + + System.exit(SpringApplication.exit(applicationContext, () -> 0)); + } + + private void logStart(Set enabledTargets, List targetOrder) { + log.info( + "Starting data migration (dryRun={}, batchSize={}, enabledTargets={}, targetOrder={}, enabledSteps={})", + migrationProperties.isDryRun(), + migrationProperties.getBatchSize(), + migrationProperties.getEnabledTargets().isEmpty() ? "ALL" : enabledTargets, + targetOrder, + migrationProperties.getEnabledSteps().isEmpty() ? "ALL" : migrationProperties.getEnabledSteps() + ); + } + + private List filterStepsByName() { + List stepsEnabledByName = new ArrayList<>(); + for (MigrationStep step : migrations) { + if (!migrationProperties.isStepEnabled(step.stepName())) { + log.info("Skipping step '{}' (not in migration.enabled-steps)", step.stepName()); + continue; + } + stepsEnabledByName.add(step); + } + return stepsEnabledByName; + } + + private Set runByTargetGroups( + MigrationContext context, + List targetOrder, + List stepsEnabledByName + ) { + Set executedSteps = new HashSet<>(); + for (MigrationTarget target : targetOrder) { + log.info("Running target group '{}'", target); + runTargetGroup(context, target, stepsEnabledByName, executedSteps); + } + return executedSteps; + } + + private void runTargetGroup( + MigrationContext context, + MigrationTarget target, + List stepsEnabledByName, + Set executedSteps + ) { + for (MigrationStep step : stepsEnabledByName) { + if (!step.targets().contains(target) || executedSteps.contains(step)) { + continue; + } + runStep(context, step); + executedSteps.add(step); + } + } + + private void runStep(MigrationContext context, MigrationStep step) { + long startedAt = System.nanoTime(); + try { + step.migrate(context); + } catch (RuntimeException ex) { + log.error("Migration step '{}' failed: {}", step.stepName(), ex.getMessage(), ex); + throw ex; + } + long durationMs = (System.nanoTime() - startedAt) / 1_000_000L; + log.info("Finished step '{}' in {} ms", step.stepName(), durationMs); + } + + private void logStepsSkippedByTarget(List stepsEnabledByName, Set executedSteps) { + for (MigrationStep step : stepsEnabledByName) { + if (!executedSteps.contains(step)) { + log.info("Skipping step '{}' (target not enabled: {})", step.stepName(), step.targets()); + } + } + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/spi/MigrationStep.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/spi/MigrationStep.java new file mode 100644 index 000000000..4404ae971 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/spi/MigrationStep.java @@ -0,0 +1,25 @@ +package com.example.arimaabackend.migration.spi; + +import java.util.Set; + +import org.springframework.core.Ordered; + +import com.example.arimaabackend.migration.MigrationContext; + +/** + * One modular step in the data migration pipeline (e.g. SQL → Neo4j, SQL → MongoDB, or both). + * {@link Ordered#getOrder()} defines run order (lower first). {@link #stepName()} is used for + * {@code migration.enabled-steps} filtering. + *

Concrete implementations typically live in {@code com.example.arimaabackend.migration.steps}.

+ */ +public interface MigrationStep extends Ordered { + + /** + * Stable step id, e.g. {@code country}. Compared case-insensitively to configured enabled steps. + */ + String stepName(); + + Set targets(); + + void migrate(MigrationContext context); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/spi/MigrationTarget.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/spi/MigrationTarget.java new file mode 100644 index 000000000..17a77c5fc --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/spi/MigrationTarget.java @@ -0,0 +1,20 @@ +package com.example.arimaabackend.migration.spi; + +import java.util.Locale; + +public enum MigrationTarget { + NEO4J, + MONGODB; + + public static MigrationTarget fromPropertyValue(String value) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("Migration target must not be blank"); + } + var normalized = value.trim().toLowerCase(Locale.ROOT); + return switch (normalized) { + case "neo4j" -> NEO4J; + case "mongodb", "mongo" -> MONGODB; + default -> throw new IllegalArgumentException("Unsupported migration target: " + value); + }; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/MatchMongoMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/MatchMongoMigration.java new file mode 100644 index 000000000..778e7a0cd --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/MatchMongoMigration.java @@ -0,0 +1,196 @@ +package com.example.arimaabackend.migration.steps.mongodb; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.model.mongo.MatchDocument; +import com.example.arimaabackend.model.sql.MatchEntity; +import com.example.arimaabackend.repository.mongo.MatchMongoRepository; +import com.example.arimaabackend.repository.sql.MatchJpaRepository; + +@Service +@Profile("migration") +public class MatchMongoMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(MatchMongoMigration.class); + + private final MatchMongoRepository matchMongoRepository; + private final MatchJpaRepository matchJpaRepository; + private final JdbcTemplate jdbcTemplate; + + public MatchMongoMigration( + MatchMongoRepository matchMongoRepository, + MatchJpaRepository matchJpaRepository, + JdbcTemplate jdbcTemplate + ) { + this.matchMongoRepository = matchMongoRepository; + this.matchJpaRepository = matchJpaRepository; + this.jdbcTemplate = jdbcTemplate; + } + + + @Override + public String stepName() { + return "match-mongo"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.MONGODB); + } + + @Override + public int getOrder() { + return 123; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), matchJpaRepository.count()); + return; + } + Map> openingByMatchId = loadMatchOpenings(); + Map> movesByMatchId = loadMatchMoves(); + List documents = matchJpaRepository.findAllForMigration().stream() + .map(m -> toDocument( + m, + openingByMatchId.get(m.getId()), + movesByMatchId.getOrDefault(m.getId(), List.of()))) + .toList(); + matchMongoRepository.saveAll(documents); + log.info("[{}] migrated {} matches", stepName(), documents.size()); + } + + private MatchDocument toDocument( + MatchEntity e, + List opening, + List moves) { + var d = new MatchDocument(); + d.setId(e.getId()); + d.setTerminationType(e.getTerminationType()); + d.setMatchResult(e.getMatchResult()); + d.setGoldRating(e.getGoldRating()); + d.setSilverRating(e.getSilverRating()); + d.setTimestamp(e.getTimestamp()); + + d.setPlayers(List.of( + playerRef(e.getGoldPlayer().getId(), "gold"), + playerRef(e.getSilverPlayer().getId(), "silver") + )); + + d.setEvent(event(e)); + d.setGameType(gameType(e)); + d.setOpening(opening); + d.setMoves(moves); + return d; + } + + private MatchDocument.PlayerRef playerRef(Integer playerId, String color) { + var p = new MatchDocument.PlayerRef(); + p.setPlayerId(playerId); + p.setColor(color); + return p; + } + + private MatchDocument.Event event(MatchEntity e) { + var src = e.getEvent(); + if (src == null) { + return null; + } + var ev = new MatchDocument.Event(); + ev.setId(src.getId()); + ev.setName(src.getName()); + ev.setIsRated(src.getRated()); + return ev; + } + + private MatchDocument.GameType gameType(MatchEntity e) { + var src = e.getGameType(); + if (src == null) { + return null; + } + var gt = new MatchDocument.GameType(); + gt.setId(src.getId()); + gt.setName(src.getName()); + gt.setTimeIncrement(src.getTimeIncrement()); + gt.setTimeReserve(src.getTimeReserve()); + return gt; + } + + private Map> loadMatchMoves() { + var grouped = new HashMap>(); + jdbcTemplate.query( + """ + SELECT mv.matches_id, mv.turn, mv.sequence, mv.direction, mv.status, + p.color, p.piece, p.cordinate + FROM Moves mv + JOIN Position p ON p.id = mv.position_id + ORDER BY mv.matches_id ASC, mv.turn ASC, mv.sequence ASC + """, + rs -> { + int matchId = rs.getInt("matches_id"); + var move = new MatchDocument.Move(); + move.setTurn(rs.getInt("turn")); + move.setSequence(rs.getInt("sequence")); + move.setDirection(rs.getString("direction")); + move.setStatus(rs.getString("status")); + move.setPosition(positionRow( + rs.getString("color"), + rs.getString("piece"), + rs.getString("cordinate") + )); + grouped.computeIfAbsent(matchId, ignored -> new java.util.ArrayList<>()).add(move); + } + ); + return grouped; + } + + private Map> loadMatchOpenings() { + var grouped = new HashMap>(); + jdbcTemplate.query( + """ + SELECT obm.matches_id, p.color, p.piece, p.cordinate + FROM OpeningsByMatch obm + JOIN Position p ON p.id = obm.position_id + ORDER BY obm.id ASC + """, + rs -> { + int matchId = rs.getInt("matches_id"); + grouped.computeIfAbsent(matchId, ignored -> new java.util.ArrayList<>()).add(positionRow( + rs.getString("color"), + rs.getString("piece"), + rs.getString("cordinate") + )); + } + ); + return grouped; + } + + private MatchDocument.Position positionRow(String color, String piece, String coordinate) { + var p = new MatchDocument.Position(); + p.setColor(color); + p.setPiece(piece); + p.setCoordinate(coordinate); + return p; + } + + + + + +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/PlayerMongoMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/PlayerMongoMigration.java new file mode 100644 index 000000000..172bb64e1 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/PlayerMongoMigration.java @@ -0,0 +1,86 @@ +package com.example.arimaabackend.migration.steps.mongodb; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.model.mongo.PlayerDocument; +import com.example.arimaabackend.model.mongo.UserDocument; +import com.example.arimaabackend.model.sql.PlayerEntity; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.mongo.PlayerMongoRepository; +import com.example.arimaabackend.repository.sql.PlayerJpaRepository; + +@Service +@Profile("migration") +public class PlayerMongoMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(PlayerMongoMigration.class); + + private final PlayerJpaRepository playerJpaRepository; + private final PlayerMongoRepository playerMongoRepository; + + public PlayerMongoMigration(PlayerJpaRepository playerJpaRepository, PlayerMongoRepository playerMongoRepository) { + this.playerJpaRepository = playerJpaRepository; + this.playerMongoRepository = playerMongoRepository; + } + + @Override + public String stepName() { + return "player-mongo"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.MONGODB); + } + + @Override + public int getOrder() { + return 122; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), playerJpaRepository.count()); + return; + } + List documents = playerJpaRepository.findAllWithUserAndCountry().stream() + .map(this::toDocument) + .toList(); + playerMongoRepository.saveAll(documents); + log.info("[{}] migrated {} players", stepName(), documents.size()); + } + + private PlayerDocument toDocument(PlayerEntity entity) { + var d = new PlayerDocument(); + d.setId(entity.getId()); + d.setUser(userRef(entity.getUser())); + d.setRating(entity.getRating()); + d.setRu(entity.getRu()); + d.setGamesPlayed(entity.getGamesPlayed()); + d.setCountry(entity.getCountry() != null ? entity.getCountry().getName() : null); + return d; + } + + private UserDocument userRef(UserEntity user) { + if (user == null) { + return null; + } + var document = new UserDocument(); + document.setId(user.getId()); + return document; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/PuzzleMongoMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/PuzzleMongoMigration.java new file mode 100644 index 000000000..7a40c7079 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/PuzzleMongoMigration.java @@ -0,0 +1,150 @@ +package com.example.arimaabackend.migration.steps.mongodb; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.model.mongo.PuzzleDocument; +import com.example.arimaabackend.model.sql.PuzzleEntity; +import com.example.arimaabackend.repository.mongo.PuzzleMongoRepository; +import com.example.arimaabackend.repository.sql.PuzzleJpaRepository; + +@Service +@Profile("migration") +public class PuzzleMongoMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(PuzzleMongoMigration.class); + + private final PuzzleJpaRepository puzzleJpaRepository; + private final PuzzleMongoRepository puzzleMongoRepository; + private final JdbcTemplate jdbcTemplate; + + public PuzzleMongoMigration( + PuzzleJpaRepository puzzleJpaRepository, + PuzzleMongoRepository puzzleMongoRepository, + JdbcTemplate jdbcTemplate + ) { + this.puzzleJpaRepository = puzzleJpaRepository; + this.puzzleMongoRepository = puzzleMongoRepository; + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public String stepName() { + return "puzzle-mongo"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.MONGODB); + } + + @Override + public int getOrder() { + return 124; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), puzzleJpaRepository.count()); + return; + } + Map> openingByPuzzleId = loadPuzzleOpenings(); + Map> solutionsByPuzzleId = loadPuzzleSolutions(); + List documents = puzzleJpaRepository.findAll().stream() + .map(p -> toDocument( + p, + openingByPuzzleId.get(p.getId()), + solutionsByPuzzleId.getOrDefault(p.getId(), List.of()))) + .toList(); + puzzleMongoRepository.saveAll(documents); + log.info("[{}] migrated {} puzzles", stepName(), documents.size()); + } + + private PuzzleDocument toDocument( + PuzzleEntity e, + List opening, + List solutions) { + var d = new PuzzleDocument(); + d.setId(e.getId()); + d.setName(e.getName()); + d.setObjective(e.getObjective()); + d.setPlayerSide(e.getPlayerSide()); + d.setRounds(e.getRounds()); + d.setOpening(opening); + d.setSolution(solutions); + return d; + } + + private Map> loadPuzzleSolutions() { + var grouped = new HashMap>(); + jdbcTemplate.query( + """ + SELECT s.puzzles_id, s.turn, s.sequence, s.direction, s.status, + p.color, p.piece, p.cordinate + FROM Solutions s + JOIN Position p ON p.id = s.position_id + ORDER BY s.puzzles_id ASC, s.turn ASC, s.sequence ASC + """, + rs -> { + int puzzleId = rs.getInt("puzzles_id"); + var move = new PuzzleDocument.SolutionMove(); + move.setTurn(rs.getInt("turn")); + move.setSequence(rs.getInt("sequence")); + move.setDirection(rs.getString("direction")); + move.setStatus(rs.getString("status")); + move.setPosition(positionRow( + rs.getString("color"), + rs.getString("piece"), + rs.getString("cordinate") + )); + grouped.computeIfAbsent(puzzleId, ignored -> new java.util.ArrayList<>()).add(move); + } + ); + return grouped; + } + + private Map> loadPuzzleOpenings() { + var grouped = new HashMap>(); + jdbcTemplate.query( + """ + SELECT obp.puzzles_id, p.color, p.piece, p.cordinate + FROM OpeningsByPuzzle obp + JOIN Position p ON p.id = obp.position_id + ORDER BY obp.id ASC + """, + rs -> { + int puzzleId = rs.getInt("puzzles_id"); + grouped.computeIfAbsent(puzzleId, ignored -> new java.util.ArrayList<>()).add(positionRow( + rs.getString("color"), + rs.getString("piece"), + rs.getString("cordinate") + )); + } + ); + return grouped; + } + + private PuzzleDocument.Position positionRow(String color, String piece, String coordinate) { + var p = new PuzzleDocument.Position(); + p.setColor(color); + p.setPiece(piece); + p.setCoordinate(coordinate); + return p; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/UserMongoMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/UserMongoMigration.java new file mode 100644 index 000000000..727cb998b --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/mongodb/UserMongoMigration.java @@ -0,0 +1,89 @@ +package com.example.arimaabackend.migration.steps.mongodb; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.model.mongo.DatabaseSequence; +import com.example.arimaabackend.model.mongo.UserDocument; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.mongo.UserMongoRepository; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; + +@Service +@Profile("migration") +public class UserMongoMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(UserMongoMigration.class); + + private final UserJpaRepository userJpaRepository; + private final UserMongoRepository userMongoRepository; + private final MongoOperations mongoOperations; + + public UserMongoMigration(UserJpaRepository userJpaRepository, UserMongoRepository userMongoRepository, MongoOperations mongoOperations) { + this.userJpaRepository = userJpaRepository; + this.userMongoRepository = userMongoRepository; + this.mongoOperations = mongoOperations; + } + + @Override + public String stepName() { + return "user-mongo"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.MONGODB); + } + + @Override + public int getOrder() { + return 121; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), userJpaRepository.count()); + return; + } + List documents = userJpaRepository.findAll().stream().map(this::toDocument).toList(); + userMongoRepository.saveAll(documents); + log.info("[{}] migrated {} users", stepName(), documents.size()); + + // Update sequence counter + long maxId = documents.stream().mapToLong(UserDocument::getId).max().orElse(0L); + if (maxId > 0) { + mongoOperations.upsert( + Query.query(Criteria.where("_id").is(UserDocument.SEQUENCE_NAME)), + new Update().set("seq", maxId), + DatabaseSequence.class + ); + log.info("[{}] updated sequence {} to {}", stepName(), UserDocument.SEQUENCE_NAME, maxId); + } + } + + private UserDocument toDocument(UserEntity entity) { + var document = new UserDocument(); + document.setId(entity.getId()); + document.setUsername(entity.getUsername()); + document.setEmail(entity.getEmail()); + document.setPasswordHash(entity.getPasswordHash()); + document.setRole(entity.getRole() != null ? entity.getRole().name() : null); + document.setCreatedAt(entity.getCreatedAt()); + document.setUpdatedAt(entity.getUpdatedAt()); + return document; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/CountryNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/CountryNeo4jMigration.java new file mode 100644 index 000000000..7b1b545c7 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/CountryNeo4jMigration.java @@ -0,0 +1,73 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.CountryNode; +import com.example.arimaabackend.model.sql.CountryEntity; +import com.example.arimaabackend.repository.neo4j.CountryNeo4jRepository; +import com.example.arimaabackend.repository.sql.CountryJpaRepository; + +@Service +@Profile("migration") +public class CountryNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(CountryNeo4jMigration.class); + + private final CountryJpaRepository countryJpaRepository; + private final CountryNeo4jRepository countryNeo4jRepository; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public CountryNeo4jMigration( + CountryJpaRepository countryJpaRepository, + CountryNeo4jRepository countryNeo4jRepository, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.countryJpaRepository = countryJpaRepository; + this.countryNeo4jRepository = countryNeo4jRepository; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "country"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 10; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), countryJpaRepository.count()); + return; + } + var entities = countryJpaRepository.findAll(); + var nodes = entities.stream().map(this::toNode).toList(); + neo4jTransactionHelper.write(() -> countryNeo4jRepository.saveAll(nodes)); + log.info("[{}] migrated {} countries", stepName(), nodes.size()); + } + + private CountryNode toNode(CountryEntity e) { + var n = new CountryNode(); + n.setId(e.getId()); + n.setName(e.getName()); + return n; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/EventNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/EventNeo4jMigration.java new file mode 100644 index 000000000..44f8359c8 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/EventNeo4jMigration.java @@ -0,0 +1,73 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.EventNode; +import com.example.arimaabackend.model.sql.EventEntity; +import com.example.arimaabackend.repository.neo4j.EventNeo4jRepository; +import com.example.arimaabackend.repository.sql.EventJpaRepository; + +@Service +@Profile("migration") +public class EventNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(EventNeo4jMigration.class); + + private final EventJpaRepository eventJpaRepository; + private final EventNeo4jRepository eventNeo4jRepository; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public EventNeo4jMigration( + EventJpaRepository eventJpaRepository, + EventNeo4jRepository eventNeo4jRepository, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.eventJpaRepository = eventJpaRepository; + this.eventNeo4jRepository = eventNeo4jRepository; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "event"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 20; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), eventJpaRepository.count()); + return; + } + var nodes = eventJpaRepository.findAll().stream().map(this::toNode).toList(); + neo4jTransactionHelper.write(() -> eventNeo4jRepository.saveAll(nodes)); + log.info("[{}] migrated {} events", stepName(), nodes.size()); + } + + private EventNode toNode(EventEntity e) { + var n = new EventNode(); + n.setId(e.getId()); + n.setName(e.getName()); + n.setRated(e.getRated()); + return n; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/GameTypeNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/GameTypeNeo4jMigration.java new file mode 100644 index 000000000..e348b7440 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/GameTypeNeo4jMigration.java @@ -0,0 +1,74 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.GameTypeNode; +import com.example.arimaabackend.model.sql.GameTypeEntity; +import com.example.arimaabackend.repository.neo4j.GameTypeNeo4jRepository; +import com.example.arimaabackend.repository.sql.GameTypeJpaRepository; + +@Service +@Profile("migration") +public class GameTypeNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(GameTypeNeo4jMigration.class); + + private final GameTypeJpaRepository gameTypeJpaRepository; + private final GameTypeNeo4jRepository gameTypeNeo4jRepository; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public GameTypeNeo4jMigration( + GameTypeJpaRepository gameTypeJpaRepository, + GameTypeNeo4jRepository gameTypeNeo4jRepository, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.gameTypeJpaRepository = gameTypeJpaRepository; + this.gameTypeNeo4jRepository = gameTypeNeo4jRepository; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "game-type"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 30; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), gameTypeJpaRepository.count()); + return; + } + var nodes = gameTypeJpaRepository.findAll().stream().map(this::toNode).toList(); + neo4jTransactionHelper.write(() -> gameTypeNeo4jRepository.saveAll(nodes)); + log.info("[{}] migrated {} game types", stepName(), nodes.size()); + } + + private GameTypeNode toNode(GameTypeEntity e) { + var n = new GameTypeNode(); + n.setId(e.getId()); + n.setName(e.getName()); + n.setTimeIncrement(e.getTimeIncrement()); + n.setTimeReserve(e.getTimeReserve()); + return n; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/MatchNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/MatchNeo4jMigration.java new file mode 100644 index 000000000..e4ee5defa --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/MatchNeo4jMigration.java @@ -0,0 +1,100 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jLinkSupport; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.MatchNode; +import com.example.arimaabackend.model.sql.MatchEntity; +import com.example.arimaabackend.repository.neo4j.MatchNeo4jRepository; +import com.example.arimaabackend.repository.sql.MatchJpaRepository; + +@Service +@Profile("migration") +public class MatchNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(MatchNeo4jMigration.class); + + private final MatchJpaRepository matchJpaRepository; + private final MatchNeo4jRepository matchNeo4jRepository; + private final Neo4jLinkSupport neo4jLinkSupport; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public MatchNeo4jMigration( + MatchJpaRepository matchJpaRepository, + MatchNeo4jRepository matchNeo4jRepository, + Neo4jLinkSupport neo4jLinkSupport, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.matchJpaRepository = matchJpaRepository; + this.matchNeo4jRepository = matchNeo4jRepository; + this.neo4jLinkSupport = neo4jLinkSupport; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "match"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 70; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), matchJpaRepository.count()); + return; + } + var entities = matchJpaRepository.findAllForMigration(); + var nodes = entities.stream().map(this::toNode).toList(); + List> linkRows = entities.stream().map(this::linkRow).toList(); + neo4jTransactionHelper.write(() -> { + matchNeo4jRepository.saveAll(nodes); + neo4jLinkSupport.mergeMatchReferenceEdges(linkRows); + }); + log.info("[{}] migrated {} matches", stepName(), nodes.size()); + } + + private MatchNode toNode(MatchEntity e) { + var n = new MatchNode(); + n.setId(e.getId()); + n.setTerminationType(e.getTerminationType()); + n.setMatchResult(e.getMatchResult()); + n.setGoldRating(e.getGoldRating()); + n.setSilverRating(e.getSilverRating()); + n.setTimestamp(e.getTimestamp()); + return n; + } + + private Map linkRow(MatchEntity e) { + var m = new HashMap(); + m.put("matchId", e.getId()); + m.put("silverPlayerId", e.getSilverPlayer().getId()); + m.put("goldPlayerId", e.getGoldPlayer().getId()); + m.put("eventId", e.getEvent().getId()); + m.put("gameTypeId", e.getGameType().getId()); + return m; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/MoveNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/MoveNeo4jMigration.java new file mode 100644 index 000000000..dc6679aa5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/MoveNeo4jMigration.java @@ -0,0 +1,100 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jLinkSupport; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.sql.MoveEntity; +import com.example.arimaabackend.repository.sql.MoveJpaRepository; + +@Service +@Profile("migration") +public class MoveNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(MoveNeo4jMigration.class); + + private final MoveJpaRepository moveJpaRepository; + private final Neo4jLinkSupport neo4jLinkSupport; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public MoveNeo4jMigration( + MoveJpaRepository moveJpaRepository, + Neo4jLinkSupport neo4jLinkSupport, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.moveJpaRepository = moveJpaRepository; + this.neo4jLinkSupport = neo4jLinkSupport; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "move"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 80; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), moveJpaRepository.count()); + return; + } + int batch = context.batchSize(); + long migrated = 0; + for (int page = 0; ; page++) { + var slice = moveJpaRepository.findAll(PageRequest.of(page, batch)); + if (!slice.hasContent()) { + break; + } + List> rows = new ArrayList<>(slice.getNumberOfElements()); + for (MoveEntity e : slice) { + rows.add(row(e)); + } + neo4jTransactionHelper.write(() -> { + neo4jLinkSupport.mergeMovesBatch(rows); + }); + migrated += rows.size(); + if (!slice.hasNext()) { + break; + } + } + log.info("[{}] migrated {} moves (nodes + edges in one batch query)", stepName(), migrated); + } + + private Map row(MoveEntity e) { + var m = new HashMap(); + m.put("matchId", e.getMatch().getId()); + m.put("moveId", e.getId()); + m.put("turn", e.getTurn()); + m.put("sequence", e.getSequence()); + m.put("direction", e.getDirection()); + m.put("status", e.getStatus()); + m.put("positionId", e.getPosition().getId()); + return m; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/Neo4jSchemaMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/Neo4jSchemaMigration.java new file mode 100644 index 000000000..aade36906 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/Neo4jSchemaMigration.java @@ -0,0 +1,81 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.data.neo4j.core.Neo4jClient; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; + +@Service +@Profile("migration") +public class Neo4jSchemaMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(Neo4jSchemaMigration.class); + + private final Neo4jClient neo4jClient; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public Neo4jSchemaMigration(Neo4jClient neo4jClient, Neo4jTransactionHelper neo4jTransactionHelper) { + this.neo4jClient = neo4jClient; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "neo4j-schema"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 0; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would ensure constraints/indexes", stepName()); + return; + } + + neo4jTransactionHelper.write(() -> { + // Lookups used heavily by migration MATCH clauses. + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (m:Match) REQUIRE m.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (p:Player) REQUIRE p.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (e:Event) REQUIRE e.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (g:GameType) REQUIRE g.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (c:Country) REQUIRE c.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (z:Puzzle) REQUIRE z.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (s:Solution) REQUIRE s.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (v:Move) REQUIRE v.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (p:Position) REQUIRE p.id IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (u:User) REQUIRE u.id IS UNIQUE").run(); + + // Uniques from SQL schema (identity on User, not Player). + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (c:Country) REQUIRE c.name IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (z:Puzzle) REQUIRE z.name IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (u:User) REQUIRE u.username IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (u:User) REQUIRE u.email IS UNIQUE").run(); + + // Synthetic keys used for move/opening grouping. + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (ml:MoveList) REQUIRE ml.key IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (t:Turn) REQUIRE t.key IS UNIQUE").run(); + neo4jClient.query("CREATE CONSTRAINT IF NOT EXISTS FOR (o:Opening) REQUIRE o.key IS UNIQUE").run(); + }); + + log.info("[{}] ensured Neo4j constraints/indexes", stepName()); + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/OpeningByMatchNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/OpeningByMatchNeo4jMigration.java new file mode 100644 index 000000000..d0c1512b4 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/OpeningByMatchNeo4jMigration.java @@ -0,0 +1,83 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jLinkSupport; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; + +@Service +@Profile("migration") +public class OpeningByMatchNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(OpeningByMatchNeo4jMigration.class); + + private final JdbcTemplate jdbcTemplate; + private final Neo4jLinkSupport neo4jLinkSupport; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public OpeningByMatchNeo4jMigration( + JdbcTemplate jdbcTemplate, + Neo4jLinkSupport neo4jLinkSupport, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.jdbcTemplate = jdbcTemplate; + this.neo4jLinkSupport = neo4jLinkSupport; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "opening-by-match"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 100; + } + + @Override + public void migrate(MigrationContext context) { + Long count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM OpeningsByMatch", Long.class); + if (count == null) { + count = 0L; + } + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), count); + return; + } + int batch = context.batchSize(); + List> rows = jdbcTemplate.query( + "SELECT id, matches_id, position_id FROM OpeningsByMatch", + (rs, rowNum) -> { + var m = new HashMap(); + m.put("openingId", rs.getInt("id")); + m.put("matchId", rs.getInt("matches_id")); + m.put("positionId", rs.getInt("position_id")); + return m; + } + ); + for (int i = 0; i < rows.size(); i += batch) { + var batchRows = rows.subList(i, Math.min(i + batch, rows.size())); + neo4jTransactionHelper.write(() -> neo4jLinkSupport.mergeOpeningByMatch(batchRows)); + } + log.info("[{}] migrated {} opening-by-match links", stepName(), rows.size()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/OpeningByPuzzleNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/OpeningByPuzzleNeo4jMigration.java new file mode 100644 index 000000000..28d306c4e --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/OpeningByPuzzleNeo4jMigration.java @@ -0,0 +1,83 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jLinkSupport; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; + +@Service +@Profile("migration") +public class OpeningByPuzzleNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(OpeningByPuzzleNeo4jMigration.class); + + private final JdbcTemplate jdbcTemplate; + private final Neo4jLinkSupport neo4jLinkSupport; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public OpeningByPuzzleNeo4jMigration( + JdbcTemplate jdbcTemplate, + Neo4jLinkSupport neo4jLinkSupport, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.jdbcTemplate = jdbcTemplate; + this.neo4jLinkSupport = neo4jLinkSupport; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "opening-by-puzzle"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 110; + } + + @Override + public void migrate(MigrationContext context) { + Long count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM OpeningsByPuzzle", Long.class); + if (count == null) { + count = 0L; + } + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), count); + return; + } + int batch = context.batchSize(); + List> rows = jdbcTemplate.query( + "SELECT id, puzzles_id, position_id FROM OpeningsByPuzzle", + (rs, rowNum) -> { + var m = new HashMap(); + m.put("openingId", rs.getInt("id")); + m.put("puzzleId", rs.getInt("puzzles_id")); + m.put("positionId", rs.getInt("position_id")); + return m; + } + ); + for (int i = 0; i < rows.size(); i += batch) { + var batchRows = rows.subList(i, Math.min(i + batch, rows.size())); + neo4jTransactionHelper.write(() -> neo4jLinkSupport.mergeOpeningByPuzzle(batchRows)); + } + log.info("[{}] migrated {} opening-by-puzzle links", stepName(), rows.size()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PlayerNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PlayerNeo4jMigration.java new file mode 100644 index 000000000..bc51f6afa --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PlayerNeo4jMigration.java @@ -0,0 +1,106 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jLinkSupport; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.PlayerNode; +import com.example.arimaabackend.model.neo4j.UserNode; +import com.example.arimaabackend.model.sql.PlayerEntity; +import com.example.arimaabackend.repository.neo4j.PlayerNeo4jRepository; +import com.example.arimaabackend.repository.sql.PlayerJpaRepository; + +@Service +@Profile("migration") +public class PlayerNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(PlayerNeo4jMigration.class); + + private final PlayerJpaRepository playerJpaRepository; + private final PlayerNeo4jRepository playerNeo4jRepository; + private final Neo4jLinkSupport neo4jLinkSupport; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public PlayerNeo4jMigration( + PlayerJpaRepository playerJpaRepository, + PlayerNeo4jRepository playerNeo4jRepository, + Neo4jLinkSupport neo4jLinkSupport, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.playerJpaRepository = playerJpaRepository; + this.playerNeo4jRepository = playerNeo4jRepository; + this.neo4jLinkSupport = neo4jLinkSupport; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "player"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 60; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), playerJpaRepository.count()); + return; + } + var entities = playerJpaRepository.findAllWithUserAndCountry(); + var nodes = entities.stream().map(this::toNode).toList(); + List> countryRows = entities.stream().map(this::countryLinkRow).toList(); + List> userRows = entities.stream().map(this::userLinkRow).toList(); + neo4jTransactionHelper.write(() -> { + playerNeo4jRepository.saveAll(nodes); + neo4jLinkSupport.mergePlayerCountryEdges(countryRows); + neo4jLinkSupport.mergePlayerUserEdges(userRows); + }); + log.info("[{}] migrated {} players", stepName(), nodes.size()); + } + + private PlayerNode toNode(PlayerEntity e) { + var n = new PlayerNode(); + n.setId(e.getId()); + n.setRating(e.getRating()); + n.setRu(e.getRu()); + n.setGamesPlayed(e.getGamesPlayed()); + return n; + } + + + private Map countryLinkRow(PlayerEntity e) { + var m = new HashMap(); + m.put("playerId", e.getId()); + m.put("countryId", e.getCountry().getId()); + return m; + } + + private Map userLinkRow(PlayerEntity e) { + var m = new HashMap(); + m.put("playerId", e.getId()); + m.put("userId", e.getUser().getId()); + return m; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PositionNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PositionNeo4jMigration.java new file mode 100644 index 000000000..a7a681e2d --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PositionNeo4jMigration.java @@ -0,0 +1,93 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.PositionNode; +import com.example.arimaabackend.model.sql.PositionEntity; +import com.example.arimaabackend.repository.neo4j.PositionNeo4jRepository; +import com.example.arimaabackend.repository.sql.PositionJpaRepository; + +@Service +@Profile("migration") +public class PositionNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(PositionNeo4jMigration.class); + + private final PositionJpaRepository positionJpaRepository; + private final PositionNeo4jRepository positionNeo4jRepository; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public PositionNeo4jMigration( + PositionJpaRepository positionJpaRepository, + PositionNeo4jRepository positionNeo4jRepository, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.positionJpaRepository = positionJpaRepository; + this.positionNeo4jRepository = positionNeo4jRepository; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "position"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 40; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), positionJpaRepository.count()); + return; + } + int batch = context.batchSize(); + long total = positionJpaRepository.count(); + long migrated = 0; + for (int page = 0; ; page++) { + var slice = positionJpaRepository.findAll(PageRequest.of(page, batch)); + if (!slice.hasContent()) { + break; + } + List batchNodes = new ArrayList<>(slice.getNumberOfElements()); + for (PositionEntity e : slice) { + batchNodes.add(toNode(e)); + } + neo4jTransactionHelper.write(() -> positionNeo4jRepository.saveAll(batchNodes)); + migrated += batchNodes.size(); + if (!slice.hasNext()) { + break; + } + } + log.info("[{}] migrated {} positions (total source ~{})", stepName(), migrated, total); + } + + private PositionNode toNode(PositionEntity e) { + var n = new PositionNode(); + n.setId(e.getId()); + n.setColor(e.getColor()); + n.setPiece(e.getPiece()); + n.setCoordinate(e.getCoordinate()); + return n; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PuzzleNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PuzzleNeo4jMigration.java new file mode 100644 index 000000000..86beb13bb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/PuzzleNeo4jMigration.java @@ -0,0 +1,75 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.PuzzleNode; +import com.example.arimaabackend.model.sql.PuzzleEntity; +import com.example.arimaabackend.repository.neo4j.PuzzleNeo4jRepository; +import com.example.arimaabackend.repository.sql.PuzzleJpaRepository; + +@Service +@Profile("migration") +public class PuzzleNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(PuzzleNeo4jMigration.class); + + private final PuzzleJpaRepository puzzleJpaRepository; + private final PuzzleNeo4jRepository puzzleNeo4jRepository; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public PuzzleNeo4jMigration( + PuzzleJpaRepository puzzleJpaRepository, + PuzzleNeo4jRepository puzzleNeo4jRepository, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.puzzleJpaRepository = puzzleJpaRepository; + this.puzzleNeo4jRepository = puzzleNeo4jRepository; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "puzzle"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 50; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), puzzleJpaRepository.count()); + return; + } + var nodes = puzzleJpaRepository.findAll().stream().map(this::toNode).toList(); + neo4jTransactionHelper.write(() -> puzzleNeo4jRepository.saveAll(nodes)); + log.info("[{}] migrated {} puzzles", stepName(), nodes.size()); + } + + private PuzzleNode toNode(PuzzleEntity e) { + var n = new PuzzleNode(); + n.setId(e.getId()); + n.setName(e.getName()); + n.setObjective(e.getObjective()); + n.setPlayerSide(e.getPlayerSide()); + n.setRounds(e.getRounds()); + return n; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/SolutionNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/SolutionNeo4jMigration.java new file mode 100644 index 000000000..9ac260fe4 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/SolutionNeo4jMigration.java @@ -0,0 +1,115 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jLinkSupport; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.SolutionNode; +import com.example.arimaabackend.model.sql.SolutionEntity; +import com.example.arimaabackend.repository.neo4j.SolutionNeo4jRepository; +import com.example.arimaabackend.repository.sql.SolutionJpaRepository; + +@Service +@Profile("migration") +public class SolutionNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(SolutionNeo4jMigration.class); + + private final SolutionJpaRepository solutionJpaRepository; + private final SolutionNeo4jRepository solutionNeo4jRepository; + private final Neo4jLinkSupport neo4jLinkSupport; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public SolutionNeo4jMigration( + SolutionJpaRepository solutionJpaRepository, + SolutionNeo4jRepository solutionNeo4jRepository, + Neo4jLinkSupport neo4jLinkSupport, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.solutionJpaRepository = solutionJpaRepository; + this.solutionNeo4jRepository = solutionNeo4jRepository; + this.neo4jLinkSupport = neo4jLinkSupport; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "solution"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 90; + } + + @Override + @Transactional(readOnly = true) + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), solutionJpaRepository.count()); + return; + } + int batch = context.batchSize(); + long migrated = 0; + for (int page = 0; ; page++) { + var slice = solutionJpaRepository.findAll(PageRequest.of(page, batch)); + if (!slice.hasContent()) { + break; + } + List nodes = new ArrayList<>(slice.getNumberOfElements()); + List> linkRows = new ArrayList<>(slice.getNumberOfElements()); + for (SolutionEntity e : slice) { + nodes.add(toNode(e)); + linkRows.add(linkRow(e)); + } + neo4jTransactionHelper.write(() -> { + solutionNeo4jRepository.saveAll(nodes); + neo4jLinkSupport.mergeHasSolutionEdges(linkRows); + neo4jLinkSupport.mergeSolutionPositionEdges(linkRows); + }); + migrated += nodes.size(); + if (!slice.hasNext()) { + break; + } + } + log.info("[{}] migrated {} solutions (nodes + HAS_SOLUTION edges)", stepName(), migrated); + } + + private SolutionNode toNode(SolutionEntity e) { + var n = new SolutionNode(); + n.setId(e.getId()); + n.setTurn(e.getTurn()); + n.setSequence(e.getSequence()); + n.setDirection(e.getDirection()); + n.setStatus(e.getStatus()); + return n; + } + + private Map linkRow(SolutionEntity e) { + var m = new HashMap(); + m.put("puzzleId", e.getPuzzle().getId()); + m.put("solutionId", e.getId()); + m.put("positionId", e.getPosition().getId()); + return m; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/UserNeo4jMigration.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/UserNeo4jMigration.java new file mode 100644 index 000000000..5526f058c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/steps/neo4j/UserNeo4jMigration.java @@ -0,0 +1,76 @@ +package com.example.arimaabackend.migration.steps.neo4j; + +import java.util.EnumSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.migration.MigrationContext; +import com.example.arimaabackend.migration.spi.MigrationStep; +import com.example.arimaabackend.migration.spi.MigrationTarget; +import com.example.arimaabackend.migration.support.Neo4jTransactionHelper; +import com.example.arimaabackend.model.neo4j.UserNode; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.neo4j.UserNeo4jRepository; +import com.example.arimaabackend.repository.sql.UserJpaRepository; + +@Service +@Profile("migration") +public class UserNeo4jMigration implements MigrationStep { + + private static final Logger log = LoggerFactory.getLogger(UserNeo4jMigration.class); + + private final UserJpaRepository userJpaRepository; + private final UserNeo4jRepository userNeo4jRepository; + private final Neo4jTransactionHelper neo4jTransactionHelper; + + public UserNeo4jMigration( + UserJpaRepository userJpaRepository, + UserNeo4jRepository userNeo4jRepository, + Neo4jTransactionHelper neo4jTransactionHelper + ) { + this.userJpaRepository = userJpaRepository; + this.userNeo4jRepository = userNeo4jRepository; + this.neo4jTransactionHelper = neo4jTransactionHelper; + } + + @Override + public String stepName() { + return "user"; + } + + @Override + public Set targets() { + return EnumSet.of(MigrationTarget.NEO4J); + } + + @Override + public int getOrder() { + return 55; + } + + @Override + public void migrate(MigrationContext context) { + if (context.dryRun()) { + log.info("[{}] dry-run: would migrate {} rows", stepName(), userJpaRepository.count()); + return; + } + var nodes = userJpaRepository.findAll().stream().map(this::toNode).toList(); + neo4jTransactionHelper.write(() -> userNeo4jRepository.saveAll(nodes)); + log.info("[{}] migrated {} users", stepName(), nodes.size()); + } + + private UserNode toNode(UserEntity e) { + var n = new UserNode(); + n.setId(e.getId()); + n.setUsername(e.getUsername()); + n.setEmail(e.getEmail()); + n.setRole(e.getRole()); + n.setCreatedAt(e.getCreatedAt()); + n.setUpdatedAt(e.getUpdatedAt()); + return n; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/support/Neo4jLinkSupport.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/support/Neo4jLinkSupport.java new file mode 100644 index 000000000..9dbf78400 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/support/Neo4jLinkSupport.java @@ -0,0 +1,240 @@ +package com.example.arimaabackend.migration.support; + +import java.util.List; +import java.util.Map; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.neo4j.core.Neo4jClient; +import org.springframework.stereotype.Component; + +/** + * Parameterized Cypher for edges not modeled from the child node side. + */ +@Component +@Profile("migration") +public class Neo4jLinkSupport { + + private final Neo4jClient neo4jClient; + + public Neo4jLinkSupport(Neo4jClient neo4jClient) { + this.neo4jClient = neo4jClient; + } + + public void mergeHasMoveEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (m:Match {id: row.matchId}) + MATCH (v:Move {id: row.moveId}) + WITH row, m, v, "matchMoves:" + toString(row.matchId) AS moveListKey + MERGE (ml:MoveList {key: moveListKey}) + MERGE (m)-[:HAS_MOVELIST]->(ml) + WITH row, ml, v, "matchTurn:" + toString(row.matchId) + ":" + toString(v.turn) AS turnKey + MERGE (t:Turn {key: turnKey}) + SET t.matchId = row.matchId, + t.turn = v.turn + MERGE (ml)-[:HAS_TURN]->(t) + MERGE (t)-[:HAS_MOVE]->(v) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergeMovePositionEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (v:Move {id: row.moveId}) + MATCH (p:Position {id: row.positionId}) + MERGE (v)-[:AT_POSITION]->(p) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + /** + * Fast-path: merge Move nodes and all required edges in one UNWIND. + * Expected row keys: matchId, moveId, turn, sequence, direction, status, positionId + */ + public void mergeMovesBatch(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MERGE (v:Move {id: row.moveId}) + SET v.turn = row.turn, + v.sequence = row.sequence, + v.direction = row.direction, + v.status = row.status + WITH row, v + MATCH (p:Position {id: row.positionId}) + MERGE (v)-[:AT_POSITION]->(p) + WITH row, v + MATCH (m:Match {id: row.matchId}) + WITH row, m, v, "matchMoves:" + toString(row.matchId) AS moveListKey + MERGE (ml:MoveList {key: moveListKey}) + MERGE (m)-[:HAS_MOVELIST]->(ml) + WITH row, ml, v, "matchTurn:" + toString(row.matchId) + ":" + toString(row.turn) AS turnKey + MERGE (t:Turn {key: turnKey}) + SET t.matchId = row.matchId, + t.turn = row.turn + MERGE (ml)-[:HAS_TURN]->(t) + MERGE (t)-[:HAS_MOVE]->(v) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergeHasSolutionEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (z:Puzzle {id: row.puzzleId}) + MATCH (s:Solution {id: row.solutionId}) + MERGE (z)-[:HAS_SOLUTION]->(s) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergeSolutionPositionEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (s:Solution {id: row.solutionId}) + MATCH (p:Position {id: row.positionId}) + MERGE (s)-[:AT_POSITION]->(p) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergePlayerCountryEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (p:Player {id: row.playerId}) + MATCH (c:Country {id: row.countryId}) + MERGE (p)-[:IN_COUNTRY]->(c) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergePlayerUserEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (p:Player {id: row.playerId}) + MATCH (u:User {id: row.userId}) + MERGE (p)-[:HAS_USER]->(u) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergeMatchReferenceEdges(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (m:Match {id: row.matchId}) + MATCH (silver:Player {id: row.silverPlayerId}) + MATCH (gold:Player {id: row.goldPlayerId}) + MATCH (e:Event {id: row.eventId}) + MATCH (g:GameType {id: row.gameTypeId}) + MERGE (m)-[:HAS_PLAYER {side: "SILVER"}]->(silver) + MERGE (m)-[:HAS_PLAYER {side: "GOLD"}]->(gold) + MERGE (m)-[:IN_EVENT]->(e) + MERGE (m)-[:HAS_GAMETYPE]->(g) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergeOpeningByMatch(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (m:Match {id: row.matchId}) + MATCH (p:Position {id: row.positionId}) + WITH row, m, p, coalesce(p.color, "UNKNOWN") AS side + WITH row, m, p, side, "match:" + toString(row.matchId) + ":" + side AS openingKey + MERGE (o:Opening {key: openingKey}) + SET o.side = side, + o.parentType = "MATCH", + o.parentId = row.matchId + MERGE (m)-[:HAS_OPENING]->(o) + MERGE (o)-[:HAS_POSITION]->(p) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } + + public void mergeOpeningByPuzzle(List> rows) { + if (rows.isEmpty()) { + return; + } + neo4jClient + .query( + """ + UNWIND $rows AS row + MATCH (z:Puzzle {id: row.puzzleId}) + MATCH (p:Position {id: row.positionId}) + WITH row, z, p, coalesce(p.color, "UNKNOWN") AS side + WITH row, z, p, side, "puzzle:" + toString(row.puzzleId) + ":" + side AS openingKey + MERGE (o:Opening {key: openingKey}) + SET o.side = side, + o.parentType = "PUZZLE", + o.parentId = row.puzzleId + MERGE (z)-[:HAS_OPENING]->(o) + MERGE (o)-[:HAS_POSITION]->(p) + """ + ) + .bindAll(Map.of("rows", rows)) + .run(); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/support/Neo4jTransactionHelper.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/support/Neo4jTransactionHelper.java new file mode 100644 index 000000000..58d8a9d4c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/migration/support/Neo4jTransactionHelper.java @@ -0,0 +1,26 @@ +package com.example.arimaabackend.migration.support; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +/** + * Imperative Spring Data Neo4j writes require a Neo4j-managed transaction; the default + * application {@code transactionManager} is typically JPA, so repository {@code save*} calls + * must run inside this helper. + */ +@Component +@Profile("migration") +public class Neo4jTransactionHelper { + + private final TransactionTemplate neo4jWrite; + + public Neo4jTransactionHelper(Neo4jTransactionManager neo4jTransactionManager) { + this.neo4jWrite = new TransactionTemplate(neo4jTransactionManager); + } + + public void write(Runnable work) { + neo4jWrite.executeWithoutResult(status -> work.run()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/DatabaseSequence.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/DatabaseSequence.java new file mode 100644 index 000000000..35564e5e0 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/DatabaseSequence.java @@ -0,0 +1,29 @@ +package com.example.arimaabackend.model.mongo; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("database_sequences") +public class DatabaseSequence { + + @Id + private String id; + + private long seq; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public long getSeq() { + return seq; + } + + public void setSeq(long seq) { + this.seq = seq; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/MatchDocument.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/MatchDocument.java new file mode 100644 index 000000000..129b03bd3 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/MatchDocument.java @@ -0,0 +1,285 @@ +package com.example.arimaabackend.model.mongo; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("matches") +public class MatchDocument { + + @Id + private Integer id; + + private String terminationType; + private String matchResult; + private Integer goldRating; + private Integer silverRating; + private Instant timestamp; + + private List players = new ArrayList<>(); + + private Event event; + private GameType gameType; + + private List opening = new ArrayList<>(); + private List moves = new ArrayList<>(); + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTerminationType() { + return terminationType; + } + + public void setTerminationType(String terminationType) { + this.terminationType = terminationType; + } + + public String getMatchResult() { + return matchResult; + } + + public void setMatchResult(String matchResult) { + this.matchResult = matchResult; + } + + public Integer getGoldRating() { + return goldRating; + } + + public void setGoldRating(Integer goldRating) { + this.goldRating = goldRating; + } + + public Integer getSilverRating() { + return silverRating; + } + + public void setSilverRating(Integer silverRating) { + this.silverRating = silverRating; + } + + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } + + public List getPlayers() { + return players; + } + + public void setPlayers(List players) { + this.players = players != null ? players : new ArrayList<>(); + } + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + public GameType getGameType() { + return gameType; + } + + public void setGameType(GameType gameType) { + this.gameType = gameType; + } + + public List getOpening() { + return opening; + } + + public void setOpening(List opening) { + this.opening = opening != null ? opening : new ArrayList<>(); + } + + public List getMoves() { + return moves; + } + + public void setMoves(List moves) { + this.moves = moves != null ? moves : new ArrayList<>(); + } + + public static class PlayerRef { + private Integer playerId; + private String color; + + public Integer getPlayerId() { + return playerId; + } + + public void setPlayerId(Integer playerId) { + this.playerId = playerId; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + } + + public static class Event { + private Integer id; + private String name; + private Boolean isRated; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getIsRated() { + return isRated; + } + + public void setIsRated(Boolean isRated) { + this.isRated = isRated; + } + } + + public static class GameType { + private Integer id; + private String name; + private Integer timeIncrement; + private Integer timeReserve; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getTimeIncrement() { + return timeIncrement; + } + + public void setTimeIncrement(Integer timeIncrement) { + this.timeIncrement = timeIncrement; + } + + public Integer getTimeReserve() { + return timeReserve; + } + + public void setTimeReserve(Integer timeReserve) { + this.timeReserve = timeReserve; + } + } + + public static class Position { + private String color; + private String piece; + private String coordinate; + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getPiece() { + return piece; + } + + public void setPiece(String piece) { + this.piece = piece; + } + + public String getCoordinate() { + return coordinate; + } + + public void setCoordinate(String coordinate) { + this.coordinate = coordinate; + } + } + + public static class Move { + private Integer turn; + private Integer sequence; + private String direction; + private String status; + private Position position; + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public Integer getSequence() { + return sequence; + } + + public void setSequence(Integer sequence) { + this.sequence = sequence; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/PlayerDocument.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/PlayerDocument.java new file mode 100644 index 000000000..e3a07640a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/PlayerDocument.java @@ -0,0 +1,68 @@ +package com.example.arimaabackend.model.mongo; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.DocumentReference; + +@Document("players") +public class PlayerDocument { + + @Id + private Integer id; + + @DocumentReference + private UserDocument user; + private Integer rating; + private Integer ru; + private Integer gamesPlayed; + private String country; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public UserDocument getUser() { + return user; + } + + public void setUser(UserDocument user) { + this.user = user; + } + + public Integer getRating() { + return rating; + } + + public void setRating(Integer rating) { + this.rating = rating; + } + + public Integer getRu() { + return ru; + } + + public void setRu(Integer ru) { + this.ru = ru; + } + + public Integer getGamesPlayed() { + return gamesPlayed; + } + + public void setGamesPlayed(Integer gamesPlayed) { + this.gamesPlayed = gamesPlayed; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/PuzzleDocument.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/PuzzleDocument.java new file mode 100644 index 000000000..17fa5aa33 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/PuzzleDocument.java @@ -0,0 +1,157 @@ +package com.example.arimaabackend.model.mongo; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("puzzles") +public class PuzzleDocument { + + @Id + private Integer id; + + private String name; + private String objective; + private String playerSide; + private Integer rounds; + + private List opening = new ArrayList<>(); + private List solution = new ArrayList<>(); + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getObjective() { + return objective; + } + + public void setObjective(String objective) { + this.objective = objective; + } + + public String getPlayerSide() { + return playerSide; + } + + public void setPlayerSide(String playerSide) { + this.playerSide = playerSide; + } + + public Integer getRounds() { + return rounds; + } + + public void setRounds(Integer rounds) { + this.rounds = rounds; + } + + public List getOpening() { + return opening; + } + + public void setOpening(List opening) { + this.opening = opening != null ? opening : new ArrayList<>(); + } + + public List getSolution() { + return solution; + } + + public void setSolution(List solution) { + this.solution = solution != null ? solution : new ArrayList<>(); + } + + public static class Position { + private String color; + private String piece; + private String coordinate; + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getPiece() { + return piece; + } + + public void setPiece(String piece) { + this.piece = piece; + } + + public String getCoordinate() { + return coordinate; + } + + public void setCoordinate(String coordinate) { + this.coordinate = coordinate; + } + } + + public static class SolutionMove { + private Integer turn; + private Integer sequence; + private String direction; + private String status; + private Position position; + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public Integer getSequence() { + return sequence; + } + + public void setSequence(Integer sequence) { + this.sequence = sequence; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/UserDocument.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/UserDocument.java new file mode 100644 index 000000000..b21b1fc8a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/mongo/UserDocument.java @@ -0,0 +1,78 @@ +package com.example.arimaabackend.model.mongo; + +import java.time.Instant; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("users") +public class UserDocument { + + public static final String SEQUENCE_NAME = "users_sequence"; + + @Id + private Long id; + + private String username; + private String email; + private String passwordHash; + private String role; + private Instant createdAt; + private Instant updatedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPasswordHash() { + return passwordHash; + } + + public void setPasswordHash(String passwordHash) { + this.passwordHash = passwordHash; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/CountryNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/CountryNode.java new file mode 100644 index 000000000..9f268064c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/CountryNode.java @@ -0,0 +1,30 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; + +@Node("Country") +public class CountryNode { + + @Id + private Integer id; + + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/EventNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/EventNode.java new file mode 100644 index 000000000..c6bd103b6 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/EventNode.java @@ -0,0 +1,39 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; + +@Node("Event") +public class EventNode { + + @Id + private Integer id; + + private String name; + private Boolean rated; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getRated() { + return rated; + } + + public void setRated(Boolean rated) { + this.rated = rated; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/GameTypeNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/GameTypeNode.java new file mode 100644 index 000000000..4728fe66f --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/GameTypeNode.java @@ -0,0 +1,48 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; + +@Node("GameType") +public class GameTypeNode { + + @Id + private Integer id; + + private String name; + private Integer timeIncrement; + private Integer timeReserve; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getTimeIncrement() { + return timeIncrement; + } + + public void setTimeIncrement(Integer timeIncrement) { + this.timeIncrement = timeIncrement; + } + + public Integer getTimeReserve() { + return timeReserve; + } + + public void setTimeReserve(Integer timeReserve) { + this.timeReserve = timeReserve; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MatchNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MatchNode.java new file mode 100644 index 000000000..3a57ab73a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MatchNode.java @@ -0,0 +1,125 @@ +package com.example.arimaabackend.model.neo4j; + +import java.time.Instant; +import java.util.List; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Match") +public class MatchNode { + + @Id + private Integer id; + + private String terminationType; + private String matchResult; + private Integer goldRating; + private Integer silverRating; + private Instant timestamp; + + @Relationship(type = "HAS_PLAYER") + private List players; + + @Relationship(type = "IN_EVENT") + private EventNode event; + + @Relationship(type = "HAS_GAMETYPE") + private GameTypeNode gameType; + + @Relationship(type = "HAS_MOVELIST") + private MoveListNode moveList; + + @Relationship(type = "HAS_OPENING") + private List openings; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTerminationType() { + return terminationType; + } + + public void setTerminationType(String terminationType) { + this.terminationType = terminationType; + } + + public String getMatchResult() { + return matchResult; + } + + public void setMatchResult(String matchResult) { + this.matchResult = matchResult; + } + + public Integer getGoldRating() { + return goldRating; + } + + public void setGoldRating(Integer goldRating) { + this.goldRating = goldRating; + } + + public Integer getSilverRating() { + return silverRating; + } + + public void setSilverRating(Integer silverRating) { + this.silverRating = silverRating; + } + + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } + + public List getPlayers() { + return players; + } + + public void setPlayers(List players) { + this.players = players; + } + + public EventNode getEvent() { + return event; + } + + public void setEvent(EventNode event) { + this.event = event; + } + + public GameTypeNode getGameType() { + return gameType; + } + + public void setGameType(GameTypeNode gameType) { + this.gameType = gameType; + } + + public MoveListNode getMoveList() { + return moveList; + } + + public void setMoveList(MoveListNode moveList) { + this.moveList = moveList; + } + + public List getOpenings() { + return openings; + } + + public void setOpenings(List openings) { + this.openings = openings; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MatchPlayerRelationship.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MatchPlayerRelationship.java new file mode 100644 index 000000000..58ea3b6b6 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MatchPlayerRelationship.java @@ -0,0 +1,49 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.GeneratedValue; +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.RelationshipProperties; +import org.springframework.data.neo4j.core.schema.TargetNode; + +@RelationshipProperties +public class MatchPlayerRelationship { + + public enum Side { + SILVER, + GOLD + } + + @Id + @GeneratedValue + private Long id; + + private Side side; + + @TargetNode + private PlayerNode player; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Side getSide() { + return side; + } + + public void setSide(Side side) { + this.side = side; + } + + public PlayerNode getPlayer() { + return player; + } + + public void setPlayer(PlayerNode player) { + this.player = player; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MoveListNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MoveListNode.java new file mode 100644 index 000000000..c3b1b4023 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MoveListNode.java @@ -0,0 +1,34 @@ +package com.example.arimaabackend.model.neo4j; + +import java.util.List; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("MoveList") +public class MoveListNode { + + @Id + private String key; + + @Relationship(type = "HAS_TURN") + private List turns; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public List getTurns() { + return turns; + } + + public void setTurns(List turns) { + this.turns = turns; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MoveNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MoveNode.java new file mode 100644 index 000000000..1a48add8a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/MoveNode.java @@ -0,0 +1,69 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Move") +public class MoveNode { + + @Id + private Integer id; + + private Integer turn; + private Integer sequence; + private String direction; + private String status; + + @Relationship(type = "AT_POSITION") + private PositionNode position; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public Integer getSequence() { + return sequence; + } + + public void setSequence(Integer sequence) { + this.sequence = sequence; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public PositionNode getPosition() { + return position; + } + + public void setPosition(PositionNode position) { + this.position = position; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/OpeningNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/OpeningNode.java new file mode 100644 index 000000000..4e9879ee1 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/OpeningNode.java @@ -0,0 +1,62 @@ +package com.example.arimaabackend.model.neo4j; + +import java.util.List; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Opening") +public class OpeningNode { + + @Id + private String key; + + private String side; + private String parentType; + private Integer parentId; + + @Relationship(type = "HAS_POSITION") + private List positions; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getSide() { + return side; + } + + public void setSide(String side) { + this.side = side; + } + + public String getParentType() { + return parentType; + } + + public void setParentType(String parentType) { + this.parentType = parentType; + } + + public Integer getParentId() { + return parentId; + } + + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + public List getPositions() { + return positions; + } + + public void setPositions(List positions) { + this.positions = positions; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PlayerNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PlayerNode.java new file mode 100644 index 000000000..2881f1b9a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PlayerNode.java @@ -0,0 +1,71 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Player") +public class PlayerNode { + + @Id + private Integer id; + + private Integer rating; + private Integer ru; + private Integer gamesPlayed; + + @Relationship(type = "HAS_USER") + private UserNode user; + + @Relationship(type = "IN_COUNTRY") + private CountryNode country; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getRating() { + return rating; + } + + public void setRating(Integer rating) { + this.rating = rating; + } + + public Integer getRu() { + return ru; + } + + public void setRu(Integer ru) { + this.ru = ru; + } + + public Integer getGamesPlayed() { + return gamesPlayed; + } + + public void setGamesPlayed(Integer gamesPlayed) { + this.gamesPlayed = gamesPlayed; + } + + public UserNode getUser() { + return user; + } + + public void setUser(UserNode user) { + this.user = user; + } + + public CountryNode getCountry() { + return country; + } + + public void setCountry(CountryNode country) { + this.country = country; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PositionNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PositionNode.java new file mode 100644 index 000000000..cacd109f4 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PositionNode.java @@ -0,0 +1,48 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; + +@Node("Position") +public class PositionNode { + + @Id + private Integer id; + + private String color; + private String piece; + private String coordinate; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getPiece() { + return piece; + } + + public void setPiece(String piece) { + this.piece = piece; + } + + public String getCoordinate() { + return coordinate; + } + + public void setCoordinate(String coordinate) { + this.coordinate = coordinate; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PuzzleNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PuzzleNode.java new file mode 100644 index 000000000..0b78d89a5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/PuzzleNode.java @@ -0,0 +1,82 @@ +package com.example.arimaabackend.model.neo4j; + +import java.util.List; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Puzzle") +public class PuzzleNode { + + @Id + private Integer id; + + private String name; + private String objective; + private String playerSide; + private Integer rounds; + + @Relationship(type = "HAS_SOLUTION") + private List solutions; + + @Relationship(type = "HAS_OPENING") + private List openings; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getObjective() { + return objective; + } + + public void setObjective(String objective) { + this.objective = objective; + } + + public String getPlayerSide() { + return playerSide; + } + + public void setPlayerSide(String playerSide) { + this.playerSide = playerSide; + } + + public Integer getRounds() { + return rounds; + } + + public void setRounds(Integer rounds) { + this.rounds = rounds; + } + + public List getSolutions() { + return solutions; + } + + public void setSolutions(List solutions) { + this.solutions = solutions; + } + + public List getOpenings() { + return openings; + } + + public void setOpenings(List openings) { + this.openings = openings; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/SolutionNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/SolutionNode.java new file mode 100644 index 000000000..5b12e5087 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/SolutionNode.java @@ -0,0 +1,69 @@ +package com.example.arimaabackend.model.neo4j; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Solution") +public class SolutionNode { + + @Id + private Integer id; + + private Integer turn; + private Integer sequence; + private String direction; + private String status; + + @Relationship(type = "AT_POSITION") + private PositionNode position; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public Integer getSequence() { + return sequence; + } + + public void setSequence(Integer sequence) { + this.sequence = sequence; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public PositionNode getPosition() { + return position; + } + + public void setPosition(PositionNode position) { + this.position = position; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/TurnNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/TurnNode.java new file mode 100644 index 000000000..d4f78dac1 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/TurnNode.java @@ -0,0 +1,53 @@ +package com.example.arimaabackend.model.neo4j; + +import java.util.List; + +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import org.springframework.data.neo4j.core.schema.Relationship; + +@Node("Turn") +public class TurnNode { + + @Id + private String key; + + private Integer matchId; + private Integer turn; + + @Relationship(type = "HAS_MOVE") + private List moves; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Integer getMatchId() { + return matchId; + } + + public void setMatchId(Integer matchId) { + this.matchId = matchId; + } + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public List getMoves() { + return moves; + } + + public void setMoves(List moves) { + this.moves = moves; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/UserNode.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/UserNode.java new file mode 100644 index 000000000..912b21abb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/neo4j/UserNode.java @@ -0,0 +1,67 @@ +package com.example.arimaabackend.model.neo4j; +import com.example.arimaabackend.enums.UserRole; +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; +import java.time.Instant; + +@Node("User") +public class UserNode { + + @Id + private Long id; + + private String username; + private String email; + private UserRole role = UserRole.USER; + private Instant createdAt; + private Instant updatedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public UserRole getRole() { + return role; + } + + public void setRole(UserRole role) { + this.role = role; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/CountryEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/CountryEntity.java new file mode 100644 index 000000000..18ee7cbb5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/CountryEntity.java @@ -0,0 +1,34 @@ + +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Countries") +public class CountryEntity { + + @Id + private Integer id; + + @Column(nullable = false, unique = true, length = 45) + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/EventEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/EventEntity.java new file mode 100644 index 000000000..f86c1d3fb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/EventEntity.java @@ -0,0 +1,44 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Events") +public class EventEntity { + + @Id + private Integer id; + + @Column(nullable = false, length = 45) + private String name; + + @Column(name = "isRated", nullable = false) + private Boolean rated; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getRated() { + return rated; + } + + public void setRated(Boolean rated) { + this.rated = rated; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/GameTypeEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/GameTypeEntity.java new file mode 100644 index 000000000..1fd70acbf --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/GameTypeEntity.java @@ -0,0 +1,55 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "GameTypes") +public class GameTypeEntity { + + @Id + private Integer id; + + @Column(nullable = false, length = 45) + private String name; + + @Column(name = "time_increment") + private Integer timeIncrement; + + @Column(name = "time_reserve") + private Integer timeReserve; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getTimeIncrement() { + return timeIncrement; + } + + public void setTimeIncrement(Integer timeIncrement) { + this.timeIncrement = timeIncrement; + } + + public Integer getTimeReserve() { + return timeReserve; + } + + public void setTimeReserve(Integer timeReserve) { + this.timeReserve = timeReserve; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/MatchEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/MatchEntity.java new file mode 100644 index 000000000..36e2ab499 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/MatchEntity.java @@ -0,0 +1,130 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; + +import java.time.Instant; + +@Entity +@Table(name = "Matches") +public class MatchEntity { + + @Id + private Integer id; + + @Column(name = "termination_type", nullable = false, length = 45) + private String terminationType; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "player_id_silver", nullable = false) + private PlayerEntity silverPlayer; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "player_id_gold", nullable = false) + private PlayerEntity goldPlayer; + + @Column(name = "gold_rating", nullable = true, length = 45) + private Integer goldRating; + + @Column(name = "silver_rating", nullable = true, length = 45) + private Integer silverRating; + + @Column(name = "match_result", nullable = false, length = 45) + private String matchResult; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "events_id", nullable = false) + private EventEntity event; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "gameTypes_id", nullable = false) + private GameTypeEntity gameType; + + @Column(name = "timestamp") + private Instant timestamp; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTerminationType() { + return terminationType; + } + + public void setTerminationType(String terminationType) { + this.terminationType = terminationType; + } + + public PlayerEntity getSilverPlayer() { + return silverPlayer; + } + + public void setSilverPlayer(PlayerEntity silverPlayer) { + this.silverPlayer = silverPlayer; + } + + public PlayerEntity getGoldPlayer() { + return goldPlayer; + } + + public void setGoldPlayer(PlayerEntity goldPlayer) { + this.goldPlayer = goldPlayer; + } + + public Integer getGoldRating() { + return this.goldRating; + } + + public void setGoldRating(Integer goldRating) { + this.goldRating = goldRating; + } + + public Integer getSilverRating() { + return this.silverRating; + } + + public void setSilverRating(Integer silverRating) { + this.silverRating = silverRating; + } + + public String getMatchResult() { + return matchResult; + } + + public void setMatchResult(String matchResult) { + this.matchResult = matchResult; + } + + public EventEntity getEvent() { + return event; + } + + public void setEvent(EventEntity event) { + this.event = event; + } + + public GameTypeEntity getGameType() { + return gameType; + } + + public void setGameType(GameTypeEntity gameType) { + this.gameType = gameType; + } + + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/MoveEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/MoveEntity.java new file mode 100644 index 000000000..863c688f0 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/MoveEntity.java @@ -0,0 +1,93 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Moves") +public class MoveEntity { + + @Id + private Integer id; + + @Column(nullable = false) + private Integer turn; + + @Column(nullable = false) + private Integer sequence; + + @Column(nullable = false, length = 1) + private String direction; + + @Column(nullable = false, length = 1) + private String status; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "matches_id", nullable = false) + private MatchEntity match; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "position_id", nullable = false) + private PositionEntity position; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public Integer getSequence() { + return sequence; + } + + public void setSequence(Integer sequence) { + this.sequence = sequence; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public MatchEntity getMatch() { + return match; + } + + public void setMatch(MatchEntity match) { + this.match = match; + } + + public PositionEntity getPosition() { + return position; + } + + public void setPosition(PositionEntity position) { + this.position = position; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PlayerEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PlayerEntity.java new file mode 100644 index 000000000..a6eeed031 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PlayerEntity.java @@ -0,0 +1,82 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Players") +public class PlayerEntity { + + @Id + private Integer id; + + @OneToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "user_id", nullable = false, unique = true) + private UserEntity user; + + private Integer rating; + + @Column(name = "RU") + private Integer ru; + + @Column(name = "games_played") + private Integer gamesPlayed; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "countries_id", nullable = false) + private CountryEntity country; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public UserEntity getUser() { + return user; + } + + public void setUser(UserEntity user) { + this.user = user; + } + + public Integer getRating() { + return rating; + } + + public void setRating(Integer rating) { + this.rating = rating; + } + + public Integer getRu() { + return ru; + } + + public void setRu(Integer ru) { + this.ru = ru; + } + + public Integer getGamesPlayed() { + return gamesPlayed; + } + + public void setGamesPlayed(Integer gamesPlayed) { + this.gamesPlayed = gamesPlayed; + } + + public CountryEntity getCountry() { + return country; + } + + public void setCountry(CountryEntity country) { + this.country = country; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PositionEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PositionEntity.java new file mode 100644 index 000000000..552a38dec --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PositionEntity.java @@ -0,0 +1,55 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Position") +public class PositionEntity { + + @Id + private Integer id; + + @Column(nullable = false, length = 6) + private String color; + + @Column(nullable = false, length = 4) + private String piece; + + @Column(name = "cordinate", nullable = false, length = 2) + private String coordinate; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getPiece() { + return piece; + } + + public void setPiece(String piece) { + this.piece = piece; + } + + public String getCoordinate() { + return coordinate; + } + + public void setCoordinate(String coordinate) { + this.coordinate = coordinate; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PuzzleEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PuzzleEntity.java new file mode 100644 index 000000000..9783e4828 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/PuzzleEntity.java @@ -0,0 +1,66 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Puzzles") +public class PuzzleEntity { + + @Id + private Integer id; + + @Column(nullable = false, unique = true, length = 45) + private String name; + + @Column(nullable = false, length = 45) + private String objective; + + @Column(name = "playerSide", nullable = false, length = 6) + private String playerSide; + + @Column(nullable = false) + private Integer rounds; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getObjective() { + return objective; + } + + public void setObjective(String objective) { + this.objective = objective; + } + + public String getPlayerSide() { + return playerSide; + } + + public void setPlayerSide(String playerSide) { + this.playerSide = playerSide; + } + + public Integer getRounds() { + return rounds; + } + + public void setRounds(Integer rounds) { + this.rounds = rounds; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/SolutionEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/SolutionEntity.java new file mode 100644 index 000000000..1cfed0bce --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/SolutionEntity.java @@ -0,0 +1,92 @@ +package com.example.arimaabackend.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Solutions") +public class SolutionEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(nullable = false) + private Integer turn; + + @Column(nullable = false) + private Integer sequence; + + @Column(nullable = false, length = 1) + private String direction; + + @Column(nullable = false, length = 1) + private String status; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "position_id", nullable = false) + private PositionEntity position; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "puzzles_id", nullable = false) + private PuzzleEntity puzzle; + + public Integer getId() { + return id; + } + + public Integer getTurn() { + return turn; + } + + public void setTurn(Integer turn) { + this.turn = turn; + } + + public Integer getSequence() { + return sequence; + } + + public void setSequence(Integer sequence) { + this.sequence = sequence; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public PositionEntity getPosition() { + return position; + } + + public void setPosition(PositionEntity position) { + this.position = position; + } + + public PuzzleEntity getPuzzle() { + return puzzle; + } + + public void setPuzzle(PuzzleEntity puzzle) { + this.puzzle = puzzle; + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/UserEntity.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/UserEntity.java new file mode 100644 index 000000000..6e989f239 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/model/sql/UserEntity.java @@ -0,0 +1,106 @@ +package com.example.arimaabackend.model.sql; + +import java.time.Instant; + +import com.example.arimaabackend.enums.UserRole; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.PrePersist; +import jakarta.persistence.PreUpdate; +import jakarta.persistence.Table; + +@Entity +@Table(name = "Users") +public class UserEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true, length = 50) + private String username; + + @Column(nullable = false, unique = true, length = 254) + private String email; + + @Column(name = "password", nullable = false, length = 100) + private String passwordHash; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 20) + private UserRole role = UserRole.USER; + + @Column(name = "created_at", nullable = false, updatable = false) + private Instant createdAt; + + @Column(name = "updated_at", nullable = false) + private Instant updatedAt; + + @PrePersist + @SuppressWarnings("unused") + void prePersist() { + var now = Instant.now(); + this.createdAt = now; + this.updatedAt = now; + if (this.role == null) { + this.role = UserRole.USER; + } + } + + @PreUpdate + @SuppressWarnings("unused") + void preUpdate() { + this.updatedAt = Instant.now(); + } + + public Long getId() { + return id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPasswordHash() { + return passwordHash; + } + + public void setPasswordHash(String passwordHash) { + this.passwordHash = passwordHash; + } + + public UserRole getRole() { + return role; + } + + public void setRole(UserRole role) { + this.role = role; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/MatchMongoRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/MatchMongoRepository.java new file mode 100644 index 000000000..0c41da1ba --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/MatchMongoRepository.java @@ -0,0 +1,12 @@ +package com.example.arimaabackend.repository.mongo; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; + +import com.example.arimaabackend.model.mongo.MatchDocument; +import java.util.List; + +public interface MatchMongoRepository extends MongoRepository { + @Query("{ 'players.playerId': ?0 }") + List findByPlayerId(Integer playerId); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/PlayerMongoRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/PlayerMongoRepository.java new file mode 100644 index 000000000..2087d393d --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/PlayerMongoRepository.java @@ -0,0 +1,13 @@ +package com.example.arimaabackend.repository.mongo; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.example.arimaabackend.model.mongo.PlayerDocument; +import java.util.List; +import java.util.Optional; + +public interface PlayerMongoRepository extends MongoRepository { + Optional findByUser_Username(String username); + List findByCountry(String country); +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/PuzzleMongoRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/PuzzleMongoRepository.java new file mode 100644 index 000000000..1be644dc9 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/PuzzleMongoRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.mongo; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.example.arimaabackend.model.mongo.PuzzleDocument; + +public interface PuzzleMongoRepository extends MongoRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/UserMongoRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/UserMongoRepository.java new file mode 100644 index 000000000..755fa9167 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/mongo/UserMongoRepository.java @@ -0,0 +1,10 @@ +package com.example.arimaabackend.repository.mongo; + +import com.example.arimaabackend.model.mongo.UserDocument; +import org.springframework.data.mongodb.repository.MongoRepository; +import java.util.Optional; + +public interface UserMongoRepository extends MongoRepository { + Optional findByUsername(String username); +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/CountryNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/CountryNeo4jRepository.java new file mode 100644 index 000000000..571bd6cca --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/CountryNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.CountryNode; + +public interface CountryNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/EventNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/EventNeo4jRepository.java new file mode 100644 index 000000000..159957351 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/EventNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.EventNode; + +public interface EventNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/GameTypeNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/GameTypeNeo4jRepository.java new file mode 100644 index 000000000..6a5f26629 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/GameTypeNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.GameTypeNode; + +public interface GameTypeNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/MatchNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/MatchNeo4jRepository.java new file mode 100644 index 000000000..02bf59e13 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/MatchNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.MatchNode; + +public interface MatchNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/MoveNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/MoveNeo4jRepository.java new file mode 100644 index 000000000..bfd7bf249 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/MoveNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.MoveNode; + +public interface MoveNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PlayerNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PlayerNeo4jRepository.java new file mode 100644 index 000000000..31a68feb9 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PlayerNeo4jRepository.java @@ -0,0 +1,24 @@ +package com.example.arimaabackend.repository.neo4j; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.data.neo4j.repository.query.Query; + +import com.example.arimaabackend.model.neo4j.PlayerNode; + +public interface PlayerNeo4jRepository extends Neo4jRepository { + + @Query(""" + MATCH (p:Player)-[:HAS_USER]->(u:User {username: $username}) + RETURN p + """) + Optional findByUsername(String username); + + @Query(""" + MATCH (p:Player)-[:IN_COUNTRY]->(c:Country {name: $countryName}) + RETURN p + """) + List findByCountryName(String countryName); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PositionNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PositionNeo4jRepository.java new file mode 100644 index 000000000..4ebd46063 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PositionNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.PositionNode; + +public interface PositionNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PuzzleNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PuzzleNeo4jRepository.java new file mode 100644 index 000000000..aaf2e3a22 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/PuzzleNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.PuzzleNode; + +public interface PuzzleNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/SolutionNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/SolutionNeo4jRepository.java new file mode 100644 index 000000000..773a3c84e --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/SolutionNeo4jRepository.java @@ -0,0 +1,8 @@ +package com.example.arimaabackend.repository.neo4j; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +import com.example.arimaabackend.model.neo4j.SolutionNode; + +public interface SolutionNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/UserNeo4jRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/UserNeo4jRepository.java new file mode 100644 index 000000000..0781cec03 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/neo4j/UserNeo4jRepository.java @@ -0,0 +1,7 @@ +package com.example.arimaabackend.repository.neo4j; + +import com.example.arimaabackend.model.neo4j.UserNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; + +public interface UserNeo4jRepository extends Neo4jRepository {} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/CountryJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/CountryJpaRepository.java new file mode 100644 index 000000000..029f5bf27 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/CountryJpaRepository.java @@ -0,0 +1,10 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.arimaabackend.model.sql.CountryEntity; + +public interface CountryJpaRepository extends JpaRepository { + Optional findByName(String name); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/EventJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/EventJpaRepository.java new file mode 100644 index 000000000..683882455 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/EventJpaRepository.java @@ -0,0 +1,10 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.arimaabackend.model.sql.EventEntity; + +public interface EventJpaRepository extends JpaRepository { + Optional findByName(String name); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/GameTypeJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/GameTypeJpaRepository.java new file mode 100644 index 000000000..88141a775 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/GameTypeJpaRepository.java @@ -0,0 +1,10 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.arimaabackend.model.sql.GameTypeEntity; + +public interface GameTypeJpaRepository extends JpaRepository { + Optional findByName(String name); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/MatchJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/MatchJpaRepository.java new file mode 100644 index 000000000..0c793f5a6 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/MatchJpaRepository.java @@ -0,0 +1,27 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.example.arimaabackend.model.sql.MatchEntity; + +public interface MatchJpaRepository extends JpaRepository { + + @Query(""" + SELECT m FROM MatchEntity m + JOIN FETCH m.goldPlayer + JOIN FETCH m.silverPlayer + JOIN FETCH m.event + JOIN FETCH m.gameType + """) + List findAllForMigration(); + List findBySilverPlayer_Id(Integer playerId); + + List findByGoldPlayer_Id(Integer playerId); + + List findByEvent_Id(Integer eventId); + + List findByGameType_Id(Integer gameTypeId); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/MoveJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/MoveJpaRepository.java new file mode 100644 index 000000000..5a99bc860 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/MoveJpaRepository.java @@ -0,0 +1,13 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.arimaabackend.model.sql.MoveEntity; + +public interface MoveJpaRepository extends JpaRepository { + List findByMatch_IdOrderByTurnAscSequenceAsc(Integer matchId); + + void deleteByMatch_Id(Integer matchId); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PlayerJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PlayerJpaRepository.java new file mode 100644 index 000000000..a5249001b --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PlayerJpaRepository.java @@ -0,0 +1,24 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.example.arimaabackend.model.sql.PlayerEntity; + +public interface PlayerJpaRepository extends JpaRepository { + + @Query("SELECT p FROM PlayerEntity p JOIN FETCH p.user JOIN FETCH p.country") + List findAllWithUserAndCountry(); + Optional findByUser_Id(Long id); + + Optional findByUser_Username(String username); + + Optional findByUser_Email(String email); + + List findByCountryName(String countryName); + +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PositionJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PositionJpaRepository.java new file mode 100644 index 000000000..847c3ac41 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PositionJpaRepository.java @@ -0,0 +1,16 @@ +package com.example.arimaabackend.repository.sql; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.example.arimaabackend.model.sql.PositionEntity; + +public interface PositionJpaRepository extends JpaRepository { + @Modifying + @Query("DELETE FROM PositionEntity p WHERE p.id IN (SELECT m.position.id FROM MoveEntity m WHERE m.match.id = :matchId) " + + "AND NOT EXISTS (SELECT 1 FROM MoveEntity m2 WHERE m2.position.id = p.id AND m2.match.id <> :matchId) " + + "AND NOT EXISTS (SELECT 1 FROM SolutionEntity s WHERE s.position.id = p.id)") + void deleteUnusedByMatchId(@Param("matchId") Integer matchId); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PuzzleJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PuzzleJpaRepository.java new file mode 100644 index 000000000..e13c8fc2a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/PuzzleJpaRepository.java @@ -0,0 +1,11 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.arimaabackend.model.sql.PuzzleEntity; + +public interface PuzzleJpaRepository extends JpaRepository { + Optional findByName(String name); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/SolutionJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/SolutionJpaRepository.java new file mode 100644 index 000000000..a1310f95f --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/SolutionJpaRepository.java @@ -0,0 +1,11 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.example.arimaabackend.model.sql.SolutionEntity; + +public interface SolutionJpaRepository extends JpaRepository { + List findByPuzzle_IdOrderByTurnAscSequenceAsc(Integer puzzleId); +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/UserJpaRepository.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/UserJpaRepository.java new file mode 100644 index 000000000..11090a3c0 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/repository/sql/UserJpaRepository.java @@ -0,0 +1,36 @@ +package com.example.arimaabackend.repository.sql; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.example.arimaabackend.model.sql.UserEntity; + +public interface UserJpaRepository extends JpaRepository { + + // Hibernate/JPA: Spring Data looks at the method name (findByEmail), + // matches 'email' to the 'email' field on UserEntity, and generates + // a JPQL query like: select u from UserEntity u where u.email = :email. + // JPA then maps that to real SQL against the 'users' table. + Optional findByEmail(String email); + + Optional findByUsername(String username); + + boolean existsByUsername(String username); + boolean existsByEmail(String email); + + // JOQL SQL @Query example. Uses UserEntity as table reference + @Query("select u from UserEntity u where lower(u.email) like lower(concat('%', :part, '%'))") + List searchByEmailPart(@Param("part") String part); + + // Native SQL @Query example. Uses the real table name (users). + @Query( + value = "select * from users u where u.username like concat(:prefix, '%')", + nativeQuery = true + ) + List findByUsernameStartingWith(@Param("prefix") String prefix); +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/security/UserDetailsServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/security/UserDetailsServiceImpl.java new file mode 100644 index 000000000..3db9101b8 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/security/UserDetailsServiceImpl.java @@ -0,0 +1,31 @@ +package com.example.arimaabackend.security; + +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class UserDetailsServiceImpl implements UserDetailsService { + + private final UserJpaRepository userJpaRepository; + + public UserDetailsServiceImpl(UserJpaRepository userJpaRepository) { + this.userJpaRepository = userJpaRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + var entity = userJpaRepository.findByUsername(username) + .orElseThrow(() -> new UsernameNotFoundException("User not found: " + username)); + + var authority = new SimpleGrantedAuthority("ROLE_" + entity.getRole().name()); + + return new User(entity.getUsername(), entity.getPasswordHash(), List.of(authority)); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MatchService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MatchService.java new file mode 100644 index 000000000..9d83b27b6 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MatchService.java @@ -0,0 +1,11 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.dto.MatchResponse; +import java.util.Optional; + +public interface MatchService { + Optional getMatch(Integer id); + MatchResponse createMatch(String matchData); + void deleteMatch(Integer id); + MatchResponse updateMatch(Integer id, String matchData); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MatchServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MatchServiceImpl.java new file mode 100644 index 000000000..5ec105def --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MatchServiceImpl.java @@ -0,0 +1,235 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.dto.*; +import com.example.arimaabackend.model.sql.*; +import com.example.arimaabackend.repository.sql.*; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import java.time.Instant; +import java.util.Optional; + +@Service +public class MatchServiceImpl implements MatchService { + + private final MatchJpaRepository matchRepository; + private final PlayerJpaRepository playerRepository; + private final UserJpaRepository userRepository; + private final EventJpaRepository eventRepository; + private final GameTypeJpaRepository gameTypeRepository; + private final CountryJpaRepository countryRepository; + private final MoveJpaRepository moveRepository; + private final PositionJpaRepository positionRepository; + public MatchServiceImpl( + MatchJpaRepository matchRepository, + PlayerJpaRepository playerRepository, + UserJpaRepository userRepository, + EventJpaRepository eventRepository, + GameTypeJpaRepository gameTypeRepository, + CountryJpaRepository countryRepository, + MoveJpaRepository moveRepository, + PositionJpaRepository positionRepository) { + this.matchRepository = matchRepository; + this.playerRepository = playerRepository; + this.userRepository = userRepository; + this.eventRepository = eventRepository; + this.gameTypeRepository = gameTypeRepository; + this.countryRepository = countryRepository; + this.moveRepository = moveRepository; + this.positionRepository = positionRepository; + } + + @Override + @Transactional(readOnly = true) + public Optional getMatch(Integer id) { + return matchRepository.findById(id).map(this::toMatchResponse); + } + + @Override + @Transactional + public MatchResponse createMatch(String matchData) { + String[] parts = splitAndValidateMatchData(matchData); + Integer id = Integer.parseInt(parts[0]); + + MatchEntity match = new MatchEntity(); + match.setId(id); + populateMatchFromParts(match, parts); + + return toMatchResponse(matchRepository.save(match)); + } + + @Override + @Transactional + public MatchResponse updateMatch(Integer id, String matchData) { + MatchEntity match = matchRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Match not found")); + + String[] parts = splitAndValidateMatchData(matchData); + populateMatchFromParts(match, parts); + + return toMatchResponse(matchRepository.save(match)); + } + + private String[] splitAndValidateMatchData(String matchData) { + String[] parts = matchData.split("\t"); + if (parts.length < 23) { + throw new IllegalArgumentException("Invalid match data format"); + } + return parts; + } + + private void populateMatchFromParts(MatchEntity match, String[] parts) { + Integer wPlayerId = Integer.parseInt(parts[1]); + Integer bPlayerId = Integer.parseInt(parts[2]); + String wUsername = parts[3]; + String bUsername = parts[4]; + String wCountryName = parts[7]; + String bCountryName = parts[8]; + Integer wRating = Integer.parseInt(parts[9]); + Integer bRating = Integer.parseInt(parts[10]); + String eventName = parts[15]; + String timeControl = parts[17]; + long startTs = Long.parseLong(parts[19]); + String result = parts[21]; + String termination = parts[22]; + + PlayerEntity goldPlayer = getOrCreatePlayer(wPlayerId, wUsername, wCountryName, wRating); + PlayerEntity silverPlayer = getOrCreatePlayer(bPlayerId, bUsername, bCountryName, bRating); + EventEntity event = getOrCreateEvent(eventName); + GameTypeEntity gameType = getOrCreateGameType(timeControl); + + match.setGoldPlayer(goldPlayer); + match.setSilverPlayer(silverPlayer); + match.setGoldRating(wRating); + match.setSilverRating(bRating); + match.setEvent(event); + match.setGameType(gameType); + match.setTimestamp(Instant.ofEpochSecond(startTs)); + match.setMatchResult(result); + match.setTerminationType(termination); + } + + private MatchResponse toMatchResponse(MatchEntity match) { + PlayerSummary silverPlayer = null; + if (match.getSilverPlayer() != null) { + String username = match.getSilverPlayer().getUser() != null ? match.getSilverPlayer().getUser().getUsername() : null; + silverPlayer = new PlayerSummary(match.getSilverPlayer().getId(), username); + } + + PlayerSummary goldPlayer = null; + if (match.getGoldPlayer() != null) { + String username = match.getGoldPlayer().getUser() != null ? match.getGoldPlayer().getUser().getUsername() : null; + goldPlayer = new PlayerSummary(match.getGoldPlayer().getId(), username); + } + + EventSummary event = null; + if (match.getEvent() != null) { + event = new EventSummary(match.getEvent().getId(), match.getEvent().getName()); + } + + GameTypeSummary gameType = null; + if (match.getGameType() != null) { + gameType = new GameTypeSummary( + match.getGameType().getId(), + match.getGameType().getName(), + match.getGameType().getTimeIncrement(), + match.getGameType().getTimeReserve()); + } + + return new MatchResponse( + match.getId(), + match.getTerminationType(), + silverPlayer, + goldPlayer, + match.getGoldRating(), + match.getSilverRating(), + match.getMatchResult(), + event, + gameType, + match.getTimestamp() + ); + } + + @Override + @Transactional + public void deleteMatch(Integer id) { + if (!matchRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Match with ID " + id + " not found"); + } + positionRepository.deleteUnusedByMatchId(id); + moveRepository.deleteByMatch_Id(id); + matchRepository.deleteById(id); + } + + private PlayerEntity getOrCreatePlayer(Integer id, String username, String countryName, Integer rating) { + // First, check if the player already exists + Optional existingPlayerOpt = playerRepository.findById(id); + + if (existingPlayerOpt.isPresent()) { + PlayerEntity existingPlayer = existingPlayerOpt.get(); + String existingUsername = existingPlayer.getUser() != null + ? existingPlayer.getUser().getUsername() + : null; + + // If the username doesn't match, this is a data inconsistency → fail fast + if (!username.equals(existingUsername)) { + throw new IllegalArgumentException( + String.format("Player with ID %d exists but has different username. " + + "Expected: %s, Found: %s", + id, username, existingUsername)); + } + + // Player exists and username matches → return it + return existingPlayer; + } + + // Player doesn't exist → create new one (with user and country if needed) + UserEntity user = userRepository.findByUsername(username).orElseGet(() -> { + UserEntity newUser = new UserEntity(); + newUser.setUsername(username); + newUser.setEmail(username + "@example.com"); + newUser.setPasswordHash("PLACEHOLDER"); + return userRepository.save(newUser); + }); + + CountryEntity country = countryRepository.findByName(countryName).orElseGet(() -> { + CountryEntity newCountry = new CountryEntity(); + newCountry.setId(countryName.hashCode()); // Consider proper ID strategy later + newCountry.setName(countryName); + return countryRepository.save(newCountry); + }); + + PlayerEntity player = new PlayerEntity(); + player.setId(id); + player.setUser(user); + player.setCountry(country); + player.setRating(rating); + player.setGamesPlayed(0); + player.setRu(0); + + return playerRepository.save(player); + } + + private EventEntity getOrCreateEvent(String name) { + return eventRepository.findByName(name).orElseGet(() -> { + EventEntity event = new EventEntity(); + event.setId(name.hashCode()); + event.setName(name); + event.setRated(true); + return eventRepository.save(event); + }); + } + + private GameTypeEntity getOrCreateGameType(String name) { + return gameTypeRepository.findByName(name).orElseGet(() -> { + GameTypeEntity gameType = new GameTypeEntity(); + gameType.setId(name.hashCode()); + gameType.setName(name); + gameType.setTimeIncrement(0); + gameType.setTimeReserve(0); + return gameTypeRepository.save(gameType); + }); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MoveService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MoveService.java new file mode 100644 index 000000000..3f26e23e3 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MoveService.java @@ -0,0 +1,9 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.model.sql.MatchEntity; +import com.example.arimaabackend.model.sql.MoveEntity; +import com.example.arimaabackend.model.sql.PositionEntity; + +public interface MoveService { + MoveEntity createMove(Integer id, Integer turn, Integer sequence, String direction, String status, MatchEntity match, PositionEntity position); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MoveServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MoveServiceImpl.java new file mode 100644 index 000000000..6bb6067be --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/MoveServiceImpl.java @@ -0,0 +1,32 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.model.sql.MatchEntity; +import com.example.arimaabackend.model.sql.MoveEntity; +import com.example.arimaabackend.model.sql.PositionEntity; +import com.example.arimaabackend.repository.sql.MoveJpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class MoveServiceImpl implements MoveService { + + private final MoveJpaRepository moveRepository; + + public MoveServiceImpl(MoveJpaRepository moveRepository) { + this.moveRepository = moveRepository; + } + + @Override + @Transactional + public MoveEntity createMove(Integer id, Integer turn, Integer sequence, String direction, String status, MatchEntity match, PositionEntity position) { + MoveEntity move = new MoveEntity(); + move.setId(id); + move.setTurn(turn); + move.setSequence(sequence); + move.setDirection(direction); + move.setStatus(status); + move.setMatch(match); + move.setPosition(position); + return moveRepository.save(move); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PlayerService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PlayerService.java new file mode 100644 index 000000000..dbf2cfca5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PlayerService.java @@ -0,0 +1,17 @@ +package com.example.arimaabackend.services; + +import java.util.List; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.dto.PlayerUpdateRequest; + +public interface PlayerService { + PlayerResponse create(PlayerCreateRequest request); + PlayerResponse update(Integer id, PlayerUpdateRequest request); + PlayerResponse getByUsername(String username); + PlayerResponse getById(Integer id); + List getAll(); + List getByCountryName(String countryName); + void deleteById(Integer id); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PlayerServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PlayerServiceImpl.java new file mode 100644 index 000000000..92602042c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PlayerServiceImpl.java @@ -0,0 +1,176 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.dto.PlayerUpdateRequest; +import com.example.arimaabackend.model.sql.CountryEntity; +import com.example.arimaabackend.model.sql.PlayerEntity; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.sql.CountryJpaRepository; +import com.example.arimaabackend.repository.sql.MatchJpaRepository; +import com.example.arimaabackend.repository.sql.PlayerJpaRepository; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; + +@Service +@Transactional +public class PlayerServiceImpl implements PlayerService { + + private final PlayerJpaRepository playerJpaRepository; + private final UserJpaRepository userJpaRepository; + private final CountryJpaRepository countryJpaRepository; + private final MatchJpaRepository matchJpaRepository; + private final PasswordEncoder passwordEncoder; + + public PlayerServiceImpl(PlayerJpaRepository playerJpaRepository, + UserJpaRepository userJpaRepository, + CountryJpaRepository countryJpaRepository, + MatchJpaRepository matchJpaRepository, + PasswordEncoder passwordEncoder) { + this.playerJpaRepository = playerJpaRepository; + this.userJpaRepository = userJpaRepository; + this.countryJpaRepository = countryJpaRepository; + this.matchJpaRepository = matchJpaRepository; + this.passwordEncoder = passwordEncoder; + } + + @Override + public PlayerResponse create(PlayerCreateRequest request) { + UserEntity user = userJpaRepository.findById(request.userId()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found".formatted(request.userId()))); + + if (playerJpaRepository.findByUser_Id(user.getId()).isPresent()) { + throw new ResponseStatusException(HttpStatus.CONFLICT, "Player for user %d already exists".formatted(user.getId())); + } + + CountryEntity country = null; + if (request.countryId() != null) { + country = countryJpaRepository.findById(request.countryId()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Country %d not found".formatted(request.countryId()))); + } + + PlayerEntity entity = new PlayerEntity(); + entity.setUser(user); + entity.setCountry(country); + entity.setRating(request.rating() != null ? request.rating() : 1200); + entity.setRu(request.ru() != null ? request.ru() : 0); + entity.setGamesPlayed(request.gamesPlayed() != null ? request.gamesPlayed() : 0); + entity.setId(user.getId().intValue()); + entity = playerJpaRepository.save(entity); + return toResponse(entity); + } + + @Override + public PlayerResponse update(Integer id, PlayerUpdateRequest request) { + PlayerEntity entity = playerJpaRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Player %d not found".formatted(id))); + + CountryEntity country = null; + if (request.countryId() != null) { + country = countryJpaRepository.findById(request.countryId()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Country %d not found".formatted(request.countryId()))); + } + + entity.setRating(request.rating()); + entity.setRu(request.ru()); + entity.setGamesPlayed(request.gamesPlayed()); + entity.setCountry(country); + + if (request.userUpdate() != null) { + UserEntity user = entity.getUser(); + user.setUsername(request.userUpdate().username()); + user.setEmail(request.userUpdate().email()); + if (request.userUpdate().password() != null && !request.userUpdate().password().isBlank()) { + user.setPasswordHash(passwordEncoder.encode(request.userUpdate().password())); + } + userJpaRepository.save(user); + } + + entity = playerJpaRepository.save(entity); + return toResponse(entity); + } + + @Override + @Transactional(readOnly = true) + public PlayerResponse getByUsername(String username) { + + UserEntity user = userJpaRepository.findByUsername(username) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User '%s' not found".formatted(username))); + + PlayerResponse player = playerJpaRepository + .findByUser_Id(user.getId()).map(PlayerServiceImpl::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Player '%s' not found".formatted(username))); + + return new PlayerResponse( + player.id(), + user.getUsername(), + user.getEmail(), + player.rating(), + player.ru(), + player.gamesPlayed(), + player.createTime(), + player.countryId() + ); + } + + + @Override + @Transactional(readOnly = true) + public PlayerResponse getById(Integer id) { + return playerJpaRepository.findById(id) + .map(PlayerServiceImpl::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Player %d not found".formatted(id))); + } + + @Override + @Transactional(readOnly = true) + public List getAll() { + return playerJpaRepository.findAll().stream() + .map(PlayerServiceImpl::toResponse) + .toList(); + } + + @Override + @Transactional(readOnly = true) + public List getByCountryName(String countryName) { + return playerJpaRepository.findByCountryName(countryName).stream() + .map(PlayerServiceImpl::toResponse) + .toList(); + } + + @Override + public void deleteById(Integer id) { + if (!playerJpaRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Player %d not found".formatted(id)); + } + + boolean hasMatches = !matchJpaRepository.findByGoldPlayer_Id(id).isEmpty() || + !matchJpaRepository.findBySilverPlayer_Id(id).isEmpty(); + + if (hasMatches) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Cannot delete player with matches"); + } + + playerJpaRepository.deleteById(id); + } + + private static PlayerResponse toResponse(PlayerEntity entity) { + UserEntity user = entity.getUser(); + return new PlayerResponse( + entity.getId(), + user != null ? user.getUsername() : "", + user != null ? user.getEmail() : "", + entity.getRating(), + entity.getRu(), + entity.getGamesPlayed(), + null, + entity.getCountry() != null ? entity.getCountry().getId() : null + ); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PositionService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PositionService.java new file mode 100644 index 000000000..e4a1d8f46 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PositionService.java @@ -0,0 +1,7 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.model.sql.PositionEntity; + +public interface PositionService { + PositionEntity getOrCreatePosition(Integer id, String color, String piece, String coordinate); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PositionServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PositionServiceImpl.java new file mode 100644 index 000000000..af49066bf --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/PositionServiceImpl.java @@ -0,0 +1,29 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.model.sql.PositionEntity; +import com.example.arimaabackend.repository.sql.PositionJpaRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class PositionServiceImpl implements PositionService { + + private final PositionJpaRepository positionRepository; + + public PositionServiceImpl(PositionJpaRepository positionRepository) { + this.positionRepository = positionRepository; + } + + @Override + @Transactional + public PositionEntity getOrCreatePosition(Integer id, String color, String piece, String coordinate) { + return positionRepository.findById(id).orElseGet(() -> { + PositionEntity position = new PositionEntity(); + position.setId(id); + position.setColor(color); + position.setPiece(piece); + position.setCoordinate(coordinate); + return positionRepository.save(position); + }); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/UserService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/UserService.java new file mode 100644 index 000000000..8c874e6da --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/UserService.java @@ -0,0 +1,14 @@ +package com.example.arimaabackend.services; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; + +public interface UserService { + UserResponse create(UserCreateRequest request); + UserResponse getById(Long id); + UserResponse update(Long id, UserUpdateRequest request); + + void deleteById(Long id); +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/UserServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/UserServiceImpl.java new file mode 100644 index 000000000..b23a01d7c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/UserServiceImpl.java @@ -0,0 +1,79 @@ +package com.example.arimaabackend.services; + +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.sql.UserJpaRepository; + +@Service +@Transactional +public class UserServiceImpl implements UserService { + + private final UserJpaRepository userJpaRepository; + private final PasswordEncoder passwordEncoder; + + public UserServiceImpl(UserJpaRepository userJpaRepository, PasswordEncoder passwordEncoder) { + this.userJpaRepository = userJpaRepository; + this.passwordEncoder = passwordEncoder; + } + + @Override + public UserResponse create(UserCreateRequest request) { + var entity = new UserEntity(); + entity.setUsername(request.username()); + entity.setEmail(request.email()); + entity.setPasswordHash(passwordEncoder.encode(request.password())); + entity = userJpaRepository.save(entity); + return toResponse(entity); + } + + @Override + @Transactional(readOnly = true) + public UserResponse getById(Long id) { + return userJpaRepository.findById(id) + .map(UserServiceImpl::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found".formatted(id))); + } + + @Override + public UserResponse update(Long id, UserUpdateRequest request) { + UserEntity entity = userJpaRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found".formatted(id))); + + entity.setUsername(request.username()); + entity.setEmail(request.email()); + if (request.password() != null && !request.password().isBlank()) { + entity.setPasswordHash(passwordEncoder.encode(request.password())); + } + + entity = userJpaRepository.save(entity); + return toResponse(entity); + } + + @Override + public void deleteById(Long id) { + if (!userJpaRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found".formatted(id)); + } + userJpaRepository.deleteById(id); + } + + private static UserResponse toResponse(UserEntity entity) { + return new UserResponse( + entity.getId(), + entity.getUsername(), + entity.getEmail(), + entity.getRole().name(), + entity.getCreatedAt(), + entity.getUpdatedAt() + ); + } +} + diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/MatchMongoService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/MatchMongoService.java new file mode 100644 index 000000000..0979c216c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/MatchMongoService.java @@ -0,0 +1,11 @@ +package com.example.arimaabackend.services.mongo; + +import com.example.arimaabackend.dto.MatchResponse; +import java.util.Optional; + +public interface MatchMongoService { + Optional getMatch(Integer id); + MatchResponse createMatch(String matchData); + void deleteMatch(Integer id); + MatchResponse updateMatch(Integer id, String matchData); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/MatchMongoServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/MatchMongoServiceImpl.java new file mode 100644 index 000000000..4ac4a8736 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/MatchMongoServiceImpl.java @@ -0,0 +1,192 @@ +package com.example.arimaabackend.services.mongo; + +import com.example.arimaabackend.dto.*; +import com.example.arimaabackend.model.mongo.MatchDocument; +import com.example.arimaabackend.model.mongo.PlayerDocument; +import com.example.arimaabackend.model.mongo.UserDocument; +import com.example.arimaabackend.repository.mongo.MatchMongoRepository; +import com.example.arimaabackend.repository.mongo.PlayerMongoRepository; +import com.example.arimaabackend.repository.mongo.UserMongoRepository; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +public class MatchMongoServiceImpl implements MatchMongoService { + + private final MatchMongoRepository matchMongoRepository; + private final PlayerMongoRepository playerMongoRepository; + private final UserMongoRepository userMongoRepository; + + public MatchMongoServiceImpl( + MatchMongoRepository matchMongoRepository, + PlayerMongoRepository playerMongoRepository, + UserMongoRepository userMongoRepository) { + this.matchMongoRepository = matchMongoRepository; + this.playerMongoRepository = playerMongoRepository; + this.userMongoRepository = userMongoRepository; + } + + @Override + public Optional getMatch(Integer id) { + return matchMongoRepository.findById(id).map(this::toMatchResponse); + } + + @Override + public MatchResponse createMatch(String matchData) { + String[] parts = splitAndValidateMatchData(matchData); + Integer id = Integer.parseInt(parts[0]); + + MatchDocument doc = new MatchDocument(); + doc.setId(id); + populateMatchFromParts(doc, parts); + + return toMatchResponse(matchMongoRepository.save(doc)); + } + + @Override + public MatchResponse updateMatch(Integer id, String matchData) { + MatchDocument doc = matchMongoRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Match %d not found in Mongo".formatted(id))); + + String[] parts = splitAndValidateMatchData(matchData); + populateMatchFromParts(doc, parts); + + return toMatchResponse(matchMongoRepository.save(doc)); + } + + @Override + public void deleteMatch(Integer id) { + if (!matchMongoRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Match %d not found in Mongo".formatted(id)); + } + matchMongoRepository.deleteById(id); + } + + private String[] splitAndValidateMatchData(String matchData) { + String[] parts = matchData.split("\t"); + if (parts.length < 23) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid match data format: expected 23+ parts, got " + parts.length); + } + return parts; + } + + private void populateMatchFromParts(MatchDocument doc, String[] parts) { + Integer wPlayerId = Integer.parseInt(parts[1]); + Integer bPlayerId = Integer.parseInt(parts[2]); + String wUsername = parts[3]; + String bUsername = parts[4]; + String wCountryName = parts[7]; + String bCountryName = parts[8]; + Integer wRating = Integer.parseInt(parts[9]); + Integer bRating = Integer.parseInt(parts[10]); + String eventName = parts[15]; + String timeControl = parts[17]; + long startTs = Long.parseLong(parts[19]); + String result = parts[21]; + String termination = parts[22]; + + getOrCreatePlayer(wPlayerId, wUsername, wCountryName, wRating); + getOrCreatePlayer(bPlayerId, bUsername, bCountryName, bRating); + + doc.setGoldRating(wRating); + doc.setSilverRating(bRating); + doc.setTimestamp(Instant.ofEpochSecond(startTs)); + doc.setMatchResult(result); + doc.setTerminationType(termination); + + List playerRefs = new ArrayList<>(); + MatchDocument.PlayerRef goldRef = new MatchDocument.PlayerRef(); + goldRef.setPlayerId(wPlayerId); + goldRef.setColor("gold"); + playerRefs.add(goldRef); + + MatchDocument.PlayerRef silverRef = new MatchDocument.PlayerRef(); + silverRef.setPlayerId(bPlayerId); + silverRef.setColor("silver"); + playerRefs.add(silverRef); + + doc.setPlayers(playerRefs); + + MatchDocument.Event event = new MatchDocument.Event(); + event.setName(eventName); + event.setIsRated(true); + doc.setEvent(event); + + MatchDocument.GameType gt = new MatchDocument.GameType(); + gt.setName(timeControl); + doc.setGameType(gt); + } + + private void getOrCreatePlayer(Integer id, String username, String countryName, Integer rating) { + Optional existing = playerMongoRepository.findById(id); + if (existing.isPresent()) { + return; + } + + UserDocument user = userMongoRepository.findByUsername(username).orElseGet(() -> { + UserDocument newUser = new UserDocument(); + newUser.setUsername(username); + newUser.setEmail(username + "@example.com"); + newUser.setPasswordHash("PLACEHOLDER"); + return userMongoRepository.save(newUser); + }); + + PlayerDocument player = new PlayerDocument(); + player.setId(id); + player.setUser(user); + player.setCountry(countryName); + player.setRating(rating); + player.setGamesPlayed(0); + player.setRu(0); + playerMongoRepository.save(player); + } + + private MatchResponse toMatchResponse(MatchDocument doc) { + PlayerSummary silver = null; + PlayerSummary gold = null; + + if (doc.getPlayers() != null) { + for (MatchDocument.PlayerRef ref : doc.getPlayers()) { + PlayerSummary summary = getPlayerSummary(ref.getPlayerId()); + if ("silver".equalsIgnoreCase(ref.getColor())) { + silver = summary; + } else if ("gold".equalsIgnoreCase(ref.getColor())) { + gold = summary; + } + } + } + + EventSummary event = doc.getEvent() != null ? + new EventSummary(doc.getEvent().getId(), doc.getEvent().getName()) : null; + + GameTypeSummary gameType = doc.getGameType() != null ? + new GameTypeSummary(doc.getGameType().getId(), doc.getGameType().getName(), + doc.getGameType().getTimeIncrement(), doc.getGameType().getTimeReserve()) : null; + + return new MatchResponse( + doc.getId(), + doc.getTerminationType(), + silver, + gold, + doc.getGoldRating(), + doc.getSilverRating(), + doc.getMatchResult(), + event, + gameType, + doc.getTimestamp() + ); + } + + private PlayerSummary getPlayerSummary(Integer playerId) { + if (playerId == null) return null; + return playerMongoRepository.findById(playerId) + .map(p -> new PlayerSummary(p.getId(), p.getUser() != null ? p.getUser().getUsername() : "Unknown")) + .orElse(new PlayerSummary(playerId, "Unknown")); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/PlayerMongoService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/PlayerMongoService.java new file mode 100644 index 000000000..b4d84743a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/PlayerMongoService.java @@ -0,0 +1,17 @@ +package com.example.arimaabackend.services.mongo; + +import java.util.List; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.dto.PlayerUpdateRequest; + +public interface PlayerMongoService { + PlayerResponse create(PlayerCreateRequest request); + PlayerResponse update(Integer id, PlayerUpdateRequest request); + PlayerResponse getByUsername(String username); + PlayerResponse getById(Integer id); + List getAll(); + List getByCountryName(String countryName); + void deleteById(Integer id); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/PlayerMongoServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/PlayerMongoServiceImpl.java new file mode 100644 index 000000000..125c776be --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/PlayerMongoServiceImpl.java @@ -0,0 +1,150 @@ +package com.example.arimaabackend.services.mongo; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.dto.PlayerUpdateRequest; +import com.example.arimaabackend.model.mongo.PlayerDocument; +import com.example.arimaabackend.model.mongo.UserDocument; +import com.example.arimaabackend.repository.mongo.MatchMongoRepository; +import com.example.arimaabackend.repository.mongo.PlayerMongoRepository; +import com.example.arimaabackend.repository.mongo.UserMongoRepository; +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class PlayerMongoServiceImpl implements PlayerMongoService { + + private final PlayerMongoRepository playerMongoRepository; + private final UserMongoRepository userMongoRepository; + private final MatchMongoRepository matchMongoRepository; + private final PasswordEncoder passwordEncoder; + + public PlayerMongoServiceImpl(PlayerMongoRepository playerMongoRepository, + UserMongoRepository userMongoRepository, + MatchMongoRepository matchMongoRepository, + PasswordEncoder passwordEncoder) { + this.playerMongoRepository = playerMongoRepository; + this.userMongoRepository = userMongoRepository; + this.matchMongoRepository = matchMongoRepository; + this.passwordEncoder = passwordEncoder; + } + + @Override + public PlayerResponse create(PlayerCreateRequest request) { + UserDocument user = userMongoRepository.findById(request.userId()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found in Mongo".formatted(request.userId()))); + + if (playerMongoRepository.findById(user.getId().intValue()).isPresent()) { + throw new ResponseStatusException(HttpStatus.CONFLICT, "Player for user %d already exists in Mongo".formatted(user.getId())); + } + + PlayerDocument doc = new PlayerDocument(); + doc.setId(user.getId().intValue()); + doc.setUser(user); + doc.setRating(request.rating() != null ? request.rating() : 1200); + doc.setRu(request.ru() != null ? request.ru() : 0); + doc.setGamesPlayed(request.gamesPlayed() != null ? request.gamesPlayed() : 0); + // Map country name to country field in Mongo if available, or use countryId + doc.setCountry(request.country() != null ? request.country() : (request.countryId() != null ? request.countryId().toString() : null)); + + doc = playerMongoRepository.save(doc); + return toResponse(doc); + } + + @Override + public PlayerResponse update(Integer id, PlayerUpdateRequest request) { + PlayerDocument doc = playerMongoRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Player %d not found in Mongo".formatted(id))); + + doc.setRating(request.rating()); + doc.setRu(request.ru()); + doc.setGamesPlayed(request.gamesPlayed()); + doc.setCountry(request.countryId() != null ? request.countryId().toString() : null); + + if (request.userUpdate() != null) { + UserDocument user = doc.getUser(); + if (user != null) { + user.setUsername(request.userUpdate().username()); + user.setEmail(request.userUpdate().email()); + if (request.userUpdate().password() != null && !request.userUpdate().password().isBlank()) { + user.setPasswordHash(passwordEncoder.encode(request.userUpdate().password())); + } + user.setUpdatedAt(Instant.now()); + userMongoRepository.save(user); + } + } + + doc = playerMongoRepository.save(doc); + return toResponse(doc); + } + + @Override + public PlayerResponse getByUsername(String username) { + return playerMongoRepository.findByUser_Username(username) + .map(this::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Player with username '%s' not found in Mongo".formatted(username))); + } + + @Override + public PlayerResponse getById(Integer id) { + return playerMongoRepository.findById(id) + .map(this::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Player %d not found in Mongo".formatted(id))); + } + + @Override + public List getAll() { + return playerMongoRepository.findAll().stream() + .map(this::toResponse) + .collect(Collectors.toList()); + } + + @Override + public List getByCountryName(String countryName) { + return playerMongoRepository.findByCountry(countryName).stream() + .map(this::toResponse) + .collect(Collectors.toList()); + } + + @Override + public void deleteById(Integer id) { + if (!playerMongoRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Player %d not found in Mongo".formatted(id)); + } + + boolean hasMatches = !matchMongoRepository.findByPlayerId(id).isEmpty(); + + if (hasMatches) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Cannot delete player with matches in Mongo"); + } + + playerMongoRepository.deleteById(id); + } + + private PlayerResponse toResponse(PlayerDocument doc) { + UserDocument user = doc.getUser(); + Integer countryId = null; + try { + if (doc.getCountry() != null) { + countryId = Integer.parseInt(doc.getCountry()); + } + } catch (NumberFormatException ignored) {} + + return new PlayerResponse( + doc.getId(), + user != null ? user.getUsername() : null, + user != null ? user.getEmail() : null, + doc.getRating(), + doc.getRu(), + doc.getGamesPlayed(), + user != null ? user.getCreatedAt() : null, + countryId + ); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/SequenceGeneratorService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/SequenceGeneratorService.java new file mode 100644 index 000000000..d16da4f6d --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/SequenceGeneratorService.java @@ -0,0 +1,30 @@ +package com.example.arimaabackend.services.mongo; + +import com.example.arimaabackend.model.mongo.DatabaseSequence; +import org.springframework.data.mongodb.core.FindAndModifyOptions; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +@Service +public class SequenceGeneratorService { + + private final MongoOperations mongoOperations; + + public SequenceGeneratorService(MongoOperations mongoOperations) { + this.mongoOperations = mongoOperations; + } + + public long generateSequence(String seqName) { + DatabaseSequence counter = mongoOperations.findAndModify( + Query.query(Criteria.where("_id").is(seqName)), + new Update().inc("seq", 1), + FindAndModifyOptions.options().returnNew(true).upsert(true), + DatabaseSequence.class); + return !Objects.isNull(counter) ? counter.getSeq() : 1; + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/UserMongoService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/UserMongoService.java new file mode 100644 index 000000000..6c1e79a12 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/UserMongoService.java @@ -0,0 +1,13 @@ +package com.example.arimaabackend.services.mongo; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; + +public interface UserMongoService { + UserResponse create(UserCreateRequest request); + UserResponse getById(Long id); + UserResponse update(Long id, UserUpdateRequest request); + UserResponse getByUsername(String username); + void deleteById(Long id); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/UserMongoServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/UserMongoServiceImpl.java new file mode 100644 index 000000000..7fd4ea84c --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/mongo/UserMongoServiceImpl.java @@ -0,0 +1,91 @@ +package com.example.arimaabackend.services.mongo; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.example.arimaabackend.model.mongo.UserDocument; +import com.example.arimaabackend.repository.mongo.UserMongoRepository; +import org.springframework.http.HttpStatus; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.time.Instant; + +@Service +public class UserMongoServiceImpl implements UserMongoService { + + private final UserMongoRepository userMongoRepository; + private final PasswordEncoder passwordEncoder; + private final SequenceGeneratorService sequenceGeneratorService; + + public UserMongoServiceImpl(UserMongoRepository userMongoRepository, PasswordEncoder passwordEncoder, SequenceGeneratorService sequenceGeneratorService) { + this.userMongoRepository = userMongoRepository; + this.passwordEncoder = passwordEncoder; + this.sequenceGeneratorService = sequenceGeneratorService; + } + + @Override + public UserResponse create(UserCreateRequest request) { + UserDocument doc = new UserDocument(); + doc.setId(sequenceGeneratorService.generateSequence(UserDocument.SEQUENCE_NAME)); + doc.setUsername(request.username()); + doc.setEmail(request.email()); + doc.setPasswordHash(passwordEncoder.encode(request.password())); + doc.setRole("USER"); // Default role + doc.setCreatedAt(Instant.now()); + doc.setUpdatedAt(Instant.now()); + + doc = userMongoRepository.save(doc); + return toResponse(doc); + } + + @Override + public UserResponse getById(Long id) { + return userMongoRepository.findById(id) + .map(this::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found in Mongo".formatted(id))); + } + + @Override + public UserResponse update(Long id, UserUpdateRequest request) { + UserDocument doc = userMongoRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found in Mongo".formatted(id))); + + doc.setUsername(request.username()); + doc.setEmail(request.email()); + if (request.password() != null && !request.password().isBlank()) { + doc.setPasswordHash(passwordEncoder.encode(request.password())); + } + doc.setUpdatedAt(Instant.now()); + + doc = userMongoRepository.save(doc); + return toResponse(doc); + } + + @Override + public UserResponse getByUsername(String username) { + return userMongoRepository.findByUsername(username) + .map(this::toResponse) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User %s not found in Mongo".formatted(username))); + } + + @Override + public void deleteById(Long id) { + if (!userMongoRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User %d not found in Mongo".formatted(id)); + } + userMongoRepository.deleteById(id); + } + + private UserResponse toResponse(UserDocument doc) { + return new UserResponse( + doc.getId(), + doc.getUsername(), + doc.getEmail(), + doc.getRole(), + doc.getCreatedAt(), + doc.getUpdatedAt() + ); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/MatchNeo4jService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/MatchNeo4jService.java new file mode 100644 index 000000000..39d79d065 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/MatchNeo4jService.java @@ -0,0 +1,9 @@ +package com.example.arimaabackend.services.neo4j; + +import java.util.Optional; + +import com.example.arimaabackend.dto.MatchResponse; + +public interface MatchNeo4jService { + Optional getMatch(Integer id); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/MatchNeo4jServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/MatchNeo4jServiceImpl.java new file mode 100644 index 000000000..4aa91647f --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/MatchNeo4jServiceImpl.java @@ -0,0 +1,86 @@ +package com.example.arimaabackend.services.neo4j; + +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import com.example.arimaabackend.dto.EventSummary; +import com.example.arimaabackend.dto.GameTypeSummary; +import com.example.arimaabackend.dto.MatchResponse; +import com.example.arimaabackend.dto.PlayerSummary; +import com.example.arimaabackend.model.neo4j.EventNode; +import com.example.arimaabackend.model.neo4j.GameTypeNode; +import com.example.arimaabackend.model.neo4j.MatchNode; +import com.example.arimaabackend.model.neo4j.MatchPlayerRelationship; +import com.example.arimaabackend.model.neo4j.PlayerNode; +import com.example.arimaabackend.model.neo4j.UserNode; +import com.example.arimaabackend.repository.neo4j.MatchNeo4jRepository; + +@Service +public class MatchNeo4jServiceImpl implements MatchNeo4jService { + + private final MatchNeo4jRepository matchNeo4jRepository; + + public MatchNeo4jServiceImpl(MatchNeo4jRepository matchNeo4jRepository) { + this.matchNeo4jRepository = matchNeo4jRepository; + } + + @Override + public Optional getMatch(Integer id) { + return matchNeo4jRepository.findById(id).map(this::toMatchResponse); + } + + private MatchResponse toMatchResponse(MatchNode node) { + PlayerSummary silver = null; + PlayerSummary gold = null; + + if (node.getPlayers() != null) { + for (MatchPlayerRelationship rel : node.getPlayers()) { + PlayerSummary summary = toPlayerSummary(rel.getPlayer()); + if (rel.getSide() == MatchPlayerRelationship.Side.SILVER) { + silver = summary; + } else if (rel.getSide() == MatchPlayerRelationship.Side.GOLD) { + gold = summary; + } + } + } + + EventNode event = node.getEvent(); + EventSummary eventSummary = event != null + ? new EventSummary(event.getId(), event.getName()) + : null; + + GameTypeNode gameType = node.getGameType(); + GameTypeSummary gameTypeSummary = gameType != null + ? new GameTypeSummary( + gameType.getId(), + gameType.getName(), + gameType.getTimeIncrement(), + gameType.getTimeReserve()) + : null; + + return new MatchResponse( + node.getId(), + node.getTerminationType(), + silver, + gold, + node.getGoldRating(), + node.getSilverRating(), + node.getMatchResult(), + eventSummary, + gameTypeSummary, + node.getTimestamp() + ); + } + + private PlayerSummary toPlayerSummary(PlayerNode player) { + if (player == null) { + return null; + } + UserNode user = player.getUser(); + return new PlayerSummary( + player.getId(), + user != null ? user.getUsername() : "Unknown" + ); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/PlayerNeo4jService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/PlayerNeo4jService.java new file mode 100644 index 000000000..4526ae1ae --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/PlayerNeo4jService.java @@ -0,0 +1,10 @@ +package com.example.arimaabackend.services.neo4j; + +import java.util.List; + +import com.example.arimaabackend.dto.PlayerResponse; + +public interface PlayerNeo4jService { + PlayerResponse getByUsername(String username); + List getByCountryName(String countryName); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/PlayerNeo4jServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/PlayerNeo4jServiceImpl.java new file mode 100644 index 000000000..28ba6d08f --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/PlayerNeo4jServiceImpl.java @@ -0,0 +1,54 @@ +package com.example.arimaabackend.services.neo4j; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.model.neo4j.CountryNode; +import com.example.arimaabackend.model.neo4j.PlayerNode; +import com.example.arimaabackend.model.neo4j.UserNode; +import com.example.arimaabackend.repository.neo4j.PlayerNeo4jRepository; + +@Service +public class PlayerNeo4jServiceImpl implements PlayerNeo4jService { + + private final PlayerNeo4jRepository playerNeo4jRepository; + + public PlayerNeo4jServiceImpl(PlayerNeo4jRepository playerNeo4jRepository) { + this.playerNeo4jRepository = playerNeo4jRepository; + } + + @Override + public PlayerResponse getByUsername(String username) { + return playerNeo4jRepository.findByUsername(username) + .map(this::toResponse) + .orElseThrow(() -> new ResponseStatusException( + HttpStatus.NOT_FOUND, + "Player with username '%s' not found in Neo4j".formatted(username))); + } + + @Override + public List getByCountryName(String countryName) { + return playerNeo4jRepository.findByCountryName(countryName).stream() + .map(this::toResponse) + .toList(); + } + + private PlayerResponse toResponse(PlayerNode node) { + UserNode user = node.getUser(); + CountryNode country = node.getCountry(); + return new PlayerResponse( + node.getId(), + user != null ? user.getUsername() : null, + user != null ? user.getEmail() : null, + node.getRating(), + node.getRu(), + node.getGamesPlayed(), + null, + country != null ? country.getId() : null + ); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/UserNeo4jService.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/UserNeo4jService.java new file mode 100644 index 000000000..6000ca439 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/UserNeo4jService.java @@ -0,0 +1,12 @@ +package com.example.arimaabackend.services.neo4j; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; + +public interface UserNeo4jService { + UserResponse create(UserCreateRequest request); + UserResponse getById(Long id); + UserResponse update(Long id, UserUpdateRequest request); + void deleteById(Long id); +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/UserNeo4jServiceImpl.java b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/UserNeo4jServiceImpl.java new file mode 100644 index 000000000..b739ff16d --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/java/com/example/arimaabackend/services/neo4j/UserNeo4jServiceImpl.java @@ -0,0 +1,81 @@ +package com.example.arimaabackend.services.neo4j; +import com.example.arimaabackend.enums.UserRole; +import java.time.Instant; +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.example.arimaabackend.model.neo4j.UserNode; +import com.example.arimaabackend.repository.neo4j.UserNeo4jRepository; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +@Service +public class UserNeo4jServiceImpl implements UserNeo4jService { + + private final UserNeo4jRepository userNeo4jRepository; + + public UserNeo4jServiceImpl(UserNeo4jRepository userNeo4jRepository) { + this.userNeo4jRepository = userNeo4jRepository; + } + + @Override + public UserResponse create(UserCreateRequest request) { + UserNode node = new UserNode(); + // Since we removed @GeneratedValue, we need a way to generate IDs for new users. + // For simplicity, we'll use a timestamp-based ID or similar if no ID is provided. + // But better is to find the max ID and increment, or use a UUID. + // For now, let's use current time millis to avoid collisions in this simple implementation. + node.setId(System.currentTimeMillis()); + node.setUsername(request.username()); + node.setEmail(request.email()); + node.setRole(UserRole.USER); + Instant now = Instant.now(); + node.setCreatedAt(now); + node.setUpdatedAt(now); + + UserNode saved = userNeo4jRepository.save(node); + return toResponse(saved); + } + + @Override + public UserResponse getById(Long id) { + return userNeo4jRepository.findById(id) + .map(this::toResponse) + .orElseThrow(() -> new ResponseStatusException( + HttpStatus.NOT_FOUND, "User not found with id: " + id)); + } + + @Override + public UserResponse update(Long id, UserUpdateRequest request) { + UserNode node = userNeo4jRepository.findById(id) + .orElseThrow(() -> new ResponseStatusException( + HttpStatus.NOT_FOUND, "User not found with id: " + id)); + + node.setUsername(request.username()); + node.setEmail(request.email()); + node.setUpdatedAt(Instant.now()); + + UserNode updated = userNeo4jRepository.save(node); + return toResponse(updated); + } + + @Override + public void deleteById(Long id) { + if (!userNeo4jRepository.existsById(id)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found with id: " + id); + } + userNeo4jRepository.deleteById(id); + } + + private UserResponse toResponse(UserNode node) { + return new UserResponse( + node.getId(), + node.getUsername(), + node.getEmail(), + node.getRole() != null ? node.getRole().name() : null, + node.getCreatedAt(), + node.getUpdatedAt() + ); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/resources/application-migration.properties b/jdk_21_maven/cs/rest/arimaa/src/main/resources/application-migration.properties new file mode 100644 index 000000000..0030f98b0 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/resources/application-migration.properties @@ -0,0 +1,28 @@ +# Activated with: spring.profiles.active=migration +# Requires MySQL (JPA) and Neo4j per application.properties / local overrides. + +# Re-enable MongoDB and Neo4j (disabled in application.properties for normal API mode). +spring.autoconfigure.exclude= + +# Do not start the repo root compose.yaml (mydatabase on a random port). Use MySQL from +# Database/docker-compose.mysql.yml (e.g. localhost:3307 / arimaadockermysqldb), started separately. +spring.docker.compose.enabled=false + +# Leave unset (or empty) to run all steps. To run a subset, use indexed properties, e.g.: +migration.enabled-targets[0]=neo4j +migration.enabled-targets[1]=mongodb +# +# migration.enabled-steps[0]=country +# migration.enabled-steps[1]=match +# +# Targets (use with migration.enabled-targets; case-insensitive): +# neo4j, mongodb (or mongo) +# +# Step ids (use with migration.enabled-steps; case-insensitive): +# country, event, game-type, position, puzzle, player, match, move, solution, +# opening-by-match, opening-by-puzzle, user, user-mongo +# +# Order is fixed by each migration's Ordered#getOrder(); enabled-steps only filters which steps run. + +migration.batch-size=500 +migration.dry-run=false diff --git a/jdk_21_maven/cs/rest/arimaa/src/main/resources/application.properties b/jdk_21_maven/cs/rest/arimaa/src/main/resources/application.properties new file mode 100644 index 000000000..62ff350e0 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/main/resources/application.properties @@ -0,0 +1,29 @@ +spring.application.name=arimaa-backend + +# Tell Spring Boot where the Docker Compose file is (so it doesn't look for ./compose.yaml) +#spring.docker.compose.file=Database/docker-compose.mysql.yml +#spring.docker.compose.env-file=.env +spring.config.import=optional:file:.env[.properties] +spring.docker.compose.enabled=false + +# --- SQL (MySQL) source via Hibernate/JPA --- +spring.datasource.url=${SPRING_DATASOURCE_URL} +spring.datasource.username=${SPRING_DATASOURCE_USERNAME} +spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} +spring.jpa.hibernate.ddl-auto=update +# Use annotated table/column names as-is; default Spring lowercasing breaks MySQL (Docker/Linux) with PascalCase tables like `Countries`. +spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl +spring.jpa.open-in-view=false + +# --- MongoDB target --- +spring.mongodb.uri=${SPRING_MONGODB_URI} + +# --- Neo4j target --- +spring.neo4j.uri=${SPRING_NEO4J_URI} +spring.neo4j.authentication.username=${SPRING_NEO4J_USERNAME} +spring.neo4j.authentication.password=${SPRING_NEO4J_PASSWORD} + +# Run the one-time migrator explicitly: +# spring.profiles.active=migration + +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/MatchMongoTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/MatchMongoTest.java new file mode 100644 index 000000000..2c81fc740 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/MatchMongoTest.java @@ -0,0 +1,233 @@ +package com.example.arimaabackend.playwright.mongo; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.playwright.APIRequest; +import com.microsoft.playwright.APIRequestContext; +import com.microsoft.playwright.APIResponse; +import com.microsoft.playwright.Playwright; +import com.microsoft.playwright.options.RequestOptions; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; + +import java.util.Base64; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class MatchMongoTest { + + private Playwright playwright; + private Dotenv dotenv; + private ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + private static final String MATCH_ID = "27557"; + private static final String GOLD_ID = "4803"; + private static final String GOLD_USERNAME = "Matthias"; + private static final String SILVER_ID = "4613"; + private static final String SILVER_USERNAME = "bot_GnoBot2006P1"; + + private static final String MATCH_DATA = + MATCH_ID + "\t" + GOLD_ID + "\t" + SILVER_ID + "\t"+ GOLD_USERNAME +"\t"+ SILVER_USERNAME + + "\t\t\tUS\tAU\t1258\t1238\t98\t30\th\tb\tCasual game\tOver the Net" + + "\t2/2/100/10/8\t0\t1143867610\t1143867977\tb\tr\t11\tIGS\t1\t0\t" + + "1w Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Ch1 Ha2 Mb2 Dc2 Dd2 Ee2 Cf2 Hg2 Rh2\\n" + + "1b ra8 rb8 rc8 dd8 de8 rf8 rg8 rh8 hb7 ra7 cc7 ed7 me7 cf7 rh7 hg7\\n" + + "2w Ee2n Ee3n Ee4n Ee5n\\n2b ed7s me7w de8s dd8e\\n3w Ee6s de7s Ee5s de6s\\n" + + "3b ed6s de8s de5n ed5s\\n4w Ee4s Ee3w Rh2n Rh3w\\n4b hg7s rh7w hb7s ra7e\\n" + + "5w Rg3w Rf3w Ch1n Ch2n\\n5b ed4e md7s ee4w Re3n\\n6w Hg2n Hg3w Hf3n Ch3w\\n" + + "6b Re4n ed4e rf8w re8w\\n7w Cg3n Cg4n Mb2n Mb3n\t7b Hf4n ee4e Hf5n Hf6x ef4n\\n" + + "8w Ed3n Ed4n Ed5s md6s\\n8b ef5s Cg5w Cf5n Cf6x ef4n\\n9w Ed4w md5s md4s Ec4e\\n" + + "9b de6w Re5n Re6e Rf6x de7s\\n10w md3w mc3x Ed4s Ha2e Hb2n\\n10b ef5w ee5s ee4w ed4w\\n" + + "11w\tevents"; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + @Disabled("Skipped, hard to fix") + @Test + void AsAdmin_UpdateMatch() throws JsonProcessingException { + + // Create Match + APIResponse createResponse = adminRequest.post("/api/mongo/matches", RequestOptions.create().setData(MATCH_DATA)); + assertEquals(201, createResponse.status(), "Failed to create match. Body: " + createResponse.text()); + + // Update Match + // Modify the result in MATCH_DATA from "b" to "w" (Gold wins) + // Correcting the replace to use single tabs as it is built in MATCH_DATA + String updatedData = MATCH_DATA.replace("\tb\tr\t", "\tw\tr\t"); + + APIResponse updateResponse = adminRequest.put("/api/mongo/matches/" + MATCH_ID, RequestOptions.create().setData(updatedData)); + assertEquals(200, updateResponse.status(), "Failed to update match. Body: " + updateResponse.text()); + + JsonNode matchJson = objectMapper.readTree(updateResponse.text()); + assertEquals("w", matchJson.get("matchResult").asText()); + + try { + // Make sure you can get the match with the new value: + APIResponse getResponse = adminRequest.get("/api/mongo/matches/" + MATCH_ID); + Integer getResponseStatus = getResponse.status(); + String getResponseText = getResponse.text(); + assertEquals(200, getResponseStatus, "Failed to get match. Body: " + getResponseText); + JsonNode getJson = objectMapper.readTree(getResponseText); + assertEquals("w", getJson.get("matchResult").asText()); + + // Delete the Match + APIResponse deleteResponse = adminRequest.delete("/api/mongo/matches/" + MATCH_ID); + assertEquals(204, deleteResponse.status(), "Failed to delete match. Status: " + deleteResponse.status()); + + // Verify Match is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/mongo/matches/" + MATCH_ID); + assertEquals(404, getAfterDeleteResponse.status()); + } finally { + // Cleanup just in case + adminRequest.delete("/api/mongo/matches/" + MATCH_ID); + } + } + + @Disabled("Skipped, hard to fix") + @Test + void AsUser_UpdateMatch() throws JsonProcessingException { + // Create Match (as an admin, to have a match to update) + APIResponse createResponse = adminRequest.post("/api/mongo/matches", RequestOptions.create().setData(MATCH_DATA)); + assertEquals(201, createResponse.status(), "Failed to create match. Body: " + createResponse.text()); + + // Update Match + // Modify the result in MATCH_DATA from "b" to "w" (Gold wins) + String updatedData = MATCH_DATA.replace("\tb\tr\t", "\tw\tr\t"); + + APIResponse updateResponse = userRequest.put("/api/mongo/matches/" + MATCH_ID, RequestOptions.create().setData(updatedData)); + // The users attempt to update the match should fail with a 403 Forbidden + assertEquals(403, updateResponse.status(), "Failed to update match. Body: " + updateResponse.text()); + + // Delete the Match + APIResponse deleteResponse = adminRequest.delete("/api/mongo/matches/" + MATCH_ID); + assertEquals(204, deleteResponse.status(), "Failed to delete match. Status: " + deleteResponse.status()); + + // Verify Match is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/mongo/matches/" + MATCH_ID); + assertEquals(404, getAfterDeleteResponse.status()); + } + + @Disabled("Skipped, hard to fix") + @Test + void AsAdmin_CreateThenDeleteMatch() throws JsonProcessingException { + + // Create Match + APIResponse createResponse = adminRequest.post("/api/mongo/matches", RequestOptions.create().setData(MATCH_DATA)); + + Integer responseStatus = createResponse.status(); + String responseText = createResponse.text(); + assertEquals(201, (int)responseStatus, "Failed to create match. Body: " + responseText); + + JsonNode matchJson = objectMapper.readTree(createResponse.text()); + assertEquals(MATCH_ID, matchJson.get("id").asText()); + + try { + // Get the Match + APIResponse getResponse = adminRequest.get("/api/mongo/matches/" + MATCH_ID); + Integer getResponseStatus = getResponse.status(); + String getResponseText = getResponse.text(); + assertEquals(200, getResponseStatus, "Failed to get match. Body: " + getResponseText); + JsonNode getJson = objectMapper.readTree(getResponseText); + + // verify the match values + assertEquals(Integer.parseInt(MATCH_ID), getJson.get("id").asInt()); + assertEquals("r", getJson.get("terminationType").asText()); + assertEquals("bot_GnoBot2006P1", getJson.get("silverPlayer").get("username").asText()); + assertEquals(4803, getJson.get("goldPlayer").get("id").asInt()); + assertEquals("Matthias", getJson.get("goldPlayer").get("username").asText()); + assertEquals(1258, getJson.get("goldRating").asInt()); + assertEquals(1238, getJson.get("silverRating").asInt()); + assertEquals("b", getJson.get("matchResult").asText()); + assertEquals("Casual game", getJson.get("event").get("name").asText()); + assertEquals("2/2/100/10/8", getJson.get("gameType").get("name").asText()); + assertEquals("null", getJson.get("gameType").get("timeIncrement").asText()); + assertEquals("null", getJson.get("gameType").get("timeReserve").asText()); + assertEquals("2006-04-01T05:00:10Z", getJson.get("timestamp").asText()); + + // Delete the Match + APIResponse deleteResponse = adminRequest.delete("/api/mongo/matches/" + MATCH_ID); + assertEquals(204, deleteResponse.status(), "Failed to delete match. Status: " + deleteResponse.status()); + + // Verify Match is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/mongo/matches/" + MATCH_ID); + assertEquals(404, getAfterDeleteResponse.status()); + } finally { + // Cleanup just in case + adminRequest.delete("/api/mongo/matches/" + MATCH_ID); + } + } + + + @Test + void AsUser_FailToCreateMatch() { + String matchData = "999998\t1001\t1002\tplayer1\tplayer2\t\t\tUSA\tCanada\t1500\t1500\t\t\t\t\tTest Event\t\t2m+2s\t\t" + (System.currentTimeMillis()/1000) + "\t\t1-0\tnormal"; + APIResponse response = userRequest.post("/api/mongo/matches", RequestOptions.create().setData(matchData)); + assertEquals(403, response.status()); + } + + @Test + void AsUser_FailToDeleteMatch() { + APIResponse response = userRequest.delete("/api/mongo/matches/1"); + assertEquals(403, response.status()); + } + + @Test + void deleteById_SHouldFail() { + APIResponse response = adminRequest.delete("/api/mongo/matches/9999999"); + assertEquals(404, response.status()); + } + + @Test + void AsAdmin_FailToGetMissingMatch() { + APIResponse response = adminRequest.get("/api/mongo/matches/9999999"); + assertEquals(404, response.status()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/PlayerMongoTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/PlayerMongoTest.java new file mode 100644 index 000000000..ec362d346 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/PlayerMongoTest.java @@ -0,0 +1,268 @@ +package com.example.arimaabackend.playwright.mongo; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerUpdateRequest; +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.playwright.APIRequest; +import com.microsoft.playwright.APIRequestContext; +import com.microsoft.playwright.APIResponse; +import com.microsoft.playwright.Playwright; +import com.microsoft.playwright.options.RequestOptions; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; +import java.util.Base64; +import java.util.Map; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class PlayerMongoTest { + + private static final Integer BOT_SHALLOWBLUE_ID = 371; + + private Playwright playwright; + private Dotenv dotenv; + private ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + @Disabled("Skipped, hard to fix") + @Test + void ASAdmin_CreateThenDeletePlayer() throws JsonProcessingException { + // Create user first (add player later) + String testUsername = "player_mongo_test_" + System.currentTimeMillis(); + UserCreateRequest userRequestData = new UserCreateRequest( + testUsername, + testUsername + "@example.com", + "password123" + ); + APIResponse userCreateResponse = adminRequest.post("/api/mongo/users", RequestOptions.create().setData(userRequestData)); + assertEquals(201, userCreateResponse.status()); + JsonNode userJson = objectMapper.readTree(userCreateResponse.text()); + long userId = userJson.get("id").asLong(); + + try { + // Create a Player + // Match constructor arguments: userId, rating, ru, gamesPlayed, country (as name) + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(userId, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = adminRequest.post("/api/mongo/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(201, playerCreateResponse.status(), "Failed to create player: " + playerCreateResponse.text()); + + JsonNode playerJson = objectMapper.readTree(playerCreateResponse.text()); + int playerId = playerJson.get("id").asInt(); + assertEquals(testUsername, playerJson.get("username").asText()); + + // Get the Player + APIResponse getResponse = adminRequest.get("/api/mongo/players/" + playerId); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + assertEquals(playerId, getJson.get("id").asInt()); + + // Get the user + APIResponse getUserResponse = adminRequest.get("/api/mongo/users/" + userId); + assertEquals(200, getUserResponse.status()); + JsonNode getUserJson = objectMapper.readTree(getUserResponse.text()); + assertEquals(userId, getUserJson.get("id").asInt()); + + // Delete the Player + APIResponse deleteResponse = adminRequest.delete("/api/mongo/players/" + playerId); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(204, deleteResponse.status()); + + // Verify Player is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/mongo/players/" + playerId); + assertEquals(404, getAfterDeleteResponse.status()); + + //verify user is gone + APIResponse getAfterDeleteUserResponse = adminRequest.get("/api/mongo/users/" + userId); + assertEquals(404, getAfterDeleteUserResponse.status()); + + } finally { + // Cleanup: delete user (which might also cascade delete player if we didn't do it) + adminRequest.delete("/api/mongo/users/" + userId); + } + } + + @Test + void AsAdmin_FailToCreatePlayerWithoutUserObj() { + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(null, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = adminRequest.post("/api/mongo/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(400, playerCreateResponse.status(), "Expected status 400 but got: " + playerCreateResponse.text()); + } + + @Disabled("Skipped, hard to fix") + @Test + void AsUser_FailToCreatePlayerWithoutUser() { + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(null, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = userRequest.post("/api/mongo/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(400, playerCreateResponse.status(), "Expected status 400 but got: " + playerCreateResponse.text()); + } + + @Disabled("Skipped, hard to fix") + @Test + void AsAdmin_FailToDeletePlayerWithMatches() throws JsonProcessingException { + APIResponse getResponse = adminRequest.get("/api/mongo/players/by-username/bot_ShallowBlue"); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + int playerId = getJson.get("id").asInt(); + + APIResponse deleteResponse = adminRequest.delete("/api/mongo/players/" + playerId); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(400, deleteResponse.status()); + } + + @Disabled("Skipped, hard to fix") + @Test + void AsUser_FailToDeletePlayerWithMatches() throws JsonProcessingException { + APIResponse getResponse = adminRequest.get("/api/mongo/players/by-username/bot_ShallowBlue"); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + int playerId = getJson.get("id").asInt(); + + APIResponse deleteResponse = userRequest.delete("/api/mongo/players/" + playerId); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(403, deleteResponse.status()); + } + + @Test + void deleteById_returns404_whenNotFound() { + APIResponse response = adminRequest.delete("/api/mongo/players/999999"); + assertEquals(404, response.status()); + } + + @Disabled("Skipped, hard to fix") + @Test + void AsAdmin_UpdatePlayer() throws JsonProcessingException { + // Create user first (add player later) + String testUsername = "player_mongo_test_update_" + System.currentTimeMillis(); + UserCreateRequest userRequestData = new UserCreateRequest( + testUsername, + testUsername + "@example.com", + "password123" + ); + APIResponse userCreateResponse = adminRequest.post("/api/mongo/users", RequestOptions.create().setData(userRequestData)); + assertEquals(201, userCreateResponse.status()); + JsonNode userJson = objectMapper.readTree(userCreateResponse.text()); + long userId = userJson.get("id").asLong(); + + try { + // Create a Player + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(userId, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = adminRequest.post("/api/mongo/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(201, playerCreateResponse.status(), "Failed to create player: " + playerCreateResponse.text()); + + JsonNode playerJson = objectMapper.readTree(playerCreateResponse.text()); + int playerId = playerJson.get("id").asInt(); + assertEquals(testUsername, playerJson.get("username").asText()); + + // Get the Player + APIResponse getResponse = adminRequest.get("/api/mongo/players/" + playerId); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + assertEquals(playerId, getJson.get("id").asInt()); + + // Get the user + APIResponse getUserResponse = adminRequest.get("/api/mongo/users/" + userId); + assertEquals(200, getUserResponse.status()); + JsonNode getUserJson = objectMapper.readTree(getUserResponse.text()); + assertEquals(userId, getUserJson.get("id").asInt()); + + // Update player and their user information + UserUpdateRequest userUpdate = new UserUpdateRequest( + "updated_player", + "updated_player" + "@example.com", + "new_password123"); + PlayerUpdateRequest updateRequest = new PlayerUpdateRequest(1500, 10, 5, 2, userUpdate); // Update rating to 1500, country to 2 + + APIResponse updateResponse = adminRequest.put("/api/mongo/players/" + playerId, RequestOptions.create().setData(updateRequest)); + assertEquals(200, updateResponse.status()); + JsonNode updatedJson = objectMapper.readTree(updateResponse.text()); + + assertEquals(1500, updatedJson.get("rating").asInt()); + assertEquals(10, updatedJson.get("ru").asInt()); + assertEquals(5, updatedJson.get("gamesPlayed").asInt()); + assertEquals(2, updatedJson.get("countryId").asInt()); + assertEquals("updated_player", updatedJson.get("username").asText()); + assertEquals("updated_player" + "@example.com", updatedJson.get("email").asText()); + + // Verify user was updated too via GET /api/mongo/users/{id} + APIResponse updatedUserResponse = adminRequest.get("/api/mongo/users/" + userId); + assertEquals(200, updatedUserResponse.status()); + JsonNode updatedUserJson = objectMapper.readTree(updatedUserResponse.text()); + assertEquals("updated_player", updatedUserJson.get("username").asText()); + assertEquals("updated_player" + "@example.com", updatedUserJson.get("email").asText()); + + // Delete the Player + APIResponse deleteResponse = adminRequest.delete("/api/mongo/players/" + playerId); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(204, deleteResponse.status()); + + // Verify Player is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/mongo/players/" + playerId); + assertEquals(404, getAfterDeleteResponse.status()); + + //verify user is gone + APIResponse getAfterDeleteUserResponse = adminRequest.get("/api/mongo/users/" + userId); + assertEquals(404, getAfterDeleteUserResponse.status()); + + } finally { + // Cleanup: delete user (which might also cascade delete player if we didn't do it) + adminRequest.delete("/api/mongo/users/" + userId); + } + } + @Test + void AsUser_FailToUpdatePlayer() { + PlayerUpdateRequest updateRequest = new PlayerUpdateRequest(2000, 100, 50, 1, null); + APIResponse response = userRequest.put("/api/mongo/players/1", RequestOptions.create().setData(updateRequest)); + assertEquals(403, response.status()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/UserMongoTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/UserMongoTest.java new file mode 100644 index 000000000..fe39953df --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/mongo/UserMongoTest.java @@ -0,0 +1,248 @@ +package com.example.arimaabackend.playwright.mongo; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserResponse; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.microsoft.playwright.options.RequestOptions; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microsoft.playwright.*; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; +import java.time.Instant; +import java.util.Base64; +import java.util.Map; +import static org.junit.jupiter.api.Assertions.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class UserMongoTest { + + private Playwright playwright; + private Dotenv dotenv; + private final ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + @Test + void AsUser_FailToCreateUser() { + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + UserCreateRequest createUser = new UserCreateRequest( + "usernametest_mongo_" + uniqueSuffix, + "usernametest_mongo_" + uniqueSuffix + "@unknown.invalid", + "usernametest1_userCantCreateuser"); + APIResponse response = userRequest.post("/api/mongo/users", RequestOptions.create().setData(createUser)); + assertFalse(response.ok(), "Expected 4xx status. Got: " + response.status()); + assertEquals(403, response.status()); + } + + @Test + void AsUser_FailToDeleteUser() { + // First find user by username to get the ID + APIResponse responseByUsername = adminRequest.get("/api/mongo/users/by-username/bot_ShallowBlue"); + assertTrue(responseByUsername.ok()); + long targetId; + try { + targetId = objectMapper.readTree(responseByUsername.text()).get("id").asLong(); + } catch (Exception e) { + fail(e.getMessage()); + return; + } + + APIResponse getFirstUserResponse = adminRequest.get("/api/mongo/users/" + targetId); + assertTrue(getFirstUserResponse.ok(), "Expected 2xx status. Got: " + getFirstUserResponse.status()); + assertEquals(200, getFirstUserResponse.status()); + + APIResponse responseDelete = userRequest.delete("/api/mongo/users/" + targetId); + assertFalse(responseDelete.ok(), "Expected 4xx status. Got: " + responseDelete.status()); + assertEquals(403, responseDelete.status()); + } + + @Test + void AsAdmin_CreateThenDeleteUser() { + // Create user (to delete later) + String username = "AsAdmin_CreateThenDeleteUser"; + UserCreateRequest createUser = new UserCreateRequest( + username, + "usernametest_" + username + "@unknown.invalid", + "username_123_" + username); + APIResponse response = adminRequest.post("/api/mongo/users", RequestOptions.create().setData(createUser)); + assertTrue(response.ok(), "Expected 2xx status. Got: " + response.status()); + assertEquals(201, response.status()); + JsonNode json; + try { + json = objectMapper.readTree(response.text()); + } catch (JsonProcessingException e) { + fail("Invalid JSON response: " + e.getMessage()); + return; + } + Integer newUserId = json.path("id").asInt(); + String newUserName = json.path("username").asText(); + assertEquals(username, newUserName); + + // get user by newUserId + APIResponse getNewUserResponse = adminRequest.get("/api/mongo/users/" + newUserId); + assertTrue(getNewUserResponse.ok(), "Expected 2xx status. Got: " + getNewUserResponse.status()); + assertEquals(200, getNewUserResponse.status()); + + // delete the user + APIResponse responseDelete = adminRequest.delete("/api/mongo/users/" + newUserId); + assertTrue(responseDelete.ok(), "Expected 2xx status. Got: " + responseDelete.status()); + assertEquals(204, responseDelete.status()); + + // try to find the deleted user again + APIResponse responsegetdeleted = adminRequest.get("/api/mongo/users/" + newUserId); + assertEquals(404, responsegetdeleted.status(), + "Expected 404 Not Found after user deletion, but got: " + responsegetdeleted.status()); + } + + + @Test + void AsAdmin_GetUserById() { + Long userId = 1L; + + APIResponse response = adminRequest.get("/api/mongo/users/" + userId); + assertTrue(response.ok(), "Expected 2xx status. Got: " + response.status()); + assertEquals(200, response.status()); + String jsonString = response.text(); + + JsonNode json; + try { + json = objectMapper.readTree(jsonString); + } catch (JsonProcessingException e) { + fail("Invalid JSON response: " + e.getMessage()); + return; + } + assertEquals(userId, json.get("id").asLong()); + assertEquals("bot_ShallowBlue", json.get("username").asText()); + assertEquals("bot_ShallowBlue@unknown.invalid", json.get("email").asText()); + assertEquals("PLAYER", json.get("role").asText()); + + assertValidDate(json.get("createdAt").asText()); + assertValidDate(json.get("updatedAt").asText()); + } + + @Test + void AsAdmin_FailToGetMissingUserById() { + APIResponse response = adminRequest.get("/api/mongo/users/43543637"); + assertFalse(response.ok(), "Expected 4xx status. Got: " + response.status()); + assertEquals(404, response.status()); + } + + @Test + void AsAdmin_UpdateUser() throws JsonProcessingException { + // Create user (to update later) + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + UserCreateRequest createUser = new UserCreateRequest( + "update_me_" + uniqueSuffix, + "update_me_" + uniqueSuffix + "@example.com", + "password123"); + APIResponse createResponse = adminRequest.post("/api/mongo/users", RequestOptions.create().setData(createUser)); + assertEquals(201, createResponse.status()); + JsonNode json = objectMapper.readTree(createResponse.text()); + Integer userId = json.get("id").asInt(); + + // Update user + UserUpdateRequest updateRequest = new UserUpdateRequest( + "updated_" + uniqueSuffix, + "updated_" + uniqueSuffix + "@example.com", + "new_password123"); + + APIResponse updateResponse = adminRequest.put("/api/mongo/users/" + userId, RequestOptions.create().setData(updateRequest)); + assertEquals(200, updateResponse.status()); + JsonNode updatedJson = objectMapper.readTree(updateResponse.text()); + Integer newUserID = updatedJson.get("id").asInt(); + assertEquals("updated_" + uniqueSuffix, updatedJson.get("username").asText()); + assertEquals("updated_" + uniqueSuffix + "@example.com", updatedJson.get("email").asText()); + + // get user by newUserId + APIResponse getNewUserResponse = adminRequest.get("/api/mongo/users/" + newUserID); + assertTrue(getNewUserResponse.ok(), "Expected 2xx status. Got: " + getNewUserResponse.status()); + assertEquals(200, getNewUserResponse.status()); + + // delete the user + APIResponse responseDelete = adminRequest.delete("/api/mongo/users/" + newUserID); + assertTrue(responseDelete.ok(), "Expected 2xx status. Got: " + responseDelete.status()); + assertEquals(204, responseDelete.status()); + + // try to find the deleted user again + APIResponse responsegetdeleted = adminRequest.get("/api/mongo/users/" + newUserID); + assertEquals(404, responsegetdeleted.status(), + "Expected 404 Not Found after user deletion, but got: " + responsegetdeleted.status()); + } + + @Test + void AsUser_FailToUpdateUser() { + // Try to update username, email and password of user 1 + // Using bot_ShallowBlue ID instead of hardcoded 1 + APIResponse responseByUsername = adminRequest.get("/api/mongo/users/by-username/bot_ShallowBlue"); + assertTrue(responseByUsername.ok()); + long targetId; + try { + targetId = objectMapper.readTree(responseByUsername.text()).get("id").asLong(); + } catch (Exception e) { + fail(e.getMessage()); + return; + } + + UserUpdateRequest updateRequest = new UserUpdateRequest( + "hacker", + "hacker@example.com", + "hacked123"); + + APIResponse updateResponse = userRequest.put("/api/mongo/users/" + targetId, RequestOptions.create().setData(updateRequest)); + // The users attempt to update the user should fail with a 403 Forbidden + assertEquals(403, updateResponse.status()); + } + + private void assertValidDate(String dateString) { + assertDoesNotThrow(() -> Instant.parse(dateString), + "Expected a valid date (e.g. 2026-03-04T09:04:54Z), but got: " + dateString); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/neo4j/UserNeo4jTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/neo4j/UserNeo4jTest.java new file mode 100644 index 000000000..57205cb80 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/neo4j/UserNeo4jTest.java @@ -0,0 +1,227 @@ +package com.example.arimaabackend.playwright.neo4j; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.microsoft.playwright.options.RequestOptions; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microsoft.playwright.*; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; +import java.time.Instant; +import java.util.Base64; +import java.util.Map; +import static org.junit.jupiter.api.Assertions.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class UserNeo4jTest { + + private Playwright playwright; + private Dotenv dotenv; + private final ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + private static String API_USERS = "/api/neo4j/users"; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + + @Test + void AsUser_FailToCreateUser() { + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + UserCreateRequest createUser = new UserCreateRequest( + "usernametest_" + uniqueSuffix, + "usernametest_" + uniqueSuffix + "@unknown.invalid", + "usernametest1_userCantCreateuser"); + APIResponse response = userRequest.post(API_USERS, RequestOptions.create().setData(createUser)); + assertFalse(response.ok(), "Expected 4xx status. Got: " + response.status()); + assertEquals(403, response.status()); + } + + @Test + void AsUser_FailToDeleteUser() { + APIResponse getFirstUserResponse = adminRequest.get(API_USERS + "/1"); + assertTrue(getFirstUserResponse.ok(), "Expected 2xx status. Got: " + getFirstUserResponse.status()); + assertEquals(200, getFirstUserResponse.status()); + + APIResponse responseDelete = userRequest.delete(API_USERS + "/1"); + assertFalse(responseDelete.ok(), "Expected 4xx status. Got: " + responseDelete.status()); + assertEquals(403, responseDelete.status()); + } + + @Test + void AsAdmin_CreateThenDeleteUser() { + // Create user (to delete later) + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + String username = "DeleteMe_" + uniqueSuffix; + UserCreateRequest createUser = new UserCreateRequest( + username, + "delete_me_" + uniqueSuffix + "@unknown.invalid", + "password_123"); + APIResponse response = adminRequest.post(API_USERS, RequestOptions.create().setData(createUser)); + assertTrue(response.ok(), "Expected 2xx status. Got: " + response.status() + " Body: " + response.text()); + assertEquals(201, response.status()); + JsonNode json; + try { + json = objectMapper.readTree(response.text()); + } catch (JsonProcessingException e) { + fail("Invalid JSON response: " + e.getMessage()); + return; + } + Long newUserId = json.path("id").asLong(); + String newUserName = json.path("username").asText(); + assertEquals(username, newUserName); + + // get user by newUserId + APIResponse getNewUserResponse = adminRequest.get(API_USERS + "/" + newUserId); + assertTrue(getNewUserResponse.ok(), "Expected 2xx status. Got: " + getNewUserResponse.status() + " Body: " + getNewUserResponse.text()); + assertEquals(200, getNewUserResponse.status()); + + // delete the user + APIResponse responseDelete = adminRequest.delete(API_USERS + "/" + newUserId); + assertTrue(responseDelete.ok(), "Expected 2xx status. Got: " + responseDelete.status()); + assertEquals(204, responseDelete.status()); + + // try to find the deleted user again + APIResponse responseget18deleted = adminRequest.get(API_USERS + "/" + newUserId); + assertEquals(404, responseget18deleted.status(), + "Expected 404 Not Found after user deletion, but got: " + response.status()); + } + + + @Test + void AsAdmin_GetUserById() { + APIResponse response = adminRequest.get(API_USERS + "/1"); + assertTrue(response.ok(), "Expected 2xx status. Got: " + response.status()); + assertEquals(200, response.status()); + String jsonString = response.text(); + + JsonNode json; + try { + json = objectMapper.readTree(jsonString); + } catch (JsonProcessingException e) { + fail("Invalid JSON response: " + e.getMessage()); + return; + } + assertEquals(1, json.get("id").asInt()); + assertEquals("bot_ShallowBlue", json.get("username").asText()); + assertEquals("bot_ShallowBlue@unknown.invalid", json.get("email").asText()); + assertEquals("PLAYER", json.get("role").asText()); + + assertValidDate(json.get("createdAt").asText()); + assertValidDate(json.get("updatedAt").asText()); + } + + @Test + void AsAdmin_FailToGetMissingUserById() { + APIResponse response = adminRequest.get(API_USERS + "/43543637"); + assertFalse(response.ok(), "Expected 4xx status. Got: " + response.status()); + assertEquals(404, response.status()); + } + + @Test + void AsAdmin_UpdateUser() throws JsonProcessingException { + // Create user (to update later) + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + UserCreateRequest createUser = new UserCreateRequest( + "update_me_" + uniqueSuffix, + "update_me_" + uniqueSuffix + "@example.com", + "password123"); + APIResponse createResponse = adminRequest.post(API_USERS, RequestOptions.create().setData(createUser)); + assertEquals(201, createResponse.status()); + JsonNode json = objectMapper.readTree(createResponse.text()); + Long userId = json.get("id").asLong(); + + // Update user + UserUpdateRequest updateRequest = new UserUpdateRequest( + "updated_" + uniqueSuffix, + "updated_" + uniqueSuffix + "@example.com", + "new_password123"); + + APIResponse updateResponse = adminRequest.put(API_USERS + "/" + userId, RequestOptions.create().setData(updateRequest)); + assertEquals(200, updateResponse.status()); + JsonNode updatedJson = objectMapper.readTree(updateResponse.text()); + Long newUserID = updatedJson.get("id").asLong(); + assertEquals("updated_" + uniqueSuffix, updatedJson.get("username").asText()); + assertEquals("updated_" + uniqueSuffix + "@example.com", updatedJson.get("email").asText()); + + // get user by newUserId + APIResponse getNewUserResponse = adminRequest.get(API_USERS + "/" + newUserID); + assertTrue(getNewUserResponse.ok(), "Expected 2xx status. Got: " + getNewUserResponse.status()); + assertEquals(200, getNewUserResponse.status()); + + // delete the user + APIResponse responseDelete = adminRequest.delete(API_USERS + "/" + newUserID); + assertTrue(responseDelete.ok(), "Expected 2xx status. Got: " + responseDelete.status()); + assertEquals(204, responseDelete.status()); + + // try to find the deleted user again + APIResponse responseget18deleted = adminRequest.get(API_USERS + "/" + newUserID); + assertEquals(404, responseget18deleted.status(), + "Expected 404 Not Found after user deletion, but got: " + responseget18deleted.status()); + } + + @Test + void AsUser_FailToUpdateUser() { + // Try to update username, email and password of user 1 + UserUpdateRequest updateRequest = new UserUpdateRequest( + "hacker", + "hacker@example.com", + "hacked123"); + + APIResponse updateResponse = userRequest.put(API_USERS + "/1", RequestOptions.create().setData(updateRequest)); + // The users attempt to update the user should fail with a 403 Forbidden + assertEquals(403, updateResponse.status()); + } + + private void assertValidDate(String dateString) { + assertDoesNotThrow(() -> Instant.parse(dateString), + "Expected a valid date (e.g. 2026-03-04T09:04:54Z), but got: " + dateString); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/MatchTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/MatchTest.java new file mode 100644 index 000000000..d89a03ff1 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/MatchTest.java @@ -0,0 +1,231 @@ +package com.example.arimaabackend.playwright.sql; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.playwright.APIRequest; +import com.microsoft.playwright.APIRequestContext; +import com.microsoft.playwright.APIResponse; +import com.microsoft.playwright.Playwright; +import com.microsoft.playwright.options.RequestOptions; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; + +import java.util.Base64; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class MatchTest { + + private Playwright playwright; + private Dotenv dotenv; + private ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + private static final String MATCH_ID = "27557"; + private static final String GOLD_ID = "4803"; + private static final String GOLD_USERNAME = "Matthias"; + private static final String SILVER_ID = "4613"; + private static final String SILVER_USERNAME = "bot_GnoBot2006P1"; + + private static final String MATCH_DATA = + MATCH_ID + "\t" + GOLD_ID + "\t" + SILVER_ID + "\t"+ GOLD_USERNAME +"\t"+ SILVER_USERNAME + + "\t\t\tUS\tAU\t1258\t1238\t98\t30\th\tb\tCasual game\tOver the Net" + + "\t2/2/100/10/8\t0\t1143867610\t1143867977\tb\tr\t11\tIGS\t1\t0\t" + + "1w Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Ch1 Ha2 Mb2 Dc2 Dd2 Ee2 Cf2 Hg2 Rh2\\n" + + "1b ra8 rb8 rc8 dd8 de8 rf8 rg8 rh8 hb7 ra7 cc7 ed7 me7 cf7 rh7 hg7\\n" + + "2w Ee2n Ee3n Ee4n Ee5n\\n2b ed7s me7w de8s dd8e\\n3w Ee6s de7s Ee5s de6s\\n" + + "3b ed6s de8s de5n ed5s\\n4w Ee4s Ee3w Rh2n Rh3w\\n4b hg7s rh7w hb7s ra7e\\n" + + "5w Rg3w Rf3w Ch1n Ch2n\\n5b ed4e md7s ee4w Re3n\\n6w Hg2n Hg3w Hf3n Ch3w\\n" + + "6b Re4n ed4e rf8w re8w\\n7w Cg3n Cg4n Mb2n Mb3n\t7b Hf4n ee4e Hf5n Hf6x ef4n\\n" + + "8w Ed3n Ed4n Ed5s md6s\\n8b ef5s Cg5w Cf5n Cf6x ef4n\\n9w Ed4w md5s md4s Ec4e\\n" + + "9b de6w Re5n Re6e Rf6x de7s\\n10w md3w mc3x Ed4s Ha2e Hb2n\\n10b ef5w ee5s ee4w ed4w\\n" + + "11w\tevents"; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + @Test + void AsAdmin_UpdateMatch() throws JsonProcessingException { + + // Create Match + APIResponse createResponse = adminRequest.post("/api/matches", RequestOptions.create().setData(MATCH_DATA)); + assertEquals(201, createResponse.status(), "Failed to create match. Body: " + createResponse.text()); + + // Update Match + // Modify the result in MATCH_DATA from "b" to "w" (Gold wins) + String updatedData = MATCH_DATA.replace("\tb\tr\t11\tIGS", "\tw\tr\t11\tIGS"); + + APIResponse updateResponse = adminRequest.put("/api/matches/" + MATCH_ID, RequestOptions.create().setData(updatedData)); + assertEquals(200, updateResponse.status(), "Failed to update match. Body: " + updateResponse.text()); + + JsonNode matchJson = objectMapper.readTree(updateResponse.text()); + assertEquals("w", matchJson.get("matchResult").asText()); + + try { + // Make sure you can get the match with the new value: + APIResponse getResponse = adminRequest.get("/api/matches/" + MATCH_ID); + Integer getResponseStatus = getResponse.status(); + String getResponseText = getResponse.text(); + assertEquals(200, getResponseStatus); + JsonNode getJson = objectMapper.readTree(getResponseText); + assertEquals("w", getJson.get("matchResult").asText()); + + // Delete the Match + APIResponse deleteResponse = adminRequest.delete("/api/matches/" + MATCH_ID); + assertEquals(204, deleteResponse.status()); + + // Verify Match is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/matches/" + MATCH_ID); + assertEquals(404, getAfterDeleteResponse.status()); + } finally { + // Cleanup just in case + adminRequest.delete("/api/matches/" + MATCH_ID); + } + } + + + @Test + void AsUser_UpdateMatch() throws JsonProcessingException { + // Create Match (as an admin, to have a match to update) + APIResponse createResponse = adminRequest.post("/api/matches", RequestOptions.create().setData(MATCH_DATA)); + assertEquals(201, createResponse.status(), "Failed to create match. Body: " + createResponse.text()); + + // Update Match + // Modify the result in MATCH_DATA from "b" to "w" (Gold wins) + String updatedData = MATCH_DATA.replace("\tb\tr\t11\tIGS", "\tw\tr\t11\tIGS"); + + APIResponse updateResponse = userRequest.put("/api/matches/" + MATCH_ID, RequestOptions.create().setData(updatedData)); + // The users attempt to update the match should fail with a 403 Forbidden + assertEquals(403, updateResponse.status(), "Failed to update match. Body: " + updateResponse.text()); + + // Delete the Match + APIResponse deleteResponse = adminRequest.delete("/api/matches/" + MATCH_ID); + assertEquals(204, deleteResponse.status()); + + // Verify Match is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/matches/" + MATCH_ID); + assertEquals(404, getAfterDeleteResponse.status()); + } + + + @Test + void AsAdmin_CreateThenDeleteMatch() throws JsonProcessingException { + + // Create Match + APIResponse createResponse = adminRequest.post("/api/matches", RequestOptions.create().setData(MATCH_DATA)); + + Integer responseStatus = createResponse.status(); + String responseText = createResponse.text(); + assertEquals(201, (int)responseStatus, "Failed to create match. Body: " + responseText); + + JsonNode matchJson = objectMapper.readTree(createResponse.text()); + assertEquals(MATCH_ID, matchJson.get("id").toString()); + + try { + // Get the Match + APIResponse getResponse = adminRequest.get("/api/matches/" + MATCH_ID); + Integer getResponseStatus = getResponse.status(); + String getResponseText = getResponse.text(); + assertEquals(200, getResponseStatus); + JsonNode getJson = objectMapper.readTree(getResponseText); + + // verify the match values + assertEquals(Integer.parseInt(MATCH_ID), getJson.get("id").asInt()); + assertEquals("r", getJson.get("terminationType").asText()); + assertEquals("bot_GnoBot2006P1", getJson.get("silverPlayer").get("username").asText()); + assertEquals(4803, getJson.get("goldPlayer").get("id").asInt()); + assertEquals("Matthias", getJson.get("goldPlayer").get("username").asText()); + assertEquals(1258, getJson.get("goldRating").asInt()); + assertEquals(1238, getJson.get("silverRating").asInt()); + assertEquals("b", getJson.get("matchResult").asText()); + assertEquals("Casual game", getJson.get("event").get("name").asText()); + assertEquals("2/2/100/10/8", getJson.get("gameType").get("name").asText()); + assertEquals("null", getJson.get("gameType").get("timeIncrement").asText()); + assertEquals("null", getJson.get("gameType").get("timeReserve").asText()); + assertEquals("2006-04-01T05:00:10Z", getJson.get("timestamp").asText()); + + // Delete the Match + APIResponse deleteResponse = adminRequest.delete("/api/matches/" + MATCH_ID); + assertEquals(204, deleteResponse.status()); + + // Verify Match is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/matches/" + MATCH_ID); + assertEquals(404, getAfterDeleteResponse.status()); + } finally { + // Cleanup just in case + adminRequest.delete("/api/matches/" + MATCH_ID); + } + } + + + @Test + void AsUser_FailToCreateMatch() { + String matchData = "999998\t1001\t1002\tplayer1\tplayer2\t\t\tUSA\tCanada\t1500\t1500\t\t\t\t\tTest Event\t\t2m+2s\t\t" + (System.currentTimeMillis()/1000) + "\t\t1-0\tnormal"; + APIResponse response = userRequest.post("/api/matches", RequestOptions.create().setData(matchData)); + assertEquals(403, response.status()); + } + + @Test + void AsUser_FailToDeleteMatch() { + APIResponse response = userRequest.delete("/api/matches/1"); + assertEquals(403, response.status()); + } + + @Test + void deleteById_SHouldFail() { + APIResponse response = adminRequest.delete("/api/matches/9999999"); + assertEquals(404, response.status()); + } + + @Test + void AsAdmin_FailToGetMissingMatch() { + APIResponse response = adminRequest.get("/api/matches/9999999"); + assertEquals(404, response.status()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/PlayerTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/PlayerTest.java new file mode 100644 index 000000000..9be74923f --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/PlayerTest.java @@ -0,0 +1,264 @@ +package com.example.arimaabackend.playwright.sql; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerUpdateRequest; +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.playwright.APIRequest; +import com.microsoft.playwright.APIRequestContext; +import com.microsoft.playwright.APIResponse; +import com.microsoft.playwright.Playwright; +import com.microsoft.playwright.options.RequestOptions; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; +import java.util.Base64; +import java.util.Map; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class PlayerTest { + + private static final Integer BOT_SHALLOWBLUE_ID = 371; + + private Playwright playwright; + private Dotenv dotenv; + private ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + @Test + void ASAdmin_CreateThenDeletePlayer() throws JsonProcessingException { + // Create user first (add player later) + String testUsername = "player_test_" + System.currentTimeMillis(); + UserCreateRequest userRequestData = new UserCreateRequest( + testUsername, + testUsername + "@example.com", + "password123" + ); + APIResponse userCreateResponse = adminRequest.post("/api/users", RequestOptions.create().setData(userRequestData)); + assertEquals(201, userCreateResponse.status()); + JsonNode userJson = objectMapper.readTree(userCreateResponse.text()); + long userId = userJson.get("id").asLong(); + + try { + // Create a Player + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(userId, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = adminRequest.post("/api/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(201, playerCreateResponse.status(), "Failed to create player: " + playerCreateResponse.text()); + + JsonNode playerJson = objectMapper.readTree(playerCreateResponse.text()); + int playerId = playerJson.get("id").asInt(); + assertEquals(testUsername, playerJson.get("username").asText()); + + // Get the Player + APIResponse getResponse = adminRequest.get("/api/players/" + playerId); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + assertEquals(playerId, getJson.get("id").asInt()); + + // Get the user + APIResponse getUserResponse = adminRequest.get("/api/users/" + userId); + assertEquals(200, getUserResponse.status()); + JsonNode getUserJson = objectMapper.readTree(getUserResponse.text()); + assertEquals(userId, getUserJson.get("id").asInt()); + + // Delete the Player + APIResponse deleteResponse = adminRequest.delete("/api/players/" + playerId); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(204, deleteResponse.status()); + + // Verify Player is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/players/" + playerId); + assertEquals(404, getAfterDeleteResponse.status()); + + //verify user is gone + APIResponse getAfterDeleteUserResponse = adminRequest.get("/api/users/" + userId); + assertEquals(404, getAfterDeleteResponse.status()); + + } finally { + // Cleanup: delete user (which might also cascade delete player if we didn't do it) + adminRequest.delete("/api/users/" + userId); + } + } + + @Test + void AsAdmin_FailToCreatePlayerWithoutUserObj() { + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(null, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = adminRequest.post("/api/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(400, playerCreateResponse.status(), "Expected status 400 but got: " + playerCreateResponse.text()); + } + + + @Test + void AsUser_FailToCreatePlayerWithoutUser() { + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(null, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = userRequest.post("/api/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(400, playerCreateResponse.status(), "Expected status 400 but got: " + playerCreateResponse.text()); + } + + + @Test + void AsAdmin_FailToDeletePlayerWithMatches() throws JsonProcessingException { + APIResponse getResponse = adminRequest.get("/api/players/" + BOT_SHALLOWBLUE_ID); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + assertEquals(BOT_SHALLOWBLUE_ID, getJson.get("id").asInt()); + + APIResponse deleteResponse = adminRequest.delete("/api/players/" + BOT_SHALLOWBLUE_ID); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(400, deleteResponse.status()); + } + + @Test + void AsUser_FailToDeletePlayerWithMatches() throws JsonProcessingException { + APIResponse getResponse = userRequest.get("/api/players/" + BOT_SHALLOWBLUE_ID); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + assertEquals(BOT_SHALLOWBLUE_ID, getJson.get("id").asInt()); + + APIResponse deleteResponse = userRequest.delete("/api/players/" + BOT_SHALLOWBLUE_ID); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(403, deleteResponse.status()); + } + + @Test + void deleteById_returns404_whenNotFound() { + APIResponse response = adminRequest.delete("/api/players/999999"); + assertEquals(404, response.status()); + } + + @Test + void AsAdmin_UpdatePlayer() throws JsonProcessingException { + // Create user first (add player later) + String testUsername = "player_test_" + System.currentTimeMillis(); + UserCreateRequest userRequestData = new UserCreateRequest( + testUsername, + testUsername + "@example.com", + "password123" + ); + APIResponse userCreateResponse = adminRequest.post("/api/users", RequestOptions.create().setData(userRequestData)); + assertEquals(201, userCreateResponse.status()); + JsonNode userJson = objectMapper.readTree(userCreateResponse.text()); + long userId = userJson.get("id").asLong(); + + try { + // Create a Player + PlayerCreateRequest playerRequestData = new PlayerCreateRequest(userId, 1500, 100, 5, 1, null); + APIResponse playerCreateResponse = adminRequest.post("/api/players", RequestOptions.create().setData(playerRequestData)); + assertEquals(201, playerCreateResponse.status(), "Failed to create player: " + playerCreateResponse.text()); + + JsonNode playerJson = objectMapper.readTree(playerCreateResponse.text()); + int playerId = playerJson.get("id").asInt(); + assertEquals(testUsername, playerJson.get("username").asText()); + + // Get the Player + APIResponse getResponse = adminRequest.get("/api/players/" + playerId); + assertEquals(200, getResponse.status()); + JsonNode getJson = objectMapper.readTree(getResponse.text()); + assertEquals(playerId, getJson.get("id").asInt()); + + // Get the user + APIResponse getUserResponse = adminRequest.get("/api/users/" + userId); + assertEquals(200, getUserResponse.status()); + JsonNode getUserJson = objectMapper.readTree(getUserResponse.text()); + assertEquals(userId, getUserJson.get("id").asInt()); + + // Update player and their user information + UserUpdateRequest userUpdate = new UserUpdateRequest( + "updated_player", + "updated_player" + "@example.com", + "new_password123"); + PlayerUpdateRequest updateRequest = new PlayerUpdateRequest(1500, 10, 5, 2, userUpdate); // Update rating to 1500, country to 2 + + APIResponse updateResponse = adminRequest.put("/api/players/" + playerId, RequestOptions.create().setData(updateRequest)); + assertEquals(200, updateResponse.status()); + JsonNode updatedJson = objectMapper.readTree(updateResponse.text()); + + assertEquals(1500, updatedJson.get("rating").asInt()); + assertEquals(10, updatedJson.get("ru").asInt()); + assertEquals(5, updatedJson.get("gamesPlayed").asInt()); + assertEquals(2, updatedJson.get("countryId").asInt()); + assertEquals("updated_player", updatedJson.get("username").asText()); + assertEquals("updated_player" + "@example.com", updatedJson.get("email").asText()); + + // Verify user was updated too via GET /api/users/{id} + APIResponse updatedUserResponse = adminRequest.get("/api/users/" + userId); + assertEquals(200, updatedUserResponse.status()); + JsonNode updatedUserJson = objectMapper.readTree(updatedUserResponse.text()); + assertEquals("updated_player", updatedUserJson.get("username").asText()); + assertEquals("updated_player" + "@example.com", updatedUserJson.get("email").asText()); + + // Delete the Player + APIResponse deleteResponse = adminRequest.delete("/api/players/" + playerId); + System.out.println("[DEBUG_LOG] Delete response status: " + deleteResponse.status()); + assertEquals(204, deleteResponse.status()); + + // Verify Player is gone + APIResponse getAfterDeleteResponse = adminRequest.get("/api/players/" + playerId); + assertEquals(404, getAfterDeleteResponse.status()); + + //verify user is gone + APIResponse getAfterDeleteUserResponse = adminRequest.get("/api/users/" + userId); + assertEquals(404, getAfterDeleteResponse.status()); + + } finally { + // Cleanup: delete user (which might also cascade delete player if we didn't do it) + adminRequest.delete("/api/users/" + userId); + } + } + @Test + void AsUser_FailToUpdatePlayer() { + PlayerUpdateRequest updateRequest = new PlayerUpdateRequest(2000, 100, 50, 1, null); + APIResponse response = userRequest.put("/api/players/1", RequestOptions.create().setData(updateRequest)); + assertEquals(403, response.status()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/UserTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/UserTest.java new file mode 100644 index 000000000..d8f9100be --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/playwright/sql/UserTest.java @@ -0,0 +1,226 @@ +package com.example.arimaabackend.playwright.sql; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.dto.UserUpdateRequest; +import com.microsoft.playwright.options.RequestOptions; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.microsoft.playwright.*; +import io.github.cdimascio.dotenv.Dotenv; +import org.junit.jupiter.api.*; +import java.time.Instant; +import java.util.Base64; +import java.util.Map; +import static org.junit.jupiter.api.Assertions.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class UserTest { + + private Playwright playwright; + private Dotenv dotenv; + private final ObjectMapper objectMapper = new ObjectMapper(); + + private APIRequestContext adminRequest; + private APIRequestContext userRequest; + + private static String API_USERS = "/api/users"; + + @BeforeAll + void setup() { + // use the .env file in the root directory + dotenv = Dotenv.configure() + .directory("./") + .ignoreIfMissing() + .load(); + + playwright = Playwright.create(); + + String adminAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_ADMIN_USERNAME", "admin1") + ":" + + dotenv.get("DEFAULT_ADMIN_PASSWORD", "password")).getBytes()); + + String userAuth = Base64.getEncoder().encodeToString( + (dotenv.get("DEFAULT_USER_USERNAME", "user1") + ":" + + dotenv.get("DEFAULT_USER_PASSWORD", "password")).getBytes()); + + + adminRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + adminAuth)) + ); + + userRequest = playwright.request().newContext( + new APIRequest.NewContextOptions() + .setBaseURL("http://localhost:8080") + .setExtraHTTPHeaders(Map.of( + "Accept", "application/json", + "Content-Type", "application/json", + "Authorization", "Basic " + userAuth)) + ); + } + + @AfterAll + void teardown() { + if (adminRequest != null) adminRequest.dispose(); + if (userRequest != null) userRequest.dispose(); + if (playwright != null) playwright.close(); + } + + @Test + void AsUser_FailToCreateUser() { + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + UserCreateRequest createUser = new UserCreateRequest( + "usernametest_" + uniqueSuffix, + "usernametest_" + uniqueSuffix + "@unknown.invalid", + "usernametest1_userCantCreateuser"); + APIResponse response = userRequest.post(API_USERS, RequestOptions.create().setData(createUser)); + assertFalse(response.ok(), "Expected 4xx status. Got: " + response.status()); + assertEquals(403, response.status()); + } + + @Test + void AsUser_FailToDeleteUser() { + APIResponse getFirstUserResponse = adminRequest.get(API_USERS + "/1"); + assertTrue(getFirstUserResponse.ok(), "Expected 2xx status. Got: " + getFirstUserResponse.status()); + assertEquals(200, getFirstUserResponse.status()); + + APIResponse responseDelete = userRequest.delete(API_USERS + "/1"); + assertFalse(responseDelete.ok(), "Expected 4xx status. Got: " + responseDelete.status()); + assertEquals(403, responseDelete.status()); + } + + @Test + void AsAdmin_CreateThenDeleteUser() { + // Create user (to delete later) + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + String username = "DeleteMe_" + uniqueSuffix; + UserCreateRequest createUser = new UserCreateRequest( + username, + "delete_me_" + uniqueSuffix + "@unknown.invalid", + "password_123"); + APIResponse response = adminRequest.post(API_USERS, RequestOptions.create().setData(createUser)); + assertTrue(response.ok(), "Expected 2xx status. Got: " + response.status() + " Body: " + response.text()); + assertEquals(201, response.status()); + JsonNode json; + try { + json = objectMapper.readTree(response.text()); + } catch (JsonProcessingException e) { + fail("Invalid JSON response: " + e.getMessage()); + return; + } + Long newUserId = json.path("id").asLong(); + String newUserName = json.path("username").asText(); + assertEquals(username, newUserName); + + // get user by newUserId + APIResponse getNewUserResponse = adminRequest.get(API_USERS + "/" + newUserId); + assertTrue(getNewUserResponse.ok(), "Expected 2xx status. Got: " + getNewUserResponse.status() + " Body: " + getNewUserResponse.text()); + assertEquals(200, getNewUserResponse.status()); + + // delete the user + APIResponse responseDelete = adminRequest.delete(API_USERS + "/" + newUserId); + assertTrue(responseDelete.ok(), "Expected 2xx status. Got: " + responseDelete.status()); + assertEquals(204, responseDelete.status()); + + // try to find the deleted user again + APIResponse responseget18deleted = adminRequest.get(API_USERS + "/" + newUserId); + assertEquals(404, responseget18deleted.status(), + "Expected 404 Not Found after user deletion, but got: " + response.status()); + } + + + @Test + void AsAdmin_GetUserById() { + APIResponse response = adminRequest.get(API_USERS + "/1"); + assertTrue(response.ok(), "Expected 2xx status. Got: " + response.status()); + assertEquals(200, response.status()); + String jsonString = response.text(); + + JsonNode json; + try { + json = objectMapper.readTree(jsonString); + } catch (JsonProcessingException e) { + fail("Invalid JSON response: " + e.getMessage()); + return; + } + assertEquals(1, json.get("id").asInt()); + assertEquals("bot_ShallowBlue", json.get("username").asText()); + assertEquals("bot_ShallowBlue@unknown.invalid", json.get("email").asText()); + assertEquals("PLAYER", json.get("role").asText()); + + assertValidDate(json.get("createdAt").asText()); + assertValidDate(json.get("updatedAt").asText()); + } + + @Test + void AsAdmin_FailToGetMissingUserById() { + APIResponse response = adminRequest.get(API_USERS + "/43543637"); + assertFalse(response.ok(), "Expected 4xx status. Got: " + response.status()); + assertEquals(404, response.status()); + } + + @Test + void AsAdmin_UpdateUser() throws JsonProcessingException { + // Create user (to update later) + String uniqueSuffix = String.valueOf(System.currentTimeMillis()); + UserCreateRequest createUser = new UserCreateRequest( + "update_me_" + uniqueSuffix, + "update_me_" + uniqueSuffix + "@example.com", + "password123"); + APIResponse createResponse = adminRequest.post(API_USERS, RequestOptions.create().setData(createUser)); + assertEquals(201, createResponse.status()); + JsonNode json = objectMapper.readTree(createResponse.text()); + Long userId = json.get("id").asLong(); + + // Update user + UserUpdateRequest updateRequest = new UserUpdateRequest( + "updated_" + uniqueSuffix, + "updated_" + uniqueSuffix + "@example.com", + "new_password123"); + + APIResponse updateResponse = adminRequest.put(API_USERS + "/" + userId, RequestOptions.create().setData(updateRequest)); + assertEquals(200, updateResponse.status()); + JsonNode updatedJson = objectMapper.readTree(updateResponse.text()); + Long newUserID = updatedJson.get("id").asLong(); + assertEquals("updated_" + uniqueSuffix, updatedJson.get("username").asText()); + assertEquals("updated_" + uniqueSuffix + "@example.com", updatedJson.get("email").asText()); + + // get user by newUserId + APIResponse getNewUserResponse = adminRequest.get(API_USERS + "/" + newUserID); + assertTrue(getNewUserResponse.ok(), "Expected 2xx status. Got: " + getNewUserResponse.status()); + assertEquals(200, getNewUserResponse.status()); + + // delete the user + APIResponse responseDelete = adminRequest.delete(API_USERS + "/" + newUserID); + assertTrue(responseDelete.ok(), "Expected 2xx status. Got: " + responseDelete.status()); + assertEquals(204, responseDelete.status()); + + // try to find the deleted user again + APIResponse responseget18deleted = adminRequest.get(API_USERS + "/" + newUserID); + assertEquals(404, responseget18deleted.status(), + "Expected 404 Not Found after user deletion, but got: " + responseget18deleted.status()); + } + + @Test + void AsUser_FailToUpdateUser() { + // Try to update username, email and password of user 1 + UserUpdateRequest updateRequest = new UserUpdateRequest( + "hacker", + "hacker@example.com", + "hacked123"); + + APIResponse updateResponse = userRequest.put(API_USERS + "/1", RequestOptions.create().setData(updateRequest)); + // The users attempt to update the user should fail with a 403 Forbidden + assertEquals(403, updateResponse.status()); + } + + private void assertValidDate(String dateString) { + assertDoesNotThrow(() -> Instant.parse(dateString), + "Expected a valid date (e.g. 2026-03-04T09:04:54Z), but got: " + dateString); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/ArimaaBackendApplicationTests.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/ArimaaBackendApplicationTests.java new file mode 100644 index 000000000..0a2e13a35 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/ArimaaBackendApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.arimaabackend.unittests; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ArimaaBackendApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/CountryJpaRepositoryTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/CountryJpaRepositoryTest.java new file mode 100644 index 000000000..293d859b4 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/CountryJpaRepositoryTest.java @@ -0,0 +1,30 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.model.sql.CountryEntity; +import com.example.arimaabackend.repository.sql.CountryJpaRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +class CountryJpaRepositoryTest { + + @Autowired + private CountryJpaRepository countryJpaRepository; + + @Test + void shouldSaveAndLoadCountry() { + var country = new CountryEntity(); + country.setId(1); + country.setName("US"); + + countryJpaRepository.save(country); + + var loaded = countryJpaRepository.findById(1); + + assertThat(loaded).isPresent(); + assertThat(loaded.get().getName()).isEqualTo("US"); + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/MatchJpaRepositoryTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/MatchJpaRepositoryTest.java new file mode 100644 index 000000000..291b29cad --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/MatchJpaRepositoryTest.java @@ -0,0 +1,113 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.model.sql.*; +import com.example.arimaabackend.repository.sql.CountryJpaRepository; +import com.example.arimaabackend.repository.sql.EventJpaRepository; +import com.example.arimaabackend.repository.sql.GameTypeJpaRepository; +import com.example.arimaabackend.repository.sql.MatchJpaRepository; +import com.example.arimaabackend.repository.sql.PlayerJpaRepository; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +class MatchJpaRepositoryTest { + + @Autowired + private MatchJpaRepository matchJpaRepository; + + @Autowired + private PlayerJpaRepository playerJpaRepository; + + @Autowired + private CountryJpaRepository countryJpaRepository; + + @Autowired + private EventJpaRepository eventJpaRepository; + + @Autowired + private GameTypeJpaRepository gameTypeJpaRepository; + + @Autowired + private UserJpaRepository userJpaRepository; + + @Test + void shouldSaveAndLoadMatchAndFindByPlayerIds() { + var countryUs = new CountryEntity(); + countryUs.setId(1); + countryUs.setName("US"); + countryJpaRepository.save(countryUs); + + var countryAu = new CountryEntity(); + countryAu.setId(2); + countryAu.setName("AU"); + countryJpaRepository.save(countryAu); + + var silverUser = new UserEntity(); + silverUser.setUsername("Matthias"); + silverUser.setEmail("matthias@example.com"); + silverUser.setPasswordHash("password"); + + var silver = new PlayerEntity(); + silver.setId(4803); + silver.setUser(silverUser); + silver.setCountry(countryUs); + userJpaRepository.save(silverUser); + playerJpaRepository.save(silver); + + var goldUser = new UserEntity(); + goldUser.setUsername("bot_GnoBot2006P1"); + goldUser.setEmail("bot@example.com"); + goldUser.setPasswordHash("password"); + + var gold = new PlayerEntity(); + gold.setId(4613); + gold.setUser(goldUser); + gold.setCountry(countryAu); + userJpaRepository.save(goldUser); + playerJpaRepository.save(gold); + + var event = new EventEntity(); + event.setId(1); + event.setName("Casual game"); + event.setRated(false); + eventJpaRepository.save(event); + + var gameType = new GameTypeEntity(); + gameType.setId(1); + gameType.setName("Over the Net"); + gameType.setTimeIncrement(2); + gameType.setTimeReserve(2); + gameTypeJpaRepository.save(gameType); + + var match = new MatchEntity(); + match.setId(27557); + match.setTerminationType("test"); + match.setSilverPlayer(silver); + match.setGoldPlayer(gold); + match.setMatchResult("unknown"); + match.setEvent(event); + match.setGameType(gameType); + + matchJpaRepository.save(match); + + var loaded = matchJpaRepository.findById(27557); + + assertThat(loaded).isPresent(); + assertThat(loaded.get().getSilverPlayer().getUser().getUsername()).isEqualTo("Matthias"); + assertThat(loaded.get().getGoldPlayer().getUser().getUsername()).isEqualTo("bot_GnoBot2006P1"); + + var bySilver = matchJpaRepository.findBySilverPlayer_Id(4803); + var byGold = matchJpaRepository.findByGoldPlayer_Id(4613); + var byEvent = matchJpaRepository.findByEvent_Id(1); + var byGameType = matchJpaRepository.findByGameType_Id(1); + + assertThat(bySilver).hasSize(1); + assertThat(byGold).hasSize(1); + assertThat(byEvent).hasSize(1); + assertThat(byGameType).hasSize(1); + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/MatchServiceTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/MatchServiceTest.java new file mode 100644 index 000000000..618e4660a --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/MatchServiceTest.java @@ -0,0 +1,109 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.dto.MatchResponse; +import com.example.arimaabackend.model.sql.*; +import com.example.arimaabackend.repository.sql.*; +import com.example.arimaabackend.services.MatchServiceImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.springframework.web.server.ResponseStatusException; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +class MatchServiceTest { + + @Mock + private MatchJpaRepository matchRepository; + @Mock + private PlayerJpaRepository playerRepository; + @Mock + private UserJpaRepository userRepository; + @Mock + private EventJpaRepository eventRepository; + @Mock + private GameTypeJpaRepository gameTypeRepository; + @Mock + private CountryJpaRepository countryRepository; + @Mock + private MoveJpaRepository moveRepository; + @Mock + private PositionJpaRepository positionRepository; + + @InjectMocks + private MatchServiceImpl matchService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void deleteMatch_validId_deletesMatchMovesAndPositions() { + final Integer MATCH_ID = 669178; + when(matchRepository.existsById(MATCH_ID)).thenReturn(true); + + matchService.deleteMatch(MATCH_ID); + + verify(positionRepository).deleteUnusedByMatchId(MATCH_ID); + verify(moveRepository).deleteByMatch_Id(MATCH_ID); + verify(matchRepository).deleteById(MATCH_ID); + } + + @Test + void deleteMatch_invalidId_throwsNotFound() { + final Integer MATCH_ID = 999; + when(matchRepository.existsById(MATCH_ID)).thenReturn(false); + + assertThrows(ResponseStatusException.class, () -> matchService.deleteMatch(MATCH_ID)); + } + + @Test + void createMatch_validString_createsAndSavesMatch() { + String matchId = "27557"; + String goldId = "4803"; + String goldusername = "Matthias"; + String silverId = "4613"; + String silverUsername = "bot_GnoBot2006P1"; + + String matchData = + matchId + "\t" + goldId + "\t" +silverId + "\t"+goldusername+"\t"+silverUsername+ + "\t\t\tUS\tAU\t1258\t1238\t98\t30\th\tb\tCasual game\tOver the Net" + + "\t2/2/100/10/8\t0\t1143867610\t1143867977\tb\tr\t11\tIGS\t1\t0\t1w Ra1 Rb1 Rc1 Rd1 Re1 Rf1 Rg1 Ch1 Ha2 Mb2 Dc2 Dd2 Ee2 Cf2 Hg2 Rh2\\n1b ra8 rb8 rc8 dd8 de8 rf8 rg8 rh8 hb7 ra7 cc7 ed7 me7 cf7 rh7 hg7\\n2w Ee2n Ee3n Ee4n Ee5n\\n2b ed7s me7w de8s dd8e\\n3w Ee6s de7s Ee5s de6s\\n3b ed6s de8s de5n ed5s\\n4w Ee4s Ee3w Rh2n Rh3w\\n4b hg7s rh7w hb7s ra7e\\n5w Rg3w Rf3w Ch1n Ch2n\\n5b ed4e md7s ee4w Re3n\\n6w Hg2n Hg3w Hf3n Ch3w\\n6b Re4n ed4e rf8w re8w\\n7w Cg3n Cg4n Mb2n Mb3n\t7b Hf4n ee4e Hf5n Hf6x ef4n\\n8w Ed3n Ed4n Ed5s md6s\\n8b ef5s Cg5w Cf5n Cf6x ef4n\\n9w Ed4w md5s md4s Ec4e\\n9b de6w Re5n Re6e Rf6x de7s\\n10w md3w mc3x Ed4s Ha2e Hb2n\\n10b ef5w ee5s ee4w ed4w\\n11w\tevents"; + + when(playerRepository.findById(anyInt())).thenReturn(Optional.empty()); + when(userRepository.findByUsername(anyString())).thenReturn(Optional.empty()); + when(countryRepository.findByName(anyString())).thenReturn(Optional.empty()); + when(eventRepository.findByName(anyString())).thenReturn(Optional.empty()); + when(gameTypeRepository.findByName(anyString())).thenReturn(Optional.empty()); + + when(userRepository.save(any(UserEntity.class))).thenAnswer(i -> i.getArgument(0)); + when(countryRepository.save(any(CountryEntity.class))).thenAnswer(i -> i.getArgument(0)); + when(playerRepository.save(any(PlayerEntity.class))).thenAnswer(i -> i.getArgument(0)); + when(eventRepository.save(any(EventEntity.class))).thenAnswer(i -> i.getArgument(0)); + when(gameTypeRepository.save(any(GameTypeEntity.class))).thenAnswer(i -> i.getArgument(0)); + when(matchRepository.save(any(MatchEntity.class))).thenAnswer(i -> i.getArgument(0)); + + MatchResponse created = matchService.createMatch(matchData); + + assertNotNull(created); + assertEquals(27557, created.id()); + assertEquals("b", created.matchResult()); + assertEquals("r", created.terminationType()); + assertEquals(4803, created.goldPlayer().id()); + assertEquals(4613, created.silverPlayer().id()); + assertEquals("Matthias", created.goldPlayer().username()); + assertEquals("bot_GnoBot2006P1", created.silverPlayer().username()); + assertEquals("Casual game", created.event().name()); + assertEquals("2/2/100/10/8", created.gameType().name()); + + verify(matchRepository).save(any(MatchEntity.class)); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PasswordEncoderTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PasswordEncoderTest.java new file mode 100644 index 000000000..cdae714bb --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PasswordEncoderTest.java @@ -0,0 +1,64 @@ +package com.example.arimaabackend.unittests; + +import org.junit.jupiter.api.Test; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import static org.assertj.core.api.Assertions.assertThat; + +class PasswordEncoderTest { + + private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + @Test + void encode_generatesHashForAdminAndUserPasswords() { + String adminRawPassword = "adminpassword1"; + String userRawPassword = "userpassword1"; + + String adminHash = passwordEncoder.encode(adminRawPassword); + String userHash = passwordEncoder.encode(userRawPassword); + + assertThat(adminHash).startsWith("$2a$"); + assertThat(userHash).startsWith("$2a$"); + + assertThat(passwordEncoder.matches(adminRawPassword, adminHash)).isTrue(); + assertThat(passwordEncoder.matches(userRawPassword, userHash)).isTrue(); + } + + @Test + void encode_producesHashWithBCryptPrefix() { + String hash = passwordEncoder.encode("secret123"); + + assertThat(hash).startsWith("$2a$"); + } + + @Test + void encode_doesNotReturnPlaintext() { + String raw = "secret123"; + String hash = passwordEncoder.encode(raw); + + assertThat(hash).isNotEqualTo(raw); + } + + @Test + void matches_returnsTrueForCorrectPassword() { + String hash = passwordEncoder.encode("secret123"); + + assertThat(passwordEncoder.matches("secret123", hash)).isTrue(); + } + + @Test + void matches_returnsFalseForWrongPassword() { + String hash = passwordEncoder.encode("secret123"); + + assertThat(passwordEncoder.matches("wrongPassword", hash)).isFalse(); + } + + @Test + void encode_producesDifferentHashesForSamePassword() { + String hash1 = passwordEncoder.encode("secret123"); + String hash2 = passwordEncoder.encode("secret123"); + + assertThat(hash1).isNotEqualTo(hash2); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PlayerJpaRepositoryTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PlayerJpaRepositoryTest.java new file mode 100644 index 000000000..747c8dbac --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PlayerJpaRepositoryTest.java @@ -0,0 +1,96 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.model.sql.CountryEntity; +import com.example.arimaabackend.model.sql.PlayerEntity; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.sql.CountryJpaRepository; +import com.example.arimaabackend.repository.sql.PlayerJpaRepository; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +class PlayerJpaRepositoryTest { + + @Autowired + private PlayerJpaRepository playerJpaRepository; + + @Autowired + private CountryJpaRepository countryJpaRepository; + + @Autowired + private UserJpaRepository userJpaRepository; + + @Test + void shouldSaveAndLoadPlayerByUsername() { + var country = new CountryEntity(); + country.setId(1); + country.setName("US"); + countryJpaRepository.save(country); + + var playerUser = new UserEntity(); + playerUser.setUsername("Matthias"); + playerUser.setEmail("matthias@example.com"); + playerUser.setPasswordHash("hashed_password"); + userJpaRepository.save(playerUser); + + var player = new PlayerEntity(); + player.setId(4803); + player.setUser(playerUser); + player.setCountry(country); + + playerJpaRepository.save(player); + + var loaded = playerJpaRepository.findByUser_Username("Matthias"); + + assertThat(loaded).isPresent(); + assertThat(loaded.get().getId()).isEqualTo(4803); + assertThat(loaded.get().getUser().getUsername()).isEqualTo("Matthias"); + assertThat(loaded.get().getCountry().getName()).isEqualTo("US"); + } + + @Test + void shouldFindPlayersByCountryName() { + var countryUs = new CountryEntity(); + countryUs.setId(1); + countryUs.setName("US"); + countryJpaRepository.save(countryUs); + + var countryAu = new CountryEntity(); + countryAu.setId(2); + countryAu.setName("AU"); + countryJpaRepository.save(countryAu); + + var player1User = new UserEntity(); + player1User.setUsername("Matthias"); + player1User.setEmail("matthias@example.com"); + player1User.setPasswordHash("hashed_password"); + userJpaRepository.save(player1User); + + var player1 = new PlayerEntity(); + player1.setId(4803); + player1.setUser(player1User); + player1.setCountry(countryUs); + playerJpaRepository.save(player1); + + var player2User = new UserEntity(); + player2User.setUsername("bot_GnoBot2006P1"); + player2User.setEmail("bot@example.com"); + player2User.setPasswordHash("hashed_password"); + userJpaRepository.save(player2User); + + var player2 = new PlayerEntity(); + player2.setId(4613); + player2.setUser(player2User); + player2.setCountry(countryAu); + playerJpaRepository.save(player2); + + var usPlayers = playerJpaRepository.findByCountryName("US"); + + assertThat(usPlayers).hasSize(1); + assertThat(usPlayers.get(0).getUser().getUsername()).isEqualTo("Matthias"); + } +} \ No newline at end of file diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PlayerServiceTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PlayerServiceTest.java new file mode 100644 index 000000000..2b6423484 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/PlayerServiceTest.java @@ -0,0 +1,268 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.dto.PlayerCreateRequest; +import com.example.arimaabackend.dto.PlayerResponse; +import com.example.arimaabackend.model.sql.CountryEntity; +import com.example.arimaabackend.model.sql.PlayerEntity; +import com.example.arimaabackend.repository.sql.CountryJpaRepository; +import com.example.arimaabackend.repository.sql.MatchJpaRepository; +import com.example.arimaabackend.repository.sql.PlayerJpaRepository; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import com.example.arimaabackend.model.sql.UserEntity; +import org.springframework.security.crypto.password.PasswordEncoder; +import static org.springframework.test.util.ReflectionTestUtils.setField; +import com.example.arimaabackend.services.PlayerServiceImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.any; + +@ExtendWith(MockitoExtension.class) +class PlayerServiceTest { + + @Mock + private PlayerJpaRepository playerJpaRepository; + + @Mock + private UserJpaRepository userJpaRepository; + + @Mock + private CountryJpaRepository countryJpaRepository; + + @Mock + private MatchJpaRepository matchJpaRepository; + + @Mock + private PasswordEncoder passwordEncoder; + + @InjectMocks + private PlayerServiceImpl playerService; + + private CountryEntity country; + private UserEntity user1; + private UserEntity user2; + private PlayerEntity player1; + private PlayerEntity player2; + + @BeforeEach + void setUp() { + country = new CountryEntity(); + country.setId(1); + country.setName("US"); + + user1 = new UserEntity(); + user1.setUsername("alice"); + user1.setEmail("alice@example.com"); + setField(user1, "id", 1L); + + player1 = new PlayerEntity(); + player1.setId(1); + player1.setUser(user1); + player1.setRating(1500); + player1.setRu(100); + player1.setGamesPlayed(10); + player1.setCountry(country); + + user2 = new UserEntity(); + user2.setUsername("bob"); + user2.setEmail("bob@example.com"); + setField(user2, "id", 2L); + + player2 = new PlayerEntity(); + player2.setId(2); + player2.setUser(user2); + player2.setRating(1200); + player2.setRu(50); + player2.setGamesPlayed(5); + player2.setCountry(country); + } + + // --- getByUsername --- + + @Test + void getByUsername_found_returnsMatchingPlayer() { + when(userJpaRepository.findByUsername("alice")).thenReturn(Optional.of(user1)); + when(playerJpaRepository.findByUser_Id(1L)).thenReturn(Optional.of(player1)); + + PlayerResponse response = playerService.getByUsername("alice"); + + assertThat(response.id()).isEqualTo(1); + assertThat(response.username()).isEqualTo("alice"); + assertThat(response.email()).isEqualTo("alice@example.com"); + assertThat(response.countryId()).isEqualTo(1); + } + + @Test + void getByUsername_notFound_throws404() { + when(userJpaRepository.findByUsername("unknown")).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> playerService.getByUsername("unknown")) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("not found"); + } + + // --- getById --- + + @Test + void getById_found_returnsMatchingPlayer() { + when(playerJpaRepository.findById(1)).thenReturn(Optional.of(player1)); + + PlayerResponse response = playerService.getById(1); + + assertThat(response.id()).isEqualTo(1); + assertThat(response.username()).isEqualTo("alice"); + } + + @Test + void getById_notFound_throws404() { + when(playerJpaRepository.findById(99)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> playerService.getById(99)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("not found"); + } + + // --- getByCountryId --- + + @Test + void getByCountryId_returnsPlayersFromCountry() { + when(playerJpaRepository.findByCountryName("US")).thenReturn(List.of(player1, player2)); + + List responses = playerService.getByCountryName("US"); + + assertThat(responses).hasSize(2); + assertThat(responses).extracting(PlayerResponse::countryId).containsOnly(1); + assertThat(responses).extracting(PlayerResponse::username).containsExactly("alice", "bob"); + } + + @Test + void getByCountryId_noPlayersInCountry_returnsEmptyList() { + when(playerJpaRepository.findByCountryName("XX")).thenReturn(List.of()); + + List responses = playerService.getByCountryName("XX"); + + assertThat(responses).isEmpty(); + } + + // --- getAll --- + + @Test + void getAll_returnsAllPlayers() { + when(playerJpaRepository.findAll()).thenReturn(List.of(player1, player2)); + + List responses = playerService.getAll(); + + assertThat(responses).hasSize(2); + assertThat(responses).extracting(PlayerResponse::username).containsExactly("alice", "bob"); + } + + @Test + void getAll_noPlayers_returnsEmptyList() { + when(playerJpaRepository.findAll()).thenReturn(List.of()); + + List responses = playerService.getAll(); + + assertThat(responses).isEmpty(); + } + + // --- deleteById --- + + @Test + void deleteById_found_deletesPlayer() { + when(playerJpaRepository.existsById(1)).thenReturn(true); + when(matchJpaRepository.findByGoldPlayer_Id(1)).thenReturn(List.of()); + when(matchJpaRepository.findBySilverPlayer_Id(1)).thenReturn(List.of()); + + playerService.deleteById(1); + + verify(playerJpaRepository).deleteById(1); + } + + @Test + void deleteById_hasMatches_throws400() { + when(playerJpaRepository.existsById(1)).thenReturn(true); + when(matchJpaRepository.findByGoldPlayer_Id(1)).thenReturn(List.of(new com.example.arimaabackend.model.sql.MatchEntity())); + + assertThatThrownBy(() -> playerService.deleteById(1)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("Cannot delete player with matches"); + + verify(playerJpaRepository, never()).deleteById(any()); + } + + @Test + void deleteById_notFound_throws404() { + when(playerJpaRepository.existsById(99)).thenReturn(false); + + assertThatThrownBy(() -> playerService.deleteById(99)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("99"); + + verify(playerJpaRepository, never()).deleteById(any()); + } + + // --- create --- + + @Test + void create_validRequest_createsPlayer() { + PlayerCreateRequest request = new PlayerCreateRequest(2L, 1600, 150, 20, 1, null); + + when(userJpaRepository.findById(2L)).thenReturn(Optional.of(user2)); + when(playerJpaRepository.findByUser_Id(2L)).thenReturn(Optional.empty()); + when(countryJpaRepository.findById(1)).thenReturn(Optional.of(country)); + when(playerJpaRepository.save(any(PlayerEntity.class))).thenAnswer(invocation -> invocation.getArgument(0)); + + PlayerResponse response = playerService.create(request); + + assertThat(response.username()).isEqualTo("bob"); + assertThat(response.rating()).isEqualTo(1600); + assertThat(response.countryId()).isEqualTo(1); + verify(playerJpaRepository).save(any(PlayerEntity.class)); + } + + @Test + void create_userNotFound_throws404() { + PlayerCreateRequest request = new PlayerCreateRequest(99L, 1200, 0, 0, 1, null); + when(userJpaRepository.findById(99L)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> playerService.create(request)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("User 99 not found"); + } + + @Test + void create_playerAlreadyExists_throws409() { + PlayerCreateRequest request = new PlayerCreateRequest(1L, 1200, 0, 0, 1, null); + when(userJpaRepository.findById(1L)).thenReturn(Optional.of(user1)); + when(playerJpaRepository.findByUser_Id(1L)).thenReturn(Optional.of(player1)); + + assertThatThrownBy(() -> playerService.create(request)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("already exists"); + } + + @Test + void create_countryNotFound_throws404() { + PlayerCreateRequest request = new PlayerCreateRequest(2L, 1200, 0, 0, 99, null); + when(userJpaRepository.findById(2L)).thenReturn(Optional.of(user2)); + when(playerJpaRepository.findByUser_Id(2L)).thenReturn(Optional.empty()); + when(countryJpaRepository.findById(99)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> playerService.create(request)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("Country 99 not found"); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/UserDetailsServiceImplTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/UserDetailsServiceImplTest.java new file mode 100644 index 000000000..0c822a7ac --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/UserDetailsServiceImplTest.java @@ -0,0 +1,65 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.enums.UserRole; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import com.example.arimaabackend.security.UserDetailsServiceImpl; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class UserDetailsServiceImplTest { + + @Mock + private UserJpaRepository userJpaRepository; + + @InjectMocks + private UserDetailsServiceImpl userDetailsService; + + @Test + void loadUserByUsername_returnsUserDetails_withUserRole() { + var entity = new UserEntity(); + entity.setUsername("alice"); + entity.setPasswordHash("$2a$hashed"); + entity.setRole(UserRole.USER); + when(userJpaRepository.findByUsername("alice")).thenReturn(Optional.of(entity)); + + var details = userDetailsService.loadUserByUsername("alice"); + + assertThat(details.getUsername()).isEqualTo("alice"); + assertThat(details.getPassword()).isEqualTo("$2a$hashed"); + assertThat(details.getAuthorities()).extracting("authority").containsExactly("ROLE_USER"); + } + + @Test + void loadUserByUsername_returnsUserDetails_withAdminRole() { + var entity = new UserEntity(); + entity.setUsername("bob"); + entity.setPasswordHash("$2a$adminhash"); + entity.setRole(UserRole.ADMIN); + when(userJpaRepository.findByUsername("bob")).thenReturn(Optional.of(entity)); + + var details = userDetailsService.loadUserByUsername("bob"); + + assertThat(details.getAuthorities()).extracting("authority").containsExactly("ROLE_ADMIN"); + } + + @Test + void loadUserByUsername_throwsUsernameNotFoundException_whenNotFound() { + when(userJpaRepository.findByUsername("unknown")).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> userDetailsService.loadUserByUsername("unknown")) + .isInstanceOf(UsernameNotFoundException.class) + .hasMessageContaining("unknown"); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/UserServiceImplTest.java b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/UserServiceImplTest.java new file mode 100644 index 000000000..e909e82aa --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/java/com/example/arimaabackend/unittests/UserServiceImplTest.java @@ -0,0 +1,117 @@ +package com.example.arimaabackend.unittests; + +import com.example.arimaabackend.dto.UserCreateRequest; +import com.example.arimaabackend.enums.UserRole; +import com.example.arimaabackend.model.sql.UserEntity; +import com.example.arimaabackend.repository.sql.UserJpaRepository; +import com.example.arimaabackend.services.UserServiceImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.server.ResponseStatusException; + +import java.time.Instant; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class UserServiceImplTest { + + @Mock + private UserJpaRepository userJpaRepository; + + @Mock + private PasswordEncoder passwordEncoder; + + @InjectMocks + private UserServiceImpl userService; + + private UserEntity savedEntity; + + @BeforeEach + void setUp() { + savedEntity = new UserEntity(); + savedEntity.setUsername("alice"); + savedEntity.setEmail("alice@example.com"); + savedEntity.setPasswordHash("$2a$hashed"); + savedEntity.setRole(UserRole.USER); + // simulate @PrePersist + var now = Instant.now(); + try { + var createdAt = UserEntity.class.getDeclaredField("createdAt"); + createdAt.setAccessible(true); + createdAt.set(savedEntity, now); + var updatedAt = UserEntity.class.getDeclaredField("updatedAt"); + updatedAt.setAccessible(true); + updatedAt.set(savedEntity, now); + var id = UserEntity.class.getDeclaredField("id"); + id.setAccessible(true); + id.set(savedEntity, 1L); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + void create_hashesPasswordAndDefaultsRoleToUser() { + when(passwordEncoder.encode("secret123")).thenReturn("$2a$hashed"); + when(userJpaRepository.save(any(UserEntity.class))).thenReturn(savedEntity); + + var request = new UserCreateRequest("alice", "alice@example.com", "secret123"); + var response = userService.create(request); + + assertThat(response.username()).isEqualTo("alice"); + assertThat(response.email()).isEqualTo("alice@example.com"); + assertThat(response.role()).isEqualTo("USER"); + verify(passwordEncoder).encode("secret123"); + } + + @Test + void getById_returnsUser_whenFound() { + when(userJpaRepository.findById(1L)).thenReturn(Optional.of(savedEntity)); + + var response = userService.getById(1L); + + assertThat(response.id()).isEqualTo(1L); + assertThat(response.username()).isEqualTo("alice"); + } + + @Test + void getById_throws404_whenNotFound() { + when(userJpaRepository.findById(99L)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> userService.getById(99L)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("99"); + } + + @Test + void deleteById_deletesUser_whenFound() { + when(userJpaRepository.existsById(1L)).thenReturn(true); + + userService.deleteById(1L); + + verify(userJpaRepository).deleteById(1L); + } + + @Test + void deleteById_throws404_whenNotFound() { + when(userJpaRepository.existsById(99L)).thenReturn(false); + + assertThatThrownBy(() -> userService.deleteById(99L)) + .isInstanceOf(ResponseStatusException.class) + .hasMessageContaining("99"); + + verify(userJpaRepository, never()).deleteById(any()); + } +} diff --git a/jdk_21_maven/cs/rest/arimaa/src/test/resources/application.properties b/jdk_21_maven/cs/rest/arimaa/src/test/resources/application.properties new file mode 100644 index 000000000..f4569bbc5 --- /dev/null +++ b/jdk_21_maven/cs/rest/arimaa/src/test/resources/application.properties @@ -0,0 +1,13 @@ +spring.docker.compose.enabled=false +spring.autoconfigure.exclude=\ + org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ + org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ + org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ + org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\ + org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ + org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration +spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect