From 03d5a133eb1e6f8b3825a0dd1bbc13ccdeb1289b Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Sat, 24 May 2025 15:32:27 +0200
Subject: [PATCH 01/47] Close sqlite pool before erroring
---
.../src/backend/fs_backend/error.rs | 5 +-
.../src/backend/fs_backend/manager.rs | 10 +-
.../client/base_client/non_wasm_helpers.rs | 100 +++++++++++++-----
common/client-core/surb-storage/Cargo.toml | 8 +-
.../src/backend/fs_backend/error.rs | 5 +-
.../src/backend/fs_backend/manager.rs | 8 +-
.../src/backend/fs_backend/mod.rs | 81 ++++++++------
.../src/persistent_storage/mod.rs | 1 +
common/gateway-stats-storage/src/lib.rs | 1 +
common/gateway-storage/src/lib.rs | 1 +
10 files changed, 147 insertions(+), 73 deletions(-)
diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs
index bdcaa0fdb5..59b7bef89d 100644
--- a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs
+++ b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs
@@ -2,8 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::BadGateway;
-use std::io;
-use std::path::PathBuf;
+use std::{io, path::PathBuf};
use thiserror::Error;
#[derive(Debug, Error)]
@@ -19,7 +18,6 @@ pub enum StorageError {
#[error("failed to perform sqlx migration: {source}")]
MigrationError {
- #[source]
#[from]
source: sqlx::migrate::MigrateError,
},
@@ -32,7 +30,6 @@ pub enum StorageError {
#[error("failed to run the SQL query: {source}")]
QueryError {
- #[source]
#[from]
source: sqlx::error::Error,
},
diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs
index 101a6a8710..0b7aafdb28 100644
--- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs
+++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs
@@ -47,12 +47,14 @@ impl StorageManager {
StorageError::DatabaseConnectionError { source }
})?;
- sqlx::migrate!("./fs_gateways_migrations")
+ if let Err(err) = sqlx::migrate!("./fs_gateways_migrations")
.run(&connection_pool)
.await
- .inspect_err(|err| {
- error!("Failed to initialize SQLx database: {err}");
- })?;
+ {
+ error!("Failed to initialize SQLx database: {err}");
+ connection_pool.close().await;
+ return Err(err)?;
+ }
debug!("Database migration finished!");
Ok(StorageManager { connection_pool })
diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs
index e7ef621c9d..4f3a2c0c77 100644
--- a/common/client-core/src/client/base_client/non_wasm_helpers.rs
+++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs
@@ -1,20 +1,22 @@
// Copyright 2022-2024 - Nym Technologies SA
// SPDX-License-Identifier: Apache-2.0
-use crate::client::replies::reply_storage::{
- fs_backend, CombinedReplyStorage, ReplyStorageBackend,
+use crate::{
+ client::replies::reply_storage::{fs_backend, CombinedReplyStorage, ReplyStorageBackend},
+ config,
+ config::Config,
+ error::ClientCoreError,
};
-use crate::config;
-use crate::config::Config;
-use crate::error::ClientCoreError;
+#[cfg(windows)]
+use log::debug;
use log::{error, info, trace};
use nym_bandwidth_controller::BandwidthController;
use nym_client_core_gateways_storage::OnDiskGatewaysDetails;
use nym_credential_storage::storage::Storage as CredentialStorage;
-use nym_validator_client::nyxd;
-use nym_validator_client::QueryHttpRpcNyxdClient;
-use std::path::Path;
-use std::{fs, io};
+use nym_validator_client::{nyxd, QueryHttpRpcNyxdClient};
+#[cfg(windows)]
+use std::time::Duration;
+use std::{io, path::Path};
use time::OffsetDateTime;
use url::Url;
@@ -22,11 +24,14 @@ async fn setup_fresh_backend>(
db_path: P,
surb_config: &config::ReplySurbs,
) -> Result {
- info!("creating fresh surb database");
+ info!(
+ "creating fresh surb database: {}",
+ db_path.as_ref().display()
+ );
let mut storage_backend = match fs_backend::Backend::init(db_path).await {
Ok(backend) => backend,
Err(err) => {
- error!("failed to setup persistent storage backend for our reply needs: {err}");
+ error!("setup_fresh_backend: Failed to setup persistent storage backend for our reply needs: {err}");
return Err(ClientCoreError::SurbStorageError {
source: Box::new(err),
});
@@ -40,14 +45,15 @@ async fn setup_fresh_backend>(
surb_config.minimum_reply_surb_storage_threshold,
surb_config.maximum_reply_surb_storage_threshold,
);
- storage_backend
- .init_fresh(&mem_store)
- .await
- .map_err(|err| ClientCoreError::SurbStorageError {
- source: Box::new(err),
- })?;
-
- Ok(storage_backend)
+ match storage_backend.init_fresh(&mem_store).await {
+ Ok(()) => Ok(storage_backend),
+ Err(err) => {
+ storage_backend.shutdown().await;
+ Err(ClientCoreError::SurbStorageError {
+ source: Box::new(err),
+ })
+ }
+ }
}
// fn setup_inactive_backend(surb_config: &config::ReplySurbs) -> fs_backend::Backend {
@@ -58,12 +64,11 @@ async fn setup_fresh_backend>(
// )
// }
-fn archive_corrupted_database>(db_path: P) -> io::Result<()> {
+async fn archive_corrupted_database>(db_path: P) -> io::Result<()> {
let db_path = db_path.as_ref();
debug_assert!(db_path.exists());
let now = OffsetDateTime::now_utc().unix_timestamp();
-
let suffix = format!("_{now}.corrupted");
let new_extension =
@@ -72,11 +77,51 @@ fn archive_corrupted_database>(db_path: P) -> io::Result<()> {
} else {
suffix
};
+ let renamed = db_path.with_extension(new_extension);
- let mut renamed = db_path.to_owned();
- renamed.set_extension(new_extension);
+ rename_db_file(&db_path, &renamed).await.inspect_err(|_| {
+ tracing::error!(
+ "Failed to rename corrupt database file: {} to {}",
+ db_path.display(),
+ renamed.display()
+ );
+ })
+}
- fs::rename(db_path, renamed)
+#[cfg(not(windows))]
+async fn rename_db_file(db_path: impl AsRef, renamed: impl AsRef) -> io::Result<()> {
+ tokio::fs::rename(db_path, &renamed).await
+}
+
+#[cfg(windows)]
+async fn rename_db_file(db_path: impl AsRef, renamed: impl AsRef) -> io::Result<()> {
+ // Due to bug in sqlx (https://github.com/launchbadge/sqlx/issues/3217),
+ // the sqlite file can be still in use after closing sqlite connection pool
+ // Poll for a bit until the db file is released.
+
+ // Max number of retries
+ const MAX_RETRY_ATTEMPTS: u32 = 10;
+ // Delay between retries
+ const WAIT_DELAY: Duration = Duration::from_millis(100);
+ // Error code returned when file is still in use.
+ const FILE_IN_USE_ERR: i32 = 32;
+
+ let mut retry_attempt = 0;
+ while let Err(e) = tokio::fs::rename(db_path.as_ref(), renamed.as_ref()).await {
+ retry_attempt += 1;
+
+ if e.raw_os_error() == Some(FILE_IN_USE_ERR) && retry_attempt < MAX_RETRY_ATTEMPTS {
+ debug!(
+ "File {} is still open. Sleep and retry",
+ db_path.as_ref().display()
+ );
+ tokio::time::sleep(WAIT_DELAY).await;
+ } else {
+ return Err(e);
+ }
+ }
+
+ Ok(())
}
pub async fn setup_fs_reply_surb_backend>(
@@ -87,13 +132,12 @@ pub async fn setup_fs_reply_surb_backend>(
// the existing one
let db_path = db_path.as_ref();
if db_path.exists() {
- info!("loading existing surb database");
+ info!("Loading existing surb database: {}", db_path.display());
match fs_backend::Backend::try_load(db_path, surb_config.fresh_sender_tags).await {
Ok(backend) => Ok(backend),
Err(err) => {
- error!("failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future");
-
- archive_corrupted_database(db_path)?;
+ error!("setup_fs_reply_surb_backend: Failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future");
+ archive_corrupted_database(db_path).await?;
setup_fresh_backend(db_path, surb_config).await
}
}
diff --git a/common/client-core/surb-storage/Cargo.toml b/common/client-core/surb-storage/Cargo.toml
index 7a902bef94..49dfbe4b8c 100644
--- a/common/client-core/surb-storage/Cargo.toml
+++ b/common/client-core/surb-storage/Cargo.toml
@@ -12,6 +12,7 @@ dashmap.workspace = true
log.workspace = true
thiserror.workspace = true
time.workspace = true
+tokio = { workspace = true, features = ["fs"] }
nym-crypto = { path = "../../crypto", optional = true, default-features = false }
nym-sphinx = { path = "../../nymsphinx" }
@@ -25,7 +26,12 @@ optional = true
[build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
-sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
+sqlx = { workspace = true, features = [
+ "runtime-tokio-rustls",
+ "sqlite",
+ "macros",
+ "migrate",
+] }
[features]
fs-surb-storage = ["sqlx", "nym-crypto", "nym-crypto/hashing"]
diff --git a/common/client-core/surb-storage/src/backend/fs_backend/error.rs b/common/client-core/surb-storage/src/backend/fs_backend/error.rs
index 02742758ae..e1eb9036da 100644
--- a/common/client-core/surb-storage/src/backend/fs_backend/error.rs
+++ b/common/client-core/surb-storage/src/backend/fs_backend/error.rs
@@ -1,8 +1,7 @@
// Copyright 2022 - Nym Technologies SA
// SPDX-License-Identifier: Apache-2.0
-use std::io;
-use std::path::PathBuf;
+use std::{io, path::PathBuf};
use thiserror::Error;
#[derive(Debug, Error)]
@@ -30,7 +29,6 @@ pub enum StorageError {
#[error("failed to perform sqlx migration: {source}")]
MigrationError {
- #[source]
#[from]
source: sqlx::migrate::MigrateError,
},
@@ -43,7 +41,6 @@ pub enum StorageError {
#[error("failed to run the SQL query: {source}")]
QueryError {
- #[source]
#[from]
source: sqlx::error::Error,
},
diff --git a/common/client-core/surb-storage/src/backend/fs_backend/manager.rs b/common/client-core/surb-storage/src/backend/fs_backend/manager.rs
index 02316ddb7f..3daa4744a4 100644
--- a/common/client-core/surb-storage/src/backend/fs_backend/manager.rs
+++ b/common/client-core/surb-storage/src/backend/fs_backend/manager.rs
@@ -17,7 +17,7 @@ use std::path::Path;
#[derive(Debug, Clone)]
pub struct StorageManager {
- pub connection_pool: sqlx::SqlitePool,
+ connection_pool: sqlx::SqlitePool,
}
// all SQL goes here
@@ -54,6 +54,7 @@ impl StorageManager {
.await
{
error!("Failed to initialize SQLx database: {err}");
+ connection_pool.close().await;
return Err(err.into());
}
@@ -61,6 +62,11 @@ impl StorageManager {
Ok(StorageManager { connection_pool })
}
+ /// Close connection pool waiting for all connections to be closed.
+ pub async fn close_pool(&self) {
+ self.connection_pool.close().await;
+ }
+
#[allow(dead_code)]
pub async fn status_table_exists(&self) -> Result {
sqlx::query!("SELECT name FROM sqlite_master WHERE type='table' AND name='status'")
diff --git a/common/client-core/surb-storage/src/backend/fs_backend/mod.rs b/common/client-core/surb-storage/src/backend/fs_backend/mod.rs
index 4467e17538..1f7e9bc198 100644
--- a/common/client-core/surb-storage/src/backend/fs_backend/mod.rs
+++ b/common/client-core/surb-storage/src/backend/fs_backend/mod.rs
@@ -1,18 +1,21 @@
// Copyright 2022 - Nym Technologies SA
// SPDX-License-Identifier: Apache-2.0
-use crate::backend::fs_backend::manager::StorageManager;
-use crate::backend::fs_backend::models::{
- ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender,
-};
-use crate::surb_storage::ReceivedReplySurbs;
use crate::{
- CombinedReplyStorage, ReceivedReplySurbsMap, ReplyStorageBackend, SentReplyKeys, UsedSenderTags,
+ backend::fs_backend::{
+ manager::StorageManager,
+ models::{
+ ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag,
+ StoredSurbSender,
+ },
+ },
+ surb_storage::ReceivedReplySurbs,
+ CombinedReplyStorage, ReceivedReplySurbsMap, ReplyStorageBackend, SentReplyKeys,
+ UsedSenderTags,
};
use async_trait::async_trait;
use log::{debug, error, info, warn};
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
-use std::fs;
use std::path::{Path, PathBuf};
use time::OffsetDateTime;
@@ -41,15 +44,17 @@ impl Backend {
}
let manager = StorageManager::init(database_path, true).await?;
- manager.create_status_table().await?;
-
- let backend = Backend {
- temporary_old_path: None,
- database_path: owned_path,
- manager,
- };
-
- Ok(backend)
+ match manager.create_status_table().await {
+ Ok(()) => Ok(Backend {
+ temporary_old_path: None,
+ database_path: owned_path,
+ manager,
+ }),
+ Err(err) => {
+ manager.close_pool().await;
+ Err(err.into())
+ }
+ }
}
pub async fn try_load>(
@@ -64,7 +69,28 @@ impl Backend {
}
let manager = StorageManager::init(database_path, false).await?;
+ match Self::try_load_inner(&manager, fresh_sender_tags).await {
+ Ok(()) => Ok(Backend {
+ temporary_old_path: None,
+ database_path: owned_path,
+ manager,
+ }),
+ Err(e) => {
+ manager.close_pool().await;
+ Err(e)
+ }
+ }
+ }
+ /// Gracefully close sqlite connection pool and drop backend.
+ pub async fn shutdown(self) {
+ self.manager.close_pool().await
+ }
+
+ async fn try_load_inner(
+ manager: &StorageManager,
+ fresh_sender_tags: bool,
+ ) -> Result<(), StorageError> {
// the database flush wasn't fully finished and thus the data is in inconsistent state
// (we don't really know what's properly saved or what's not)
if manager.get_flush_status().await? {
@@ -126,20 +152,11 @@ impl Backend {
manager.delete_all_tags().await?;
}
- Ok(Backend {
- temporary_old_path: None,
- database_path: owned_path,
- // manager: StorageManagerState::Storage(manager),
- manager,
- })
- }
-
- async fn close_pool(&mut self) {
- self.manager.connection_pool.close().await;
+ Ok(())
}
async fn rotate(&mut self) -> Result<(), StorageError> {
- self.close_pool().await;
+ self.manager.close_pool().await;
let new_extension = if let Some(existing_extension) =
self.database_path.extension().and_then(|ext| ext.to_str())
@@ -152,7 +169,8 @@ impl Backend {
let mut temp_old = self.database_path.clone();
temp_old.set_extension(new_extension);
- fs::rename(&self.database_path, &temp_old)
+ tokio::fs::rename(&self.database_path, &temp_old)
+ .await
.map_err(|err| StorageError::DatabaseRenameError { source: err })?;
self.manager = StorageManager::init(&self.database_path, true).await?;
self.manager.create_status_table().await?;
@@ -161,9 +179,10 @@ impl Backend {
Ok(())
}
- fn remove_old(&mut self) -> Result<(), StorageError> {
+ async fn remove_old(&mut self) -> Result<(), StorageError> {
if let Some(old_path) = self.temporary_old_path.take() {
- fs::remove_file(old_path)
+ tokio::fs::remove_file(old_path)
+ .await
.map_err(|err| StorageError::DatabaseOldFileRemoveError { source: err })
} else {
warn!("the old database file doesn't seem to exist!");
@@ -335,7 +354,7 @@ impl ReplyStorageBackend for Backend {
self.dump_reply_surb_storage_metadata(surbs_ref).await?;
self.dump_reply_surbs(surbs_ref).await?;
- self.remove_old()?;
+ self.remove_old().await?;
self.end_storage_flush().await
}
diff --git a/common/credential-storage/src/persistent_storage/mod.rs b/common/credential-storage/src/persistent_storage/mod.rs
index 565ab94513..bccbccf4ab 100644
--- a/common/credential-storage/src/persistent_storage/mod.rs
+++ b/common/credential-storage/src/persistent_storage/mod.rs
@@ -76,6 +76,7 @@ impl PersistentStorage {
if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
+ connection_pool.close().await;
return Err(err.into());
}
diff --git a/common/gateway-stats-storage/src/lib.rs b/common/gateway-stats-storage/src/lib.rs
index 8ad34bbca4..10aa61062d 100644
--- a/common/gateway-stats-storage/src/lib.rs
+++ b/common/gateway-stats-storage/src/lib.rs
@@ -59,6 +59,7 @@ impl PersistentStatsStorage {
if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
+ connection_pool.close().await;
return Err(err.into());
}
diff --git a/common/gateway-storage/src/lib.rs b/common/gateway-storage/src/lib.rs
index 2d05d43fe7..1d91576ccb 100644
--- a/common/gateway-storage/src/lib.rs
+++ b/common/gateway-storage/src/lib.rs
@@ -108,6 +108,7 @@ impl GatewayStorage {
if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
+ connection_pool.close().await;
return Err(err.into());
}
From a215b3d0bf409e13b0483bbb0fc26015a7dae783 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Wed, 28 May 2025 21:04:40 +0200
Subject: [PATCH 02/47] Open file watch
---
Cargo.lock | 19 ++++
Cargo.toml | 3 +-
sqlx-pool-guard/Cargo.toml | 16 +++
sqlx-pool-guard/src/lib.rs | 201 +++++++++++++++++++++++++++++++++++++
4 files changed, 238 insertions(+), 1 deletion(-)
create mode 100644 sqlx-pool-guard/Cargo.toml
create mode 100644 sqlx-pool-guard/src/lib.rs
diff --git a/Cargo.lock b/Cargo.lock
index 4cad468c66..13a80c207b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7954,6 +7954,15 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "proc_pidinfo"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1724fdb3f7349e4c58806dfb29dbc3b5e2f8b0997bb5117acf8db6e555867a91"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "prometheus"
version = "0.14.0"
@@ -9525,6 +9534,16 @@ dependencies = [
"whoami",
]
+[[package]]
+name = "sqlx-pool-guard"
+version = "0.1.0"
+dependencies = [
+ "log",
+ "proc_pidinfo",
+ "sqlx",
+ "tokio",
+]
+
[[package]]
name = "sqlx-postgres"
version = "0.8.6"
diff --git a/Cargo.toml b/Cargo.toml
index c2f5b97078..e15ac95c90 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -124,7 +124,7 @@ members = [
"service-providers/authenticator",
"service-providers/common",
"service-providers/ip-packet-router",
- "service-providers/network-requester",
+ "service-providers/network-requester", "sqlx-pool-guard",
"tools/echo-server",
"tools/internal/contract-state-importer/importer-cli",
"tools/internal/contract-state-importer/importer-contract",
@@ -286,6 +286,7 @@ petgraph = "0.6.5"
pin-project = "1.1"
pin-project-lite = "0.2.16"
publicsuffix = "2.3.0"
+proc_pidinfo = "0.1"
quote = "1"
rand = "0.8.5"
rand_chacha = "0.3"
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
new file mode 100644
index 0000000000..ee60690b4d
--- /dev/null
+++ b/sqlx-pool-guard/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "sqlx-pool-guard"
+version = "0.1.0"
+edition = "2024"
+license.workspace = true
+
+[lints]
+workspace = true
+
+[dependencies]
+tokio = { workspace = true, features = ["rt-multi-thread", "macros", "time", "fs"] }
+sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite"] }
+log.workspace = true
+
+[target.'cfg(target_os = "macos")'.dependencies]
+proc_pidinfo.workspace = true
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
new file mode 100644
index 0000000000..05a933fe5f
--- /dev/null
+++ b/sqlx-pool-guard/src/lib.rs
@@ -0,0 +1,201 @@
+// Copyright 2025 - Nym Technologies SA
+// SPDX-License-Identifier: Apache-2.0
+
+use std::{
+ io,
+ ops::{Deref, DerefMut},
+ path::{Path, PathBuf},
+ time::Duration,
+};
+
+#[cfg(target_os = "macos")]
+use proc_pidinfo::{
+ ProcFDInfo, ProcFDType, VnodeFdInfoWithPath, proc_pidfdinfo_self, proc_pidinfo_list_self,
+};
+
+const SQL_CLOSE_MAX_ATTEMPTS: u8 = 10;
+const SQL_CLOSE_RETRY_DELAY: Duration = Duration::from_millis(100);
+
+pub struct SqlitePoolGuard {
+ database_path: PathBuf,
+ connection_pool: sqlx::SqlitePool,
+}
+
+impl Deref for SqlitePoolGuard {
+ type Target = sqlx::SqlitePool;
+ fn deref(&self) -> &Self::Target {
+ &self.connection_pool
+ }
+}
+
+impl DerefMut for SqlitePoolGuard {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.connection_pool
+ }
+}
+
+impl SqlitePoolGuard {
+ pub fn new(database_path: PathBuf, connection_pool: sqlx::SqlitePool) -> Self {
+ Self {
+ database_path,
+ connection_pool,
+ }
+ }
+
+ /// Close udnerlying sqlite pool
+ pub async fn close_pool(&self) {
+ _ = self.close_pool_inner();
+ }
+
+ async fn close_pool_inner(&self) -> std::io::Result<()> {
+ self.connection_pool.close().await;
+
+ #[cfg(target_os = "macos")]
+ if let Err(e) = self.wait_io_close().await {
+ log::error!("Failed to wait for file to close: {e}");
+ }
+
+ Ok(())
+ }
+
+ /// Returns all database files, including shm and wal files.
+ fn all_database_files(&self) -> Vec {
+ let mut database_files = vec![];
+ let canonical_path = self
+ .database_path
+ .canonicalize()
+ .inspect_err(|e| {
+ log::error!(
+ "Failed to canonicalize path: {}. Cause: {e}",
+ self.database_path.display()
+ );
+ })
+ .unwrap_or(self.database_path.clone());
+
+ if let Some(ext) = canonical_path.extension() {
+ for added_ext in ["-shm", "-wal"] {
+ let mut new_ext = ext.to_owned();
+ new_ext.push(added_ext);
+ database_files.push(canonical_path.with_extension(new_ext));
+ }
+ }
+ database_files.push(canonical_path);
+ database_files
+ }
+
+ /// Wait for I/O close to the database files
+ async fn wait_io_close(&self) -> std::io::Result<()> {
+ let database_files = self.all_database_files();
+ let paths: Vec<&Path> = database_files.iter().map(PathBuf::as_path).collect();
+
+ for _ in 0..SQL_CLOSE_MAX_ATTEMPTS {
+ match Self::check_io_close(&paths)
+ .await
+ .inspect_err(|e| log::error!("check_io_close() failure: {e}"))
+ {
+ Ok(true) | Err(_) => tokio::time::sleep(SQL_CLOSE_RETRY_DELAY).await,
+ Ok(false) => return Ok(()),
+ }
+ }
+
+ Err(io::Error::new(
+ io::ErrorKind::TimedOut,
+ "timed out waiting for sqlite files to be closed",
+ ))
+ }
+
+ /// Check if no more open file descriptors exist for the given files.
+ ///
+ /// On macOS this is done using `proc_pidinfo` (`sys/proc_info.h`)
+ /// See: http://blog.palominolabs.com/2012/06/19/getting-the-files-being-used-by-a-process-on-mac-os-x/
+ #[cfg(target_os = "macos")]
+ async fn check_io_close(file_paths: &[&Path]) -> io::Result {
+ let fd_list = proc_pidinfo_list_self::()?;
+
+ for fd in fd_list
+ .iter()
+ .filter(|s| s.fd_type() == Ok(ProcFDType::VNODE))
+ {
+ let Some(vnode) = proc_pidfdinfo_self::(fd.proc_fd)
+ .inspect_err(|e| {
+ log::warn!("proc_pidfdinfo_self::() failure: {e}");
+ })
+ .ok()
+ .flatten()
+ else {
+ continue;
+ };
+
+ if let Ok(true) = vnode
+ .path()
+ .map(|vnode_path| file_paths.contains(&vnode_path))
+ .inspect_err(|e| {
+ log::warn!("vnode.path() failure: {e:?}");
+ })
+ {
+ return Ok(true);
+ }
+ }
+
+ Ok(false)
+ }
+
+ /// Check if no more open file descriptors exist for the given files.
+ #[cfg(target_os = "linux")]
+ async fn check_io_close(file_paths: &[&Path]) -> io::Result {
+ let mut dir = tokio::fs::read_dir("/proc/self/fd/").await?;
+
+ while let Ok(Some(entry)) = dir.next_entry().await {
+ // Looking for DT_LNK
+ if entry
+ .file_type()
+ .await
+ .inspect_err(|e| log::warn!("entry.file_type() failure: {e}"))
+ .is_ok_and(|entry_type| entry_type.is_symlink())
+ {
+ // atoi(d->d_name) to obtain open fd?
+ let path = PathBuf::from(entry.file_name());
+ if file_paths.contains(&path.as_ref()) {
+ return Ok(true);
+ }
+ }
+ }
+
+ Ok(false)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use sqlx::{
+ ConnectOptions,
+ sqlite::{SqliteAutoVacuum, SqliteSynchronous},
+ };
+
+ use super::*;
+
+ #[tokio::test]
+ async fn test_wait_close() {
+ let database_path = PathBuf::from("/tmp/storage.sqlite");
+ let opts = sqlx::sqlite::SqliteConnectOptions::new()
+ .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
+ .synchronous(SqliteSynchronous::Normal)
+ .auto_vacuum(SqliteAutoVacuum::Incremental)
+ .filename(database_path.clone())
+ .create_if_missing(true)
+ .disable_statement_logging();
+ let connection_pool = sqlx::SqlitePool::connect_with(opts).await.unwrap();
+
+ let guard = SqlitePoolGuard::new(database_path, connection_pool);
+
+ assert!(
+ guard
+ .wait_io_close()
+ .await
+ .err()
+ .is_some_and(|e| e.kind() == io::ErrorKind::TimedOut)
+ );
+
+ assert!(guard.close_pool_inner().await.is_ok());
+ }
+}
From 548b8717b2b2ada5679389e3a8078c44e6c80f43 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 29 May 2025 11:13:57 +0200
Subject: [PATCH 03/47] Update Linux impl
---
Cargo.lock | 1 +
sqlx-pool-guard/Cargo.toml | 3 +++
sqlx-pool-guard/src/lib.rs | 30 ++++++++++++++++++------------
3 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 13a80c207b..3a13a133f4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9541,6 +9541,7 @@ dependencies = [
"log",
"proc_pidinfo",
"sqlx",
+ "tempfile",
"tokio",
]
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
index ee60690b4d..e0b4452d3c 100644
--- a/sqlx-pool-guard/Cargo.toml
+++ b/sqlx-pool-guard/Cargo.toml
@@ -14,3 +14,6 @@ log.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
proc_pidinfo.workspace = true
+
+[dev-dependencies]
+tempfile = { workspace = true }
\ No newline at end of file
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index 05a933fe5f..eb7f0ea568 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -50,7 +50,6 @@ impl SqlitePoolGuard {
async fn close_pool_inner(&self) -> std::io::Result<()> {
self.connection_pool.close().await;
- #[cfg(target_os = "macos")]
if let Err(e) = self.wait_io_close().await {
log::error!("Failed to wait for file to close: {e}");
}
@@ -84,6 +83,12 @@ impl SqlitePoolGuard {
}
/// Wait for I/O close to the database files
+ ///
+ /// - macOS: uses `proc_pidinfo` (`sys/proc_info.h`)
+ /// See: http://blog.palominolabs.com/2012/06/19/getting-the-files-being-used-by-a-process-on-mac-os-x/
+ ///
+ /// - Linux, Android: uses `/proc/self/fd/` to list open file descriptors
+ /// See: https://stackoverflow.com/a/59797198/351305
async fn wait_io_close(&self) -> std::io::Result<()> {
let database_files = self.all_database_files();
let paths: Vec<&Path> = database_files.iter().map(PathBuf::as_path).collect();
@@ -105,9 +110,6 @@ impl SqlitePoolGuard {
}
/// Check if no more open file descriptors exist for the given files.
- ///
- /// On macOS this is done using `proc_pidinfo` (`sys/proc_info.h`)
- /// See: http://blog.palominolabs.com/2012/06/19/getting-the-files-being-used-by-a-process-on-mac-os-x/
#[cfg(target_os = "macos")]
async fn check_io_close(file_paths: &[&Path]) -> io::Result {
let fd_list = proc_pidinfo_list_self::()?;
@@ -141,22 +143,26 @@ impl SqlitePoolGuard {
}
/// Check if no more open file descriptors exist for the given files.
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
async fn check_io_close(file_paths: &[&Path]) -> io::Result {
let mut dir = tokio::fs::read_dir("/proc/self/fd/").await?;
while let Ok(Some(entry)) = dir.next_entry().await {
- // Looking for DT_LNK
if entry
.file_type()
.await
.inspect_err(|e| log::warn!("entry.file_type() failure: {e}"))
.is_ok_and(|entry_type| entry_type.is_symlink())
{
- // atoi(d->d_name) to obtain open fd?
- let path = PathBuf::from(entry.file_name());
- if file_paths.contains(&path.as_ref()) {
- return Ok(true);
+ match tokio::fs::read_link(entry.path()).await {
+ Ok(resolved_path) => {
+ if file_paths.contains(&resolved_path.as_ref()) {
+ return Ok(true);
+ }
+ }
+ Err(e) => {
+ log::error!("Failed to read symlink: {e}");
+ }
}
}
}
@@ -176,7 +182,8 @@ mod tests {
#[tokio::test]
async fn test_wait_close() {
- let database_path = PathBuf::from("/tmp/storage.sqlite");
+ let temp_dir = tempfile::tempdir().unwrap();
+ let database_path = temp_dir.path().join("storage.sqlite");
let opts = sqlx::sqlite::SqliteConnectOptions::new()
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.synchronous(SqliteSynchronous::Normal)
@@ -187,7 +194,6 @@ mod tests {
let connection_pool = sqlx::SqlitePool::connect_with(opts).await.unwrap();
let guard = SqlitePoolGuard::new(database_path, connection_pool);
-
assert!(
guard
.wait_io_close()
From 4eedbb235af4576c769e4f9ecfbf494d0bf93d33 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 29 May 2025 11:30:34 +0200
Subject: [PATCH 04/47] Add Windows implementation
---
sqlx-pool-guard/src/lib.rs | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index eb7f0ea568..b3e0f672bc 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -89,6 +89,8 @@ impl SqlitePoolGuard {
///
/// - Linux, Android: uses `/proc/self/fd/` to list open file descriptors
/// See: https://stackoverflow.com/a/59797198/351305
+ ///
+ /// - Windows: attempts to open files to detect whether they are still open.
async fn wait_io_close(&self) -> std::io::Result<()> {
let database_files = self.all_database_files();
let paths: Vec<&Path> = database_files.iter().map(PathBuf::as_path).collect();
@@ -98,8 +100,8 @@ impl SqlitePoolGuard {
.await
.inspect_err(|e| log::error!("check_io_close() failure: {e}"))
{
- Ok(true) | Err(_) => tokio::time::sleep(SQL_CLOSE_RETRY_DELAY).await,
- Ok(false) => return Ok(()),
+ Ok(false) | Err(_) => tokio::time::sleep(SQL_CLOSE_RETRY_DELAY).await,
+ Ok(true) => return Ok(()),
}
}
@@ -135,11 +137,11 @@ impl SqlitePoolGuard {
log::warn!("vnode.path() failure: {e:?}");
})
{
- return Ok(true);
+ return Ok(false);
}
}
- Ok(false)
+ Ok(true)
}
/// Check if no more open file descriptors exist for the given files.
@@ -157,7 +159,7 @@ impl SqlitePoolGuard {
match tokio::fs::read_link(entry.path()).await {
Ok(resolved_path) => {
if file_paths.contains(&resolved_path.as_ref()) {
- return Ok(true);
+ return Ok(false);
}
}
Err(e) => {
@@ -167,7 +169,29 @@ impl SqlitePoolGuard {
}
}
- Ok(false)
+ Ok(true)
+ }
+
+ #[cfg(windows)]
+ async fn check_io_close(file_paths: &[&Path]) -> io::Result {
+ // Error code returned when file is still in use.
+ const FILE_IN_USE_ERR: i32 = 32;
+
+ for file_path in file_paths {
+ if let Err(e) = tokio::fs::OpenOptions::new()
+ .read(true)
+ .open(file_path)
+ .await
+ {
+ if e.raw_os_error() == Some(FILE_IN_USE_ERR) {
+ return Ok(false);
+ } else if e.kind() != io::ErrorKind::NotFound {
+ log::error!("Failed to open file: {}", file_path.display());
+ }
+ }
+ }
+
+ Ok(true)
}
}
From c225511f951bf3f6480e16efa3d03fb50737d58b Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 29 May 2025 18:14:55 +0200
Subject: [PATCH 05/47] Add Windows impl
---
Cargo.lock | 109 +++++++++++++++++++--
sqlx-pool-guard/Cargo.toml | 19 +++-
sqlx-pool-guard/src/lib.rs | 141 +++++++-------------------
sqlx-pool-guard/src/linux.rs | 34 +++++++
sqlx-pool-guard/src/macos.rs | 41 ++++++++
sqlx-pool-guard/src/windows.rs | 174 +++++++++++++++++++++++++++++++++
6 files changed, 403 insertions(+), 115 deletions(-)
create mode 100644 sqlx-pool-guard/src/linux.rs
create mode 100644 sqlx-pool-guard/src/macos.rs
create mode 100644 sqlx-pool-guard/src/windows.rs
diff --git a/Cargo.lock b/Cargo.lock
index 3a13a133f4..01820eb102 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9543,6 +9543,7 @@ dependencies = [
"sqlx",
"tempfile",
"tokio",
+ "windows 0.61.1",
]
[[package]]
@@ -11559,6 +11560,28 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows"
+version = "0.61.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
+dependencies = [
+ "windows-collections",
+ "windows-core 0.61.2",
+ "windows-future",
+ "windows-link",
+ "windows-numerics",
+]
+
+[[package]]
+name = "windows-collections"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
+dependencies = [
+ "windows-core 0.61.2",
+]
+
[[package]]
name = "windows-core"
version = "0.52.0"
@@ -11593,6 +11616,30 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows-core"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
+dependencies = [
+ "windows-implement 0.60.0",
+ "windows-interface 0.59.1",
+ "windows-link",
+ "windows-result 0.3.4",
+ "windows-strings 0.4.2",
+]
+
+[[package]]
+name = "windows-future"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
+dependencies = [
+ "windows-core 0.61.2",
+ "windows-link",
+ "windows-threading",
+]
+
[[package]]
name = "windows-implement"
version = "0.57.0"
@@ -11615,6 +11662,17 @@ dependencies = [
"syn 2.0.98",
]
+[[package]]
+name = "windows-implement"
+version = "0.60.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.98",
+]
+
[[package]]
name = "windows-interface"
version = "0.57.0"
@@ -11638,10 +11696,31 @@ dependencies = [
]
[[package]]
-name = "windows-link"
-version = "0.1.0"
+name = "windows-interface"
+version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.98",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+
+[[package]]
+name = "windows-numerics"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
+dependencies = [
+ "windows-core 0.61.2",
+ "windows-link",
+]
[[package]]
name = "windows-registry"
@@ -11649,7 +11728,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
dependencies = [
- "windows-result 0.3.1",
+ "windows-result 0.3.4",
"windows-strings 0.3.1",
"windows-targets 0.53.0",
]
@@ -11674,9 +11753,9 @@ dependencies = [
[[package]]
name = "windows-result"
-version = "0.3.1"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
]
@@ -11700,6 +11779,15 @@ dependencies = [
"windows-link",
]
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link",
+]
+
[[package]]
name = "windows-sys"
version = "0.45.0"
@@ -11798,6 +11886,15 @@ dependencies = [
"windows_x86_64_msvc 0.53.0",
]
+[[package]]
+name = "windows-threading"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
+dependencies = [
+ "windows-link",
+]
+
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
index e0b4452d3c..a77ee80024 100644
--- a/sqlx-pool-guard/Cargo.toml
+++ b/sqlx-pool-guard/Cargo.toml
@@ -8,12 +8,27 @@ license.workspace = true
workspace = true
[dependencies]
-tokio = { workspace = true, features = ["rt-multi-thread", "macros", "time", "fs"] }
+tokio = { workspace = true, features = [
+ "rt-multi-thread",
+ "macros",
+ "time",
+ "fs",
+] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite"] }
log.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
proc_pidinfo.workspace = true
+[target.'cfg(windows)'.dependencies]
+windows = { version = "0.61", features = [
+ "Win32",
+ "Win32_System",
+ "Win32_System_Memory",
+ "Win32_System_Threading",
+ "Win32_Storage_FileSystem",
+ "Wdk_System_SystemInformation",
+] }
+
[dev-dependencies]
-tempfile = { workspace = true }
\ No newline at end of file
+tempfile = { workspace = true }
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index b3e0f672bc..8b120ee261 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -8,13 +8,23 @@ use std::{
time::Duration,
};
-#[cfg(target_os = "macos")]
-use proc_pidinfo::{
- ProcFDInfo, ProcFDType, VnodeFdInfoWithPath, proc_pidfdinfo_self, proc_pidinfo_list_self,
-};
+#[cfg(windows)]
+#[path = "windows.rs"]
+mod imp;
-const SQL_CLOSE_MAX_ATTEMPTS: u8 = 10;
-const SQL_CLOSE_RETRY_DELAY: Duration = Duration::from_millis(100);
+#[cfg(target_os = "macos")]
+#[path = "macos.rs"]
+mod imp;
+
+#[cfg(any(target_os = "linux", target_os = "android"))]
+#[path = "linux.rs"]
+mod imp;
+
+/// Max number of retry attempts
+const CHECK_FILES_CLOSED_MAX_ATTEMPTS: u8 = 10;
+
+/// Delay between file checks
+const CHECK_FILES_CLOSED_RETRY_DELAY: Duration = Duration::from_millis(100);
pub struct SqlitePoolGuard {
database_path: PathBuf,
@@ -42,7 +52,7 @@ impl SqlitePoolGuard {
}
}
- /// Close udnerlying sqlite pool
+ /// Close udnerlying sqlite pool and wait for files to be closed before returning.
pub async fn close_pool(&self) {
_ = self.close_pool_inner();
}
@@ -50,7 +60,7 @@ impl SqlitePoolGuard {
async fn close_pool_inner(&self) -> std::io::Result<()> {
self.connection_pool.close().await;
- if let Err(e) = self.wait_io_close().await {
+ if let Err(e) = self.wait_for_db_files_close().await {
log::error!("Failed to wait for file to close: {e}");
}
@@ -82,25 +92,17 @@ impl SqlitePoolGuard {
database_files
}
- /// Wait for I/O close to the database files
- ///
- /// - macOS: uses `proc_pidinfo` (`sys/proc_info.h`)
- /// See: http://blog.palominolabs.com/2012/06/19/getting-the-files-being-used-by-a-process-on-mac-os-x/
- ///
- /// - Linux, Android: uses `/proc/self/fd/` to list open file descriptors
- /// See: https://stackoverflow.com/a/59797198/351305
- ///
- /// - Windows: attempts to open files to detect whether they are still open.
- async fn wait_io_close(&self) -> std::io::Result<()> {
+ /// Wait for database files to be closed before returning.
+ async fn wait_for_db_files_close(&self) -> std::io::Result<()> {
let database_files = self.all_database_files();
let paths: Vec<&Path> = database_files.iter().map(PathBuf::as_path).collect();
- for _ in 0..SQL_CLOSE_MAX_ATTEMPTS {
- match Self::check_io_close(&paths)
+ for _ in 0..CHECK_FILES_CLOSED_MAX_ATTEMPTS {
+ match imp::check_files_closed(&paths)
.await
- .inspect_err(|e| log::error!("check_io_close() failure: {e}"))
+ .inspect_err(|e| log::error!("imp::check_files_closed() failure: {e}"))
{
- Ok(false) | Err(_) => tokio::time::sleep(SQL_CLOSE_RETRY_DELAY).await,
+ Ok(false) | Err(_) => tokio::time::sleep(CHECK_FILES_CLOSED_RETRY_DELAY).await,
Ok(true) => return Ok(()),
}
}
@@ -110,95 +112,12 @@ impl SqlitePoolGuard {
"timed out waiting for sqlite files to be closed",
))
}
-
- /// Check if no more open file descriptors exist for the given files.
- #[cfg(target_os = "macos")]
- async fn check_io_close(file_paths: &[&Path]) -> io::Result {
- let fd_list = proc_pidinfo_list_self::()?;
-
- for fd in fd_list
- .iter()
- .filter(|s| s.fd_type() == Ok(ProcFDType::VNODE))
- {
- let Some(vnode) = proc_pidfdinfo_self::(fd.proc_fd)
- .inspect_err(|e| {
- log::warn!("proc_pidfdinfo_self::() failure: {e}");
- })
- .ok()
- .flatten()
- else {
- continue;
- };
-
- if let Ok(true) = vnode
- .path()
- .map(|vnode_path| file_paths.contains(&vnode_path))
- .inspect_err(|e| {
- log::warn!("vnode.path() failure: {e:?}");
- })
- {
- return Ok(false);
- }
- }
-
- Ok(true)
- }
-
- /// Check if no more open file descriptors exist for the given files.
- #[cfg(any(target_os = "linux", target_os = "android"))]
- async fn check_io_close(file_paths: &[&Path]) -> io::Result {
- let mut dir = tokio::fs::read_dir("/proc/self/fd/").await?;
-
- while let Ok(Some(entry)) = dir.next_entry().await {
- if entry
- .file_type()
- .await
- .inspect_err(|e| log::warn!("entry.file_type() failure: {e}"))
- .is_ok_and(|entry_type| entry_type.is_symlink())
- {
- match tokio::fs::read_link(entry.path()).await {
- Ok(resolved_path) => {
- if file_paths.contains(&resolved_path.as_ref()) {
- return Ok(false);
- }
- }
- Err(e) => {
- log::error!("Failed to read symlink: {e}");
- }
- }
- }
- }
-
- Ok(true)
- }
-
- #[cfg(windows)]
- async fn check_io_close(file_paths: &[&Path]) -> io::Result {
- // Error code returned when file is still in use.
- const FILE_IN_USE_ERR: i32 = 32;
-
- for file_path in file_paths {
- if let Err(e) = tokio::fs::OpenOptions::new()
- .read(true)
- .open(file_path)
- .await
- {
- if e.raw_os_error() == Some(FILE_IN_USE_ERR) {
- return Ok(false);
- } else if e.kind() != io::ErrorKind::NotFound {
- log::error!("Failed to open file: {}", file_path.display());
- }
- }
- }
-
- Ok(true)
- }
}
#[cfg(test)]
mod tests {
use sqlx::{
- ConnectOptions,
+ ConnectOptions, Executor,
sqlite::{SqliteAutoVacuum, SqliteSynchronous},
};
@@ -208,6 +127,9 @@ mod tests {
async fn test_wait_close() {
let temp_dir = tempfile::tempdir().unwrap();
let database_path = temp_dir.path().join("storage.sqlite");
+
+ println!("Database path: {}", database_path.display());
+
let opts = sqlx::sqlite::SqliteConnectOptions::new()
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.synchronous(SqliteSynchronous::Normal)
@@ -217,10 +139,15 @@ mod tests {
.disable_statement_logging();
let connection_pool = sqlx::SqlitePool::connect_with(opts).await.unwrap();
+ connection_pool
+ .execute("create table test (col int)")
+ .await
+ .unwrap();
+
let guard = SqlitePoolGuard::new(database_path, connection_pool);
assert!(
guard
- .wait_io_close()
+ .wait_for_db_files_close()
.await
.err()
.is_some_and(|e| e.kind() == io::ErrorKind::TimedOut)
diff --git a/sqlx-pool-guard/src/linux.rs b/sqlx-pool-guard/src/linux.rs
new file mode 100644
index 0000000000..5a1fc94bd4
--- /dev/null
+++ b/sqlx-pool-guard/src/linux.rs
@@ -0,0 +1,34 @@
+// Copyright 2025 - Nym Technologies SA
+// SPDX-License-Identifier: Apache-2.0
+
+static PROC_SELF_FD_DIR: &str = "/proc/self/fd/";
+
+/// Check if there are no open file descriptors for the given files.
+///
+/// Linux, Android: uses `/proc/self/fd/` to list open file descriptors
+/// See: https://stackoverflow.com/a/59797198/351305
+pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
+ let mut dir = tokio::fs::read_dir(PROC_SELF_FD_DIR).await?;
+
+ while let Ok(Some(entry)) = dir.next_entry().await {
+ if entry
+ .file_type()
+ .await
+ .inspect_err(|e| log::warn!("entry.file_type() failure: {e}"))
+ .is_ok_and(|entry_type| entry_type.is_symlink())
+ {
+ match tokio::fs::read_link(entry.path()).await {
+ Ok(resolved_path) => {
+ if file_paths.contains(&resolved_path.as_ref()) {
+ return Ok(false);
+ }
+ }
+ Err(e) => {
+ log::error!("Failed to read symlink: {e}");
+ }
+ }
+ }
+ }
+
+ Ok(true)
+}
diff --git a/sqlx-pool-guard/src/macos.rs b/sqlx-pool-guard/src/macos.rs
new file mode 100644
index 0000000000..1142ffd11b
--- /dev/null
+++ b/sqlx-pool-guard/src/macos.rs
@@ -0,0 +1,41 @@
+// Copyright 2025 - Nym Technologies SA
+// SPDX-License-Identifier: Apache-2.0
+
+use proc_pidinfo::{
+ ProcFDInfo, ProcFDType, VnodeFdInfoWithPath, proc_pidfdinfo_self, proc_pidinfo_list_self,
+};
+
+/// Check if there are no open file descriptors for the given files.
+///
+/// Uses `proc_pidinfo` (`sys/proc_info.h`)
+/// See: http://blog.palominolabs.com/2012/06/19/getting-the-files-being-used-by-a-process-on-mac-os-x/
+pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
+ let fd_list = proc_pidinfo_list_self::()?;
+
+ for fd in fd_list
+ .iter()
+ .filter(|s| s.fd_type() == Ok(ProcFDType::VNODE))
+ {
+ let Some(vnode) = proc_pidfdinfo_self::(fd.proc_fd)
+ .inspect_err(|e| {
+ log::warn!("proc_pidfdinfo_self::() failure: {e}");
+ })
+ .ok()
+ .flatten()
+ else {
+ continue;
+ };
+
+ if let Ok(true) = vnode
+ .path()
+ .map(|vnode_path| file_paths.contains(&vnode_path))
+ .inspect_err(|e| {
+ log::warn!("vnode.path() failure: {e:?}");
+ })
+ {
+ return Ok(false);
+ }
+ }
+
+ Ok(true)
+}
diff --git a/sqlx-pool-guard/src/windows.rs b/sqlx-pool-guard/src/windows.rs
new file mode 100644
index 0000000000..43eee8f465
--- /dev/null
+++ b/sqlx-pool-guard/src/windows.rs
@@ -0,0 +1,174 @@
+// Copyright 2025 - Nym Technologies SA
+// SPDX-License-Identifier: Apache-2.0
+
+use std::{
+ ffi::{OsString, c_uchar, c_ulong, c_ushort, c_void},
+ io,
+ os::windows::ffi::OsStringExt,
+ path::{Path, PathBuf},
+};
+
+use windows::{
+ Wdk::System::SystemInformation::{NtQuerySystemInformation, SYSTEM_INFORMATION_CLASS},
+ Win32::{
+ Foundation::{HANDLE, MAX_PATH, NTSTATUS, STATUS_INFO_LENGTH_MISMATCH},
+ Storage::FileSystem::{
+ FILE_NAME_NORMALIZED, FILE_TYPE_DISK, GetFileType, GetFinalPathNameByHandleW,
+ },
+ System::{
+ Memory::{
+ GetProcessHeap, HEAP_FLAGS, HEAP_ZERO_MEMORY, HeapAlloc, HeapFree, HeapReAlloc,
+ },
+ Threading::GetCurrentProcessId,
+ },
+ },
+};
+
+/// Private information class used to retrieve open file handles
+const SYSTEM_HANDLE_INFORMATION_CLASS: SYSTEM_INFORMATION_CLASS = SYSTEM_INFORMATION_CLASS(0x10);
+
+/// Initial buffer size holding the handle info
+/// The number is based on what I observe on a pretty standard Windows 11
+const SYSTEM_HANDLE_INFORMATION_INITIAL_SIZE: usize = 2_500_000;
+
+/// Check if there are no open handles to the given files.
+///
+/// Uses undocumented NT API to obtain open handles on the system.
+/// See: https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/get-all-open-handles-and-kernel-object-address-from-userland
+pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
+ let current_pid = unsafe { GetCurrentProcessId() };
+
+ // Allocate info struct on heap with some initial value
+ let mut reserved_memory = SYSTEM_HANDLE_INFORMATION_INITIAL_SIZE;
+ let mut handle_table_info = HeapGuard::::new(reserved_memory)?;
+
+ let mut status: NTSTATUS = NTSTATUS::default();
+ let mut return_len = reserved_memory as u32;
+ for _ in 0..2 {
+ status = unsafe {
+ NtQuerySystemInformation(
+ SYSTEM_HANDLE_INFORMATION_CLASS,
+ handle_table_info.inner as _,
+ return_len,
+ &mut return_len,
+ )
+ };
+
+ // Buffer is too small, resize memory and retry again.
+ if status == STATUS_INFO_LENGTH_MISMATCH {
+ log::trace!("Buffer is too small ({reserved_memory}), resizing to {return_len}");
+ println!("Buffer is too small ({reserved_memory}), resizing to {return_len}");
+ reserved_memory = return_len as usize;
+ handle_table_info.reallocate(reserved_memory)?;
+ } else {
+ break;
+ }
+ }
+ status.ok()?;
+
+ let num_handles = unsafe { (*handle_table_info.inner).number_of_handles };
+ let proc_entries = unsafe {
+ std::slice::from_raw_parts(
+ (*handle_table_info.inner).handles.as_ptr(),
+ num_handles as usize,
+ )
+ };
+
+ for entry in proc_entries {
+ if entry.unique_process_id == current_pid {
+ let file_handle = HANDLE(entry.handle_value as _);
+
+ if unsafe { GetFileType(file_handle) } == FILE_TYPE_DISK {
+ let mut file_handle_path = vec![0u16; MAX_PATH as usize];
+ let num_chars_without_nul = unsafe {
+ GetFinalPathNameByHandleW(
+ file_handle,
+ &mut file_handle_path,
+ FILE_NAME_NORMALIZED,
+ ) as usize
+ };
+
+ if num_chars_without_nul > 0 {
+ let path_str = OsString::from_wide(&file_handle_path[0..num_chars_without_nul]);
+ let file_handle_pathbuf = PathBuf::from(path_str);
+
+ if file_paths.contains(&file_handle_pathbuf.as_path()) {
+ return Ok(false);
+ }
+ }
+ }
+ }
+ }
+
+ Ok(true)
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+struct SystemHandleInformation {
+ pub number_of_handles: c_ulong,
+ pub handles: [SystemHandleTableEntryInfo; 1],
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+struct SystemHandleTableEntryInfo {
+ pub unique_process_id: c_ulong,
+ pub object_type_index: c_uchar,
+ pub handle_attributes: c_uchar,
+ pub handle_value: c_ushort,
+ pub object: *mut c_void,
+ pub granted_access: c_ulong,
+}
+
+struct HeapGuard {
+ pub inner: *mut T,
+ process_heap: HANDLE,
+}
+
+impl HeapGuard {
+ fn new(length: usize) -> io::Result {
+ let process_heap = unsafe { GetProcessHeap()? };
+ let inner: *mut T = unsafe { HeapAlloc(process_heap, HEAP_ZERO_MEMORY, length) as _ };
+
+ if inner.is_null() {
+ Err(io::Error::other("Failed to allocate memory"))
+ } else {
+ Ok(Self {
+ inner,
+ process_heap,
+ })
+ }
+ }
+
+ fn reallocate(&mut self, new_length: usize) -> io::Result<()> {
+ let new_ptr: *mut T = unsafe {
+ HeapReAlloc(
+ self.process_heap,
+ HEAP_ZERO_MEMORY,
+ Some(self.inner as _),
+ new_length,
+ ) as _
+ };
+
+ if new_ptr.is_null() {
+ Err(io::Error::other("Failed to reallocate memory"))
+ } else {
+ self.inner = new_ptr;
+ Ok(())
+ }
+ }
+}
+
+impl Drop for HeapGuard {
+ fn drop(&mut self) {
+ unsafe {
+ HeapFree(
+ self.process_heap,
+ HEAP_FLAGS(0),
+ Some(self.inner as *mut c_void),
+ )
+ }
+ .expect("HeapFree failure");
+ }
+}
From 6391b7ed3af74c8250d4ff6ff1fe3be5e30f5464 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 29 May 2025 18:19:56 +0200
Subject: [PATCH 06/47] Document
---
sqlx-pool-guard/src/windows.rs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sqlx-pool-guard/src/windows.rs b/sqlx-pool-guard/src/windows.rs
index 43eee8f465..9b04414804 100644
--- a/sqlx-pool-guard/src/windows.rs
+++ b/sqlx-pool-guard/src/windows.rs
@@ -42,6 +42,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
let mut reserved_memory = SYSTEM_HANDLE_INFORMATION_INITIAL_SIZE;
let mut handle_table_info = HeapGuard::::new(reserved_memory)?;
+ // Request system handle information
let mut status: NTSTATUS = NTSTATUS::default();
let mut return_len = reserved_memory as u32;
for _ in 0..2 {
@@ -66,6 +67,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
}
status.ok()?;
+ // Convert returned data into slice
let num_handles = unsafe { (*handle_table_info.inner).number_of_handles };
let proc_entries = unsafe {
std::slice::from_raw_parts(
@@ -74,11 +76,14 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
)
};
+ // Iterate over open file handle entries
for entry in proc_entries {
if entry.unique_process_id == current_pid {
let file_handle = HANDLE(entry.handle_value as _);
+ // Filter everything except disk files
if unsafe { GetFileType(file_handle) } == FILE_TYPE_DISK {
+ // Obtain canonical path for file handle
let mut file_handle_path = vec![0u16; MAX_PATH as usize];
let num_chars_without_nul = unsafe {
GetFinalPathNameByHandleW(
@@ -91,7 +96,6 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
if num_chars_without_nul > 0 {
let path_str = OsString::from_wide(&file_handle_path[0..num_chars_without_nul]);
let file_handle_pathbuf = PathBuf::from(path_str);
-
if file_paths.contains(&file_handle_pathbuf.as_path()) {
return Ok(false);
}
From e4e349bea8419810ba028bfda576552f0d6420dd Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 29 May 2025 18:21:29 +0200
Subject: [PATCH 07/47] Remove logs
---
sqlx-pool-guard/src/lib.rs | 2 --
sqlx-pool-guard/src/windows.rs | 1 -
2 files changed, 3 deletions(-)
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index 8b120ee261..62838ac20f 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -128,8 +128,6 @@ mod tests {
let temp_dir = tempfile::tempdir().unwrap();
let database_path = temp_dir.path().join("storage.sqlite");
- println!("Database path: {}", database_path.display());
-
let opts = sqlx::sqlite::SqliteConnectOptions::new()
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.synchronous(SqliteSynchronous::Normal)
diff --git a/sqlx-pool-guard/src/windows.rs b/sqlx-pool-guard/src/windows.rs
index 9b04414804..606b5863d5 100644
--- a/sqlx-pool-guard/src/windows.rs
+++ b/sqlx-pool-guard/src/windows.rs
@@ -58,7 +58,6 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
// Buffer is too small, resize memory and retry again.
if status == STATUS_INFO_LENGTH_MISMATCH {
log::trace!("Buffer is too small ({reserved_memory}), resizing to {return_len}");
- println!("Buffer is too small ({reserved_memory}), resizing to {return_len}");
reserved_memory = return_len as usize;
handle_table_info.reallocate(reserved_memory)?;
} else {
From 31e161604a18033f3f649a817924f12cd478fc0a Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Mon, 2 Jun 2025 17:36:24 +0200
Subject: [PATCH 08/47] Use sqlite pool guard
---
Cargo.lock | 6 +-
Cargo.toml | 5 +-
common/client-core/surb-storage/Cargo.toml | 1 +
.../src/backend/fs_backend/manager.rs | 55 ++++++++++---------
common/credential-storage/Cargo.toml | 10 +++-
.../credential-storage/src/backends/sqlite.rs | 33 +++++------
.../src/persistent_storage/mod.rs | 10 +++-
sqlx-pool-guard/src/{macos.rs => apple.rs} | 2 +
sqlx-pool-guard/src/lib.rs | 23 ++++++--
sqlx-pool-guard/src/linux.rs | 2 +
10 files changed, 91 insertions(+), 56 deletions(-)
rename sqlx-pool-guard/src/{macos.rs => apple.rs} (97%)
diff --git a/Cargo.lock b/Cargo.lock
index 01820eb102..508eb70645 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5272,6 +5272,7 @@ dependencies = [
"nym-sphinx",
"nym-task",
"sqlx",
+ "sqlx-pool-guard",
"thiserror 2.0.12",
"time",
"tokio",
@@ -5472,6 +5473,7 @@ dependencies = [
"nym-ecash-time",
"serde",
"sqlx",
+ "sqlx-pool-guard",
"thiserror 2.0.12",
"tokio",
"zeroize",
@@ -7956,9 +7958,9 @@ dependencies = [
[[package]]
name = "proc_pidinfo"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1724fdb3f7349e4c58806dfb29dbc3b5e2f8b0997bb5117acf8db6e555867a91"
+checksum = "af53dad2390f8df98dda1e4188322bdf2f91c86cf6001f51d10d64451edf463a"
dependencies = [
"libc",
]
diff --git a/Cargo.toml b/Cargo.toml
index e15ac95c90..f538f5db92 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -124,7 +124,8 @@ members = [
"service-providers/authenticator",
"service-providers/common",
"service-providers/ip-packet-router",
- "service-providers/network-requester", "sqlx-pool-guard",
+ "service-providers/network-requester",
+ "sqlx-pool-guard",
"tools/echo-server",
"tools/internal/contract-state-importer/importer-cli",
"tools/internal/contract-state-importer/importer-contract",
@@ -286,7 +287,7 @@ petgraph = "0.6.5"
pin-project = "1.1"
pin-project-lite = "0.2.16"
publicsuffix = "2.3.0"
-proc_pidinfo = "0.1"
+proc_pidinfo = "0.1.3"
quote = "1"
rand = "0.8.5"
rand_chacha = "0.3"
diff --git a/common/client-core/surb-storage/Cargo.toml b/common/client-core/surb-storage/Cargo.toml
index 49dfbe4b8c..449ce0d589 100644
--- a/common/client-core/surb-storage/Cargo.toml
+++ b/common/client-core/surb-storage/Cargo.toml
@@ -17,6 +17,7 @@ tokio = { workspace = true, features = ["fs"] }
nym-crypto = { path = "../../crypto", optional = true, default-features = false }
nym-sphinx = { path = "../../nymsphinx" }
nym-task = { path = "../../task" }
+sqlx-pool-guard = { path = "../../../sqlx-pool-guard" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
diff --git a/common/client-core/surb-storage/src/backend/fs_backend/manager.rs b/common/client-core/surb-storage/src/backend/fs_backend/manager.rs
index 3daa4744a4..68d21009c5 100644
--- a/common/client-core/surb-storage/src/backend/fs_backend/manager.rs
+++ b/common/client-core/surb-storage/src/backend/fs_backend/manager.rs
@@ -15,9 +15,11 @@ use sqlx::{
};
use std::path::Path;
+use sqlx_pool_guard::SqlitePoolGuard;
+
#[derive(Debug, Clone)]
pub struct StorageManager {
- connection_pool: sqlx::SqlitePool,
+ connection_pool: SqlitePoolGuard,
}
// all SQL goes here
@@ -37,7 +39,7 @@ impl StorageManager {
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.synchronous(SqliteSynchronous::Normal)
.auto_vacuum(SqliteAutoVacuum::Incremental)
- .filename(database_path)
+ .filename(&database_path)
.create_if_missing(fresh)
.disable_statement_logging();
@@ -49,8 +51,11 @@ impl StorageManager {
}
};
+ let connection_pool =
+ SqlitePoolGuard::new(database_path.as_ref().to_path_buf(), connection_pool);
+
if let Err(err) = sqlx::migrate!("./fs_surbs_migrations")
- .run(&connection_pool)
+ .run(&*connection_pool)
.await
{
error!("Failed to initialize SQLx database: {err}");
@@ -70,35 +75,35 @@ impl StorageManager {
#[allow(dead_code)]
pub async fn status_table_exists(&self) -> Result {
sqlx::query!("SELECT name FROM sqlite_master WHERE type='table' AND name='status'")
- .fetch_optional(&self.connection_pool)
+ .fetch_optional(&*self.connection_pool)
.await
.map(|r| r.is_some())
}
pub async fn create_status_table(&self) -> Result<(), sqlx::Error> {
sqlx::query!("INSERT INTO status(flush_in_progress, previous_flush_timestamp, client_in_use) VALUES (0, 0, 1)")
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn get_flush_status(&self) -> Result {
sqlx::query!("SELECT flush_in_progress FROM status;")
- .fetch_one(&self.connection_pool)
+ .fetch_one(&*self.connection_pool)
.await
.map(|r| r.flush_in_progress > 0)
}
pub async fn set_previous_flush_timestamp(&self, timestamp: i64) -> Result<(), sqlx::Error> {
sqlx::query!("UPDATE status SET previous_flush_timestamp = ?", timestamp)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn get_previous_flush_timestamp(&self) -> Result {
sqlx::query!("SELECT previous_flush_timestamp FROM status;")
- .fetch_one(&self.connection_pool)
+ .fetch_one(&*self.connection_pool)
.await
.map(|r| r.previous_flush_timestamp)
}
@@ -106,14 +111,14 @@ impl StorageManager {
pub async fn set_flush_status(&self, in_progress: bool) -> Result<(), sqlx::Error> {
let in_progress_int = i64::from(in_progress);
sqlx::query!("UPDATE status SET flush_in_progress = ?", in_progress_int)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn get_client_in_use_status(&self) -> Result {
sqlx::query!("SELECT client_in_use FROM status;")
- .fetch_one(&self.connection_pool)
+ .fetch_one(&*self.connection_pool)
.await
.map(|r| r.client_in_use > 0)
}
@@ -121,21 +126,21 @@ impl StorageManager {
pub async fn set_client_in_use_status(&self, in_use: bool) -> Result<(), sqlx::Error> {
let in_use_int = i64::from(in_use);
sqlx::query!("UPDATE status SET client_in_use = ?", in_use_int)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn delete_all_tags(&self) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM sender_tag;")
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn get_tags(&self) -> Result, sqlx::Error> {
sqlx::query_as!(StoredSenderTag, "SELECT * FROM sender_tag;",)
- .fetch_all(&self.connection_pool)
+ .fetch_all(&*self.connection_pool)
.await
}
@@ -147,21 +152,21 @@ impl StorageManager {
stored_tag.recipient,
stored_tag.tag
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn delete_all_reply_keys(&self) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM reply_key;")
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn get_reply_keys(&self) -> Result, sqlx::Error> {
sqlx::query_as!(StoredReplyKey, "SELECT * FROM reply_key;",)
- .fetch_all(&self.connection_pool)
+ .fetch_all(&*self.connection_pool)
.await
}
@@ -177,14 +182,14 @@ impl StorageManager {
stored_reply_key.reply_key,
stored_reply_key.sent_at_timestamp
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
pub async fn get_surb_senders(&self) -> Result, sqlx::Error> {
sqlx::query_as!(StoredSurbSender, "SELECT * FROM reply_surb_sender;",)
- .fetch_all(&self.connection_pool)
+ .fetch_all(&*self.connection_pool)
.await
}
@@ -199,7 +204,7 @@ impl StorageManager {
stored_surb_sender.tag,
stored_surb_sender.last_sent_timestamp
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?
.last_insert_rowid();
Ok(id)
@@ -214,17 +219,17 @@ impl StorageManager {
"SELECT * FROM reply_surb WHERE reply_surb_sender_id = ?",
sender_id
)
- .fetch_all(&self.connection_pool)
+ .fetch_all(&*self.connection_pool)
.await
}
pub async fn delete_all_reply_surb_data(&self) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM reply_surb;")
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
sqlx::query!("DELETE FROM reply_surb_sender;")
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
@@ -241,7 +246,7 @@ impl StorageManager {
stored_reply_surb.reply_surb_sender_id,
stored_reply_surb.reply_surb
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
@@ -255,7 +260,7 @@ impl StorageManager {
SELECT min_reply_surb_threshold as "min_reply_surb_threshold: u32", max_reply_surb_threshold as "max_reply_surb_threshold: u32" FROM reply_surb_storage_metadata;
"#,
)
- .fetch_one(&self.connection_pool)
+ .fetch_one(&*self.connection_pool)
.await
}
@@ -269,7 +274,7 @@ impl StorageManager {
"#,
metadata.min_reply_surb_threshold,
metadata.max_reply_surb_threshold,
- ).execute(&self.connection_pool).await?;
+ ).execute(&*self.connection_pool).await?;
Ok(())
}
}
diff --git a/common/credential-storage/Cargo.toml b/common/credential-storage/Cargo.toml
index b822d49db6..07a01486df 100644
--- a/common/credential-storage/Cargo.toml
+++ b/common/credential-storage/Cargo.toml
@@ -19,6 +19,7 @@ zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-credentials = { path = "../credentials" }
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
nym-ecash-time = { path = "../ecash-time" }
+sqlx-pool-guard = { path = "../../sqlx-pool-guard" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
@@ -31,8 +32,13 @@ features = ["rt-multi-thread", "net", "signal", "fs"]
[build-dependencies]
-sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
+sqlx = { workspace = true, features = [
+ "runtime-tokio-rustls",
+ "sqlite",
+ "macros",
+ "migrate",
+] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
[features]
-persistent-storage = ["bincode", "serde"]
\ No newline at end of file
+persistent-storage = ["bincode", "serde"]
diff --git a/common/credential-storage/src/backends/sqlite.rs b/common/credential-storage/src/backends/sqlite.rs
index 3d91741ee3..6ac45aec47 100644
--- a/common/credential-storage/src/backends/sqlite.rs
+++ b/common/credential-storage/src/backends/sqlite.rs
@@ -7,10 +7,11 @@ use crate::models::{
};
use nym_ecash_time::Date;
use sqlx::{Executor, Sqlite, Transaction};
+use sqlx_pool_guard::SqlitePoolGuard;
#[derive(Clone)]
pub struct SqliteEcashTicketbookManager {
- connection_pool: sqlx::SqlitePool,
+ connection_pool: SqlitePoolGuard,
}
impl SqliteEcashTicketbookManager {
@@ -19,7 +20,7 @@ impl SqliteEcashTicketbookManager {
/// # Arguments
///
/// * `connection_pool`: database connection pool to use.
- pub fn new(connection_pool: sqlx::SqlitePool) -> Self {
+ pub fn new(connection_pool: SqlitePoolGuard) -> Self {
SqliteEcashTicketbookManager { connection_pool }
}
@@ -33,7 +34,7 @@ impl SqliteEcashTicketbookManager {
"DELETE FROM ecash_ticketbook WHERE expiration_date <= ?",
deadline
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
@@ -60,7 +61,7 @@ impl SqliteEcashTicketbookManager {
data,
expiration_date,
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
@@ -90,7 +91,7 @@ impl SqliteEcashTicketbookManager {
epoch_id,
total_tickets,
used_tickets,
- ).execute(&self.connection_pool).await?;
+ ).execute(&*self.connection_pool).await?;
Ok(())
}
@@ -105,7 +106,7 @@ impl SqliteEcashTicketbookManager {
"#,
)
.bind(data)
- .fetch_optional(&self.connection_pool)
+ .fetch_optional(&*self.connection_pool)
.await?
.is_some();
@@ -121,7 +122,7 @@ impl SqliteEcashTicketbookManager {
FROM ecash_ticketbook
"#,
)
- .fetch_all(&self.connection_pool)
+ .fetch_all(&*self.connection_pool)
.await
}
@@ -143,7 +144,7 @@ impl SqliteEcashTicketbookManager {
ticketbook_id,
expected_current_total_spent
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?
.rows_affected();
Ok(affected > 0)
@@ -153,7 +154,7 @@ impl SqliteEcashTicketbookManager {
&self,
) -> Result, sqlx::Error> {
sqlx::query_as("SELECT * FROM pending_issuance")
- .fetch_all(&self.connection_pool)
+ .fetch_all(&*self.connection_pool)
.await
}
@@ -165,7 +166,7 @@ impl SqliteEcashTicketbookManager {
"DELETE FROM pending_issuance WHERE deposit_id = ?",
pending_id
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
@@ -182,7 +183,7 @@ impl SqliteEcashTicketbookManager {
"#,
epoch_id
)
- .fetch_optional(&self.connection_pool)
+ .fetch_optional(&*self.connection_pool)
.await
}
@@ -208,7 +209,7 @@ impl SqliteEcashTicketbookManager {
serialisation_revision,
epoch_id
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
@@ -225,7 +226,7 @@ impl SqliteEcashTicketbookManager {
"#,
epoch_id
)
- .fetch_optional(&self.connection_pool)
+ .fetch_optional(&*self.connection_pool)
.await
}
@@ -251,7 +252,7 @@ impl SqliteEcashTicketbookManager {
serialisation_revision,
epoch_id,
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
@@ -269,7 +270,7 @@ impl SqliteEcashTicketbookManager {
"#,
expiration_date
)
- .fetch_optional(&self.connection_pool)
+ .fetch_optional(&*self.connection_pool)
.await
}
@@ -298,7 +299,7 @@ impl SqliteEcashTicketbookManager {
serialisation_revision,
expiration_date
)
- .execute(&self.connection_pool)
+ .execute(&*self.connection_pool)
.await?;
Ok(())
}
diff --git a/common/credential-storage/src/persistent_storage/mod.rs b/common/credential-storage/src/persistent_storage/mod.rs
index bccbccf4ab..c8dd5a08b2 100644
--- a/common/credential-storage/src/persistent_storage/mod.rs
+++ b/common/credential-storage/src/persistent_storage/mod.rs
@@ -37,6 +37,7 @@ use sqlx::{
sqlite::{SqliteAutoVacuum, SqliteSynchronous},
ConnectOptions,
};
+use sqlx_pool_guard::SqlitePoolGuard;
use std::path::Path;
use zeroize::Zeroizing;
@@ -62,7 +63,7 @@ impl PersistentStorage {
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.synchronous(SqliteSynchronous::Normal)
.auto_vacuum(SqliteAutoVacuum::Incremental)
- .filename(database_path)
+ .filename(&database_path)
.create_if_missing(true)
.disable_statement_logging();
@@ -74,14 +75,17 @@ impl PersistentStorage {
}
};
- if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
+ let connection_pool =
+ SqlitePoolGuard::new(database_path.as_ref().to_path_buf(), connection_pool);
+
+ if let Err(err) = sqlx::migrate!("./migrations").run(&*connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
connection_pool.close().await;
return Err(err.into());
}
Ok(PersistentStorage {
- storage_manager: SqliteEcashTicketbookManager::new(connection_pool.clone()),
+ storage_manager: SqliteEcashTicketbookManager::new(connection_pool),
})
}
}
diff --git a/sqlx-pool-guard/src/macos.rs b/sqlx-pool-guard/src/apple.rs
similarity index 97%
rename from sqlx-pool-guard/src/macos.rs
rename to sqlx-pool-guard/src/apple.rs
index 1142ffd11b..549839a550 100644
--- a/sqlx-pool-guard/src/macos.rs
+++ b/sqlx-pool-guard/src/apple.rs
@@ -1,6 +1,8 @@
// Copyright 2025 - Nym Technologies SA
// SPDX-License-Identifier: Apache-2.0
+use std::{io, path::Path};
+
use proc_pidinfo::{
ProcFDInfo, ProcFDType, VnodeFdInfoWithPath, proc_pidfdinfo_self, proc_pidinfo_list_self,
};
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index 62838ac20f..b851f1ef79 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -12,8 +12,8 @@ use std::{
#[path = "windows.rs"]
mod imp;
-#[cfg(target_os = "macos")]
-#[path = "macos.rs"]
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[path = "apple.rs"]
mod imp;
#[cfg(any(target_os = "linux", target_os = "android"))]
@@ -21,18 +21,25 @@ mod imp;
mod imp;
/// Max number of retry attempts
-const CHECK_FILES_CLOSED_MAX_ATTEMPTS: u8 = 10;
+const CHECK_FILES_CLOSED_MAX_ATTEMPTS: u8 = 20;
/// Delay between file checks
const CHECK_FILES_CLOSED_RETRY_DELAY: Duration = Duration::from_millis(100);
+/// `sqlx::SqlitePool` wrapper providing a workaround for the [known bug](https://github.com/launchbadge/sqlx/issues/3217).
+/// In principle after requesting to close the sqlite pool, the wrapper monitors open file descriptor and polls periodically until all database files are closed.
+#[derive(Debug, Clone)]
pub struct SqlitePoolGuard {
+ /// Path to sqlite database file.
database_path: PathBuf,
+
+ /// Inner connection pool.
connection_pool: sqlx::SqlitePool,
}
impl Deref for SqlitePoolGuard {
type Target = sqlx::SqlitePool;
+
fn deref(&self) -> &Self::Target {
&self.connection_pool
}
@@ -53,8 +60,12 @@ impl SqlitePoolGuard {
}
/// Close udnerlying sqlite pool and wait for files to be closed before returning.
- pub async fn close_pool(&self) {
- _ = self.close_pool_inner();
+ pub async fn close(&self) {
+ // Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database.
+ if !self.connection_pool.is_closed() {
+ log::info!("Closing sqlite pool: {}", self.database_path.display());
+ _ = self.close_pool_inner();
+ }
}
async fn close_pool_inner(&self) -> std::io::Result<()> {
@@ -126,7 +137,7 @@ mod tests {
#[tokio::test]
async fn test_wait_close() {
let temp_dir = tempfile::tempdir().unwrap();
- let database_path = temp_dir.path().join("storage.sqlite");
+ let database_path = temp_dir.path().join("storage.db");
let opts = sqlx::sqlite::SqliteConnectOptions::new()
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
diff --git a/sqlx-pool-guard/src/linux.rs b/sqlx-pool-guard/src/linux.rs
index 5a1fc94bd4..f7610e67c5 100644
--- a/sqlx-pool-guard/src/linux.rs
+++ b/sqlx-pool-guard/src/linux.rs
@@ -1,6 +1,8 @@
// Copyright 2025 - Nym Technologies SA
// SPDX-License-Identifier: Apache-2.0
+use std::{io, path::Path};
+
static PROC_SELF_FD_DIR: &str = "/proc/self/fd/";
/// Check if there are no open file descriptors for the given files.
From 574f7f1abdc4a67c9168b04a56a8303a28ddd44b Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Mon, 2 Jun 2025 17:41:56 +0200
Subject: [PATCH 09/47] Revert
---
.../gateways-storage/src/backend/fs_backend/manager.rs | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs
index 0b7aafdb28..101a6a8710 100644
--- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs
+++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs
@@ -47,14 +47,12 @@ impl StorageManager {
StorageError::DatabaseConnectionError { source }
})?;
- if let Err(err) = sqlx::migrate!("./fs_gateways_migrations")
+ sqlx::migrate!("./fs_gateways_migrations")
.run(&connection_pool)
.await
- {
- error!("Failed to initialize SQLx database: {err}");
- connection_pool.close().await;
- return Err(err)?;
- }
+ .inspect_err(|err| {
+ error!("Failed to initialize SQLx database: {err}");
+ })?;
debug!("Database migration finished!");
Ok(StorageManager { connection_pool })
From 085103b33380fdaf883a4b071b6bf04bc4b3581b Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Mon, 2 Jun 2025 17:53:54 +0200
Subject: [PATCH 10/47] Cleanup
---
.../client/base_client/non_wasm_helpers.rs | 49 ++-----------------
1 file changed, 3 insertions(+), 46 deletions(-)
diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs
index 4f3a2c0c77..0400355fdc 100644
--- a/common/client-core/src/client/base_client/non_wasm_helpers.rs
+++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs
@@ -7,15 +7,11 @@ use crate::{
config::Config,
error::ClientCoreError,
};
-#[cfg(windows)]
-use log::debug;
use log::{error, info, trace};
use nym_bandwidth_controller::BandwidthController;
use nym_client_core_gateways_storage::OnDiskGatewaysDetails;
use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_validator_client::{nyxd, QueryHttpRpcNyxdClient};
-#[cfg(windows)]
-use std::time::Duration;
use std::{io, path::Path};
use time::OffsetDateTime;
use url::Url;
@@ -24,10 +20,7 @@ async fn setup_fresh_backend>(
db_path: P,
surb_config: &config::ReplySurbs,
) -> Result {
- info!(
- "creating fresh surb database: {}",
- db_path.as_ref().display()
- );
+ info!("Creating fresh surb database");
let mut storage_backend = match fs_backend::Backend::init(db_path).await {
Ok(backend) => backend,
Err(err) => {
@@ -79,7 +72,7 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<()
};
let renamed = db_path.with_extension(new_extension);
- rename_db_file(&db_path, &renamed).await.inspect_err(|_| {
+ tokio::fs::rename(db_path, &renamed).await.inspect_err(|_| {
tracing::error!(
"Failed to rename corrupt database file: {} to {}",
db_path.display(),
@@ -88,42 +81,6 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<()
})
}
-#[cfg(not(windows))]
-async fn rename_db_file(db_path: impl AsRef, renamed: impl AsRef) -> io::Result<()> {
- tokio::fs::rename(db_path, &renamed).await
-}
-
-#[cfg(windows)]
-async fn rename_db_file(db_path: impl AsRef, renamed: impl AsRef) -> io::Result<()> {
- // Due to bug in sqlx (https://github.com/launchbadge/sqlx/issues/3217),
- // the sqlite file can be still in use after closing sqlite connection pool
- // Poll for a bit until the db file is released.
-
- // Max number of retries
- const MAX_RETRY_ATTEMPTS: u32 = 10;
- // Delay between retries
- const WAIT_DELAY: Duration = Duration::from_millis(100);
- // Error code returned when file is still in use.
- const FILE_IN_USE_ERR: i32 = 32;
-
- let mut retry_attempt = 0;
- while let Err(e) = tokio::fs::rename(db_path.as_ref(), renamed.as_ref()).await {
- retry_attempt += 1;
-
- if e.raw_os_error() == Some(FILE_IN_USE_ERR) && retry_attempt < MAX_RETRY_ATTEMPTS {
- debug!(
- "File {} is still open. Sleep and retry",
- db_path.as_ref().display()
- );
- tokio::time::sleep(WAIT_DELAY).await;
- } else {
- return Err(e);
- }
- }
-
- Ok(())
-}
-
pub async fn setup_fs_reply_surb_backend>(
db_path: P,
surb_config: &config::ReplySurbs,
@@ -132,7 +89,7 @@ pub async fn setup_fs_reply_surb_backend>(
// the existing one
let db_path = db_path.as_ref();
if db_path.exists() {
- info!("Loading existing surb database: {}", db_path.display());
+ info!("Loading existing surb database");
match fs_backend::Backend::try_load(db_path, surb_config.fresh_sender_tags).await {
Ok(backend) => Ok(backend),
Err(err) => {
From f26fd5384d910458f40b16b9c10bb56811c33e16 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Mon, 2 Jun 2025 18:27:07 +0200
Subject: [PATCH 11/47] Improve windows
---
sqlx-pool-guard/src/windows.rs | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/sqlx-pool-guard/src/windows.rs b/sqlx-pool-guard/src/windows.rs
index 606b5863d5..4fca6c1bef 100644
--- a/sqlx-pool-guard/src/windows.rs
+++ b/sqlx-pool-guard/src/windows.rs
@@ -49,7 +49,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
status = unsafe {
NtQuerySystemInformation(
SYSTEM_HANDLE_INFORMATION_CLASS,
- handle_table_info.inner as _,
+ handle_table_info.as_mut_ptr() as _,
return_len,
&mut return_len,
)
@@ -70,7 +70,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
let num_handles = unsafe { (*handle_table_info.inner).number_of_handles };
let proc_entries = unsafe {
std::slice::from_raw_parts(
- (*handle_table_info.inner).handles.as_ptr(),
+ (*handle_table_info.as_mut_ptr()).handles.as_ptr(),
num_handles as usize,
)
};
@@ -124,12 +124,14 @@ struct SystemHandleTableEntryInfo {
pub granted_access: c_ulong,
}
+/// Managed heap memory
struct HeapGuard {
- pub inner: *mut T,
+ inner: *mut T,
process_heap: HANDLE,
}
impl HeapGuard {
+ /// Allocate new memory using `HealAlloc`
fn new(length: usize) -> io::Result {
let process_heap = unsafe { GetProcessHeap()? };
let inner: *mut T = unsafe { HeapAlloc(process_heap, HEAP_ZERO_MEMORY, length) as _ };
@@ -144,6 +146,10 @@ impl HeapGuard {
}
}
+ /// Reallocate existing chunk of memory
+ ///
+ /// On success: the internal memory pointer is replaced.
+ /// On failure: the internal memory pointer remains the same and still valid.
fn reallocate(&mut self, new_length: usize) -> io::Result<()> {
let new_ptr: *mut T = unsafe {
HeapReAlloc(
@@ -161,10 +167,15 @@ impl HeapGuard {
Ok(())
}
}
+
+ fn as_mut_ptr(&self) -> *mut T {
+ self.inner
+ }
}
impl Drop for HeapGuard {
fn drop(&mut self) {
+ #[allow(clippy::expect_used)]
unsafe {
HeapFree(
self.process_heap,
From 11262836d22ce1c8724925ccb5a06f1e4b5c0b28 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Mon, 2 Jun 2025 18:59:17 +0200
Subject: [PATCH 12/47] Clean up
---
common/gateway-stats-storage/src/lib.rs | 1 -
common/gateway-storage/src/lib.rs | 1 -
2 files changed, 2 deletions(-)
diff --git a/common/gateway-stats-storage/src/lib.rs b/common/gateway-stats-storage/src/lib.rs
index 10aa61062d..8ad34bbca4 100644
--- a/common/gateway-stats-storage/src/lib.rs
+++ b/common/gateway-stats-storage/src/lib.rs
@@ -59,7 +59,6 @@ impl PersistentStatsStorage {
if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
- connection_pool.close().await;
return Err(err.into());
}
diff --git a/common/gateway-storage/src/lib.rs b/common/gateway-storage/src/lib.rs
index 1d91576ccb..2d05d43fe7 100644
--- a/common/gateway-storage/src/lib.rs
+++ b/common/gateway-storage/src/lib.rs
@@ -108,7 +108,6 @@ impl GatewayStorage {
if let Err(err) = sqlx::migrate!("./migrations").run(&connection_pool).await {
error!("Failed to perform migration on the SQLx database: {err}");
- connection_pool.close().await;
return Err(err.into());
}
From 02909c03dd1028036b404777cc09d7dd1cb69ab5 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Tue, 3 Jun 2025 14:49:35 +0200
Subject: [PATCH 13/47] Expose database path
---
sqlx-pool-guard/src/lib.rs | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index b851f1ef79..6f01b2b55c 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -37,21 +37,8 @@ pub struct SqlitePoolGuard {
connection_pool: sqlx::SqlitePool,
}
-impl Deref for SqlitePoolGuard {
- type Target = sqlx::SqlitePool;
-
- fn deref(&self) -> &Self::Target {
- &self.connection_pool
- }
-}
-
-impl DerefMut for SqlitePoolGuard {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.connection_pool
- }
-}
-
impl SqlitePoolGuard {
+ /// Create new instance providing path to database and connection pool
pub fn new(database_path: PathBuf, connection_pool: sqlx::SqlitePool) -> Self {
Self {
database_path,
@@ -59,6 +46,11 @@ impl SqlitePoolGuard {
}
}
+ /// Returns database path
+ pub fn database_path(&self) -> &Path {
+ &self.database_path
+ }
+
/// Close udnerlying sqlite pool and wait for files to be closed before returning.
pub async fn close(&self) {
// Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database.
@@ -125,6 +117,19 @@ impl SqlitePoolGuard {
}
}
+impl Deref for SqlitePoolGuard {
+ type Target = sqlx::SqlitePool;
+
+ fn deref(&self) -> &Self::Target {
+ &self.connection_pool
+ }
+}
+
+impl DerefMut for SqlitePoolGuard {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.connection_pool
+ }
+}
#[cfg(test)]
mod tests {
use sqlx::{
From b8c8d33c945c2d79eb86917380ecea150f8b8a2c Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Tue, 3 Jun 2025 15:12:55 +0200
Subject: [PATCH 14/47] Use log here
---
common/client-core/src/client/base_client/non_wasm_helpers.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs
index 0400355fdc..7a8b9b1467 100644
--- a/common/client-core/src/client/base_client/non_wasm_helpers.rs
+++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs
@@ -73,7 +73,7 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<()
let renamed = db_path.with_extension(new_extension);
tokio::fs::rename(db_path, &renamed).await.inspect_err(|_| {
- tracing::error!(
+ error!(
"Failed to rename corrupt database file: {} to {}",
db_path.display(),
renamed.display()
From 7fcc188041f7776eaeb7d1d9f68b1cc3edad55f2 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Tue, 3 Jun 2025 17:19:42 +0200
Subject: [PATCH 15/47] Switch to tracing
---
Cargo.lock | 2 +-
sqlx-pool-guard/Cargo.toml | 2 +-
sqlx-pool-guard/src/apple.rs | 4 ++--
sqlx-pool-guard/src/lib.rs | 8 ++++----
sqlx-pool-guard/src/linux.rs | 4 ++--
sqlx-pool-guard/src/windows.rs | 2 +-
6 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 508eb70645..08fc8c0c70 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9540,11 +9540,11 @@ dependencies = [
name = "sqlx-pool-guard"
version = "0.1.0"
dependencies = [
- "log",
"proc_pidinfo",
"sqlx",
"tempfile",
"tokio",
+ "tracing",
"windows 0.61.1",
]
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
index a77ee80024..86c57a5277 100644
--- a/sqlx-pool-guard/Cargo.toml
+++ b/sqlx-pool-guard/Cargo.toml
@@ -15,7 +15,7 @@ tokio = { workspace = true, features = [
"fs",
] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite"] }
-log.workspace = true
+tracing.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
proc_pidinfo.workspace = true
diff --git a/sqlx-pool-guard/src/apple.rs b/sqlx-pool-guard/src/apple.rs
index 549839a550..a67ed1a447 100644
--- a/sqlx-pool-guard/src/apple.rs
+++ b/sqlx-pool-guard/src/apple.rs
@@ -20,7 +20,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
{
let Some(vnode) = proc_pidfdinfo_self::(fd.proc_fd)
.inspect_err(|e| {
- log::warn!("proc_pidfdinfo_self::() failure: {e}");
+ tracing::warn!("proc_pidfdinfo_self::() failure: {e}");
})
.ok()
.flatten()
@@ -32,7 +32,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
.path()
.map(|vnode_path| file_paths.contains(&vnode_path))
.inspect_err(|e| {
- log::warn!("vnode.path() failure: {e:?}");
+ tracing::warn!("vnode.path() failure: {e:?}");
})
{
return Ok(false);
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index 6f01b2b55c..fc5169b519 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -55,7 +55,7 @@ impl SqlitePoolGuard {
pub async fn close(&self) {
// Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database.
if !self.connection_pool.is_closed() {
- log::info!("Closing sqlite pool: {}", self.database_path.display());
+ tracing::info!("Closing sqlite pool: {}", self.database_path.display());
_ = self.close_pool_inner();
}
}
@@ -64,7 +64,7 @@ impl SqlitePoolGuard {
self.connection_pool.close().await;
if let Err(e) = self.wait_for_db_files_close().await {
- log::error!("Failed to wait for file to close: {e}");
+ tracing::error!("Failed to wait for file to close: {e}");
}
Ok(())
@@ -77,7 +77,7 @@ impl SqlitePoolGuard {
.database_path
.canonicalize()
.inspect_err(|e| {
- log::error!(
+ tracing::error!(
"Failed to canonicalize path: {}. Cause: {e}",
self.database_path.display()
);
@@ -103,7 +103,7 @@ impl SqlitePoolGuard {
for _ in 0..CHECK_FILES_CLOSED_MAX_ATTEMPTS {
match imp::check_files_closed(&paths)
.await
- .inspect_err(|e| log::error!("imp::check_files_closed() failure: {e}"))
+ .inspect_err(|e| tracing::error!("imp::check_files_closed() failure: {e}"))
{
Ok(false) | Err(_) => tokio::time::sleep(CHECK_FILES_CLOSED_RETRY_DELAY).await,
Ok(true) => return Ok(()),
diff --git a/sqlx-pool-guard/src/linux.rs b/sqlx-pool-guard/src/linux.rs
index f7610e67c5..e0f26de9e5 100644
--- a/sqlx-pool-guard/src/linux.rs
+++ b/sqlx-pool-guard/src/linux.rs
@@ -16,7 +16,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
if entry
.file_type()
.await
- .inspect_err(|e| log::warn!("entry.file_type() failure: {e}"))
+ .inspect_err(|e| tracing::warn!("entry.file_type() failure: {e}"))
.is_ok_and(|entry_type| entry_type.is_symlink())
{
match tokio::fs::read_link(entry.path()).await {
@@ -26,7 +26,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
}
}
Err(e) => {
- log::error!("Failed to read symlink: {e}");
+ tracing::error!("Failed to read symlink: {e}");
}
}
}
diff --git a/sqlx-pool-guard/src/windows.rs b/sqlx-pool-guard/src/windows.rs
index 4fca6c1bef..799eac2abe 100644
--- a/sqlx-pool-guard/src/windows.rs
+++ b/sqlx-pool-guard/src/windows.rs
@@ -57,7 +57,7 @@ pub async fn check_files_closed(file_paths: &[&Path]) -> io::Result {
// Buffer is too small, resize memory and retry again.
if status == STATUS_INFO_LENGTH_MISMATCH {
- log::trace!("Buffer is too small ({reserved_memory}), resizing to {return_len}");
+ tracing::trace!("Buffer is too small ({reserved_memory}), resizing to {return_len}");
reserved_memory = return_len as usize;
handle_table_info.reallocate(reserved_memory)?;
} else {
From d7779df1b7c2d6248a260335de9f33429446895f Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Wed, 4 Jun 2025 10:58:08 +0200
Subject: [PATCH 16/47] Include proc_pidinfo on iOS
---
sqlx-pool-guard/Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
index 86c57a5277..c576f522a0 100644
--- a/sqlx-pool-guard/Cargo.toml
+++ b/sqlx-pool-guard/Cargo.toml
@@ -17,7 +17,7 @@ tokio = { workspace = true, features = [
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite"] }
tracing.workspace = true
-[target.'cfg(target_os = "macos")'.dependencies]
+[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
proc_pidinfo.workspace = true
[target.'cfg(windows)'.dependencies]
From f5846d5bc2fda280dcacf80ea1fc23e07db0d2c6 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Wed, 4 Jun 2025 11:40:56 +0200
Subject: [PATCH 17/47] Log all tracing output just in case
---
Cargo.lock | 1 +
sqlx-pool-guard/Cargo.toml | 3 ++-
sqlx-pool-guard/src/lib.rs | 4 ++++
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Cargo.lock b/Cargo.lock
index 08fc8c0c70..efc17902f2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9545,6 +9545,7 @@ dependencies = [
"tempfile",
"tokio",
"tracing",
+ "tracing-subscriber",
"windows 0.61.1",
]
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
index c576f522a0..5482346200 100644
--- a/sqlx-pool-guard/Cargo.toml
+++ b/sqlx-pool-guard/Cargo.toml
@@ -31,4 +31,5 @@ windows = { version = "0.61", features = [
] }
[dev-dependencies]
-tempfile = { workspace = true }
+tempfile.workspace = true
+tracing-subscriber.workspace = true
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index fc5169b519..d9d89eaae7 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -141,6 +141,10 @@ mod tests {
#[tokio::test]
async fn test_wait_close() {
+ tracing_subscriber::fmt()
+ .with_max_level(tracing::Level::TRACE)
+ .init();
+
let temp_dir = tempfile::tempdir().unwrap();
let database_path = temp_dir.path().join("storage.db");
From 3593631e4ab631d9d03a5487a1af9934c3542b88 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Fri, 6 Jun 2025 13:24:04 +0200
Subject: [PATCH 18/47] Exclude sqlx-pool-guard from wasm builds
---
common/client-core/surb-storage/Cargo.toml | 5 +++--
common/credential-storage/Cargo.toml | 3 ++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/common/client-core/surb-storage/Cargo.toml b/common/client-core/surb-storage/Cargo.toml
index 449ce0d589..1706008302 100644
--- a/common/client-core/surb-storage/Cargo.toml
+++ b/common/client-core/surb-storage/Cargo.toml
@@ -17,14 +17,15 @@ tokio = { workspace = true, features = ["fs"] }
nym-crypto = { path = "../../crypto", optional = true, default-features = false }
nym-sphinx = { path = "../../nymsphinx" }
nym-task = { path = "../../task" }
-sqlx-pool-guard = { path = "../../../sqlx-pool-guard" }
-
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
optional = true
+[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx-pool-guard]
+path = "../../../sqlx-pool-guard"
+
[build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sqlx = { workspace = true, features = [
diff --git a/common/credential-storage/Cargo.toml b/common/credential-storage/Cargo.toml
index 07a01486df..aa9b615805 100644
--- a/common/credential-storage/Cargo.toml
+++ b/common/credential-storage/Cargo.toml
@@ -19,8 +19,9 @@ zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-credentials = { path = "../credentials" }
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
nym-ecash-time = { path = "../ecash-time" }
-sqlx-pool-guard = { path = "../../sqlx-pool-guard" }
+[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx-pool-guard]
+path = "../../sqlx-pool-guard"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true
From 9d82d6d1112680c4fbfed75e53a0e66e93ae8aff Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Fri, 6 Jun 2025 13:34:56 +0200
Subject: [PATCH 19/47] Hide tokio and sqlx behind not(wasm32)
---
sqlx-pool-guard/Cargo.toml | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/sqlx-pool-guard/Cargo.toml b/sqlx-pool-guard/Cargo.toml
index 5482346200..cef202e4df 100644
--- a/sqlx-pool-guard/Cargo.toml
+++ b/sqlx-pool-guard/Cargo.toml
@@ -8,15 +8,16 @@ license.workspace = true
workspace = true
[dependencies]
-tokio = { workspace = true, features = [
- "rt-multi-thread",
- "macros",
- "time",
- "fs",
-] }
-sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite"] }
tracing.workspace = true
+[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
+workspace = true
+features = ["runtime-tokio-rustls", "sqlite"]
+
+[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
+workspace = true
+features = ["rt-multi-thread", "macros", "time", "fs"]
+
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
proc_pidinfo.workspace = true
From e52bd918fb6a4940c4621907ee68327a3462876c Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Fri, 6 Jun 2025 15:00:40 +0200
Subject: [PATCH 20/47] Hide tokio behind feature
---
common/client-core/surb-storage/Cargo.toml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/common/client-core/surb-storage/Cargo.toml b/common/client-core/surb-storage/Cargo.toml
index 1706008302..303675a220 100644
--- a/common/client-core/surb-storage/Cargo.toml
+++ b/common/client-core/surb-storage/Cargo.toml
@@ -12,12 +12,15 @@ dashmap.workspace = true
log.workspace = true
thiserror.workspace = true
time.workspace = true
-tokio = { workspace = true, features = ["fs"] }
nym-crypto = { path = "../../crypto", optional = true, default-features = false }
nym-sphinx = { path = "../../nymsphinx" }
nym-task = { path = "../../task" }
+[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
+workspace = true
+features = ["fs"]
+
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
From 3ac58e0c4980666010fae89428f61be665fae1c5 Mon Sep 17 00:00:00 2001
From: benedettadavico
Date: Wed, 11 Jun 2025 16:02:19 +0200
Subject: [PATCH 21/47] Clean up
remove old explorer references
---
.github/workflows/ci-build.yml | 1 -
.github/workflows/publish-nym-binaries.yml | 8 +-
common/network-defaults/build.rs | 1 -
common/network-defaults/src/mainnet.rs | 3 -
common/network-defaults/src/network.rs | 11 -
common/network-defaults/src/var_names.rs | 1 -
envs/canary.env | 1 -
envs/mainnet-local-api.env | 1 -
envs/mainnet.env | 1 -
envs/qa.env | 1 -
envs/sandbox.env | 1 -
explorer-nextjs/.eslintrc.json | 3 -
explorer-nextjs/.gitignore | 36 -
explorer-nextjs/README.md | 36 -
explorer-nextjs/app/App.tsx | 11 -
explorer-nextjs/app/account/[id]/page.tsx | 407 -
explorer-nextjs/app/api/constants.ts | 39 -
explorer-nextjs/app/api/index.ts | 217 -
explorer-nextjs/app/assets/world-110m.json | 39718 ----------------
.../app/components/ComponentError.tsx | 12 -
.../app/components/ContentCard.tsx | 38 -
.../app/components/CustomColumnHeading.tsx | 30 -
.../Delegations/ConfirmationModal.tsx | 83 -
.../Delegations/DelegateIconButton.tsx | 39 -
.../components/Delegations/DelegateModal.tsx | 191 -
.../Delegations/DelegationModal.tsx | 95 -
.../app/components/Delegations/ErrorModal.tsx | 28 -
.../components/Delegations/LoadingModal.tsx | 18 -
.../components/Delegations/ModalDivider.tsx | 6 -
.../components/Delegations/ModalListItem.tsx | 32 -
.../components/Delegations/SimpleModal.tsx | 152 -
.../app/components/Delegations/index.ts | 10 -
.../app/components/Delegations/styles.ts | 21 -
.../app/components/DetailTable.tsx | 146 -
.../app/components/Filters/Filters.tsx | 193 -
.../app/components/Filters/FiltersButton.tsx | 34 -
.../app/components/Filters/filterSchema.ts | 69 -
explorer-nextjs/app/components/Footer.tsx | 56 -
.../app/components/Gateways/Gateways.ts | 52 -
.../Gateways/VersionDisplaySelector.tsx | 51 -
explorer-nextjs/app/components/Icons.ts | 28 -
.../app/components/MixNodes/BondBreakdown.tsx | 213 -
.../app/components/MixNodes/DetailSection.tsx | 114 -
.../components/MixNodes/Economics/Columns.ts | 51 -
.../Economics/EconomicsProgress.stories.tsx | 31 -
.../MixNodes/Economics/EconomicsProgress.tsx | 38 -
.../Economics/MixNodeEconomics.stories.tsx | 107 -
.../app/components/MixNodes/Economics/Rows.ts | 57 -
.../Economics/StakeSaturationProgressBar.tsx | 47 -
.../components/MixNodes/Economics/Table.tsx | 91 -
.../components/MixNodes/Economics/index.ts | 3 -
.../components/MixNodes/Economics/types.ts | 20 -
.../app/components/MixNodes/Status.tsx | 36 -
.../components/MixNodes/StatusDropdown.tsx | 83 -
.../app/components/MixNodes/index.ts | 3 -
.../app/components/MixNodes/mappings.ts | 57 -
.../app/components/Nav/DesktopNav.tsx | 379 -
.../app/components/Nav/MobileNav.tsx | 147 -
explorer-nextjs/app/components/Nav/Navbar.tsx | 18 -
explorer-nextjs/app/components/Nav/Search.tsx | 76 -
.../app/components/NetworkTitle.tsx | 57 -
.../app/components/ReleaseAlert.tsx | 9 -
explorer-nextjs/app/components/Socials.tsx | 58 -
explorer-nextjs/app/components/StatsCard.tsx | 73 -
explorer-nextjs/app/components/StyledLink.tsx | 34 -
explorer-nextjs/app/components/Switch.tsx | 70 -
.../app/components/TableToolbar.tsx | 61 -
explorer-nextjs/app/components/Title.tsx | 14 -
explorer-nextjs/app/components/Tooltip.tsx | 36 -
.../app/components/TwoColSmallTable.tsx | 78 -
.../app/components/Universal-DataGrid.tsx | 96 -
.../app/components/UptimeChart.tsx | 115 -
.../components/Wallet/ConnectKeplrWallet.tsx | 50 -
.../app/components/Wallet/WalletAddress.tsx | 20 -
.../app/components/Wallet/WalletBalance.tsx | 25 -
.../app/components/Wallet/index.ts | 2 -
explorer-nextjs/app/components/WorldMap.tsx | 129 -
explorer-nextjs/app/components/index.ts | 9 -
explorer-nextjs/app/context/cosmos-kit.tsx | 73 -
explorer-nextjs/app/context/delegations.tsx | 252 -
explorer-nextjs/app/context/gateway.tsx | 69 -
explorer-nextjs/app/context/hooks.ts | 49 -
explorer-nextjs/app/context/main.tsx | 297 -
explorer-nextjs/app/context/mixnode.tsx | 173 -
explorer-nextjs/app/context/nav.tsx | 59 -
explorer-nextjs/app/context/node.tsx | 77 -
explorer-nextjs/app/context/wallet.tsx | 123 -
explorer-nextjs/app/delegations/page.tsx | 311 -
.../app/errors/ErrorBoundaryContent.tsx | 26 -
explorer-nextjs/app/hooks/index.ts | 4 -
.../app/hooks/useGetMixnodeStatusColor.ts | 19 -
explorer-nextjs/app/hooks/useIsMobile.ts | 11 -
explorer-nextjs/app/hooks/useIsMounted.ts | 16 -
explorer-nextjs/app/hooks/useNymClient.tsx | 44 -
explorer-nextjs/app/icons/DelevateSVG.tsx | 12 -
explorer-nextjs/app/icons/ElipsSVG.tsx | 20 -
explorer-nextjs/app/icons/GatewaysSVG.tsx | 28 -
explorer-nextjs/app/icons/LightSwitchSVG.tsx | 15 -
explorer-nextjs/app/icons/MixnodesSVG.tsx | 92 -
.../app/icons/MobileDrawerClose.tsx | 10 -
explorer-nextjs/app/icons/NetworksSVG.tsx | 18 -
explorer-nextjs/app/icons/NodemapSVG.tsx | 22 -
explorer-nextjs/app/icons/NymVpn.tsx | 58 -
explorer-nextjs/app/icons/OverviewSVG.tsx | 16 -
explorer-nextjs/app/icons/TokenSVG.tsx | 25 -
explorer-nextjs/app/icons/ValidatorsSVG.tsx | 47 -
.../app/icons/socials/DiscordIcon.tsx | 38 -
.../app/icons/socials/GitHubIcon.tsx | 32 -
.../app/icons/socials/TelegramIcon.tsx | 23 -
.../app/icons/socials/TwitterIcon.tsx | 30 -
explorer-nextjs/app/layout.tsx | 21 -
explorer-nextjs/app/loading.tsx | 10 -
.../network-components/gateways/[id]/page.tsx | 206 -
.../app/network-components/gateways/page.tsx | 256 -
.../network-components/mixnodes/[id]/page.tsx | 302 -
.../app/network-components/mixnodes/page.tsx | 382 -
.../network-components/nodes/DeclaredRole.tsx | 11 -
.../nodes/[id]/NodeDelegationsTable.tsx | 93 -
.../network-components/nodes/[id]/page.tsx | 336 -
.../app/network-components/nodes/page.tsx | 254 -
explorer-nextjs/app/nodemap/page.tsx | 85 -
explorer-nextjs/app/page.tsx | 144 -
explorer-nextjs/app/providers/index.tsx | 19 -
explorer-nextjs/app/theme/index.tsx | 15 -
explorer-nextjs/app/theme/mui-theme.d.ts | 36 -
explorer-nextjs/app/typeDefs/explorer-api.ts | 294 -
explorer-nextjs/app/typeDefs/filters.ts | 22 -
explorer-nextjs/app/typeDefs/network.ts | 1 -
explorer-nextjs/app/typeDefs/tables.ts | 8 -
explorer-nextjs/app/typings/FC.d.ts | 1 -
explorer-nextjs/app/typings/jpeg.d.ts | 9 -
explorer-nextjs/app/typings/json.d.ts | 4 -
explorer-nextjs/app/typings/png.d.ts | 4 -
.../app/typings/react-identicons.d.ts | 18 -
.../app/typings/react-tooltip.d.ts | 1 -
explorer-nextjs/app/typings/svg.d.ts | 4 -
explorer-nextjs/app/utils/currency.ts | 110 -
explorer-nextjs/app/utils/index.ts | 124 -
explorer-nextjs/next.config.mjs | 14 -
explorer-nextjs/package.json | 31 -
explorer-nextjs/public/favicon.ico | Bin 5430 -> 0 bytes
explorer-nextjs/public/next.svg | 1 -
explorer-nextjs/public/vercel.svg | 1 -
explorer-nextjs/tsconfig.json | 43 -
explorer/.babelrc | 3 -
explorer/.editorconfig | 18 -
explorer/.env.dev | 9 -
explorer/.env.prod | 6 -
explorer/.env.qa | 6 -
explorer/.eslintrc.js | 14 -
explorer/.gitignore | 4 -
explorer/.nvmrc | 1 -
explorer/.prettierrc | 6 -
explorer/.storybook/main.js | 63 -
explorer/.storybook/preview.js | 56 -
explorer/.vscode/settings.json | 5 -
explorer/CHANGELOG.md | 47 -
explorer/README.md | 77 -
explorer/docs/README.md | 48 -
explorer/jest.config.js | 5 -
explorer/package.json | 146 -
explorer/src/App.tsx | 22 -
explorer/src/api/constants.ts | 31 -
explorer/src/api/index.ts | 173 -
explorer/src/assets/world-110m.json | 39718 ----------------
explorer/src/components/ComponentError.tsx | 12 -
explorer/src/components/ContentCard.tsx | 40 -
.../src/components/CustomColumnHeading.tsx | 30 -
.../Delegations/ConfirmationModal.tsx | 83 -
.../Delegations/DelegateIconButton.tsx | 33 -
.../components/Delegations/DelegateModal.tsx | 166 -
.../Delegations/DelegationModal.tsx | 67 -
.../src/components/Delegations/ErrorModal.tsx | 28 -
.../components/Delegations/LoadingModal.tsx | 18 -
.../components/Delegations/ModalDivider.tsx | 6 -
.../components/Delegations/ModalListItem.tsx | 32 -
.../components/Delegations/SimpleModal.tsx | 112 -
explorer/src/components/Delegations/index.ts | 10 -
explorer/src/components/Delegations/styles.ts | 21 -
explorer/src/components/DetailTable.tsx | 127 -
explorer/src/components/Filters/Filters.tsx | 172 -
.../src/components/Filters/FiltersButton.tsx | 34 -
.../src/components/Filters/filterSchema.ts | 69 -
explorer/src/components/Footer.tsx | 53 -
explorer/src/components/Gateways.ts | 52 -
.../Gateways/VersionDisplaySelector.tsx | 42 -
explorer/src/components/Icons.ts | 28 -
.../src/components/MixNodes/BondBreakdown.tsx | 206 -
.../src/components/MixNodes/DetailSection.tsx | 95 -
.../components/MixNodes/Economics/Columns.ts | 51 -
.../Economics/EconomicsProgress.stories.tsx | 31 -
.../MixNodes/Economics/EconomicsProgress.tsx | 38 -
.../Economics/MixNodeEconomics.stories.tsx | 107 -
.../src/components/MixNodes/Economics/Rows.ts | 57 -
.../Economics/StakeSaturationProgressBar.tsx | 32 -
.../components/MixNodes/Economics/Table.tsx | 74 -
.../components/MixNodes/Economics/index.ts | 3 -
.../components/MixNodes/Economics/types.ts | 20 -
explorer/src/components/MixNodes/Status.tsx | 34 -
.../components/MixNodes/StatusDropdown.tsx | 77 -
explorer/src/components/MixNodes/index.ts | 3 -
explorer/src/components/MixNodes/mappings.ts | 57 -
explorer/src/components/MobileNav.tsx | 128 -
explorer/src/components/Nav.tsx | 401 -
explorer/src/components/NetworkTitle.tsx | 47 -
explorer/src/components/Socials.tsx | 40 -
explorer/src/components/StatsCard.tsx | 67 -
explorer/src/components/StyledLink.tsx | 28 -
explorer/src/components/Switch.tsx | 70 -
explorer/src/components/TableToolbar.tsx | 102 -
explorer/src/components/Title.tsx | 14 -
explorer/src/components/Tooltip.tsx | 36 -
explorer/src/components/TwoColSmallTable.tsx | 78 -
.../src/components/Universal-DataGrid.tsx | 96 -
explorer/src/components/UptimeChart.tsx | 115 -
.../components/Wallet/ConnectKeplrWallet.tsx | 43 -
.../src/components/Wallet/WalletAddress.tsx | 20 -
.../src/components/Wallet/WalletBalance.tsx | 25 -
explorer/src/components/Wallet/index.ts | 2 -
explorer/src/components/WorldMap.tsx | 113 -
.../src/components/delegatorsInfo/types.ts | 15 -
explorer/src/components/index.ts | 9 -
explorer/src/context/cosmos-kit.tsx | 71 -
explorer/src/context/delegations.tsx | 200 -
explorer/src/context/gateway.tsx | 59 -
explorer/src/context/hooks.ts | 47 -
explorer/src/context/main.tsx | 241 -
explorer/src/context/mixnode.tsx | 157 -
explorer/src/context/nav.tsx | 60 -
explorer/src/context/wallet.tsx | 90 -
explorer/src/errors/ErrorBoundaryContent.tsx | 24 -
explorer/src/hooks/index.ts | 4 -
.../src/hooks/useGetMixnodeStatusColor.ts | 17 -
explorer/src/hooks/useIsMobile.ts | 9 -
explorer/src/hooks/useIsMounted.ts | 14 -
explorer/src/hooks/useNymClient.tsx | 31 -
explorer/src/icons/DelevateSVG.tsx | 12 -
explorer/src/icons/ElipsSVG.tsx | 20 -
explorer/src/icons/GatewaysSVG.tsx | 28 -
explorer/src/icons/LightSwitchSVG.tsx | 15 -
explorer/src/icons/MixnodesSVG.tsx | 92 -
explorer/src/icons/MobileDrawerClose.tsx | 10 -
explorer/src/icons/NetworksSVG.tsx | 18 -
explorer/src/icons/NodemapSVG.tsx | 22 -
explorer/src/icons/NymVpn.tsx | 56 -
explorer/src/icons/OverviewSVG.tsx | 16 -
explorer/src/icons/TokenSVG.tsx | 25 -
explorer/src/icons/ValidatorsSVG.tsx | 47 -
explorer/src/icons/socials/DiscordIcon.tsx | 40 -
explorer/src/icons/socials/GitHubIcon.tsx | 34 -
explorer/src/icons/socials/TelegramIcon.tsx | 25 -
explorer/src/icons/socials/TwitterIcon.tsx | 32 -
explorer/src/index.html | 14 -
explorer/src/index.tsx | 33 -
explorer/src/pages/404/index.tsx | 49 -
explorer/src/pages/Delegations/index.tsx | 264 -
explorer/src/pages/GatewayDetail/index.tsx | 184 -
explorer/src/pages/Gateways/index.tsx | 271 -
explorer/src/pages/MixnodeDetail/index.tsx | 236 -
explorer/src/pages/Mixnodes/index.tsx | 427 -
explorer/src/pages/MixnodesMap/index.tsx | 114 -
explorer/src/pages/Overview/index.tsx | 130 -
explorer/src/pages/ServiceProviders/index.tsx | 135 -
explorer/src/routes/index.tsx | 17 -
explorer/src/routes/network-components.tsx | 27 -
explorer/src/stories/Introduction.stories.mdx | 7 -
explorer/src/styles.css | 30 -
explorer/src/tests/Nav.test.tsx | 13 -
explorer/src/tests/WorldMap.test.tsx | 28 -
explorer/src/tests/todo.test.ts | 7 -
explorer/src/theme/index.tsx | 8 -
explorer/src/theme/mui-theme.d.ts | 37 -
explorer/src/typeDefs/explorer-api.ts | 277 -
explorer/src/typeDefs/filters.ts | 22 -
explorer/src/typeDefs/network.ts | 1 -
explorer/src/typeDefs/tables.ts | 8 -
explorer/src/typings/FC.d.ts | 1 -
explorer/src/typings/jpeg.d.ts | 9 -
explorer/src/typings/json.d.ts | 4 -
explorer/src/typings/png.d.ts | 4 -
explorer/src/typings/react-identicons.d.ts | 18 -
explorer/src/typings/react-tooltip.d.ts | 1 -
explorer/src/typings/svg.d.ts | 4 -
explorer/src/utils/currency.ts | 100 -
explorer/src/utils/index.ts | 123 -
explorer/src/x-data-grid/LICENSE | 21 -
explorer/src/x-data-grid/README.md | 29 -
explorer/src/x-data-grid/package.json | 89 -
explorer/tsconfig.json | 15 -
explorer/webpack.common.js | 32 -
explorer/webpack.config.js | 76 -
explorer/webpack.prod.js | 52 -
.../nym-node-status-api/src/cli/mod.rs | 4 -
nym-wallet/nym-wallet-types/src/network/qa.rs | 3 -
.../nym-wallet-types/src/network/sandbox.rs | 3 -
.../testnet-manager/src/manager/network.rs | 1 -
.../src/manager/network_init.rs | 1 -
297 files changed, 5 insertions(+), 97804 deletions(-)
delete mode 100644 explorer-nextjs/.eslintrc.json
delete mode 100644 explorer-nextjs/.gitignore
delete mode 100644 explorer-nextjs/README.md
delete mode 100644 explorer-nextjs/app/App.tsx
delete mode 100644 explorer-nextjs/app/account/[id]/page.tsx
delete mode 100644 explorer-nextjs/app/api/constants.ts
delete mode 100644 explorer-nextjs/app/api/index.ts
delete mode 100644 explorer-nextjs/app/assets/world-110m.json
delete mode 100644 explorer-nextjs/app/components/ComponentError.tsx
delete mode 100644 explorer-nextjs/app/components/ContentCard.tsx
delete mode 100644 explorer-nextjs/app/components/CustomColumnHeading.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/ConfirmationModal.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/DelegateIconButton.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/DelegateModal.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/DelegationModal.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/ErrorModal.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/LoadingModal.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/ModalDivider.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/ModalListItem.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/SimpleModal.tsx
delete mode 100644 explorer-nextjs/app/components/Delegations/index.ts
delete mode 100644 explorer-nextjs/app/components/Delegations/styles.ts
delete mode 100644 explorer-nextjs/app/components/DetailTable.tsx
delete mode 100644 explorer-nextjs/app/components/Filters/Filters.tsx
delete mode 100644 explorer-nextjs/app/components/Filters/FiltersButton.tsx
delete mode 100644 explorer-nextjs/app/components/Filters/filterSchema.ts
delete mode 100644 explorer-nextjs/app/components/Footer.tsx
delete mode 100644 explorer-nextjs/app/components/Gateways/Gateways.ts
delete mode 100644 explorer-nextjs/app/components/Gateways/VersionDisplaySelector.tsx
delete mode 100644 explorer-nextjs/app/components/Icons.ts
delete mode 100644 explorer-nextjs/app/components/MixNodes/BondBreakdown.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/DetailSection.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/Columns.ts
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.stories.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/MixNodeEconomics.stories.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/Rows.ts
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/StakeSaturationProgressBar.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/Table.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/index.ts
delete mode 100644 explorer-nextjs/app/components/MixNodes/Economics/types.ts
delete mode 100644 explorer-nextjs/app/components/MixNodes/Status.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/StatusDropdown.tsx
delete mode 100644 explorer-nextjs/app/components/MixNodes/index.ts
delete mode 100644 explorer-nextjs/app/components/MixNodes/mappings.ts
delete mode 100644 explorer-nextjs/app/components/Nav/DesktopNav.tsx
delete mode 100644 explorer-nextjs/app/components/Nav/MobileNav.tsx
delete mode 100644 explorer-nextjs/app/components/Nav/Navbar.tsx
delete mode 100644 explorer-nextjs/app/components/Nav/Search.tsx
delete mode 100644 explorer-nextjs/app/components/NetworkTitle.tsx
delete mode 100644 explorer-nextjs/app/components/ReleaseAlert.tsx
delete mode 100644 explorer-nextjs/app/components/Socials.tsx
delete mode 100644 explorer-nextjs/app/components/StatsCard.tsx
delete mode 100644 explorer-nextjs/app/components/StyledLink.tsx
delete mode 100644 explorer-nextjs/app/components/Switch.tsx
delete mode 100644 explorer-nextjs/app/components/TableToolbar.tsx
delete mode 100644 explorer-nextjs/app/components/Title.tsx
delete mode 100644 explorer-nextjs/app/components/Tooltip.tsx
delete mode 100644 explorer-nextjs/app/components/TwoColSmallTable.tsx
delete mode 100644 explorer-nextjs/app/components/Universal-DataGrid.tsx
delete mode 100644 explorer-nextjs/app/components/UptimeChart.tsx
delete mode 100644 explorer-nextjs/app/components/Wallet/ConnectKeplrWallet.tsx
delete mode 100644 explorer-nextjs/app/components/Wallet/WalletAddress.tsx
delete mode 100644 explorer-nextjs/app/components/Wallet/WalletBalance.tsx
delete mode 100644 explorer-nextjs/app/components/Wallet/index.ts
delete mode 100644 explorer-nextjs/app/components/WorldMap.tsx
delete mode 100644 explorer-nextjs/app/components/index.ts
delete mode 100644 explorer-nextjs/app/context/cosmos-kit.tsx
delete mode 100644 explorer-nextjs/app/context/delegations.tsx
delete mode 100644 explorer-nextjs/app/context/gateway.tsx
delete mode 100644 explorer-nextjs/app/context/hooks.ts
delete mode 100644 explorer-nextjs/app/context/main.tsx
delete mode 100644 explorer-nextjs/app/context/mixnode.tsx
delete mode 100644 explorer-nextjs/app/context/nav.tsx
delete mode 100644 explorer-nextjs/app/context/node.tsx
delete mode 100644 explorer-nextjs/app/context/wallet.tsx
delete mode 100644 explorer-nextjs/app/delegations/page.tsx
delete mode 100644 explorer-nextjs/app/errors/ErrorBoundaryContent.tsx
delete mode 100644 explorer-nextjs/app/hooks/index.ts
delete mode 100644 explorer-nextjs/app/hooks/useGetMixnodeStatusColor.ts
delete mode 100644 explorer-nextjs/app/hooks/useIsMobile.ts
delete mode 100644 explorer-nextjs/app/hooks/useIsMounted.ts
delete mode 100644 explorer-nextjs/app/hooks/useNymClient.tsx
delete mode 100644 explorer-nextjs/app/icons/DelevateSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/ElipsSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/GatewaysSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/LightSwitchSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/MixnodesSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/MobileDrawerClose.tsx
delete mode 100644 explorer-nextjs/app/icons/NetworksSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/NodemapSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/NymVpn.tsx
delete mode 100644 explorer-nextjs/app/icons/OverviewSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/TokenSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/ValidatorsSVG.tsx
delete mode 100644 explorer-nextjs/app/icons/socials/DiscordIcon.tsx
delete mode 100644 explorer-nextjs/app/icons/socials/GitHubIcon.tsx
delete mode 100644 explorer-nextjs/app/icons/socials/TelegramIcon.tsx
delete mode 100644 explorer-nextjs/app/icons/socials/TwitterIcon.tsx
delete mode 100644 explorer-nextjs/app/layout.tsx
delete mode 100644 explorer-nextjs/app/loading.tsx
delete mode 100644 explorer-nextjs/app/network-components/gateways/[id]/page.tsx
delete mode 100644 explorer-nextjs/app/network-components/gateways/page.tsx
delete mode 100644 explorer-nextjs/app/network-components/mixnodes/[id]/page.tsx
delete mode 100644 explorer-nextjs/app/network-components/mixnodes/page.tsx
delete mode 100644 explorer-nextjs/app/network-components/nodes/DeclaredRole.tsx
delete mode 100644 explorer-nextjs/app/network-components/nodes/[id]/NodeDelegationsTable.tsx
delete mode 100644 explorer-nextjs/app/network-components/nodes/[id]/page.tsx
delete mode 100644 explorer-nextjs/app/network-components/nodes/page.tsx
delete mode 100644 explorer-nextjs/app/nodemap/page.tsx
delete mode 100644 explorer-nextjs/app/page.tsx
delete mode 100644 explorer-nextjs/app/providers/index.tsx
delete mode 100644 explorer-nextjs/app/theme/index.tsx
delete mode 100644 explorer-nextjs/app/theme/mui-theme.d.ts
delete mode 100644 explorer-nextjs/app/typeDefs/explorer-api.ts
delete mode 100644 explorer-nextjs/app/typeDefs/filters.ts
delete mode 100644 explorer-nextjs/app/typeDefs/network.ts
delete mode 100644 explorer-nextjs/app/typeDefs/tables.ts
delete mode 100644 explorer-nextjs/app/typings/FC.d.ts
delete mode 100644 explorer-nextjs/app/typings/jpeg.d.ts
delete mode 100644 explorer-nextjs/app/typings/json.d.ts
delete mode 100644 explorer-nextjs/app/typings/png.d.ts
delete mode 100644 explorer-nextjs/app/typings/react-identicons.d.ts
delete mode 100644 explorer-nextjs/app/typings/react-tooltip.d.ts
delete mode 100644 explorer-nextjs/app/typings/svg.d.ts
delete mode 100644 explorer-nextjs/app/utils/currency.ts
delete mode 100644 explorer-nextjs/app/utils/index.ts
delete mode 100644 explorer-nextjs/next.config.mjs
delete mode 100644 explorer-nextjs/package.json
delete mode 100644 explorer-nextjs/public/favicon.ico
delete mode 100644 explorer-nextjs/public/next.svg
delete mode 100644 explorer-nextjs/public/vercel.svg
delete mode 100644 explorer-nextjs/tsconfig.json
delete mode 100644 explorer/.babelrc
delete mode 100644 explorer/.editorconfig
delete mode 100644 explorer/.env.dev
delete mode 100644 explorer/.env.prod
delete mode 100644 explorer/.env.qa
delete mode 100644 explorer/.eslintrc.js
delete mode 100644 explorer/.gitignore
delete mode 100644 explorer/.nvmrc
delete mode 100644 explorer/.prettierrc
delete mode 100644 explorer/.storybook/main.js
delete mode 100644 explorer/.storybook/preview.js
delete mode 100644 explorer/.vscode/settings.json
delete mode 100644 explorer/CHANGELOG.md
delete mode 100644 explorer/README.md
delete mode 100644 explorer/docs/README.md
delete mode 100644 explorer/jest.config.js
delete mode 100644 explorer/package.json
delete mode 100644 explorer/src/App.tsx
delete mode 100644 explorer/src/api/constants.ts
delete mode 100644 explorer/src/api/index.ts
delete mode 100644 explorer/src/assets/world-110m.json
delete mode 100644 explorer/src/components/ComponentError.tsx
delete mode 100644 explorer/src/components/ContentCard.tsx
delete mode 100644 explorer/src/components/CustomColumnHeading.tsx
delete mode 100644 explorer/src/components/Delegations/ConfirmationModal.tsx
delete mode 100644 explorer/src/components/Delegations/DelegateIconButton.tsx
delete mode 100644 explorer/src/components/Delegations/DelegateModal.tsx
delete mode 100644 explorer/src/components/Delegations/DelegationModal.tsx
delete mode 100644 explorer/src/components/Delegations/ErrorModal.tsx
delete mode 100644 explorer/src/components/Delegations/LoadingModal.tsx
delete mode 100644 explorer/src/components/Delegations/ModalDivider.tsx
delete mode 100644 explorer/src/components/Delegations/ModalListItem.tsx
delete mode 100644 explorer/src/components/Delegations/SimpleModal.tsx
delete mode 100644 explorer/src/components/Delegations/index.ts
delete mode 100644 explorer/src/components/Delegations/styles.ts
delete mode 100644 explorer/src/components/DetailTable.tsx
delete mode 100644 explorer/src/components/Filters/Filters.tsx
delete mode 100644 explorer/src/components/Filters/FiltersButton.tsx
delete mode 100644 explorer/src/components/Filters/filterSchema.ts
delete mode 100644 explorer/src/components/Footer.tsx
delete mode 100644 explorer/src/components/Gateways.ts
delete mode 100644 explorer/src/components/Gateways/VersionDisplaySelector.tsx
delete mode 100644 explorer/src/components/Icons.ts
delete mode 100644 explorer/src/components/MixNodes/BondBreakdown.tsx
delete mode 100644 explorer/src/components/MixNodes/DetailSection.tsx
delete mode 100644 explorer/src/components/MixNodes/Economics/Columns.ts
delete mode 100644 explorer/src/components/MixNodes/Economics/EconomicsProgress.stories.tsx
delete mode 100644 explorer/src/components/MixNodes/Economics/EconomicsProgress.tsx
delete mode 100644 explorer/src/components/MixNodes/Economics/MixNodeEconomics.stories.tsx
delete mode 100644 explorer/src/components/MixNodes/Economics/Rows.ts
delete mode 100644 explorer/src/components/MixNodes/Economics/StakeSaturationProgressBar.tsx
delete mode 100644 explorer/src/components/MixNodes/Economics/Table.tsx
delete mode 100644 explorer/src/components/MixNodes/Economics/index.ts
delete mode 100644 explorer/src/components/MixNodes/Economics/types.ts
delete mode 100644 explorer/src/components/MixNodes/Status.tsx
delete mode 100644 explorer/src/components/MixNodes/StatusDropdown.tsx
delete mode 100644 explorer/src/components/MixNodes/index.ts
delete mode 100644 explorer/src/components/MixNodes/mappings.ts
delete mode 100644 explorer/src/components/MobileNav.tsx
delete mode 100644 explorer/src/components/Nav.tsx
delete mode 100644 explorer/src/components/NetworkTitle.tsx
delete mode 100644 explorer/src/components/Socials.tsx
delete mode 100644 explorer/src/components/StatsCard.tsx
delete mode 100644 explorer/src/components/StyledLink.tsx
delete mode 100644 explorer/src/components/Switch.tsx
delete mode 100644 explorer/src/components/TableToolbar.tsx
delete mode 100644 explorer/src/components/Title.tsx
delete mode 100644 explorer/src/components/Tooltip.tsx
delete mode 100644 explorer/src/components/TwoColSmallTable.tsx
delete mode 100644 explorer/src/components/Universal-DataGrid.tsx
delete mode 100644 explorer/src/components/UptimeChart.tsx
delete mode 100644 explorer/src/components/Wallet/ConnectKeplrWallet.tsx
delete mode 100644 explorer/src/components/Wallet/WalletAddress.tsx
delete mode 100644 explorer/src/components/Wallet/WalletBalance.tsx
delete mode 100644 explorer/src/components/Wallet/index.ts
delete mode 100644 explorer/src/components/WorldMap.tsx
delete mode 100644 explorer/src/components/delegatorsInfo/types.ts
delete mode 100644 explorer/src/components/index.ts
delete mode 100644 explorer/src/context/cosmos-kit.tsx
delete mode 100644 explorer/src/context/delegations.tsx
delete mode 100644 explorer/src/context/gateway.tsx
delete mode 100644 explorer/src/context/hooks.ts
delete mode 100644 explorer/src/context/main.tsx
delete mode 100644 explorer/src/context/mixnode.tsx
delete mode 100644 explorer/src/context/nav.tsx
delete mode 100644 explorer/src/context/wallet.tsx
delete mode 100644 explorer/src/errors/ErrorBoundaryContent.tsx
delete mode 100644 explorer/src/hooks/index.ts
delete mode 100644 explorer/src/hooks/useGetMixnodeStatusColor.ts
delete mode 100644 explorer/src/hooks/useIsMobile.ts
delete mode 100644 explorer/src/hooks/useIsMounted.ts
delete mode 100644 explorer/src/hooks/useNymClient.tsx
delete mode 100644 explorer/src/icons/DelevateSVG.tsx
delete mode 100644 explorer/src/icons/ElipsSVG.tsx
delete mode 100644 explorer/src/icons/GatewaysSVG.tsx
delete mode 100644 explorer/src/icons/LightSwitchSVG.tsx
delete mode 100644 explorer/src/icons/MixnodesSVG.tsx
delete mode 100644 explorer/src/icons/MobileDrawerClose.tsx
delete mode 100644 explorer/src/icons/NetworksSVG.tsx
delete mode 100644 explorer/src/icons/NodemapSVG.tsx
delete mode 100644 explorer/src/icons/NymVpn.tsx
delete mode 100644 explorer/src/icons/OverviewSVG.tsx
delete mode 100644 explorer/src/icons/TokenSVG.tsx
delete mode 100644 explorer/src/icons/ValidatorsSVG.tsx
delete mode 100644 explorer/src/icons/socials/DiscordIcon.tsx
delete mode 100644 explorer/src/icons/socials/GitHubIcon.tsx
delete mode 100644 explorer/src/icons/socials/TelegramIcon.tsx
delete mode 100644 explorer/src/icons/socials/TwitterIcon.tsx
delete mode 100644 explorer/src/index.html
delete mode 100644 explorer/src/index.tsx
delete mode 100644 explorer/src/pages/404/index.tsx
delete mode 100644 explorer/src/pages/Delegations/index.tsx
delete mode 100644 explorer/src/pages/GatewayDetail/index.tsx
delete mode 100644 explorer/src/pages/Gateways/index.tsx
delete mode 100644 explorer/src/pages/MixnodeDetail/index.tsx
delete mode 100644 explorer/src/pages/Mixnodes/index.tsx
delete mode 100644 explorer/src/pages/MixnodesMap/index.tsx
delete mode 100644 explorer/src/pages/Overview/index.tsx
delete mode 100644 explorer/src/pages/ServiceProviders/index.tsx
delete mode 100644 explorer/src/routes/index.tsx
delete mode 100644 explorer/src/routes/network-components.tsx
delete mode 100644 explorer/src/stories/Introduction.stories.mdx
delete mode 100644 explorer/src/styles.css
delete mode 100644 explorer/src/tests/Nav.test.tsx
delete mode 100644 explorer/src/tests/WorldMap.test.tsx
delete mode 100644 explorer/src/tests/todo.test.ts
delete mode 100644 explorer/src/theme/index.tsx
delete mode 100644 explorer/src/theme/mui-theme.d.ts
delete mode 100644 explorer/src/typeDefs/explorer-api.ts
delete mode 100644 explorer/src/typeDefs/filters.ts
delete mode 100644 explorer/src/typeDefs/network.ts
delete mode 100644 explorer/src/typeDefs/tables.ts
delete mode 100644 explorer/src/typings/FC.d.ts
delete mode 100644 explorer/src/typings/jpeg.d.ts
delete mode 100644 explorer/src/typings/json.d.ts
delete mode 100644 explorer/src/typings/png.d.ts
delete mode 100644 explorer/src/typings/react-identicons.d.ts
delete mode 100644 explorer/src/typings/react-tooltip.d.ts
delete mode 100644 explorer/src/typings/svg.d.ts
delete mode 100644 explorer/src/utils/currency.ts
delete mode 100644 explorer/src/utils/index.ts
delete mode 100644 explorer/src/x-data-grid/LICENSE
delete mode 100644 explorer/src/x-data-grid/README.md
delete mode 100644 explorer/src/x-data-grid/package.json
delete mode 100644 explorer/tsconfig.json
delete mode 100644 explorer/webpack.common.js
delete mode 100644 explorer/webpack.config.js
delete mode 100644 explorer/webpack.prod.js
diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index 5863df8822..be2ede84c1 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -5,7 +5,6 @@ on:
paths:
- 'clients/**'
- 'common/**'
- - 'explorer-api/**'
- 'gateway/**'
- 'integrations/**'
- 'nym-api/**'
diff --git a/.github/workflows/publish-nym-binaries.yml b/.github/workflows/publish-nym-binaries.yml
index 618304e9ae..07b358c45f 100644
--- a/.github/workflows/publish-nym-binaries.yml
+++ b/.github/workflows/publish-nym-binaries.yml
@@ -19,7 +19,11 @@ jobs:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
strategy:
fail-fast: false
- runs-on: arc-ubuntu-22.04
+ matrix:
+ include:
+ - os: arc-ubuntu-22.04
+ target: x86_64-unknown-linux-gnu
+ runs-on: ${{ matrix.os }}
outputs:
release_id: ${{ steps.create-release.outputs.id }}
@@ -66,7 +70,6 @@ jobs:
with:
name: my-artifact
path: |
- target/release/explorer-api
target/release/nym-client
target/release/nym-socks5-client
target/release/nym-api
@@ -82,7 +85,6 @@ jobs:
if: github.event_name == 'release'
with:
files: |
- target/release/explorer-api
target/release/nym-client
target/release/nym-socks5-client
target/release/nym-api
diff --git a/common/network-defaults/build.rs b/common/network-defaults/build.rs
index aa52baa876..64de45df77 100644
--- a/common/network-defaults/build.rs
+++ b/common/network-defaults/build.rs
@@ -23,7 +23,6 @@ fn main() {
"REWARDING_VALIDATOR_ADDRESS",
"NYM_API",
"NYXD_WS",
- "EXPLORER_API",
"NYM_VPN_API",
];
diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs
index 2b54d17406..501c46651b 100644
--- a/common/network-defaults/src/mainnet.rs
+++ b/common/network-defaults/src/mainnet.rs
@@ -31,7 +31,6 @@ pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772
pub const NYXD_URL: &str = "https://rpc.nymtech.net";
pub const NYM_API: &str = "https://validator.nymtech.net/api/";
pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket";
-pub const EXPLORER_API: &str = "https://explorer.nymtech.net/api/";
pub const NYM_VPN_API: &str = "https://nymvpn.com/api/";
// I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging
@@ -123,7 +122,6 @@ pub fn export_to_env() {
set_var_to_default(var_names::NYXD, NYXD_URL);
set_var_to_default(var_names::NYM_API, NYM_API);
set_var_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
- set_var_to_default(var_names::EXPLORER_API, EXPLORER_API);
set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
set_var_to_default(var_names::NYM_VPN_API, NYM_VPN_API);
}
@@ -165,6 +163,5 @@ pub fn export_to_env_if_not_set() {
set_var_conditionally_to_default(var_names::NYXD, NYXD_URL);
set_var_conditionally_to_default(var_names::NYM_API, NYM_API);
set_var_conditionally_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
- set_var_conditionally_to_default(var_names::EXPLORER_API, EXPLORER_API);
set_var_conditionally_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
}
diff --git a/common/network-defaults/src/network.rs b/common/network-defaults/src/network.rs
index 8cebe53340..5a3e6ab711 100644
--- a/common/network-defaults/src/network.rs
+++ b/common/network-defaults/src/network.rs
@@ -35,7 +35,6 @@ pub struct NymNetworkDetails {
pub chain_details: ChainDetails,
pub endpoints: Vec,
pub contracts: NymContracts,
- pub explorer_api: Option,
pub nym_vpn_api_url: Option,
}
@@ -65,7 +64,6 @@ impl NymNetworkDetails {
},
endpoints: Default::default(),
contracts: Default::default(),
- explorer_api: Default::default(),
nym_vpn_api_url: Default::default(),
}
}
@@ -124,7 +122,6 @@ impl NymNetworkDetails {
.with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS))
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
- .with_explorer_api(get_optional_env(var_names::EXPLORER_API))
.with_nym_vpn_api_url(get_optional_env(var_names::NYM_VPN_API))
}
@@ -152,7 +149,6 @@ impl NymNetworkDetails {
mainnet::COCONUT_DKG_CONTRACT_ADDRESS,
),
},
- explorer_api: parse_optional_str(mainnet::EXPLORER_API),
nym_vpn_api_url: parse_optional_str(mainnet::NYM_VPN_API),
}
}
@@ -193,7 +189,6 @@ impl NymNetworkDetails {
set_optional_var(var_names::MULTISIG_CONTRACT_ADDRESS, self.contracts.multisig_contract_address);
set_optional_var(var_names::COCONUT_DKG_CONTRACT_ADDRESS, self.contracts.coconut_dkg_contract_address);
- set_optional_var(var_names::EXPLORER_API, self.explorer_api);
set_optional_var(var_names::NYM_VPN_API, self.nym_vpn_api_url);
}
@@ -297,12 +292,6 @@ impl NymNetworkDetails {
self
}
- #[must_use]
- pub fn with_explorer_api>(mut self, endpoint: Option) -> Self {
- self.explorer_api = endpoint.map(Into::into);
- self
- }
-
#[must_use]
pub fn with_nym_vpn_api_url>(mut self, endpoint: Option) -> Self {
self.nym_vpn_api_url = endpoint.map(Into::into);
diff --git a/common/network-defaults/src/var_names.rs b/common/network-defaults/src/var_names.rs
index bf92b95799..5bcebe85eb 100644
--- a/common/network-defaults/src/var_names.rs
+++ b/common/network-defaults/src/var_names.rs
@@ -22,7 +22,6 @@ pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS";
pub const NYXD: &str = "NYXD";
pub const NYM_API: &str = "NYM_API";
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
-pub const EXPLORER_API: &str = "EXPLORER_API";
pub const EXIT_POLICY_URL: &str = "EXIT_POLICY";
pub const NYM_VPN_API: &str = "NYM_VPN_API";
pub const CLIENT_STATS_COLLECTION_PROVIDER: &str = "CLIENT_STATS_COLLECTION_PROVIDER";
diff --git a/envs/canary.env b/envs/canary.env
index 6bdd85494e..f494ad3270 100644
--- a/envs/canary.env
+++ b/envs/canary.env
@@ -18,7 +18,6 @@ GROUP_CONTRACT_ADDRESS=n1qg5ega6dykkxc307y25pecuufrjkxkaggkkxh7nad0vhyhtuhw3sa07
MULTISIG_CONTRACT_ADDRESS=n1zwv6feuzhy6a9wekh96cd57lsarmqlwxdypdsplw6zhfncqw6ftqx5a364
COCONUT_DKG_CONTRACT_ADDRESS=n1aakfpghcanxtc45gpqlx8j3rq0zcpyf49qmhm9mdjrfx036h4z5sy2vfh9
-EXPLORER_API=https://canary-explorer.performance.nymte.ch/api/
NYXD=https://rpc.canary-validator.performance.nymte.ch
NYM_API=https://canary-api.performance.nymte.ch/api/
NYXD_WS=wss://rpc.canary-validator.performance.nymte.ch/websocket
diff --git a/envs/mainnet-local-api.env b/envs/mainnet-local-api.env
index d6683c937d..f7d1fec6d5 100644
--- a/envs/mainnet-local-api.env
+++ b/envs/mainnet-local-api.env
@@ -23,5 +23,4 @@ STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090"
NYXD="https://rpc.nymtech.net"
NYM_API="http://127.0.0.1:8000"
NYXD_WS="wss://rpc.nymtech.net/websocket"
-EXPLORER_API="https://explorer.nymtech.net/api/"
NYM_VPN_API="https://nymvpn.com/api"
diff --git a/envs/mainnet.env b/envs/mainnet.env
index ad1e2cd88e..444307f836 100644
--- a/envs/mainnet.env
+++ b/envs/mainnet.env
@@ -24,5 +24,4 @@ STATISTICS_SERVICE_DOMAIN_ADDRESS=https://mainnet-stats.nymte.ch:8090
NYXD=https://rpc.nymtech.net
NYM_API=https://validator.nymtech.net/api/
NYXD_WS=wss://rpc.nymtech.net/websocket
-EXPLORER_API=https://explorer.nymtech.net/api/
NYM_VPN_API=https://nymvpn.com/api/
diff --git a/envs/qa.env b/envs/qa.env
index 2a4fddb0a7..1a350109e2 100644
--- a/envs/qa.env
+++ b/envs/qa.env
@@ -18,7 +18,6 @@ COCONUT_DKG_CONTRACT_ADDRESS=n1pk8jgr6y4c5k93gz7qf3xc0hvygmp7csk88c2tf8l39tkq683
VESTING_CONTRACT_ADDRESS=n1jlzdxnyces4hrhqz68dqk28mrw5jgwtcfq0c2funcwrmw0dx9l9s8nnnvj
REWARDING_VALIDATOR_ADDRESS=n1rfvpsynktze6wvn6ldskj8xgwfzzk5v6pnff39
-EXPLORER_API=https://qa-network-explorer.qa.nymte.ch/api/
NYXD=https://rpc.qa-validator.qa.nymte.ch
NYXD_WS=wss://rpc.qa-validator.qa.nymte.ch/websocket
NYM_API=https://qa-nym-api.qa.nymte.ch/api/
diff --git a/envs/sandbox.env b/envs/sandbox.env
index 68e51fec59..e90257f015 100644
--- a/envs/sandbox.env
+++ b/envs/sandbox.env
@@ -19,7 +19,6 @@ COCONUT_DKG_CONTRACT_ADDRESS=n1v3n2ly2dp3a9ng3ff6rh26yfkn0pc5hed7w2shc5u9ca5c865
ECASH_CONTRACT_ADDRESS=n1v3vydvs2ued84yv3khqwtgldmgwn0elljsdh08dr5s2j9x4rc5fs9jlwz9
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
-EXPLORER_API=https://sandbox-explorer.nymtech.net/api/
NYXD=https://rpc.sandbox.nymtech.net
NYXD_WS=wss://rpc.sandbox.nymtech.net/websocket
NYM_API=https://sandbox-nym-api1.nymtech.net/api/
diff --git a/explorer-nextjs/.eslintrc.json b/explorer-nextjs/.eslintrc.json
deleted file mode 100644
index 957cd1545e..0000000000
--- a/explorer-nextjs/.eslintrc.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": ["next/core-web-vitals"]
-}
diff --git a/explorer-nextjs/.gitignore b/explorer-nextjs/.gitignore
deleted file mode 100644
index fd3dbb571a..0000000000
--- a/explorer-nextjs/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-.yarn/install-state.gz
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# local env files
-.env*.local
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts
diff --git a/explorer-nextjs/README.md b/explorer-nextjs/README.md
deleted file mode 100644
index c4033664f8..0000000000
--- a/explorer-nextjs/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
-
-## Getting Started
-
-First, run the development server:
-
-```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
-```
-
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
-
-This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/explorer-nextjs/app/App.tsx b/explorer-nextjs/app/App.tsx
deleted file mode 100644
index 6763797c84..0000000000
--- a/explorer-nextjs/app/App.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-import { Navbar } from './components/Nav/Navbar'
-import { Providers } from './providers'
-
-const App = ({ children }: { children: React.ReactNode }) => (
-
- {children}
-
-)
-
-export { App }
diff --git a/explorer-nextjs/app/account/[id]/page.tsx b/explorer-nextjs/app/account/[id]/page.tsx
deleted file mode 100644
index c0c482476c..0000000000
--- a/explorer-nextjs/app/account/[id]/page.tsx
+++ /dev/null
@@ -1,407 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {Alert, AlertTitle, Box, Button, Chip, CircularProgress, Grid, Tooltip, Typography} from '@mui/material'
-import { useParams } from 'next/navigation'
-import { useMainContext } from '@/app/context/main'
-import { Title } from '@/app/components/Title'
-import { MaterialReactTable, MRT_ColumnDef, useMaterialReactTable } from "material-react-table";
-import { useMemo } from "react";
-import { humanReadableCurrencyToString } from "@/app/utils/currency";
-import Table from '@mui/material/Table';
-import TableBody from '@mui/material/TableBody';
-import TableCell from '@mui/material/TableCell';
-import TableContainer from '@mui/material/TableContainer';
-import TableRow from '@mui/material/TableRow';
-import Paper from '@mui/material/Paper';
-import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
-import WarningAmberIcon from '@mui/icons-material/WarningAmber';
-import { PieChart } from '@mui/x-charts/PieChart';
-import { useTheme } from "@mui/material/styles";
-import { useIsMobile } from "@/app/hooks";
-import { StyledLink } from "@/app/components";
-
-const AccumulatedRewards = ({account}: { account?: any}) => {
- const columns = useMemo<
- MRT_ColumnDef[]
- >(() => {
- return [
- {
- id: 'accumulated-rewards-data',
- header: 'Accumulated Rewards Data',
- columns: [
- {
- id: 'node_id',
- accessorKey: 'node_id',
- header: 'Node ID',
- size: 150,
- Cell: ({ row }) => (
- {row.original.node_id}
- ),
- },
- {
- id: 'node_still_fully_bonded',
- accessorKey: 'node_still_fully_bonded',
- header: 'Node still bonded?',
- width: 150,
- Cell: ({ row }) => (
- <>{row.original.node_still_fully_bonded ? :
- theme.palette.warning.main }}>
-
- Unbonded
- }>
- )
- },
- {
- id: 'amount_staked',
- accessorKey: 'amount_staked',
- header: 'Amount',
- width: 150,
- Cell: ({ row }) => (
- <>{humanReadableCurrencyToString(row.original.amount_staked)}>
- )
- },
- {
- id: 'rewards',
- accessorKey: 'rewards',
- header: 'Rewards',
- width: 150,
- Cell: ({ row }) => (
- {humanReadableCurrencyToString(row.original.rewards)}
- )
- },
- ],
- },
- ]
- }, [])
-
- const table = useMaterialReactTable({
- columns,
- data: account?.accumulated_rewards || [],
- enableFullScreenToggle: false,
- })
-
- return ();
-}
-
-const DelegationHistory = ({account}: { account?: any}) => {
- const columns = useMemo<
- MRT_ColumnDef[]
- >(() => {
- return [
- {
- id: 'delegation-history-data',
- header: 'Delegation History',
- columns: [
- {
- id: 'node_id',
- accessorKey: 'node_id',
- header: 'Node ID',
- size: 150,
- },
- {
- id: 'delegated',
- accessorKey: 'delegated',
- header: 'Amount',
- width: 150,
- Cell: ({ row }) => (
- <>{humanReadableCurrencyToString(row.original.delegated)}>
- )
- },
- {
- id: 'height',
- accessorKey: 'height',
- header: 'Delegated at height',
- width: 150,
- Cell: ({ row }) => (
- <>{row.original.height}>
- )
- },
- ],
- },
- ]
- }, [])
-
- const table = useMaterialReactTable({
- columns,
- data: account?.delegations || [],
- enableFullScreenToggle: false,
- })
-
- return ();
-}
-
-
-/**
- * Shows account details
- */
-const PageAccountWithState = ({ account }: {
- account?: any;
-}) => {
- const theme = useTheme();
- const isMobile = useIsMobile();
-
- const pieChartData = React.useMemo(() => {
- if(!account) {
- return [];
- }
-
- const parts = [];
-
- const nymBalance = Number.parseFloat(account.balances.find((b: any) => b.denom === "unym")?.amount || "0") / 1e6;
-
- if(nymBalance > 0) {
- parts.push({label: "Spendable", value: nymBalance, color: theme.palette.primary.main});
- }
-
- if(account.vesting_account) {
- if (`${account.vesting_account.locked?.amount}` !== "0") {
- const value = Number.parseFloat(account.vesting_account.locked.amount) / 1e6;
- if(value > 0) {
- parts.push({
- label: "Vesting locked",
- value,
- color: 'red'
- });
- }
- }
- if (`${account.vesting_account.spendable?.amount}` !== "0") {
- const value = Number.parseFloat(account.vesting_account.spendable.amount) / 1e6;
- if(value > 0) {
- parts.push({
- label: "Vesting spendable",
- value,
- color: theme.palette.primary.light
- });
- }
- }
- }
-
- if (account.claimable_rewards &&`${account.claimable_rewards.amount}` !== "0") {
- const value = Number.parseFloat(account.claimable_rewards.amount) / 1e6;
- if(value > 0) {
- parts.push({
- label: "Claimable delegation rewards",
- value,
- color: theme.palette.success.light
- });
- }
- }
- if (account.operator_rewards && `${account.operator_rewards.amount}` !== "0") {
- const value = Number.parseFloat(account.operator_rewards.amount) / 1e6;
- if(value > 0) {
- parts.push({
- label: "Claimable operator rewards",
- value,
- color: theme.palette.success.dark
- });
- }
- }
- if (account.total_delegations && `${account.total_delegations.amount}` !== "0") {
- const value = Number.parseFloat(account.total_delegations.amount) / 1e6;
- if(value > 0) {
- parts.push({
- label: "Total delegations",
- value,
- color: '#888'
- });
- }
- }
-
- return parts;
- }, [account]);
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
- theme.palette.primary.main }}>
-
- Spendable Balance
-
-
- {account.balances.map((b: any) => ({humanReadableCurrencyToString(b)}
))}
-
-
-
-
- Total delegations
-
-
- {humanReadableCurrencyToString(account.total_delegations)}
-
-
- {account.claimable_rewards && theme.palette.success.light }}>
-
- Claimable delegation rewards
-
-
- {humanReadableCurrencyToString(account.claimable_rewards)}
-
- }
- {account.operator_rewards && `${account.operator_rewards.amount}` !== "0" && theme.palette.success.light }}>
-
- Claimable operator rewards
-
-
- {humanReadableCurrencyToString(account.operator_rewards)}
-
- }
- {account.vesting_account && (
- <>
-
-
- Vesting account
-
-
- {`${account.vesting_account.locked.amount}` !== "0" &&
-
-
- Locked
-
-
- {humanReadableCurrencyToString(account.vesting_account.locked)}
-
-
- }
- {`${account.vesting_account.vested.amount}` !== "0" &&
-
-
- Vested
-
-
- {humanReadableCurrencyToString(account.vesting_account.vested)}
-
-
- }
- {`${account.vesting_account.vesting.amount}` !== "0" &&
-
-
- Vesting
-
-
- {humanReadableCurrencyToString(account.vesting_account.vesting)}
-
-
- }
- {`${account.vesting_account.spendable.amount}` !== "0" &&
-
-
- Spendable
-
-
- {humanReadableCurrencyToString(account.vesting_account.spendable)}
-
-
- }
- >
- )}
-
-
- Total value
-
-
- {humanReadableCurrencyToString(account.total_value)}
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
-
-/**
- * Guard component to handle loading and not found states
- */
-const PageAccountDetailGuard = ({ account } : { account: string }) => {
- const [accountDetails, setAccountDetails] = React.useState();
- const [isLoading, setLoading] = React.useState(true);
- const [error, setError] = React.useState();
- const { fetchAccountById } = useMainContext()
- const { id } = useParams()
-
- React.useEffect(() => {
- setLoading(true);
- (async () => {
- if(typeof(id) === "string") {
- try {
- const res = await fetchAccountById(account);
- setAccountDetails(res);
- } catch(e: any) {
- setError(e.message);
- }
- finally {
- setLoading(false);
- }
- }
- })();
- }, [id])
-
- if (isLoading) {
- return
- }
-
- // loaded, but not found
- if (error) {
- return (
-
- Account not found
- Sorry, we could not find the account {id || ''}
-
- )
- }
-
- return
-}
-
-/**
- * Wrapper component that adds the account details based on the `id` in the address URL
- */
-const PageAccountDetail = () => {
- const { id } = useParams()
-
- if (!id || typeof id !== 'string') {
- return (
- Oh no! Could not find that account
- )
- }
-
- return (
-
- )
-}
-
-export default PageAccountDetail
diff --git a/explorer-nextjs/app/api/constants.ts b/explorer-nextjs/app/api/constants.ts
deleted file mode 100644
index 515655c184..0000000000
--- a/explorer-nextjs/app/api/constants.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// master APIs
-export const API_BASE_URL = process.env.NEXT_PUBLIC_EXPLORER_API_URL || 'https://explorer.nymtech.net/api/v1';
-export const NYM_API_BASE_URL = process.env.NEXT_PUBLIC_NYM_API_URL || 'https://validator.nymtech.net';
-
-export const NYX_RPC_BASE_URL = process.env.NEXT_PUBLIC_NYX_RPC_BASE_URL || 'https://rpc.nymtech.net';
-
-export const VALIDATOR_BASE_URL = process.env.NEXT_PUBLIC_VALIDATOR_URL || 'https://rpc.nymtech.net';
-export const BLOCK_EXPLORER_BASE_URL = process.env.NEXT_PUBLIC_BIG_DIPPER_URL || 'https://nym.explorers.guru';
-
-// specific API routes
-export const OVERVIEW_API = `${API_BASE_URL}/overview`;
-export const MIXNODE_PING = `${API_BASE_URL}/ping`;
-export const MIXNODES_API = `${API_BASE_URL}/mix-nodes`;
-export const MIXNODE_API = `${API_BASE_URL}/mix-node`;
-export const VALIDATORS_API = `${NYX_RPC_BASE_URL}/validators`;
-export const BLOCK_API = `${NYX_RPC_BASE_URL}/block`;
-export const COUNTRY_DATA_API = `${API_BASE_URL}/countries`;
-export const UPTIME_STORY_API = `${NYM_API_BASE_URL}/api/v1/status/mixnode`; // add ID then '/history' to this.
-export const UPTIME_STORY_API_GATEWAY = `${NYM_API_BASE_URL}/api/v1/status/gateway`; // add ID then '/history' or '/report' to this
-export const SERVICE_PROVIDERS = `${API_BASE_URL}/service-providers`;
-export const TEMP_UNSTABLE_NYM_NODES = `${API_BASE_URL}/tmp/unstable/nym-nodes`;
-export const TEMP_UNSTABLE_ACCOUNT = `${API_BASE_URL}/tmp/unstable/account`;
-export const NYM_API_NODE_UPTIME = `${NYM_API_BASE_URL}/api/v1/nym-nodes/uptime-history`;
-export const NYM_API_NODE_PERFORMANCE = `${NYM_API_BASE_URL}/api/v1/nym-nodes/performance-history`;
-
-export const LEGACY_MIXNODES_API = `${API_BASE_URL}/tmp/unstable/legacy-mixnode-bonds`;
-export const LEGACY_GATEWAYS_API = `${API_BASE_URL}/tmp/unstable/legacy-gateway-bonds`;
-
-// errors
-export const MIXNODE_API_ERROR = "We're having trouble finding that record, please try again or Contact Us.";
-
-export const NYM_WEBSITE = 'https://nymtech.net';
-
-export const EXPLORER_FOR_ACCOUNTS = ''; // set to empty to use this Nym Explorer and NOT an external one
-
-export const NYM_MIXNET_CONTRACT =
- process.env.NYM_MIXNET_CONTRACT || 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr';
-export const COSMOS_KIT_USE_CHAIN = process.env.NEXT_PUBLIC_COSMOS_KIT_USE_CHAIN || 'sandbox';
-export const WALLET_CONNECT_PROJECT_ID = process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID || '';
diff --git a/explorer-nextjs/app/api/index.ts b/explorer-nextjs/app/api/index.ts
deleted file mode 100644
index ae190de9b9..0000000000
--- a/explorer-nextjs/app/api/index.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-import keyBy from 'lodash/keyBy';
-import {
- API_BASE_URL,
- BLOCK_API,
- COUNTRY_DATA_API,
- UPTIME_STORY_API_GATEWAY,
- MIXNODE_API,
- MIXNODE_PING,
- MIXNODES_API,
- OVERVIEW_API,
- UPTIME_STORY_API,
- VALIDATORS_API,
- SERVICE_PROVIDERS,
- TEMP_UNSTABLE_NYM_NODES,
- NYM_API_NODE_UPTIME,
- NYM_API_NODE_PERFORMANCE,
- TEMP_UNSTABLE_ACCOUNT,
- LEGACY_MIXNODES_API, LEGACY_GATEWAYS_API,
-} from './constants';
-
-import {
- CountryDataResponse,
- DelegationsResponse,
- UniqDelegationsResponse,
- GatewayReportResponse,
- UptimeStoryResponse,
- MixNodeDescriptionResponse,
- MixNodeResponse,
- MixNodeResponseItem,
- MixnodeStatus,
- MixNodeEconomicDynamicsStatsResponse,
- StatsResponse,
- StatusResponse,
- SummaryOverviewResponse,
- ValidatorsResponse,
- Environment,
- GatewayBondAnnotated,
- GatewayBond,
- DirectoryServiceProvider,
- LocatedGateway,
-} from '../typeDefs/explorer-api';
-
-function getFromCache(key: string) {
- const ts = Number(localStorage.getItem('ts'));
- const hasExpired = Date.now() - ts > 5000;
- const curr = localStorage.getItem(key);
- if (curr && !hasExpired) {
- return JSON.parse(curr);
- }
- return undefined;
-}
-
-function storeInCache(key: string, data: any) {
- localStorage.setItem(key, data);
- localStorage.setItem('ts', Date.now().toString());
-}
-
-export class Api {
- static fetchOverviewSummary = async (): Promise => {
- const cache = getFromCache('overview-summary');
- if (cache) {
- return cache;
- }
- const res = await fetch(`${OVERVIEW_API}/summary`);
- const json: SummaryOverviewResponse = await res.json();
-
- if (json.nymnodes?.roles) {
- json.mixnodes.count += json.nymnodes.roles.mixnode;
- json.gateways.count += json.nymnodes.roles.entry;
- json.gateways.count += Math.max(json.nymnodes.roles.exit_ipr, json.nymnodes.roles.exit_nr);
- }
-
- storeInCache('overview-summary', JSON.stringify(json));
- return json;
- };
-
- static fetchMixnodes = async (): Promise => {
- const cachedMixnodes = getFromCache('mixnodes');
- if (cachedMixnodes) {
- return cachedMixnodes;
- }
-
- const res = await fetch(LEGACY_MIXNODES_API);
- const json = await res.json();
- storeInCache('mixnodes', JSON.stringify(json));
- return json;
- };
-
- static fetchMixnodesActiveSetByStatus = async (status: MixnodeStatus): Promise => {
- const cachedMixnodes = getFromCache(`mixnodes-${status}`);
- if (cachedMixnodes) {
- return cachedMixnodes;
- }
- const res = await fetch(`${MIXNODES_API}/active-set/${status}`);
- const json = await res.json();
- storeInCache(`mixnodes-${status}`, JSON.stringify(json));
- return json;
- };
-
- static fetchMixnodeByID = async (id: string): Promise => {
- const response = await fetch(`${MIXNODE_API}/${id}`);
-
- // when the mixnode is not found, returned undefined
- if (response.status === 404) {
- return undefined;
- }
-
- return response.json();
- };
-
- static fetchGateways = async (): Promise => {
- // const res = await fetch(GATEWAYS_API);
- // const gatewaysAnnotated: GatewayBondAnnotated[] = await res.json();
- // const res2 = await fetch(GATEWAYS_EXPLORER_API);
- // const locatedGateways: LocatedGateway[] = await res2.json();
- // const locatedGatewaysByOwner = keyBy(locatedGateways, 'owner');
- // return gatewaysAnnotated.map(({ gateway_bond, node_performance }) => ({
- // ...gateway_bond,
- // node_performance,
- // location: locatedGatewaysByOwner[gateway_bond.owner]?.location,
- // }));
-
- const res = await fetch(LEGACY_GATEWAYS_API);
- const locatedGateways: LocatedGateway[] = await res.json();
- return locatedGateways;
- };
-
- static fetchGatewayUptimeStoryById = async (id: string): Promise =>
- (await fetch(`${UPTIME_STORY_API_GATEWAY}/${id}/history`)).json();
-
- static fetchGatewayReportById = async (id: string): Promise =>
- (await fetch(`${UPTIME_STORY_API_GATEWAY}/${id}/report`)).json();
-
- static fetchValidators = async (): Promise => {
- const res = await fetch(VALIDATORS_API);
- const json = await res.json();
- return json.result;
- };
-
- static fetchBlock = async (): Promise => {
- const res = await fetch(BLOCK_API);
- const json = await res.json();
- const { height } = json.result.block.header;
- return height;
- };
-
- static fetchCountryData = async (): Promise => {
- const result: CountryDataResponse = {};
- const res = await fetch(COUNTRY_DATA_API);
- const json = await res.json();
- Object.keys(json).forEach((ISO3) => {
- result[ISO3] = { ISO3, nodes: json[ISO3] };
- });
- return result;
- };
-
- static fetchDelegationsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/delegations`)).json();
-
- static fetchUniqDelegationsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/delegations/summed`)).json();
-
- static fetchStatsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/stats`)).json();
-
- static fetchMixnodeDescriptionById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/description`)).json();
-
- static fetchMixnodeEconomicDynamicsStatsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/economic-dynamics-stats`)).json();
-
- static fetchStatusById = async (id: string): Promise => (await fetch(`${MIXNODE_PING}/${id}`)).json();
-
- static fetchUptimeStoryById = async (id: string): Promise =>
- (await fetch(`${UPTIME_STORY_API}/${id}/history`)).json();
-
- static fetchServiceProviders = async (): Promise => {
- const res = await fetch(SERVICE_PROVIDERS);
- const json = await res.json();
- return json;
- };
-
- static fetchNodes = async () => {
- const res = await fetch(TEMP_UNSTABLE_NYM_NODES);
- const json = await res.json();
- return json;
- }
-
- static fetchNodeById = async (id: number) => {
- const res = await fetch(`${TEMP_UNSTABLE_NYM_NODES}/${id}`);
- const json = await res.json();
- return json;
- }
-
- static fetchNymNodeUptimeHistoryById = async (id: number | string) => {
- const res = await fetch(`${NYM_API_NODE_UPTIME}/${id}`)
- const json = await res.json();
- return json;
- }
-
- static fetchNymNodePerformanceById = async (id: number | string) => {
- const res = await fetch(`${NYM_API_NODE_PERFORMANCE}/${id}`)
- const json = await res.json();
- return json;
- }
-
- static fetchAccountById = async (id: string) => {
- const res = await fetch(`${TEMP_UNSTABLE_ACCOUNT}/${id}`);
- const json = await res.json();
- return json;
- }
-}
-
-export const getEnvironment = (): Environment => {
- const matchEnv = (env: Environment) => API_BASE_URL?.toLocaleLowerCase().includes(env) && env;
- return matchEnv('sandbox') || matchEnv('qa') || 'mainnet';
-};
diff --git a/explorer-nextjs/app/assets/world-110m.json b/explorer-nextjs/app/assets/world-110m.json
deleted file mode 100644
index 5c999c82ca..0000000000
--- a/explorer-nextjs/app/assets/world-110m.json
+++ /dev/null
@@ -1,39718 +0,0 @@
-{
- "type": "Topology",
- "arcs": [
- [
- [
- 16814,
- 15074
- ],
- [
- 71,
- -45
- ],
- [
- 53,
- 16
- ],
- [
- 15,
- 54
- ],
- [
- 55,
- 18
- ],
- [
- 39,
- 37
- ],
- [
- 14,
- 95
- ],
- [
- 59,
- 24
- ],
- [
- 11,
- 42
- ],
- [
- 32,
- -32
- ],
- [
- 21,
- -3
- ]
- ],
- [
- [
- 17184,
- 15280
- ],
- [
- 39,
- -1
- ],
- [
- 53,
- -26
- ]
- ],
- [
- [
- 17276,
- 15253
- ],
- [
- 21,
- -14
- ],
- [
- 51,
- 38
- ],
- [
- 23,
- -23
- ],
- [
- 23,
- 55
- ],
- [
- 41,
- -2
- ],
- [
- 11,
- 17
- ],
- [
- 7,
- 49
- ],
- [
- 30,
- 41
- ],
- [
- 38,
- -27
- ],
- [
- -8,
- -37
- ],
- [
- 22,
- -5
- ],
- [
- -7,
- -101
- ],
- [
- 28,
- -39
- ],
- [
- 24,
- 25
- ],
- [
- 31,
- 12
- ],
- [
- 43,
- 53
- ],
- [
- 48,
- -8
- ],
- [
- 72,
- -1
- ]
- ],
- [
- [
- 17774,
- 15286
- ],
- [
- 13,
- -34
- ]
- ],
- [
- [
- 17787,
- 15252
- ],
- [
- -41,
- -13
- ],
- [
- -35,
- -23
- ],
- [
- -80,
- -14
- ],
- [
- -75,
- -25
- ],
- [
- -41,
- -52
- ],
- [
- 17,
- -51
- ],
- [
- 8,
- -60
- ],
- [
- -35,
- -50
- ],
- [
- 3,
- -46
- ],
- [
- -19,
- -43
- ],
- [
- -67,
- 4
- ],
- [
- 28,
- -80
- ],
- [
- -45,
- -30
- ],
- [
- -29,
- -73
- ],
- [
- 4,
- -72
- ],
- [
- -28,
- -33
- ],
- [
- -26,
- 11
- ],
- [
- -53,
- -16
- ],
- [
- -7,
- -33
- ],
- [
- -52,
- 0
- ],
- [
- -39,
- -68
- ],
- [
- -3,
- -102
- ],
- [
- -90,
- -50
- ],
- [
- -49,
- 10
- ],
- [
- -14,
- -26
- ],
- [
- -42,
- 15
- ],
- [
- -69,
- -17
- ],
- [
- -117,
- 61
- ]
- ],
- [
- [
- 16791,
- 14376
- ],
- [
- 63,
- 109
- ],
- [
- -6,
- 77
- ],
- [
- -52,
- 20
- ],
- [
- -6,
- 76
- ],
- [
- -23,
- 96
- ],
- [
- 30,
- 66
- ],
- [
- -30,
- 17
- ],
- [
- 19,
- 88
- ],
- [
- 28,
- 149
- ]
- ],
- [
- [
- 14166,
- 8695
- ],
- [
- -128,
- -49
- ],
- [
- -169,
- 17
- ],
- [
- -48,
- 58
- ],
- [
- -283,
- -6
- ],
- [
- -11,
- -8
- ],
- [
- -41,
- 54
- ],
- [
- -45,
- 4
- ],
- [
- -42,
- -21
- ],
- [
- -34,
- -22
- ]
- ],
- [
- [
- 13365,
- 8722
- ],
- [
- -6,
- 75
- ],
- [
- 10,
- 105
- ],
- [
- 24,
- 110
- ],
- [
- 3,
- 52
- ],
- [
- 23,
- 108
- ],
- [
- 16,
- 49
- ],
- [
- 41,
- 79
- ],
- [
- 22,
- 53
- ],
- [
- 7,
- 89
- ],
- [
- -3,
- 68
- ],
- [
- -21,
- 43
- ],
- [
- -19,
- 72
- ],
- [
- -17,
- 72
- ],
- [
- 4,
- 25
- ],
- [
- 21,
- 48
- ],
- [
- -21,
- 116
- ],
- [
- -14,
- 80
- ],
- [
- -35,
- 76
- ],
- [
- 6,
- 23
- ]
- ],
- [
- [
- 13406,
- 10065
- ],
- [
- 29,
- 16
- ],
- [
- 20,
- -2
- ],
- [
- 25,
- 15
- ],
- [
- 206,
- -2
- ],
- [
- 17,
- -89
- ],
- [
- 20,
- -72
- ],
- [
- 16,
- -39
- ],
- [
- 27,
- -63
- ],
- [
- 46,
- 10
- ],
- [
- 23,
- 17
- ],
- [
- 38,
- -17
- ],
- [
- 11,
- 30
- ],
- [
- 17,
- 70
- ],
- [
- 43,
- 4
- ],
- [
- 4,
- 21
- ],
- [
- 36,
- 1
- ],
- [
- -6,
- -44
- ],
- [
- 84,
- 2
- ],
- [
- 1,
- -76
- ],
- [
- 15,
- -46
- ],
- [
- -11,
- -73
- ],
- [
- 5,
- -73
- ],
- [
- 24,
- -45
- ],
- [
- -4,
- -143
- ],
- [
- 17,
- 11
- ],
- [
- 30,
- -3
- ],
- [
- 44,
- 18
- ],
- [
- 31,
- -7
- ]
- ],
- [
- [
- 14214,
- 9486
- ],
- [
- 8,
- -37
- ],
- [
- -8,
- -58
- ],
- [
- 12,
- -56
- ],
- [
- -10,
- -45
- ],
- [
- 6,
- -42
- ],
- [
- -146,
- 2
- ],
- [
- -3,
- -382
- ],
- [
- 47,
- -98
- ],
- [
- 46,
- -75
- ]
- ],
- [
- [
- 13397,
- 10103
- ],
- [
- -19,
- 90
- ]
- ],
- [
- [
- 13378,
- 10193
- ],
- [
- 28,
- 52
- ],
- [
- 21,
- 20
- ],
- [
- 26,
- -41
- ]
- ],
- [
- [
- 13453,
- 10224
- ],
- [
- -25,
- -26
- ],
- [
- -11,
- -30
- ],
- [
- -3,
- -53
- ],
- [
- -17,
- -12
- ]
- ],
- [
- [
- 14013,
- 15697
- ],
- [
- -2,
- -31
- ],
- [
- -22,
- -18
- ],
- [
- -4,
- -39
- ],
- [
- -33,
- -58
- ]
- ],
- [
- [
- 13952,
- 15551
- ],
- [
- -12,
- 8
- ],
- [
- -1,
- 27
- ],
- [
- -39,
- 40
- ],
- [
- -6,
- 57
- ],
- [
- 6,
- 82
- ],
- [
- 10,
- 37
- ],
- [
- -12,
- 19
- ]
- ],
- [
- [
- 13898,
- 15821
- ],
- [
- -5,
- 38
- ],
- [
- 30,
- 59
- ],
- [
- 5,
- -22
- ],
- [
- 19,
- 11
- ]
- ],
- [
- [
- 13947,
- 15907
- ],
- [
- 14,
- -33
- ],
- [
- 17,
- -12
- ],
- [
- 5,
- -43
- ]
- ],
- [
- [
- 13983,
- 15819
- ],
- [
- -9,
- -41
- ],
- [
- 10,
- -52
- ],
- [
- 29,
- -29
- ]
- ],
- [
- [
- 16143,
- 13706
- ],
- [
- 12,
- 6
- ],
- [
- 3,
- -33
- ],
- [
- 55,
- 19
- ],
- [
- 57,
- -3
- ],
- [
- 42,
- -4
- ],
- [
- 48,
- 81
- ],
- [
- 52,
- 77
- ],
- [
- 44,
- 74
- ]
- ],
- [
- [
- 16456,
- 13923
- ],
- [
- 13,
- -41
- ]
- ],
- [
- [
- 16469,
- 13882
- ],
- [
- 10,
- -95
- ]
- ],
- [
- [
- 16479,
- 13787
- ],
- [
- -36,
- 0
- ],
- [
- -5,
- -78
- ],
- [
- 12,
- -17
- ],
- [
- -32,
- -24
- ],
- [
- 0,
- -49
- ],
- [
- -20,
- -49
- ],
- [
- -2,
- -49
- ]
- ],
- [
- [
- 16396,
- 13521
- ],
- [
- -14,
- -25
- ],
- [
- -210,
- 61
- ],
- [
- -26,
- 121
- ],
- [
- -3,
- 28
- ]
- ],
- [
- [
- 7880,
- 4211
- ],
- [
- -42,
- 4
- ],
- [
- -75,
- 0
- ],
- [
- 0,
- 267
- ]
- ],
- [
- [
- 7763,
- 4482
- ],
- [
- 27,
- -55
- ],
- [
- 35,
- -90
- ],
- [
- 90,
- -72
- ],
- [
- 98,
- -30
- ],
- [
- -31,
- -60
- ],
- [
- -67,
- -6
- ],
- [
- -35,
- 42
- ]
- ],
- [
- [
- 7767,
- 4523
- ],
- [
- -64,
- 19
- ],
- [
- -169,
- 16
- ],
- [
- -28,
- 70
- ],
- [
- 1,
- 90
- ],
- [
- -47,
- -8
- ],
- [
- -24,
- 43
- ],
- [
- -6,
- 128
- ],
- [
- 53,
- 52
- ],
- [
- 22,
- 76
- ],
- [
- -8,
- 61
- ],
- [
- 37,
- 102
- ],
- [
- 26,
- 159
- ],
- [
- -8,
- 71
- ],
- [
- 31,
- 22
- ],
- [
- -8,
- 46
- ],
- [
- -32,
- 24
- ],
- [
- 23,
- 50
- ],
- [
- -32,
- 46
- ],
- [
- -16,
- 138
- ],
- [
- 28,
- 24
- ],
- [
- -12,
- 147
- ],
- [
- 17,
- 122
- ],
- [
- 18,
- 107
- ],
- [
- 42,
- 44
- ],
- [
- -21,
- 117
- ],
- [
- 0,
- 110
- ],
- [
- 52,
- 79
- ],
- [
- -1,
- 100
- ],
- [
- 40,
- 117
- ],
- [
- 0,
- 110
- ],
- [
- -18,
- 22
- ],
- [
- -32,
- 207
- ],
- [
- 43,
- 124
- ],
- [
- -7,
- 116
- ],
- [
- 25,
- 109
- ],
- [
- 46,
- 113
- ],
- [
- 49,
- 74
- ],
- [
- -21,
- 47
- ],
- [
- 14,
- 39
- ],
- [
- -2,
- 200
- ],
- [
- 76,
- 59
- ],
- [
- 24,
- 125
- ],
- [
- -8,
- 30
- ]
- ],
- [
- [
- 7870,
- 8070
- ],
- [
- 58,
- 108
- ],
- [
- 91,
- -29
- ],
- [
- 41,
- -87
- ],
- [
- 27,
- 97
- ],
- [
- 80,
- -5
- ],
- [
- 11,
- -26
- ]
- ],
- [
- [
- 8178,
- 8128
- ],
- [
- 128,
- -196
- ],
- [
- 57,
- -18
- ],
- [
- 85,
- -89
- ],
- [
- 72,
- -47
- ],
- [
- 10,
- -52
- ],
- [
- -69,
- -183
- ],
- [
- 71,
- -32
- ],
- [
- 78,
- -19
- ],
- [
- 55,
- 20
- ],
- [
- 63,
- 91
- ],
- [
- 12,
- 106
- ]
- ],
- [
- [
- 8740,
- 7709
- ],
- [
- 34,
- 23
- ],
- [
- 35,
- -69
- ],
- [
- -1,
- -96
- ],
- [
- -59,
- -66
- ],
- [
- -47,
- -49
- ],
- [
- -78,
- -116
- ],
- [
- -93,
- -164
- ]
- ],
- [
- [
- 8531,
- 7172
- ],
- [
- -18,
- -96
- ],
- [
- -19,
- -123
- ],
- [
- 1,
- -120
- ],
- [
- -15,
- -26
- ],
- [
- -5,
- -78
- ]
- ],
- [
- [
- 8475,
- 6729
- ],
- [
- -5,
- -63
- ],
- [
- 88,
- -102
- ],
- [
- -9,
- -83
- ],
- [
- 43,
- -52
- ],
- [
- -3,
- -59
- ],
- [
- -67,
- -154
- ],
- [
- -103,
- -64
- ],
- [
- -140,
- -25
- ],
- [
- -77,
- 12
- ],
- [
- 15,
- -71
- ],
- [
- -14,
- -90
- ],
- [
- 12,
- -61
- ],
- [
- -41,
- -42
- ],
- [
- -72,
- -17
- ],
- [
- -67,
- 44
- ],
- [
- -27,
- -31
- ],
- [
- 10,
- -119
- ],
- [
- 47,
- -37
- ],
- [
- 38,
- 38
- ],
- [
- 21,
- -62
- ],
- [
- -64,
- -37
- ],
- [
- -56,
- -75
- ],
- [
- -10,
- -121
- ],
- [
- -17,
- -64
- ],
- [
- -66,
- 0
- ],
- [
- -54,
- -62
- ],
- [
- -20,
- -90
- ],
- [
- 68,
- -87
- ],
- [
- 67,
- -25
- ],
- [
- -24,
- -107
- ],
- [
- -83,
- -68
- ],
- [
- -45,
- -141
- ],
- [
- -63,
- -47
- ],
- [
- -29,
- -56
- ],
- [
- 22,
- -125
- ],
- [
- 47,
- -69
- ],
- [
- -30,
- 6
- ]
- ],
- [
- [
- 15586,
- 15727
- ],
- [
- 96,
- 19
- ]
- ],
- [
- [
- 15682,
- 15746
- ],
- [
- 15,
- -32
- ],
- [
- 26,
- -21
- ],
- [
- -14,
- -30
- ],
- [
- 38,
- -41
- ],
- [
- -20,
- -38
- ],
- [
- 29,
- -33
- ],
- [
- 32,
- -19
- ],
- [
- 1,
- -84
- ]
- ],
- [
- [
- 15789,
- 15448
- ],
- [
- -25,
- -3
- ]
- ],
- [
- [
- 15764,
- 15445
- ],
- [
- -28,
- 69
- ],
- [
- 0,
- 19
- ],
- [
- -31,
- 0
- ],
- [
- -20,
- 32
- ],
- [
- -15,
- -3
- ]
- ],
- [
- [
- 15670,
- 15562
- ],
- [
- -27,
- 35
- ],
- [
- -52,
- 29
- ],
- [
- 6,
- 59
- ],
- [
- -11,
- 42
- ]
- ],
- [
- [
- 8395,
- 1195
- ],
- [
- -21,
- -61
- ],
- [
- -20,
- -54
- ],
- [
- -146,
- 16
- ],
- [
- -156,
- -7
- ],
- [
- -87,
- 40
- ],
- [
- 0,
- 5
- ],
- [
- -38,
- 35
- ],
- [
- 157,
- -5
- ],
- [
- 150,
- -11
- ],
- [
- 52,
- 49
- ],
- [
- 36,
- 42
- ],
- [
- 73,
- -49
- ]
- ],
- [
- [
- 1449,
- 1260
- ],
- [
- -133,
- -16
- ],
- [
- -92,
- 42
- ],
- [
- -41,
- 42
- ],
- [
- -3,
- 7
- ],
- [
- -45,
- 33
- ],
- [
- 43,
- 45
- ],
- [
- 129,
- -19
- ],
- [
- 70,
- -38
- ],
- [
- 53,
- -42
- ],
- [
- 19,
- -54
- ]
- ],
- [
- [
- 9400,
- 1434
- ],
- [
- 86,
- -52
- ],
- [
- 30,
- -73
- ],
- [
- 8,
- -51
- ],
- [
- 3,
- -61
- ],
- [
- -108,
- -38
- ],
- [
- -113,
- -31
- ],
- [
- -131,
- -28
- ],
- [
- -147,
- -23
- ],
- [
- -165,
- 7
- ],
- [
- -91,
- 40
- ],
- [
- 12,
- 49
- ],
- [
- 149,
- 33
- ],
- [
- 60,
- 40
- ],
- [
- 44,
- 52
- ],
- [
- 31,
- 44
- ],
- [
- 42,
- 43
- ],
- [
- 45,
- 49
- ],
- [
- 36,
- 0
- ],
- [
- 104,
- 26
- ],
- [
- 105,
- -26
- ]
- ],
- [
- [
- 4098,
- 1979
- ],
- [
- 90,
- -18
- ],
- [
- 83,
- 21
- ],
- [
- -39,
- -43
- ],
- [
- -66,
- -30
- ],
- [
- -97,
- 9
- ],
- [
- -69,
- 43
- ],
- [
- 15,
- 40
- ],
- [
- 83,
- -22
- ]
- ],
- [
- [
- 3795,
- 1982
- ],
- [
- 106,
- -47
- ],
- [
- -41,
- 4
- ],
- [
- -90,
- 12
- ],
- [
- -95,
- 33
- ],
- [
- 50,
- 26
- ],
- [
- 70,
- -28
- ]
- ],
- [
- [
- 5648,
- 2167
- ],
- [
- 76,
- -16
- ],
- [
- 77,
- 14
- ],
- [
- 41,
- -68
- ],
- [
- -55,
- 9
- ],
- [
- -85,
- -4
- ],
- [
- -86,
- 4
- ],
- [
- -94,
- -7
- ],
- [
- -71,
- 24
- ],
- [
- -37,
- 49
- ],
- [
- 44,
- 21
- ],
- [
- 89,
- -16
- ],
- [
- 101,
- -10
- ]
- ],
- [
- [
- 7776,
- 2285
- ],
- [
- 8,
- -54
- ],
- [
- -12,
- -47
- ],
- [
- -19,
- -45
- ],
- [
- -82,
- -16
- ],
- [
- -78,
- -24
- ],
- [
- -92,
- 2
- ],
- [
- 35,
- 47
- ],
- [
- -82,
- -16
- ],
- [
- -78,
- -17
- ],
- [
- -53,
- 36
- ],
- [
- -5,
- 49
- ],
- [
- 77,
- 47
- ],
- [
- 48,
- 14
- ],
- [
- 80,
- -5
- ],
- [
- 21,
- 62
- ],
- [
- 4,
- 44
- ],
- [
- -2,
- 97
- ],
- [
- 40,
- 56
- ],
- [
- 64,
- 19
- ],
- [
- 37,
- -45
- ],
- [
- 17,
- -44
- ],
- [
- 30,
- -55
- ],
- [
- 23,
- -51
- ],
- [
- 19,
- -54
- ]
- ],
- [
- [
- 8462,
- 3101
- ],
- [
- -30,
- -26
- ],
- [
- -52,
- 19
- ],
- [
- -58,
- -12
- ],
- [
- -47,
- -28
- ],
- [
- -51,
- -31
- ],
- [
- -34,
- -35
- ],
- [
- -10,
- -47
- ],
- [
- 4,
- -45
- ],
- [
- 33,
- -40
- ],
- [
- -48,
- -28
- ],
- [
- -65,
- -9
- ],
- [
- -38,
- -40
- ],
- [
- -41,
- -38
- ],
- [
- -44,
- -51
- ],
- [
- -11,
- -45
- ],
- [
- 25,
- -50
- ],
- [
- 37,
- -37
- ],
- [
- 57,
- -28
- ],
- [
- 53,
- -38
- ],
- [
- 29,
- -47
- ],
- [
- 15,
- -45
- ],
- [
- 20,
- -47
- ],
- [
- 33,
- -40
- ],
- [
- 21,
- -44
- ],
- [
- 9,
- -111
- ],
- [
- 21,
- -44
- ],
- [
- 5,
- -47
- ],
- [
- 22,
- -47
- ],
- [
- -10,
- -64
- ],
- [
- -38,
- -49
- ],
- [
- -41,
- -40
- ],
- [
- -93,
- -17
- ],
- [
- -31,
- -42
- ],
- [
- -42,
- -40
- ],
- [
- -106,
- -45
- ],
- [
- -92,
- -18
- ],
- [
- -88,
- -26
- ],
- [
- -94,
- -26
- ],
- [
- -56,
- -50
- ],
- [
- -112,
- -4
- ],
- [
- -123,
- 4
- ],
- [
- -110,
- -9
- ],
- [
- -118,
- 0
- ],
- [
- 22,
- -47
- ],
- [
- 107,
- -21
- ],
- [
- 77,
- -33
- ],
- [
- 44,
- -42
- ],
- [
- -78,
- -38
- ],
- [
- -120,
- 12
- ],
- [
- -100,
- -31
- ],
- [
- -4,
- -49
- ],
- [
- -2,
- -47
- ],
- [
- 82,
- -40
- ],
- [
- 15,
- -45
- ],
- [
- 88,
- -44
- ],
- [
- 148,
- -19
- ],
- [
- 125,
- -33
- ],
- [
- 100,
- -38
- ],
- [
- 127,
- -37
- ],
- [
- 173,
- -19
- ],
- [
- 171,
- -33
- ],
- [
- 119,
- -35
- ],
- [
- 130,
- -40
- ],
- [
- 68,
- -57
- ],
- [
- 34,
- -44
- ],
- [
- 85,
- 42
- ],
- [
- 114,
- 35
- ],
- [
- 122,
- 38
- ],
- [
- 144,
- 30
- ],
- [
- 125,
- 33
- ],
- [
- 173,
- 3
- ],
- [
- 171,
- -17
- ],
- [
- 140,
- -28
- ],
- [
- 45,
- 52
- ],
- [
- 97,
- 35
- ],
- [
- 177,
- 2
- ],
- [
- 137,
- 26
- ],
- [
- 131,
- 26
- ],
- [
- 145,
- 16
- ],
- [
- 154,
- 22
- ],
- [
- 108,
- 30
- ],
- [
- -49,
- 42
- ],
- [
- -30,
- 43
- ],
- [
- 0,
- 44
- ],
- [
- -135,
- -4
- ],
- [
- -143,
- -19
- ],
- [
- -137,
- 0
- ],
- [
- -19,
- 45
- ],
- [
- 10,
- 89
- ],
- [
- 31,
- 26
- ],
- [
- 100,
- 28
- ],
- [
- 117,
- 28
- ],
- [
- 85,
- 35
- ],
- [
- 84,
- 36
- ],
- [
- 63,
- 47
- ],
- [
- 96,
- 21
- ],
- [
- 94,
- 16
- ],
- [
- 48,
- 10
- ],
- [
- 108,
- 4
- ],
- [
- 102,
- 17
- ],
- [
- 86,
- 23
- ],
- [
- 85,
- 29
- ],
- [
- 76,
- 28
- ],
- [
- 97,
- 37
- ],
- [
- 61,
- 40
- ],
- [
- 66,
- 36
- ],
- [
- 20,
- 47
- ],
- [
- -73,
- 28
- ],
- [
- 24,
- 49
- ],
- [
- 47,
- 38
- ],
- [
- 72,
- 23
- ],
- [
- 77,
- 29
- ],
- [
- 71,
- 37
- ],
- [
- 54,
- 47
- ],
- [
- 34,
- 57
- ],
- [
- 51,
- 33
- ],
- [
- 83,
- -7
- ],
- [
- 34,
- -40
- ],
- [
- 83,
- -5
- ],
- [
- 3,
- 45
- ],
- [
- 36,
- 47
- ],
- [
- 75,
- -12
- ],
- [
- 18,
- -45
- ],
- [
- 83,
- -7
- ],
- [
- 90,
- 21
- ],
- [
- 87,
- 14
- ],
- [
- 80,
- -7
- ],
- [
- 30,
- -49
- ],
- [
- 76,
- 40
- ],
- [
- 71,
- 21
- ],
- [
- 79,
- 16
- ],
- [
- 78,
- 17
- ],
- [
- 71,
- 28
- ],
- [
- 78,
- 19
- ],
- [
- 60,
- 26
- ],
- [
- 42,
- 42
- ],
- [
- 52,
- -30
- ],
- [
- 72,
- 16
- ],
- [
- 51,
- -56
- ],
- [
- 40,
- -43
- ],
- [
- 79,
- 24
- ],
- [
- 31,
- 47
- ],
- [
- 71,
- 33
- ],
- [
- 92,
- -7
- ],
- [
- 27,
- -45
- ],
- [
- 57,
- 45
- ],
- [
- 75,
- 14
- ],
- [
- 82,
- 4
- ],
- [
- 74,
- -2
- ],
- [
- 78,
- -14
- ],
- [
- 75,
- -7
- ],
- [
- 33,
- -40
- ],
- [
- 45,
- -35
- ],
- [
- 76,
- 21
- ],
- [
- 82,
- 5
- ],
- [
- 79,
- 0
- ],
- [
- 78,
- 2
- ],
- [
- 70,
- 16
- ],
- [
- 74,
- 15
- ],
- [
- 61,
- 32
- ],
- [
- 65,
- 22
- ],
- [
- 71,
- 11
- ],
- [
- 54,
- 33
- ],
- [
- 38,
- 66
- ],
- [
- 40,
- 40
- ],
- [
- 72,
- -19
- ],
- [
- 27,
- -42
- ],
- [
- 60,
- -28
- ],
- [
- 73,
- 9
- ],
- [
- 49,
- -42
- ],
- [
- 52,
- -31
- ],
- [
- 71,
- 28
- ],
- [
- 24,
- 52
- ],
- [
- 63,
- 21
- ],
- [
- 72,
- 40
- ],
- [
- 69,
- 17
- ],
- [
- 82,
- 23
- ],
- [
- 54,
- 26
- ],
- [
- 58,
- 28
- ],
- [
- 54,
- 26
- ],
- [
- 66,
- -14
- ],
- [
- 63,
- 42
- ],
- [
- 45,
- 33
- ],
- [
- 65,
- -2
- ],
- [
- 57,
- 28
- ],
- [
- 14,
- 42
- ],
- [
- 59,
- 33
- ],
- [
- 57,
- 24
- ],
- [
- 70,
- 19
- ],
- [
- 64,
- 9
- ],
- [
- 61,
- -7
- ],
- [
- 66,
- -12
- ],
- [
- 56,
- -33
- ],
- [
- 7,
- -51
- ],
- [
- 61,
- -40
- ],
- [
- 42,
- -33
- ],
- [
- 84,
- -14
- ],
- [
- 46,
- -33
- ],
- [
- 58,
- -33
- ],
- [
- 66,
- -7
- ],
- [
- 56,
- 23
- ],
- [
- 60,
- 50
- ],
- [
- 66,
- -26
- ],
- [
- 68,
- -14
- ],
- [
- 66,
- -14
- ],
- [
- 68,
- -10
- ],
- [
- 70,
- 0
- ],
- [
- 57,
- -124
- ],
- [
- -3,
- -31
- ],
- [
- -8,
- -54
- ],
- [
- -67,
- -31
- ],
- [
- -54,
- -44
- ],
- [
- 9,
- -47
- ],
- [
- 78,
- 2
- ],
- [
- -10,
- -47
- ],
- [
- -35,
- -45
- ],
- [
- -33,
- -49
- ],
- [
- 53,
- -38
- ],
- [
- 81,
- -11
- ],
- [
- 81,
- 21
- ],
- [
- 38,
- 47
- ],
- [
- 23,
- 45
- ],
- [
- 38,
- 37
- ],
- [
- 44,
- 35
- ],
- [
- 18,
- 43
- ],
- [
- 36,
- 58
- ],
- [
- 44,
- 12
- ],
- [
- 79,
- 5
- ],
- [
- 70,
- 14
- ],
- [
- 71,
- 19
- ],
- [
- 34,
- 47
- ],
- [
- 21,
- 45
- ],
- [
- 47,
- 44
- ],
- [
- 69,
- 31
- ],
- [
- 58,
- 23
- ],
- [
- 39,
- 40
- ],
- [
- 39,
- 21
- ],
- [
- 51,
- 19
- ],
- [
- 69,
- -12
- ],
- [
- 63,
- 12
- ],
- [
- 68,
- 14
- ],
- [
- 77,
- -7
- ],
- [
- 50,
- 33
- ],
- [
- 36,
- 80
- ],
- [
- 26,
- -33
- ],
- [
- 33,
- -56
- ],
- [
- 58,
- -24
- ],
- [
- 67,
- -9
- ],
- [
- 67,
- 14
- ],
- [
- 71,
- -9
- ],
- [
- 66,
- -3
- ],
- [
- 43,
- 12
- ],
- [
- 59,
- -7
- ],
- [
- 53,
- -26
- ],
- [
- 63,
- 16
- ],
- [
- 75,
- 0
- ],
- [
- 64,
- 17
- ],
- [
- 73,
- -17
- ],
- [
- 46,
- 40
- ],
- [
- 36,
- 40
- ],
- [
- 47,
- 33
- ],
- [
- 88,
- 90
- ],
- [
- 45,
- -17
- ],
- [
- 53,
- -33
- ],
- [
- 46,
- -42
- ],
- [
- 89,
- -73
- ],
- [
- 69,
- -2
- ],
- [
- 64,
- 0
- ],
- [
- 75,
- 14
- ],
- [
- 75,
- 16
- ],
- [
- 57,
- 33
- ],
- [
- 48,
- 35
- ],
- [
- 78,
- 5
- ],
- [
- 52,
- 26
- ],
- [
- 54,
- -23
- ],
- [
- 36,
- -38
- ],
- [
- 49,
- -38
- ],
- [
- 76,
- 5
- ],
- [
- 48,
- -31
- ],
- [
- 83,
- -30
- ],
- [
- 88,
- -12
- ],
- [
- 72,
- 10
- ],
- [
- 55,
- 37
- ],
- [
- 46,
- 38
- ],
- [
- 63,
- 9
- ],
- [
- 63,
- -16
- ],
- [
- 72,
- -12
- ],
- [
- 66,
- 19
- ],
- [
- 63,
- 0
- ],
- [
- 61,
- -12
- ],
- [
- 64,
- -12
- ],
- [
- 63,
- 21
- ],
- [
- 75,
- 19
- ],
- [
- 71,
- 5
- ],
- [
- 79,
- 0
- ],
- [
- 64,
- 12
- ],
- [
- 63,
- 9
- ],
- [
- 19,
- 59
- ],
- [
- 3,
- 49
- ],
- [
- 44,
- -33
- ],
- [
- 12,
- -54
- ],
- [
- 23,
- -49
- ],
- [
- 29,
- -40
- ],
- [
- 59,
- -21
- ],
- [
- 79,
- 7
- ],
- [
- 91,
- 2
- ],
- [
- 63,
- 7
- ],
- [
- 92,
- 0
- ],
- [
- 65,
- 3
- ],
- [
- 92,
- -5
- ],
- [
- 77,
- -10
- ],
- [
- 50,
- -37
- ],
- [
- -14,
- -45
- ],
- [
- 45,
- -35
- ],
- [
- 75,
- -28
- ],
- [
- 78,
- -31
- ],
- [
- 90,
- -21
- ],
- [
- 94,
- -19
- ],
- [
- 71,
- -19
- ],
- [
- 79,
- -2
- ],
- [
- 45,
- 40
- ],
- [
- 62,
- -33
- ],
- [
- 53,
- -38
- ],
- [
- 62,
- -28
- ],
- [
- 84,
- -12
- ],
- [
- 81,
- -14
- ],
- [
- 34,
- -47
- ],
- [
- 79,
- -28
- ],
- [
- 53,
- -42
- ],
- [
- 78,
- -19
- ],
- [
- 81,
- 2
- ],
- [
- 75,
- -7
- ],
- [
- 83,
- 3
- ],
- [
- 83,
- -10
- ],
- [
- 78,
- -16
- ],
- [
- 73,
- -28
- ],
- [
- 72,
- -24
- ],
- [
- 49,
- -35
- ],
- [
- -8,
- -47
- ],
- [
- -37,
- -42
- ],
- [
- -31,
- -55
- ],
- [
- -25,
- -42
- ],
- [
- -33,
- -49
- ],
- [
- -91,
- -19
- ],
- [
- -41,
- -42
- ],
- [
- -90,
- -26
- ],
- [
- -32,
- -47
- ],
- [
- -47,
- -45
- ],
- [
- -51,
- -38
- ],
- [
- -29,
- -49
- ],
- [
- -17,
- -45
- ],
- [
- -7,
- -54
- ],
- [
- 1,
- -44
- ],
- [
- 40,
- -47
- ],
- [
- 15,
- -45
- ],
- [
- 32,
- -42
- ],
- [
- 130,
- -17
- ],
- [
- 27,
- -51
- ],
- [
- -125,
- -19
- ],
- [
- -107,
- -26
- ],
- [
- -132,
- -5
- ],
- [
- -59,
- -68
- ],
- [
- -12,
- -56
- ],
- [
- -30,
- -45
- ],
- [
- -37,
- -45
- ],
- [
- 93,
- -40
- ],
- [
- 35,
- -49
- ],
- [
- 60,
- -45
- ],
- [
- 85,
- -40
- ],
- [
- 97,
- -37
- ],
- [
- 105,
- -38
- ],
- [
- 160,
- -38
- ],
- [
- 35,
- -58
- ],
- [
- 201,
- -26
- ],
- [
- 14,
- -9
- ],
- [
- 52,
- -36
- ],
- [
- 192,
- 31
- ],
- [
- 160,
- -38
- ],
- [
- 120,
- -29
- ],
- [
- 0,
- -634
- ],
- [
- -25095,
- 0
- ],
- [
- 0,
- 634
- ],
- [
- 4,
- -1
- ],
- [
- 62,
- 70
- ],
- [
- 125,
- -38
- ],
- [
- 8,
- 5
- ],
- [
- 74,
- 38
- ],
- [
- 10,
- -1
- ],
- [
- 8,
- -1
- ],
- [
- 101,
- -50
- ],
- [
- 88,
- 50
- ],
- [
- 16,
- 6
- ],
- [
- 204,
- 22
- ],
- [
- 67,
- -28
- ],
- [
- 33,
- -15
- ],
- [
- 105,
- -40
- ],
- [
- 198,
- -30
- ],
- [
- 157,
- -38
- ],
- [
- 269,
- -28
- ],
- [
- 200,
- 33
- ],
- [
- 297,
- -24
- ],
- [
- 168,
- -37
- ],
- [
- 184,
- 35
- ],
- [
- 194,
- 33
- ],
- [
- 15,
- 56
- ],
- [
- -275,
- 5
- ],
- [
- -225,
- 28
- ],
- [
- -59,
- 47
- ],
- [
- -187,
- 26
- ],
- [
- 13,
- 54
- ],
- [
- 25,
- 50
- ],
- [
- 26,
- 44
- ],
- [
- -13,
- 50
- ],
- [
- -116,
- 33
- ],
- [
- -54,
- 42
- ],
- [
- -107,
- 37
- ],
- [
- 169,
- -7
- ],
- [
- 161,
- 19
- ],
- [
- 101,
- -40
- ],
- [
- 124,
- 36
- ],
- [
- 115,
- 44
- ],
- [
- 56,
- 40
- ],
- [
- -25,
- 50
- ],
- [
- -90,
- 32
- ],
- [
- -102,
- 36
- ],
- [
- -143,
- 7
- ],
- [
- -126,
- 16
- ],
- [
- -135,
- 12
- ],
- [
- -45,
- 45
- ],
- [
- -90,
- 37
- ],
- [
- -55,
- 43
- ],
- [
- -22,
- 136
- ],
- [
- 34,
- -12
- ],
- [
- 63,
- -37
- ],
- [
- 115,
- 11
- ],
- [
- 110,
- 17
- ],
- [
- 58,
- -52
- ],
- [
- 110,
- 12
- ],
- [
- 93,
- 26
- ],
- [
- 87,
- 33
- ],
- [
- 80,
- 39
- ],
- [
- 105,
- 12
- ],
- [
- -3,
- 45
- ],
- [
- -24,
- 45
- ],
- [
- 20,
- 42
- ],
- [
- 90,
- 21
- ],
- [
- 41,
- -40
- ],
- [
- 107,
- 24
- ],
- [
- 80,
- 30
- ],
- [
- 100,
- 3
- ],
- [
- 94,
- 11
- ],
- [
- 94,
- 28
- ],
- [
- 75,
- 26
- ],
- [
- 85,
- 26
- ],
- [
- 55,
- -7
- ],
- [
- 47,
- -9
- ],
- [
- 104,
- 16
- ],
- [
- 93,
- -21
- ],
- [
- 95,
- 2
- ],
- [
- 92,
- 17
- ],
- [
- 94,
- -12
- ],
- [
- 104,
- -12
- ],
- [
- 97,
- 5
- ],
- [
- 101,
- -2
- ],
- [
- 104,
- -3
- ],
- [
- 95,
- 5
- ],
- [
- 71,
- 35
- ],
- [
- 85,
- 19
- ],
- [
- 87,
- -26
- ],
- [
- 84,
- 21
- ],
- [
- 75,
- 43
- ],
- [
- 45,
- -38
- ],
- [
- 24,
- -42
- ],
- [
- 45,
- -40
- ],
- [
- 73,
- 35
- ],
- [
- 83,
- -45
- ],
- [
- 94,
- -14
- ],
- [
- 81,
- -33
- ],
- [
- 98,
- 7
- ],
- [
- 89,
- 22
- ],
- [
- 105,
- -5
- ],
- [
- 94,
- -17
- ],
- [
- 96,
- -21
- ],
- [
- 37,
- 52
- ],
- [
- -46,
- 40
- ],
- [
- -34,
- 42
- ],
- [
- -90,
- 10
- ],
- [
- -39,
- 44
- ],
- [
- -15,
- 45
- ],
- [
- -25,
- 89
- ],
- [
- 53,
- -16
- ],
- [
- 92,
- -7
- ],
- [
- 90,
- 7
- ],
- [
- 82,
- -19
- ],
- [
- 71,
- -35
- ],
- [
- 30,
- -42
- ],
- [
- 94,
- -8
- ],
- [
- 90,
- 17
- ],
- [
- 96,
- 23
- ],
- [
- 86,
- 15
- ],
- [
- 71,
- -29
- ],
- [
- 93,
- 10
- ],
- [
- 60,
- 91
- ],
- [
- 56,
- -54
- ],
- [
- 80,
- -21
- ],
- [
- 88,
- 12
- ],
- [
- 57,
- -47
- ],
- [
- 91,
- -5
- ],
- [
- 85,
- -14
- ],
- [
- 83,
- -26
- ],
- [
- 55,
- 45
- ],
- [
- 27,
- 42
- ],
- [
- 70,
- -47
- ],
- [
- 95,
- 12
- ],
- [
- 71,
- -26
- ],
- [
- 48,
- -40
- ],
- [
- 93,
- 12
- ],
- [
- 72,
- 26
- ],
- [
- 71,
- 30
- ],
- [
- 85,
- 17
- ],
- [
- 98,
- 14
- ],
- [
- 89,
- 16
- ],
- [
- 68,
- 26
- ],
- [
- 41,
- 38
- ],
- [
- 17,
- 52
- ],
- [
- -8,
- 49
- ],
- [
- -22,
- 47
- ],
- [
- -25,
- 47
- ],
- [
- -22,
- 47
- ],
- [
- -18,
- 42
- ],
- [
- -4,
- 47
- ],
- [
- 7,
- 47
- ],
- [
- 33,
- 45
- ],
- [
- 27,
- 49
- ],
- [
- 11,
- 47
- ],
- [
- -13,
- 52
- ],
- [
- -9,
- 47
- ],
- [
- 35,
- 54
- ],
- [
- 38,
- 35
- ],
- [
- 45,
- 45
- ],
- [
- 48,
- 38
- ],
- [
- 56,
- 35
- ],
- [
- 27,
- 52
- ],
- [
- 38,
- 33
- ],
- [
- 44,
- 30
- ],
- [
- 67,
- 7
- ],
- [
- 43,
- 38
- ],
- [
- 50,
- 23
- ],
- [
- 57,
- 14
- ],
- [
- 50,
- 31
- ],
- [
- 40,
- 38
- ],
- [
- 55,
- 14
- ],
- [
- 41,
- -31
- ],
- [
- -26,
- -40
- ],
- [
- -71,
- -35
- ]
- ],
- [
- [
- 17353,
- 4964
- ],
- [
- 45,
- -38
- ],
- [
- 66,
- -15
- ],
- [
- 2,
- -23
- ],
- [
- -19,
- -54
- ],
- [
- -107,
- -8
- ],
- [
- -2,
- 64
- ],
- [
- 10,
- 49
- ],
- [
- 5,
- 25
- ]
- ],
- [
- [
- 22683,
- 5903
- ],
- [
- 67,
- -41
- ],
- [
- 38,
- 16
- ],
- [
- 55,
- 23
- ],
- [
- 41,
- -8
- ],
- [
- 5,
- -142
- ],
- [
- -23,
- -41
- ],
- [
- -8,
- -97
- ],
- [
- -24,
- 33
- ],
- [
- -48,
- -84
- ],
- [
- -15,
- 7
- ],
- [
- -43,
- 4
- ],
- [
- -43,
- 102
- ],
- [
- -9,
- 79
- ],
- [
- -40,
- 105
- ],
- [
- 1,
- 55
- ],
- [
- 46,
- -11
- ]
- ],
- [
- [
- 22555,
- 9146
- ],
- [
- 25,
- -94
- ],
- [
- 45,
- 45
- ],
- [
- 23,
- -51
- ],
- [
- 33,
- -47
- ],
- [
- -7,
- -53
- ],
- [
- 15,
- -103
- ],
- [
- 11,
- -59
- ],
- [
- 17,
- -15
- ],
- [
- 19,
- -103
- ],
- [
- -7,
- -62
- ],
- [
- 23,
- -81
- ],
- [
- 75,
- -63
- ],
- [
- 50,
- -57
- ],
- [
- 46,
- -52
- ],
- [
- -9,
- -29
- ],
- [
- 40,
- -75
- ],
- [
- 27,
- -130
- ],
- [
- 28,
- 26
- ],
- [
- 28,
- -52
- ],
- [
- 17,
- 19
- ],
- [
- 12,
- -128
- ],
- [
- 50,
- -73
- ],
- [
- 32,
- -46
- ],
- [
- 55,
- -97
- ],
- [
- 19,
- -97
- ],
- [
- 2,
- -68
- ],
- [
- -5,
- -74
- ],
- [
- 34,
- -102
- ],
- [
- -4,
- -106
- ],
- [
- -12,
- -56
- ],
- [
- -19,
- -107
- ],
- [
- 1,
- -69
- ],
- [
- -14,
- -86
- ],
- [
- -30,
- -109
- ],
- [
- -52,
- -59
- ],
- [
- -26,
- -93
- ],
- [
- -23,
- -59
- ],
- [
- -20,
- -104
- ],
- [
- -27,
- -59
- ],
- [
- -18,
- -90
- ],
- [
- -9,
- -83
- ],
- [
- 4,
- -38
- ],
- [
- -40,
- -41
- ],
- [
- -78,
- -5
- ],
- [
- -65,
- -49
- ],
- [
- -32,
- -46
- ],
- [
- -42,
- -52
- ],
- [
- -58,
- 53
- ],
- [
- -42,
- 21
- ],
- [
- 10,
- 63
- ],
- [
- -38,
- -23
- ],
- [
- -61,
- -87
- ],
- [
- -60,
- 33
- ],
- [
- -39,
- 19
- ],
- [
- -40,
- 8
- ],
- [
- -68,
- 35
- ],
- [
- -45,
- 74
- ],
- [
- -13,
- 91
- ],
- [
- -16,
- 61
- ],
- [
- -34,
- 48
- ],
- [
- -67,
- 15
- ],
- [
- 23,
- 58
- ],
- [
- -17,
- 89
- ],
- [
- -34,
- -83
- ],
- [
- -62,
- -22
- ],
- [
- 36,
- 66
- ],
- [
- 11,
- 70
- ],
- [
- 27,
- 58
- ],
- [
- -6,
- 89
- ],
- [
- -57,
- -102
- ],
- [
- -43,
- -41
- ],
- [
- -27,
- -96
- ],
- [
- -54,
- 50
- ],
- [
- 2,
- 63
- ],
- [
- -44,
- 87
- ],
- [
- -37,
- 45
- ],
- [
- 14,
- 28
- ],
- [
- -90,
- 73
- ],
- [
- -49,
- 3
- ],
- [
- -67,
- 59
- ],
- [
- -125,
- -12
- ],
- [
- -90,
- -43
- ],
- [
- -79,
- -40
- ],
- [
- -67,
- 8
- ],
- [
- -74,
- -61
- ],
- [
- -60,
- -28
- ],
- [
- -14,
- -63
- ],
- [
- -25,
- -49
- ],
- [
- -60,
- -2
- ],
- [
- -43,
- -11
- ],
- [
- -62,
- 22
- ],
- [
- -50,
- -13
- ],
- [
- -48,
- -6
- ],
- [
- -41,
- -64
- ],
- [
- -21,
- 6
- ],
- [
- -35,
- -34
- ],
- [
- -33,
- -38
- ],
- [
- -51,
- 4
- ],
- [
- -47,
- 0
- ],
- [
- -74,
- 77
- ],
- [
- -37,
- 23
- ],
- [
- 1,
- 68
- ],
- [
- 35,
- 17
- ],
- [
- 12,
- 27
- ],
- [
- -3,
- 43
- ],
- [
- 9,
- 84
- ],
- [
- -8,
- 71
- ],
- [
- -37,
- 121
- ],
- [
- -11,
- 68
- ],
- [
- 3,
- 69
- ],
- [
- -28,
- 78
- ],
- [
- -2,
- 35
- ],
- [
- -31,
- 48
- ],
- [
- -8,
- 94
- ],
- [
- -40,
- 95
- ],
- [
- -10,
- 51
- ],
- [
- 31,
- -52
- ],
- [
- -24,
- 111
- ],
- [
- 35,
- -34
- ],
- [
- 20,
- -47
- ],
- [
- -1,
- 62
- ],
- [
- -34,
- 94
- ],
- [
- -7,
- 38
- ],
- [
- -16,
- 36
- ],
- [
- 8,
- 69
- ],
- [
- 14,
- 30
- ],
- [
- 9,
- 60
- ],
- [
- -7,
- 70
- ],
- [
- 29,
- 86
- ],
- [
- 5,
- -91
- ],
- [
- 29,
- 82
- ],
- [
- 57,
- 40
- ],
- [
- 34,
- 52
- ],
- [
- 53,
- 44
- ],
- [
- 32,
- 9
- ],
- [
- 19,
- -15
- ],
- [
- 55,
- 45
- ],
- [
- 42,
- 13
- ],
- [
- 11,
- 27
- ],
- [
- 18,
- 10
- ],
- [
- 39,
- -2
- ],
- [
- 73,
- 35
- ],
- [
- 38,
- 53
- ],
- [
- 18,
- 64
- ],
- [
- 41,
- 61
- ],
- [
- 3,
- 48
- ],
- [
- 2,
- 65
- ],
- [
- 49,
- 102
- ],
- [
- 29,
- -103
- ],
- [
- 30,
- 23
- ],
- [
- -25,
- 57
- ],
- [
- 22,
- 58
- ],
- [
- 30,
- -26
- ],
- [
- 9,
- 92
- ],
- [
- 38,
- 59
- ],
- [
- 17,
- 47
- ],
- [
- 35,
- 20
- ],
- [
- 1,
- 34
- ],
- [
- 30,
- -14
- ],
- [
- 2,
- 30
- ],
- [
- 30,
- 17
- ],
- [
- 34,
- 16
- ],
- [
- 52,
- -55
- ],
- [
- 38,
- -71
- ],
- [
- 44,
- 0
- ],
- [
- 44,
- -12
- ],
- [
- -15,
- 66
- ],
- [
- 34,
- 96
- ],
- [
- 31,
- 32
- ],
- [
- -11,
- 30
- ],
- [
- 31,
- 68
- ],
- [
- 42,
- 43
- ],
- [
- 36,
- -15
- ],
- [
- 58,
- 23
- ],
- [
- -1,
- 61
- ],
- [
- -51,
- 40
- ],
- [
- 37,
- 17
- ],
- [
- 46,
- -30
- ],
- [
- 37,
- -49
- ],
- [
- 59,
- -31
- ],
- [
- 20,
- 13
- ],
- [
- 43,
- -37
- ],
- [
- 41,
- 34
- ],
- [
- 26,
- -10
- ],
- [
- 16,
- 23
- ],
- [
- 32,
- -60
- ],
- [
- -18,
- -64
- ],
- [
- -27,
- -48
- ],
- [
- -24,
- -4
- ],
- [
- 8,
- -48
- ],
- [
- -20,
- -60
- ],
- [
- -25,
- -59
- ],
- [
- 5,
- -34
- ],
- [
- 55,
- -66
- ],
- [
- 54,
- -39
- ],
- [
- 36,
- -41
- ],
- [
- 50,
- -71
- ],
- [
- 20,
- 0
- ],
- [
- 37,
- -31
- ],
- [
- 10,
- -37
- ],
- [
- 67,
- -41
- ],
- [
- 46,
- 41
- ],
- [
- 13,
- 65
- ],
- [
- 14,
- 53
- ],
- [
- 9,
- 66
- ],
- [
- 21,
- 95
- ],
- [
- -9,
- 58
- ],
- [
- 5,
- 35
- ],
- [
- -8,
- 69
- ],
- [
- 9,
- 90
- ],
- [
- 13,
- 25
- ],
- [
- -11,
- 40
- ],
- [
- 17,
- 63
- ],
- [
- 13,
- 66
- ],
- [
- 2,
- 34
- ],
- [
- 26,
- 45
- ],
- [
- 20,
- -58
- ],
- [
- 5,
- -76
- ],
- [
- 17,
- -14
- ],
- [
- 3,
- -51
- ],
- [
- 25,
- -61
- ],
- [
- 5,
- -67
- ],
- [
- -2,
- -44
- ]
- ],
- [
- [
- 13731,
- 16571
- ],
- [
- -5,
- -50
- ],
- [
- -39,
- 0
- ],
- [
- 13,
- -26
- ],
- [
- -23,
- -77
- ]
- ],
- [
- [
- 13677,
- 16418
- ],
- [
- -13,
- -20
- ],
- [
- -61,
- -3
- ],
- [
- -35,
- -27
- ],
- [
- -58,
- 9
- ]
- ],
- [
- [
- 13510,
- 16377
- ],
- [
- -100,
- 31
- ],
- [
- -15,
- 42
- ],
- [
- -69,
- -21
- ],
- [
- -8,
- -23
- ],
- [
- -43,
- 17
- ]
- ],
- [
- [
- 13275,
- 16423
- ],
- [
- -35,
- 3
- ],
- [
- -32,
- 22
- ],
- [
- 11,
- 29
- ],
- [
- -3,
- 22
- ]
- ],
- [
- [
- 13216,
- 16499
- ],
- [
- 21,
- 6
- ],
- [
- 36,
- -33
- ],
- [
- 10,
- 32
- ],
- [
- 61,
- -5
- ],
- [
- 50,
- 21
- ],
- [
- 33,
- -4
- ],
- [
- 22,
- -24
- ],
- [
- 7,
- 20
- ],
- [
- -10,
- 78
- ],
- [
- 25,
- 16
- ],
- [
- 24,
- 55
- ]
- ],
- [
- [
- 13495,
- 16661
- ],
- [
- 52,
- -39
- ],
- [
- 39,
- 49
- ],
- [
- 25,
- 9
- ],
- [
- 54,
- -36
- ],
- [
- 33,
- 6
- ],
- [
- 32,
- -23
- ]
- ],
- [
- [
- 13730,
- 16627
- ],
- [
- -6,
- -15
- ],
- [
- 7,
- -41
- ]
- ],
- [
- [
- 15682,
- 15746
- ],
- [
- 18,
- 19
- ],
- [
- 51,
- -34
- ],
- [
- 38,
- -7
- ],
- [
- 10,
- 14
- ],
- [
- -35,
- 65
- ],
- [
- 18,
- 16
- ]
- ],
- [
- [
- 15782,
- 15819
- ],
- [
- 20,
- -4
- ],
- [
- 48,
- -73
- ],
- [
- 31,
- -8
- ],
- [
- 12,
- 31
- ],
- [
- 41,
- 48
- ]
- ],
- [
- [
- 15934,
- 15813
- ],
- [
- 37,
- -63
- ],
- [
- 35,
- -85
- ],
- [
- 33,
- -6
- ],
- [
- 21,
- -32
- ],
- [
- -57,
- -10
- ],
- [
- -12,
- -93
- ],
- [
- -12,
- -42
- ],
- [
- -26,
- -28
- ],
- [
- 2,
- -60
- ]
- ],
- [
- [
- 15955,
- 15394
- ],
- [
- -17,
- -6
- ],
- [
- -44,
- 63
- ],
- [
- 24,
- 60
- ],
- [
- -20,
- 35
- ],
- [
- -26,
- -9
- ],
- [
- -83,
- -89
- ]
- ],
- [
- [
- 15764,
- 15445
- ],
- [
- -48,
- 16
- ],
- [
- -35,
- 55
- ],
- [
- -11,
- 46
- ]
- ],
- [
- [
- 14593,
- 10257
- ],
- [
- -5,
- 145
- ],
- [
- -17,
- 55
- ]
- ],
- [
- [
- 14571,
- 10457
- ],
- [
- 42,
- -10
- ],
- [
- 21,
- 68
- ],
- [
- 37,
- -7
- ]
- ],
- [
- [
- 14671,
- 10508
- ],
- [
- 5,
- -48
- ],
- [
- 15,
- -27
- ],
- [
- 0,
- -39
- ],
- [
- -17,
- -25
- ],
- [
- -27,
- -62
- ],
- [
- -25,
- -44
- ],
- [
- -29,
- -6
- ]
- ],
- [
- [
- 12977,
- 16892
- ],
- [
- -8,
- -81
- ]
- ],
- [
- [
- 12969,
- 16811
- ],
- [
- -18,
- -5
- ],
- [
- -8,
- -67
- ]
- ],
- [
- [
- 12943,
- 16739
- ],
- [
- -61,
- 55
- ],
- [
- -36,
- -9
- ],
- [
- -48,
- 56
- ],
- [
- -33,
- 48
- ],
- [
- -32,
- 2
- ],
- [
- -10,
- 42
- ]
- ],
- [
- [
- 12723,
- 16933
- ],
- [
- 56,
- 24
- ]
- ],
- [
- [
- 12779,
- 16957
- ],
- [
- 51,
- -9
- ],
- [
- 64,
- 25
- ],
- [
- 44,
- -53
- ],
- [
- 39,
- -28
- ]
- ],
- [
- [
- 12735,
- 11548
- ],
- [
- -57,
- -14
- ]
- ],
- [
- [
- 12678,
- 11534
- ],
- [
- -18,
- 83
- ],
- [
- 4,
- 275
- ],
- [
- -15,
- 25
- ],
- [
- -2,
- 59
- ],
- [
- -24,
- 42
- ],
- [
- -22,
- 35
- ],
- [
- 9,
- 64
- ]
- ],
- [
- [
- 12610,
- 12117
- ],
- [
- 24,
- 13
- ],
- [
- 14,
- 53
- ],
- [
- 34,
- 11
- ],
- [
- 16,
- 36
- ]
- ],
- [
- [
- 12698,
- 12230
- ],
- [
- 23,
- 35
- ],
- [
- 25,
- 0
- ],
- [
- 53,
- -69
- ]
- ],
- [
- [
- 12799,
- 12196
- ],
- [
- -2,
- -40
- ],
- [
- 15,
- -71
- ],
- [
- -14,
- -48
- ],
- [
- 8,
- -33
- ],
- [
- -34,
- -74
- ],
- [
- -21,
- -37
- ],
- [
- -14,
- -75
- ],
- [
- 2,
- -77
- ],
- [
- -4,
- -193
- ]
- ],
- [
- [
- 12610,
- 12117
- ],
- [
- -61,
- 2
- ]
- ],
- [
- [
- 12549,
- 12119
- ],
- [
- -32,
- 10
- ],
- [
- -23,
- -20
- ],
- [
- -30,
- 9
- ],
- [
- -121,
- -6
- ],
- [
- -2,
- -68
- ],
- [
- 9,
- -90
- ]
- ],
- [
- [
- 12350,
- 11954
- ],
- [
- -47,
- 31
- ],
- [
- -33,
- -5
- ],
- [
- -24,
- -30
- ],
- [
- -32,
- 26
- ],
- [
- -12,
- 39
- ],
- [
- -31,
- 26
- ]
- ],
- [
- [
- 12171,
- 12041
- ],
- [
- -5,
- 70
- ],
- [
- 19,
- 51
- ],
- [
- -1,
- 40
- ],
- [
- 55,
- 100
- ],
- [
- 10,
- 82
- ],
- [
- 19,
- 29
- ],
- [
- 34,
- -16
- ],
- [
- 29,
- 25
- ],
- [
- 10,
- 31
- ],
- [
- 54,
- 53
- ],
- [
- 13,
- 38
- ],
- [
- 65,
- 50
- ],
- [
- 39,
- 17
- ],
- [
- 17,
- -23
- ],
- [
- 45,
- 0
- ]
- ],
- [
- [
- 12574,
- 12588
- ],
- [
- -6,
- -58
- ],
- [
- 9,
- -55
- ],
- [
- 40,
- -78
- ],
- [
- 2,
- -58
- ],
- [
- 80,
- -27
- ],
- [
- -1,
- -82
- ]
- ],
- [
- [
- 19008,
- 13441
- ],
- [
- -2,
- -86
- ],
- [
- -24,
- 19
- ],
- [
- 4,
- -97
- ]
- ],
- [
- [
- 18986,
- 13277
- ],
- [
- -20,
- 63
- ],
- [
- -4,
- 61
- ],
- [
- -13,
- 57
- ],
- [
- -29,
- 70
- ],
- [
- -64,
- 5
- ],
- [
- 6,
- -49
- ],
- [
- -22,
- -67
- ],
- [
- -29,
- 24
- ],
- [
- -11,
- -22
- ],
- [
- -19,
- 13
- ],
- [
- -27,
- 11
- ]
- ],
- [
- [
- 18754,
- 13443
- ],
- [
- -11,
- 99
- ],
- [
- -24,
- 90
- ],
- [
- 12,
- 72
- ],
- [
- -43,
- 33
- ],
- [
- 15,
- 43
- ],
- [
- 44,
- 45
- ],
- [
- -51,
- 64
- ],
- [
- 25,
- 81
- ],
- [
- 55,
- -52
- ],
- [
- 34,
- -6
- ],
- [
- 6,
- -83
- ],
- [
- 66,
- -17
- ],
- [
- 65,
- 2
- ],
- [
- 40,
- -20
- ],
- [
- -32,
- -102
- ],
- [
- -31,
- -7
- ],
- [
- -22,
- -68
- ],
- [
- 38,
- -62
- ],
- [
- 12,
- 76
- ],
- [
- 19,
- 1
- ],
- [
- 37,
- -191
- ]
- ],
- [
- [
- 14127,
- 16104
- ],
- [
- 20,
- -49
- ],
- [
- 27,
- 8
- ],
- [
- 54,
- -18
- ],
- [
- 102,
- -7
- ],
- [
- 34,
- 31
- ],
- [
- 83,
- 28
- ],
- [
- 50,
- -44
- ],
- [
- 41,
- -12
- ]
- ],
- [
- [
- 14538,
- 16041
- ],
- [
- -36,
- -50
- ],
- [
- -25,
- -86
- ],
- [
- 22,
- -68
- ]
- ],
- [
- [
- 14499,
- 15837
- ],
- [
- -60,
- 16
- ],
- [
- -71,
- -38
- ]
- ],
- [
- [
- 14368,
- 15815
- ],
- [
- -1,
- -60
- ],
- [
- -63,
- -11
- ],
- [
- -49,
- 42
- ],
- [
- -56,
- -33
- ],
- [
- -52,
- 3
- ]
- ],
- [
- [
- 14147,
- 15756
- ],
- [
- -4,
- 80
- ],
- [
- -35,
- 38
- ]
- ],
- [
- [
- 14108,
- 15874
- ],
- [
- 11,
- 17
- ],
- [
- -7,
- 15
- ],
- [
- 11,
- 38
- ],
- [
- 27,
- 37
- ],
- [
- -34,
- 52
- ],
- [
- -6,
- 44
- ],
- [
- 17,
- 27
- ]
- ],
- [
- [
- 7143,
- 13648
- ],
- [
- -17,
- -6
- ],
- [
- -18,
- 69
- ],
- [
- -26,
- 35
- ],
- [
- 15,
- 76
- ],
- [
- 21,
- -5
- ],
- [
- 24,
- -100
- ],
- [
- 1,
- -69
- ]
- ],
- [
- [
- 7123,
- 13986
- ],
- [
- -76,
- -19
- ],
- [
- -5,
- 44
- ],
- [
- 33,
- 10
- ],
- [
- 46,
- -4
- ],
- [
- 2,
- -31
- ]
- ],
- [
- [
- 7180,
- 13987
- ],
- [
- -12,
- -85
- ],
- [
- -13,
- 15
- ],
- [
- 1,
- 63
- ],
- [
- -31,
- 47
- ],
- [
- 0,
- 14
- ],
- [
- 55,
- -54
- ]
- ],
- [
- [
- 13887,
- 16019
- ],
- [
- -13,
- -11
- ],
- [
- -23,
- -28
- ],
- [
- -10,
- -66
- ]
- ],
- [
- [
- 13841,
- 15914
- ],
- [
- -61,
- 45
- ],
- [
- -27,
- 50
- ],
- [
- -26,
- 27
- ],
- [
- -32,
- 45
- ],
- [
- -15,
- 37
- ],
- [
- -35,
- 56
- ],
- [
- 15,
- 50
- ],
- [
- 25,
- -28
- ],
- [
- 15,
- 25
- ],
- [
- 33,
- 3
- ],
- [
- 60,
- -20
- ],
- [
- 48,
- 2
- ],
- [
- 31,
- -27
- ]
- ],
- [
- [
- 13872,
- 16179
- ],
- [
- 26,
- 0
- ],
- [
- -18,
- -52
- ],
- [
- 34,
- -47
- ],
- [
- -10,
- -56
- ],
- [
- -17,
- -5
- ]
- ],
- [
- [
- 14185,
- 17265
- ],
- [
- 67,
- -1
- ],
- [
- 76,
- 45
- ],
- [
- 16,
- 68
- ],
- [
- 57,
- 39
- ],
- [
- -7,
- 53
- ]
- ],
- [
- [
- 14394,
- 17469
- ],
- [
- 43,
- 20
- ],
- [
- 75,
- 47
- ]
- ],
- [
- [
- 14512,
- 17536
- ],
- [
- 73,
- -30
- ],
- [
- 10,
- -30
- ],
- [
- 37,
- 14
- ],
- [
- 68,
- -28
- ],
- [
- 6,
- -57
- ],
- [
- -14,
- -32
- ],
- [
- 43,
- -79
- ],
- [
- 29,
- -22
- ],
- [
- -5,
- -21
- ],
- [
- 47,
- -21
- ],
- [
- 21,
- -32
- ],
- [
- -28,
- -27
- ],
- [
- -56,
- 5
- ],
- [
- -13,
- -12
- ],
- [
- 16,
- -39
- ],
- [
- 17,
- -77
- ]
- ],
- [
- [
- 14763,
- 17048
- ],
- [
- -60,
- -7
- ],
- [
- -21,
- -27
- ],
- [
- -5,
- -60
- ],
- [
- -27,
- 12
- ],
- [
- -63,
- -6
- ],
- [
- -18,
- 28
- ],
- [
- -27,
- -21
- ],
- [
- -26,
- 17
- ],
- [
- -55,
- 3
- ],
- [
- -78,
- 28
- ],
- [
- -70,
- 10
- ],
- [
- -54,
- -3
- ],
- [
- -38,
- -32
- ],
- [
- -33,
- -5
- ]
- ],
- [
- [
- 14188,
- 16985
- ],
- [
- -2,
- 53
- ],
- [
- -21,
- 56
- ],
- [
- 42,
- 24
- ],
- [
- 0,
- 48
- ],
- [
- -19,
- 46
- ],
- [
- -3,
- 53
- ]
- ],
- [
- [
- 6333,
- 12934
- ],
- [
- 0,
- 17
- ],
- [
- 8,
- 6
- ],
- [
- 13,
- -14
- ],
- [
- 25,
- 72
- ],
- [
- 13,
- 2
- ]
- ],
- [
- [
- 6392,
- 13017
- ],
- [
- 1,
- -18
- ],
- [
- 13,
- -1
- ],
- [
- -1,
- -32
- ],
- [
- -12,
- -52
- ],
- [
- 6,
- -19
- ],
- [
- -7,
- -43
- ],
- [
- 4,
- -11
- ],
- [
- -8,
- -61
- ],
- [
- -13,
- -31
- ],
- [
- -13,
- -4
- ],
- [
- -14,
- -42
- ]
- ],
- [
- [
- 6348,
- 12703
- ],
- [
- -21,
- 0
- ],
- [
- 6,
- 136
- ],
- [
- 0,
- 95
- ]
- ],
- [
- [
- 7870,
- 8070
- ],
- [
- -51,
- -17
- ],
- [
- -27,
- 166
- ],
- [
- -37,
- 134
- ],
- [
- 22,
- 116
- ],
- [
- -37,
- 51
- ],
- [
- -9,
- 87
- ],
- [
- -35,
- 81
- ]
- ],
- [
- [
- 7696,
- 8688
- ],
- [
- 44,
- 130
- ],
- [
- -30,
- 100
- ],
- [
- 16,
- 41
- ],
- [
- -12,
- 44
- ],
- [
- 27,
- 60
- ],
- [
- 2,
- 102
- ],
- [
- 3,
- 85
- ],
- [
- 15,
- 40
- ],
- [
- -60,
- 193
- ]
- ],
- [
- [
- 7701,
- 9483
- ],
- [
- 52,
- -10
- ],
- [
- 35,
- 3
- ],
- [
- 16,
- 36
- ],
- [
- 61,
- 49
- ],
- [
- 37,
- 45
- ],
- [
- 91,
- 20
- ],
- [
- -8,
- -90
- ],
- [
- 9,
- -46
- ],
- [
- -6,
- -80
- ],
- [
- 76,
- -108
- ],
- [
- 78,
- -20
- ],
- [
- 28,
- -44
- ],
- [
- 47,
- -24
- ],
- [
- 29,
- -35
- ],
- [
- 43,
- 1
- ],
- [
- 41,
- -35
- ],
- [
- 3,
- -70
- ],
- [
- 14,
- -35
- ],
- [
- 0,
- -52
- ],
- [
- -20,
- -2
- ],
- [
- 27,
- -139
- ],
- [
- 134,
- -5
- ],
- [
- -11,
- -70
- ],
- [
- 8,
- -47
- ],
- [
- 38,
- -34
- ],
- [
- 16,
- -74
- ],
- [
- -12,
- -95
- ],
- [
- -19,
- -52
- ],
- [
- 7,
- -69
- ],
- [
- -22,
- -24
- ]
- ],
- [
- [
- 8493,
- 8377
- ],
- [
- -1,
- 37
- ],
- [
- -65,
- 61
- ],
- [
- -65,
- 2
- ],
- [
- -122,
- -35
- ],
- [
- -33,
- -106
- ],
- [
- -2,
- -64
- ],
- [
- -27,
- -144
- ]
- ],
- [
- [
- 8740,
- 7709
- ],
- [
- 13,
- 70
- ],
- [
- 10,
- 70
- ],
- [
- 0,
- 66
- ],
- [
- -25,
- 22
- ],
- [
- -26,
- -19
- ],
- [
- -26,
- 5
- ],
- [
- -9,
- 46
- ],
- [
- -6,
- 110
- ],
- [
- -13,
- 36
- ],
- [
- -47,
- 33
- ],
- [
- -29,
- -24
- ],
- [
- -73,
- 23
- ],
- [
- 4,
- 163
- ],
- [
- -20,
- 67
- ]
- ],
- [
- [
- 7701,
- 9483
- ],
- [
- -40,
- -20
- ],
- [
- -31,
- 13
- ],
- [
- 4,
- 183
- ],
- [
- -57,
- -71
- ],
- [
- -61,
- 3
- ],
- [
- -27,
- 64
- ],
- [
- -46,
- 7
- ],
- [
- 15,
- 52
- ],
- [
- -39,
- 73
- ],
- [
- -29,
- 108
- ],
- [
- 18,
- 22
- ],
- [
- 0,
- 50
- ],
- [
- 42,
- 35
- ],
- [
- -7,
- 65
- ],
- [
- 18,
- 41
- ],
- [
- 5,
- 56
- ],
- [
- 80,
- 82
- ],
- [
- 57,
- 23
- ],
- [
- 10,
- 18
- ],
- [
- 62,
- -5
- ]
- ],
- [
- [
- 7675,
- 10282
- ],
- [
- 32,
- 328
- ],
- [
- 1,
- 53
- ],
- [
- -11,
- 68
- ],
- [
- -31,
- 44
- ],
- [
- 1,
- 87
- ],
- [
- 39,
- 20
- ],
- [
- 14,
- -13
- ],
- [
- 2,
- 46
- ],
- [
- -40,
- 13
- ],
- [
- -1,
- 75
- ],
- [
- 135,
- -3
- ],
- [
- 24,
- 42
- ],
- [
- 19,
- -38
- ],
- [
- 14,
- -71
- ],
- [
- 13,
- 15
- ]
- ],
- [
- [
- 7886,
- 10948
- ],
- [
- 38,
- -64
- ],
- [
- 54,
- 8
- ],
- [
- 14,
- 37
- ],
- [
- 52,
- 28
- ],
- [
- 28,
- 19
- ],
- [
- 8,
- 51
- ],
- [
- 50,
- 34
- ],
- [
- -4,
- 25
- ],
- [
- -59,
- 11
- ],
- [
- -9,
- 75
- ],
- [
- 2,
- 81
- ],
- [
- -31,
- 31
- ],
- [
- 13,
- 11
- ],
- [
- 52,
- -15
- ],
- [
- 55,
- -30
- ],
- [
- 21,
- 28
- ],
- [
- 50,
- 19
- ],
- [
- 78,
- 44
- ],
- [
- 25,
- 46
- ],
- [
- -9,
- 34
- ]
- ],
- [
- [
- 8314,
- 11421
- ],
- [
- 36,
- 5
- ],
- [
- 16,
- -27
- ],
- [
- -9,
- -53
- ],
- [
- 24,
- -18
- ],
- [
- 16,
- -56
- ],
- [
- -19,
- -42
- ],
- [
- -11,
- -102
- ],
- [
- 18,
- -61
- ],
- [
- 5,
- -55
- ],
- [
- 43,
- -57
- ],
- [
- 34,
- -6
- ],
- [
- 7,
- 24
- ],
- [
- 23,
- 5
- ],
- [
- 31,
- 21
- ],
- [
- 23,
- 32
- ],
- [
- 38,
- -10
- ],
- [
- 17,
- 4
- ]
- ],
- [
- [
- 8606,
- 11025
- ],
- [
- 38,
- -10
- ],
- [
- 6,
- 25
- ],
- [
- -11,
- 24
- ],
- [
- 7,
- 34
- ],
- [
- 28,
- -10
- ],
- [
- 33,
- 12
- ],
- [
- 40,
- -25
- ]
- ],
- [
- [
- 8747,
- 11075
- ],
- [
- 30,
- -25
- ],
- [
- 22,
- 32
- ],
- [
- 15,
- -5
- ],
- [
- 10,
- -33
- ],
- [
- 33,
- 8
- ],
- [
- 27,
- 46
- ],
- [
- 21,
- 88
- ],
- [
- 42,
- 110
- ]
- ],
- [
- [
- 8947,
- 11296
- ],
- [
- 23,
- 5
- ],
- [
- 18,
- -66
- ],
- [
- 39,
- -210
- ],
- [
- 37,
- -19
- ],
- [
- 2,
- -83
- ],
- [
- -53,
- -99
- ],
- [
- 22,
- -36
- ],
- [
- 123,
- -19
- ],
- [
- 3,
- -120
- ],
- [
- 53,
- 78
- ],
- [
- 87,
- -43
- ],
- [
- 116,
- -73
- ],
- [
- 34,
- -70
- ],
- [
- -11,
- -67
- ],
- [
- 81,
- 37
- ],
- [
- 136,
- -63
- ],
- [
- 104,
- 5
- ],
- [
- 103,
- -100
- ],
- [
- 89,
- -134
- ],
- [
- 53,
- -35
- ],
- [
- 60,
- -5
- ],
- [
- 25,
- -37
- ],
- [
- 24,
- -153
- ],
- [
- 12,
- -73
- ],
- [
- -28,
- -198
- ],
- [
- -36,
- -78
- ],
- [
- -98,
- -167
- ],
- [
- -44,
- -136
- ],
- [
- -52,
- -104
- ],
- [
- -17,
- -2
- ],
- [
- -20,
- -89
- ],
- [
- 5,
- -224
- ],
- [
- -19,
- -185
- ],
- [
- -8,
- -79
- ],
- [
- -22,
- -48
- ],
- [
- -12,
- -160
- ],
- [
- -71,
- -157
- ],
- [
- -12,
- -124
- ],
- [
- -56,
- -52
- ],
- [
- -16,
- -71
- ],
- [
- -76,
- 0
- ],
- [
- -110,
- -46
- ],
- [
- -49,
- -54
- ],
- [
- -78,
- -35
- ],
- [
- -82,
- -95
- ],
- [
- -59,
- -119
- ],
- [
- -10,
- -90
- ],
- [
- 11,
- -66
- ],
- [
- -13,
- -121
- ],
- [
- -15,
- -59
- ],
- [
- -49,
- -66
- ],
- [
- -77,
- -211
- ],
- [
- -62,
- -95
- ],
- [
- -47,
- -56
- ],
- [
- -32,
- -114
- ],
- [
- -46,
- -69
- ]
- ],
- [
- [
- 8827,
- 6746
- ],
- [
- -19,
- 68
- ],
- [
- 30,
- 57
- ],
- [
- -40,
- 82
- ],
- [
- -55,
- 66
- ],
- [
- -71,
- 77
- ],
- [
- -26,
- -4
- ],
- [
- -70,
- 93
- ],
- [
- -45,
- -13
- ]
- ],
- [
- [
- 20508,
- 11340
- ],
- [
- 28,
- 45
- ],
- [
- 59,
- 66
- ]
- ],
- [
- [
- 20595,
- 11451
- ],
- [
- -3,
- -59
- ],
- [
- -4,
- -77
- ],
- [
- -33,
- 4
- ],
- [
- -15,
- -41
- ],
- [
- -32,
- 62
- ]
- ],
- [
- [
- 18940,
- 14129
- ],
- [
- 28,
- -38
- ],
- [
- -5,
- -74
- ],
- [
- -57,
- -4
- ],
- [
- -59,
- 8
- ],
- [
- -44,
- -18
- ],
- [
- -63,
- 45
- ],
- [
- -1,
- 24
- ]
- ],
- [
- [
- 18739,
- 14072
- ],
- [
- 46,
- 89
- ],
- [
- 37,
- 31
- ],
- [
- 50,
- -28
- ],
- [
- 37,
- -3
- ],
- [
- 31,
- -32
- ]
- ],
- [
- [
- 14599,
- 8147
- ],
- [
- -98,
- -88
- ],
- [
- -63,
- -90
- ],
- [
- -23,
- -80
- ],
- [
- -21,
- -45
- ],
- [
- -38,
- -10
- ],
- [
- -12,
- -57
- ],
- [
- -7,
- -37
- ],
- [
- -45,
- -28
- ],
- [
- -57,
- 6
- ],
- [
- -33,
- 33
- ],
- [
- -29,
- 15
- ],
- [
- -34,
- -28
- ],
- [
- -18,
- -58
- ],
- [
- -33,
- -36
- ],
- [
- -34,
- -53
- ],
- [
- -50,
- -12
- ],
- [
- -16,
- 42
- ],
- [
- 7,
- 73
- ],
- [
- -42,
- 114
- ],
- [
- -19,
- 18
- ]
- ],
- [
- [
- 13934,
- 7826
- ],
- [
- 0,
- 350
- ],
- [
- 69,
- 4
- ],
- [
- 2,
- 427
- ],
- [
- 52,
- 4
- ],
- [
- 108,
- 42
- ],
- [
- 26,
- -49
- ],
- [
- 45,
- 47
- ],
- [
- 21,
- 0
- ],
- [
- 39,
- 27
- ]
- ],
- [
- [
- 14296,
- 8678
- ],
- [
- 13,
- -9
- ]
- ],
- [
- [
- 14309,
- 8669
- ],
- [
- 26,
- -96
- ],
- [
- 14,
- -21
- ],
- [
- 22,
- -69
- ],
- [
- 79,
- -132
- ],
- [
- 30,
- -13
- ],
- [
- 0,
- -42
- ],
- [
- 21,
- -76
- ],
- [
- 54,
- -19
- ],
- [
- 44,
- -54
- ]
- ],
- [
- [
- 13613,
- 11688
- ],
- [
- 57,
- 9
- ],
- [
- 13,
- 30
- ],
- [
- 12,
- -2
- ],
- [
- 17,
- -27
- ],
- [
- 88,
- 46
- ],
- [
- 29,
- 47
- ],
- [
- 37,
- 42
- ],
- [
- -7,
- 42
- ],
- [
- 20,
- 11
- ],
- [
- 67,
- -8
- ],
- [
- 65,
- 56
- ],
- [
- 51,
- 131
- ],
- [
- 35,
- 48
- ],
- [
- 44,
- 21
- ]
- ],
- [
- [
- 14141,
- 12134
- ],
- [
- 8,
- -51
- ],
- [
- 40,
- -75
- ],
- [
- 1,
- -49
- ],
- [
- -12,
- -50
- ],
- [
- 5,
- -38
- ],
- [
- 24,
- -34
- ],
- [
- 53,
- -53
- ]
- ],
- [
- [
- 14260,
- 11784
- ],
- [
- 38,
- -48
- ],
- [
- 1,
- -39
- ],
- [
- 47,
- -63
- ],
- [
- 29,
- -51
- ],
- [
- 17,
- -72
- ],
- [
- 53,
- -48
- ],
- [
- 11,
- -38
- ]
- ],
- [
- [
- 14456,
- 11425
- ],
- [
- -23,
- -13
- ],
- [
- -45,
- 3
- ],
- [
- -52,
- 13
- ],
- [
- -26,
- -11
- ],
- [
- -11,
- -29
- ],
- [
- -22,
- -3
- ],
- [
- -28,
- 25
- ],
- [
- -77,
- -60
- ],
- [
- -32,
- 12
- ],
- [
- -10,
- -9
- ],
- [
- -21,
- -72
- ],
- [
- -52,
- 23
- ],
- [
- -51,
- 12
- ],
- [
- -44,
- 44
- ],
- [
- -57,
- 41
- ],
- [
- -38,
- -39
- ],
- [
- -27,
- -61
- ],
- [
- -6,
- -83
- ]
- ],
- [
- [
- 13834,
- 11218
- ],
- [
- -45,
- 6
- ],
- [
- -47,
- 20
- ],
- [
- -42,
- -63
- ],
- [
- -36,
- -112
- ]
- ],
- [
- [
- 13664,
- 11069
- ],
- [
- -8,
- 35
- ],
- [
- -3,
- 55
- ],
- [
- -32,
- 38
- ],
- [
- -25,
- 62
- ],
- [
- -6,
- 43
- ],
- [
- -33,
- 63
- ],
- [
- 5,
- 36
- ],
- [
- -7,
- 50
- ],
- [
- 6,
- 93
- ],
- [
- 17,
- 22
- ],
- [
- 35,
- 122
- ]
- ],
- [
- [
- 8110,
- 16382
- ],
- [
- 50,
- -16
- ],
- [
- 65,
- 3
- ],
- [
- -35,
- -49
- ],
- [
- -25,
- -8
- ],
- [
- -89,
- 51
- ],
- [
- -17,
- 40
- ],
- [
- 26,
- 37
- ],
- [
- 25,
- -58
- ]
- ],
- [
- [
- 8239,
- 16688
- ],
- [
- -34,
- -2
- ],
- [
- -90,
- 38
- ],
- [
- -65,
- 56
- ],
- [
- 24,
- 10
- ],
- [
- 92,
- -30
- ],
- [
- 71,
- -50
- ],
- [
- 2,
- -22
- ]
- ],
- [
- [
- 3938,
- 16617
- ],
- [
- -35,
- -17
- ],
- [
- -115,
- 55
- ],
- [
- -21,
- 42
- ],
- [
- -62,
- 42
- ],
- [
- -13,
- 34
- ],
- [
- -71,
- 22
- ],
- [
- -27,
- 65
- ],
- [
- 6,
- 28
- ],
- [
- 73,
- -26
- ],
- [
- 43,
- -18
- ],
- [
- 65,
- -13
- ],
- [
- 24,
- -41
- ],
- [
- 34,
- -57
- ],
- [
- 70,
- -50
- ],
- [
- 29,
- -66
- ]
- ],
- [
- [
- 8634,
- 16878
- ],
- [
- -46,
- -105
- ],
- [
- 46,
- 41
- ],
- [
- 47,
- -26
- ],
- [
- -25,
- -42
- ],
- [
- 62,
- -33
- ],
- [
- 32,
- 29
- ],
- [
- 70,
- -36
- ],
- [
- -22,
- -88
- ],
- [
- 49,
- 20
- ],
- [
- 9,
- -63
- ],
- [
- 21,
- -75
- ],
- [
- -29,
- -106
- ],
- [
- -31,
- -4
- ],
- [
- -46,
- 23
- ],
- [
- 15,
- 98
- ],
- [
- -20,
- 15
- ],
- [
- -80,
- -104
- ],
- [
- -42,
- 4
- ],
- [
- 49,
- 56
- ],
- [
- -67,
- 30
- ],
- [
- -75,
- -8
- ],
- [
- -135,
- 4
- ],
- [
- -11,
- 36
- ],
- [
- 44,
- 42
- ],
- [
- -30,
- 32
- ],
- [
- 58,
- 73
- ],
- [
- 72,
- 191
- ],
- [
- 43,
- 68
- ],
- [
- 61,
- 41
- ],
- [
- 32,
- -5
- ],
- [
- -13,
- -32
- ],
- [
- -38,
- -76
- ]
- ],
- [
- [
- 3264,
- 17296
- ],
- [
- 33,
- -16
- ],
- [
- 66,
- 10
- ],
- [
- -20,
- -136
- ],
- [
- 60,
- -97
- ],
- [
- -28,
- 0
- ],
- [
- -42,
- 55
- ],
- [
- -25,
- 56
- ],
- [
- -36,
- 37
- ],
- [
- -12,
- 53
- ],
- [
- 4,
- 38
- ]
- ],
- [
- [
- 7022,
- 18254
- ],
- [
- -27,
- -63
- ],
- [
- -31,
- 10
- ],
- [
- -18,
- 36
- ],
- [
- 3,
- 9
- ],
- [
- 27,
- 36
- ],
- [
- 28,
- -3
- ],
- [
- 18,
- -25
- ]
- ],
- [
- [
- 6839,
- 18321
- ],
- [
- -82,
- -67
- ],
- [
- -49,
- 3
- ],
- [
- -16,
- 33
- ],
- [
- 52,
- 55
- ],
- [
- 96,
- -1
- ],
- [
- -1,
- -23
- ]
- ],
- [
- [
- 6611,
- 18674
- ],
- [
- 13,
- -53
- ],
- [
- 36,
- 19
- ],
- [
- 40,
- -32
- ],
- [
- 77,
- -41
- ],
- [
- 79,
- -37
- ],
- [
- 7,
- -57
- ],
- [
- 51,
- 9
- ],
- [
- 50,
- -40
- ],
- [
- -62,
- -37
- ],
- [
- -109,
- 28
- ],
- [
- -39,
- 54
- ],
- [
- -69,
- -63
- ],
- [
- -99,
- -62
- ],
- [
- -24,
- 70
- ],
- [
- -95,
- -12
- ],
- [
- 61,
- 59
- ],
- [
- 9,
- 95
- ],
- [
- 24,
- 110
- ],
- [
- 50,
- -10
- ]
- ],
- [
- [
- 7259,
- 18853
- ],
- [
- -78,
- -6
- ],
- [
- -18,
- 59
- ],
- [
- 30,
- 67
- ],
- [
- 64,
- 17
- ],
- [
- 54,
- -34
- ],
- [
- 1,
- -51
- ],
- [
- -8,
- -17
- ],
- [
- -45,
- -35
- ]
- ],
- [
- [
- 5880,
- 19088
- ],
- [
- -43,
- -42
- ],
- [
- -94,
- 36
- ],
- [
- -57,
- -13
- ],
- [
- -95,
- 54
- ],
- [
- 61,
- 37
- ],
- [
- 49,
- 52
- ],
- [
- 74,
- -34
- ],
- [
- 42,
- -21
- ],
- [
- 21,
- -23
- ],
- [
- 42,
- -46
- ]
- ],
- [
- [
- 3985,
- 16676
- ],
- [
- -10,
- 0
- ],
- [
- -135,
- 118
- ],
- [
- -50,
- 52
- ],
- [
- -126,
- 49
- ],
- [
- -39,
- 106
- ],
- [
- 10,
- 74
- ],
- [
- -89,
- 51
- ],
- [
- -12,
- 97
- ],
- [
- -84,
- 87
- ],
- [
- -2,
- 62
- ]
- ],
- [
- [
- 3448,
- 17372
- ],
- [
- 39,
- 58
- ],
- [
- -2,
- 75
- ],
- [
- -119,
- 77
- ],
- [
- -71,
- 137
- ],
- [
- -43,
- 86
- ],
- [
- -64,
- 54
- ],
- [
- -47,
- 49
- ],
- [
- -37,
- 62
- ],
- [
- -70,
- -39
- ],
- [
- -68,
- -67
- ],
- [
- -62,
- 79
- ],
- [
- -49,
- 52
- ],
- [
- -68,
- 34
- ],
- [
- -68,
- 3
- ],
- [
- 0,
- 683
- ],
- [
- 1,
- 445
- ]
- ],
- [
- [
- 2720,
- 19160
- ],
- [
- 130,
- -28
- ],
- [
- 109,
- -58
- ],
- [
- 73,
- -11
- ],
- [
- 61,
- 50
- ],
- [
- 85,
- 37
- ],
- [
- 103,
- -14
- ],
- [
- 105,
- 52
- ],
- [
- 114,
- 30
- ],
- [
- 48,
- -49
- ],
- [
- 52,
- 28
- ],
- [
- 15,
- 56
- ],
- [
- 48,
- -13
- ],
- [
- 118,
- -107
- ],
- [
- 93,
- 81
- ],
- [
- 9,
- -91
- ],
- [
- 86,
- 20
- ],
- [
- 26,
- 35
- ],
- [
- 85,
- -7
- ],
- [
- 106,
- -51
- ],
- [
- 164,
- -44
- ],
- [
- 96,
- -20
- ],
- [
- 68,
- 8
- ],
- [
- 94,
- -61
- ],
- [
- -98,
- -60
- ],
- [
- 126,
- -25
- ],
- [
- 188,
- 14
- ],
- [
- 59,
- 21
- ],
- [
- 75,
- -72
- ],
- [
- 75,
- 61
- ],
- [
- -71,
- 50
- ],
- [
- 45,
- 42
- ],
- [
- 85,
- 5
- ],
- [
- 56,
- 12
- ],
- [
- 56,
- -29
- ],
- [
- 70,
- -65
- ],
- [
- 78,
- 10
- ],
- [
- 123,
- -54
- ],
- [
- 109,
- 19
- ],
- [
- 101,
- -3
- ],
- [
- -8,
- 75
- ],
- [
- 62,
- 20
- ],
- [
- 108,
- -40
- ],
- [
- 0,
- -114
- ],
- [
- 44,
- 96
- ],
- [
- 56,
- -3
- ],
- [
- 32,
- 120
- ],
- [
- -75,
- 74
- ],
- [
- -81,
- 49
- ],
- [
- 5,
- 132
- ],
- [
- 83,
- 87
- ],
- [
- 92,
- -19
- ],
- [
- 70,
- -53
- ],
- [
- 95,
- -135
- ],
- [
- -62,
- -59
- ],
- [
- 130,
- -24
- ],
- [
- -1,
- -123
- ],
- [
- 93,
- 94
- ],
- [
- 84,
- -77
- ],
- [
- -21,
- -89
- ],
- [
- 67,
- -81
- ],
- [
- 73,
- 87
- ],
- [
- 51,
- 103
- ],
- [
- 4,
- 132
- ],
- [
- 99,
- -9
- ],
- [
- 103,
- -18
- ],
- [
- 94,
- -60
- ],
- [
- 4,
- -59
- ],
- [
- -52,
- -64
- ],
- [
- 49,
- -64
- ],
- [
- -9,
- -59
- ],
- [
- -136,
- -83
- ],
- [
- -97,
- -19
- ],
- [
- -72,
- 36
- ],
- [
- -21,
- -60
- ],
- [
- -67,
- -101
- ],
- [
- -21,
- -53
- ],
- [
- -80,
- -81
- ],
- [
- -100,
- -8
- ],
- [
- -55,
- -51
- ],
- [
- -5,
- -78
- ],
- [
- -81,
- -15
- ],
- [
- -85,
- -97
- ],
- [
- -76,
- -135
- ],
- [
- -27,
- -94
- ],
- [
- -4,
- -140
- ],
- [
- 103,
- -20
- ],
- [
- 31,
- -112
- ],
- [
- 33,
- -91
- ],
- [
- 97,
- 24
- ],
- [
- 130,
- -52
- ],
- [
- 69,
- -46
- ],
- [
- 50,
- -57
- ],
- [
- 88,
- -33
- ],
- [
- 73,
- -50
- ],
- [
- 116,
- -7
- ],
- [
- 75,
- -12
- ],
- [
- -11,
- -104
- ],
- [
- 22,
- -120
- ],
- [
- 50,
- -134
- ],
- [
- 104,
- -114
- ],
- [
- 54,
- 39
- ],
- [
- 37,
- 123
- ],
- [
- -36,
- 189
- ],
- [
- -49,
- 64
- ],
- [
- 111,
- 56
- ],
- [
- 79,
- 84
- ],
- [
- 39,
- 84
- ],
- [
- -6,
- 80
- ],
- [
- -47,
- 102
- ],
- [
- -85,
- 90
- ],
- [
- 82,
- 126
- ],
- [
- -30,
- 108
- ],
- [
- -23,
- 188
- ],
- [
- 48,
- 27
- ],
- [
- 120,
- -32
- ],
- [
- 72,
- -12
- ],
- [
- 57,
- 32
- ],
- [
- 65,
- -41
- ],
- [
- 86,
- -70
- ],
- [
- 21,
- -46
- ],
- [
- 124,
- -9
- ],
- [
- -2,
- -101
- ],
- [
- 24,
- -152
- ],
- [
- 63,
- -19
- ],
- [
- 51,
- -70
- ],
- [
- 101,
- 66
- ],
- [
- 66,
- 133
- ],
- [
- 46,
- 56
- ],
- [
- 55,
- -108
- ],
- [
- 91,
- -153
- ],
- [
- 77,
- -143
- ],
- [
- -28,
- -76
- ],
- [
- 92,
- -67
- ],
- [
- 63,
- -69
- ],
- [
- 111,
- -31
- ],
- [
- 45,
- -38
- ],
- [
- 28,
- -102
- ],
- [
- 54,
- -16
- ],
- [
- 28,
- -45
- ],
- [
- 5,
- -135
- ],
- [
- -51,
- -45
- ],
- [
- -50,
- -42
- ],
- [
- -115,
- -43
- ],
- [
- -87,
- -98
- ],
- [
- -118,
- -20
- ],
- [
- -149,
- 26
- ],
- [
- -105,
- 0
- ],
- [
- -72,
- -8
- ],
- [
- -58,
- -86
- ],
- [
- -89,
- -53
- ],
- [
- -101,
- -159
- ],
- [
- -80,
- -111
- ],
- [
- 59,
- 20
- ],
- [
- 112,
- 158
- ],
- [
- 146,
- 100
- ],
- [
- 105,
- 12
- ],
- [
- 61,
- -59
- ],
- [
- -66,
- -81
- ],
- [
- 23,
- -129
- ],
- [
- 22,
- -91
- ],
- [
- 91,
- -60
- ],
- [
- 115,
- 18
- ],
- [
- 70,
- 135
- ],
- [
- 5,
- -87
- ],
- [
- 45,
- -44
- ],
- [
- -86,
- -78
- ],
- [
- -155,
- -72
- ],
- [
- -69,
- -48
- ],
- [
- -78,
- -87
- ],
- [
- -53,
- 9
- ],
- [
- -3,
- 102
- ],
- [
- 122,
- 99
- ],
- [
- -112,
- -4
- ],
- [
- -78,
- -15
- ]
- ],
- [
- [
- 7867,
- 16212
- ],
- [
- -45,
- 68
- ],
- [
- 0,
- 164
- ],
- [
- -31,
- 34
- ],
- [
- -47,
- -20
- ],
- [
- -23,
- 31
- ],
- [
- -53,
- -90
- ],
- [
- -21,
- -93
- ],
- [
- -25,
- -55
- ],
- [
- -30,
- -19
- ],
- [
- -22,
- -6
- ],
- [
- -7,
- -29
- ],
- [
- -128,
- 0
- ],
- [
- -106,
- -1
- ],
- [
- -32,
- -22
- ],
- [
- -73,
- -87
- ],
- [
- -9,
- -9
- ],
- [
- -22,
- -47
- ],
- [
- -64,
- 0
- ],
- [
- -69,
- 0
- ],
- [
- -31,
- -19
- ],
- [
- 11,
- -24
- ],
- [
- 6,
- -36
- ],
- [
- -1,
- -13
- ],
- [
- -91,
- -59
- ],
- [
- -72,
- -19
- ],
- [
- -81,
- -64
- ],
- [
- -18,
- 0
- ],
- [
- -23,
- 19
- ],
- [
- -8,
- 17
- ],
- [
- 1,
- 12
- ],
- [
- 16,
- 42
- ],
- [
- 32,
- 66
- ],
- [
- 21,
- 71
- ],
- [
- -14,
- 105
- ],
- [
- -15,
- 108
- ],
- [
- -73,
- 57
- ],
- [
- 9,
- 21
- ],
- [
- -10,
- 15
- ],
- [
- -19,
- 0
- ],
- [
- -14,
- 19
- ],
- [
- -4,
- 28
- ],
- [
- -13,
- -12
- ],
- [
- -19,
- 3
- ],
- [
- 4,
- 12
- ],
- [
- -16,
- 12
- ],
- [
- -7,
- 32
- ],
- [
- -54,
- 38
- ],
- [
- -57,
- 40
- ],
- [
- -68,
- 46
- ],
- [
- -65,
- 44
- ],
- [
- -63,
- -34
- ],
- [
- -22,
- -1
- ],
- [
- -86,
- 31
- ],
- [
- -57,
- -16
- ],
- [
- -67,
- 38
- ],
- [
- -71,
- 19
- ],
- [
- -49,
- 7
- ],
- [
- -22,
- 20
- ],
- [
- -12,
- 66
- ],
- [
- -24,
- 0
- ],
- [
- 0,
- -46
- ],
- [
- -144,
- 0
- ],
- [
- -239,
- 0
- ],
- [
- -237,
- 0
- ],
- [
- -209,
- 0
- ],
- [
- -209,
- 0
- ],
- [
- -206,
- 0
- ],
- [
- -212,
- 0
- ],
- [
- -69,
- 0
- ],
- [
- -207,
- 0
- ],
- [
- -197,
- 0
- ]
- ],
- [
- [
- 4589,
- 19569
- ],
- [
- -35,
- -56
- ],
- [
- 155,
- 37
- ],
- [
- 97,
- -61
- ],
- [
- 79,
- 61
- ],
- [
- 64,
- -39
- ],
- [
- 57,
- -118
- ],
- [
- 35,
- 50
- ],
- [
- -50,
- 123
- ],
- [
- 62,
- 17
- ],
- [
- 69,
- -19
- ],
- [
- 78,
- -48
- ],
- [
- 44,
- -117
- ],
- [
- 21,
- -85
- ],
- [
- 118,
- -59
- ],
- [
- 125,
- -57
- ],
- [
- -7,
- -53
- ],
- [
- -115,
- -9
- ],
- [
- 45,
- -47
- ],
- [
- -24,
- -44
- ],
- [
- -126,
- 19
- ],
- [
- -120,
- 33
- ],
- [
- -81,
- -8
- ],
- [
- -131,
- -40
- ],
- [
- -176,
- -18
- ],
- [
- -124,
- -12
- ],
- [
- -38,
- 57
- ],
- [
- -95,
- 33
- ],
- [
- -62,
- -14
- ],
- [
- -86,
- 95
- ],
- [
- 46,
- 13
- ],
- [
- 108,
- 20
- ],
- [
- 98,
- -5
- ],
- [
- 91,
- 21
- ],
- [
- -135,
- 28
- ],
- [
- -149,
- -10
- ],
- [
- -98,
- 3
- ],
- [
- -37,
- 44
- ],
- [
- 161,
- 48
- ],
- [
- -107,
- -2
- ],
- [
- -122,
- 32
- ],
- [
- 59,
- 90
- ],
- [
- 48,
- 48
- ],
- [
- 187,
- 73
- ],
- [
- 71,
- -24
- ]
- ],
- [
- [
- 5263,
- 19605
- ],
- [
- -61,
- -79
- ],
- [
- -109,
- 84
- ],
- [
- 24,
- 17
- ],
- [
- 93,
- 5
- ],
- [
- 53,
- -27
- ]
- ],
- [
- [
- 7226,
- 19567
- ],
- [
- 6,
- -33
- ],
- [
- -74,
- 4
- ],
- [
- -75,
- 2
- ],
- [
- -76,
- -16
- ],
- [
- -21,
- 7
- ],
- [
- -76,
- 64
- ],
- [
- 3,
- 43
- ],
- [
- 33,
- 8
- ],
- [
- 160,
- -13
- ],
- [
- 120,
- -66
- ]
- ],
- [
- [
- 6513,
- 19574
- ],
- [
- 55,
- -75
- ],
- [
- 65,
- 97
- ],
- [
- 176,
- 49
- ],
- [
- 120,
- -124
- ],
- [
- -10,
- -79
- ],
- [
- 138,
- 35
- ],
- [
- 65,
- 48
- ],
- [
- 155,
- -61
- ],
- [
- 96,
- -57
- ],
- [
- 9,
- -52
- ],
- [
- 130,
- 27
- ],
- [
- 72,
- -77
- ],
- [
- 169,
- -47
- ],
- [
- 60,
- -48
- ],
- [
- 66,
- -113
- ],
- [
- -128,
- -56
- ],
- [
- 164,
- -78
- ],
- [
- 111,
- -26
- ],
- [
- 100,
- -110
- ],
- [
- 110,
- -8
- ],
- [
- -22,
- -85
- ],
- [
- -122,
- -139
- ],
- [
- -86,
- 51
- ],
- [
- -110,
- 116
- ],
- [
- -90,
- -15
- ],
- [
- -9,
- -69
- ],
- [
- 74,
- -70
- ],
- [
- 94,
- -55
- ],
- [
- 29,
- -32
- ],
- [
- 46,
- -119
- ],
- [
- -25,
- -86
- ],
- [
- -87,
- 33
- ],
- [
- -175,
- 96
- ],
- [
- 98,
- -104
- ],
- [
- 73,
- -72
- ],
- [
- 11,
- -42
- ],
- [
- -189,
- 48
- ],
- [
- -149,
- 70
- ],
- [
- -85,
- 58
- ],
- [
- 24,
- 34
- ],
- [
- -104,
- 61
- ],
- [
- -101,
- 59
- ],
- [
- 1,
- -35
- ],
- [
- -202,
- -19
- ],
- [
- -59,
- 41
- ],
- [
- 46,
- 88
- ],
- [
- 131,
- 2
- ],
- [
- 144,
- 16
- ],
- [
- -23,
- 43
- ],
- [
- 24,
- 59
- ],
- [
- 90,
- 117
- ],
- [
- -19,
- 53
- ],
- [
- -27,
- 41
- ],
- [
- -107,
- 59
- ],
- [
- -141,
- 40
- ],
- [
- 45,
- 31
- ],
- [
- -74,
- 74
- ],
- [
- -62,
- 7
- ],
- [
- -54,
- 41
- ],
- [
- -38,
- -35
- ],
- [
- -126,
- -16
- ],
- [
- -254,
- 27
- ],
- [
- -147,
- 35
- ],
- [
- -113,
- 18
- ],
- [
- -58,
- 42
- ],
- [
- 73,
- 55
- ],
- [
- -99,
- 1
- ],
- [
- -23,
- 121
- ],
- [
- 54,
- 107
- ],
- [
- 72,
- 49
- ],
- [
- 180,
- 32
- ],
- [
- -52,
- -77
- ]
- ],
- [
- [
- 5552,
- 19656
- ],
- [
- 83,
- -25
- ],
- [
- 124,
- 15
- ],
- [
- 18,
- -35
- ],
- [
- -65,
- -57
- ],
- [
- 106,
- -52
- ],
- [
- -13,
- -108
- ],
- [
- -114,
- -46
- ],
- [
- -67,
- 10
- ],
- [
- -48,
- 46
- ],
- [
- -174,
- 92
- ],
- [
- 2,
- 39
- ],
- [
- 142,
- -15
- ],
- [
- -77,
- 78
- ],
- [
- 83,
- 58
- ]
- ],
- [
- [
- 6051,
- 19528
- ],
- [
- -75,
- -90
- ],
- [
- -79,
- 4
- ],
- [
- -44,
- 106
- ],
- [
- 1,
- 59
- ],
- [
- 37,
- 51
- ],
- [
- 69,
- 33
- ],
- [
- 145,
- -4
- ],
- [
- 133,
- -29
- ],
- [
- -104,
- -107
- ],
- [
- -83,
- -23
- ]
- ],
- [
- [
- 4150,
- 19361
- ],
- [
- -183,
- -58
- ],
- [
- -37,
- 53
- ],
- [
- -161,
- 63
- ],
- [
- 30,
- 51
- ],
- [
- 48,
- 88
- ],
- [
- 61,
- 78
- ],
- [
- -68,
- 74
- ],
- [
- 235,
- 19
- ],
- [
- 100,
- -25
- ],
- [
- 178,
- -7
- ],
- [
- 68,
- -35
- ],
- [
- 74,
- -50
- ],
- [
- -87,
- -30
- ],
- [
- -171,
- -85
- ],
- [
- -87,
- -84
- ],
- [
- 0,
- -52
- ]
- ],
- [
- [
- 6022,
- 19792
- ],
- [
- -38,
- -46
- ],
- [
- -101,
- 9
- ],
- [
- -85,
- 31
- ],
- [
- 37,
- 54
- ],
- [
- 101,
- 32
- ],
- [
- 60,
- -42
- ],
- [
- 26,
- -38
- ]
- ],
- [
- [
- 5681,
- 20001
- ],
- [
- 54,
- -55
- ],
- [
- 2,
- -62
- ],
- [
- -32,
- -89
- ],
- [
- -115,
- -12
- ],
- [
- -75,
- 19
- ],
- [
- 2,
- 70
- ],
- [
- -115,
- -10
- ],
- [
- -4,
- 93
- ],
- [
- 75,
- -4
- ],
- [
- 105,
- 41
- ],
- [
- 98,
- -7
- ],
- [
- 5,
- 16
- ]
- ],
- [
- [
- 5004,
- 19939
- ],
- [
- 28,
- -43
- ],
- [
- 62,
- 20
- ],
- [
- 73,
- -5
- ],
- [
- 12,
- -59
- ],
- [
- -42,
- -57
- ],
- [
- -237,
- -18
- ],
- [
- -175,
- -52
- ],
- [
- -106,
- -3
- ],
- [
- -9,
- 39
- ],
- [
- 145,
- 53
- ],
- [
- -315,
- -14
- ],
- [
- -98,
- 22
- ],
- [
- 95,
- 117
- ],
- [
- 66,
- 33
- ],
- [
- 196,
- -40
- ],
- [
- 124,
- -71
- ],
- [
- 122,
- -9
- ],
- [
- -100,
- 114
- ],
- [
- 64,
- 44
- ],
- [
- 72,
- -14
- ],
- [
- 23,
- -57
- ]
- ],
- [
- [
- 5947,
- 20047
- ],
- [
- 78,
- -39
- ],
- [
- 137,
- 0
- ],
- [
- 60,
- -39
- ],
- [
- -16,
- -45
- ],
- [
- 80,
- -27
- ],
- [
- 44,
- -29
- ],
- [
- 94,
- -5
- ],
- [
- 102,
- -10
- ],
- [
- 111,
- 26
- ],
- [
- 142,
- 10
- ],
- [
- 113,
- -8
- ],
- [
- 75,
- -46
- ],
- [
- 15,
- -49
- ],
- [
- -43,
- -32
- ],
- [
- -104,
- -26
- ],
- [
- -89,
- 15
- ],
- [
- -200,
- -19
- ],
- [
- -143,
- -2
- ],
- [
- -113,
- 15
- ],
- [
- -185,
- 38
- ],
- [
- -24,
- 66
- ],
- [
- -9,
- 60
- ],
- [
- -70,
- 52
- ],
- [
- -144,
- 15
- ],
- [
- -81,
- 37
- ],
- [
- 27,
- 49
- ],
- [
- 143,
- -7
- ]
- ],
- [
- [
- 4447,
- 20112
- ],
- [
- -9,
- -92
- ],
- [
- -54,
- -42
- ],
- [
- -65,
- -5
- ],
- [
- -129,
- -52
- ],
- [
- -112,
- -18
- ],
- [
- -95,
- 26
- ],
- [
- 119,
- 90
- ],
- [
- 143,
- 77
- ],
- [
- 107,
- -1
- ],
- [
- 95,
- 17
- ]
- ],
- [
- [
- 6006,
- 20097
- ],
- [
- -32,
- -3
- ],
- [
- -130,
- 7
- ],
- [
- -19,
- 34
- ],
- [
- 140,
- -2
- ],
- [
- 49,
- -22
- ],
- [
- -8,
- -14
- ]
- ],
- [
- [
- 4867,
- 20118
- ],
- [
- -130,
- -34
- ],
- [
- -104,
- 39
- ],
- [
- 57,
- 38
- ],
- [
- 101,
- 12
- ],
- [
- 99,
- -19
- ],
- [
- -23,
- -36
- ]
- ],
- [
- [
- 4903,
- 20227
- ],
- [
- -85,
- -23
- ],
- [
- -116,
- 0
- ],
- [
- 2,
- 17
- ],
- [
- 71,
- 36
- ],
- [
- 37,
- -6
- ],
- [
- 91,
- -24
- ]
- ],
- [
- [
- 5867,
- 20162
- ],
- [
- -103,
- -25
- ],
- [
- -57,
- 28
- ],
- [
- -29,
- 45
- ],
- [
- -6,
- 49
- ],
- [
- 90,
- -4
- ],
- [
- 41,
- -8
- ],
- [
- 83,
- -42
- ],
- [
- -19,
- -43
- ]
- ],
- [
- [
- 5572,
- 20194
- ],
- [
- 28,
- -50
- ],
- [
- -114,
- 13
- ],
- [
- -115,
- 39
- ],
- [
- -155,
- 4
- ],
- [
- 67,
- 36
- ],
- [
- -84,
- 29
- ],
- [
- -5,
- 46
- ],
- [
- 137,
- -16
- ],
- [
- 188,
- -44
- ],
- [
- 53,
- -57
- ]
- ],
- [
- [
- 6481,
- 20354
- ],
- [
- 85,
- -39
- ],
- [
- -96,
- -36
- ],
- [
- -129,
- -90
- ],
- [
- -123,
- -8
- ],
- [
- -145,
- 15
- ],
- [
- -75,
- 49
- ],
- [
- 1,
- 43
- ],
- [
- 56,
- 32
- ],
- [
- -128,
- -1
- ],
- [
- -77,
- 40
- ],
- [
- -44,
- 55
- ],
- [
- 48,
- 53
- ],
- [
- 49,
- 37
- ],
- [
- 71,
- 8
- ],
- [
- -30,
- 27
- ],
- [
- 162,
- 7
- ],
- [
- 89,
- -65
- ],
- [
- 117,
- -25
- ],
- [
- 114,
- -23
- ],
- [
- 55,
- -79
- ]
- ],
- [
- [
- 7772,
- 20767
- ],
- [
- 187,
- -9
- ],
- [
- 149,
- -15
- ],
- [
- 128,
- -33
- ],
- [
- -3,
- -32
- ],
- [
- -170,
- -52
- ],
- [
- -169,
- -24
- ],
- [
- -63,
- -27
- ],
- [
- 152,
- 0
- ],
- [
- -165,
- -72
- ],
- [
- -113,
- -34
- ],
- [
- -119,
- -98
- ],
- [
- -144,
- -20
- ],
- [
- -45,
- -25
- ],
- [
- -211,
- -13
- ],
- [
- 96,
- -15
- ],
- [
- -48,
- -21
- ],
- [
- 58,
- -59
- ],
- [
- -66,
- -41
- ],
- [
- -108,
- -34
- ],
- [
- -33,
- -47
- ],
- [
- -97,
- -36
- ],
- [
- 9,
- -27
- ],
- [
- 119,
- 4
- ],
- [
- 2,
- -29
- ],
- [
- -186,
- -72
- ],
- [
- -182,
- 33
- ],
- [
- -205,
- -18
- ],
- [
- -104,
- 14
- ],
- [
- -132,
- 6
- ],
- [
- -8,
- 58
- ],
- [
- 128,
- 27
- ],
- [
- -34,
- 87
- ],
- [
- 43,
- 8
- ],
- [
- 186,
- -52
- ],
- [
- -95,
- 77
- ],
- [
- -113,
- 23
- ],
- [
- 56,
- 47
- ],
- [
- 124,
- 28
- ],
- [
- 20,
- 42
- ],
- [
- -99,
- 47
- ],
- [
- -29,
- 62
- ],
- [
- 190,
- -5
- ],
- [
- 55,
- -13
- ],
- [
- 109,
- 43
- ],
- [
- -157,
- 14
- ],
- [
- -244,
- -7
- ],
- [
- -123,
- 40
- ],
- [
- -58,
- 49
- ],
- [
- -82,
- 35
- ],
- [
- -15,
- 41
- ],
- [
- 104,
- 23
- ],
- [
- 81,
- 4
- ],
- [
- 137,
- 19
- ],
- [
- 102,
- 45
- ],
- [
- 87,
- -6
- ],
- [
- 75,
- -34
- ],
- [
- 53,
- 65
- ],
- [
- 92,
- 19
- ],
- [
- 125,
- 13
- ],
- [
- 213,
- 5
- ],
- [
- 37,
- -13
- ],
- [
- 202,
- 21
- ],
- [
- 151,
- -8
- ],
- [
- 150,
- -8
- ]
- ],
- [
- [
- 13275,
- 16423
- ],
- [
- -5,
- -49
- ],
- [
- -31,
- -20
- ],
- [
- -51,
- 15
- ],
- [
- -15,
- -49
- ],
- [
- -34,
- -4
- ],
- [
- -12,
- 19
- ],
- [
- -39,
- -40
- ],
- [
- -33,
- -6
- ],
- [
- -30,
- 26
- ]
- ],
- [
- [
- 13025,
- 16315
- ],
- [
- -24,
- 52
- ],
- [
- -34,
- -18
- ],
- [
- 1,
- 54
- ],
- [
- 51,
- 67
- ],
- [
- -2,
- 31
- ],
- [
- 32,
- -11
- ],
- [
- 19,
- 20
- ]
- ],
- [
- [
- 13068,
- 16510
- ],
- [
- 59,
- -1
- ],
- [
- 15,
- 26
- ],
- [
- 74,
- -36
- ]
- ],
- [
- [
- 7880,
- 4211
- ],
- [
- -23,
- -48
- ],
- [
- -60,
- -37
- ],
- [
- -34,
- 3
- ],
- [
- -42,
- 10
- ],
- [
- -50,
- 36
- ],
- [
- -73,
- 17
- ],
- [
- -88,
- 67
- ],
- [
- -71,
- 65
- ],
- [
- -96,
- 134
- ],
- [
- 57,
- -25
- ],
- [
- 98,
- -80
- ],
- [
- 93,
- -43
- ],
- [
- 36,
- 55
- ],
- [
- 22,
- 82
- ],
- [
- 65,
- 50
- ],
- [
- 49,
- -15
- ]
- ],
- [
- [
- 7767,
- 4523
- ],
- [
- -62,
- 1
- ],
- [
- -33,
- -30
- ],
- [
- -63,
- -43
- ],
- [
- -11,
- -112
- ],
- [
- -30,
- -3
- ],
- [
- -78,
- 39
- ],
- [
- -80,
- 84
- ],
- [
- -87,
- 68
- ],
- [
- -22,
- 76
- ],
- [
- 20,
- 71
- ],
- [
- -35,
- 79
- ],
- [
- -9,
- 205
- ],
- [
- 30,
- 115
- ],
- [
- 73,
- 93
- ],
- [
- -106,
- 35
- ],
- [
- 67,
- 106
- ],
- [
- 24,
- 199
- ],
- [
- 77,
- -42
- ],
- [
- 36,
- 249
- ],
- [
- -46,
- 31
- ],
- [
- -22,
- -149
- ],
- [
- -44,
- 17
- ],
- [
- 22,
- 171
- ],
- [
- 24,
- 222
- ],
- [
- 32,
- 82
- ],
- [
- -20,
- 117
- ],
- [
- -6,
- 136
- ],
- [
- 29,
- 3
- ],
- [
- 43,
- 194
- ],
- [
- 48,
- 192
- ],
- [
- 30,
- 179
- ],
- [
- -16,
- 180
- ],
- [
- 20,
- 99
- ],
- [
- -8,
- 148
- ],
- [
- 41,
- 146
- ],
- [
- 12,
- 232
- ],
- [
- 23,
- 249
- ],
- [
- 22,
- 269
- ],
- [
- -6,
- 196
- ],
- [
- -14,
- 169
- ]
- ],
- [
- [
- 7642,
- 8596
- ],
- [
- 36,
- 31
- ],
- [
- 18,
- 61
- ]
- ],
- [
- [
- 17774,
- 15286
- ],
- [
- -10,
- 69
- ],
- [
- 2,
- 46
- ],
- [
- -42,
- 28
- ],
- [
- -23,
- -12
- ],
- [
- -18,
- 111
- ]
- ],
- [
- [
- 17683,
- 15528
- ],
- [
- 20,
- 27
- ],
- [
- -9,
- 28
- ],
- [
- 66,
- 57
- ],
- [
- 48,
- 23
- ],
- [
- 74,
- -16
- ],
- [
- 26,
- 77
- ],
- [
- 90,
- 14
- ],
- [
- 25,
- 48
- ],
- [
- 109,
- 65
- ],
- [
- 10,
- 27
- ]
- ],
- [
- [
- 18142,
- 15878
- ],
- [
- -5,
- 68
- ],
- [
- 48,
- 31
- ],
- [
- -63,
- 209
- ],
- [
- 138,
- 48
- ],
- [
- 36,
- 27
- ],
- [
- 50,
- 214
- ],
- [
- 138,
- -39
- ],
- [
- 39,
- 54
- ],
- [
- 3,
- 120
- ],
- [
- 58,
- 12
- ],
- [
- 53,
- 79
- ]
- ],
- [
- [
- 18637,
- 16701
- ],
- [
- 27,
- 10
- ]
- ],
- [
- [
- 18664,
- 16711
- ],
- [
- 19,
- -83
- ],
- [
- 58,
- -64
- ],
- [
- 100,
- -45
- ],
- [
- 48,
- -97
- ],
- [
- -27,
- -140
- ],
- [
- 25,
- -52
- ],
- [
- 83,
- -20
- ],
- [
- 94,
- -17
- ],
- [
- 84,
- -75
- ],
- [
- 43,
- -13
- ],
- [
- 32,
- -111
- ],
- [
- 41,
- -71
- ],
- [
- 77,
- 3
- ],
- [
- 144,
- -27
- ],
- [
- 92,
- 17
- ],
- [
- 69,
- -18
- ],
- [
- 103,
- -73
- ],
- [
- 85,
- 0
- ],
- [
- 30,
- -37
- ],
- [
- 82,
- 64
- ],
- [
- 112,
- 42
- ],
- [
- 105,
- 4
- ],
- [
- 81,
- 42
- ],
- [
- 50,
- 65
- ],
- [
- 49,
- 40
- ],
- [
- -11,
- 40
- ],
- [
- -23,
- 46
- ],
- [
- 37,
- 77
- ],
- [
- 39,
- -11
- ],
- [
- 72,
- -24
- ],
- [
- 69,
- 64
- ],
- [
- 107,
- 46
- ],
- [
- 51,
- 79
- ],
- [
- 49,
- 34
- ],
- [
- 101,
- 16
- ],
- [
- 55,
- -13
- ],
- [
- 8,
- 42
- ],
- [
- -64,
- 84
- ],
- [
- -55,
- 39
- ],
- [
- -54,
- -45
- ],
- [
- -69,
- 19
- ],
- [
- -39,
- -15
- ],
- [
- -18,
- 49
- ],
- [
- 49,
- 120
- ],
- [
- 34,
- 90
- ]
- ],
- [
- [
- 20681,
- 16782
- ],
- [
- 84,
- -45
- ],
- [
- 98,
- 76
- ],
- [
- -1,
- 53
- ],
- [
- 63,
- 127
- ],
- [
- 39,
- 38
- ],
- [
- -1,
- 67
- ],
- [
- -38,
- 28
- ],
- [
- 57,
- 60
- ],
- [
- 87,
- 21
- ],
- [
- 92,
- 4
- ],
- [
- 105,
- -36
- ],
- [
- 61,
- -44
- ],
- [
- 43,
- -121
- ],
- [
- 26,
- -52
- ],
- [
- 24,
- -74
- ],
- [
- 26,
- -117
- ],
- [
- 122,
- -38
- ],
- [
- 82,
- -86
- ],
- [
- 28,
- -112
- ],
- [
- 106,
- -1
- ],
- [
- 61,
- 48
- ],
- [
- 115,
- 35
- ],
- [
- -37,
- -108
- ],
- [
- -27,
- -44
- ],
- [
- -24,
- -131
- ],
- [
- -47,
- -117
- ],
- [
- -84,
- 21
- ],
- [
- -60,
- -42
- ],
- [
- 18,
- -103
- ],
- [
- -10,
- -142
- ],
- [
- -35,
- -3
- ],
- [
- 0,
- -61
- ]
- ],
- [
- [
- 21654,
- 15883
- ],
- [
- -45,
- 71
- ],
- [
- -28,
- -67
- ],
- [
- -107,
- -52
- ],
- [
- 11,
- -63
- ],
- [
- -61,
- 4
- ],
- [
- -33,
- 38
- ],
- [
- -48,
- -85
- ],
- [
- -76,
- -65
- ],
- [
- -57,
- -77
- ]
- ],
- [
- [
- 21210,
- 15587
- ],
- [
- -98,
- -35
- ],
- [
- -51,
- -56
- ],
- [
- -75,
- -32
- ],
- [
- 37,
- 55
- ],
- [
- -15,
- 47
- ],
- [
- 56,
- 81
- ],
- [
- -37,
- 62
- ],
- [
- -61,
- -42
- ],
- [
- -79,
- -83
- ],
- [
- -43,
- -78
- ],
- [
- -68,
- -6
- ],
- [
- -35,
- -55
- ],
- [
- 36,
- -82
- ],
- [
- 57,
- -19
- ],
- [
- 3,
- -54
- ],
- [
- 55,
- -35
- ],
- [
- 78,
- 85
- ],
- [
- 62,
- -46
- ],
- [
- 45,
- -3
- ],
- [
- 11,
- -63
- ],
- [
- -99,
- -34
- ],
- [
- -32,
- -65
- ],
- [
- -68,
- -60
- ],
- [
- -36,
- -84
- ],
- [
- 75,
- -66
- ],
- [
- 28,
- -118
- ],
- [
- 42,
- -110
- ],
- [
- 48,
- -92
- ],
- [
- -2,
- -89
- ],
- [
- -43,
- -33
- ],
- [
- 16,
- -64
- ],
- [
- 41,
- -37
- ],
- [
- -10,
- -98
- ],
- [
- -18,
- -95
- ],
- [
- -39,
- -10
- ],
- [
- -51,
- -130
- ],
- [
- -56,
- -158
- ],
- [
- -65,
- -143
- ],
- [
- -96,
- -111
- ],
- [
- -97,
- -101
- ],
- [
- -79,
- -13
- ],
- [
- -42,
- -54
- ],
- [
- -24,
- 39
- ],
- [
- -40,
- -59
- ],
- [
- -97,
- -60
- ],
- [
- -74,
- -19
- ],
- [
- -24,
- -127
- ],
- [
- -38,
- -7
- ],
- [
- -19,
- 88
- ],
- [
- 17,
- 46
- ],
- [
- -94,
- 38
- ],
- [
- -33,
- -19
- ]
- ],
- [
- [
- 20079,
- 13383
- ],
- [
- -70,
- 31
- ],
- [
- -33,
- 49
- ],
- [
- 11,
- 69
- ],
- [
- -64,
- 22
- ],
- [
- -33,
- 45
- ],
- [
- -60,
- -64
- ],
- [
- -67,
- -14
- ],
- [
- -56,
- 1
- ],
- [
- -37,
- -30
- ]
- ],
- [
- [
- 19670,
- 13492
- ],
- [
- -37,
- -17
- ],
- [
- 11,
- -138
- ],
- [
- -37,
- 4
- ],
- [
- -6,
- 28
- ]
- ],
- [
- [
- 19601,
- 13369
- ],
- [
- -2,
- 50
- ],
- [
- -52,
- -35
- ],
- [
- -30,
- 22
- ],
- [
- -52,
- 45
- ],
- [
- 21,
- 99
- ],
- [
- -44,
- 24
- ],
- [
- -17,
- 110
- ],
- [
- -74,
- -20
- ],
- [
- 9,
- 142
- ],
- [
- 66,
- 101
- ],
- [
- 3,
- 99
- ],
- [
- -2,
- 91
- ],
- [
- -31,
- 29
- ],
- [
- -23,
- 71
- ],
- [
- -41,
- -9
- ]
- ],
- [
- [
- 19332,
- 14188
- ],
- [
- -75,
- 18
- ],
- [
- 23,
- 50
- ],
- [
- -32,
- 75
- ],
- [
- -50,
- -51
- ],
- [
- -58,
- 30
- ],
- [
- -81,
- -77
- ],
- [
- -63,
- -89
- ],
- [
- -56,
- -15
- ]
- ],
- [
- [
- 18739,
- 14072
- ],
- [
- -6,
- 95
- ],
- [
- -43,
- -25
- ]
- ],
- [
- [
- 18690,
- 14142
- ],
- [
- -81,
- 11
- ],
- [
- -79,
- 28
- ],
- [
- -56,
- 52
- ],
- [
- -55,
- 24
- ],
- [
- -23,
- 58
- ],
- [
- -39,
- 17
- ],
- [
- -71,
- 78
- ],
- [
- -55,
- 37
- ],
- [
- -29,
- -29
- ]
- ],
- [
- [
- 18202,
- 14418
- ],
- [
- -97,
- 84
- ],
- [
- -69,
- 76
- ],
- [
- -19,
- 132
- ],
- [
- 50,
- -16
- ],
- [
- 2,
- 61
- ],
- [
- -28,
- 62
- ],
- [
- 7,
- 98
- ],
- [
- -75,
- 140
- ]
- ],
- [
- [
- 17973,
- 15055
- ],
- [
- -114,
- 49
- ],
- [
- -21,
- 92
- ],
- [
- -51,
- 56
- ]
- ],
- [
- [
- 20239,
- 13038
- ],
- [
- -60,
- -58
- ],
- [
- -57,
- 38
- ],
- [
- -2,
- 103
- ],
- [
- 34,
- 54
- ],
- [
- 76,
- 34
- ],
- [
- 40,
- -3
- ],
- [
- 16,
- -46
- ],
- [
- -31,
- -53
- ],
- [
- -16,
- -69
- ]
- ],
- [
- [
- 12350,
- 11954
- ],
- [
- 19,
- -171
- ],
- [
- -29,
- -100
- ],
- [
- -19,
- -136
- ],
- [
- 31,
- -103
- ],
- [
- -4,
- -48
- ]
- ],
- [
- [
- 12348,
- 11396
- ],
- [
- -31,
- -1
- ],
- [
- -49,
- 24
- ],
- [
- -45,
- -2
- ],
- [
- -82,
- -21
- ],
- [
- -49,
- -34
- ],
- [
- -69,
- -44
- ],
- [
- -13,
- 3
- ]
- ],
- [
- [
- 12010,
- 11321
- ],
- [
- 5,
- 99
- ],
- [
- 7,
- 15
- ],
- [
- -2,
- 47
- ],
- [
- -30,
- 50
- ],
- [
- -22,
- 8
- ],
- [
- -20,
- 33
- ],
- [
- 15,
- 53
- ],
- [
- -7,
- 58
- ],
- [
- 3,
- 35
- ]
- ],
- [
- [
- 11959,
- 11719
- ],
- [
- 11,
- 0
- ],
- [
- 4,
- 53
- ],
- [
- -5,
- 23
- ],
- [
- 7,
- 17
- ],
- [
- 26,
- 14
- ],
- [
- -18,
- 96
- ],
- [
- -16,
- 50
- ],
- [
- 6,
- 40
- ],
- [
- 14,
- 10
- ]
- ],
- [
- [
- 11988,
- 12022
- ],
- [
- 9,
- 11
- ],
- [
- 19,
- -18
- ],
- [
- 54,
- -1
- ],
- [
- 13,
- 35
- ],
- [
- 12,
- -3
- ],
- [
- 20,
- 14
- ],
- [
- 11,
- -52
- ],
- [
- 16,
- 16
- ],
- [
- 29,
- 17
- ]
- ],
- [
- [
- 13664,
- 11069
- ],
- [
- -5,
- -65
- ],
- [
- -56,
- 29
- ],
- [
- -56,
- 31
- ],
- [
- -88,
- 5
- ]
- ],
- [
- [
- 13459,
- 11069
- ],
- [
- -9,
- 7
- ],
- [
- -41,
- -16
- ],
- [
- -42,
- 16
- ],
- [
- -33,
- -8
- ]
- ],
- [
- [
- 13334,
- 11068
- ],
- [
- -114,
- 3
- ]
- ],
- [
- [
- 13220,
- 11071
- ],
- [
- 10,
- 95
- ],
- [
- -27,
- 79
- ],
- [
- -32,
- 21
- ],
- [
- -14,
- 53
- ],
- [
- -18,
- 18
- ],
- [
- 1,
- 33
- ]
- ],
- [
- [
- 13140,
- 11370
- ],
- [
- 18,
- 85
- ],
- [
- 33,
- 115
- ],
- [
- 20,
- 1
- ],
- [
- 42,
- 71
- ],
- [
- 26,
- 2
- ],
- [
- 39,
- -50
- ],
- [
- 48,
- 41
- ],
- [
- 7,
- 50
- ],
- [
- 15,
- 48
- ],
- [
- 11,
- 61
- ],
- [
- 38,
- 49
- ],
- [
- 14,
- 84
- ],
- [
- 14,
- 27
- ],
- [
- 10,
- 62
- ],
- [
- 19,
- 77
- ],
- [
- 58,
- 93
- ],
- [
- 4,
- 39
- ],
- [
- 8,
- 22
- ],
- [
- -28,
- 48
- ]
- ],
- [
- [
- 13536,
- 12295
- ],
- [
- 2,
- 38
- ],
- [
- 20,
- 7
- ]
- ],
- [
- [
- 13558,
- 12340
- ],
- [
- 28,
- -77
- ],
- [
- 4,
- -79
- ],
- [
- -2,
- -80
- ],
- [
- 38,
- -109
- ],
- [
- -39,
- 1
- ],
- [
- -20,
- -9
- ],
- [
- -32,
- 12
- ],
- [
- -15,
- -56
- ],
- [
- 41,
- -70
- ],
- [
- 31,
- -21
- ],
- [
- 10,
- -49
- ],
- [
- 22,
- -83
- ],
- [
- -11,
- -32
- ]
- ],
- [
- [
- 13406,
- 10065
- ],
- [
- -9,
- 38
- ]
- ],
- [
- [
- 13453,
- 10224
- ],
- [
- 19,
- -13
- ],
- [
- 24,
- 46
- ],
- [
- 38,
- -1
- ],
- [
- 4,
- -34
- ],
- [
- 26,
- -21
- ],
- [
- 41,
- 75
- ],
- [
- 41,
- 59
- ],
- [
- 17,
- 38
- ],
- [
- -2,
- 99
- ],
- [
- 30,
- 116
- ],
- [
- 32,
- 62
- ],
- [
- 46,
- 58
- ],
- [
- 8,
- 38
- ],
- [
- 2,
- 44
- ],
- [
- 11,
- 42
- ],
- [
- -3,
- 68
- ],
- [
- 8,
- 106
- ],
- [
- 14,
- 75
- ],
- [
- 21,
- 64
- ],
- [
- 4,
- 73
- ]
- ],
- [
- [
- 14456,
- 11425
- ],
- [
- 42,
- -99
- ],
- [
- 31,
- -14
- ],
- [
- 19,
- 20
- ],
- [
- 32,
- -8
- ],
- [
- 39,
- 25
- ],
- [
- 17,
- -51
- ],
- [
- 61,
- -80
- ]
- ],
- [
- [
- 14697,
- 11218
- ],
- [
- -4,
- -140
- ],
- [
- 28,
- -16
- ],
- [
- -23,
- -43
- ],
- [
- -27,
- -32
- ],
- [
- -26,
- -62
- ],
- [
- -15,
- -56
- ],
- [
- -4,
- -96
- ],
- [
- -16,
- -46
- ],
- [
- -1,
- -91
- ]
- ],
- [
- [
- 14609,
- 10636
- ],
- [
- -20,
- -33
- ],
- [
- -2,
- -72
- ],
- [
- -10,
- -9
- ],
- [
- -6,
- -65
- ]
- ],
- [
- [
- 14593,
- 10257
- ],
- [
- 12,
- -110
- ],
- [
- -7,
- -62
- ],
- [
- 14,
- -70
- ],
- [
- 41,
- -67
- ],
- [
- 37,
- -151
- ]
- ],
- [
- [
- 14690,
- 9797
- ],
- [
- -27,
- 12
- ],
- [
- -94,
- -20
- ],
- [
- -18,
- -15
- ],
- [
- -20,
- -76
- ],
- [
- 15,
- -53
- ],
- [
- -12,
- -142
- ],
- [
- -9,
- -121
- ],
- [
- 19,
- -21
- ],
- [
- 49,
- -47
- ],
- [
- 19,
- 22
- ],
- [
- 6,
- -129
- ],
- [
- -54,
- 1
- ],
- [
- -28,
- 66
- ],
- [
- -26,
- 51
- ],
- [
- -53,
- 17
- ],
- [
- -16,
- 63
- ],
- [
- -43,
- -38
- ],
- [
- -55,
- 16
- ],
- [
- -24,
- 55
- ],
- [
- -44,
- 11
- ],
- [
- -33,
- -3
- ],
- [
- -4,
- 37
- ],
- [
- -24,
- 3
- ]
- ],
- [
- [
- 13378,
- 10193
- ],
- [
- -57,
- 127
- ]
- ],
- [
- [
- 13321,
- 10320
- ],
- [
- 53,
- 66
- ],
- [
- -26,
- 79
- ],
- [
- 24,
- 31
- ],
- [
- 47,
- 14
- ],
- [
- 5,
- 53
- ],
- [
- 37,
- -57
- ],
- [
- 62,
- -5
- ],
- [
- 21,
- 56
- ],
- [
- 9,
- 80
- ],
- [
- -8,
- 94
- ],
- [
- -33,
- 71
- ],
- [
- 31,
- 139
- ],
- [
- -18,
- 24
- ],
- [
- -52,
- -10
- ],
- [
- -19,
- 62
- ],
- [
- 5,
- 52
- ]
- ],
- [
- [
- 7675,
- 10282
- ],
- [
- -35,
- 63
- ],
- [
- -20,
- 3
- ],
- [
- 45,
- 122
- ],
- [
- -54,
- 56
- ],
- [
- -42,
- -10
- ],
- [
- -25,
- 21
- ],
- [
- -38,
- -32
- ],
- [
- -52,
- 15
- ],
- [
- -41,
- 126
- ],
- [
- -32,
- 31
- ],
- [
- -23,
- 57
- ],
- [
- -46,
- 56
- ],
- [
- -19,
- -11
- ]
- ],
- [
- [
- 7293,
- 10779
- ],
- [
- -29,
- 28
- ],
- [
- -35,
- 40
- ],
- [
- -20,
- -19
- ],
- [
- -59,
- 17
- ],
- [
- -17,
- 51
- ],
- [
- -13,
- -2
- ],
- [
- -69,
- 69
- ]
- ],
- [
- [
- 7051,
- 10963
- ],
- [
- -10,
- 37
- ],
- [
- 26,
- 9
- ],
- [
- -3,
- 60
- ],
- [
- 16,
- 44
- ],
- [
- 35,
- 8
- ],
- [
- 29,
- 75
- ],
- [
- 27,
- 63
- ],
- [
- -26,
- 29
- ],
- [
- 14,
- 69
- ],
- [
- -16,
- 110
- ],
- [
- 15,
- 31
- ],
- [
- -11,
- 102
- ],
- [
- -28,
- 64
- ]
- ],
- [
- [
- 7119,
- 11664
- ],
- [
- 8,
- 58
- ],
- [
- 23,
- -8
- ],
- [
- 13,
- 35
- ],
- [
- -16,
- 71
- ],
- [
- 8,
- 17
- ]
- ],
- [
- [
- 7155,
- 11837
- ],
- [
- 36,
- -3
- ],
- [
- 53,
- 83
- ],
- [
- 28,
- 13
- ],
- [
- 1,
- 40
- ],
- [
- 13,
- 101
- ],
- [
- 40,
- 56
- ],
- [
- 44,
- 2
- ],
- [
- 5,
- 25
- ],
- [
- 55,
- -10
- ],
- [
- 55,
- 61
- ],
- [
- 27,
- 26
- ],
- [
- 34,
- 58
- ],
- [
- 24,
- -7
- ],
- [
- 19,
- -32
- ],
- [
- -14,
- -40
- ]
- ],
- [
- [
- 7575,
- 12210
- ],
- [
- -45,
- -20
- ],
- [
- -17,
- -60
- ],
- [
- -27,
- -35
- ],
- [
- -21,
- -44
- ],
- [
- -8,
- -86
- ],
- [
- -19,
- -70
- ],
- [
- 36,
- -8
- ],
- [
- 8,
- -55
- ],
- [
- 16,
- -26
- ],
- [
- 5,
- -49
- ],
- [
- -8,
- -44
- ],
- [
- 3,
- -25
- ],
- [
- 17,
- -10
- ],
- [
- 16,
- -42
- ],
- [
- 90,
- 12
- ],
- [
- 40,
- -16
- ],
- [
- 49,
- -103
- ],
- [
- 29,
- 13
- ],
- [
- 50,
- -7
- ],
- [
- 40,
- 14
- ],
- [
- 24,
- -21
- ],
- [
- -12,
- -64
- ],
- [
- -16,
- -40
- ],
- [
- -5,
- -86
- ],
- [
- 14,
- -80
- ],
- [
- 20,
- -36
- ],
- [
- 2,
- -27
- ],
- [
- -35,
- -59
- ],
- [
- 25,
- -27
- ],
- [
- 18,
- -42
- ],
- [
- 22,
- -119
- ]
- ],
- [
- [
- 6764,
- 11784
- ],
- [
- -38,
- 27
- ],
- [
- -14,
- 25
- ],
- [
- 8,
- 21
- ],
- [
- -2,
- 26
- ],
- [
- -20,
- 29
- ],
- [
- -27,
- 23
- ],
- [
- -24,
- 16
- ],
- [
- -5,
- 35
- ],
- [
- -18,
- 21
- ],
- [
- 4,
- -35
- ],
- [
- -13,
- -28
- ],
- [
- -16,
- 33
- ],
- [
- -23,
- 12
- ],
- [
- -9,
- 24
- ],
- [
- 0,
- 37
- ],
- [
- 9,
- 37
- ],
- [
- -19,
- 17
- ],
- [
- 16,
- 23
- ]
- ],
- [
- [
- 6573,
- 12127
- ],
- [
- 10,
- 16
- ],
- [
- 46,
- -32
- ],
- [
- 16,
- 16
- ],
- [
- 22,
- -10
- ],
- [
- 12,
- -25
- ],
- [
- 20,
- -8
- ],
- [
- 17,
- 26
- ]
- ],
- [
- [
- 6716,
- 12110
- ],
- [
- 18,
- -66
- ],
- [
- 27,
- -48
- ],
- [
- 32,
- -51
- ]
- ],
- [
- [
- 6793,
- 11945
- ],
- [
- -27,
- -11
- ],
- [
- 1,
- -48
- ],
- [
- 14,
- -18
- ],
- [
- -10,
- -14
- ],
- [
- 3,
- -22
- ],
- [
- -6,
- -24
- ],
- [
- -4,
- -24
- ]
- ],
- [
- [
- 6813,
- 13579
- ],
- [
- 60,
- -8
- ],
- [
- 55,
- -2
- ],
- [
- 65,
- -41
- ],
- [
- 28,
- -44
- ],
- [
- 65,
- 14
- ],
- [
- 25,
- -28
- ],
- [
- 59,
- -75
- ],
- [
- 43,
- -54
- ],
- [
- 23,
- 2
- ],
- [
- 42,
- -24
- ],
- [
- -5,
- -34
- ],
- [
- 51,
- -5
- ],
- [
- 53,
- -49
- ],
- [
- -9,
- -28
- ],
- [
- -46,
- -16
- ],
- [
- -47,
- -6
- ],
- [
- -48,
- 10
- ],
- [
- -100,
- -12
- ],
- [
- 47,
- 67
- ],
- [
- -28,
- 31
- ],
- [
- -45,
- 8
- ],
- [
- -24,
- 35
- ],
- [
- -17,
- 68
- ],
- [
- -39,
- -4
- ],
- [
- -65,
- 32
- ],
- [
- -21,
- 25
- ],
- [
- -91,
- 19
- ],
- [
- -24,
- 23
- ],
- [
- 26,
- 30
- ],
- [
- -69,
- 6
- ],
- [
- -50,
- -62
- ],
- [
- -29,
- -2
- ],
- [
- -10,
- -29
- ],
- [
- -34,
- -13
- ],
- [
- -30,
- 11
- ],
- [
- 37,
- 37
- ],
- [
- 15,
- 43
- ],
- [
- 31,
- 27
- ],
- [
- 36,
- 23
- ],
- [
- 53,
- 12
- ],
- [
- 17,
- 13
- ]
- ],
- [
- [
- 14829,
- 15013
- ],
- [
- 5,
- 1
- ],
- [
- 10,
- 28
- ],
- [
- 50,
- -1
- ],
- [
- 64,
- 36
- ],
- [
- -47,
- -51
- ],
- [
- 5,
- -23
- ]
- ],
- [
- [
- 14916,
- 15003
- ],
- [
- -8,
- 4
- ],
- [
- -13,
- -9
- ],
- [
- -10,
- 3
- ],
- [
- -4,
- -5
- ],
- [
- -1,
- 12
- ],
- [
- -5,
- 8
- ],
- [
- -14,
- 1
- ],
- [
- -19,
- -10
- ],
- [
- -13,
- 6
- ]
- ],
- [
- [
- 14916,
- 15003
- ],
- [
- 2,
- -10
- ],
- [
- -72,
- -48
- ],
- [
- -34,
- 15
- ],
- [
- -16,
- 48
- ],
- [
- 33,
- 5
- ]
- ],
- [
- [
- 13495,
- 16661
- ],
- [
- -39,
- 52
- ],
- [
- -36,
- 28
- ],
- [
- -7,
- 51
- ],
- [
- -12,
- 36
- ],
- [
- 50,
- 26
- ],
- [
- 26,
- 30
- ],
- [
- 50,
- 23
- ],
- [
- 18,
- 23
- ],
- [
- 18,
- -14
- ],
- [
- 31,
- 12
- ]
- ],
- [
- [
- 13594,
- 16928
- ],
- [
- 33,
- -38
- ],
- [
- 52,
- -11
- ],
- [
- -4,
- -33
- ],
- [
- 38,
- -24
- ],
- [
- 10,
- 30
- ],
- [
- 48,
- -13
- ],
- [
- 7,
- -37
- ],
- [
- 52,
- -8
- ],
- [
- 32,
- -59
- ]
- ],
- [
- [
- 13862,
- 16735
- ],
- [
- -21,
- 0
- ],
- [
- -11,
- -22
- ],
- [
- -16,
- -5
- ],
- [
- -4,
- -27
- ],
- [
- -14,
- -6
- ],
- [
- -2,
- -11
- ],
- [
- -23,
- -12
- ],
- [
- -31,
- 2
- ],
- [
- -10,
- -27
- ]
- ],
- [
- [
- 13068,
- 16510
- ],
- [
- 9,
- 86
- ],
- [
- 35,
- 82
- ],
- [
- -100,
- 22
- ],
- [
- -33,
- 31
- ]
- ],
- [
- [
- 12979,
- 16731
- ],
- [
- 4,
- 53
- ],
- [
- -14,
- 27
- ]
- ],
- [
- [
- 12977,
- 16892
- ],
- [
- -12,
- 126
- ],
- [
- 42,
- 0
- ],
- [
- 18,
- 45
- ],
- [
- 17,
- 110
- ],
- [
- -13,
- 40
- ]
- ],
- [
- [
- 13029,
- 17213
- ],
- [
- 13,
- 26
- ],
- [
- 59,
- 6
- ],
- [
- 13,
- -26
- ],
- [
- 47,
- 59
- ],
- [
- -16,
- 45
- ],
- [
- -3,
- 68
- ]
- ],
- [
- [
- 13142,
- 17391
- ],
- [
- 53,
- -16
- ],
- [
- 44,
- 18
- ]
- ],
- [
- [
- 13239,
- 17393
- ],
- [
- 1,
- -46
- ],
- [
- 71,
- -28
- ],
- [
- -1,
- -42
- ],
- [
- 71,
- 22
- ],
- [
- 39,
- 33
- ],
- [
- 79,
- -47
- ],
- [
- 33,
- -39
- ]
- ],
- [
- [
- 13532,
- 17246
- ],
- [
- 16,
- -61
- ],
- [
- -19,
- -32
- ],
- [
- 25,
- -42
- ],
- [
- 17,
- -65
- ],
- [
- -5,
- -41
- ],
- [
- 28,
- -77
- ]
- ],
- [
- [
- 15551,
- 12321
- ],
- [
- 16,
- -37
- ],
- [
- -2,
- -50
- ],
- [
- -40,
- -29
- ],
- [
- 30,
- -33
- ]
- ],
- [
- [
- 15555,
- 12172
- ],
- [
- -26,
- -64
- ]
- ],
- [
- [
- 15529,
- 12108
- ],
- [
- -15,
- 21
- ],
- [
- -17,
- -8
- ],
- [
- -39,
- 2
- ],
- [
- -1,
- 36
- ],
- [
- -5,
- 34
- ],
- [
- 23,
- 56
- ],
- [
- 25,
- 53
- ]
- ],
- [
- [
- 15500,
- 12302
- ],
- [
- 30,
- -11
- ],
- [
- 21,
- 30
- ]
- ],
- [
- [
- 13142,
- 17391
- ],
- [
- -28,
- 67
- ],
- [
- -3,
- 122
- ],
- [
- 12,
- 33
- ],
- [
- 20,
- 36
- ],
- [
- 61,
- 7
- ],
- [
- 25,
- 33
- ],
- [
- 56,
- 34
- ],
- [
- -2,
- -62
- ],
- [
- -21,
- -39
- ],
- [
- 8,
- -33
- ],
- [
- 38,
- -19
- ],
- [
- -17,
- -45
- ],
- [
- -21,
- 13
- ],
- [
- -50,
- -86
- ],
- [
- 19,
- -59
- ]
- ],
- [
- [
- 13432,
- 17469
- ],
- [
- -42,
- -98
- ],
- [
- -73,
- 68
- ],
- [
- -9,
- 50
- ],
- [
- 102,
- 40
- ],
- [
- 22,
- -60
- ]
- ],
- [
- [
- 7549,
- 13162
- ],
- [
- 8,
- 21
- ],
- [
- 55,
- -1
- ],
- [
- 41,
- -31
- ],
- [
- 18,
- 3
- ],
- [
- 13,
- -42
- ],
- [
- 38,
- 2
- ],
- [
- -2,
- -36
- ],
- [
- 31,
- -4
- ],
- [
- 34,
- -44
- ],
- [
- -26,
- -49
- ],
- [
- -33,
- 26
- ],
- [
- -32,
- -5
- ],
- [
- -23,
- 6
- ],
- [
- -12,
- -22
- ],
- [
- -27,
- -7
- ],
- [
- -11,
- 29
- ],
- [
- -23,
- -17
- ],
- [
- -28,
- -83
- ],
- [
- -18,
- 20
- ],
- [
- -3,
- 34
- ]
- ],
- [
- [
- 7549,
- 12962
- ],
- [
- 1,
- 33
- ],
- [
- -18,
- 36
- ],
- [
- 17,
- 20
- ],
- [
- 6,
- 46
- ],
- [
- -6,
- 65
- ]
- ],
- [
- [
- 12845,
- 13095
- ],
- [
- -77,
- -12
- ],
- [
- -1,
- 77
- ],
- [
- -32,
- 19
- ],
- [
- -44,
- 35
- ],
- [
- -16,
- 56
- ],
- [
- -236,
- 262
- ],
- [
- -235,
- 261
- ]
- ],
- [
- [
- 12204,
- 13793
- ],
- [
- -262,
- 291
- ]
- ],
- [
- [
- 11942,
- 14084
- ],
- [
- 1,
- 23
- ],
- [
- 0,
- 8
- ]
- ],
- [
- [
- 11943,
- 14115
- ],
- [
- 0,
- 142
- ],
- [
- 112,
- 89
- ],
- [
- 70,
- 18
- ],
- [
- 57,
- 32
- ],
- [
- 27,
- 60
- ],
- [
- 81,
- 48
- ],
- [
- 3,
- 89
- ],
- [
- 41,
- 10
- ],
- [
- 31,
- 45
- ],
- [
- 91,
- 20
- ],
- [
- 13,
- 46
- ],
- [
- -18,
- 26
- ],
- [
- -24,
- 127
- ],
- [
- -4,
- 72
- ],
- [
- -27,
- 77
- ]
- ],
- [
- [
- 12396,
- 15016
- ],
- [
- 67,
- 66
- ],
- [
- 76,
- 21
- ],
- [
- 44,
- 49
- ],
- [
- 67,
- 37
- ],
- [
- 118,
- 21
- ],
- [
- 115,
- 10
- ],
- [
- 35,
- -18
- ],
- [
- 66,
- 47
- ],
- [
- 74,
- 1
- ],
- [
- 29,
- -28
- ],
- [
- 48,
- 8
- ]
- ],
- [
- [
- 13135,
- 15230
- ],
- [
- -15,
- -62
- ],
- [
- 11,
- -114
- ],
- [
- -16,
- -99
- ],
- [
- -43,
- -67
- ],
- [
- 6,
- -91
- ],
- [
- 57,
- -71
- ],
- [
- 1,
- -29
- ],
- [
- 43,
- -48
- ],
- [
- 29,
- -216
- ]
- ],
- [
- [
- 13208,
- 14433
- ],
- [
- 23,
- -106
- ],
- [
- 4,
- -56
- ],
- [
- -12,
- -97
- ],
- [
- 5,
- -55
- ],
- [
- -9,
- -66
- ],
- [
- 6,
- -75
- ],
- [
- -28,
- -50
- ],
- [
- 41,
- -88
- ],
- [
- 3,
- -51
- ],
- [
- 25,
- -67
- ],
- [
- 32,
- 22
- ],
- [
- 55,
- -56
- ],
- [
- 31,
- -75
- ]
- ],
- [
- [
- 13384,
- 13613
- ],
- [
- -239,
- -229
- ],
- [
- -202,
- -235
- ],
- [
- -98,
- -54
- ]
- ],
- [
- [
- 7293,
- 10779
- ],
- [
- 10,
- -91
- ],
- [
- -22,
- -78
- ],
- [
- -76,
- -126
- ],
- [
- -83,
- -47
- ],
- [
- -43,
- -104
- ],
- [
- -13,
- -81
- ],
- [
- -40,
- -50
- ],
- [
- -29,
- 61
- ],
- [
- -28,
- 13
- ],
- [
- -29,
- -10
- ],
- [
- -2,
- 44
- ],
- [
- 20,
- 29
- ],
- [
- -8,
- 50
- ]
- ],
- [
- [
- 6950,
- 10389
- ],
- [
- 37,
- 89
- ],
- [
- -15,
- 53
- ],
- [
- -27,
- -56
- ],
- [
- -42,
- 53
- ],
- [
- 15,
- 33
- ],
- [
- -12,
- 109
- ],
- [
- 24,
- 18
- ],
- [
- 13,
- 75
- ],
- [
- 26,
- 77
- ],
- [
- -4,
- 49
- ],
- [
- 38,
- 26
- ],
- [
- 48,
- 48
- ]
- ],
- [
- [
- 15117,
- 13437
- ],
- [
- -276,
- 0
- ],
- [
- -271,
- 0
- ],
- [
- -280,
- 0
- ]
- ],
- [
- [
- 14290,
- 13437
- ],
- [
- 0,
- 441
- ],
- [
- 0,
- 427
- ],
- [
- -21,
- 97
- ],
- [
- 18,
- 74
- ],
- [
- -11,
- 51
- ],
- [
- 26,
- 58
- ]
- ],
- [
- [
- 14302,
- 14585
- ],
- [
- 92,
- 1
- ],
- [
- 68,
- -31
- ],
- [
- 69,
- -36
- ],
- [
- 32,
- -18
- ],
- [
- 54,
- 38
- ],
- [
- 28,
- 34
- ],
- [
- 62,
- 10
- ],
- [
- 49,
- -15
- ],
- [
- 19,
- -60
- ],
- [
- 17,
- 39
- ],
- [
- 55,
- -28
- ],
- [
- 55,
- -7
- ],
- [
- 34,
- 31
- ]
- ],
- [
- [
- 14936,
- 14543
- ],
- [
- 39,
- -175
- ],
- [
- 7,
- -32
- ]
- ],
- [
- [
- 14982,
- 14336
- ],
- [
- -20,
- -48
- ],
- [
- -15,
- -90
- ],
- [
- -19,
- -63
- ],
- [
- -16,
- -21
- ],
- [
- -23,
- 39
- ],
- [
- -32,
- 53
- ],
- [
- -49,
- 172
- ],
- [
- -7,
- -10
- ],
- [
- 28,
- -127
- ],
- [
- 43,
- -121
- ],
- [
- 53,
- -187
- ],
- [
- 26,
- -65
- ],
- [
- 22,
- -68
- ],
- [
- 63,
- -132
- ],
- [
- -14,
- -21
- ],
- [
- 2,
- -78
- ],
- [
- 81,
- -108
- ],
- [
- 12,
- -24
- ]
- ],
- [
- [
- 15500,
- 12302
- ],
- [
- -24,
- 39
- ],
- [
- -29,
- 70
- ],
- [
- -31,
- 39
- ],
- [
- -18,
- 41
- ],
- [
- -60,
- 48
- ],
- [
- -48,
- 2
- ],
- [
- -17,
- 25
- ],
- [
- -41,
- -29
- ],
- [
- -42,
- 55
- ],
- [
- -22,
- -90
- ],
- [
- -81,
- 25
- ]
- ],
- [
- [
- 15087,
- 12527
- ],
- [
- -7,
- 48
- ],
- [
- 30,
- 177
- ],
- [
- 6,
- 79
- ],
- [
- 22,
- 37
- ],
- [
- 52,
- 20
- ],
- [
- 35,
- 68
- ]
- ],
- [
- [
- 15225,
- 12956
- ],
- [
- 40,
- -138
- ],
- [
- 20,
- -111
- ],
- [
- 38,
- -58
- ],
- [
- 95,
- -113
- ],
- [
- 39,
- -69
- ],
- [
- 38,
- -69
- ],
- [
- 21,
- -41
- ],
- [
- 35,
- -36
- ]
- ],
- [
- [
- 11918,
- 15822
- ],
- [
- 3,
- 85
- ],
- [
- -28,
- 52
- ],
- [
- 98,
- 87
- ],
- [
- 86,
- -22
- ],
- [
- 93,
- 1
- ],
- [
- 74,
- -21
- ],
- [
- 58,
- 7
- ],
- [
- 113,
- -4
- ]
- ],
- [
- [
- 12415,
- 16007
- ],
- [
- 28,
- -47
- ],
- [
- 128,
- -55
- ],
- [
- 25,
- 26
- ],
- [
- 79,
- -54
- ],
- [
- 81,
- 16
- ]
- ],
- [
- [
- 12756,
- 15893
- ],
- [
- 3,
- -70
- ],
- [
- -66,
- -80
- ],
- [
- -89,
- -25
- ],
- [
- -6,
- -41
- ],
- [
- -43,
- -66
- ],
- [
- -27,
- -98
- ],
- [
- 27,
- -68
- ],
- [
- -40,
- -54
- ],
- [
- -15,
- -78
- ],
- [
- -53,
- -24
- ],
- [
- -49,
- -92
- ],
- [
- -89,
- -2
- ],
- [
- -66,
- 2
- ],
- [
- -44,
- -42
- ],
- [
- -26,
- -45
- ],
- [
- -34,
- 10
- ],
- [
- -26,
- 40
- ],
- [
- -20,
- 69
- ],
- [
- -65,
- 19
- ]
- ],
- [
- [
- 12028,
- 15248
- ],
- [
- -6,
- 39
- ],
- [
- 26,
- 45
- ],
- [
- 10,
- 33
- ],
- [
- -25,
- 36
- ],
- [
- 20,
- 79
- ],
- [
- -28,
- 72
- ],
- [
- 30,
- 9
- ],
- [
- 3,
- 57
- ],
- [
- 11,
- 18
- ],
- [
- 1,
- 93
- ],
- [
- 32,
- 33
- ],
- [
- -19,
- 60
- ],
- [
- -41,
- 4
- ],
- [
- -12,
- -15
- ],
- [
- -41,
- 0
- ],
- [
- -18,
- 59
- ],
- [
- -28,
- -18
- ],
- [
- -25,
- -30
- ]
- ],
- [
- [
- 14242,
- 17731
- ],
- [
- 8,
- 70
- ],
- [
- -25,
- -15
- ],
- [
- -44,
- 43
- ],
- [
- -7,
- 69
- ],
- [
- 89,
- 33
- ],
- [
- 87,
- 18
- ],
- [
- 76,
- -20
- ],
- [
- 72,
- 3
- ]
- ],
- [
- [
- 14498,
- 17932
- ],
- [
- 11,
- -21
- ],
- [
- -50,
- -69
- ],
- [
- 21,
- -112
- ],
- [
- -30,
- -38
- ]
- ],
- [
- [
- 14450,
- 17692
- ],
- [
- -58,
- 1
- ],
- [
- -60,
- 44
- ],
- [
- -30,
- 15
- ],
- [
- -60,
- -21
- ]
- ],
- [
- [
- 15529,
- 12108
- ],
- [
- -15,
- -42
- ],
- [
- 26,
- -66
- ],
- [
- 26,
- -58
- ],
- [
- 26,
- -43
- ],
- [
- 228,
- -142
- ],
- [
- 59,
- 0
- ]
- ],
- [
- [
- 15879,
- 11757
- ],
- [
- -197,
- -360
- ],
- [
- -91,
- -5
- ],
- [
- -62,
- -85
- ],
- [
- -45,
- -2
- ],
- [
- -19,
- -38
- ]
- ],
- [
- [
- 15465,
- 11267
- ],
- [
- -47,
- 0
- ],
- [
- -29,
- 41
- ],
- [
- -63,
- -50
- ],
- [
- -21,
- -50
- ],
- [
- -46,
- 9
- ],
- [
- -16,
- 14
- ],
- [
- -16,
- -3
- ],
- [
- -22,
- 1
- ],
- [
- -88,
- 102
- ],
- [
- -49,
- 0
- ],
- [
- -24,
- 39
- ],
- [
- 0,
- 68
- ],
- [
- -36,
- 20
- ]
- ],
- [
- [
- 15008,
- 11458
- ],
- [
- -41,
- 130
- ],
- [
- -32,
- 28
- ],
- [
- -12,
- 48
- ],
- [
- -36,
- 59
- ],
- [
- -42,
- 8
- ],
- [
- 23,
- 68
- ],
- [
- 37,
- 3
- ],
- [
- 11,
- 37
- ]
- ],
- [
- [
- 14916,
- 11839
- ],
- [
- -1,
- 108
- ],
- [
- 21,
- 125
- ],
- [
- 33,
- 34
- ],
- [
- 7,
- 49
- ],
- [
- 29,
- 92
- ],
- [
- 42,
- 59
- ],
- [
- 29,
- 118
- ],
- [
- 11,
- 103
- ]
- ],
- [
- [
- 14214,
- 18716
- ],
- [
- -24,
- 47
- ],
- [
- -2,
- 184
- ],
- [
- -108,
- 82
- ],
- [
- -93,
- 59
- ]
- ],
- [
- [
- 13987,
- 19088
- ],
- [
- 41,
- 31
- ],
- [
- 78,
- -63
- ],
- [
- 91,
- 6
- ],
- [
- 75,
- -29
- ],
- [
- 66,
- 53
- ],
- [
- 34,
- 88
- ],
- [
- 109,
- 41
- ],
- [
- 89,
- -48
- ],
- [
- -29,
- -84
- ]
- ],
- [
- [
- 14541,
- 19083
- ],
- [
- -11,
- -84
- ],
- [
- 107,
- -80
- ],
- [
- -64,
- -91
- ],
- [
- 81,
- -136
- ],
- [
- -47,
- -103
- ],
- [
- 63,
- -89
- ],
- [
- -29,
- -78
- ],
- [
- 103,
- -83
- ],
- [
- -26,
- -61
- ],
- [
- -65,
- -69
- ],
- [
- -149,
- -153
- ]
- ],
- [
- [
- 14504,
- 18056
- ],
- [
- -126,
- -10
- ],
- [
- -123,
- -44
- ],
- [
- -113,
- -25
- ],
- [
- -41,
- 65
- ],
- [
- -67,
- 40
- ],
- [
- 15,
- 118
- ],
- [
- -33,
- 108
- ],
- [
- 33,
- 70
- ],
- [
- 63,
- 75
- ],
- [
- 159,
- 130
- ],
- [
- 47,
- 26
- ],
- [
- -7,
- 50
- ],
- [
- -97,
- 57
- ]
- ],
- [
- [
- 24982,
- 8717
- ],
- [
- 24,
- -35
- ],
- [
- -12,
- -62
- ],
- [
- -43,
- -17
- ],
- [
- -39,
- 15
- ],
- [
- -6,
- 53
- ],
- [
- 27,
- 41
- ],
- [
- 31,
- -15
- ],
- [
- 18,
- 20
- ]
- ],
- [
- [
- 25051,
- 8782
- ],
- [
- -45,
- -26
- ],
- [
- -9,
- 45
- ],
- [
- 35,
- 25
- ],
- [
- 22,
- 6
- ],
- [
- 41,
- 38
- ],
- [
- 0,
- -59
- ],
- [
- -44,
- -29
- ]
- ],
- [
- [
- 6,
- 8817
- ],
- [
- -6,
- -6
- ],
- [
- 0,
- 59
- ],
- [
- 14,
- 5
- ],
- [
- -8,
- -58
- ]
- ],
- [
- [
- 8281,
- 4577
- ],
- [
- 84,
- 72
- ],
- [
- 59,
- -30
- ],
- [
- 42,
- 48
- ],
- [
- 56,
- -54
- ],
- [
- -21,
- -42
- ],
- [
- -94,
- -36
- ],
- [
- -32,
- 42
- ],
- [
- -59,
- -54
- ],
- [
- -35,
- 54
- ]
- ],
- [
- [
- 12943,
- 16739
- ],
- [
- 16,
- -10
- ],
- [
- 20,
- 2
- ]
- ],
- [
- [
- 13025,
- 16315
- ],
- [
- -3,
- -34
- ],
- [
- 20,
- -45
- ],
- [
- -24,
- -37
- ],
- [
- 18,
- -93
- ],
- [
- 38,
- -15
- ],
- [
- -8,
- -52
- ]
- ],
- [
- [
- 13066,
- 16039
- ],
- [
- -63,
- -68
- ],
- [
- -138,
- 33
- ],
- [
- -101,
- -39
- ],
- [
- -8,
- -72
- ]
- ],
- [
- [
- 12415,
- 16007
- ],
- [
- 36,
- 72
- ],
- [
- 13,
- 239
- ],
- [
- -72,
- 125
- ],
- [
- -51,
- 61
- ],
- [
- -107,
- 46
- ],
- [
- -7,
- 88
- ],
- [
- 91,
- 26
- ],
- [
- 117,
- -31
- ],
- [
- -22,
- 136
- ],
- [
- 66,
- -52
- ],
- [
- 162,
- 94
- ],
- [
- 21,
- 98
- ],
- [
- 61,
- 24
- ]
- ],
- [
- [
- 8747,
- 11075
- ],
- [
- 17,
- 51
- ],
- [
- 6,
- 54
- ],
- [
- 12,
- 52
- ],
- [
- -27,
- 71
- ],
- [
- -5,
- 82
- ],
- [
- 36,
- 103
- ]
- ],
- [
- [
- 8786,
- 11488
- ],
- [
- 24,
- -13
- ],
- [
- 51,
- -29
- ],
- [
- 74,
- -101
- ],
- [
- 12,
- -49
- ]
- ],
- [
- [
- 13214,
- 15854
- ],
- [
- -23,
- -92
- ],
- [
- -32,
- 24
- ],
- [
- -16,
- 81
- ],
- [
- 14,
- 44
- ],
- [
- 45,
- 46
- ],
- [
- 12,
- -103
- ]
- ],
- [
- [
- 13321,
- 10320
- ],
- [
- -72,
- 121
- ],
- [
- -46,
- 99
- ],
- [
- -42,
- 124
- ],
- [
- 2,
- 40
- ],
- [
- 15,
- 38
- ],
- [
- 17,
- 87
- ],
- [
- 14,
- 89
- ]
- ],
- [
- [
- 13209,
- 10918
- ],
- [
- 24,
- 7
- ],
- [
- 101,
- -1
- ],
- [
- 0,
- 144
- ]
- ],
- [
- [
- 12115,
- 17260
- ],
- [
- -52,
- 24
- ],
- [
- -43,
- -1
- ],
- [
- 14,
- 64
- ],
- [
- -14,
- 64
- ]
- ],
- [
- [
- 12020,
- 17411
- ],
- [
- 58,
- 5
- ],
- [
- 75,
- -74
- ],
- [
- -38,
- -82
- ]
- ],
- [
- [
- 12338,
- 17832
- ],
- [
- -74,
- -130
- ],
- [
- 71,
- 16
- ],
- [
- 76,
- 0
- ],
- [
- -18,
- -98
- ],
- [
- -63,
- -108
- ],
- [
- 72,
- -7
- ],
- [
- 6,
- -13
- ],
- [
- 62,
- -142
- ],
- [
- 47,
- -19
- ],
- [
- 43,
- -136
- ],
- [
- 20,
- -48
- ],
- [
- 85,
- -23
- ],
- [
- -9,
- -76
- ],
- [
- -35,
- -36
- ],
- [
- 28,
- -62
- ],
- [
- -63,
- -63
- ],
- [
- -93,
- 2
- ],
- [
- -119,
- -33
- ],
- [
- -33,
- 23
- ],
- [
- -46,
- -56
- ],
- [
- -64,
- 14
- ],
- [
- -49,
- -46
- ],
- [
- -37,
- 24
- ],
- [
- 102,
- 126
- ],
- [
- 62,
- 26
- ],
- [
- 0,
- 0
- ],
- [
- -109,
- 20
- ],
- [
- -20,
- 48
- ],
- [
- 73,
- 37
- ],
- [
- -38,
- 64
- ],
- [
- 13,
- 79
- ],
- [
- 104,
- -11
- ],
- [
- 10,
- 70
- ],
- [
- -46,
- 74
- ],
- [
- -2,
- 1
- ],
- [
- -84,
- 21
- ],
- [
- -17,
- 33
- ],
- [
- 26,
- 53
- ],
- [
- -23,
- 34
- ],
- [
- -38,
- -57
- ],
- [
- -4,
- 115
- ],
- [
- -35,
- 62
- ],
- [
- 25,
- 124
- ],
- [
- 54,
- 97
- ],
- [
- 56,
- -10
- ],
- [
- 84,
- 11
- ]
- ],
- [
- [
- 15586,
- 15727
- ],
- [
- -68,
- 59
- ],
- [
- -74,
- -6
- ]
- ],
- [
- [
- 15444,
- 15780
- ],
- [
- 11,
- 51
- ],
- [
- -18,
- 82
- ],
- [
- -40,
- 44
- ],
- [
- -39,
- 14
- ],
- [
- -25,
- 37
- ]
- ],
- [
- [
- 15333,
- 16008
- ],
- [
- 8,
- 14
- ],
- [
- 59,
- -20
- ],
- [
- 103,
- -20
- ],
- [
- 95,
- -57
- ],
- [
- 12,
- -23
- ],
- [
- 42,
- 19
- ],
- [
- 65,
- -25
- ],
- [
- 21,
- -49
- ],
- [
- 44,
- -28
- ]
- ],
- [
- [
- 12549,
- 12119
- ],
- [
- -5,
- -37
- ],
- [
- 29,
- -62
- ],
- [
- 0,
- -87
- ],
- [
- 7,
- -95
- ],
- [
- 17,
- -44
- ],
- [
- -15,
- -108
- ],
- [
- 5,
- -59
- ],
- [
- 19,
- -76
- ],
- [
- 15,
- -43
- ]
- ],
- [
- [
- 12621,
- 11508
- ],
- [
- -109,
- -70
- ],
- [
- -39,
- -41
- ],
- [
- -62,
- -35
- ],
- [
- -63,
- 34
- ]
- ],
- [
- [
- 11959,
- 11719
- ],
- [
- -20,
- 3
- ],
- [
- -14,
- -48
- ],
- [
- -19,
- 1
- ],
- [
- -14,
- 25
- ],
- [
- 5,
- 48
- ],
- [
- -30,
- 74
- ],
- [
- -18,
- -14
- ],
- [
- -15,
- -2
- ]
- ],
- [
- [
- 11834,
- 11806
- ],
- [
- -19,
- -7
- ],
- [
- 1,
- 44
- ],
- [
- -11,
- 31
- ],
- [
- 2,
- 35
- ],
- [
- -15,
- 50
- ],
- [
- -19,
- 43
- ],
- [
- -56,
- 1
- ],
- [
- -16,
- -23
- ],
- [
- -20,
- -3
- ],
- [
- -12,
- -26
- ],
- [
- -8,
- -33
- ],
- [
- -37,
- -53
- ]
- ],
- [
- [
- 11624,
- 11865
- ],
- [
- -30,
- 71
- ],
- [
- -28,
- 47
- ],
- [
- -17,
- 16
- ],
- [
- -18,
- 24
- ],
- [
- -8,
- 53
- ],
- [
- -10,
- 26
- ],
- [
- -20,
- 20
- ]
- ],
- [
- [
- 11493,
- 12122
- ],
- [
- 31,
- 58
- ],
- [
- 21,
- -2
- ],
- [
- 18,
- 20
- ],
- [
- 15,
- 0
- ],
- [
- 11,
- 16
- ],
- [
- -5,
- 40
- ],
- [
- 7,
- 12
- ],
- [
- 1,
- 41
- ]
- ],
- [
- [
- 11592,
- 12307
- ],
- [
- 34,
- -1
- ],
- [
- 50,
- -29
- ],
- [
- 16,
- 2
- ],
- [
- 5,
- 14
- ],
- [
- 38,
- -10
- ],
- [
- 10,
- 7
- ]
- ],
- [
- [
- 11745,
- 12290
- ],
- [
- 4,
- -44
- ],
- [
- 11,
- 0
- ],
- [
- 18,
- 16
- ],
- [
- 12,
- -4
- ],
- [
- 19,
- -30
- ],
- [
- 30,
- -10
- ],
- [
- 19,
- 26
- ],
- [
- 23,
- 16
- ],
- [
- 16,
- 17
- ],
- [
- 14,
- -3
- ],
- [
- 16,
- -27
- ],
- [
- 8,
- -33
- ],
- [
- 29,
- -50
- ],
- [
- -15,
- -31
- ],
- [
- -2,
- -39
- ],
- [
- 14,
- 12
- ],
- [
- 9,
- -14
- ],
- [
- -4,
- -36
- ],
- [
- 22,
- -34
- ]
- ],
- [
- [
- 11374,
- 12375
- ],
- [
- 8,
- 53
- ]
- ],
- [
- [
- 11382,
- 12428
- ],
- [
- 76,
- 4
- ],
- [
- 16,
- 28
- ],
- [
- 22,
- 2
- ],
- [
- 28,
- -30
- ],
- [
- 21,
- 0
- ],
- [
- 23,
- 20
- ],
- [
- 14,
- -35
- ],
- [
- -30,
- -27
- ],
- [
- -30,
- 3
- ],
- [
- -30,
- 25
- ],
- [
- -26,
- -28
- ],
- [
- -12,
- -1
- ],
- [
- -17,
- -17
- ],
- [
- -63,
- 3
- ]
- ],
- [
- [
- 11493,
- 12122
- ],
- [
- -37,
- 50
- ],
- [
- -30,
- 8
- ],
- [
- -16,
- 34
- ],
- [
- 1,
- 18
- ],
- [
- -22,
- 25
- ],
- [
- -4,
- 26
- ]
- ],
- [
- [
- 11385,
- 12283
- ],
- [
- 37,
- 20
- ],
- [
- 23,
- -4
- ],
- [
- 19,
- 13
- ],
- [
- 128,
- -5
- ]
- ],
- [
- [
- 13209,
- 10918
- ],
- [
- -13,
- 18
- ],
- [
- 24,
- 135
- ]
- ],
- [
- [
- 14013,
- 15697
- ],
- [
- 45,
- 11
- ],
- [
- 27,
- 26
- ],
- [
- 38,
- -2
- ],
- [
- 11,
- 20
- ],
- [
- 13,
- 4
- ]
- ],
- [
- [
- 14368,
- 15815
- ],
- [
- 34,
- -32
- ],
- [
- -22,
- -75
- ],
- [
- -16,
- -13
- ]
- ],
- [
- [
- 14364,
- 15695
- ],
- [
- -43,
- 3
- ],
- [
- -36,
- 12
- ],
- [
- -84,
- -32
- ],
- [
- 48,
- -67
- ],
- [
- -35,
- -20
- ],
- [
- -39,
- 0
- ],
- [
- -37,
- 62
- ],
- [
- -13,
- -26
- ],
- [
- 15,
- -72
- ],
- [
- 35,
- -56
- ],
- [
- -26,
- -27
- ],
- [
- 39,
- -55
- ],
- [
- 34,
- -35
- ],
- [
- 1,
- -67
- ],
- [
- -64,
- 31
- ],
- [
- 20,
- -61
- ],
- [
- -44,
- -12
- ],
- [
- 27,
- -106
- ],
- [
- -47,
- -2
- ],
- [
- -57,
- 52
- ],
- [
- -26,
- 96
- ],
- [
- -12,
- 80
- ],
- [
- -27,
- 55
- ],
- [
- -36,
- 69
- ],
- [
- -5,
- 34
- ]
- ],
- [
- [
- 14200,
- 15081
- ],
- [
- 38,
- -41
- ],
- [
- 54,
- 7
- ],
- [
- 52,
- -8
- ],
- [
- -2,
- -21
- ],
- [
- 38,
- 14
- ],
- [
- -9,
- -35
- ],
- [
- -100,
- -10
- ],
- [
- 1,
- 19
- ],
- [
- -85,
- 24
- ],
- [
- 13,
- 51
- ]
- ],
- [
- [
- 9288,
- 20710
- ],
- [
- 234,
- 72
- ],
- [
- 244,
- -6
- ],
- [
- 89,
- 44
- ],
- [
- 247,
- 12
- ],
- [
- 556,
- -15
- ],
- [
- 436,
- -95
- ],
- [
- -128,
- -46
- ],
- [
- -267,
- -6
- ],
- [
- -375,
- -11
- ],
- [
- 35,
- -22
- ],
- [
- 247,
- 13
- ],
- [
- 210,
- -41
- ],
- [
- 135,
- 37
- ],
- [
- 58,
- -43
- ],
- [
- -77,
- -70
- ],
- [
- 178,
- 45
- ],
- [
- 338,
- 46
- ],
- [
- 209,
- -23
- ],
- [
- 39,
- -51
- ],
- [
- -284,
- -86
- ],
- [
- -39,
- -27
- ],
- [
- -223,
- -21
- ],
- [
- 162,
- -6
- ],
- [
- -82,
- -87
- ],
- [
- -56,
- -78
- ],
- [
- 2,
- -134
- ],
- [
- 84,
- -78
- ],
- [
- -109,
- -5
- ],
- [
- -115,
- -38
- ],
- [
- 129,
- -63
- ],
- [
- 16,
- -102
- ],
- [
- -74,
- -11
- ],
- [
- 90,
- -104
- ],
- [
- -155,
- -8
- ],
- [
- 81,
- -49
- ],
- [
- -23,
- -42
- ],
- [
- -98,
- -19
- ],
- [
- -97,
- 0
- ],
- [
- 87,
- -82
- ],
- [
- 1,
- -53
- ],
- [
- -138,
- 50
- ],
- [
- -36,
- -32
- ],
- [
- 94,
- -30
- ],
- [
- 92,
- -74
- ],
- [
- 26,
- -96
- ],
- [
- -124,
- -23
- ],
- [
- -54,
- 46
- ],
- [
- -86,
- 69
- ],
- [
- 24,
- -82
- ],
- [
- -81,
- -63
- ],
- [
- 184,
- -5
- ],
- [
- 96,
- -6
- ],
- [
- -187,
- -105
- ],
- [
- -190,
- -94
- ],
- [
- -204,
- -42
- ],
- [
- -77,
- 0
- ],
- [
- -72,
- -47
- ],
- [
- -97,
- -126
- ],
- [
- -150,
- -84
- ],
- [
- -48,
- -5
- ],
- [
- -93,
- -30
- ],
- [
- -100,
- -28
- ],
- [
- -59,
- -74
- ],
- [
- -1,
- -84
- ],
- [
- -36,
- -79
- ],
- [
- -113,
- -96
- ],
- [
- 28,
- -94
- ],
- [
- -32,
- -99
- ],
- [
- -35,
- -117
- ],
- [
- -99,
- -7
- ],
- [
- -102,
- 98
- ],
- [
- -140,
- 0
- ],
- [
- -67,
- 66
- ],
- [
- -47,
- 117
- ],
- [
- -121,
- 149
- ],
- [
- -35,
- 79
- ],
- [
- -10,
- 107
- ],
- [
- -96,
- 111
- ],
- [
- 25,
- 88
- ],
- [
- -47,
- 43
- ],
- [
- 69,
- 140
- ],
- [
- 105,
- 45
- ],
- [
- 28,
- 50
- ],
- [
- 14,
- 94
- ],
- [
- -79,
- -43
- ],
- [
- -38,
- -18
- ],
- [
- -63,
- -17
- ],
- [
- -85,
- 39
- ],
- [
- -5,
- 82
- ],
- [
- 27,
- 64
- ],
- [
- 65,
- 1
- ],
- [
- 142,
- -32
- ],
- [
- -120,
- 77
- ],
- [
- -62,
- 41
- ],
- [
- -69,
- -17
- ],
- [
- -59,
- 29
- ],
- [
- 78,
- 112
- ],
- [
- -42,
- 45
- ],
- [
- -56,
- 83
- ],
- [
- -83,
- 127
- ],
- [
- -89,
- 47
- ],
- [
- 1,
- 50
- ],
- [
- -187,
- 70
- ],
- [
- -148,
- 9
- ],
- [
- -187,
- -5
- ],
- [
- -170,
- -9
- ],
- [
- -81,
- 38
- ],
- [
- -121,
- 76
- ],
- [
- 183,
- 38
- ],
- [
- 140,
- 6
- ],
- [
- -298,
- 31
- ],
- [
- -157,
- 49
- ],
- [
- 10,
- 47
- ],
- [
- 264,
- 57
- ],
- [
- 255,
- 58
- ],
- [
- 27,
- 44
- ],
- [
- -188,
- 43
- ],
- [
- 60,
- 48
- ],
- [
- 242,
- 83
- ],
- [
- 101,
- 13
- ],
- [
- -29,
- 54
- ],
- [
- 165,
- 32
- ],
- [
- 215,
- 19
- ],
- [
- 214,
- 1
- ],
- [
- 76,
- -38
- ],
- [
- 185,
- 66
- ],
- [
- 166,
- -45
- ],
- [
- 98,
- -9
- ],
- [
- 145,
- -39
- ],
- [
- -166,
- 65
- ],
- [
- 10,
- 51
- ]
- ],
- [
- [
- 6348,
- 12703
- ],
- [
- 23,
- -22
- ],
- [
- 6,
- 18
- ],
- [
- 20,
- -15
- ]
- ],
- [
- [
- 6397,
- 12684
- ],
- [
- -31,
- -46
- ],
- [
- -33,
- -33
- ],
- [
- -5,
- -23
- ],
- [
- 5,
- -24
- ],
- [
- -14,
- -30
- ]
- ],
- [
- [
- 6319,
- 12528
- ],
- [
- -16,
- -8
- ],
- [
- 3,
- -14
- ],
- [
- -13,
- -13
- ],
- [
- -24,
- -30
- ],
- [
- -2,
- -18
- ]
- ],
- [
- [
- 6267,
- 12445
- ],
- [
- -36,
- 21
- ],
- [
- -43,
- 2
- ],
- [
- -32,
- 24
- ],
- [
- -38,
- 49
- ]
- ],
- [
- [
- 6118,
- 12541
- ],
- [
- 2,
- 35
- ],
- [
- 8,
- 28
- ],
- [
- -10,
- 23
- ],
- [
- 34,
- 98
- ],
- [
- 89,
- 0
- ],
- [
- 2,
- 41
- ],
- [
- -11,
- 7
- ],
- [
- -8,
- 26
- ],
- [
- -26,
- 28
- ],
- [
- -26,
- 40
- ],
- [
- 32,
- 0
- ],
- [
- 0,
- 68
- ],
- [
- 65,
- 0
- ],
- [
- 64,
- -1
- ]
- ],
- [
- [
- 8314,
- 11421
- ],
- [
- -47,
- 91
- ],
- [
- 19,
- 33
- ],
- [
- -2,
- 56
- ],
- [
- 43,
- 19
- ],
- [
- 17,
- 22
- ],
- [
- -23,
- 45
- ],
- [
- 6,
- 44
- ],
- [
- 55,
- 70
- ]
- ],
- [
- [
- 8382,
- 11801
- ],
- [
- 46,
- -44
- ],
- [
- 43,
- -78
- ],
- [
- 2,
- -62
- ],
- [
- 26,
- -3
- ],
- [
- 37,
- -58
- ],
- [
- 28,
- -42
- ]
- ],
- [
- [
- 8564,
- 11514
- ],
- [
- -11,
- -108
- ],
- [
- -43,
- -31
- ],
- [
- 4,
- -29
- ],
- [
- -13,
- -62
- ],
- [
- 31,
- -87
- ],
- [
- 23,
- 0
- ],
- [
- 9,
- -68
- ],
- [
- 42,
- -104
- ]
- ],
- [
- [
- 6397,
- 12684
- ],
- [
- 8,
- -5
- ],
- [
- 15,
- 21
- ],
- [
- 20,
- 2
- ],
- [
- 6,
- -10
- ],
- [
- 11,
- 6
- ],
- [
- 33,
- -10
- ],
- [
- 32,
- 3
- ],
- [
- 22,
- 13
- ],
- [
- 8,
- 13
- ],
- [
- 23,
- -6
- ],
- [
- 16,
- -8
- ],
- [
- 19,
- 3
- ],
- [
- 13,
- 10
- ],
- [
- 32,
- -16
- ],
- [
- 11,
- -3
- ],
- [
- 22,
- -23
- ],
- [
- 20,
- -26
- ],
- [
- 25,
- -19
- ],
- [
- 18,
- -33
- ]
- ],
- [
- [
- 6751,
- 12596
- ],
- [
- -23,
- 3
- ],
- [
- -10,
- -17
- ],
- [
- -24,
- -15
- ],
- [
- -18,
- 0
- ],
- [
- -15,
- -16
- ],
- [
- -14,
- 6
- ],
- [
- -12,
- 18
- ],
- [
- -7,
- -3
- ],
- [
- -9,
- -29
- ],
- [
- -7,
- 1
- ],
- [
- -1,
- -25
- ],
- [
- -25,
- -33
- ],
- [
- -12,
- -14
- ],
- [
- -8,
- -15
- ],
- [
- -20,
- 24
- ],
- [
- -15,
- -32
- ],
- [
- -15,
- 1
- ],
- [
- -16,
- -3
- ],
- [
- 1,
- -59
- ],
- [
- -10,
- -1
- ],
- [
- -9,
- -27
- ],
- [
- -21,
- -5
- ]
- ],
- [
- [
- 6461,
- 12355
- ],
- [
- -12,
- 37
- ],
- [
- -21,
- 11
- ]
- ],
- [
- [
- 6428,
- 12403
- ],
- [
- 4,
- 48
- ],
- [
- -9,
- 13
- ],
- [
- -14,
- 9
- ],
- [
- -31,
- -15
- ],
- [
- -3,
- 16
- ],
- [
- -21,
- 20
- ],
- [
- -15,
- 24
- ],
- [
- -20,
- 10
- ]
- ],
- [
- [
- 13841,
- 15914
- ],
- [
- -7,
- -21
- ]
- ],
- [
- [
- 13834,
- 15893
- ],
- [
- -66,
- 45
- ],
- [
- -40,
- 43
- ],
- [
- -64,
- 36
- ],
- [
- -59,
- 88
- ],
- [
- 14,
- 9
- ],
- [
- -31,
- 50
- ],
- [
- -2,
- 41
- ],
- [
- -45,
- 19
- ],
- [
- -21,
- -52
- ],
- [
- -20,
- 40
- ],
- [
- 1,
- 42
- ],
- [
- 3,
- 2
- ]
- ],
- [
- [
- 13504,
- 16256
- ],
- [
- 48,
- -4
- ],
- [
- 13,
- 20
- ],
- [
- 24,
- -20
- ],
- [
- 27,
- -2
- ],
- [
- 0,
- 34
- ],
- [
- 24,
- 12
- ],
- [
- 7,
- 48
- ],
- [
- 55,
- 32
- ]
- ],
- [
- [
- 13702,
- 16376
- ],
- [
- 22,
- -15
- ],
- [
- 52,
- -51
- ],
- [
- 58,
- -23
- ],
- [
- 26,
- 18
- ]
- ],
- [
- [
- 13860,
- 16305
- ],
- [
- 17,
- -47
- ],
- [
- 22,
- -34
- ],
- [
- -27,
- -45
- ]
- ],
- [
- [
- 7549,
- 12962
- ],
- [
- -46,
- 20
- ],
- [
- -33,
- -8
- ],
- [
- -43,
- 9
- ],
- [
- -33,
- -23
- ],
- [
- -37,
- 38
- ],
- [
- 6,
- 38
- ],
- [
- 64,
- -16
- ],
- [
- 53,
- -10
- ],
- [
- 25,
- 27
- ],
- [
- -32,
- 52
- ],
- [
- 1,
- 46
- ],
- [
- -44,
- 18
- ],
- [
- 16,
- 33
- ],
- [
- 42,
- -5
- ],
- [
- 61,
- -19
- ]
- ],
- [
- [
- 13731,
- 16571
- ],
- [
- 36,
- -31
- ],
- [
- 25,
- -13
- ],
- [
- 59,
- 14
- ],
- [
- 5,
- 25
- ],
- [
- 28,
- 3
- ],
- [
- 34,
- 19
- ],
- [
- 8,
- -8
- ],
- [
- 32,
- 15
- ],
- [
- 17,
- 28
- ],
- [
- 23,
- 8
- ],
- [
- 74,
- -37
- ],
- [
- 15,
- 12
- ]
- ],
- [
- [
- 14087,
- 16606
- ],
- [
- 39,
- -32
- ],
- [
- 5,
- -32
- ]
- ],
- [
- [
- 14131,
- 16542
- ],
- [
- -43,
- -26
- ],
- [
- -33,
- -81
- ],
- [
- -42,
- -81
- ],
- [
- -56,
- -23
- ]
- ],
- [
- [
- 13957,
- 16331
- ],
- [
- -43,
- 5
- ],
- [
- -54,
- -31
- ]
- ],
- [
- [
- 13702,
- 16376
- ],
- [
- -13,
- 41
- ],
- [
- -12,
- 1
- ]
- ],
- [
- [
- 20962,
- 9569
- ],
- [
- -29,
- -3
- ],
- [
- -92,
- 85
- ],
- [
- 65,
- 23
- ],
- [
- 36,
- -36
- ],
- [
- 25,
- -37
- ],
- [
- -5,
- -32
- ]
- ],
- [
- [
- 21259,
- 9730
- ],
- [
- 7,
- -23
- ],
- [
- 1,
- -37
- ]
- ],
- [
- [
- 21267,
- 9670
- ],
- [
- -45,
- -89
- ],
- [
- -60,
- -27
- ],
- [
- -8,
- 15
- ],
- [
- 6,
- 40
- ],
- [
- 30,
- 74
- ],
- [
- 69,
- 47
- ]
- ],
- [
- [
- 20766,
- 9826
- ],
- [
- 25,
- -32
- ],
- [
- 43,
- 10
- ],
- [
- 18,
- -51
- ],
- [
- -81,
- -24
- ],
- [
- -48,
- -16
- ],
- [
- -38,
- 1
- ],
- [
- 24,
- 69
- ],
- [
- 38,
- 1
- ],
- [
- 19,
- 42
- ]
- ],
- [
- [
- 21115,
- 9826
- ],
- [
- -10,
- -67
- ],
- [
- -105,
- -34
- ],
- [
- -93,
- 15
- ],
- [
- 0,
- 44
- ],
- [
- 55,
- 25
- ],
- [
- 44,
- -36
- ],
- [
- 46,
- 9
- ],
- [
- 63,
- 44
- ]
- ],
- [
- [
- 20119,
- 9984
- ],
- [
- 134,
- -12
- ],
- [
- 15,
- 50
- ],
- [
- 130,
- -58
- ],
- [
- 25,
- -78
- ],
- [
- 105,
- -22
- ],
- [
- 85,
- -71
- ],
- [
- -79,
- -46
- ],
- [
- -77,
- 49
- ],
- [
- -63,
- -4
- ],
- [
- -72,
- 9
- ],
- [
- -66,
- 22
- ],
- [
- -80,
- 46
- ],
- [
- -52,
- 11
- ],
- [
- -29,
- -15
- ],
- [
- -127,
- 50
- ],
- [
- -12,
- 51
- ],
- [
- -64,
- 9
- ],
- [
- 48,
- 115
- ],
- [
- 85,
- -7
- ],
- [
- 56,
- -47
- ],
- [
- 29,
- -9
- ],
- [
- 9,
- -43
- ]
- ],
- [
- [
- 21939,
- 10052
- ],
- [
- -36,
- -82
- ],
- [
- -7,
- 90
- ],
- [
- 13,
- 43
- ],
- [
- 14,
- 41
- ],
- [
- 16,
- -35
- ],
- [
- 0,
- -57
- ]
- ],
- [
- [
- 21418,
- 10382
- ],
- [
- -26,
- -40
- ],
- [
- -48,
- 22
- ],
- [
- -14,
- 52
- ],
- [
- 71,
- 6
- ],
- [
- 17,
- -40
- ]
- ],
- [
- [
- 21642,
- 10426
- ],
- [
- 26,
- -92
- ],
- [
- -59,
- 50
- ],
- [
- -58,
- 10
- ],
- [
- -40,
- -8
- ],
- [
- -48,
- 4
- ],
- [
- 17,
- 66
- ],
- [
- 86,
- 5
- ],
- [
- 76,
- -35
- ]
- ],
- [
- [
- 22376,
- 10485
- ],
- [
- 2,
- -391
- ],
- [
- 1,
- -391
- ]
- ],
- [
- [
- 22379,
- 9703
- ],
- [
- -62,
- 99
- ],
- [
- -71,
- 24
- ],
- [
- -17,
- -34
- ],
- [
- -89,
- -4
- ],
- [
- 30,
- 98
- ],
- [
- 44,
- 33
- ],
- [
- -18,
- 130
- ],
- [
- -34,
- 101
- ],
- [
- -135,
- 102
- ],
- [
- -57,
- 10
- ],
- [
- -105,
- 111
- ],
- [
- -21,
- -59
- ],
- [
- -26,
- -10
- ],
- [
- -16,
- 44
- ],
- [
- 0,
- 52
- ],
- [
- -54,
- 59
- ],
- [
- 75,
- 43
- ],
- [
- 50,
- -2
- ],
- [
- -6,
- 32
- ],
- [
- -102,
- 0
- ],
- [
- -27,
- 71
- ],
- [
- -63,
- 22
- ],
- [
- -29,
- 60
- ],
- [
- 94,
- 29
- ],
- [
- 35,
- 39
- ],
- [
- 112,
- -49
- ],
- [
- 11,
- -45
- ],
- [
- 20,
- -194
- ],
- [
- 72,
- -72
- ],
- [
- 58,
- 127
- ],
- [
- 80,
- 73
- ],
- [
- 62,
- 0
- ],
- [
- 60,
- -42
- ],
- [
- 52,
- -43
- ],
- [
- 74,
- -23
- ]
- ],
- [
- [
- 21278,
- 10968
- ],
- [
- -56,
- -119
- ],
- [
- -53,
- -24
- ],
- [
- -67,
- 24
- ],
- [
- -116,
- -6
- ],
- [
- -61,
- -17
- ],
- [
- -10,
- -91
- ],
- [
- 63,
- -107
- ],
- [
- 37,
- 55
- ],
- [
- 130,
- 40
- ],
- [
- -5,
- -55
- ],
- [
- -31,
- 18
- ],
- [
- -30,
- -71
- ],
- [
- -61,
- -46
- ],
- [
- 66,
- -154
- ],
- [
- -13,
- -41
- ],
- [
- 63,
- -139
- ],
- [
- -1,
- -79
- ],
- [
- -37,
- -35
- ],
- [
- -28,
- 42
- ],
- [
- 34,
- 99
- ],
- [
- -68,
- -47
- ],
- [
- -18,
- 33
- ],
- [
- 9,
- 47
- ],
- [
- -50,
- 70
- ],
- [
- 5,
- 117
- ],
- [
- -46,
- -37
- ],
- [
- 6,
- -139
- ],
- [
- 3,
- -172
- ],
- [
- -45,
- -17
- ],
- [
- -30,
- 35
- ],
- [
- 20,
- 110
- ],
- [
- -10,
- 116
- ],
- [
- -30,
- 1
- ],
- [
- -21,
- 82
- ],
- [
- 28,
- 79
- ],
- [
- 10,
- 95
- ],
- [
- 35,
- 181
- ],
- [
- 15,
- 49
- ],
- [
- 59,
- 89
- ],
- [
- 55,
- -35
- ],
- [
- 88,
- -17
- ],
- [
- 80,
- 5
- ],
- [
- 69,
- 87
- ],
- [
- 12,
- -26
- ]
- ],
- [
- [
- 21518,
- 10933
- ],
- [
- -4,
- -105
- ],
- [
- -35,
- 12
- ],
- [
- -11,
- -73
- ],
- [
- 29,
- -63
- ],
- [
- -20,
- -15
- ],
- [
- -28,
- 76
- ],
- [
- -21,
- 154
- ],
- [
- 14,
- 95
- ],
- [
- 23,
- 44
- ],
- [
- 5,
- -65
- ],
- [
- 42,
- -11
- ],
- [
- 6,
- -49
- ]
- ],
- [
- [
- 20192,
- 11038
- ],
- [
- 12,
- -80
- ],
- [
- 47,
- -68
- ],
- [
- 45,
- 24
- ],
- [
- 45,
- -8
- ],
- [
- 40,
- 60
- ],
- [
- 34,
- 11
- ],
- [
- 66,
- -34
- ],
- [
- 57,
- 26
- ],
- [
- 35,
- 167
- ],
- [
- 27,
- 41
- ],
- [
- 24,
- 137
- ],
- [
- 80,
- 0
- ],
- [
- 61,
- -20
- ]
- ],
- [
- [
- 20765,
- 11294
- ],
- [
- -40,
- -109
- ],
- [
- 51,
- -113
- ],
- [
- -12,
- -56
- ],
- [
- 79,
- -111
- ],
- [
- -83,
- -14
- ],
- [
- -23,
- -82
- ],
- [
- 3,
- -108
- ],
- [
- -67,
- -82
- ],
- [
- -2,
- -120
- ],
- [
- -27,
- -183
- ],
- [
- -10,
- 42
- ],
- [
- -79,
- -54
- ],
- [
- -28,
- 74
- ],
- [
- -50,
- 7
- ],
- [
- -35,
- 38
- ],
- [
- -82,
- -43
- ],
- [
- -26,
- 58
- ],
- [
- -46,
- -7
- ],
- [
- -57,
- 14
- ],
- [
- -11,
- 161
- ],
- [
- -34,
- 33
- ],
- [
- -34,
- 103
- ],
- [
- -10,
- 105
- ],
- [
- 9,
- 111
- ],
- [
- 41,
- 80
- ]
- ],
- [
- [
- 19924,
- 10095
- ],
- [
- -77,
- -2
- ],
- [
- -59,
- 100
- ],
- [
- -90,
- 98
- ],
- [
- -29,
- 73
- ],
- [
- -53,
- 97
- ],
- [
- -35,
- 90
- ],
- [
- -53,
- 168
- ],
- [
- -61,
- 100
- ],
- [
- -20,
- 103
- ],
- [
- -26,
- 94
- ],
- [
- -63,
- 75
- ],
- [
- -36,
- 103
- ],
- [
- -53,
- 67
- ],
- [
- -73,
- 133
- ],
- [
- -6,
- 61
- ],
- [
- 45,
- -5
- ],
- [
- 108,
- -23
- ],
- [
- 62,
- -118
- ],
- [
- 54,
- -81
- ],
- [
- 38,
- -50
- ],
- [
- 66,
- -129
- ],
- [
- 71,
- -2
- ],
- [
- 58,
- -82
- ],
- [
- 41,
- -100
- ],
- [
- 53,
- -55
- ],
- [
- -28,
- -98
- ],
- [
- 40,
- -42
- ],
- [
- 25,
- -3
- ],
- [
- 12,
- -84
- ],
- [
- 24,
- -67
- ],
- [
- 51,
- -10
- ],
- [
- 34,
- -76
- ],
- [
- -17,
- -149
- ],
- [
- -3,
- -186
- ]
- ],
- [
- [
- 18754,
- 13443
- ],
- [
- -10,
- -44
- ],
- [
- -48,
- 2
- ],
- [
- -86,
- -25
- ],
- [
- 4,
- -90
- ],
- [
- -37,
- -71
- ],
- [
- -100,
- -81
- ],
- [
- -78,
- -141
- ],
- [
- -53,
- -76
- ],
- [
- -69,
- -78
- ],
- [
- 0,
- -56
- ],
- [
- -35,
- -29
- ],
- [
- -63,
- -43
- ],
- [
- -32,
- -6
- ],
- [
- -21,
- -92
- ],
- [
- 14,
- -156
- ],
- [
- 4,
- -99
- ],
- [
- -29,
- -114
- ],
- [
- -1,
- -204
- ],
- [
- -36,
- -6
- ],
- [
- -32,
- -92
- ],
- [
- 22,
- -39
- ],
- [
- -64,
- -34
- ],
- [
- -23,
- -82
- ],
- [
- -28,
- -34
- ],
- [
- -66,
- 112
- ],
- [
- -33,
- 168
- ],
- [
- -26,
- 121
- ],
- [
- -25,
- 57
- ],
- [
- -37,
- 115
- ],
- [
- -17,
- 150
- ],
- [
- -12,
- 75
- ],
- [
- -64,
- 165
- ],
- [
- -28,
- 232
- ],
- [
- -21,
- 154
- ],
- [
- 0,
- 145
- ],
- [
- -14,
- 112
- ],
- [
- -101,
- -72
- ],
- [
- -49,
- 15
- ],
- [
- -91,
- 145
- ],
- [
- 33,
- 44
- ],
- [
- -20,
- 47
- ],
- [
- -82,
- 101
- ]
- ],
- [
- [
- 17300,
- 13639
- ],
- [
- 46,
- 81
- ],
- [
- 154,
- -1
- ],
- [
- -14,
- 103
- ],
- [
- -39,
- 61
- ],
- [
- -8,
- 92
- ],
- [
- -46,
- 54
- ],
- [
- 77,
- 126
- ],
- [
- 81,
- -9
- ],
- [
- 73,
- 126
- ],
- [
- 44,
- 121
- ],
- [
- 67,
- 121
- ],
- [
- -1,
- 85
- ],
- [
- 60,
- 70
- ],
- [
- -57,
- 59
- ],
- [
- -24,
- 81
- ],
- [
- -25,
- 105
- ],
- [
- 35,
- 52
- ],
- [
- 105,
- -29
- ],
- [
- 78,
- 18
- ],
- [
- 67,
- 100
- ]
- ],
- [
- [
- 18202,
- 14418
- ],
- [
- -45,
- -54
- ],
- [
- -27,
- -112
- ],
- [
- 68,
- -46
- ],
- [
- 66,
- -59
- ],
- [
- 91,
- -67
- ],
- [
- 95,
- -15
- ],
- [
- 40,
- -61
- ],
- [
- 54,
- -12
- ],
- [
- 84,
- -28
- ],
- [
- 58,
- 2
- ],
- [
- 8,
- 48
- ],
- [
- -9,
- 76
- ],
- [
- 5,
- 52
- ]
- ],
- [
- [
- 19332,
- 14188
- ],
- [
- 5,
- -46
- ],
- [
- -24,
- -22
- ],
- [
- 6,
- -74
- ],
- [
- -50,
- 22
- ],
- [
- -91,
- -83
- ],
- [
- 3,
- -68
- ],
- [
- -39,
- -101
- ],
- [
- -3,
- -59
- ],
- [
- -31,
- -98
- ],
- [
- -55,
- 27
- ],
- [
- -3,
- -124
- ],
- [
- -15,
- -41
- ],
- [
- 7,
- -51
- ],
- [
- -34,
- -29
- ]
- ],
- [
- [
- 12115,
- 17260
- ],
- [
- 12,
- -86
- ],
- [
- -53,
- -107
- ],
- [
- -123,
- -71
- ],
- [
- -99,
- 18
- ],
- [
- 57,
- 125
- ],
- [
- -37,
- 122
- ],
- [
- 95,
- 94
- ],
- [
- 53,
- 56
- ]
- ],
- [
- [
- 16791,
- 14376
- ],
- [
- 34,
- -63
- ],
- [
- 29,
- -73
- ],
- [
- 66,
- -53
- ],
- [
- 2,
- -105
- ],
- [
- 33,
- -20
- ],
- [
- 6,
- -55
- ],
- [
- -100,
- -62
- ],
- [
- -27,
- -139
- ]
- ],
- [
- [
- 16834,
- 13806
- ],
- [
- -131,
- 36
- ],
- [
- -76,
- 28
- ],
- [
- -78,
- 15
- ],
- [
- -30,
- 147
- ],
- [
- -34,
- 22
- ],
- [
- -53,
- -22
- ],
- [
- -70,
- -58
- ],
- [
- -86,
- 40
- ],
- [
- -70,
- 92
- ],
- [
- -67,
- 34
- ],
- [
- -47,
- 114
- ],
- [
- -51,
- 160
- ],
- [
- -38,
- -19
- ],
- [
- -44,
- 39
- ],
- [
- -26,
- -47
- ]
- ],
- [
- [
- 15933,
- 14387
- ],
- [
- -38,
- 64
- ],
- [
- -1,
- 63
- ],
- [
- -22,
- 0
- ],
- [
- 11,
- 87
- ],
- [
- -36,
- 91
- ],
- [
- -85,
- 66
- ],
- [
- -49,
- 114
- ],
- [
- 17,
- 94
- ],
- [
- 35,
- 41
- ],
- [
- -6,
- 70
- ],
- [
- -45,
- 36
- ],
- [
- -45,
- 143
- ]
- ],
- [
- [
- 15669,
- 15256
- ],
- [
- -39,
- 97
- ],
- [
- 14,
- 37
- ],
- [
- -22,
- 137
- ],
- [
- 48,
- 35
- ]
- ],
- [
- [
- 15955,
- 15394
- ],
- [
- 22,
- -88
- ],
- [
- 66,
- -25
- ],
- [
- 49,
- -60
- ],
- [
- 99,
- -21
- ],
- [
- 109,
- 32
- ],
- [
- 6,
- 28
- ]
- ],
- [
- [
- 16306,
- 15260
- ],
- [
- 62,
- 23
- ],
- [
- 49,
- 69
- ],
- [
- 47,
- -4
- ],
- [
- 30,
- 23
- ],
- [
- 50,
- -11
- ],
- [
- 77,
- -61
- ],
- [
- 56,
- -13
- ],
- [
- 79,
- -107
- ],
- [
- 52,
- -4
- ],
- [
- 6,
- -101
- ]
- ],
- [
- [
- 15933,
- 14387
- ],
- [
- -41,
- 6
- ]
- ],
- [
- [
- 15892,
- 14393
- ],
- [
- -47,
- 10
- ],
- [
- -51,
- -115
- ]
- ],
- [
- [
- 15794,
- 14288
- ],
- [
- -130,
- 10
- ],
- [
- -196,
- 241
- ],
- [
- -104,
- 84
- ],
- [
- -84,
- 33
- ]
- ],
- [
- [
- 15280,
- 14656
- ],
- [
- -28,
- 146
- ]
- ],
- [
- [
- 15252,
- 14802
- ],
- [
- 154,
- 124
- ],
- [
- 26,
- 145
- ],
- [
- -6,
- 88
- ],
- [
- 38,
- 30
- ],
- [
- 36,
- 75
- ]
- ],
- [
- [
- 15500,
- 15264
- ],
- [
- 30,
- 18
- ],
- [
- 81,
- -15
- ],
- [
- 24,
- -31
- ],
- [
- 34,
- 20
- ]
- ],
- [
- [
- 11536,
- 18770
- ],
- [
- -16,
- -78
- ],
- [
- 79,
- -82
- ],
- [
- -91,
- -91
- ],
- [
- -201,
- -82
- ],
- [
- -60,
- -22
- ],
- [
- -92,
- 17
- ],
- [
- -194,
- 38
- ],
- [
- 68,
- 53
- ],
- [
- -151,
- 59
- ],
- [
- 123,
- 23
- ],
- [
- -3,
- 36
- ],
- [
- -146,
- 27
- ],
- [
- 47,
- 79
- ],
- [
- 106,
- 17
- ],
- [
- 108,
- -81
- ],
- [
- 106,
- 65
- ],
- [
- 88,
- -34
- ],
- [
- 113,
- 64
- ],
- [
- 116,
- -8
- ]
- ],
- [
- [
- 14936,
- 14543
- ],
- [
- 20,
- 39
- ],
- [
- -4,
- 7
- ],
- [
- 18,
- 56
- ],
- [
- 14,
- 90
- ],
- [
- 10,
- 31
- ],
- [
- 2,
- 1
- ]
- ],
- [
- [
- 14996,
- 14767
- ],
- [
- 23,
- 0
- ],
- [
- 7,
- 21
- ],
- [
- 19,
- 1
- ]
- ],
- [
- [
- 15045,
- 14789
- ],
- [
- 1,
- -49
- ],
- [
- -10,
- -18
- ],
- [
- 1,
- -1
- ]
- ],
- [
- [
- 15037,
- 14721
- ],
- [
- -12,
- -38
- ]
- ],
- [
- [
- 15025,
- 14683
- ],
- [
- -25,
- 17
- ],
- [
- -14,
- -80
- ],
- [
- 17,
- -13
- ],
- [
- -18,
- -17
- ],
- [
- -3,
- -31
- ],
- [
- 33,
- 16
- ]
- ],
- [
- [
- 15015,
- 14575
- ],
- [
- 2,
- -47
- ],
- [
- -35,
- -192
- ]
- ],
- [
- [
- 13510,
- 16377
- ],
- [
- -8,
- -59
- ],
- [
- 17,
- -51
- ]
- ],
- [
- [
- 13519,
- 16267
- ],
- [
- -55,
- 17
- ],
- [
- -57,
- -42
- ],
- [
- 4,
- -60
- ],
- [
- -9,
- -34
- ],
- [
- 23,
- -61
- ],
- [
- 65,
- -61
- ],
- [
- 35,
- -99
- ],
- [
- 78,
- -96
- ],
- [
- 55,
- 0
- ],
- [
- 17,
- -26
- ],
- [
- -20,
- -24
- ],
- [
- 63,
- -44
- ],
- [
- 51,
- -36
- ],
- [
- 60,
- -62
- ],
- [
- 7,
- -23
- ],
- [
- -13,
- -43
- ],
- [
- -39,
- 56
- ],
- [
- -61,
- 20
- ],
- [
- -29,
- -78
- ],
- [
- 50,
- -44
- ],
- [
- -8,
- -63
- ],
- [
- -29,
- -7
- ],
- [
- -37,
- -103
- ],
- [
- -29,
- -9
- ],
- [
- 0,
- 37
- ],
- [
- 14,
- 64
- ],
- [
- 15,
- 26
- ],
- [
- -27,
- 69
- ],
- [
- -21,
- 61
- ],
- [
- -29,
- 15
- ],
- [
- -21,
- 51
- ],
- [
- -44,
- 22
- ],
- [
- -31,
- 49
- ],
- [
- -51,
- 7
- ],
- [
- -55,
- 54
- ],
- [
- -63,
- 79
- ],
- [
- -48,
- 69
- ],
- [
- -21,
- 118
- ],
- [
- -35,
- 14
- ],
- [
- -57,
- 40
- ],
- [
- -32,
- -16
- ],
- [
- -40,
- -56
- ],
- [
- -29,
- -9
- ]
- ],
- [
- [
- 13629,
- 15384
- ],
- [
- -25,
- -95
- ],
- [
- 11,
- -37
- ],
- [
- -15,
- -62
- ],
- [
- -53,
- 46
- ],
- [
- -36,
- 13
- ],
- [
- -97,
- 61
- ],
- [
- 10,
- 61
- ],
- [
- 81,
- -11
- ],
- [
- 71,
- 13
- ],
- [
- 53,
- 11
- ]
- ],
- [
- [
- 13190,
- 15741
- ],
- [
- 41,
- -85
- ],
- [
- -9,
- -159
- ],
- [
- -32,
- 8
- ],
- [
- -29,
- -40
- ],
- [
- -26,
- 32
- ],
- [
- -3,
- 144
- ],
- [
- -16,
- 69
- ],
- [
- 39,
- -6
- ],
- [
- 35,
- 37
- ]
- ],
- [
- [
- 7140,
- 13015
- ],
- [
- 47,
- -10
- ],
- [
- 37,
- -29
- ],
- [
- 12,
- -33
- ],
- [
- -49,
- -2
- ],
- [
- -21,
- -20
- ],
- [
- -39,
- 19
- ],
- [
- -40,
- 44
- ],
- [
- 8,
- 27
- ],
- [
- 29,
- 9
- ],
- [
- 16,
- -5
- ]
- ],
- [
- [
- 15280,
- 14656
- ],
- [
- -14,
- -19
- ],
- [
- -139,
- -60
- ],
- [
- 69,
- -120
- ],
- [
- -23,
- -20
- ],
- [
- -11,
- -40
- ],
- [
- -53,
- -17
- ],
- [
- -17,
- -43
- ],
- [
- -30,
- -37
- ],
- [
- -78,
- 19
- ]
- ],
- [
- [
- 14984,
- 14319
- ],
- [
- -2,
- 17
- ]
- ],
- [
- [
- 15015,
- 14575
- ],
- [
- 10,
- 35
- ],
- [
- 0,
- 73
- ]
- ],
- [
- [
- 15037,
- 14721
- ],
- [
- 78,
- -47
- ],
- [
- 137,
- 128
- ]
- ],
- [
- [
- 21933,
- 14894
- ],
- [
- 9,
- -41
- ],
- [
- -39,
- -73
- ],
- [
- -29,
- 39
- ],
- [
- -36,
- -28
- ],
- [
- -18,
- -70
- ],
- [
- -46,
- 34
- ],
- [
- 1,
- 57
- ],
- [
- 38,
- 71
- ],
- [
- 40,
- -14
- ],
- [
- 29,
- 51
- ],
- [
- 51,
- -26
- ]
- ],
- [
- [
- 22375,
- 15253
- ],
- [
- -27,
- -96
- ],
- [
- 13,
- -60
- ],
- [
- -37,
- -84
- ],
- [
- -89,
- -57
- ],
- [
- -122,
- -7
- ],
- [
- -100,
- -137
- ],
- [
- -46,
- 46
- ],
- [
- -3,
- 90
- ],
- [
- -122,
- -27
- ],
- [
- -82,
- -56
- ],
- [
- -82,
- -3
- ],
- [
- 71,
- -88
- ],
- [
- -47,
- -204
- ],
- [
- -45,
- -50
- ],
- [
- -33,
- 46
- ],
- [
- 17,
- 109
- ],
- [
- -44,
- 34
- ],
- [
- -29,
- 83
- ],
- [
- 66,
- 37
- ],
- [
- 37,
- 75
- ],
- [
- 70,
- 62
- ],
- [
- 51,
- 82
- ],
- [
- 139,
- 36
- ],
- [
- 74,
- -25
- ],
- [
- 73,
- 214
- ],
- [
- 47,
- -58
- ],
- [
- 102,
- 120
- ],
- [
- 40,
- 47
- ],
- [
- 43,
- 147
- ],
- [
- -11,
- 135
- ],
- [
- 29,
- 75
- ],
- [
- 74,
- 22
- ],
- [
- 38,
- -166
- ],
- [
- -2,
- -97
- ],
- [
- -64,
- -121
- ],
- [
- 1,
- -124
- ]
- ],
- [
- [
- 22579,
- 16097
- ],
- [
- 49,
- -26
- ],
- [
- 50,
- 51
- ],
- [
- 15,
- -135
- ],
- [
- -103,
- -33
- ],
- [
- -61,
- -119
- ],
- [
- -110,
- 82
- ],
- [
- -38,
- -131
- ],
- [
- -77,
- -2
- ],
- [
- -10,
- 120
- ],
- [
- 34,
- 92
- ],
- [
- 75,
- 6
- ],
- [
- 20,
- 166
- ],
- [
- 21,
- 94
- ],
- [
- 82,
- -125
- ],
- [
- 53,
- -40
- ]
- ],
- [
- [
- 18142,
- 15878
- ],
- [
- -43,
- 17
- ],
- [
- -35,
- 44
- ],
- [
- -103,
- 12
- ],
- [
- -116,
- 3
- ],
- [
- -25,
- -13
- ],
- [
- -99,
- 51
- ],
- [
- -40,
- -25
- ],
- [
- -11,
- -71
- ],
- [
- -114,
- 41
- ],
- [
- -46,
- -17
- ],
- [
- -16,
- -52
- ]
- ],
- [
- [
- 17494,
- 15868
- ],
- [
- -40,
- -22
- ],
- [
- -92,
- -84
- ],
- [
- -30,
- -86
- ],
- [
- -26,
- -1
- ],
- [
- -19,
- 57
- ],
- [
- -89,
- 4
- ],
- [
- -14,
- 98
- ],
- [
- -34,
- 1
- ],
- [
- 5,
- 121
- ],
- [
- -83,
- 87
- ],
- [
- -120,
- -9
- ],
- [
- -82,
- -18
- ],
- [
- -66,
- 109
- ],
- [
- -57,
- 45
- ],
- [
- -108,
- 86
- ],
- [
- -13,
- 10
- ],
- [
- -180,
- -71
- ],
- [
- 3,
- -442
- ]
- ],
- [
- [
- 16449,
- 15753
- ],
- [
- -36,
- -6
- ],
- [
- -49,
- 94
- ],
- [
- -47,
- 34
- ],
- [
- -79,
- -25
- ],
- [
- -31,
- -40
- ]
- ],
- [
- [
- 16207,
- 15810
- ],
- [
- -4,
- 29
- ],
- [
- 18,
- 50
- ],
- [
- -14,
- 42
- ],
- [
- -81,
- 41
- ],
- [
- -31,
- 108
- ],
- [
- -38,
- 30
- ],
- [
- -3,
- 39
- ],
- [
- 68,
- -11
- ],
- [
- 3,
- 87
- ],
- [
- 59,
- 20
- ],
- [
- 61,
- -18
- ],
- [
- 12,
- 117
- ],
- [
- -12,
- 74
- ],
- [
- -70,
- -6
- ],
- [
- -59,
- 30
- ],
- [
- -81,
- -53
- ],
- [
- -65,
- -25
- ]
- ],
- [
- [
- 15970,
- 16364
- ],
- [
- -35,
- 19
- ],
- [
- 7,
- 62
- ],
- [
- -45,
- 80
- ],
- [
- -51,
- -3
- ],
- [
- -59,
- 81
- ],
- [
- 40,
- 91
- ],
- [
- -21,
- 24
- ],
- [
- 56,
- 132
- ],
- [
- 72,
- -69
- ],
- [
- 8,
- 87
- ],
- [
- 144,
- 131
- ],
- [
- 109,
- 3
- ],
- [
- 154,
- -83
- ],
- [
- 82,
- -49
- ],
- [
- 74,
- 51
- ],
- [
- 111,
- 2
- ],
- [
- 89,
- -62
- ],
- [
- 20,
- 36
- ],
- [
- 98,
- -6
- ],
- [
- 18,
- 57
- ],
- [
- -113,
- 83
- ],
- [
- 67,
- 58
- ],
- [
- -13,
- 33
- ],
- [
- 67,
- 31
- ],
- [
- -51,
- 82
- ],
- [
- 32,
- 41
- ],
- [
- 261,
- 42
- ],
- [
- 34,
- 30
- ],
- [
- 174,
- 44
- ],
- [
- 63,
- 50
- ],
- [
- 125,
- -26
- ],
- [
- 22,
- -125
- ],
- [
- 73,
- 30
- ],
- [
- 90,
- -41
- ],
- [
- -6,
- -66
- ],
- [
- 67,
- 7
- ],
- [
- 174,
- 113
- ],
- [
- -25,
- -37
- ],
- [
- 89,
- -93
- ],
- [
- 156,
- -305
- ],
- [
- 37,
- 63
- ],
- [
- 96,
- -69
- ],
- [
- 100,
- 31
- ],
- [
- 38,
- -22
- ],
- [
- 34,
- -69
- ],
- [
- 49,
- -23
- ],
- [
- 29,
- -51
- ],
- [
- 90,
- 16
- ],
- [
- 37,
- -74
- ]
- ],
- [
- [
- 15465,
- 11267
- ],
- [
- -61,
- -136
- ],
- [
- 1,
- -437
- ],
- [
- 41,
- -99
- ]
- ],
- [
- [
- 15446,
- 10595
- ],
- [
- -48,
- -48
- ],
- [
- -18,
- -50
- ],
- [
- -26,
- -8
- ],
- [
- -10,
- -85
- ],
- [
- -22,
- -48
- ],
- [
- -14,
- -80
- ],
- [
- -28,
- -40
- ]
- ],
- [
- [
- 15280,
- 10236
- ],
- [
- -100,
- 120
- ],
- [
- -5,
- 70
- ],
- [
- -252,
- 244
- ],
- [
- -12,
- 13
- ]
- ],
- [
- [
- 14911,
- 10683
- ],
- [
- -1,
- 127
- ],
- [
- 20,
- 49
- ],
- [
- 34,
- 79
- ],
- [
- 26,
- 88
- ],
- [
- -31,
- 138
- ],
- [
- -8,
- 60
- ],
- [
- -33,
- 83
- ]
- ],
- [
- [
- 14918,
- 11307
- ],
- [
- 43,
- 72
- ],
- [
- 47,
- 79
- ]
- ],
- [
- [
- 17683,
- 15528
- ],
- [
- -132,
- -18
- ],
- [
- -86,
- 38
- ],
- [
- -75,
- -9
- ],
- [
- 6,
- 69
- ],
- [
- 76,
- -20
- ],
- [
- 26,
- 37
- ]
- ],
- [
- [
- 17498,
- 15625
- ],
- [
- 53,
- -12
- ],
- [
- 89,
- 87
- ],
- [
- -83,
- 63
- ],
- [
- -49,
- -30
- ],
- [
- -52,
- 45
- ],
- [
- 59,
- 78
- ],
- [
- -21,
- 12
- ]
- ],
- [
- [
- 19699,
- 12259
- ],
- [
- -17,
- 145
- ],
- [
- 45,
- 100
- ],
- [
- 90,
- 23
- ],
- [
- 65,
- -17
- ]
- ],
- [
- [
- 19882,
- 12510
- ],
- [
- 58,
- -48
- ],
- [
- 31,
- 83
- ],
- [
- 62,
- -44
- ]
- ],
- [
- [
- 20033,
- 12501
- ],
- [
- 16,
- -80
- ],
- [
- -8,
- -144
- ],
- [
- -118,
- -92
- ],
- [
- 31,
- -73
- ],
- [
- -73,
- -8
- ],
- [
- -61,
- -49
- ]
- ],
- [
- [
- 19820,
- 12055
- ],
- [
- -58,
- 18
- ],
- [
- -28,
- 62
- ],
- [
- -35,
- 124
- ]
- ],
- [
- [
- 21495,
- 15429
- ],
- [
- 60,
- -141
- ],
- [
- 17,
- -78
- ],
- [
- 1,
- -138
- ],
- [
- -27,
- -66
- ],
- [
- -63,
- -23
- ],
- [
- -56,
- -50
- ],
- [
- -62,
- -10
- ],
- [
- -8,
- 65
- ],
- [
- 13,
- 90
- ],
- [
- -31,
- 125
- ],
- [
- 52,
- 20
- ],
- [
- -48,
- 103
- ]
- ],
- [
- [
- 21343,
- 15326
- ],
- [
- 4,
- 11
- ],
- [
- 31,
- -4
- ],
- [
- 28,
- 54
- ],
- [
- 49,
- 6
- ],
- [
- 30,
- 7
- ],
- [
- 10,
- 29
- ]
- ],
- [
- [
- 13947,
- 15907
- ],
- [
- 13,
- 26
- ]
- ],
- [
- [
- 13960,
- 15933
- ],
- [
- 16,
- 9
- ],
- [
- 10,
- 40
- ],
- [
- 12,
- 6
- ],
- [
- 10,
- -16
- ],
- [
- 13,
- -8
- ],
- [
- 9,
- -19
- ],
- [
- 12,
- -6
- ],
- [
- 14,
- -22
- ],
- [
- 9,
- 1
- ],
- [
- -7,
- -29
- ],
- [
- -9,
- -15
- ],
- [
- 3,
- -9
- ]
- ],
- [
- [
- 14052,
- 15865
- ],
- [
- -16,
- -4
- ],
- [
- -41,
- -19
- ],
- [
- -3,
- -24
- ],
- [
- -9,
- 1
- ]
- ],
- [
- [
- 15892,
- 14393
- ],
- [
- 14,
- -53
- ],
- [
- -6,
- -27
- ],
- [
- 23,
- -90
- ]
- ],
- [
- [
- 15923,
- 14223
- ],
- [
- -50,
- -4
- ],
- [
- -17,
- 58
- ],
- [
- -62,
- 11
- ]
- ],
- [
- [
- 19670,
- 13492
- ],
- [
- 40,
- -94
- ],
- [
- 32,
- -109
- ],
- [
- 85,
- -1
- ],
- [
- 28,
- -105
- ],
- [
- -45,
- -31
- ],
- [
- -20,
- -44
- ],
- [
- 83,
- -71
- ],
- [
- 58,
- -142
- ],
- [
- 44,
- -106
- ],
- [
- 53,
- -83
- ],
- [
- 18,
- -85
- ],
- [
- -13,
- -120
- ]
- ],
- [
- [
- 19882,
- 12510
- ],
- [
- 23,
- 54
- ],
- [
- 3,
- 101
- ],
- [
- -57,
- 105
- ],
- [
- -4,
- 118
- ],
- [
- -53,
- 98
- ],
- [
- -53,
- 8
- ],
- [
- -14,
- -42
- ],
- [
- -40,
- -3
- ],
- [
- -21,
- 21
- ],
- [
- -74,
- -72
- ],
- [
- -1,
- 108
- ],
- [
- 17,
- 126
- ],
- [
- -47,
- 6
- ],
- [
- -4,
- 72
- ],
- [
- -31,
- 37
- ]
- ],
- [
- [
- 19526,
- 13247
- ],
- [
- 15,
- 44
- ],
- [
- 60,
- 78
- ]
- ],
- [
- [
- 14996,
- 14767
- ],
- [
- 25,
- 98
- ],
- [
- 35,
- 84
- ],
- [
- 1,
- 5
- ]
- ],
- [
- [
- 15057,
- 14954
- ],
- [
- 31,
- -7
- ],
- [
- 12,
- -47
- ],
- [
- -38,
- -45
- ],
- [
- -17,
- -66
- ]
- ],
- [
- [
- 12010,
- 11321
- ],
- [
- -18,
- -1
- ],
- [
- -72,
- 57
- ],
- [
- -64,
- 91
- ],
- [
- -59,
- 66
- ],
- [
- -47,
- 77
- ]
- ],
- [
- [
- 11750,
- 11611
- ],
- [
- 17,
- 39
- ],
- [
- 3,
- 35
- ],
- [
- 32,
- 65
- ],
- [
- 32,
- 56
- ]
- ],
- [
- [
- 13208,
- 14433
- ],
- [
- 34,
- 28
- ],
- [
- 7,
- 51
- ],
- [
- -8,
- 49
- ],
- [
- 48,
- 47
- ],
- [
- 21,
- 38
- ],
- [
- 34,
- 34
- ],
- [
- 4,
- 93
- ]
- ],
- [
- [
- 13348,
- 14773
- ],
- [
- 82,
- -42
- ],
- [
- 30,
- 11
- ],
- [
- 58,
- -20
- ],
- [
- 92,
- -54
- ],
- [
- 33,
- -107
- ],
- [
- 62,
- -23
- ],
- [
- 99,
- -50
- ],
- [
- 74,
- -60
- ],
- [
- 34,
- 31
- ],
- [
- 33,
- 56
- ],
- [
- -16,
- 91
- ],
- [
- 22,
- 59
- ],
- [
- 50,
- 56
- ],
- [
- 48,
- 16
- ],
- [
- 95,
- -24
- ],
- [
- 23,
- -54
- ],
- [
- 26,
- 0
- ],
- [
- 22,
- -21
- ],
- [
- 70,
- -14
- ],
- [
- 17,
- -39
- ]
- ],
- [
- [
- 14290,
- 13437
- ],
- [
- 0,
- -240
- ],
- [
- -80,
- 0
- ],
- [
- -1,
- -51
- ]
- ],
- [
- [
- 14209,
- 13146
- ],
- [
- -278,
- 230
- ],
- [
- -278,
- 230
- ],
- [
- -70,
- -66
- ]
- ],
- [
- [
- 13583,
- 13540
- ],
- [
- -50,
- -45
- ],
- [
- -39,
- 66
- ],
- [
- -110,
- 52
- ]
- ],
- [
- [
- 18249,
- 11700
- ],
- [
- -11,
- -125
- ],
- [
- -29,
- -34
- ],
- [
- -61,
- -28
- ],
- [
- -33,
- 96
- ],
- [
- -12,
- 172
- ],
- [
- 31,
- 195
- ],
- [
- 49,
- -67
- ],
- [
- 32,
- -84
- ],
- [
- 34,
- -125
- ]
- ],
- [
- [
- 14568,
- 7323
- ],
- [
- 24,
- -36
- ],
- [
- -22,
- -58
- ],
- [
- -12,
- -39
- ],
- [
- -38,
- -19
- ],
- [
- -13,
- -38
- ],
- [
- -25,
- -12
- ],
- [
- -52,
- 92
- ],
- [
- 37,
- 76
- ],
- [
- 38,
- 47
- ],
- [
- 32,
- 24
- ],
- [
- 31,
- -37
- ]
- ],
- [
- [
- 14185,
- 17265
- ],
- [
- -17,
- 37
- ],
- [
- -36,
- 13
- ]
- ],
- [
- [
- 14132,
- 17315
- ],
- [
- -6,
- 30
- ],
- [
- 8,
- 33
- ],
- [
- -31,
- 19
- ],
- [
- -73,
- 21
- ]
- ],
- [
- [
- 14030,
- 17418
- ],
- [
- -15,
- 101
- ]
- ],
- [
- [
- 14015,
- 17519
- ],
- [
- 80,
- 37
- ],
- [
- 117,
- -8
- ],
- [
- 68,
- 12
- ],
- [
- 10,
- -25
- ],
- [
- 37,
- -8
- ],
- [
- 67,
- -58
- ]
- ],
- [
- [
- 14015,
- 17519
- ],
- [
- 3,
- 90
- ],
- [
- 34,
- 76
- ],
- [
- 66,
- 41
- ],
- [
- 55,
- -90
- ],
- [
- 56,
- 2
- ],
- [
- 13,
- 93
- ]
- ],
- [
- [
- 14450,
- 17692
- ],
- [
- 33,
- -27
- ],
- [
- 6,
- -58
- ],
- [
- 23,
- -71
- ]
- ],
- [
- [
- 11943,
- 14115
- ],
- [
- -10,
- 0
- ],
- [
- 1,
- -64
- ],
- [
- -43,
- -4
- ],
- [
- -22,
- -27
- ],
- [
- -32,
- 0
- ],
- [
- -25,
- 15
- ],
- [
- -59,
- -13
- ],
- [
- -22,
- -93
- ],
- [
- -22,
- -9
- ],
- [
- -33,
- -151
- ],
- [
- -97,
- -130
- ],
- [
- -23,
- -165
- ],
- [
- -28,
- -54
- ],
- [
- -9,
- -43
- ],
- [
- -157,
- -10
- ],
- [
- -1,
- 0
- ]
- ],
- [
- [
- 11361,
- 13367
- ],
- [
- 3,
- 56
- ],
- [
- 27,
- 32
- ],
- [
- 23,
- 63
- ],
- [
- -5,
- 41
- ],
- [
- 24,
- 84
- ],
- [
- 39,
- 77
- ],
- [
- 24,
- 19
- ],
- [
- 18,
- 70
- ],
- [
- 2,
- 64
- ],
- [
- 25,
- 74
- ],
- [
- 46,
- 44
- ],
- [
- 45,
- 122
- ],
- [
- 1,
- 2
- ],
- [
- 35,
- 46
- ],
- [
- 65,
- 13
- ],
- [
- 55,
- 82
- ],
- [
- 35,
- 32
- ],
- [
- 58,
- 100
- ],
- [
- -18,
- 150
- ],
- [
- 27,
- 103
- ],
- [
- 9,
- 63
- ],
- [
- 45,
- 81
- ],
- [
- 70,
- 55
- ],
- [
- 52,
- 49
- ],
- [
- 46,
- 125
- ],
- [
- 22,
- 73
- ],
- [
- 51,
- 0
- ],
- [
- 42,
- -51
- ],
- [
- 67,
- 8
- ],
- [
- 72,
- -26
- ],
- [
- 30,
- -2
- ]
- ],
- [
- [
- 14403,
- 16582
- ],
- [
- 17,
- 18
- ],
- [
- 46,
- 12
- ],
- [
- 51,
- -38
- ],
- [
- 29,
- -4
- ],
- [
- 32,
- -32
- ],
- [
- -5,
- -41
- ],
- [
- 25,
- -20
- ],
- [
- 10,
- -50
- ],
- [
- 24,
- -30
- ],
- [
- -5,
- -18
- ],
- [
- 13,
- -12
- ],
- [
- -18,
- -9
- ],
- [
- -41,
- 3
- ],
- [
- -7,
- 17
- ],
- [
- -15,
- -10
- ],
- [
- 5,
- -21
- ],
- [
- -19,
- -38
- ],
- [
- -12,
- -42
- ],
- [
- -17,
- -13
- ]
- ],
- [
- [
- 14516,
- 16254
- ],
- [
- -13,
- 55
- ],
- [
- 7,
- 51
- ],
- [
- -2,
- 53
- ],
- [
- -40,
- 71
- ],
- [
- -22,
- 51
- ],
- [
- -22,
- 35
- ],
- [
- -21,
- 12
- ]
- ],
- [
- [
- 16001,
- 9301
- ],
- [
- 19,
- -51
- ],
- [
- 17,
- -79
- ],
- [
- 11,
- -144
- ],
- [
- 18,
- -57
- ],
- [
- -7,
- -57
- ],
- [
- -12,
- -35
- ],
- [
- -24,
- 70
- ],
- [
- -13,
- -36
- ],
- [
- 13,
- -88
- ],
- [
- -6,
- -51
- ],
- [
- -19,
- -28
- ],
- [
- -4,
- -102
- ],
- [
- -28,
- -139
- ],
- [
- -34,
- -166
- ],
- [
- -43,
- -227
- ],
- [
- -27,
- -167
- ],
- [
- -32,
- -139
- ],
- [
- -56,
- -28
- ],
- [
- -61,
- -51
- ],
- [
- -40,
- 30
- ],
- [
- -56,
- 43
- ],
- [
- -19,
- 64
- ],
- [
- -4,
- 106
- ],
- [
- -25,
- 96
- ],
- [
- -6,
- 86
- ],
- [
- 12,
- 86
- ],
- [
- 32,
- 21
- ],
- [
- 0,
- 40
- ],
- [
- 34,
- 91
- ],
- [
- 6,
- 77
- ],
- [
- -16,
- 56
- ],
- [
- -13,
- 76
- ],
- [
- -6,
- 111
- ],
- [
- 24,
- 67
- ],
- [
- 10,
- 76
- ],
- [
- 35,
- 4
- ],
- [
- 38,
- 25
- ],
- [
- 26,
- 21
- ],
- [
- 31,
- 2
- ],
- [
- 40,
- 68
- ],
- [
- 57,
- 74
- ],
- [
- 21,
- 61
- ],
- [
- -10,
- 51
- ],
- [
- 30,
- -14
- ],
- [
- 38,
- 83
- ],
- [
- 2,
- 72
- ],
- [
- 23,
- 54
- ],
- [
- 24,
- -52
- ]
- ],
- [
- [
- 6118,
- 12541
- ],
- [
- -78,
- 130
- ],
- [
- -36,
- 39
- ],
- [
- -57,
- 31
- ],
- [
- -39,
- -9
- ],
- [
- -56,
- -45
- ],
- [
- -35,
- -12
- ],
- [
- -50,
- 32
- ],
- [
- -52,
- 23
- ],
- [
- -65,
- 55
- ],
- [
- -52,
- 16
- ],
- [
- -79,
- 56
- ],
- [
- -58,
- 58
- ],
- [
- -18,
- 32
- ],
- [
- -39,
- 7
- ],
- [
- -71,
- 38
- ],
- [
- -29,
- 54
- ],
- [
- -75,
- 69
- ],
- [
- -35,
- 75
- ],
- [
- -17,
- 59
- ],
- [
- 23,
- 11
- ],
- [
- -7,
- 35
- ],
- [
- 16,
- 31
- ],
- [
- 1,
- 41
- ],
- [
- -24,
- 54
- ],
- [
- -6,
- 48
- ],
- [
- -24,
- 60
- ],
- [
- -61,
- 120
- ],
- [
- -70,
- 93
- ],
- [
- -34,
- 75
- ],
- [
- -60,
- 49
- ],
- [
- -13,
- 29
- ],
- [
- 11,
- 75
- ],
- [
- -36,
- 28
- ],
- [
- -41,
- 58
- ],
- [
- -17,
- 84
- ],
- [
- -38,
- 9
- ],
- [
- -40,
- 63
- ],
- [
- -33,
- 59
- ],
- [
- -3,
- 37
- ],
- [
- -37,
- 91
- ],
- [
- -25,
- 92
- ],
- [
- 1,
- 46
- ],
- [
- -50,
- 47
- ],
- [
- -24,
- -5
- ],
- [
- -39,
- 33
- ],
- [
- -12,
- -49
- ],
- [
- 12,
- -57
- ],
- [
- 7,
- -90
- ],
- [
- 24,
- -50
- ],
- [
- 51,
- -82
- ],
- [
- 12,
- -29
- ],
- [
- 10,
- -8
- ],
- [
- 10,
- -41
- ],
- [
- 12,
- 1
- ],
- [
- 14,
- -77
- ],
- [
- 21,
- -31
- ],
- [
- 15,
- -42
- ],
- [
- 44,
- -61
- ],
- [
- 23,
- -112
- ],
- [
- 21,
- -52
- ],
- [
- 19,
- -56
- ],
- [
- 4,
- -64
- ],
- [
- 34,
- -4
- ],
- [
- 27,
- -54
- ],
- [
- 26,
- -54
- ],
- [
- -2,
- -21
- ],
- [
- -29,
- -44
- ],
- [
- -13,
- 0
- ],
- [
- -18,
- 73
- ],
- [
- -46,
- 69
- ],
- [
- -50,
- 58
- ],
- [
- -36,
- 30
- ],
- [
- 3,
- 88
- ],
- [
- -11,
- 65
- ],
- [
- -33,
- 37
- ],
- [
- -48,
- 54
- ],
- [
- -9,
- -16
- ],
- [
- -18,
- 31
- ],
- [
- -43,
- 29
- ],
- [
- -41,
- 70
- ],
- [
- 5,
- 9
- ],
- [
- 29,
- -7
- ],
- [
- 26,
- 45
- ],
- [
- 2,
- 54
- ],
- [
- -53,
- 86
- ],
- [
- -41,
- 33
- ],
- [
- -26,
- 75
- ],
- [
- -26,
- 79
- ],
- [
- -32,
- 95
- ],
- [
- -28,
- 108
- ]
- ],
- [
- [
- 4383,
- 14700
- ],
- [
- 79,
- 10
- ],
- [
- 88,
- 13
- ],
- [
- -6,
- -24
- ],
- [
- 105,
- -58
- ],
- [
- 159,
- -85
- ],
- [
- 139,
- 1
- ],
- [
- 55,
- 0
- ],
- [
- 0,
- 50
- ],
- [
- 121,
- 0
- ],
- [
- 25,
- -43
- ],
- [
- 36,
- -38
- ],
- [
- 42,
- -52
- ],
- [
- 23,
- -63
- ],
- [
- 17,
- -66
- ],
- [
- 36,
- -36
- ],
- [
- 58,
- -36
- ],
- [
- 44,
- 94
- ],
- [
- 57,
- 3
- ],
- [
- 49,
- -48
- ],
- [
- 35,
- -82
- ],
- [
- 24,
- -70
- ],
- [
- 41,
- -69
- ],
- [
- 15,
- -84
- ],
- [
- 20,
- -56
- ],
- [
- 54,
- -37
- ],
- [
- 50,
- -27
- ],
- [
- 27,
- 4
- ]
- ],
- [
- [
- 5776,
- 13901
- ],
- [
- -27,
- -106
- ],
- [
- -12,
- -86
- ],
- [
- -5,
- -161
- ],
- [
- -7,
- -58
- ],
- [
- 12,
- -66
- ],
- [
- 22,
- -58
- ],
- [
- 14,
- -93
- ],
- [
- 46,
- -90
- ],
- [
- 16,
- -68
- ],
- [
- 27,
- -59
- ],
- [
- 74,
- -32
- ],
- [
- 29,
- -50
- ],
- [
- 61,
- 33
- ],
- [
- 54,
- 13
- ],
- [
- 52,
- 21
- ],
- [
- 44,
- 21
- ],
- [
- 44,
- 49
- ],
- [
- 17,
- 70
- ],
- [
- 5,
- 100
- ],
- [
- 12,
- 36
- ],
- [
- 48,
- 31
- ],
- [
- 73,
- 28
- ],
- [
- 62,
- -4
- ],
- [
- 42,
- 10
- ],
- [
- 17,
- -26
- ],
- [
- -2,
- -57
- ],
- [
- -38,
- -72
- ],
- [
- -16,
- -73
- ],
- [
- 12,
- -21
- ],
- [
- -10,
- -52
- ],
- [
- -17,
- -93
- ],
- [
- -18,
- 31
- ],
- [
- -15,
- -2
- ]
- ],
- [
- [
- 14052,
- 15865
- ],
- [
- 23,
- 7
- ],
- [
- 33,
- 2
- ]
- ],
- [
- [
- 11745,
- 12290
- ],
- [
- 3,
- 37
- ],
- [
- -6,
- 47
- ],
- [
- -26,
- 33
- ],
- [
- -14,
- 69
- ],
- [
- -3,
- 75
- ]
- ],
- [
- [
- 11699,
- 12551
- ],
- [
- 24,
- 22
- ],
- [
- 11,
- 70
- ],
- [
- 22,
- 3
- ],
- [
- 49,
- -33
- ],
- [
- 39,
- 23
- ],
- [
- 27,
- -8
- ],
- [
- 11,
- 27
- ],
- [
- 279,
- 2
- ],
- [
- 16,
- 84
- ],
- [
- -12,
- 15
- ],
- [
- -34,
- 517
- ],
- [
- -33,
- 518
- ],
- [
- 106,
- 2
- ]
- ],
- [
- [
- 12845,
- 13095
- ],
- [
- 0,
- -276
- ],
- [
- -38,
- -80
- ],
- [
- -6,
- -74
- ],
- [
- -62,
- -19
- ],
- [
- -95,
- -10
- ],
- [
- -26,
- -43
- ],
- [
- -44,
- -5
- ]
- ],
- [
- [
- 19526,
- 13247
- ],
- [
- -40,
- -28
- ],
- [
- -40,
- -52
- ],
- [
- -49,
- -5
- ],
- [
- -32,
- -130
- ],
- [
- -30,
- -22
- ],
- [
- 34,
- -105
- ],
- [
- 44,
- -88
- ],
- [
- 29,
- -79
- ],
- [
- -26,
- -104
- ],
- [
- -24,
- -22
- ],
- [
- 17,
- -61
- ],
- [
- 46,
- -95
- ],
- [
- 8,
- -67
- ],
- [
- -1,
- -56
- ],
- [
- 28,
- -109
- ],
- [
- -39,
- -112
- ],
- [
- -33,
- -123
- ]
- ],
- [
- [
- 19418,
- 11989
- ],
- [
- -7,
- 89
- ],
- [
- 21,
- 92
- ],
- [
- -23,
- 71
- ],
- [
- 5,
- 130
- ],
- [
- -28,
- 63
- ],
- [
- -23,
- 143
- ],
- [
- -12,
- 152
- ],
- [
- -30,
- 99
- ],
- [
- -46,
- -60
- ],
- [
- -79,
- -86
- ],
- [
- -40,
- 11
- ],
- [
- -43,
- 28
- ],
- [
- 24,
- 149
- ],
- [
- -14,
- 112
- ],
- [
- -55,
- 139
- ],
- [
- 9,
- 43
- ],
- [
- -41,
- 15
- ],
- [
- -50,
- 98
- ]
- ],
- [
- [
- 13898,
- 15821
- ],
- [
- -15,
- 9
- ],
- [
- -19,
- 40
- ],
- [
- -30,
- 23
- ]
- ],
- [
- [
- 13887,
- 16019
- ],
- [
- 19,
- -21
- ],
- [
- 10,
- -17
- ],
- [
- 23,
- -12
- ],
- [
- 26,
- -25
- ],
- [
- -5,
- -11
- ]
- ],
- [
- [
- 18664,
- 16711
- ],
- [
- 74,
- 21
- ],
- [
- 133,
- 103
- ],
- [
- 106,
- 57
- ],
- [
- 61,
- -37
- ],
- [
- 72,
- -2
- ],
- [
- 47,
- -56
- ],
- [
- 70,
- -4
- ],
- [
- 100,
- -30
- ],
- [
- 68,
- 83
- ],
- [
- -28,
- 71
- ],
- [
- 72,
- 124
- ],
- [
- 78,
- -49
- ],
- [
- 63,
- -14
- ],
- [
- 82,
- -31
- ],
- [
- 14,
- -90
- ],
- [
- 99,
- -51
- ],
- [
- 65,
- 23
- ],
- [
- 89,
- 15
- ],
- [
- 70,
- -15
- ],
- [
- 68,
- -58
- ],
- [
- 42,
- -61
- ],
- [
- 65,
- 1
- ],
- [
- 88,
- -20
- ],
- [
- 64,
- 30
- ],
- [
- 91,
- 20
- ],
- [
- 103,
- 84
- ],
- [
- 41,
- -13
- ],
- [
- 37,
- -40
- ],
- [
- 83,
- 10
- ]
- ],
- [
- [
- 14957,
- 9415
- ],
- [
- 52,
- 10
- ],
- [
- 84,
- -34
- ],
- [
- 18,
- 15
- ],
- [
- 49,
- 3
- ],
- [
- 24,
- 36
- ],
- [
- 42,
- -2
- ],
- [
- 76,
- 47
- ],
- [
- 56,
- 69
- ]
- ],
- [
- [
- 15358,
- 9559
- ],
- [
- 11,
- -53
- ],
- [
- -3,
- -120
- ],
- [
- 9,
- -105
- ],
- [
- 3,
- -188
- ],
- [
- 12,
- -58
- ],
- [
- -21,
- -86
- ],
- [
- -27,
- -83
- ],
- [
- -44,
- -75
- ],
- [
- -64,
- -45
- ],
- [
- -79,
- -59
- ],
- [
- -78,
- -128
- ],
- [
- -27,
- -22
- ],
- [
- -49,
- -86
- ],
- [
- -29,
- -27
- ],
- [
- -5,
- -86
- ],
- [
- 33,
- -91
- ],
- [
- 13,
- -70
- ],
- [
- 1,
- -36
- ],
- [
- 13,
- 6
- ],
- [
- -2,
- -118
- ],
- [
- -12,
- -55
- ],
- [
- 17,
- -21
- ],
- [
- -11,
- -50
- ],
- [
- -29,
- -42
- ],
- [
- -57,
- -41
- ],
- [
- -84,
- -65
- ],
- [
- -31,
- -44
- ],
- [
- 6,
- -51
- ],
- [
- 18,
- -8
- ],
- [
- -6,
- -63
- ]
- ],
- [
- [
- 14836,
- 7589
- ],
- [
- -53,
- 1
- ]
- ],
- [
- [
- 14783,
- 7590
- ],
- [
- -6,
- 53
- ],
- [
- -10,
- 54
- ]
- ],
- [
- [
- 14767,
- 7697
- ],
- [
- -6,
- 43
- ],
- [
- 12,
- 134
- ],
- [
- -18,
- 85
- ],
- [
- -33,
- 169
- ]
- ],
- [
- [
- 14722,
- 8128
- ],
- [
- 73,
- 136
- ],
- [
- 19,
- 86
- ],
- [
- 10,
- 11
- ],
- [
- 8,
- 71
- ],
- [
- -11,
- 35
- ],
- [
- 3,
- 90
- ],
- [
- 13,
- 83
- ],
- [
- 0,
- 152
- ],
- [
- -36,
- 39
- ],
- [
- -33,
- 8
- ],
- [
- -15,
- 30
- ],
- [
- -32,
- 25
- ],
- [
- -59,
- -2
- ],
- [
- -4,
- 45
- ]
- ],
- [
- [
- 14658,
- 8937
- ],
- [
- -7,
- 85
- ],
- [
- 212,
- 99
- ]
- ],
- [
- [
- 14863,
- 9121
- ],
- [
- 40,
- -58
- ],
- [
- 19,
- 11
- ],
- [
- 28,
- -30
- ],
- [
- 4,
- -48
- ],
- [
- -15,
- -56
- ],
- [
- 5,
- -84
- ],
- [
- 46,
- -74
- ],
- [
- 21,
- 83
- ],
- [
- 30,
- 25
- ],
- [
- -6,
- 154
- ],
- [
- -29,
- 87
- ],
- [
- -25,
- 39
- ],
- [
- -24,
- -2
- ],
- [
- -20,
- 156
- ],
- [
- 20,
- 91
- ]
- ],
- [
- [
- 11699,
- 12551
- ],
- [
- -46,
- 82
- ],
- [
- -42,
- 88
- ],
- [
- -46,
- 32
- ],
- [
- -34,
- 35
- ],
- [
- -39,
- -1
- ],
- [
- -34,
- -26
- ],
- [
- -34,
- 10
- ],
- [
- -24,
- -38
- ]
- ],
- [
- [
- 11400,
- 12733
- ],
- [
- -6,
- 65
- ],
- [
- 19,
- 59
- ],
- [
- 9,
- 113
- ],
- [
- -8,
- 118
- ],
- [
- -8,
- 60
- ],
- [
- 7,
- 60
- ],
- [
- -18,
- 57
- ],
- [
- -37,
- 52
- ]
- ],
- [
- [
- 11358,
- 13317
- ],
- [
- 15,
- 40
- ],
- [
- 273,
- -1
- ],
- [
- -13,
- 173
- ],
- [
- 17,
- 62
- ],
- [
- 65,
- 10
- ],
- [
- -2,
- 307
- ],
- [
- 229,
- -6
- ],
- [
- 0,
- 182
- ]
- ],
- [
- [
- 14863,
- 9121
- ],
- [
- -37,
- 31
- ],
- [
- 21,
- 112
- ],
- [
- 22,
- 41
- ],
- [
- -13,
- 100
- ],
- [
- 14,
- 97
- ],
- [
- 12,
- 32
- ],
- [
- -18,
- 102
- ],
- [
- -33,
- 54
- ]
- ],
- [
- [
- 14831,
- 9690
- ],
- [
- 68,
- -23
- ],
- [
- 14,
- -33
- ],
- [
- 24,
- -56
- ],
- [
- 20,
- -163
- ]
- ],
- [
- [
- 20595,
- 11451
- ],
- [
- 54,
- 83
- ],
- [
- 35,
- 94
- ],
- [
- 28,
- 0
- ],
- [
- 36,
- -60
- ],
- [
- 3,
- -52
- ],
- [
- 46,
- -34
- ],
- [
- 58,
- -36
- ],
- [
- -4,
- -47
- ],
- [
- -47,
- -6
- ],
- [
- 12,
- -59
- ],
- [
- -51,
- -40
- ]
- ],
- [
- [
- 20192,
- 11038
- ],
- [
- 51,
- -41
- ],
- [
- 54,
- 22
- ],
- [
- 14,
- 102
- ],
- [
- 30,
- 22
- ],
- [
- 83,
- 26
- ],
- [
- 50,
- 95
- ],
- [
- 34,
- 76
- ]
- ],
- [
- [
- 19668,
- 11544
- ],
- [
- 16,
- -12
- ],
- [
- 41,
- -72
- ],
- [
- 29,
- -80
- ],
- [
- 4,
- -81
- ],
- [
- -7,
- -55
- ],
- [
- 6,
- -41
- ],
- [
- 5,
- -71
- ],
- [
- 25,
- -33
- ],
- [
- 27,
- -106
- ],
- [
- -1,
- -41
- ],
- [
- -49,
- -8
- ],
- [
- -66,
- 89
- ],
- [
- -83,
- 95
- ],
- [
- -8,
- 62
- ],
- [
- -40,
- 80
- ],
- [
- -10,
- 99
- ],
- [
- -25,
- 66
- ],
- [
- 8,
- 87
- ],
- [
- -16,
- 51
- ]
- ],
- [
- [
- 19524,
- 11573
- ],
- [
- 12,
- 21
- ],
- [
- 57,
- -52
- ],
- [
- 6,
- -62
- ],
- [
- 46,
- 14
- ],
- [
- 23,
- 50
- ]
- ],
- [
- [
- 14166,
- 8695
- ],
- [
- 57,
- 27
- ],
- [
- 45,
- -7
- ],
- [
- 28,
- -27
- ],
- [
- 0,
- -10
- ]
- ],
- [
- [
- 13934,
- 7826
- ],
- [
- 0,
- -443
- ],
- [
- -62,
- -62
- ],
- [
- -37,
- -8
- ],
- [
- -44,
- 22
- ],
- [
- -31,
- 9
- ],
- [
- -12,
- 51
- ],
- [
- -28,
- 33
- ],
- [
- -33,
- -59
- ]
- ],
- [
- [
- 13687,
- 7369
- ],
- [
- -52,
- 91
- ],
- [
- -27,
- 87
- ],
- [
- -16,
- 117
- ],
- [
- -17,
- 87
- ],
- [
- -23,
- 185
- ],
- [
- -2,
- 143
- ],
- [
- -9,
- 66
- ],
- [
- -27,
- 49
- ],
- [
- -36,
- 99
- ],
- [
- -36,
- 144
- ],
- [
- -16,
- 75
- ],
- [
- -56,
- 117
- ],
- [
- -5,
- 93
- ]
- ],
- [
- [
- 24104,
- 8268
- ],
- [
- 57,
- -74
- ],
- [
- 36,
- -55
- ],
- [
- -26,
- -29
- ],
- [
- -39,
- 32
- ],
- [
- -50,
- 54
- ],
- [
- -44,
- 64
- ],
- [
- -47,
- 84
- ],
- [
- -9,
- 41
- ],
- [
- 30,
- -2
- ],
- [
- 39,
- -40
- ],
- [
- 30,
- -41
- ],
- [
- 23,
- -34
- ]
- ],
- [
- [
- 13583,
- 13540
- ],
- [
- 17,
- -186
- ],
- [
- 26,
- -32
- ],
- [
- 1,
- -38
- ],
- [
- 29,
- -41
- ],
- [
- -15,
- -52
- ],
- [
- -27,
- -243
- ],
- [
- -4,
- -156
- ],
- [
- -89,
- -113
- ],
- [
- -30,
- -158
- ],
- [
- 29,
- -45
- ],
- [
- 0,
- -77
- ],
- [
- 45,
- -3
- ],
- [
- -7,
- -56
- ]
- ],
- [
- [
- 13536,
- 12295
- ],
- [
- -13,
- -3
- ],
- [
- -47,
- 132
- ],
- [
- -16,
- 4
- ],
- [
- -55,
- -67
- ],
- [
- -54,
- 35
- ],
- [
- -37,
- 7
- ],
- [
- -21,
- -17
- ],
- [
- -40,
- 4
- ],
- [
- -42,
- -51
- ],
- [
- -35,
- -3
- ],
- [
- -84,
- 62
- ],
- [
- -33,
- -29
- ],
- [
- -36,
- 2
- ],
- [
- -26,
- 45
- ],
- [
- -70,
- 45
- ],
- [
- -75,
- -15
- ],
- [
- -18,
- -25
- ],
- [
- -10,
- -69
- ],
- [
- -20,
- -49
- ],
- [
- -5,
- -107
- ]
- ],
- [
- [
- 13140,
- 11370
- ],
- [
- -72,
- -43
- ],
- [
- -27,
- 6
- ],
- [
- -27,
- -27
- ],
- [
- -55,
- 3
- ],
- [
- -38,
- 75
- ],
- [
- -23,
- 86
- ],
- [
- -49,
- 79
- ],
- [
- -52,
- -1
- ],
- [
- -62,
- 0
- ]
- ],
- [
- [
- 6573,
- 12127
- ],
- [
- -24,
- 38
- ],
- [
- -33,
- 49
- ],
- [
- -15,
- 40
- ],
- [
- -30,
- 38
- ],
- [
- -35,
- 54
- ],
- [
- 8,
- 19
- ],
- [
- 12,
- -19
- ],
- [
- 5,
- 9
- ]
- ],
- [
- [
- 6751,
- 12596
- ],
- [
- -6,
- -11
- ],
- [
- -3,
- -27
- ],
- [
- 7,
- -44
- ],
- [
- -16,
- -41
- ],
- [
- -8,
- -48
- ],
- [
- -2,
- -53
- ],
- [
- 4,
- -31
- ],
- [
- 2,
- -54
- ],
- [
- -11,
- -12
- ],
- [
- -6,
- -51
- ],
- [
- 4,
- -32
- ],
- [
- -14,
- -30
- ],
- [
- 3,
- -33
- ],
- [
- 11,
- -19
- ]
- ],
- [
- [
- 12779,
- 16957
- ],
- [
- 36,
- 33
- ],
- [
- 61,
- 177
- ],
- [
- 95,
- 50
- ],
- [
- 58,
- -4
- ]
- ],
- [
- [
- 13987,
- 19088
- ],
- [
- -44,
- -5
- ],
- [
- -10,
- -79
- ],
- [
- -131,
- 19
- ],
- [
- -19,
- -67
- ],
- [
- -67,
- 1
- ],
- [
- -46,
- -86
- ],
- [
- -69,
- -133
- ],
- [
- -109,
- -168
- ],
- [
- 26,
- -41
- ],
- [
- -24,
- -48
- ],
- [
- -70,
- 2
- ],
- [
- -45,
- -112
- ],
- [
- 4,
- -160
- ],
- [
- 45,
- -60
- ],
- [
- -23,
- -142
- ],
- [
- -58,
- -82
- ],
- [
- -31,
- -69
- ]
- ],
- [
- [
- 13316,
- 17858
- ],
- [
- -47,
- 74
- ],
- [
- -137,
- -139
- ],
- [
- -93,
- -28
- ],
- [
- -97,
- 61
- ],
- [
- -24,
- 129
- ],
- [
- -23,
- 277
- ],
- [
- 65,
- 77
- ],
- [
- 184,
- 101
- ],
- [
- 137,
- 124
- ],
- [
- 128,
- 167
- ],
- [
- 167,
- 231
- ],
- [
- 117,
- 91
- ],
- [
- 192,
- 150
- ],
- [
- 153,
- 53
- ],
- [
- 114,
- -7
- ],
- [
- 107,
- 100
- ],
- [
- 127,
- -6
- ],
- [
- 125,
- 24
- ],
- [
- 218,
- -88
- ],
- [
- -90,
- -32
- ],
- [
- 77,
- -75
- ]
- ],
- [
- [
- 14716,
- 19142
- ],
- [
- -119,
- -48
- ],
- [
- -56,
- -11
- ]
- ],
- [
- [
- 14271,
- 20137
- ],
- [
- -156,
- -49
- ],
- [
- -123,
- 28
- ],
- [
- 48,
- 31
- ],
- [
- -42,
- 38
- ],
- [
- 145,
- 24
- ],
- [
- 27,
- -45
- ],
- [
- 101,
- -27
- ]
- ],
- [
- [
- 13820,
- 20359
- ],
- [
- 229,
- -90
- ],
- [
- -175,
- -47
- ],
- [
- -39,
- -88
- ],
- [
- -61,
- -23
- ],
- [
- -33,
- -99
- ],
- [
- -84,
- -5
- ],
- [
- -150,
- 73
- ],
- [
- 63,
- 43
- ],
- [
- -104,
- 35
- ],
- [
- -136,
- 101
- ],
- [
- -54,
- 94
- ],
- [
- 190,
- 43
- ],
- [
- 38,
- -42
- ],
- [
- 99,
- 2
- ],
- [
- 27,
- 41
- ],
- [
- 102,
- 4
- ],
- [
- 88,
- -42
- ]
- ],
- [
- [
- 14321,
- 20444
- ],
- [
- 137,
- -43
- ],
- [
- -103,
- -64
- ],
- [
- -203,
- -14
- ],
- [
- -205,
- 20
- ],
- [
- -12,
- 33
- ],
- [
- -101,
- 2
- ],
- [
- -76,
- 55
- ],
- [
- 215,
- 33
- ],
- [
- 102,
- -28
- ],
- [
- 70,
- 36
- ],
- [
- 176,
- -30
- ]
- ],
- [
- [
- 24608,
- 5888
- ],
- [
- 16,
- -49
- ],
- [
- 50,
- 48
- ],
- [
- 20,
- -50
- ],
- [
- 0,
- -51
- ],
- [
- -26,
- -55
- ],
- [
- -45,
- -89
- ],
- [
- -36,
- -48
- ],
- [
- 26,
- -58
- ],
- [
- -54,
- -1
- ],
- [
- -60,
- -46
- ],
- [
- -18,
- -78
- ],
- [
- -40,
- -121
- ],
- [
- -55,
- -54
- ],
- [
- -35,
- -34
- ],
- [
- -64,
- 2
- ],
- [
- -45,
- 40
- ],
- [
- -76,
- 8
- ],
- [
- -11,
- 44
- ],
- [
- 37,
- 89
- ],
- [
- 88,
- 119
- ],
- [
- 45,
- 22
- ],
- [
- 50,
- 46
- ],
- [
- 60,
- 63
- ],
- [
- 41,
- 62
- ],
- [
- 31,
- 89
- ],
- [
- 27,
- 31
- ],
- [
- 10,
- 67
- ],
- [
- 49,
- 55
- ],
- [
- 15,
- -51
- ]
- ],
- [
- [
- 24719,
- 6460
- ],
- [
- 51,
- -127
- ],
- [
- 1,
- 82
- ],
- [
- 32,
- -33
- ],
- [
- 10,
- -90
- ],
- [
- 56,
- -39
- ],
- [
- 47,
- -10
- ],
- [
- 40,
- 46
- ],
- [
- 36,
- -14
- ],
- [
- -17,
- -107
- ],
- [
- -21,
- -70
- ],
- [
- -54,
- 3
- ],
- [
- -18,
- -37
- ],
- [
- 6,
- -51
- ],
- [
- -10,
- -22
- ],
- [
- -26,
- -65
- ],
- [
- -35,
- -82
- ],
- [
- -54,
- -48
- ],
- [
- -12,
- 31
- ],
- [
- -29,
- 18
- ],
- [
- 40,
- 98
- ],
- [
- -23,
- 66
- ],
- [
- -75,
- 48
- ],
- [
- 2,
- 44
- ],
- [
- 51,
- 42
- ],
- [
- 12,
- 92
- ],
- [
- -4,
- 78
- ],
- [
- -28,
- 80
- ],
- [
- 2,
- 21
- ],
- [
- -33,
- 50
- ],
- [
- -55,
- 106
- ],
- [
- -29,
- 85
- ],
- [
- 26,
- 9
- ],
- [
- 37,
- -66
- ],
- [
- 55,
- -32
- ],
- [
- 19,
- -106
- ]
- ],
- [
- [
- 16456,
- 13923
- ],
- [
- 20,
- 41
- ],
- [
- 9,
- -11
- ],
- [
- -7,
- -49
- ],
- [
- -9,
- -22
- ]
- ],
- [
- [
- 16479,
- 13787
- ],
- [
- 31,
- -82
- ],
- [
- 39,
- -43
- ],
- [
- 51,
- -16
- ],
- [
- 41,
- -22
- ],
- [
- 32,
- -68
- ],
- [
- 19,
- -40
- ],
- [
- 25,
- -15
- ],
- [
- -1,
- -27
- ],
- [
- -25,
- -72
- ],
- [
- -11,
- -33
- ],
- [
- -29,
- -39
- ],
- [
- -26,
- -82
- ],
- [
- -32,
- 6
- ],
- [
- -15,
- -28
- ],
- [
- -11,
- -61
- ],
- [
- 9,
- -80
- ],
- [
- -7,
- -15
- ],
- [
- -32,
- 0
- ],
- [
- -43,
- -44
- ],
- [
- -7,
- -59
- ],
- [
- -16,
- -25
- ],
- [
- -43,
- 1
- ],
- [
- -28,
- -30
- ],
- [
- 1,
- -49
- ],
- [
- -34,
- -33
- ],
- [
- -39,
- 11
- ],
- [
- -46,
- -40
- ],
- [
- -32,
- -7
- ]
- ],
- [
- [
- 16250,
- 12795
- ],
- [
- -23,
- 84
- ],
- [
- -55,
- 198
- ]
- ],
- [
- [
- 16172,
- 13077
- ],
- [
- 209,
- 120
- ],
- [
- 47,
- 240
- ],
- [
- -32,
- 84
- ]
- ],
- [
- [
- 17300,
- 13639
- ],
- [
- -51,
- 31
- ],
- [
- -21,
- 86
- ],
- [
- -54,
- 91
- ],
- [
- -128,
- -22
- ],
- [
- -113,
- -2
- ],
- [
- -99,
- -17
- ]
- ],
- [
- [
- 7119,
- 11664
- ],
- [
- -24,
- 34
- ],
- [
- -15,
- 65
- ],
- [
- 18,
- 32
- ],
- [
- -18,
- 8
- ],
- [
- -13,
- 40
- ],
- [
- -35,
- 33
- ],
- [
- -30,
- -7
- ],
- [
- -14,
- -42
- ],
- [
- -29,
- -30
- ],
- [
- -15,
- -4
- ],
- [
- -7,
- -25
- ],
- [
- 34,
- -65
- ],
- [
- -19,
- -16
- ],
- [
- -11,
- -17
- ],
- [
- -32,
- -7
- ],
- [
- -12,
- 72
- ],
- [
- -9,
- -20
- ],
- [
- -23,
- 7
- ],
- [
- -14,
- 48
- ],
- [
- -29,
- 8
- ],
- [
- -18,
- 14
- ],
- [
- -30,
- 0
- ],
- [
- -2,
- -26
- ],
- [
- -8,
- 18
- ]
- ],
- [
- [
- 6793,
- 11945
- ],
- [
- 25,
- -43
- ],
- [
- -1,
- -26
- ],
- [
- 28,
- -5
- ],
- [
- 6,
- 10
- ],
- [
- 20,
- -30
- ],
- [
- 34,
- 9
- ],
- [
- 29,
- 30
- ],
- [
- 43,
- 24
- ],
- [
- 24,
- 36
- ],
- [
- 38,
- -7
- ],
- [
- -3,
- -12
- ],
- [
- 39,
- -4
- ],
- [
- 31,
- -20
- ],
- [
- 23,
- -36
- ],
- [
- 26,
- -34
- ]
- ],
- [
- [
- 7642,
- 8596
- ],
- [
- -70,
- 69
- ],
- [
- -6,
- 49
- ],
- [
- -138,
- 121
- ],
- [
- -125,
- 131
- ],
- [
- -54,
- 74
- ],
- [
- -29,
- 99
- ],
- [
- 12,
- 34
- ],
- [
- -59,
- 158
- ],
- [
- -69,
- 221
- ],
- [
- -66,
- 239
- ],
- [
- -29,
- 55
- ],
- [
- -21,
- 88
- ],
- [
- -55,
- 78
- ],
- [
- -49,
- 49
- ],
- [
- 22,
- 54
- ],
- [
- -34,
- 114
- ],
- [
- 22,
- 84
- ],
- [
- 56,
- 76
- ]
- ],
- [
- [
- 21357,
- 11807
- ],
- [
- 7,
- -80
- ],
- [
- 4,
- -67
- ],
- [
- -24,
- -110
- ],
- [
- -25,
- 122
- ],
- [
- -33,
- -61
- ],
- [
- 23,
- -88
- ],
- [
- -20,
- -56
- ],
- [
- -82,
- 69
- ],
- [
- -20,
- 87
- ],
- [
- 21,
- 57
- ],
- [
- -44,
- 57
- ],
- [
- -22,
- -50
- ],
- [
- -33,
- 5
- ],
- [
- -51,
- -67
- ],
- [
- -12,
- 35
- ],
- [
- 28,
- 101
- ],
- [
- 44,
- 34
- ],
- [
- 38,
- 45
- ],
- [
- 24,
- -54
- ],
- [
- 53,
- 33
- ],
- [
- 12,
- 53
- ],
- [
- 49,
- 3
- ],
- [
- -4,
- 93
- ],
- [
- 56,
- -57
- ],
- [
- 6,
- -60
- ],
- [
- 5,
- -44
- ]
- ],
- [
- [
- 21190,
- 12030
- ],
- [
- -25,
- -39
- ],
- [
- -22,
- -76
- ],
- [
- -22,
- -35
- ],
- [
- -43,
- 82
- ],
- [
- 15,
- 33
- ],
- [
- 17,
- 33
- ],
- [
- 8,
- 75
- ],
- [
- 38,
- 7
- ],
- [
- -11,
- -81
- ],
- [
- 52,
- 116
- ],
- [
- -7,
- -115
- ]
- ],
- [
- [
- 20808,
- 11915
- ],
- [
- -92,
- -114
- ],
- [
- 34,
- 84
- ],
- [
- 50,
- 74
- ],
- [
- 42,
- 83
- ],
- [
- 36,
- 119
- ],
- [
- 13,
- -98
- ],
- [
- -46,
- -66
- ],
- [
- -37,
- -82
- ]
- ],
- [
- [
- 21044,
- 12224
- ],
- [
- 42,
- -37
- ],
- [
- 44,
- 0
- ],
- [
- -1,
- -50
- ],
- [
- -33,
- -51
- ],
- [
- -44,
- -36
- ],
- [
- -2,
- 56
- ],
- [
- 5,
- 61
- ],
- [
- -11,
- 57
- ]
- ],
- [
- [
- 21296,
- 12256
- ],
- [
- 20,
- -134
- ],
- [
- -54,
- 32
- ],
- [
- 1,
- -40
- ],
- [
- 17,
- -74
- ],
- [
- -33,
- -27
- ],
- [
- -3,
- 84
- ],
- [
- -21,
- 7
- ],
- [
- -11,
- 72
- ],
- [
- 41,
- -9
- ],
- [
- 0,
- 45
- ],
- [
- -43,
- 92
- ],
- [
- 67,
- -3
- ],
- [
- 19,
- -45
- ]
- ],
- [
- [
- 21019,
- 12365
- ],
- [
- -19,
- -104
- ],
- [
- -29,
- 60
- ],
- [
- -36,
- 92
- ],
- [
- 60,
- -5
- ],
- [
- 24,
- -43
- ]
- ],
- [
- [
- 21005,
- 13017
- ],
- [
- 43,
- -34
- ],
- [
- 21,
- 31
- ],
- [
- 6,
- -30
- ],
- [
- -11,
- -50
- ],
- [
- 24,
- -86
- ],
- [
- -18,
- -100
- ],
- [
- -42,
- -40
- ],
- [
- -11,
- -96
- ],
- [
- 16,
- -96
- ],
- [
- 37,
- -13
- ],
- [
- 31,
- 14
- ],
- [
- 87,
- -66
- ],
- [
- -7,
- -66
- ],
- [
- 23,
- -29
- ],
- [
- -7,
- -55
- ],
- [
- -55,
- 59
- ],
- [
- -25,
- 63
- ],
- [
- -18,
- -44
- ],
- [
- -45,
- 72
- ],
- [
- -63,
- -18
- ],
- [
- -35,
- 27
- ],
- [
- 4,
- 49
- ],
- [
- 22,
- 31
- ],
- [
- -21,
- 28
- ],
- [
- -9,
- -44
- ],
- [
- -35,
- 69
- ],
- [
- -10,
- 52
- ],
- [
- -3,
- 115
- ],
- [
- 28,
- -39
- ],
- [
- 8,
- 188
- ],
- [
- 22,
- 108
- ],
- [
- 43,
- 0
- ]
- ],
- [
- [
- 22376,
- 10485
- ],
- [
- 121,
- -82
- ],
- [
- 129,
- -69
- ],
- [
- 48,
- -62
- ],
- [
- 39,
- -60
- ],
- [
- 11,
- -71
- ],
- [
- 116,
- -74
- ],
- [
- 17,
- -63
- ],
- [
- -64,
- -13
- ],
- [
- 15,
- -80
- ],
- [
- 62,
- -79
- ],
- [
- 46,
- -127
- ],
- [
- 39,
- 4
- ],
- [
- -2,
- -53
- ],
- [
- 53,
- -21
- ],
- [
- -20,
- -22
- ],
- [
- 74,
- -51
- ],
- [
- -8,
- -34
- ],
- [
- -46,
- -9
- ],
- [
- -17,
- 31
- ],
- [
- -60,
- 14
- ],
- [
- -71,
- 18
- ],
- [
- -54,
- 76
- ],
- [
- -39,
- 66
- ],
- [
- -37,
- 105
- ],
- [
- -91,
- 53
- ],
- [
- -59,
- -34
- ],
- [
- -42,
- -40
- ],
- [
- 9,
- -88
- ],
- [
- -55,
- -42
- ],
- [
- -39,
- 20
- ],
- [
- -72,
- 5
- ]
- ],
- [
- [
- 23414,
- 9979
- ],
- [
- -20,
- -12
- ],
- [
- -30,
- 46
- ],
- [
- -31,
- 76
- ],
- [
- -15,
- 92
- ],
- [
- 10,
- 11
- ],
- [
- 8,
- -35
- ],
- [
- 21,
- -28
- ],
- [
- 33,
- -76
- ],
- [
- 33,
- -40
- ],
- [
- -9,
- -34
- ]
- ],
- [
- [
- 23142,
- 10140
- ],
- [
- -37,
- -10
- ],
- [
- -11,
- -34
- ],
- [
- -38,
- -29
- ],
- [
- -35,
- -28
- ],
- [
- -37,
- 0
- ],
- [
- -58,
- 35
- ],
- [
- -39,
- 34
- ],
- [
- 5,
- 37
- ],
- [
- 63,
- -18
- ],
- [
- 38,
- 10
- ],
- [
- 10,
- 57
- ],
- [
- 10,
- 3
- ],
- [
- 7,
- -64
- ],
- [
- 40,
- 10
- ],
- [
- 20,
- 41
- ],
- [
- 39,
- 42
- ],
- [
- -8,
- 71
- ],
- [
- 42,
- 2
- ],
- [
- 14,
- -19
- ],
- [
- -2,
- -67
- ],
- [
- -23,
- -73
- ]
- ],
- [
- [
- 23223,
- 10257
- ],
- [
- -22,
- -32
- ],
- [
- -13,
- 71
- ],
- [
- -17,
- 47
- ],
- [
- -31,
- 39
- ],
- [
- -40,
- 51
- ],
- [
- -50,
- 35
- ],
- [
- 19,
- 29
- ],
- [
- 38,
- -33
- ],
- [
- 24,
- -27
- ],
- [
- 29,
- -29
- ],
- [
- 28,
- -50
- ],
- [
- 26,
- -38
- ],
- [
- 9,
- -63
- ]
- ],
- [
- [
- 14188,
- 16985
- ],
- [
- 35,
- -105
- ],
- [
- -8,
- -33
- ],
- [
- -34,
- -14
- ],
- [
- -64,
- -100
- ],
- [
- 18,
- -54
- ],
- [
- -15,
- 7
- ]
- ],
- [
- [
- 14120,
- 16686
- ],
- [
- -66,
- 46
- ],
- [
- -50,
- -17
- ],
- [
- -33,
- 12
- ],
- [
- -42,
- -25
- ],
- [
- -35,
- 42
- ],
- [
- -28,
- -16
- ],
- [
- -4,
- 7
- ]
- ],
- [
- [
- 13532,
- 17246
- ],
- [
- 47,
- 36
- ],
- [
- 109,
- 55
- ],
- [
- 88,
- 41
- ],
- [
- 70,
- -21
- ],
- [
- 5,
- -29
- ],
- [
- 67,
- -1
- ]
- ],
- [
- [
- 13918,
- 17327
- ],
- [
- 86,
- -14
- ],
- [
- 128,
- 2
- ]
- ],
- [
- [
- 7927,
- 13018
- ],
- [
- 36,
- -10
- ],
- [
- 12,
- -24
- ],
- [
- -18,
- -30
- ],
- [
- -52,
- 0
- ],
- [
- -41,
- -4
- ],
- [
- -4,
- 52
- ],
- [
- 10,
- 17
- ],
- [
- 57,
- -1
- ]
- ],
- [
- [
- 21654,
- 15883
- ],
- [
- 10,
- -21
- ]
- ],
- [
- [
- 21664,
- 15862
- ],
- [
- -27,
- 7
- ],
- [
- -30,
- -40
- ],
- [
- -21,
- -41
- ],
- [
- 3,
- -86
- ],
- [
- -36,
- -27
- ],
- [
- -12,
- -21
- ],
- [
- -27,
- -35
- ],
- [
- -46,
- -20
- ],
- [
- -30,
- -32
- ],
- [
- -3,
- -52
- ],
- [
- -8,
- -13
- ],
- [
- 28,
- -20
- ],
- [
- 40,
- -53
- ]
- ],
- [
- [
- 21343,
- 15326
- ],
- [
- -34,
- 23
- ],
- [
- -8,
- -23
- ],
- [
- -21,
- -10
- ],
- [
- -2,
- 23
- ],
- [
- -18,
- 11
- ],
- [
- -19,
- 19
- ],
- [
- 19,
- 53
- ],
- [
- 17,
- 14
- ],
- [
- -7,
- 22
- ],
- [
- 18,
- 65
- ],
- [
- -5,
- 19
- ],
- [
- -40,
- 13
- ],
- [
- -33,
- 32
- ]
- ],
- [
- [
- 12028,
- 15248
- ],
- [
- -28,
- -31
- ],
- [
- -37,
- 17
- ],
- [
- -36,
- -14
- ],
- [
- 11,
- 94
- ],
- [
- -7,
- 74
- ],
- [
- -31,
- 11
- ],
- [
- -17,
- 45
- ],
- [
- 6,
- 79
- ],
- [
- 28,
- 44
- ],
- [
- 5,
- 48
- ],
- [
- 14,
- 72
- ],
- [
- -1,
- 51
- ],
- [
- -14,
- 43
- ],
- [
- -3,
- 41
- ]
- ],
- [
- [
- 16089,
- 13767
- ],
- [
- -4,
- 87
- ],
- [
- 19,
- 63
- ],
- [
- 19,
- 13
- ],
- [
- 21,
- -37
- ],
- [
- 1,
- -71
- ],
- [
- -15,
- -70
- ]
- ],
- [
- [
- 16130,
- 13752
- ],
- [
- -20,
- -9
- ],
- [
- -21,
- 24
- ]
- ],
- [
- [
- 14127,
- 16104
- ],
- [
- -13,
- 21
- ],
- [
- 16,
- 20
- ],
- [
- -17,
- 15
- ],
- [
- -22,
- -27
- ],
- [
- -40,
- 35
- ],
- [
- -6,
- 50
- ],
- [
- -42,
- 28
- ],
- [
- -8,
- 38
- ],
- [
- -38,
- 47
- ]
- ],
- [
- [
- 14131,
- 16542
- ],
- [
- 30,
- 25
- ],
- [
- 43,
- -13
- ],
- [
- 45,
- 0
- ],
- [
- 32,
- -30
- ],
- [
- 24,
- 19
- ],
- [
- 51,
- 11
- ],
- [
- 18,
- 28
- ],
- [
- 29,
- 0
- ]
- ],
- [
- [
- 14516,
- 16254
- ],
- [
- 31,
- -22
- ],
- [
- 32,
- 20
- ],
- [
- 32,
- -21
- ]
- ],
- [
- [
- 14611,
- 16231
- ],
- [
- 2,
- -31
- ],
- [
- -34,
- -26
- ],
- [
- -21,
- 11
- ],
- [
- -20,
- -144
- ]
- ],
- [
- [
- 15333,
- 16008
- ],
- [
- -89,
- 101
- ],
- [
- -80,
- 46
- ],
- [
- -60,
- 70
- ],
- [
- 51,
- 19
- ],
- [
- 58,
- 101
- ],
- [
- -39,
- 47
- ],
- [
- 102,
- 49
- ],
- [
- -1,
- 26
- ],
- [
- -63,
- -19
- ]
- ],
- [
- [
- 15212,
- 16448
- ],
- [
- 2,
- 53
- ],
- [
- 36,
- 34
- ],
- [
- 68,
- 9
- ],
- [
- 11,
- 40
- ],
- [
- -16,
- 66
- ],
- [
- 28,
- 63
- ],
- [
- 0,
- 35
- ],
- [
- -103,
- 39
- ],
- [
- -41,
- -1
- ],
- [
- -43,
- 56
- ],
- [
- -53,
- -19
- ],
- [
- -89,
- 42
- ],
- [
- 2,
- 23
- ],
- [
- -25,
- 53
- ],
- [
- -56,
- 5
- ],
- [
- -6,
- 38
- ],
- [
- 18,
- 24
- ],
- [
- -45,
- 68
- ],
- [
- -72,
- -12
- ],
- [
- -21,
- 6
- ],
- [
- -18,
- -27
- ],
- [
- -26,
- 5
- ]
- ],
- [
- [
- 14498,
- 17932
- ],
- [
- 79,
- 67
- ],
- [
- -73,
- 57
- ]
- ],
- [
- [
- 14716,
- 19142
- ],
- [
- 71,
- 42
- ],
- [
- 115,
- -73
- ],
- [
- 191,
- -28
- ],
- [
- 263,
- -136
- ],
- [
- 54,
- -57
- ],
- [
- 4,
- -80
- ],
- [
- -77,
- -63
- ],
- [
- -114,
- -32
- ],
- [
- -311,
- 91
- ],
- [
- -51,
- -15
- ],
- [
- 113,
- -88
- ],
- [
- 5,
- -56
- ],
- [
- 4,
- -122
- ],
- [
- 90,
- -37
- ],
- [
- 55,
- -31
- ],
- [
- 9,
- 58
- ],
- [
- -42,
- 52
- ],
- [
- 44,
- 45
- ],
- [
- 168,
- -74
- ],
- [
- 59,
- 29
- ],
- [
- -47,
- 88
- ],
- [
- 163,
- 117
- ],
- [
- 64,
- -7
- ],
- [
- 65,
- -42
- ],
- [
- 41,
- 83
- ],
- [
- -58,
- 71
- ],
- [
- 34,
- 72
- ],
- [
- -51,
- 75
- ],
- [
- 195,
- -39
- ],
- [
- 39,
- -67
- ],
- [
- -88,
- -15
- ],
- [
- 1,
- -67
- ],
- [
- 54,
- -41
- ],
- [
- 108,
- 26
- ],
- [
- 17,
- 77
- ],
- [
- 146,
- 57
- ],
- [
- 243,
- 103
- ],
- [
- 53,
- -6
- ],
- [
- -69,
- -73
- ],
- [
- 86,
- -12
- ],
- [
- 50,
- 41
- ],
- [
- 131,
- 3
- ],
- [
- 103,
- 50
- ],
- [
- 80,
- -73
- ],
- [
- 79,
- 80
- ],
- [
- -73,
- 69
- ],
- [
- 36,
- 40
- ],
- [
- 206,
- -36
- ],
- [
- 97,
- -38
- ],
- [
- 252,
- -137
- ],
- [
- 47,
- 63
- ],
- [
- -71,
- 63
- ],
- [
- -2,
- 26
- ],
- [
- -84,
- 12
- ],
- [
- 23,
- 56
- ],
- [
- -37,
- 94
- ],
- [
- -2,
- 38
- ],
- [
- 128,
- 109
- ],
- [
- 46,
- 109
- ],
- [
- 52,
- 24
- ],
- [
- 184,
- -32
- ],
- [
- 15,
- -67
- ],
- [
- -66,
- -97
- ],
- [
- 43,
- -38
- ],
- [
- 23,
- -84
- ],
- [
- -16,
- -164
- ],
- [
- 77,
- -74
- ],
- [
- -30,
- -80
- ],
- [
- -137,
- -170
- ],
- [
- 80,
- -18
- ],
- [
- 28,
- 43
- ],
- [
- 76,
- 31
- ],
- [
- 19,
- 59
- ],
- [
- 60,
- 57
- ],
- [
- -40,
- 69
- ],
- [
- 32,
- 79
- ],
- [
- -76,
- 10
- ],
- [
- -17,
- 66
- ],
- [
- 56,
- 121
- ],
- [
- -91,
- 98
- ],
- [
- 125,
- 80
- ],
- [
- -16,
- 86
- ],
- [
- 35,
- 3
- ],
- [
- 36,
- -67
- ],
- [
- -27,
- -116
- ],
- [
- 74,
- -22
- ],
- [
- -31,
- 87
- ],
- [
- 116,
- 47
- ],
- [
- 145,
- 6
- ],
- [
- 129,
- -68
- ],
- [
- -62,
- 100
- ],
- [
- -7,
- 128
- ],
- [
- 121,
- 24
- ],
- [
- 168,
- -5
- ],
- [
- 151,
- 15
- ],
- [
- -57,
- 63
- ],
- [
- 81,
- 79
- ],
- [
- 80,
- 3
- ],
- [
- 135,
- 60
- ],
- [
- 184,
- 16
- ],
- [
- 24,
- 32
- ],
- [
- 183,
- 12
- ],
- [
- 57,
- -27
- ],
- [
- 156,
- 63
- ],
- [
- 128,
- -2
- ],
- [
- 20,
- 52
- ],
- [
- 66,
- 51
- ],
- [
- 165,
- 50
- ],
- [
- 119,
- -39
- ],
- [
- -95,
- -30
- ],
- [
- 158,
- -18
- ],
- [
- 19,
- -60
- ],
- [
- 64,
- 30
- ],
- [
- 204,
- -2
- ],
- [
- 157,
- -59
- ],
- [
- 56,
- -44
- ],
- [
- -18,
- -63
- ],
- [
- -77,
- -35
- ],
- [
- -183,
- -67
- ],
- [
- -52,
- -36
- ],
- [
- 86,
- -16
- ],
- [
- 103,
- -31
- ],
- [
- 63,
- 23
- ],
- [
- 35,
- -77
- ],
- [
- 31,
- 31
- ],
- [
- 112,
- 19
- ],
- [
- 223,
- -20
- ],
- [
- 17,
- -56
- ],
- [
- 292,
- -18
- ],
- [
- 4,
- 92
- ],
- [
- 148,
- -21
- ],
- [
- 111,
- 1
- ],
- [
- 112,
- -63
- ],
- [
- 32,
- -77
- ],
- [
- -41,
- -50
- ],
- [
- 88,
- -95
- ],
- [
- 109,
- -49
- ],
- [
- 68,
- 126
- ],
- [
- 111,
- -54
- ],
- [
- 119,
- 33
- ],
- [
- 135,
- -37
- ],
- [
- 52,
- 33
- ],
- [
- 114,
- -16
- ],
- [
- -51,
- 111
- ],
- [
- 92,
- 52
- ],
- [
- 630,
- -78
- ],
- [
- 59,
- -71
- ],
- [
- 183,
- -92
- ],
- [
- 281,
- 23
- ],
- [
- 139,
- -20
- ],
- [
- 58,
- -50
- ],
- [
- -8,
- -87
- ],
- [
- 85,
- -34
- ],
- [
- 94,
- 24
- ],
- [
- 123,
- 3
- ],
- [
- 132,
- -23
- ],
- [
- 132,
- 13
- ],
- [
- 121,
- -107
- ],
- [
- 87,
- 39
- ],
- [
- -57,
- 76
- ],
- [
- 32,
- 54
- ],
- [
- 222,
- -34
- ],
- [
- 145,
- 7
- ],
- [
- 200,
- -57
- ],
- [
- 98,
- -52
- ],
- [
- 0,
- -478
- ],
- [
- -1,
- -1
- ],
- [
- -89,
- -53
- ],
- [
- -90,
- 9
- ],
- [
- 62,
- -64
- ],
- [
- 42,
- -99
- ],
- [
- 32,
- -32
- ],
- [
- 8,
- -49
- ],
- [
- -18,
- -32
- ],
- [
- -130,
- 26
- ],
- [
- -195,
- -90
- ],
- [
- -62,
- -14
- ],
- [
- -106,
- -85
- ],
- [
- -101,
- -73
- ],
- [
- -26,
- -55
- ],
- [
- -100,
- 83
- ],
- [
- -181,
- -94
- ],
- [
- -32,
- 45
- ],
- [
- -67,
- -52
- ],
- [
- -93,
- 17
- ],
- [
- -23,
- -79
- ],
- [
- -84,
- -116
- ],
- [
- 3,
- -49
- ],
- [
- 79,
- -27
- ],
- [
- -9,
- -174
- ],
- [
- -65,
- -5
- ],
- [
- -30,
- -100
- ],
- [
- 29,
- -52
- ],
- [
- -121,
- -61
- ],
- [
- -25,
- -137
- ],
- [
- -104,
- -29
- ],
- [
- -20,
- -122
- ],
- [
- -101,
- -112
- ],
- [
- -26,
- 83
- ],
- [
- -30,
- 175
- ],
- [
- -38,
- 266
- ],
- [
- 33,
- 167
- ],
- [
- 59,
- 71
- ],
- [
- 3,
- 56
- ],
- [
- 109,
- 27
- ],
- [
- 124,
- 151
- ],
- [
- 120,
- 123
- ],
- [
- 126,
- 96
- ],
- [
- 56,
- 169
- ],
- [
- -85,
- -10
- ],
- [
- -42,
- -99
- ],
- [
- -177,
- -131
- ],
- [
- -57,
- 147
- ],
- [
- -180,
- -41
- ],
- [
- -174,
- -201
- ],
- [
- 57,
- -73
- ],
- [
- -155,
- -32
- ],
- [
- -108,
- -12
- ],
- [
- 5,
- 87
- ],
- [
- -108,
- 18
- ],
- [
- -87,
- -59
- ],
- [
- -213,
- 21
- ],
- [
- -229,
- -36
- ],
- [
- -226,
- -234
- ],
- [
- -267,
- -283
- ],
- [
- 110,
- -15
- ],
- [
- 34,
- -75
- ],
- [
- 68,
- -27
- ],
- [
- 44,
- 60
- ],
- [
- 77,
- -8
- ],
- [
- 100,
- -132
- ],
- [
- 3,
- -102
- ],
- [
- -55,
- -120
- ],
- [
- -6,
- -143
- ],
- [
- -31,
- -192
- ],
- [
- -105,
- -173
- ],
- [
- -23,
- -83
- ],
- [
- -95,
- -140
- ],
- [
- -94,
- -138
- ],
- [
- -45,
- -71
- ],
- [
- -93,
- -71
- ],
- [
- -44,
- -1
- ],
- [
- -44,
- 58
- ],
- [
- -93,
- -88
- ],
- [
- -11,
- -40
- ]
- ],
- [
- [
- 15970,
- 16364
- ],
- [
- -32,
- -71
- ],
- [
- -67,
- -20
- ],
- [
- -69,
- -124
- ],
- [
- 63,
- -114
- ],
- [
- -7,
- -81
- ],
- [
- 76,
- -141
- ]
- ],
- [
- [
- 13918,
- 17327
- ],
- [
- 16,
- 52
- ],
- [
- 96,
- 39
- ]
- ],
- [
- [
- 14878,
- 16312
- ],
- [
- 19,
- 30
- ],
- [
- 49,
- -26
- ],
- [
- 23,
- -4
- ],
- [
- 9,
- -24
- ],
- [
- 10,
- -4
- ]
- ],
- [
- [
- 14988,
- 16284
- ],
- [
- 1,
- -10
- ],
- [
- 34,
- -29
- ],
- [
- 71,
- 7
- ],
- [
- -14,
- -43
- ],
- [
- -76,
- -20
- ],
- [
- -95,
- -70
- ],
- [
- -38,
- 25
- ],
- [
- 15,
- 56
- ],
- [
- -76,
- 35
- ],
- [
- 12,
- 23
- ],
- [
- 67,
- 40
- ],
- [
- -11,
- 14
- ]
- ],
- [
- [
- 22561,
- 16885
- ],
- [
- 70,
- -212
- ],
- [
- -103,
- 39
- ],
- [
- -43,
- -173
- ],
- [
- 68,
- -123
- ],
- [
- -2,
- -84
- ],
- [
- -53,
- 73
- ],
- [
- -46,
- -93
- ],
- [
- -12,
- 100
- ],
- [
- 7,
- 117
- ],
- [
- -8,
- 130
- ],
- [
- 17,
- 90
- ],
- [
- 3,
- 161
- ],
- [
- -41,
- 118
- ],
- [
- 6,
- 164
- ],
- [
- 64,
- 55
- ],
- [
- -27,
- 56
- ],
- [
- 31,
- 16
- ],
- [
- 18,
- -79
- ],
- [
- 24,
- -116
- ],
- [
- -2,
- -118
- ],
- [
- 29,
- -121
- ]
- ],
- [
- [
- 348,
- 18785
- ],
- [
- 47,
- -30
- ],
- [
- -17,
- 88
- ],
- [
- 190,
- -18
- ],
- [
- 136,
- -113
- ],
- [
- -69,
- -52
- ],
- [
- -114,
- -12
- ],
- [
- -2,
- -118
- ],
- [
- -28,
- -24
- ],
- [
- -65,
- 3
- ],
- [
- -53,
- 42
- ],
- [
- -93,
- 35
- ],
- [
- -16,
- 52
- ],
- [
- -70,
- 20
- ],
- [
- -80,
- -16
- ],
- [
- -38,
- 42
- ],
- [
- 16,
- 45
- ],
- [
- -84,
- -29
- ],
- [
- 32,
- -56
- ],
- [
- -40,
- -51
- ],
- [
- 0,
- 478
- ],
- [
- 171,
- -92
- ],
- [
- 183,
- -119
- ],
- [
- -6,
- -75
- ]
- ],
- [
- [
- 25095,
- 19295
- ],
- [
- -76,
- -6
- ],
- [
- -13,
- 38
- ],
- [
- 89,
- 50
- ],
- [
- 0,
- -82
- ]
- ],
- [
- [
- 91,
- 19302
- ],
- [
- -91,
- -7
- ],
- [
- 0,
- 82
- ],
- [
- 9,
- 5
- ],
- [
- 59,
- 0
- ],
- [
- 101,
- -35
- ],
- [
- -6,
- -16
- ],
- [
- -72,
- -29
- ]
- ],
- [
- [
- 22558,
- 19580
- ],
- [
- -106,
- 0
- ],
- [
- -143,
- 13
- ],
- [
- -12,
- 6
- ],
- [
- 66,
- 48
- ],
- [
- 87,
- 11
- ],
- [
- 99,
- -46
- ],
- [
- 9,
- -32
- ]
- ],
- [
- [
- 23055,
- 19805
- ],
- [
- -81,
- -47
- ],
- [
- -111,
- 10
- ],
- [
- -130,
- 48
- ],
- [
- 17,
- 38
- ],
- [
- 130,
- -18
- ],
- [
- 175,
- -31
- ]
- ],
- [
- [
- 22661,
- 19862
- ],
- [
- -55,
- -89
- ],
- [
- -257,
- 4
- ],
- [
- -115,
- -29
- ],
- [
- -138,
- 78
- ],
- [
- 37,
- 83
- ],
- [
- 92,
- 22
- ],
- [
- 184,
- -5
- ],
- [
- 252,
- -64
- ]
- ],
- [
- [
- 16558,
- 19281
- ],
- [
- -41,
- -10
- ],
- [
- -228,
- 16
- ],
- [
- -18,
- 53
- ],
- [
- -126,
- 32
- ],
- [
- -11,
- 65
- ],
- [
- 72,
- 25
- ],
- [
- -3,
- 66
- ],
- [
- 139,
- 102
- ],
- [
- -65,
- 15
- ],
- [
- 167,
- 105
- ],
- [
- -18,
- 55
- ],
- [
- 155,
- 63
- ],
- [
- 231,
- 77
- ],
- [
- 232,
- 22
- ],
- [
- 119,
- 45
- ],
- [
- 136,
- 16
- ],
- [
- 48,
- -48
- ],
- [
- -47,
- -37
- ],
- [
- -247,
- -60
- ],
- [
- -213,
- -57
- ],
- [
- -216,
- -114
- ],
- [
- -104,
- -117
- ],
- [
- -109,
- -116
- ],
- [
- 14,
- -99
- ],
- [
- 133,
- -99
- ]
- ],
- [
- [
- 19872,
- 20192
- ],
- [
- -393,
- -47
- ],
- [
- 128,
- 158
- ],
- [
- 57,
- 13
- ],
- [
- 52,
- -8
- ],
- [
- 177,
- -68
- ],
- [
- -21,
- -48
- ]
- ],
- [
- [
- 16112,
- 20460
- ],
- [
- -93,
- -15
- ],
- [
- -63,
- -10
- ],
- [
- -10,
- -19
- ],
- [
- -81,
- -20
- ],
- [
- -76,
- 28
- ],
- [
- 40,
- 38
- ],
- [
- -155,
- 3
- ],
- [
- 136,
- 22
- ],
- [
- 106,
- 2
- ],
- [
- 14,
- -33
- ],
- [
- 40,
- 29
- ],
- [
- 66,
- 20
- ],
- [
- 103,
- -26
- ],
- [
- -27,
- -19
- ]
- ],
- [
- [
- 19514,
- 20260
- ],
- [
- -152,
- -15
- ],
- [
- -194,
- 35
- ],
- [
- -116,
- 46
- ],
- [
- -53,
- 86
- ],
- [
- -95,
- 24
- ],
- [
- 181,
- 82
- ],
- [
- 150,
- 27
- ],
- [
- 136,
- -61
- ],
- [
- 160,
- -116
- ],
- [
- -17,
- -108
- ]
- ],
- [
- [
- 14609,
- 10636
- ],
- [
- 17,
- -12
- ],
- [
- 42,
- 37
- ]
- ],
- [
- [
- 14668,
- 10661
- ],
- [
- 28,
- -68
- ],
- [
- -4,
- -70
- ],
- [
- -21,
- -15
- ]
- ],
- [
- [
- 11358,
- 13317
- ],
- [
- 3,
- 50
- ]
- ],
- [
- [
- 16172,
- 13077
- ],
- [
- -201,
- -46
- ],
- [
- -65,
- -54
- ],
- [
- -50,
- -126
- ],
- [
- -32,
- -20
- ],
- [
- -18,
- 40
- ],
- [
- -26,
- -6
- ],
- [
- -68,
- 12
- ],
- [
- -13,
- 12
- ],
- [
- -80,
- -3
- ],
- [
- -19,
- -11
- ],
- [
- -28,
- 31
- ],
- [
- -19,
- -59
- ],
- [
- 7,
- -50
- ],
- [
- -30,
- -39
- ]
- ],
- [
- [
- 15530,
- 12758
- ],
- [
- -9,
- 52
- ],
- [
- -21,
- 36
- ],
- [
- -6,
- 48
- ],
- [
- -36,
- 43
- ],
- [
- -37,
- 100
- ],
- [
- -20,
- 98
- ],
- [
- -48,
- 83
- ],
- [
- -31,
- 19
- ],
- [
- -46,
- 115
- ],
- [
- -8,
- 83
- ],
- [
- 3,
- 71
- ],
- [
- -40,
- 133
- ],
- [
- -33,
- 47
- ],
- [
- -38,
- 25
- ],
- [
- -22,
- 68
- ],
- [
- 3,
- 28
- ],
- [
- -19,
- 62
- ],
- [
- -20,
- 27
- ],
- [
- -28,
- 89
- ],
- [
- -42,
- 97
- ],
- [
- -36,
- 82
- ],
- [
- -34,
- -1
- ],
- [
- 10,
- 66
- ],
- [
- 4,
- 42
- ],
- [
- 8,
- 48
- ]
- ],
- [
- [
- 15923,
- 14223
- ],
- [
- 27,
- -104
- ],
- [
- 34,
- -27
- ],
- [
- 12,
- -42
- ],
- [
- 48,
- -51
- ],
- [
- 4,
- -49
- ],
- [
- -7,
- -40
- ],
- [
- 9,
- -41
- ],
- [
- 20,
- -33
- ],
- [
- 9,
- -40
- ],
- [
- 10,
- -29
- ]
- ],
- [
- [
- 16130,
- 13752
- ],
- [
- 13,
- -46
- ]
- ],
- [
- [
- 14141,
- 12134
- ],
- [
- 1,
- 29
- ],
- [
- -25,
- 35
- ],
- [
- -1,
- 70
- ],
- [
- -15,
- 46
- ],
- [
- -24,
- -7
- ],
- [
- 7,
- 44
- ],
- [
- 18,
- 50
- ],
- [
- -8,
- 50
- ],
- [
- 23,
- 37
- ],
- [
- -15,
- 28
- ],
- [
- 19,
- 74
- ],
- [
- 32,
- 88
- ],
- [
- 60,
- -8
- ],
- [
- -4,
- 476
- ]
- ],
- [
- [
- 15117,
- 13437
- ],
- [
- 23,
- -118
- ],
- [
- -15,
- -22
- ],
- [
- 10,
- -123
- ],
- [
- 25,
- -144
- ],
- [
- 27,
- -29
- ],
- [
- 38,
- -45
- ]
- ],
- [
- [
- 14916,
- 11839
- ],
- [
- -1,
- 94
- ],
- [
- -10,
- 2
- ],
- [
- 2,
- 60
- ],
- [
- -9,
- 41
- ],
- [
- -36,
- 47
- ],
- [
- -8,
- 87
- ],
- [
- 8,
- 88
- ],
- [
- -32,
- 9
- ],
- [
- -5,
- -27
- ],
- [
- -42,
- -6
- ],
- [
- 17,
- -35
- ],
- [
- 6,
- -72
- ],
- [
- -38,
- -66
- ],
- [
- -35,
- -87
- ],
- [
- -36,
- -12
- ],
- [
- -58,
- 70
- ],
- [
- -27,
- -25
- ],
- [
- -7,
- -35
- ],
- [
- -36,
- -23
- ],
- [
- -2,
- -24
- ],
- [
- -70,
- 0
- ],
- [
- -9,
- 24
- ],
- [
- -51,
- 5
- ],
- [
- -25,
- -21
- ],
- [
- -19,
- 10
- ],
- [
- -36,
- 70
- ],
- [
- -12,
- 33
- ],
- [
- -50,
- -16
- ],
- [
- -19,
- -56
- ],
- [
- -18,
- -107
- ],
- [
- -24,
- -23
- ],
- [
- -21,
- -13
- ],
- [
- 47,
- -47
- ]
- ],
- [
- [
- 14918,
- 11307
- ],
- [
- -43,
- -55
- ],
- [
- -49,
- 0
- ],
- [
- -56,
- -28
- ],
- [
- -44,
- 27
- ],
- [
- -29,
- -33
- ]
- ],
- [
- [
- 11385,
- 12283
- ],
- [
- -11,
- 92
- ]
- ],
- [
- [
- 11382,
- 12428
- ],
- [
- -28,
- 94
- ],
- [
- -35,
- 42
- ],
- [
- 31,
- 23
- ],
- [
- 33,
- 84
- ],
- [
- 17,
- 62
- ]
- ],
- [
- [
- 23849,
- 9540
- ],
- [
- 19,
- -42
- ],
- [
- -49,
- 1
- ],
- [
- -26,
- 74
- ],
- [
- 41,
- -29
- ],
- [
- 15,
- -4
- ]
- ],
- [
- [
- 23760,
- 9613
- ],
- [
- -27,
- -3
- ],
- [
- -43,
- 12
- ],
- [
- -14,
- 19
- ],
- [
- 4,
- 47
- ],
- [
- 46,
- -19
- ],
- [
- 23,
- -25
- ],
- [
- 11,
- -31
- ]
- ],
- [
- [
- 23818,
- 9645
- ],
- [
- -11,
- -22
- ],
- [
- -51,
- 104
- ],
- [
- -15,
- 72
- ],
- [
- 24,
- 0
- ],
- [
- 25,
- -96
- ],
- [
- 28,
- -58
- ]
- ],
- [
- [
- 23692,
- 9797
- ],
- [
- 3,
- -24
- ],
- [
- -55,
- 51
- ],
- [
- -38,
- 43
- ],
- [
- -26,
- 40
- ],
- [
- 11,
- 12
- ],
- [
- 32,
- -29
- ],
- [
- 57,
- -55
- ],
- [
- 16,
- -38
- ]
- ],
- [
- [
- 23529,
- 9916
- ],
- [
- -14,
- -7
- ],
- [
- -30,
- 27
- ],
- [
- -29,
- 49
- ],
- [
- 4,
- 20
- ],
- [
- 41,
- -50
- ],
- [
- 28,
- -39
- ]
- ],
- [
- [
- 11750,
- 11611
- ],
- [
- -19,
- 9
- ],
- [
- -50,
- 49
- ],
- [
- -36,
- 64
- ],
- [
- -12,
- 44
- ],
- [
- -9,
- 88
- ]
- ],
- [
- [
- 6428,
- 12403
- ],
- [
- -8,
- -28
- ],
- [
- -41,
- 1
- ],
- [
- -25,
- 12
- ],
- [
- -28,
- 24
- ],
- [
- -39,
- 7
- ],
- [
- -20,
- 26
- ]
- ],
- [
- [
- 15555,
- 12172
- ],
- [
- 23,
- -22
- ],
- [
- 13,
- -49
- ],
- [
- 32,
- -51
- ],
- [
- 34,
- 0
- ],
- [
- 66,
- 31
- ],
- [
- 76,
- 14
- ],
- [
- 61,
- 37
- ],
- [
- 35,
- 8
- ],
- [
- 25,
- 22
- ],
- [
- 40,
- 4
- ]
- ],
- [
- [
- 15960,
- 12166
- ],
- [
- -1,
- -2
- ],
- [
- 0,
- -49
- ],
- [
- 0,
- -121
- ],
- [
- 0,
- -63
- ],
- [
- -32,
- -74
- ],
- [
- -48,
- -100
- ]
- ],
- [
- [
- 15960,
- 12166
- ],
- [
- 22,
- 2
- ],
- [
- 32,
- 18
- ],
- [
- 37,
- 12
- ],
- [
- 33,
- 41
- ],
- [
- 26,
- 1
- ],
- [
- 2,
- -33
- ],
- [
- -6,
- -70
- ],
- [
- 0,
- -63
- ],
- [
- -15,
- -44
- ],
- [
- -20,
- -129
- ],
- [
- -33,
- -134
- ],
- [
- -43,
- -153
- ],
- [
- -60,
- -176
- ],
- [
- -60,
- -135
- ],
- [
- -82,
- -163
- ],
- [
- -69,
- -97
- ],
- [
- -105,
- -120
- ],
- [
- -65,
- -91
- ],
- [
- -76,
- -145
- ],
- [
- -16,
- -63
- ],
- [
- -16,
- -29
- ]
- ],
- [
- [
- 8564,
- 11514
- ],
- [
- 83,
- -24
- ],
- [
- 8,
- 21
- ],
- [
- 56,
- 9
- ],
- [
- 75,
- -32
- ]
- ],
- [
- [
- 14120,
- 16686
- ],
- [
- -19,
- -31
- ],
- [
- -14,
- -49
- ]
- ],
- [
- [
- 13504,
- 16256
- ],
- [
- 15,
- 11
- ]
- ],
- [
- [
- 14214,
- 18716
- ],
- [
- -120,
- -34
- ],
- [
- -68,
- -84
- ],
- [
- 11,
- -73
- ],
- [
- -111,
- -97
- ],
- [
- -134,
- -103
- ],
- [
- -51,
- -169
- ],
- [
- 49,
- -84
- ],
- [
- 67,
- -67
- ],
- [
- -64,
- -135
- ],
- [
- -72,
- -28
- ],
- [
- -27,
- -202
- ],
- [
- -40,
- -112
- ],
- [
- -84,
- 12
- ],
- [
- -40,
- -96
- ],
- [
- -80,
- -5
- ],
- [
- -22,
- 113
- ],
- [
- -59,
- 136
- ],
- [
- -53,
- 170
- ]
- ],
- [
- [
- 14783,
- 7590
- ],
- [
- -14,
- -53
- ],
- [
- -41,
- -13
- ],
- [
- -41,
- 65
- ],
- [
- -1,
- 41
- ],
- [
- 19,
- 45
- ],
- [
- 7,
- 35
- ],
- [
- 20,
- 9
- ],
- [
- 35,
- -22
- ]
- ],
- [
- [
- 15057,
- 14954
- ],
- [
- -7,
- 91
- ],
- [
- 17,
- 50
- ]
- ],
- [
- [
- 15067,
- 15095
- ],
- [
- 19,
- 26
- ],
- [
- 19,
- 26
- ],
- [
- 4,
- 67
- ],
- [
- 22,
- -23
- ],
- [
- 77,
- 33
- ],
- [
- 37,
- -22
- ],
- [
- 58,
- 0
- ],
- [
- 80,
- 45
- ],
- [
- 37,
- -2
- ],
- [
- 80,
- 19
- ]
- ],
- [
- [
- 12678,
- 11534
- ],
- [
- -57,
- -26
- ]
- ],
- [
- [
- 19699,
- 12259
- ],
- [
- -63,
- 55
- ],
- [
- -60,
- -2
- ],
- [
- 11,
- 94
- ],
- [
- -62,
- 0
- ],
- [
- -5,
- -132
- ],
- [
- -38,
- -176
- ],
- [
- -23,
- -106
- ],
- [
- 5,
- -86
- ],
- [
- 46,
- -4
- ],
- [
- 28,
- -110
- ],
- [
- 12,
- -103
- ],
- [
- 39,
- -69
- ],
- [
- 42,
- -14
- ],
- [
- 37,
- -62
- ]
- ],
- [
- [
- 19524,
- 11573
- ],
- [
- -27,
- 46
- ],
- [
- -12,
- 59
- ],
- [
- -37,
- 68
- ],
- [
- -34,
- 57
- ],
- [
- -11,
- -71
- ],
- [
- -14,
- 67
- ],
- [
- 8,
- 75
- ],
- [
- 21,
- 115
- ]
- ],
- [
- [
- 17276,
- 15253
- ],
- [
- 39,
- 122
- ],
- [
- -15,
- 89
- ],
- [
- -51,
- 29
- ],
- [
- 18,
- 53
- ],
- [
- 58,
- -6
- ],
- [
- 33,
- 66
- ],
- [
- 22,
- 77
- ],
- [
- 94,
- 28
- ],
- [
- -15,
- -55
- ],
- [
- 10,
- -34
- ],
- [
- 29,
- 3
- ]
- ],
- [
- [
- 16306,
- 15260
- ],
- [
- -13,
- 85
- ],
- [
- 10,
- 125
- ],
- [
- -54,
- 41
- ],
- [
- 18,
- 82
- ],
- [
- -46,
- 7
- ],
- [
- 15,
- 101
- ],
- [
- 66,
- -29
- ],
- [
- 61,
- 38
- ],
- [
- -51,
- 72
- ],
- [
- -20,
- 69
- ],
- [
- -56,
- -31
- ],
- [
- -7,
- -88
- ],
- [
- -22,
- 78
- ]
- ],
- [
- [
- 16449,
- 15753
- ],
- [
- 79,
- 2
- ],
- [
- -12,
- 60
- ],
- [
- 60,
- 41
- ],
- [
- 58,
- 70
- ],
- [
- 94,
- -63
- ],
- [
- 8,
- -96
- ],
- [
- 26,
- -25
- ],
- [
- 76,
- 6
- ],
- [
- 23,
- -22
- ],
- [
- 35,
- -124
- ],
- [
- 79,
- -82
- ],
- [
- 46,
- -57
- ],
- [
- 73,
- -59
- ],
- [
- 92,
- -51
- ],
- [
- -2,
- -73
- ]
- ],
- [
- [
- 21259,
- 9730
- ],
- [
- 8,
- 29
- ],
- [
- 60,
- 27
- ],
- [
- 49,
- 4
- ],
- [
- 21,
- 15
- ],
- [
- 27,
- -15
- ],
- [
- -26,
- -33
- ],
- [
- -72,
- -52
- ],
- [
- -59,
- -35
- ]
- ],
- [
- [
- 8248,
- 12088
- ],
- [
- 40,
- 16
- ],
- [
- 15,
- -5
- ],
- [
- -3,
- -89
- ],
- [
- -58,
- -13
- ],
- [
- -13,
- 11
- ],
- [
- 20,
- 33
- ],
- [
- -1,
- 47
- ]
- ],
- [
- [
- 13135,
- 15230
- ],
- [
- 75,
- 48
- ],
- [
- 49,
- -14
- ],
- [
- -2,
- -61
- ],
- [
- 59,
- 44
- ],
- [
- 5,
- -23
- ],
- [
- -35,
- -59
- ],
- [
- 0,
- -55
- ],
- [
- 24,
- -30
- ],
- [
- -9,
- -104
- ],
- [
- -46,
- -60
- ],
- [
- 13,
- -66
- ],
- [
- 36,
- -2
- ],
- [
- 18,
- -57
- ],
- [
- 26,
- -18
- ]
- ],
- [
- [
- 15067,
- 15095
- ],
- [
- -25,
- 54
- ],
- [
- 26,
- 45
- ],
- [
- -42,
- -10
- ],
- [
- -59,
- 28
- ],
- [
- -48,
- -70
- ],
- [
- -105,
- -13
- ],
- [
- -57,
- 64
- ],
- [
- -75,
- 4
- ],
- [
- -16,
- -49
- ],
- [
- -48,
- -15
- ],
- [
- -68,
- 64
- ],
- [
- -76,
- -2
- ],
- [
- -41,
- 119
- ],
- [
- -51,
- 67
- ],
- [
- 34,
- 93
- ],
- [
- -44,
- 58
- ],
- [
- 77,
- 114
- ],
- [
- 107,
- 5
- ],
- [
- 30,
- 91
- ],
- [
- 133,
- -16
- ],
- [
- 83,
- 78
- ],
- [
- 82,
- 34
- ],
- [
- 115,
- 3
- ],
- [
- 122,
- -85
- ],
- [
- 100,
- -46
- ],
- [
- 81,
- 18
- ],
- [
- 60,
- -10
- ],
- [
- 82,
- 62
- ]
- ],
- [
- [
- 14499,
- 15837
- ],
- [
- 8,
- -46
- ],
- [
- 61,
- -39
- ],
- [
- -12,
- -29
- ],
- [
- -83,
- -7
- ],
- [
- -30,
- -37
- ],
- [
- -58,
- -65
- ],
- [
- -22,
- 56
- ],
- [
- 1,
- 25
- ]
- ],
- [
- [
- 21036,
- 13724
- ],
- [
- -42,
- -193
- ],
- [
- -29,
- -98
- ],
- [
- -37,
- 101
- ],
- [
- -8,
- 89
- ],
- [
- 41,
- 118
- ],
- [
- 56,
- 91
- ],
- [
- 32,
- -36
- ],
- [
- -13,
- -72
- ]
- ],
- [
- [
- 14668,
- 10661
- ],
- [
- 24,
- 14
- ],
- [
- 77,
- -1
- ],
- [
- 142,
- 9
- ]
- ],
- [
- [
- 15280,
- 10236
- ],
- [
- -32,
- -148
- ],
- [
- 4,
- -68
- ],
- [
- 45,
- -43
- ],
- [
- 2,
- -32
- ],
- [
- -19,
- -72
- ],
- [
- 4,
- -36
- ],
- [
- -5,
- -58
- ],
- [
- 24,
- -75
- ],
- [
- 29,
- -118
- ],
- [
- 26,
- -27
- ]
- ],
- [
- [
- 14831,
- 9690
- ],
- [
- -39,
- 36
- ],
- [
- -45,
- 20
- ],
- [
- -28,
- 20
- ],
- [
- -29,
- 31
- ]
- ],
- [
- [
- 15212,
- 16448
- ],
- [
- -56,
- -10
- ],
- [
- -46,
- -38
- ],
- [
- -65,
- -7
- ],
- [
- -60,
- -44
- ],
- [
- 3,
- -65
- ]
- ],
- [
- [
- 14878,
- 16312
- ],
- [
- -9,
- 13
- ],
- [
- -109,
- 31
- ],
- [
- -4,
- 44
- ],
- [
- -65,
- -14
- ],
- [
- -26,
- -66
- ],
- [
- -54,
- -89
- ]
- ],
- [
- [
- 8827,
- 6746
- ],
- [
- -30,
- -75
- ],
- [
- -79,
- -67
- ],
- [
- -51,
- 24
- ],
- [
- -38,
- -13
- ],
- [
- -65,
- 52
- ],
- [
- -47,
- -4
- ],
- [
- -42,
- 66
- ]
- ],
- [
- [
- 7867,
- 16212
- ],
- [
- 13,
- -39
- ],
- [
- -75,
- -58
- ],
- [
- -72,
- -42
- ],
- [
- -73,
- -35
- ],
- [
- -37,
- -71
- ],
- [
- -12,
- -27
- ],
- [
- -1,
- -64
- ],
- [
- 23,
- -64
- ],
- [
- 29,
- -3
- ],
- [
- -7,
- 44
- ],
- [
- 21,
- -26
- ],
- [
- -6,
- -35
- ],
- [
- -47,
- -19
- ],
- [
- -33,
- 2
- ],
- [
- -52,
- -21
- ],
- [
- -30,
- -6
- ],
- [
- -41,
- -6
- ],
- [
- -58,
- -34
- ],
- [
- 103,
- 22
- ],
- [
- 20,
- -22
- ],
- [
- -97,
- -36
- ],
- [
- -45,
- -1
- ],
- [
- 2,
- 15
- ],
- [
- -21,
- -33
- ],
- [
- 21,
- -6
- ],
- [
- -15,
- -86
- ],
- [
- -51,
- -92
- ],
- [
- -5,
- 31
- ],
- [
- -16,
- 6
- ],
- [
- -22,
- 30
- ],
- [
- 14,
- -65
- ],
- [
- 17,
- -21
- ],
- [
- 1,
- -46
- ],
- [
- -22,
- -46
- ],
- [
- -39,
- -96
- ],
- [
- -7,
- 5
- ],
- [
- 22,
- 81
- ],
- [
- -36,
- 46
- ],
- [
- -8,
- 100
- ],
- [
- -13,
- -52
- ],
- [
- 15,
- -76
- ],
- [
- -46,
- 19
- ],
- [
- 48,
- -39
- ],
- [
- 3,
- -114
- ],
- [
- 20,
- -8
- ],
- [
- 7,
- -42
- ],
- [
- 10,
- -120
- ],
- [
- -45,
- -89
- ],
- [
- -72,
- -35
- ],
- [
- -46,
- -71
- ],
- [
- -34,
- -8
- ],
- [
- -36,
- -44
- ],
- [
- -10,
- -40
- ],
- [
- -76,
- -78
- ],
- [
- -39,
- -57
- ],
- [
- -33,
- -71
- ],
- [
- -11,
- -85
- ],
- [
- 12,
- -83
- ],
- [
- 24,
- -103
- ],
- [
- 30,
- -85
- ],
- [
- 1,
- -52
- ],
- [
- 33,
- -139
- ],
- [
- -2,
- -81
- ],
- [
- -3,
- -47
- ],
- [
- -18,
- -73
- ],
- [
- -21,
- -15
- ],
- [
- -34,
- 15
- ],
- [
- -11,
- 52
- ],
- [
- -26,
- 28
- ],
- [
- -37,
- 103
- ],
- [
- -33,
- 92
- ],
- [
- -10,
- 47
- ],
- [
- 14,
- 79
- ],
- [
- -19,
- 66
- ],
- [
- -55,
- 101
- ],
- [
- -27,
- 18
- ],
- [
- -70,
- -54
- ],
- [
- -13,
- 6
- ],
- [
- -34,
- 56
- ],
- [
- -43,
- 29
- ],
- [
- -79,
- -15
- ],
- [
- -62,
- 13
- ],
- [
- -53,
- -8
- ],
- [
- -29,
- -19
- ],
- [
- 13,
- -31
- ],
- [
- -2,
- -49
- ],
- [
- 15,
- -24
- ],
- [
- -13,
- -16
- ],
- [
- -26,
- 18
- ],
- [
- -26,
- -23
- ],
- [
- -51,
- 4
- ],
- [
- -52,
- 64
- ],
- [
- -60,
- -15
- ],
- [
- -51,
- 27
- ],
- [
- -44,
- -8
- ],
- [
- -58,
- -28
- ],
- [
- -64,
- -89
- ],
- [
- -69,
- -52
- ],
- [
- -38,
- -57
- ],
- [
- -16,
- -54
- ],
- [
- -1,
- -83
- ],
- [
- 4,
- -57
- ],
- [
- 13,
- -41
- ]
- ],
- [
- [
- 4383,
- 14700
- ],
- [
- -12,
- 62
- ],
- [
- -45,
- 69
- ],
- [
- -33,
- 14
- ],
- [
- -7,
- 34
- ],
- [
- -39,
- 6
- ],
- [
- -25,
- 33
- ],
- [
- -65,
- 12
- ],
- [
- -18,
- 19
- ],
- [
- -8,
- 66
- ],
- [
- -68,
- 120
- ],
- [
- -58,
- 167
- ],
- [
- 2,
- 28
- ],
- [
- -30,
- 40
- ],
- [
- -54,
- 100
- ],
- [
- -10,
- 98
- ],
- [
- -37,
- 66
- ],
- [
- 15,
- 99
- ],
- [
- -2,
- 103
- ],
- [
- -22,
- 92
- ],
- [
- 27,
- 113
- ],
- [
- 8,
- 109
- ],
- [
- 9,
- 109
- ],
- [
- -13,
- 161
- ],
- [
- -22,
- 102
- ],
- [
- -20,
- 56
- ],
- [
- 8,
- 23
- ],
- [
- 101,
- -41
- ],
- [
- 37,
- -113
- ],
- [
- 17,
- 32
- ],
- [
- -11,
- 98
- ],
- [
- -23,
- 99
- ]
- ],
- [
- [
- 3448,
- 17372
- ],
- [
- -38,
- 45
- ],
- [
- -62,
- 38
- ],
- [
- -19,
- 105
- ],
- [
- -90,
- 97
- ],
- [
- -38,
- 113
- ],
- [
- -67,
- 8
- ],
- [
- -111,
- 3
- ],
- [
- -81,
- 34
- ],
- [
- -144,
- 125
- ],
- [
- -67,
- 23
- ],
- [
- -122,
- 42
- ],
- [
- -97,
- -10
- ],
- [
- -137,
- 55
- ],
- [
- -83,
- 51
- ],
- [
- -77,
- -25
- ],
- [
- 14,
- -83
- ],
- [
- -38,
- -8
- ],
- [
- -81,
- -25
- ],
- [
- -61,
- -40
- ],
- [
- -77,
- -26
- ],
- [
- -10,
- 71
- ],
- [
- 31,
- 117
- ],
- [
- 74,
- 37
- ],
- [
- -19,
- 30
- ],
- [
- -89,
- -66
- ],
- [
- -47,
- -80
- ],
- [
- -101,
- -86
- ],
- [
- 51,
- -58
- ],
- [
- -66,
- -86
- ],
- [
- -75,
- -50
- ],
- [
- -69,
- -37
- ],
- [
- -18,
- -53
- ],
- [
- -109,
- -62
- ],
- [
- -22,
- -56
- ],
- [
- -81,
- -52
- ],
- [
- -48,
- 10
- ],
- [
- -65,
- -34
- ],
- [
- -71,
- -41
- ],
- [
- -58,
- -40
- ],
- [
- -119,
- -34
- ],
- [
- -11,
- 20
- ],
- [
- 76,
- 56
- ],
- [
- 68,
- 37
- ],
- [
- 74,
- 66
- ],
- [
- 87,
- 13
- ],
- [
- 34,
- 50
- ],
- [
- 97,
- 71
- ],
- [
- 15,
- 24
- ],
- [
- 52,
- 43
- ],
- [
- 12,
- 91
- ],
- [
- 35,
- 71
- ],
- [
- -80,
- -37
- ],
- [
- -22,
- 21
- ],
- [
- -38,
- -44
- ],
- [
- -46,
- 61
- ],
- [
- -19,
- -43
- ],
- [
- -26,
- 60
- ],
- [
- -69,
- -48
- ],
- [
- -43,
- 0
- ],
- [
- -6,
- 71
- ],
- [
- 13,
- 44
- ],
- [
- -45,
- 43
- ],
- [
- -91,
- -23
- ],
- [
- -59,
- 56
- ],
- [
- -48,
- 29
- ],
- [
- 0,
- 68
- ],
- [
- -54,
- 51
- ],
- [
- 27,
- 69
- ],
- [
- 57,
- 67
- ],
- [
- 25,
- 62
- ],
- [
- 57,
- 9
- ],
- [
- 47,
- -20
- ],
- [
- 57,
- 58
- ],
- [
- 50,
- -10
- ],
- [
- 53,
- 37
- ],
- [
- -13,
- 55
- ],
- [
- -39,
- 22
- ],
- [
- 52,
- 46
- ],
- [
- -43,
- -2
- ],
- [
- -74,
- -26
- ],
- [
- -21,
- -26
- ],
- [
- -55,
- 26
- ],
- [
- -99,
- -13
- ],
- [
- -102,
- 29
- ],
- [
- -29,
- 48
- ],
- [
- -88,
- 70
- ],
- [
- 98,
- 50
- ],
- [
- 155,
- 58
- ],
- [
- 58,
- 0
- ],
- [
- -10,
- -60
- ],
- [
- 147,
- 5
- ],
- [
- -56,
- 74
- ],
- [
- -86,
- 46
- ],
- [
- -50,
- 60
- ],
- [
- -67,
- 51
- ],
- [
- -95,
- 38
- ],
- [
- 39,
- 63
- ],
- [
- 123,
- 4
- ],
- [
- 88,
- 55
- ],
- [
- 17,
- 58
- ],
- [
- 71,
- 57
- ],
- [
- 68,
- 14
- ],
- [
- 132,
- 53
- ],
- [
- 64,
- -8
- ],
- [
- 108,
- 64
- ],
- [
- 105,
- -25
- ],
- [
- 50,
- -54
- ],
- [
- 31,
- 23
- ],
- [
- 118,
- -7
- ],
- [
- -4,
- -28
- ],
- [
- 107,
- -20
- ],
- [
- 71,
- 12
- ],
- [
- 147,
- -38
- ],
- [
- 134,
- -12
- ],
- [
- 53,
- -15
- ],
- [
- 93,
- 19
- ],
- [
- 106,
- -36
- ],
- [
- 76,
- -17
- ]
- ],
- [
- [
- 1705,
- 13087
- ],
- [
- -10,
- -20
- ],
- [
- -18,
- 17
- ],
- [
- 2,
- 33
- ],
- [
- -11,
- 44
- ],
- [
- 3,
- 13
- ],
- [
- 12,
- 20
- ],
- [
- -4,
- 23
- ],
- [
- 4,
- 12
- ],
- [
- 5,
- -3
- ],
- [
- 27,
- -20
- ],
- [
- 12,
- -10
- ],
- [
- 11,
- -16
- ],
- [
- 18,
- -42
- ],
- [
- -2,
- -7
- ],
- [
- -27,
- -26
- ],
- [
- -22,
- -18
- ]
- ],
- [
- [
- 1667,
- 13274
- ],
- [
- -23,
- -9
- ],
- [
- -12,
- 26
- ],
- [
- -8,
- 9
- ],
- [
- -1,
- 8
- ],
- [
- 7,
- 10
- ],
- [
- 25,
- -11
- ],
- [
- 18,
- -19
- ],
- [
- -6,
- -14
- ]
- ],
- [
- [
- 1620,
- 13338
- ],
- [
- -2,
- -13
- ],
- [
- -37,
- 3
- ],
- [
- 5,
- 15
- ],
- [
- 34,
- -5
- ]
- ],
- [
- [
- 1558,
- 13355
- ],
- [
- -4,
- -7
- ],
- [
- -5,
- 2
- ],
- [
- -24,
- 4
- ],
- [
- -9,
- 27
- ],
- [
- -3,
- 5
- ],
- [
- 19,
- 17
- ],
- [
- 6,
- -8
- ],
- [
- 20,
- -40
- ]
- ],
- [
- [
- 1440,
- 13434
- ],
- [
- -8,
- -12
- ],
- [
- -24,
- 22
- ],
- [
- 4,
- 9
- ],
- [
- 10,
- 12
- ],
- [
- 16,
- -3
- ],
- [
- 2,
- -28
- ]
- ],
- [
- [
- 1882,
- 17649
- ],
- [
- -70,
- -45
- ],
- [
- -36,
- 31
- ],
- [
- -10,
- 56
- ],
- [
- 63,
- 42
- ],
- [
- 37,
- 19
- ],
- [
- 46,
- -8
- ],
- [
- 30,
- -38
- ],
- [
- -60,
- -57
- ]
- ],
- [
- [
- 1005,
- 17985
- ],
- [
- -43,
- -19
- ],
- [
- -45,
- 22
- ],
- [
- -43,
- 33
- ],
- [
- 69,
- 20
- ],
- [
- 56,
- -10
- ],
- [
- 6,
- -46
- ]
- ],
- [
- [
- 576,
- 18449
- ],
- [
- 43,
- -23
- ],
- [
- 44,
- 13
- ],
- [
- 56,
- -32
- ],
- [
- 69,
- -16
- ],
- [
- -5,
- -13
- ],
- [
- -53,
- -26
- ],
- [
- -53,
- 27
- ],
- [
- -27,
- 21
- ],
- [
- -61,
- -7
- ],
- [
- -17,
- 11
- ],
- [
- 4,
- 45
- ]
- ],
- [
- [
- 7575,
- 12210
- ],
- [
- -2,
- -28
- ],
- [
- -41,
- -14
- ],
- [
- 23,
- -55
- ],
- [
- -1,
- -63
- ],
- [
- -31,
- -69
- ],
- [
- 27,
- -95
- ],
- [
- 30,
- 7
- ],
- [
- 15,
- 87
- ],
- [
- -21,
- 42
- ],
- [
- -4,
- 91
- ],
- [
- 87,
- 49
- ],
- [
- -10,
- 56
- ],
- [
- 25,
- 38
- ],
- [
- 25,
- -84
- ],
- [
- 49,
- -2
- ],
- [
- 45,
- -67
- ],
- [
- 3,
- -40
- ],
- [
- 62,
- -1
- ],
- [
- 75,
- 13
- ],
- [
- 40,
- -54
- ],
- [
- 53,
- -15
- ],
- [
- 39,
- 38
- ],
- [
- 1,
- 30
- ],
- [
- 86,
- 7
- ],
- [
- 84,
- 2
- ],
- [
- -59,
- -36
- ],
- [
- 24,
- -56
- ],
- [
- 55,
- -9
- ],
- [
- 53,
- -59
- ],
- [
- 11,
- -96
- ],
- [
- 37,
- 2
- ],
- [
- 27,
- -28
- ]
- ],
- [
- [
- 20079,
- 13383
- ],
- [
- -93,
- -103
- ],
- [
- -58,
- -113
- ],
- [
- -15,
- -83
- ],
- [
- 53,
- -127
- ],
- [
- 66,
- -157
- ],
- [
- 63,
- -74
- ],
- [
- 42,
- -96
- ],
- [
- 32,
- -222
- ],
- [
- -9,
- -211
- ],
- [
- -58,
- -79
- ],
- [
- -80,
- -77
- ],
- [
- -57,
- -100
- ],
- [
- -87,
- -112
- ],
- [
- -25,
- 77
- ],
- [
- 19,
- 81
- ],
- [
- -52,
- 68
- ]
- ],
- [
- [
- 24248,
- 8822
- ],
- [
- -23,
- -16
- ],
- [
- -24,
- 52
- ],
- [
- 3,
- 33
- ],
- [
- 44,
- -69
- ]
- ],
- [
- [
- 24196,
- 9006
- ],
- [
- 12,
- -97
- ],
- [
- -19,
- 15
- ],
- [
- -15,
- -7
- ],
- [
- -10,
- 34
- ],
- [
- -1,
- 91
- ],
- [
- 33,
- -36
- ]
- ],
- [
- [
- 16250,
- 12795
- ],
- [
- -51,
- -32
- ],
- [
- -13,
- -54
- ],
- [
- -2,
- -41
- ],
- [
- -69,
- -50
- ],
- [
- -112,
- -56
- ],
- [
- -62,
- -85
- ],
- [
- -31,
- -6
- ],
- [
- -21,
- 7
- ],
- [
- -40,
- -50
- ],
- [
- -45,
- -23
- ],
- [
- -58,
- -6
- ],
- [
- -18,
- -7
- ],
- [
- -15,
- -32
- ],
- [
- -19,
- -9
- ],
- [
- -10,
- -30
- ],
- [
- -35,
- 2
- ],
- [
- -22,
- -16
- ],
- [
- -48,
- 6
- ],
- [
- -19,
- 70
- ],
- [
- 2,
- 66
- ],
- [
- -11,
- 35
- ],
- [
- -14,
- 89
- ],
- [
- -20,
- 49
- ],
- [
- 14,
- 6
- ],
- [
- -7,
- 55
- ],
- [
- 9,
- 23
- ],
- [
- -3,
- 52
- ]
- ],
- [
- [
- 14599,
- 8147
- ],
- [
- 29,
- -1
- ],
- [
- 33,
- -21
- ],
- [
- 24,
- 15
- ],
- [
- 37,
- -12
- ]
- ],
- [
- [
- 14836,
- 7589
- ],
- [
- -17,
- -87
- ],
- [
- -9,
- -100
- ],
- [
- -18,
- -54
- ],
- [
- -47,
- -61
- ],
- [
- -14,
- -17
- ],
- [
- -29,
- -61
- ],
- [
- -20,
- -62
- ],
- [
- -39,
- -86
- ],
- [
- -79,
- -123
- ],
- [
- -49,
- -72
- ],
- [
- -53,
- -55
- ],
- [
- -73,
- -47
- ],
- [
- -35,
- -6
- ],
- [
- -9,
- -33
- ],
- [
- -43,
- 18
- ],
- [
- -34,
- -23
- ],
- [
- -76,
- 23
- ],
- [
- -42,
- -15
- ],
- [
- -29,
- 7
- ],
- [
- -72,
- -48
- ],
- [
- -59,
- -19
- ],
- [
- -43,
- -45
- ],
- [
- -32,
- -3
- ],
- [
- -30,
- 43
- ],
- [
- -23,
- 2
- ],
- [
- -30,
- 54
- ],
- [
- -3,
- -17
- ],
- [
- -10,
- 32
- ],
- [
- 1,
- 70
- ],
- [
- -23,
- 81
- ],
- [
- 23,
- 22
- ],
- [
- -2,
- 92
- ],
- [
- -46,
- 112
- ],
- [
- -35,
- 102
- ],
- [
- 0,
- 0
- ],
- [
- -50,
- 156
- ]
- ],
- [
- [
- 14658,
- 8937
- ],
- [
- -53,
- -17
- ],
- [
- -40,
- -47
- ],
- [
- -8,
- -42
- ],
- [
- -25,
- -10
- ],
- [
- -61,
- -98
- ],
- [
- -38,
- -78
- ],
- [
- -24,
- -3
- ],
- [
- -22,
- 14
- ],
- [
- -78,
- 13
- ]
- ]
- ],
- "transform": {
- "scale": [
- 0.01434548714883443,
- 0.008335499711981569
- ],
- "translate": [
- -180,
- -90
- ]
- },
- "objects": {
- "ne_110m_admin_0_countries": {
- "type": "GeometryCollection",
- "geometries": [
- {
- "arcs": [
- [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Afghanistan",
- "NAME_LONG": "Afghanistan",
- "ABBREV": "Afg.",
- "FORMAL_EN": "Islamic State of Afghanistan",
- "POP_EST": 34124811,
- "POP_RANK": 15,
- "GDP_MD_EST": 64080,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AF",
- "ISO_A3": "AFG",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 6,
- 7,
- 8,
- 9
- ]
- ],
- [
- [
- 10,
- 11,
- 12
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Angola",
- "NAME_LONG": "Angola",
- "ABBREV": "Ang.",
- "FORMAL_EN": "People's Republic of Angola",
- "POP_EST": 29310273,
- "POP_RANK": 15,
- "GDP_MD_EST": 189000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AO",
- "ISO_A3": "AGO",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- 13,
- 14,
- 15,
- 16,
- 17
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Albania",
- "NAME_LONG": "Albania",
- "ABBREV": "Alb.",
- "FORMAL_EN": "Republic of Albania",
- "POP_EST": 3047987,
- "POP_RANK": 12,
- "GDP_MD_EST": 33900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AL",
- "ISO_A3": "ALB",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 18,
- 19,
- 20,
- 21,
- 22
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "United Arab Emirates",
- "NAME_LONG": "United Arab Emirates",
- "ABBREV": "U.A.E.",
- "FORMAL_EN": "United Arab Emirates",
- "POP_EST": 6072475,
- "POP_RANK": 13,
- "GDP_MD_EST": 667200,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AE",
- "ISO_A3": "ARE",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 23,
- 24
- ]
- ],
- [
- [
- 25,
- 26,
- 27,
- 28,
- 29,
- 30
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Argentina",
- "NAME_LONG": "Argentina",
- "ABBREV": "Arg.",
- "FORMAL_EN": "Argentine Republic",
- "POP_EST": 44293293,
- "POP_RANK": 15,
- "GDP_MD_EST": 879400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AR",
- "ISO_A3": "ARG",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 31,
- 32,
- 33,
- 34,
- 35
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Armenia",
- "NAME_LONG": "Armenia",
- "ABBREV": "Arm.",
- "FORMAL_EN": "Republic of Armenia",
- "POP_EST": 3045191,
- "POP_RANK": 12,
- "GDP_MD_EST": 26300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AM",
- "ISO_A3": "ARM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 36
- ]
- ],
- [
- [
- 37
- ]
- ],
- [
- [
- 38
- ]
- ],
- [
- [
- 39
- ]
- ],
- [
- [
- 40
- ]
- ],
- [
- [
- 41
- ]
- ],
- [
- [
- 42
- ]
- ],
- [
- [
- 43
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Antarctica",
- "NAME_LONG": "Antarctica",
- "ABBREV": "Ant.",
- "FORMAL_EN": "",
- "POP_EST": 4050,
- "POP_RANK": 4,
- "GDP_MD_EST": 810,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2013,
- "ISO_A2": "AQ",
- "ISO_A3": "ATA",
- "CONTINENT": "Antarctica",
- "REGION_UN": "Antarctica",
- "SUBREGION": "Antarctica"
- }
- },
- {
- "arcs": [
- [
- 44
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Fr. S. Antarctic Lands",
- "NAME_LONG": "French Southern and Antarctic Lands",
- "ABBREV": "Fr. S.A.L.",
- "FORMAL_EN": "Territory of the French Southern and Antarctic Lands",
- "POP_EST": 140,
- "POP_RANK": 1,
- "GDP_MD_EST": 16,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TF",
- "ISO_A3": "ATF",
- "CONTINENT": "Seven seas (open ocean)",
- "REGION_UN": "Seven seas (open ocean)",
- "SUBREGION": "Seven seas (open ocean)"
- }
- },
- {
- "arcs": [
- [
- [
- 45
- ]
- ],
- [
- [
- 46
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Australia",
- "NAME_LONG": "Australia",
- "ABBREV": "Auz.",
- "FORMAL_EN": "Commonwealth of Australia",
- "POP_EST": 23232413,
- "POP_RANK": 15,
- "GDP_MD_EST": 1189000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AU",
- "ISO_A3": "AUS",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Australia and New Zealand"
- }
- },
- {
- "arcs": [
- [
- 47,
- 48,
- 49,
- 50,
- 51,
- 52,
- 53
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Austria",
- "NAME_LONG": "Austria",
- "ABBREV": "Aust.",
- "FORMAL_EN": "Republic of Austria",
- "POP_EST": 8754413,
- "POP_RANK": 13,
- "GDP_MD_EST": 416600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AT",
- "ISO_A3": "AUT",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -33,
- 54,
- 55,
- 56,
- 57
- ]
- ],
- [
- [
- -35,
- 58
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Azerbaijan",
- "NAME_LONG": "Azerbaijan",
- "ABBREV": "Aze.",
- "FORMAL_EN": "Republic of Azerbaijan",
- "POP_EST": 9961396,
- "POP_RANK": 13,
- "GDP_MD_EST": 167900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AZ",
- "ISO_A3": "AZE",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 59,
- 60,
- 61
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Burundi",
- "NAME_LONG": "Burundi",
- "ABBREV": "Bur.",
- "FORMAL_EN": "Republic of Burundi",
- "POP_EST": 11466756,
- "POP_RANK": 14,
- "GDP_MD_EST": 7892,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BI",
- "ISO_A3": "BDI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- 62,
- 63,
- 64,
- 65,
- 66
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Belgium",
- "NAME_LONG": "Belgium",
- "ABBREV": "Belg.",
- "FORMAL_EN": "Kingdom of Belgium",
- "POP_EST": 11491346,
- "POP_RANK": 14,
- "GDP_MD_EST": 508600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BE",
- "ISO_A3": "BEL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- 67,
- 68,
- 69,
- 70,
- 71
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Benin",
- "NAME_LONG": "Benin",
- "ABBREV": "Benin",
- "FORMAL_EN": "Republic of Benin",
- "POP_EST": 11038805,
- "POP_RANK": 14,
- "GDP_MD_EST": 24310,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BJ",
- "ISO_A3": "BEN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -70,
- 72,
- 73,
- 74,
- 75,
- 76
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Burkina Faso",
- "NAME_LONG": "Burkina Faso",
- "ABBREV": "B.F.",
- "FORMAL_EN": "Burkina Faso",
- "POP_EST": 20107509,
- "POP_RANK": 15,
- "GDP_MD_EST": 32990,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BF",
- "ISO_A3": "BFA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- 77,
- 78,
- 79
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bangladesh",
- "NAME_LONG": "Bangladesh",
- "ABBREV": "Bang.",
- "FORMAL_EN": "People's Republic of Bangladesh",
- "POP_EST": 157826578,
- "POP_RANK": 17,
- "GDP_MD_EST": 628400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BD",
- "ISO_A3": "BGD",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- 80,
- 81,
- 82,
- 83,
- 84,
- 85
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bulgaria",
- "NAME_LONG": "Bulgaria",
- "ABBREV": "Bulg.",
- "FORMAL_EN": "Republic of Bulgaria",
- "POP_EST": 7101510,
- "POP_RANK": 13,
- "GDP_MD_EST": 143100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BG",
- "ISO_A3": "BGR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- 86
- ]
- ],
- [
- [
- 87
- ]
- ],
- [
- [
- 88
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Bahamas",
- "NAME_LONG": "Bahamas",
- "ABBREV": "Bhs.",
- "FORMAL_EN": "Commonwealth of the Bahamas",
- "POP_EST": 329988,
- "POP_RANK": 10,
- "GDP_MD_EST": 9066,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BS",
- "ISO_A3": "BHS",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- 89,
- 90,
- 91
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bosnia and Herz.",
- "NAME_LONG": "Bosnia and Herzegovina",
- "ABBREV": "B.H.",
- "FORMAL_EN": "Bosnia and Herzegovina",
- "POP_EST": 3856181,
- "POP_RANK": 12,
- "GDP_MD_EST": 42530,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BA",
- "ISO_A3": "BIH",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 92,
- 93,
- 94,
- 95,
- 96
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Belarus",
- "NAME_LONG": "Belarus",
- "ABBREV": "Bela.",
- "FORMAL_EN": "Republic of Belarus",
- "POP_EST": 9549747,
- "POP_RANK": 13,
- "GDP_MD_EST": 165400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BY",
- "ISO_A3": "BLR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- 97,
- 98,
- 99
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Belize",
- "NAME_LONG": "Belize",
- "ABBREV": "Belize",
- "FORMAL_EN": "Belize",
- "POP_EST": 360346,
- "POP_RANK": 10,
- "GDP_MD_EST": 3088,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BZ",
- "ISO_A3": "BLZ",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -27,
- 100,
- 101,
- 102,
- 103
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bolivia",
- "NAME_LONG": "Bolivia",
- "ABBREV": "Bolivia",
- "FORMAL_EN": "Plurinational State of Bolivia",
- "POP_EST": 11138234,
- "POP_RANK": 14,
- "GDP_MD_EST": 78350,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BO",
- "ISO_A3": "BOL",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -29,
- 104,
- -103,
- 105,
- 106,
- 107,
- 108,
- 109,
- 110,
- 111,
- 112
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Brazil",
- "NAME_LONG": "Brazil",
- "ABBREV": "Brazil",
- "FORMAL_EN": "Federative Republic of Brazil",
- "POP_EST": 207353391,
- "POP_RANK": 17,
- "GDP_MD_EST": 3081000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BR",
- "ISO_A3": "BRA",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 113,
- 114
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Brunei",
- "NAME_LONG": "Brunei Darussalam",
- "ABBREV": "Brunei",
- "FORMAL_EN": "Negara Brunei Darussalam",
- "POP_EST": 443593,
- "POP_RANK": 10,
- "GDP_MD_EST": 33730,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BN",
- "ISO_A3": "BRN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 115,
- 116
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bhutan",
- "NAME_LONG": "Bhutan",
- "ABBREV": "Bhutan",
- "FORMAL_EN": "Kingdom of Bhutan",
- "POP_EST": 758288,
- "POP_RANK": 11,
- "GDP_MD_EST": 6432,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BT",
- "ISO_A3": "BTN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- 117,
- 118,
- 119,
- 120
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Botswana",
- "NAME_LONG": "Botswana",
- "ABBREV": "Bwa.",
- "FORMAL_EN": "Republic of Botswana",
- "POP_EST": 2214858,
- "POP_RANK": 12,
- "GDP_MD_EST": 35900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BW",
- "ISO_A3": "BWA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- 121,
- 122,
- 123,
- 124,
- 125,
- 126
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Central African Rep.",
- "NAME_LONG": "Central African Republic",
- "ABBREV": "C.A.R.",
- "FORMAL_EN": "Central African Republic",
- "POP_EST": 5625118,
- "POP_RANK": 13,
- "GDP_MD_EST": 3206,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CF",
- "ISO_A3": "CAF",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- [
- 127
- ]
- ],
- [
- [
- 128
- ]
- ],
- [
- [
- 129
- ]
- ],
- [
- [
- 130
- ]
- ],
- [
- [
- 131
- ]
- ],
- [
- [
- 132
- ]
- ],
- [
- [
- 133
- ]
- ],
- [
- [
- 134
- ]
- ],
- [
- [
- 135
- ]
- ],
- [
- [
- 136
- ]
- ],
- [
- [
- 137,
- 138,
- 139,
- 140
- ]
- ],
- [
- [
- 141
- ]
- ],
- [
- [
- 142
- ]
- ],
- [
- [
- 143
- ]
- ],
- [
- [
- 144
- ]
- ],
- [
- [
- 145
- ]
- ],
- [
- [
- 146
- ]
- ],
- [
- [
- 147
- ]
- ],
- [
- [
- 148
- ]
- ],
- [
- [
- 149
- ]
- ],
- [
- [
- 150
- ]
- ],
- [
- [
- 151
- ]
- ],
- [
- [
- 152
- ]
- ],
- [
- [
- 153
- ]
- ],
- [
- [
- 154
- ]
- ],
- [
- [
- 155
- ]
- ],
- [
- [
- 156
- ]
- ],
- [
- [
- 157
- ]
- ],
- [
- [
- 158
- ]
- ],
- [
- [
- 159
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Canada",
- "NAME_LONG": "Canada",
- "ABBREV": "Can.",
- "FORMAL_EN": "Canada",
- "POP_EST": 35623680,
- "POP_RANK": 15,
- "GDP_MD_EST": 1674000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CA",
- "ISO_A3": "CAN",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Northern America"
- }
- },
- {
- "arcs": [
- [
- -51,
- 160,
- 161,
- 162
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Switzerland",
- "NAME_LONG": "Switzerland",
- "ABBREV": "Switz.",
- "FORMAL_EN": "Swiss Confederation",
- "POP_EST": 8236303,
- "POP_RANK": 13,
- "GDP_MD_EST": 496300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CH",
- "ISO_A3": "CHE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -24,
- 163
- ]
- ],
- [
- [
- -26,
- 164,
- 165,
- -101
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Chile",
- "NAME_LONG": "Chile",
- "ABBREV": "Chile",
- "FORMAL_EN": "Republic of Chile",
- "POP_EST": 17789267,
- "POP_RANK": 14,
- "GDP_MD_EST": 436100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CL",
- "ISO_A3": "CHL",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- -4,
- 166,
- 167,
- 168,
- 169,
- 170,
- 171,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- -117,
- 178,
- 179,
- 180,
- 181
- ]
- ],
- [
- [
- 182
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "China",
- "NAME_LONG": "China",
- "ABBREV": "China",
- "FORMAL_EN": "People's Republic of China",
- "POP_EST": 1379302771,
- "POP_RANK": 18,
- "GDP_MD_EST": 21140000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CN",
- "ISO_A3": "CHN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -75,
- 183,
- 184,
- 185,
- 186,
- 187
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Côte d'Ivoire",
- "NAME_LONG": "Côte d'Ivoire",
- "ABBREV": "I.C.",
- "FORMAL_EN": "Republic of Ivory Coast",
- "POP_EST": 24184810,
- "POP_RANK": 15,
- "GDP_MD_EST": 87120,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CI",
- "ISO_A3": "CIV",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -127,
- 188,
- 189,
- 190,
- 191,
- 192,
- 193,
- 194
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cameroon",
- "NAME_LONG": "Cameroon",
- "ABBREV": "Cam.",
- "FORMAL_EN": "Republic of Cameroon",
- "POP_EST": 24994885,
- "POP_RANK": 15,
- "GDP_MD_EST": 77240,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CM",
- "ISO_A3": "CMR",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -9,
- 195,
- -13,
- 196,
- -125,
- 197,
- 198,
- 199,
- -60,
- 200,
- 201
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Dem. Rep. Congo",
- "NAME_LONG": "Democratic Republic of the Congo",
- "ABBREV": "D.R.C.",
- "FORMAL_EN": "Democratic Republic of the Congo",
- "POP_EST": 83301151,
- "POP_RANK": 16,
- "GDP_MD_EST": 66010,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CD",
- "ISO_A3": "COD",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -12,
- 202,
- 203,
- -189,
- -126,
- -197
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Congo",
- "NAME_LONG": "Republic of the Congo",
- "ABBREV": "Rep. Congo",
- "FORMAL_EN": "Republic of the Congo",
- "POP_EST": 4954674,
- "POP_RANK": 12,
- "GDP_MD_EST": 30270,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CG",
- "ISO_A3": "COG",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -107,
- 204,
- 205,
- 206,
- 207,
- 208,
- 209
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Colombia",
- "NAME_LONG": "Colombia",
- "ABBREV": "Col.",
- "FORMAL_EN": "Republic of Colombia",
- "POP_EST": 47698524,
- "POP_RANK": 15,
- "GDP_MD_EST": 688000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CO",
- "ISO_A3": "COL",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 210,
- 211,
- 212,
- 213
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Costa Rica",
- "NAME_LONG": "Costa Rica",
- "ABBREV": "C.R.",
- "FORMAL_EN": "Republic of Costa Rica",
- "POP_EST": 4930258,
- "POP_RANK": 12,
- "GDP_MD_EST": 79260,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CR",
- "ISO_A3": "CRI",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- 214
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cuba",
- "NAME_LONG": "Cuba",
- "ABBREV": "Cuba",
- "FORMAL_EN": "Republic of Cuba",
- "POP_EST": 11147407,
- "POP_RANK": 14,
- "GDP_MD_EST": 132900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CU",
- "ISO_A3": "CUB",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- 215,
- 216
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "N. Cyprus",
- "NAME_LONG": "Northern Cyprus",
- "ABBREV": "N. Cy.",
- "FORMAL_EN": "Turkish Republic of Northern Cyprus",
- "POP_EST": 265100,
- "POP_RANK": 10,
- "GDP_MD_EST": 3600,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2013,
- "ISO_A2": "-99",
- "ISO_A3": "-99",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -217,
- 217
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cyprus",
- "NAME_LONG": "Cyprus",
- "ABBREV": "Cyp.",
- "FORMAL_EN": "Republic of Cyprus",
- "POP_EST": 1221549,
- "POP_RANK": 12,
- "GDP_MD_EST": 29260,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CY",
- "ISO_A3": "CYP",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -53,
- 218,
- 219,
- 220
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Czechia",
- "NAME_LONG": "Czech Republic",
- "ABBREV": "Cz.",
- "FORMAL_EN": "Czech Republic",
- "POP_EST": 10674723,
- "POP_RANK": 14,
- "GDP_MD_EST": 350900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CZ",
- "ISO_A3": "CZE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -52,
- -163,
- 221,
- 222,
- -63,
- 223,
- 224,
- 225,
- 226,
- 227,
- -219
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Germany",
- "NAME_LONG": "Germany",
- "ABBREV": "Ger.",
- "FORMAL_EN": "Federal Republic of Germany",
- "POP_EST": 80594017,
- "POP_RANK": 16,
- "GDP_MD_EST": 3979000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DE",
- "ISO_A3": "DEU",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- 228,
- 229,
- 230,
- 231
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Djibouti",
- "NAME_LONG": "Djibouti",
- "ABBREV": "Dji.",
- "FORMAL_EN": "Republic of Djibouti",
- "POP_EST": 865267,
- "POP_RANK": 11,
- "GDP_MD_EST": 3345,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DJ",
- "ISO_A3": "DJI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -226,
- 232
- ]
- ],
- [
- [
- 233
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Denmark",
- "NAME_LONG": "Denmark",
- "ABBREV": "Den.",
- "FORMAL_EN": "Kingdom of Denmark",
- "POP_EST": 5605948,
- "POP_RANK": 13,
- "GDP_MD_EST": 264800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DK",
- "ISO_A3": "DNK",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- 234,
- 235
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Dominican Rep.",
- "NAME_LONG": "Dominican Republic",
- "ABBREV": "Dom. Rep.",
- "FORMAL_EN": "Dominican Republic",
- "POP_EST": 10734247,
- "POP_RANK": 14,
- "GDP_MD_EST": 161900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DO",
- "ISO_A3": "DOM",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- 236,
- 237,
- 238,
- 239,
- 240,
- 241,
- 242,
- 243
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Algeria",
- "NAME_LONG": "Algeria",
- "ABBREV": "Alg.",
- "FORMAL_EN": "People's Democratic Republic of Algeria",
- "POP_EST": 40969443,
- "POP_RANK": 15,
- "GDP_MD_EST": 609400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DZ",
- "ISO_A3": "DZA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -206,
- 244,
- 245
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ecuador",
- "NAME_LONG": "Ecuador",
- "ABBREV": "Ecu.",
- "FORMAL_EN": "Republic of Ecuador",
- "POP_EST": 16290913,
- "POP_RANK": 14,
- "GDP_MD_EST": 182400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "EC",
- "ISO_A3": "ECU",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 246,
- 247,
- 248,
- 249,
- 250
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Egypt",
- "NAME_LONG": "Egypt",
- "ABBREV": "Egypt",
- "FORMAL_EN": "Arab Republic of Egypt",
- "POP_EST": 97041072,
- "POP_RANK": 16,
- "GDP_MD_EST": 1105000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "EG",
- "ISO_A3": "EGY",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -232,
- 251,
- 252,
- 253
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Eritrea",
- "NAME_LONG": "Eritrea",
- "ABBREV": "Erit.",
- "FORMAL_EN": "State of Eritrea",
- "POP_EST": 5918919,
- "POP_RANK": 13,
- "GDP_MD_EST": 9169,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ER",
- "ISO_A3": "ERI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- 254,
- 255,
- 256,
- 257
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Spain",
- "NAME_LONG": "Spain",
- "ABBREV": "Sp.",
- "FORMAL_EN": "Kingdom of Spain",
- "POP_EST": 48958159,
- "POP_RANK": 15,
- "GDP_MD_EST": 1690000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ES",
- "ISO_A3": "ESP",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 258,
- 259,
- 260
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Estonia",
- "NAME_LONG": "Estonia",
- "ABBREV": "Est.",
- "FORMAL_EN": "Republic of Estonia",
- "POP_EST": 1251581,
- "POP_RANK": 12,
- "GDP_MD_EST": 38700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "EE",
- "ISO_A3": "EST",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -231,
- 261,
- 262,
- 263,
- 264,
- 265,
- -252
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ethiopia",
- "NAME_LONG": "Ethiopia",
- "ABBREV": "Eth.",
- "FORMAL_EN": "Federal Democratic Republic of Ethiopia",
- "POP_EST": 105350020,
- "POP_RANK": 17,
- "GDP_MD_EST": 174700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ET",
- "ISO_A3": "ETH",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- 266,
- 267,
- 268,
- 269
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Finland",
- "NAME_LONG": "Finland",
- "ABBREV": "Fin.",
- "FORMAL_EN": "Republic of Finland",
- "POP_EST": 5491218,
- "POP_RANK": 13,
- "GDP_MD_EST": 224137,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "FI",
- "ISO_A3": "FIN",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- 270
- ]
- ],
- [
- [
- 271
- ]
- ],
- [
- [
- 272
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Fiji",
- "NAME_LONG": "Fiji",
- "ABBREV": "Fiji",
- "FORMAL_EN": "Republic of Fiji",
- "POP_EST": 920938,
- "POP_RANK": 11,
- "GDP_MD_EST": 8374,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "FJ",
- "ISO_A3": "FJI",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- 273
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Falkland Is.",
- "NAME_LONG": "Falkland Islands",
- "ABBREV": "Flk. Is.",
- "FORMAL_EN": "Falkland Islands",
- "POP_EST": 2931,
- "POP_RANK": 4,
- "GDP_MD_EST": 281.8,
- "POP_YEAR": 2014,
- "GDP_YEAR": 2012,
- "ISO_A2": "FK",
- "ISO_A3": "FLK",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- -65,
- 274,
- -222,
- -162,
- 275,
- 276,
- -256,
- 277
- ]
- ],
- [
- [
- -111,
- 278,
- 279
- ]
- ],
- [
- [
- 280
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "France",
- "NAME_LONG": "France",
- "ABBREV": "Fr.",
- "FORMAL_EN": "French Republic",
- "POP_EST": 67106161,
- "POP_RANK": 16,
- "GDP_MD_EST": 2699000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "FR",
- "ISO_A3": "FRA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- -190,
- -204,
- 281,
- 282
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Gabon",
- "NAME_LONG": "Gabon",
- "ABBREV": "Gabon",
- "FORMAL_EN": "Gabonese Republic",
- "POP_EST": 1772255,
- "POP_RANK": 12,
- "GDP_MD_EST": 35980,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GA",
- "ISO_A3": "GAB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- [
- 283,
- 284
- ]
- ],
- [
- [
- 285
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "United Kingdom",
- "NAME_LONG": "United Kingdom",
- "ABBREV": "U.K.",
- "FORMAL_EN": "United Kingdom of Great Britain and Northern Ireland",
- "POP_EST": 64769452,
- "POP_RANK": 16,
- "GDP_MD_EST": 2788000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GB",
- "ISO_A3": "GBR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -32,
- 286,
- 287,
- 288,
- -55
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Georgia",
- "NAME_LONG": "Georgia",
- "ABBREV": "Geo.",
- "FORMAL_EN": "Georgia",
- "POP_EST": 4926330,
- "POP_RANK": 12,
- "GDP_MD_EST": 37270,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GE",
- "ISO_A3": "GEO",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -74,
- 289,
- 290,
- -184
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ghana",
- "NAME_LONG": "Ghana",
- "ABBREV": "Ghana",
- "FORMAL_EN": "Republic of Ghana",
- "POP_EST": 27499924,
- "POP_RANK": 15,
- "GDP_MD_EST": 120800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GH",
- "ISO_A3": "GHA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -187,
- 291,
- 292,
- 293,
- 294,
- 295,
- 296
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guinea",
- "NAME_LONG": "Guinea",
- "ABBREV": "Gin.",
- "FORMAL_EN": "Republic of Guinea",
- "POP_EST": 12413867,
- "POP_RANK": 14,
- "GDP_MD_EST": 16080,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GN",
- "ISO_A3": "GIN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- 297,
- 298
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Gambia",
- "NAME_LONG": "The Gambia",
- "ABBREV": "Gambia",
- "FORMAL_EN": "Republic of the Gambia",
- "POP_EST": 2051363,
- "POP_RANK": 12,
- "GDP_MD_EST": 3387,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GM",
- "ISO_A3": "GMB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -295,
- 299,
- 300
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guinea-Bissau",
- "NAME_LONG": "Guinea-Bissau",
- "ABBREV": "GnB.",
- "FORMAL_EN": "Republic of Guinea-Bissau",
- "POP_EST": 1792338,
- "POP_RANK": 12,
- "GDP_MD_EST": 2851,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GW",
- "ISO_A3": "GNB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -191,
- -283,
- 301
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Eq. Guinea",
- "NAME_LONG": "Equatorial Guinea",
- "ABBREV": "Eq. G.",
- "FORMAL_EN": "Republic of Equatorial Guinea",
- "POP_EST": 778358,
- "POP_RANK": 11,
- "GDP_MD_EST": 31770,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GQ",
- "ISO_A3": "GNQ",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -14,
- 302,
- -84,
- 303,
- 304
- ]
- ],
- [
- [
- 305
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Greece",
- "NAME_LONG": "Greece",
- "ABBREV": "Greece",
- "FORMAL_EN": "Hellenic Republic",
- "POP_EST": 10768477,
- "POP_RANK": 14,
- "GDP_MD_EST": 290500,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GR",
- "ISO_A3": "GRC",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 306
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Greenland",
- "NAME_LONG": "Greenland",
- "ABBREV": "Grlnd.",
- "FORMAL_EN": "Greenland",
- "POP_EST": 57713,
- "POP_RANK": 8,
- "GDP_MD_EST": 2173,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2015,
- "ISO_A2": "GL",
- "ISO_A3": "GRL",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Northern America"
- }
- },
- {
- "arcs": [
- [
- -100,
- 307,
- 308,
- 309,
- 310,
- 311
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guatemala",
- "NAME_LONG": "Guatemala",
- "ABBREV": "Guat.",
- "FORMAL_EN": "Republic of Guatemala",
- "POP_EST": 15460732,
- "POP_RANK": 14,
- "GDP_MD_EST": 131800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GT",
- "ISO_A3": "GTM",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -109,
- 312,
- 313,
- 314
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guyana",
- "NAME_LONG": "Guyana",
- "ABBREV": "Guy.",
- "FORMAL_EN": "Co-operative Republic of Guyana",
- "POP_EST": 737718,
- "POP_RANK": 11,
- "GDP_MD_EST": 6093,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GY",
- "ISO_A3": "GUY",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -309,
- 315,
- 316,
- 317,
- 318
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Honduras",
- "NAME_LONG": "Honduras",
- "ABBREV": "Hond.",
- "FORMAL_EN": "Republic of Honduras",
- "POP_EST": 9038741,
- "POP_RANK": 13,
- "GDP_MD_EST": 43190,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HN",
- "ISO_A3": "HND",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -91,
- 319,
- 320,
- 321,
- 322,
- 323
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Croatia",
- "NAME_LONG": "Croatia",
- "ABBREV": "Cro.",
- "FORMAL_EN": "Republic of Croatia",
- "POP_EST": 4292095,
- "POP_RANK": 12,
- "GDP_MD_EST": 94240,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HR",
- "ISO_A3": "HRV",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -236,
- 324
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Haiti",
- "NAME_LONG": "Haiti",
- "ABBREV": "Haiti",
- "FORMAL_EN": "Republic of Haiti",
- "POP_EST": 10646714,
- "POP_RANK": 14,
- "GDP_MD_EST": 19340,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HT",
- "ISO_A3": "HTI",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -48,
- 325,
- 326,
- 327,
- 328,
- -323,
- 329
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Hungary",
- "NAME_LONG": "Hungary",
- "ABBREV": "Hun.",
- "FORMAL_EN": "Republic of Hungary",
- "POP_EST": 9850845,
- "POP_RANK": 13,
- "GDP_MD_EST": 267600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HU",
- "ISO_A3": "HUN",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- 330
- ]
- ],
- [
- [
- 331,
- 332
- ]
- ],
- [
- [
- 333
- ]
- ],
- [
- [
- 334
- ]
- ],
- [
- [
- 335
- ]
- ],
- [
- [
- 336
- ]
- ],
- [
- [
- 337
- ]
- ],
- [
- [
- 338
- ]
- ],
- [
- [
- 339,
- 340
- ]
- ],
- [
- [
- 341
- ]
- ],
- [
- [
- 342
- ]
- ],
- [
- [
- 343,
- 344
- ]
- ],
- [
- [
- 345
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Indonesia",
- "NAME_LONG": "Indonesia",
- "ABBREV": "Indo.",
- "FORMAL_EN": "Republic of Indonesia",
- "POP_EST": 260580739,
- "POP_RANK": 17,
- "GDP_MD_EST": 3028000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ID",
- "ISO_A3": "IDN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -80,
- 346,
- 347,
- -181,
- 348,
- -179,
- -116,
- -178,
- 349
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "India",
- "NAME_LONG": "India",
- "ABBREV": "India",
- "FORMAL_EN": "Republic of India",
- "POP_EST": 1281935911,
- "POP_RANK": 18,
- "GDP_MD_EST": 8721000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IN",
- "ISO_A3": "IND",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- -284,
- 350
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ireland",
- "NAME_LONG": "Ireland",
- "ABBREV": "Ire.",
- "FORMAL_EN": "Ireland",
- "POP_EST": 5011102,
- "POP_RANK": 13,
- "GDP_MD_EST": 322000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IE",
- "ISO_A3": "IRL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -6,
- 351,
- 352,
- 353,
- 354,
- -59,
- -34,
- -58,
- 355,
- 356
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Iran",
- "NAME_LONG": "Iran",
- "ABBREV": "Iran",
- "FORMAL_EN": "Islamic Republic of Iran",
- "POP_EST": 82021564,
- "POP_RANK": 16,
- "GDP_MD_EST": 1459000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IR",
- "ISO_A3": "IRN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- -354,
- 357,
- 358,
- 359,
- 360,
- 361,
- 362
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Iraq",
- "NAME_LONG": "Iraq",
- "ABBREV": "Iraq",
- "FORMAL_EN": "Republic of Iraq",
- "POP_EST": 39192111,
- "POP_RANK": 15,
- "GDP_MD_EST": 596700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IQ",
- "ISO_A3": "IRQ",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 363
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Iceland",
- "NAME_LONG": "Iceland",
- "ABBREV": "Iceland",
- "FORMAL_EN": "Republic of Iceland",
- "POP_EST": 339747,
- "POP_RANK": 10,
- "GDP_MD_EST": 16150,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IS",
- "ISO_A3": "ISL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- 364,
- 365,
- 366,
- 367,
- 368,
- 369,
- -250
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Israel",
- "NAME_LONG": "Israel",
- "ABBREV": "Isr.",
- "FORMAL_EN": "State of Israel",
- "POP_EST": 8299706,
- "POP_RANK": 13,
- "GDP_MD_EST": 297000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IL",
- "ISO_A3": "ISR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- -50,
- 370,
- 371,
- -276,
- -161
- ]
- ],
- [
- [
- 372
- ]
- ],
- [
- [
- 373
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Italy",
- "NAME_LONG": "Italy",
- "ABBREV": "Italy",
- "FORMAL_EN": "Italian Republic",
- "POP_EST": 62137802,
- "POP_RANK": 16,
- "GDP_MD_EST": 2221000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IT",
- "ISO_A3": "ITA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 374
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Jamaica",
- "NAME_LONG": "Jamaica",
- "ABBREV": "Jam.",
- "FORMAL_EN": "Jamaica",
- "POP_EST": 2990561,
- "POP_RANK": 12,
- "GDP_MD_EST": 25390,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "JM",
- "ISO_A3": "JAM",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -361,
- 375,
- 376,
- -370,
- 377,
- -368,
- 378
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Jordan",
- "NAME_LONG": "Jordan",
- "ABBREV": "Jord.",
- "FORMAL_EN": "Hashemite Kingdom of Jordan",
- "POP_EST": 10248069,
- "POP_RANK": 14,
- "GDP_MD_EST": 86190,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "JO",
- "ISO_A3": "JOR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 379
- ]
- ],
- [
- [
- 380
- ]
- ],
- [
- [
- 381
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Japan",
- "NAME_LONG": "Japan",
- "ABBREV": "Japan",
- "FORMAL_EN": "Japan",
- "POP_EST": 126451398,
- "POP_RANK": 17,
- "GDP_MD_EST": 4932000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "JP",
- "ISO_A3": "JPN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -169,
- 382,
- 383,
- 384,
- 385,
- 386
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kazakhstan",
- "NAME_LONG": "Kazakhstan",
- "ABBREV": "Kaz.",
- "FORMAL_EN": "Republic of Kazakhstan",
- "POP_EST": 18556698,
- "POP_RANK": 14,
- "GDP_MD_EST": 460700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KZ",
- "ISO_A3": "KAZ",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -264,
- 387,
- 388,
- 389,
- 390,
- 391
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kenya",
- "NAME_LONG": "Kenya",
- "ABBREV": "Ken.",
- "FORMAL_EN": "Republic of Kenya",
- "POP_EST": 47615739,
- "POP_RANK": 15,
- "GDP_MD_EST": 152700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KE",
- "ISO_A3": "KEN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -168,
- 392,
- 393,
- -383
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kyrgyzstan",
- "NAME_LONG": "Kyrgyzstan",
- "ABBREV": "Kgz.",
- "FORMAL_EN": "Kyrgyz Republic",
- "POP_EST": 5789122,
- "POP_RANK": 13,
- "GDP_MD_EST": 21010,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KG",
- "ISO_A3": "KGZ",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- 394,
- 395,
- 396,
- 397
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cambodia",
- "NAME_LONG": "Cambodia",
- "ABBREV": "Camb.",
- "FORMAL_EN": "Kingdom of Cambodia",
- "POP_EST": 16204486,
- "POP_RANK": 14,
- "GDP_MD_EST": 58940,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KH",
- "ISO_A3": "KHM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 398,
- 399
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "South Korea",
- "NAME_LONG": "Republic of Korea",
- "ABBREV": "S.K.",
- "FORMAL_EN": "Republic of Korea",
- "POP_EST": 51181299,
- "POP_RANK": 16,
- "GDP_MD_EST": 1929000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KR",
- "ISO_A3": "KOR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -17,
- 400,
- 401,
- 402
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kosovo",
- "NAME_LONG": "Kosovo",
- "ABBREV": "Kos.",
- "FORMAL_EN": "Republic of Kosovo",
- "POP_EST": 1895250,
- "POP_RANK": 12,
- "GDP_MD_EST": 18490,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "XK",
- "ISO_A3": "-99",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -359,
- 403,
- 404
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kuwait",
- "NAME_LONG": "Kuwait",
- "ABBREV": "Kwt.",
- "FORMAL_EN": "State of Kuwait",
- "POP_EST": 2875422,
- "POP_RANK": 12,
- "GDP_MD_EST": 301100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KW",
- "ISO_A3": "KWT",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -176,
- 405,
- -396,
- 406,
- 407
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Laos",
- "NAME_LONG": "Lao PDR",
- "ABBREV": "Laos",
- "FORMAL_EN": "Lao People's Democratic Republic",
- "POP_EST": 7126706,
- "POP_RANK": 13,
- "GDP_MD_EST": 40960,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LA",
- "ISO_A3": "LAO",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -366,
- 408,
- 409
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Lebanon",
- "NAME_LONG": "Lebanon",
- "ABBREV": "Leb.",
- "FORMAL_EN": "Lebanese Republic",
- "POP_EST": 6229794,
- "POP_RANK": 13,
- "GDP_MD_EST": 85160,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LB",
- "ISO_A3": "LBN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -186,
- 410,
- 411,
- -292
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Liberia",
- "NAME_LONG": "Liberia",
- "ABBREV": "Liberia",
- "FORMAL_EN": "Republic of Liberia",
- "POP_EST": 4689021,
- "POP_RANK": 12,
- "GDP_MD_EST": 3881,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LR",
- "ISO_A3": "LBR",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -243,
- 412,
- 413,
- -248,
- 414,
- 415,
- 416
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Libya",
- "NAME_LONG": "Libya",
- "ABBREV": "Libya",
- "FORMAL_EN": "Libya",
- "POP_EST": 6653210,
- "POP_RANK": 13,
- "GDP_MD_EST": 90890,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LY",
- "ISO_A3": "LBY",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- 417
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sri Lanka",
- "NAME_LONG": "Sri Lanka",
- "ABBREV": "Sri L.",
- "FORMAL_EN": "Democratic Socialist Republic of Sri Lanka",
- "POP_EST": 22409381,
- "POP_RANK": 15,
- "GDP_MD_EST": 236700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LK",
- "ISO_A3": "LKA",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- 418
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Lesotho",
- "NAME_LONG": "Lesotho",
- "ABBREV": "Les.",
- "FORMAL_EN": "Kingdom of Lesotho",
- "POP_EST": 1958042,
- "POP_RANK": 12,
- "GDP_MD_EST": 6019,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LS",
- "ISO_A3": "LSO",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- -93,
- 419,
- 420,
- 421,
- 422
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Lithuania",
- "NAME_LONG": "Lithuania",
- "ABBREV": "Lith.",
- "FORMAL_EN": "Republic of Lithuania",
- "POP_EST": 2823859,
- "POP_RANK": 12,
- "GDP_MD_EST": 85620,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LT",
- "ISO_A3": "LTU",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -64,
- -223,
- -275
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Luxembourg",
- "NAME_LONG": "Luxembourg",
- "ABBREV": "Lux.",
- "FORMAL_EN": "Grand Duchy of Luxembourg",
- "POP_EST": 594130,
- "POP_RANK": 11,
- "GDP_MD_EST": 58740,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LU",
- "ISO_A3": "LUX",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- -94,
- -423,
- 423,
- -261,
- 424
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Latvia",
- "NAME_LONG": "Latvia",
- "ABBREV": "Lat.",
- "FORMAL_EN": "Republic of Latvia",
- "POP_EST": 1944643,
- "POP_RANK": 12,
- "GDP_MD_EST": 50650,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LV",
- "ISO_A3": "LVA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -240,
- 425,
- 426
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Morocco",
- "NAME_LONG": "Morocco",
- "ABBREV": "Mor.",
- "FORMAL_EN": "Kingdom of Morocco",
- "POP_EST": 33986655,
- "POP_RANK": 15,
- "GDP_MD_EST": 282800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MA",
- "ISO_A3": "MAR",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- 427,
- 428
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Moldova",
- "NAME_LONG": "Moldova",
- "ABBREV": "Mda.",
- "FORMAL_EN": "Republic of Moldova",
- "POP_EST": 3474121,
- "POP_RANK": 12,
- "GDP_MD_EST": 18540,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MD",
- "ISO_A3": "MDA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- 429
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Madagascar",
- "NAME_LONG": "Madagascar",
- "ABBREV": "Mad.",
- "FORMAL_EN": "Republic of Madagascar",
- "POP_EST": 25054161,
- "POP_RANK": 15,
- "GDP_MD_EST": 36860,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MG",
- "ISO_A3": "MDG",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -98,
- -312,
- 430,
- 431,
- 432
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mexico",
- "NAME_LONG": "Mexico",
- "ABBREV": "Mex.",
- "FORMAL_EN": "United Mexican States",
- "POP_EST": 124574795,
- "POP_RANK": 17,
- "GDP_MD_EST": 2307000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MX",
- "ISO_A3": "MEX",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -18,
- -403,
- 433,
- -85,
- -303
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Macedonia",
- "NAME_LONG": "Macedonia",
- "ABBREV": "Mkd.",
- "FORMAL_EN": "Former Yugoslav Republic of Macedonia",
- "POP_EST": 2103721,
- "POP_RANK": 12,
- "GDP_MD_EST": 29520,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MK",
- "ISO_A3": "MKD",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -76,
- -188,
- -297,
- 434,
- 435,
- -237,
- 436
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mali",
- "NAME_LONG": "Mali",
- "ABBREV": "Mali",
- "FORMAL_EN": "Republic of Mali",
- "POP_EST": 17885245,
- "POP_RANK": 14,
- "GDP_MD_EST": 38090,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ML",
- "ISO_A3": "MLI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -78,
- -350,
- -177,
- -408,
- 437,
- 438
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Myanmar",
- "NAME_LONG": "Myanmar",
- "ABBREV": "Myan.",
- "FORMAL_EN": "Republic of the Union of Myanmar",
- "POP_EST": 55123814,
- "POP_RANK": 16,
- "GDP_MD_EST": 311100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MM",
- "ISO_A3": "MMR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -16,
- 439,
- -320,
- -90,
- 440,
- -401
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Montenegro",
- "NAME_LONG": "Montenegro",
- "ABBREV": "Mont.",
- "FORMAL_EN": "Montenegro",
- "POP_EST": 642550,
- "POP_RANK": 11,
- "GDP_MD_EST": 10610,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ME",
- "ISO_A3": "MNE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -171,
- 441
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mongolia",
- "NAME_LONG": "Mongolia",
- "ABBREV": "Mong.",
- "FORMAL_EN": "Mongolia",
- "POP_EST": 3068243,
- "POP_RANK": 12,
- "GDP_MD_EST": 37000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MN",
- "ISO_A3": "MNG",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 442,
- 443,
- 444,
- 445,
- 446,
- 447,
- 448,
- 449
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mozambique",
- "NAME_LONG": "Mozambique",
- "ABBREV": "Moz.",
- "FORMAL_EN": "Republic of Mozambique",
- "POP_EST": 26573706,
- "POP_RANK": 15,
- "GDP_MD_EST": 35010,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MZ",
- "ISO_A3": "MOZ",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -238,
- -436,
- 450,
- 451,
- 452
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mauritania",
- "NAME_LONG": "Mauritania",
- "ABBREV": "Mrt.",
- "FORMAL_EN": "Islamic Republic of Mauritania",
- "POP_EST": 3758571,
- "POP_RANK": 12,
- "GDP_MD_EST": 16710,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MR",
- "ISO_A3": "MRT",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -450,
- 453,
- 454
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Malawi",
- "NAME_LONG": "Malawi",
- "ABBREV": "Mal.",
- "FORMAL_EN": "Republic of Malawi",
- "POP_EST": 19196246,
- "POP_RANK": 14,
- "GDP_MD_EST": 21200,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MW",
- "ISO_A3": "MWI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -115,
- 455,
- -344,
- 456
- ]
- ],
- [
- [
- 457,
- 458
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Malaysia",
- "NAME_LONG": "Malaysia",
- "ABBREV": "Malay.",
- "FORMAL_EN": "Malaysia",
- "POP_EST": 31381992,
- "POP_RANK": 15,
- "GDP_MD_EST": 863000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MY",
- "ISO_A3": "MYS",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -7,
- 459,
- -119,
- 460,
- 461
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Namibia",
- "NAME_LONG": "Namibia",
- "ABBREV": "Nam.",
- "FORMAL_EN": "Republic of Namibia",
- "POP_EST": 2484780,
- "POP_RANK": 12,
- "GDP_MD_EST": 25990,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NA",
- "ISO_A3": "NAM",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- 462
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "New Caledonia",
- "NAME_LONG": "New Caledonia",
- "ABBREV": "New C.",
- "FORMAL_EN": "New Caledonia",
- "POP_EST": 279070,
- "POP_RANK": 10,
- "GDP_MD_EST": 10770,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NC",
- "ISO_A3": "NCL",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -71,
- -77,
- -437,
- -244,
- -417,
- 463,
- -194,
- 464
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Niger",
- "NAME_LONG": "Niger",
- "ABBREV": "Niger",
- "FORMAL_EN": "Republic of Niger",
- "POP_EST": 19245344,
- "POP_RANK": 14,
- "GDP_MD_EST": 20150,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NE",
- "ISO_A3": "NER",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -72,
- -465,
- -193,
- 465
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Nigeria",
- "NAME_LONG": "Nigeria",
- "ABBREV": "Nigeria",
- "FORMAL_EN": "Federal Republic of Nigeria",
- "POP_EST": 190632261,
- "POP_RANK": 17,
- "GDP_MD_EST": 1089000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NG",
- "ISO_A3": "NGA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -212,
- 466,
- -317,
- 467
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Nicaragua",
- "NAME_LONG": "Nicaragua",
- "ABBREV": "Nic.",
- "FORMAL_EN": "Republic of Nicaragua",
- "POP_EST": 6025951,
- "POP_RANK": 13,
- "GDP_MD_EST": 33550,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NI",
- "ISO_A3": "NIC",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -67,
- 468,
- -224
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Netherlands",
- "NAME_LONG": "Netherlands",
- "ABBREV": "Neth.",
- "FORMAL_EN": "Kingdom of the Netherlands",
- "POP_EST": 17084719,
- "POP_RANK": 14,
- "GDP_MD_EST": 870800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NL",
- "ISO_A3": "NLD",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -268,
- 469,
- 470,
- 471
- ]
- ],
- [
- [
- 472
- ]
- ],
- [
- [
- 473
- ]
- ],
- [
- [
- 474
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Norway",
- "NAME_LONG": "Norway",
- "ABBREV": "Nor.",
- "FORMAL_EN": "Kingdom of Norway",
- "POP_EST": 5320045,
- "POP_RANK": 13,
- "GDP_MD_EST": 364700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NO",
- "ISO_A3": "NOR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -180,
- -349
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Nepal",
- "NAME_LONG": "Nepal",
- "ABBREV": "Nepal",
- "FORMAL_EN": "Nepal",
- "POP_EST": 29384297,
- "POP_RANK": 15,
- "GDP_MD_EST": 71520,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NP",
- "ISO_A3": "NPL",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 475
- ]
- ],
- [
- [
- 476
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "New Zealand",
- "NAME_LONG": "New Zealand",
- "ABBREV": "N.Z.",
- "FORMAL_EN": "New Zealand",
- "POP_EST": 4510327,
- "POP_RANK": 12,
- "GDP_MD_EST": 174800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NZ",
- "ISO_A3": "NZL",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Australia and New Zealand"
- }
- },
- {
- "arcs": [
- [
- [
- -20,
- 477
- ]
- ],
- [
- [
- -22,
- 478,
- 479,
- 480
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Oman",
- "NAME_LONG": "Oman",
- "ABBREV": "Oman",
- "FORMAL_EN": "Sultanate of Oman",
- "POP_EST": 3424386,
- "POP_RANK": 12,
- "GDP_MD_EST": 173100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "OM",
- "ISO_A3": "OMN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -5,
- -182,
- -348,
- 481,
- -352
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Pakistan",
- "NAME_LONG": "Pakistan",
- "ABBREV": "Pak.",
- "FORMAL_EN": "Islamic Republic of Pakistan",
- "POP_EST": 204924861,
- "POP_RANK": 17,
- "GDP_MD_EST": 988200,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PK",
- "ISO_A3": "PAK",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- -208,
- 482,
- -214,
- 483
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Panama",
- "NAME_LONG": "Panama",
- "ABBREV": "Pan.",
- "FORMAL_EN": "Republic of Panama",
- "POP_EST": 3753142,
- "POP_RANK": 12,
- "GDP_MD_EST": 93120,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PA",
- "ISO_A3": "PAN",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -102,
- -166,
- 484,
- -245,
- -205,
- -106
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Peru",
- "NAME_LONG": "Peru",
- "ABBREV": "Peru",
- "FORMAL_EN": "Republic of Peru",
- "POP_EST": 31036656,
- "POP_RANK": 15,
- "GDP_MD_EST": 410400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PE",
- "ISO_A3": "PER",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- 485
- ]
- ],
- [
- [
- 486
- ]
- ],
- [
- [
- 487
- ]
- ],
- [
- [
- 488
- ]
- ],
- [
- [
- 489
- ]
- ],
- [
- [
- 490
- ]
- ],
- [
- [
- 491
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Philippines",
- "NAME_LONG": "Philippines",
- "ABBREV": "Phil.",
- "FORMAL_EN": "Republic of the Philippines",
- "POP_EST": 104256076,
- "POP_RANK": 17,
- "GDP_MD_EST": 801900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PH",
- "ISO_A3": "PHL",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- -340,
- 492
- ]
- ],
- [
- [
- 493
- ]
- ],
- [
- [
- 494
- ]
- ],
- [
- [
- 495
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Papua New Guinea",
- "NAME_LONG": "Papua New Guinea",
- "ABBREV": "P.N.G.",
- "FORMAL_EN": "Independent State of Papua New Guinea",
- "POP_EST": 6909701,
- "POP_RANK": 13,
- "GDP_MD_EST": 28020,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PG",
- "ISO_A3": "PNG",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -97,
- 496,
- 497,
- -220,
- -228,
- 498,
- 499,
- -420
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Poland",
- "NAME_LONG": "Poland",
- "ABBREV": "Pol.",
- "FORMAL_EN": "Republic of Poland",
- "POP_EST": 38476269,
- "POP_RANK": 15,
- "GDP_MD_EST": 1052000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PL",
- "ISO_A3": "POL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- 500
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Puerto Rico",
- "NAME_LONG": "Puerto Rico",
- "ABBREV": "P.R.",
- "FORMAL_EN": "Commonwealth of Puerto Rico",
- "POP_EST": 3351827,
- "POP_RANK": 12,
- "GDP_MD_EST": 131000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PR",
- "ISO_A3": "PRI",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -173,
- 501,
- 502,
- -400,
- 503
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "North Korea",
- "NAME_LONG": "Dem. Rep. Korea",
- "ABBREV": "N.K.",
- "FORMAL_EN": "Democratic People's Republic of Korea",
- "POP_EST": 25248140,
- "POP_RANK": 15,
- "GDP_MD_EST": 40000,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2016,
- "ISO_A2": "KP",
- "ISO_A3": "PRK",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -258,
- 504
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Portugal",
- "NAME_LONG": "Portugal",
- "ABBREV": "Port.",
- "FORMAL_EN": "Portuguese Republic",
- "POP_EST": 10839514,
- "POP_RANK": 14,
- "GDP_MD_EST": 297100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PT",
- "ISO_A3": "PRT",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -28,
- -104,
- -105
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Paraguay",
- "NAME_LONG": "Paraguay",
- "ABBREV": "Para.",
- "FORMAL_EN": "Republic of Paraguay",
- "POP_EST": 6943739,
- "POP_RANK": 13,
- "GDP_MD_EST": 64670,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PY",
- "ISO_A3": "PRY",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -369,
- -378
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Palestine",
- "NAME_LONG": "Palestine",
- "ABBREV": "Pal.",
- "FORMAL_EN": "West Bank and Gaza",
- "POP_EST": 4543126,
- "POP_RANK": 12,
- "GDP_MD_EST": 21220.77,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PS",
- "ISO_A3": "PSE",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 505,
- 506
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Qatar",
- "NAME_LONG": "Qatar",
- "ABBREV": "Qatar",
- "FORMAL_EN": "State of Qatar",
- "POP_EST": 2314307,
- "POP_RANK": 12,
- "GDP_MD_EST": 334500,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "QA",
- "ISO_A3": "QAT",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -81,
- 507,
- -328,
- 508,
- -429,
- 509,
- 510
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Romania",
- "NAME_LONG": "Romania",
- "ABBREV": "Rom.",
- "FORMAL_EN": "Romania",
- "POP_EST": 21529967,
- "POP_RANK": 15,
- "GDP_MD_EST": 441000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RO",
- "ISO_A3": "ROU",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -56,
- -289,
- 511,
- 512,
- -95,
- -425,
- -260,
- 513,
- -269,
- -472,
- 514,
- -502,
- -172,
- -442,
- -170,
- -387,
- 515
- ]
- ],
- [
- [
- -421,
- -500,
- 516
- ]
- ],
- [
- [
- 519
- ]
- ],
- [
- [
- 520
- ]
- ],
- [
- [
- 521
- ]
- ],
- [
- [
- 522
- ]
- ],
- [
- [
- 523
- ]
- ],
- [
- [
- 524
- ]
- ],
- [
- [
- 525
- ]
- ],
- [
- [
- 526
- ]
- ],
- [
- [
- 527
- ]
- ],
- [
- [
- 528
- ]
- ],
- [
- [
- 529
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Russia",
- "NAME_LONG": "Russian Federation",
- "ABBREV": "Rus.",
- "FORMAL_EN": "Russian Federation",
- "POP_EST": 142257519,
- "POP_RANK": 17,
- "GDP_MD_EST": 3745000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RU",
- "ISO_A3": "RUS",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -61,
- -200,
- 530,
- 531
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Rwanda",
- "NAME_LONG": "Rwanda",
- "ABBREV": "Rwa.",
- "FORMAL_EN": "Republic of Rwanda",
- "POP_EST": 11901484,
- "POP_RANK": 14,
- "GDP_MD_EST": 21970,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RW",
- "ISO_A3": "RWA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -239,
- -453,
- 532,
- -426
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "W. Sahara",
- "NAME_LONG": "Western Sahara",
- "ABBREV": "W. Sah.",
- "FORMAL_EN": "Sahrawi Arab Democratic Republic",
- "POP_EST": 603253,
- "POP_RANK": 11,
- "GDP_MD_EST": 906.5,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2007,
- "ISO_A2": "EH",
- "ISO_A3": "ESH",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -23,
- -481,
- 533,
- 534,
- -376,
- -360,
- -405,
- 535,
- -507,
- 536
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Saudi Arabia",
- "NAME_LONG": "Saudi Arabia",
- "ABBREV": "Saud.",
- "FORMAL_EN": "Kingdom of Saudi Arabia",
- "POP_EST": 28571770,
- "POP_RANK": 15,
- "GDP_MD_EST": 1731000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SA",
- "ISO_A3": "SAU",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -123,
- 537,
- -415,
- -247,
- 538,
- -253,
- -266,
- 539
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sudan",
- "NAME_LONG": "Sudan",
- "ABBREV": "Sudan",
- "FORMAL_EN": "Republic of the Sudan",
- "POP_EST": 37345935,
- "POP_RANK": 15,
- "GDP_MD_EST": 176300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SD",
- "ISO_A3": "SDN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -124,
- -540,
- -265,
- -392,
- 540,
- -198
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "S. Sudan",
- "NAME_LONG": "South Sudan",
- "ABBREV": "S. Sud.",
- "FORMAL_EN": "Republic of South Sudan",
- "POP_EST": 13026129,
- "POP_RANK": 14,
- "GDP_MD_EST": 20880,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SS",
- "ISO_A3": "SSD",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -296,
- -301,
- 541,
- -299,
- 542,
- -451,
- -435
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Senegal",
- "NAME_LONG": "Senegal",
- "ABBREV": "Sen.",
- "FORMAL_EN": "Republic of Senegal",
- "POP_EST": 14668522,
- "POP_RANK": 14,
- "GDP_MD_EST": 39720,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SN",
- "ISO_A3": "SEN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- [
- 543
- ]
- ],
- [
- [
- 544
- ]
- ],
- [
- [
- 545
- ]
- ],
- [
- [
- 546
- ]
- ],
- [
- [
- 547
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Solomon Is.",
- "NAME_LONG": "Solomon Islands",
- "ABBREV": "S. Is.",
- "FORMAL_EN": "",
- "POP_EST": 647581,
- "POP_RANK": 11,
- "GDP_MD_EST": 1198,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SB",
- "ISO_A3": "SLB",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -293,
- -412,
- 548
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sierra Leone",
- "NAME_LONG": "Sierra Leone",
- "ABBREV": "S.L.",
- "FORMAL_EN": "Republic of Sierra Leone",
- "POP_EST": 6163195,
- "POP_RANK": 13,
- "GDP_MD_EST": 10640,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SL",
- "ISO_A3": "SLE",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -310,
- -319,
- 549
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "El Salvador",
- "NAME_LONG": "El Salvador",
- "ABBREV": "El. S.",
- "FORMAL_EN": "Republic of El Salvador",
- "POP_EST": 6172011,
- "POP_RANK": 13,
- "GDP_MD_EST": 54790,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SV",
- "ISO_A3": "SLV",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -230,
- 550,
- 551,
- -262
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Somaliland",
- "NAME_LONG": "Somaliland",
- "ABBREV": "Solnd.",
- "FORMAL_EN": "Republic of Somaliland",
- "POP_EST": 3500000,
- "POP_RANK": 12,
- "GDP_MD_EST": 12250,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2013,
- "ISO_A2": "-99",
- "ISO_A3": "-99",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -263,
- -552,
- 552,
- -388
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Somalia",
- "NAME_LONG": "Somalia",
- "ABBREV": "Som.",
- "FORMAL_EN": "Federal Republic of Somalia",
- "POP_EST": 7531386,
- "POP_RANK": 13,
- "GDP_MD_EST": 4719,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SO",
- "ISO_A3": "SOM",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -86,
- -434,
- -402,
- -441,
- -92,
- -324,
- -329,
- -508
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Serbia",
- "NAME_LONG": "Serbia",
- "ABBREV": "Serb.",
- "FORMAL_EN": "Republic of Serbia",
- "POP_EST": 7111024,
- "POP_RANK": 13,
- "GDP_MD_EST": 101800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RS",
- "ISO_A3": "SRB",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -110,
- -315,
- 553,
- -279
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Suriname",
- "NAME_LONG": "Suriname",
- "ABBREV": "Sur.",
- "FORMAL_EN": "Republic of Suriname",
- "POP_EST": 591919,
- "POP_RANK": 11,
- "GDP_MD_EST": 8547,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SR",
- "ISO_A3": "SUR",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -54,
- -221,
- -498,
- 554,
- -326
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Slovakia",
- "NAME_LONG": "Slovakia",
- "ABBREV": "Svk.",
- "FORMAL_EN": "Slovak Republic",
- "POP_EST": 5445829,
- "POP_RANK": 13,
- "GDP_MD_EST": 168800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SK",
- "ISO_A3": "SVK",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -49,
- -330,
- -322,
- 555,
- -371
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Slovenia",
- "NAME_LONG": "Slovenia",
- "ABBREV": "Slo.",
- "FORMAL_EN": "Republic of Slovenia",
- "POP_EST": 1972126,
- "POP_RANK": 12,
- "GDP_MD_EST": 68350,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SI",
- "ISO_A3": "SVN",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -267,
- 556,
- -470
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sweden",
- "NAME_LONG": "Sweden",
- "ABBREV": "Swe.",
- "FORMAL_EN": "Kingdom of Sweden",
- "POP_EST": 9960487,
- "POP_RANK": 13,
- "GDP_MD_EST": 498100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SE",
- "ISO_A3": "SWE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -446,
- 557
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Swaziland",
- "NAME_LONG": "Swaziland",
- "ABBREV": "Swz.",
- "FORMAL_EN": "Kingdom of Swaziland",
- "POP_EST": 1467152,
- "POP_RANK": 12,
- "GDP_MD_EST": 11060,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SZ",
- "ISO_A3": "SWZ",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- -362,
- -379,
- -367,
- -410,
- 558,
- 559
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Syria",
- "NAME_LONG": "Syria",
- "ABBREV": "Syria",
- "FORMAL_EN": "Syrian Arab Republic",
- "POP_EST": 18028549,
- "POP_RANK": 14,
- "GDP_MD_EST": 50280,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2015,
- "ISO_A2": "SY",
- "ISO_A3": "SYR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -122,
- -195,
- -464,
- -416,
- -538
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Chad",
- "NAME_LONG": "Chad",
- "ABBREV": "Chad",
- "FORMAL_EN": "Republic of Chad",
- "POP_EST": 12075985,
- "POP_RANK": 14,
- "GDP_MD_EST": 30590,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TD",
- "ISO_A3": "TCD",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -69,
- 560,
- -290,
- -73
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Togo",
- "NAME_LONG": "Togo",
- "ABBREV": "Togo",
- "FORMAL_EN": "Togolese Republic",
- "POP_EST": 7965055,
- "POP_RANK": 13,
- "GDP_MD_EST": 11610,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TG",
- "ISO_A3": "TGO",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -395,
- 561,
- -459,
- 562,
- -438,
- -407
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Thailand",
- "NAME_LONG": "Thailand",
- "ABBREV": "Thai.",
- "FORMAL_EN": "Kingdom of Thailand",
- "POP_EST": 68414135,
- "POP_RANK": 16,
- "GDP_MD_EST": 1161000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TH",
- "ISO_A3": "THA",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -3,
- 563,
- -393,
- -167
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Tajikistan",
- "NAME_LONG": "Tajikistan",
- "ABBREV": "Tjk.",
- "FORMAL_EN": "Republic of Tajikistan",
- "POP_EST": 8468555,
- "POP_RANK": 13,
- "GDP_MD_EST": 25810,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TJ",
- "ISO_A3": "TJK",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -1,
- -357,
- 564,
- -385,
- 565
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Turkmenistan",
- "NAME_LONG": "Turkmenistan",
- "ABBREV": "Turkm.",
- "FORMAL_EN": "Turkmenistan",
- "POP_EST": 5351277,
- "POP_RANK": 13,
- "GDP_MD_EST": 94720,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TM",
- "ISO_A3": "TKM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -332,
- 566
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Timor-Leste",
- "NAME_LONG": "Timor-Leste",
- "ABBREV": "T.L.",
- "FORMAL_EN": "Democratic Republic of Timor-Leste",
- "POP_EST": 1291358,
- "POP_RANK": 12,
- "GDP_MD_EST": 4975,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TL",
- "ISO_A3": "TLS",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 567
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Trinidad and Tobago",
- "NAME_LONG": "Trinidad and Tobago",
- "ABBREV": "Tr.T.",
- "FORMAL_EN": "Republic of Trinidad and Tobago",
- "POP_EST": 1218208,
- "POP_RANK": 12,
- "GDP_MD_EST": 43570,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TT",
- "ISO_A3": "TTO",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -242,
- 568,
- -413
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Tunisia",
- "NAME_LONG": "Tunisia",
- "ABBREV": "Tun.",
- "FORMAL_EN": "Republic of Tunisia",
- "POP_EST": 11403800,
- "POP_RANK": 14,
- "GDP_MD_EST": 130800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TN",
- "ISO_A3": "TUN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -36,
- -355,
- -363,
- -560,
- 569,
- -287
- ]
- ],
- [
- [
- -83,
- 570,
- -304
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Turkey",
- "NAME_LONG": "Turkey",
- "ABBREV": "Tur.",
- "FORMAL_EN": "Republic of Turkey",
- "POP_EST": 80845215,
- "POP_RANK": 16,
- "GDP_MD_EST": 1670000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TR",
- "ISO_A3": "TUR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 571
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Taiwan",
- "NAME_LONG": "Taiwan",
- "ABBREV": "Taiwan",
- "FORMAL_EN": "",
- "POP_EST": 23508428,
- "POP_RANK": 15,
- "GDP_MD_EST": 1127000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TW",
- "ISO_A3": "TWN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -62,
- -532,
- 572,
- -390,
- 573,
- -443,
- -455,
- 574,
- -201
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Tanzania",
- "NAME_LONG": "Tanzania",
- "ABBREV": "Tanz.",
- "FORMAL_EN": "United Republic of Tanzania",
- "POP_EST": 53950935,
- "POP_RANK": 16,
- "GDP_MD_EST": 150600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TZ",
- "ISO_A3": "TZA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -199,
- -541,
- -391,
- -573,
- -531
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Uganda",
- "NAME_LONG": "Uganda",
- "ABBREV": "Uga.",
- "FORMAL_EN": "Republic of Uganda",
- "POP_EST": 39570125,
- "POP_RANK": 15,
- "GDP_MD_EST": 84930,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UG",
- "ISO_A3": "UGA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -96,
- -513,
- 575,
- -518,
- 576,
- -510,
- -428,
- -509,
- -327,
- -555,
- -497
- ],
- [
- 517,
- 518
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ukraine",
- "NAME_LONG": "Ukraine",
- "ABBREV": "Ukr.",
- "FORMAL_EN": "Ukraine",
- "POP_EST": 44033874,
- "POP_RANK": 15,
- "GDP_MD_EST": 352600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UA",
- "ISO_A3": "UKR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -30,
- -113,
- 577
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Uruguay",
- "NAME_LONG": "Uruguay",
- "ABBREV": "Ury.",
- "FORMAL_EN": "Oriental Republic of Uruguay",
- "POP_EST": 3360148,
- "POP_RANK": 12,
- "GDP_MD_EST": 73250,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UY",
- "ISO_A3": "URY",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- -141,
- 578,
- -432,
- 579
- ]
- ],
- [
- [
- -139,
- 580
- ]
- ],
- [
- [
- 581
- ]
- ],
- [
- [
- 582
- ]
- ],
- [
- [
- 583
- ]
- ],
- [
- [
- 584
- ]
- ],
- [
- [
- 585
- ]
- ],
- [
- [
- 586
- ]
- ],
- [
- [
- 587
- ]
- ],
- [
- [
- 588
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "United States of America",
- "NAME_LONG": "United States",
- "ABBREV": "U.S.A.",
- "FORMAL_EN": "United States of America",
- "POP_EST": 326625791,
- "POP_RANK": 17,
- "GDP_MD_EST": 18560000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "US",
- "ISO_A3": "USA",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Northern America"
- }
- },
- {
- "arcs": [
- [
- -2,
- -566,
- -384,
- -394,
- -564
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Uzbekistan",
- "NAME_LONG": "Uzbekistan",
- "ABBREV": "Uzb.",
- "FORMAL_EN": "Republic of Uzbekistan",
- "POP_EST": 29748859,
- "POP_RANK": 15,
- "GDP_MD_EST": 202300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UZ",
- "ISO_A3": "UZB",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -108,
- -210,
- 589,
- -313
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Venezuela",
- "NAME_LONG": "Venezuela",
- "ABBREV": "Ven.",
- "FORMAL_EN": "Bolivarian Republic of Venezuela",
- "POP_EST": 31304016,
- "POP_RANK": 15,
- "GDP_MD_EST": 468600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "VE",
- "ISO_A3": "VEN",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -175,
- 590,
- -397,
- -406
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Vietnam",
- "NAME_LONG": "Vietnam",
- "ABBREV": "Viet.",
- "FORMAL_EN": "Socialist Republic of Vietnam",
- "POP_EST": 96160163,
- "POP_RANK": 16,
- "GDP_MD_EST": 594900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "VN",
- "ISO_A3": "VNM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 591
- ]
- ],
- [
- [
- 592
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Vanuatu",
- "NAME_LONG": "Vanuatu",
- "ABBREV": "Van.",
- "FORMAL_EN": "Republic of Vanuatu",
- "POP_EST": 282814,
- "POP_RANK": 10,
- "GDP_MD_EST": 723,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "VU",
- "ISO_A3": "VUT",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -480,
- 593,
- -534
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Yemen",
- "NAME_LONG": "Yemen",
- "ABBREV": "Yem.",
- "FORMAL_EN": "Republic of Yemen",
- "POP_EST": 28036829,
- "POP_RANK": 15,
- "GDP_MD_EST": 73450,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "YE",
- "ISO_A3": "YEM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -118,
- 594,
- -447,
- -558,
- -445,
- 595,
- -461
- ],
- [
- -419
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "South Africa",
- "NAME_LONG": "South Africa",
- "ABBREV": "S.Af.",
- "FORMAL_EN": "Republic of South Africa",
- "POP_EST": 54841552,
- "POP_RANK": 16,
- "GDP_MD_EST": 739100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ZA",
- "ISO_A3": "ZAF",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- -10,
- -202,
- -575,
- -454,
- -449,
- 596,
- -120,
- -460
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Zambia",
- "NAME_LONG": "Zambia",
- "ABBREV": "Zambia",
- "FORMAL_EN": "Republic of Zambia",
- "POP_EST": 15972000,
- "POP_RANK": 14,
- "GDP_MD_EST": 65170,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ZM",
- "ISO_A3": "ZMB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -121,
- -597,
- -448,
- -595
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Zimbabwe",
- "NAME_LONG": "Zimbabwe",
- "ABBREV": "Zimb.",
- "FORMAL_EN": "Republic of Zimbabwe",
- "POP_EST": 13805084,
- "POP_RANK": 14,
- "GDP_MD_EST": 28330,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ZW",
- "ISO_A3": "ZWE",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- }
- ]
- }
- }
-}
diff --git a/explorer-nextjs/app/components/ComponentError.tsx b/explorer-nextjs/app/components/ComponentError.tsx
deleted file mode 100644
index 00b448fb9e..0000000000
--- a/explorer-nextjs/app/components/ComponentError.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Typography } from '@mui/material';
-import * as React from 'react';
-
-export const ComponentError: FCWithChildren<{ text: string }> = ({ text }) => (
-
- {text}
-
-);
diff --git a/explorer-nextjs/app/components/ContentCard.tsx b/explorer-nextjs/app/components/ContentCard.tsx
deleted file mode 100644
index c83049e5c7..0000000000
--- a/explorer-nextjs/app/components/ContentCard.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Card, CardHeader, CardContent, Typography } from '@mui/material'
-import React, { ReactEventHandler } from 'react'
-
-type ContentCardProps = {
- title?: React.ReactNode
- subtitle?: string
- Icon?: React.ReactNode
- Action?: React.ReactNode
- errorMsg?: string
- onClick?: ReactEventHandler
-}
-
-export const ContentCard: FCWithChildren = ({
- title,
- Icon,
- Action,
- subtitle,
- errorMsg,
- children,
- onClick,
-}) => (
-
- {title && (
-
- )}
- {children && {children}}
- {errorMsg && (
-
- {errorMsg}
-
- )}
-
-)
diff --git a/explorer-nextjs/app/components/CustomColumnHeading.tsx b/explorer-nextjs/app/components/CustomColumnHeading.tsx
deleted file mode 100644
index e767db34c1..0000000000
--- a/explorer-nextjs/app/components/CustomColumnHeading.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as React from 'react'
-import { Box, Typography } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import { Tooltip } from '@nymproject/react/tooltip/Tooltip'
-
-export const CustomColumnHeading: FCWithChildren<{
- headingTitle: string
- tooltipInfo?: string
-}> = ({ headingTitle, tooltipInfo }) => {
- const theme = useTheme()
-
- return (
-
- {tooltipInfo && (
-
- )}
-
- {headingTitle}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Delegations/ConfirmationModal.tsx b/explorer-nextjs/app/components/Delegations/ConfirmationModal.tsx
deleted file mode 100644
index 8e859f5eba..0000000000
--- a/explorer-nextjs/app/components/Delegations/ConfirmationModal.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import React from 'react';
-import {
- Breakpoint,
- Button,
- Paper,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- SxProps,
- Typography,
-} from '@mui/material';
-
-export interface ConfirmationModalProps {
- open: boolean;
- onConfirm: () => void;
- onClose?: () => void;
- children?: React.ReactNode;
- title: React.ReactNode | string;
- subTitle?: React.ReactNode | string;
- confirmButton: React.ReactNode | string;
- disabled?: boolean;
- sx?: SxProps;
- fullWidth?: boolean;
- maxWidth?: Breakpoint;
- backdropProps?: object;
-}
-
-export const ConfirmationModal = ({
- open,
- onConfirm,
- onClose,
- children,
- title,
- subTitle,
- confirmButton,
- disabled,
- sx,
- fullWidth,
- maxWidth,
- backdropProps,
-}: ConfirmationModalProps) => {
- const Title = (
-
- {title}
- {subTitle &&
- (typeof subTitle === 'string' ? (
-
- {subTitle}
-
- ) : (
- subTitle
- ))}
-
- );
- const ConfirmButton =
- typeof confirmButton === 'string' ? (
-
- ) : (
- confirmButton
- );
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/components/Delegations/DelegateIconButton.tsx b/explorer-nextjs/app/components/Delegations/DelegateIconButton.tsx
deleted file mode 100644
index 9ea2f54b6b..0000000000
--- a/explorer-nextjs/app/components/Delegations/DelegateIconButton.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import * as React from 'react'
-import { Button, IconButton } from '@mui/material'
-import { SxProps } from '@mui/system'
-import { useIsMobile } from '@/app/hooks'
-import { DelegateIcon } from '@/app/icons/DelevateSVG'
-
-export const DelegateIconButton: FCWithChildren<{
- size?: 'small' | 'medium'
- disabled?: boolean
- tooltip?: React.ReactNode
- sx?: SxProps
- onDelegate: () => void
-}> = ({ onDelegate, sx, disabled, size = 'medium' }) => {
- const isMobile = useIsMobile()
-
- const handleOnDelegate = () => {
- onDelegate()
- }
-
- if (isMobile) {
- return (
-
-
-
- )
- }
-
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/components/Delegations/DelegateModal.tsx b/explorer-nextjs/app/components/Delegations/DelegateModal.tsx
deleted file mode 100644
index 5b453e8ad5..0000000000
--- a/explorer-nextjs/app/components/Delegations/DelegateModal.tsx
+++ /dev/null
@@ -1,191 +0,0 @@
-'use client'
-
-import React, { useState } from 'react'
-import { Box, SxProps } from '@mui/material'
-import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'
-import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'
-import { CurrencyDenom, DecCoin } from '@nymproject/types'
-import { useWalletContext } from '@/app/context/wallet'
-import { urls } from '@/app/utils'
-import { useDelegationsContext } from '@/app/context/delegations'
-import { validateAmount } from '@/app/utils/currency'
-import { SimpleModal } from './SimpleModal'
-import { ModalListItem } from './ModalListItem'
-import { DelegationModalProps } from './DelegationModal'
-
-const MIN_AMOUNT_TO_DELEGATE = 10
-
-type Props = {
- mixId: number
- identityKey: string
- header?: string
- buttonText?: string
- rewardInterval?: string
- estimatedReward?: number
- profitMarginPercentage?: string | null
- nodeUptimePercentage?: number | null
- denom: CurrencyDenom
- sx?: SxProps
- backdropProps?: object
- onClose: () => void
- onOk?: (delegationModalProps: DelegationModalProps) => void
-}
-
-export const DelegateModal = ({
- mixId,
- identityKey,
- onClose,
- onOk,
- denom,
- sx,
-}: Props) => {
- const [amount, setAmount] = useState({
- amount: '10',
- denom: 'nym',
- })
- const [isValidated, setValidated] = useState(false)
- const [errorAmount, setErrorAmount] = useState()
-
- const { address, balance } = useWalletContext()
- const { handleDelegate } = useDelegationsContext()
-
- const validate = async () => {
- let newValidatedValue = true
- let errorAmountMessage
-
- if (amount && !(await validateAmount(amount.amount, '0'))) {
- newValidatedValue = false
- errorAmountMessage = 'Please enter a valid amount'
- }
-
- if (amount && +amount.amount < MIN_AMOUNT_TO_DELEGATE) {
- errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}`
- newValidatedValue = false
- }
-
- if (!amount?.amount.length) {
- newValidatedValue = false
- }
-
- if (amount && balance.data && +balance.data - +amount.amount <= 0) {
- errorAmountMessage = 'Not enough funds'
- newValidatedValue = false
- }
-
- setErrorAmount(errorAmountMessage)
- setValidated(newValidatedValue)
- }
-
- const delegateToMixnode = async ({
- delegationMixId,
- delegationAmount,
- }: {
- delegationMixId: number
- delegationAmount: string
- }) => {
- try {
- const tx = await handleDelegate(delegationMixId, delegationAmount)
- return tx
- } catch (e) {
- console.error('Failed to delegate to mixnode', e)
- throw e
- }
- }
-
- const handleConfirm = async () => {
- if (mixId && amount && onOk) {
- onOk({
- status: 'loading',
- })
- try {
- if (!address) {
- throw new Error('Please connect your wallet')
- }
-
- const tx = await delegateToMixnode({
- delegationMixId: mixId,
- delegationAmount: amount.amount,
- })
-
- if (!tx) {
- throw new Error('Failed to delegate')
- }
-
- onOk({
- status: 'success',
- message: 'Delegation can take up to one hour to process',
- transactions: [
- {
- url: `${urls('MAINNET').blockExplorer}/transaction/${
- tx.transactionHash
- }`,
- hash: tx.transactionHash,
- },
- ],
- })
- } catch (e) {
- console.error('Failed to delegate', e)
- onOk({
- status: 'error',
- message: (e as Error).message,
- })
- }
- }
- }
-
- const handleAmountChanged = (newAmount: DecCoin) => {
- setAmount(newAmount)
- }
-
- React.useEffect(() => {
- validate()
- }, [amount, identityKey, mixId])
-
- return (
-
-
- undefined}
- initialValue={identityKey}
- readOnly
- showTickOnValid={false}
- />
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Delegations/DelegationModal.tsx b/explorer-nextjs/app/components/Delegations/DelegationModal.tsx
deleted file mode 100644
index 76c37a9e96..0000000000
--- a/explorer-nextjs/app/components/Delegations/DelegationModal.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import React from 'react'
-import { Typography, SxProps, Stack } from '@mui/material'
-import { Link } from '@nymproject/react/link/Link'
-import { LoadingModal } from './LoadingModal'
-import { ConfirmationModal } from './ConfirmationModal'
-import { ErrorModal } from './ErrorModal'
-
-export type DelegationModalProps = {
- status: 'loading' | 'success' | 'error' | 'info'
- message?: string
- transactions?: {
- url: string
- hash: string
- }[]
-}
-
-export const DelegationModal: FCWithChildren<
- DelegationModalProps & {
- open: boolean
- onClose: () => void
- sx?: SxProps
- backdropProps?: object
- children?: React.ReactNode
- }
-> = ({
- status,
- message,
- transactions,
- open,
- onClose,
- children,
- sx,
- backdropProps,
-}) => {
- if (status === 'loading')
- return
-
- if (status === 'error') {
- return (
-
- {children}
-
- )
- }
-
- if (status === 'info') {
- return (
-
- {message}
-
- )
- }
-
- return (
- {})}
- title="Transaction successful"
- confirmButton="Done"
- >
-
- {message && {message}}
- {transactions?.length === 1 && (
-
- )}
- {transactions && transactions.length > 1 && (
-
- View the transactions on blockchain:
- {transactions.map(({ url, hash }) => (
-
- ))}
-
- )}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Delegations/ErrorModal.tsx b/explorer-nextjs/app/components/Delegations/ErrorModal.tsx
deleted file mode 100644
index b9218d1e1e..0000000000
--- a/explorer-nextjs/app/components/Delegations/ErrorModal.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import { Box, Button, Modal, SxProps, Typography } from '@mui/material';
-import { modalStyle } from './SimpleModal';
-
-export const ErrorModal: FCWithChildren<{
- open: boolean;
- title?: string;
- message?: string;
- sx?: SxProps;
- backdropProps?: object;
- onClose: () => void;
- children?: React.ReactNode;
-}> = ({ children, open, title, message, sx, backdropProps, onClose }) => (
-
-
- theme.palette.error.main} mb={1}>
- {title || 'Oh no! Something went wrong...'}
-
-
- {message}
-
- {children}
-
-
-
-);
diff --git a/explorer-nextjs/app/components/Delegations/LoadingModal.tsx b/explorer-nextjs/app/components/Delegations/LoadingModal.tsx
deleted file mode 100644
index eda13938d4..0000000000
--- a/explorer-nextjs/app/components/Delegations/LoadingModal.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { Box, CircularProgress, Modal, Stack, Typography, SxProps } from '@mui/material';
-import { modalStyle } from './SimpleModal';
-
-export const LoadingModal: FCWithChildren<{
- text?: string;
- sx?: SxProps;
- backdropProps?: object;
-}> = ({ sx, text = 'Please wait...' }) => (
-
-
-
-
- {text}
-
-
-
-);
diff --git a/explorer-nextjs/app/components/Delegations/ModalDivider.tsx b/explorer-nextjs/app/components/Delegations/ModalDivider.tsx
deleted file mode 100644
index 6258e0bfac..0000000000
--- a/explorer-nextjs/app/components/Delegations/ModalDivider.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react';
-import { Box, SxProps } from '@mui/material';
-
-export const ModalDivider: FCWithChildren<{
- sx?: SxProps;
-}> = ({ sx }) => ;
diff --git a/explorer-nextjs/app/components/Delegations/ModalListItem.tsx b/explorer-nextjs/app/components/Delegations/ModalListItem.tsx
deleted file mode 100644
index 830c25705e..0000000000
--- a/explorer-nextjs/app/components/Delegations/ModalListItem.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react';
-import { Box, Stack, SxProps, Typography, TypographyProps } from '@mui/material';
-import { ModalDivider } from './ModalDivider';
-
-export const ModalListItem: FCWithChildren<{
- label: string;
- divider?: boolean;
- hidden?: boolean;
- fontWeight?: TypographyProps['fontWeight'];
- fontSize?: TypographyProps['fontSize'];
- light?: boolean;
- value?: React.ReactNode;
- sxValue?: SxProps;
-}> = ({ label, value, hidden, fontWeight, fontSize, divider, sxValue }) => (
-
-
-
- {label}
-
- {value && (
-
- {value}
-
- )}
-
- {divider && }
-
-);
diff --git a/explorer-nextjs/app/components/Delegations/SimpleModal.tsx b/explorer-nextjs/app/components/Delegations/SimpleModal.tsx
deleted file mode 100644
index b1909c8c5e..0000000000
--- a/explorer-nextjs/app/components/Delegations/SimpleModal.tsx
+++ /dev/null
@@ -1,152 +0,0 @@
-import React from 'react'
-import { Box, Button, Modal, Stack, SxProps, Typography } from '@mui/material'
-import CloseIcon from '@mui/icons-material/Close'
-import ErrorOutline from '@mui/icons-material/ErrorOutline'
-import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'
-import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-
-export const modalStyle = (width: number | string = 600) => ({
- position: 'absolute' as 'absolute',
- top: '50%',
- left: '50%',
- width,
- transform: 'translate(-50%, -50%)',
- bgcolor: 'background.paper',
- boxShadow: 24,
- borderRadius: '16px',
- p: 4,
-})
-
-export const StyledBackButton = ({
- onBack,
- label,
- fullWidth,
- sx,
-}: {
- onBack: () => void
- label?: string
- fullWidth?: boolean
- sx?: SxProps
-}) => (
-
-)
-
-export const SimpleModal: FCWithChildren<{
- open: boolean
- hideCloseIcon?: boolean
- displayErrorIcon?: boolean
- displayInfoIcon?: boolean
- headerStyles?: SxProps
- subHeaderStyles?: SxProps
- buttonFullWidth?: boolean
- onClose?: () => void
- onOk?: () => Promise
- onBack?: () => void
- header: string | React.ReactNode
- subHeader?: string
- okLabel: string
- backLabel?: string
- backButtonFullWidth?: boolean
- okDisabled?: boolean
- sx?: SxProps
- children?: React.ReactNode
-}> = ({
- open,
- hideCloseIcon,
- displayErrorIcon,
- displayInfoIcon,
- headerStyles,
- buttonFullWidth,
- onClose,
- okDisabled,
- onOk,
- onBack,
- header,
- subHeader,
- okLabel,
- backLabel,
- backButtonFullWidth,
- sx,
- children,
-}) => {
- const isMobile = useIsMobile()
-
- return (
-
-
- {displayErrorIcon && }
- {displayInfoIcon && }
-
- {typeof header === 'string' ? (
-
- {header}
-
- ) : (
- header
- )}
- {!hideCloseIcon && }
-
-
- theme.palette.text.secondary}
- >
- {subHeader}
-
-
- {children}
-
- {(onOk || onBack) && (
-
- {onBack && (
-
- )}
- {onOk && (
-
- )}
-
- )}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Delegations/index.ts b/explorer-nextjs/app/components/Delegations/index.ts
deleted file mode 100644
index da51de9bd9..0000000000
--- a/explorer-nextjs/app/components/Delegations/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export * from './ConfirmationModal';
-export * from './DelegateIconButton';
-export * from './DelegationModal';
-export * from './DelegateModal';
-export * from './ErrorModal';
-export * from './LoadingModal';
-export * from './ModalDivider';
-export * from './ModalListItem';
-export * from './SimpleModal';
-export * from './styles';
diff --git a/explorer-nextjs/app/components/Delegations/styles.ts b/explorer-nextjs/app/components/Delegations/styles.ts
deleted file mode 100644
index 9b26551767..0000000000
--- a/explorer-nextjs/app/components/Delegations/styles.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Theme } from '@mui/material/styles';
-
-export const backDropStyles = (theme: Theme) => {
- const { mode } = theme.palette;
- return {
- style: {
- left: mode === 'light' ? '0' : '50%',
- width: '50%',
- },
- };
-};
-
-export const modalStyles = (theme: Theme) => {
- const { mode } = theme.palette;
- return { left: mode === 'light' ? '25%' : '75%' };
-};
-
-export const dialogStyles = (theme: Theme) => {
- const { mode } = theme.palette;
- return { left: mode === 'light' ? '-50%' : '50%' };
-};
diff --git a/explorer-nextjs/app/components/DetailTable.tsx b/explorer-nextjs/app/components/DetailTable.tsx
deleted file mode 100644
index b068a5c852..0000000000
--- a/explorer-nextjs/app/components/DetailTable.tsx
+++ /dev/null
@@ -1,146 +0,0 @@
-import * as React from 'react'
-import {
- Link,
- Paper,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- TableCellProps,
-} from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import { Tooltip } from '@nymproject/react/tooltip/Tooltip'
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'
-import { Box } from '@mui/system'
-import { unymToNym } from '@/app/utils/currency'
-import { GatewayEnrichedRowType } from './Gateways/Gateways'
-import { MixnodeRowType } from './MixNodes'
-import { StakeSaturationProgressBar } from './MixNodes/Economics/StakeSaturationProgressBar'
-import {EXPLORER_FOR_ACCOUNTS} from "@/app/api/constants";
-
-export type ColumnsType = {
- field: string
- title: string
- headerAlign?: TableCellProps['align']
- width?: string | number
- tooltipInfo?: string
-}
-
-export interface UniversalTableProps {
- tableName: string
- columnsData: ColumnsType[]
- rows: T[]
-}
-
-function formatCellValues(val: string | number, field: string) {
- if (field === 'identity_key' && typeof val === 'string') {
- return (
-
-
- {val}
-
- )
- }
-
- if (field === 'bond') {
- return unymToNym(val, 6)
- }
-
- if (field === 'owner') {
- return (
-
- {val}
-
- )
- }
-
- if (field === 'stake_saturation') {
- return
- }
-
- return val
-}
-
-export const DetailTable: FCWithChildren<{
- tableName: string
- columnsData: ColumnsType[]
- rows: MixnodeRowType[] | GatewayEnrichedRowType[] | any[]
-}> = ({ tableName, columnsData, rows }: UniversalTableProps) => {
- const theme = useTheme()
- return (
-
-
-
-
- {columnsData?.map(({ field, title, width, tooltipInfo }) => (
-
-
- {tooltipInfo && (
-
-
-
- )}
- {title}
-
-
- ))}
-
-
-
- {rows.map((eachRow) => (
-
- {columnsData?.map((data, index) => (
-
- {formatCellValues(
- eachRow[columnsData[index].field],
- columnsData[index].field
- )}
-
- ))}
-
- ))}
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Filters/Filters.tsx b/explorer-nextjs/app/components/Filters/Filters.tsx
deleted file mode 100644
index 3a871a5fb4..0000000000
--- a/explorer-nextjs/app/components/Filters/Filters.tsx
+++ /dev/null
@@ -1,193 +0,0 @@
-'use client'
-
-import React, { useState, useEffect, useRef, useCallback } from 'react'
-import {
- Button,
- Dialog,
- DialogContent,
- DialogActions,
- DialogTitle,
- Slider,
- Typography,
- Box,
- Snackbar,
- Slide,
- Alert,
-} from '@mui/material'
-import { useParams } from 'next/navigation'
-import { useMainContext } from '@/app/context/main'
-import {
- MixnodeStatusWithAll,
- toMixnodeStatus,
-} from '@/app/typeDefs/explorer-api'
-import { EnumFilterKey, TFilterItem, TFilters } from '@/app/typeDefs/filters'
-import { Api } from '@/app/api'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { formatOnSave, generateFilterSchema } from './filterSchema'
-import FiltersButton from './FiltersButton'
-
-const FilterItem = ({
- label,
- id,
- tooltipInfo,
- value,
- isSmooth,
- marks,
- scale,
- min,
- max,
- onChange,
-}: TFilterItem & {
- onChange: (id: EnumFilterKey, newValue: number[]) => void
-}) => (
-
- {label}
- {tooltipInfo}
-
- onChange(id, newValue as number[])
- }
- valueLabelDisplay={isSmooth ? 'auto' : 'off'}
- marks={marks}
- step={isSmooth ? 1 : null}
- scale={scale}
- min={min}
- max={max}
- valueLabelFormat={(val: number) =>
- val === 100 && id === 'stakeSaturation' ? '>100' : val
- }
- />
-
-)
-
-export const Filters = () => {
- const { filterMixnodes, fetchMixnodes, mixnodes } = useMainContext()
- const { status } = useParams<{
- status: 'active' | 'standby' | 'inactive' | 'all'
- }>()
- const isMobile = useIsMobile()
-
- const [showFilters, setShowFilters] = useState(false)
- const [isFiltered, setIsFiltered] = useState(false)
- const [filters, setFilters] = React.useState()
- const [upperSaturationValue, setUpperSaturationValue] =
- React.useState(100)
-
- const baseFilters = useRef()
- const prevFilters = useRef()
-
- const handleToggleShowFilters = () => setShowFilters(!showFilters)
-
- const initialiseFilters = useCallback(async () => {
- const allMixnodes = await Api.fetchMixnodes()
- if (allMixnodes) {
- setUpperSaturationValue(
- Math.round(
- Math.max(...allMixnodes.map((m) => m.stake_saturation)) * 100 + 1
- )
- )
- const initFilters = generateFilterSchema()
- baseFilters.current = initFilters
- prevFilters.current = initFilters
- setFilters(initFilters)
- }
- }, [])
-
- const handleOnChange = (id: EnumFilterKey, newValue: number[]) => {
- if (id === 'stakeSaturation' && newValue[1] === 100) {
- newValue.splice(1, 1, upperSaturationValue)
- }
- setFilters((ftrs) => {
- if (ftrs)
- return {
- ...ftrs,
- [id]: {
- ...ftrs[id],
- value: newValue,
- },
- }
- return undefined
- })
- }
-
- const handleOnSave = async () => {
- setShowFilters(false)
- await filterMixnodes(formatOnSave(filters!), status)
- setIsFiltered(true)
- prevFilters.current = filters
- }
-
- const handleOnCancel = () => {
- setShowFilters(false)
- setFilters(prevFilters.current)
- }
-
- const resetFilters = () => {
- setFilters(baseFilters.current)
- setIsFiltered(false)
- prevFilters.current = baseFilters.current
- }
-
- const onClearFilters = async () => {
- await fetchMixnodes(toMixnodeStatus(MixnodeStatusWithAll[status]))
- resetFilters()
- }
-
- useEffect(() => {
- initialiseFilters()
- }, [initialiseFilters])
-
- useEffect(() => {
- resetFilters()
- }, [status])
-
- if (!filters) return null
-
- return (
- <>
-
- t.palette.info.light }}
- action={
-
- }
- >
- {mixnodes?.data?.length} mixnodes matched your criteria
-
-
-
-
- >
- )
-}
diff --git a/explorer-nextjs/app/components/Filters/FiltersButton.tsx b/explorer-nextjs/app/components/Filters/FiltersButton.tsx
deleted file mode 100644
index 1e6d3e2940..0000000000
--- a/explorer-nextjs/app/components/Filters/FiltersButton.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react';
-import { Button, IconButton } from '@mui/material';
-import { Tune } from '@mui/icons-material';
-
-type FiltersButtonProps = {
- iconOnly?: boolean;
- fullWidth?: boolean;
- onClick: () => void;
-};
-
-const FiltersButton = ({ iconOnly, fullWidth, onClick }: FiltersButtonProps) => {
- if (iconOnly) {
- return (
-
-
-
- );
- }
-
- return (
- }
- onClick={onClick}
- sx={{ textTransform: 'none' }}
- >
- Filters
-
- );
-};
-
-export default FiltersButton;
diff --git a/explorer-nextjs/app/components/Filters/filterSchema.ts b/explorer-nextjs/app/components/Filters/filterSchema.ts
deleted file mode 100644
index c5011114b1..0000000000
--- a/explorer-nextjs/app/components/Filters/filterSchema.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { EnumFilterKey, TFilters } from '../../typeDefs/filters';
-
-export const generateFilterSchema = () => ({
- profitMargin: {
- label: 'Profit margin (%)',
- id: EnumFilterKey.profitMargin,
- value: [0, 100],
- isSmooth: true,
- marks: [
- { label: '0', value: 0 },
- { label: '10', value: 10 },
- { label: '20', value: 20 },
- { label: '30', value: 30 },
- { label: '40', value: 40 },
- { label: '50', value: 50 },
- { label: '60', value: 60 },
- { label: '70', value: 70 },
- { label: '80', value: 80 },
- { label: '90', value: 90 },
- { label: '100', value: 100 },
- ],
- tooltipInfo:
- 'As a delegator you want to chose nodes with lower profit margin, meaning more payout for their delegators',
- },
- stakeSaturation: {
- label: 'Stake saturation (%)',
- id: EnumFilterKey.stakeSaturation,
- value: [0, 100],
- isSmooth: true,
- marks: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) => ({
- value: value < 100 ? value : 100,
- label: value < 100 ? value : '>100',
- })),
- tooltipInfo: "Select nodes with <100% saturation. Any additional stake above 100% saturation won't get rewards",
- },
- routingScore: {
- label: 'Routing score (%)',
- id: EnumFilterKey.routingScore,
- value: [0, 100],
- isSmooth: true,
- marks: [
- { label: '0', value: 0 },
- { label: '10', value: 10 },
- { label: '20', value: 20 },
- { label: '30', value: 30 },
- { label: '40', value: 40 },
- { label: '50', value: 50 },
- { label: '60', value: 60 },
- { label: '70', value: 70 },
- { label: '80', value: 80 },
- { label: '90', value: 90 },
- { label: '100', value: 100 },
- ],
- tooltipInfo: 'The higher the routing score the better the performance of the node and so its rewards',
- },
-});
-
-const formatStakeSaturationValues = ([value_1, value_2]: number[]) => {
- const lowerValue = value_1 / 100;
- const upperValue = value_2 / 100;
-
- return [lowerValue, upperValue];
-};
-
-export const formatOnSave = (filters: TFilters) => ({
- routingScore: filters.routingScore.value,
- profitMargin: filters.profitMargin.value,
- stakeSaturation: formatStakeSaturationValues(filters.stakeSaturation.value),
-});
diff --git a/explorer-nextjs/app/components/Footer.tsx b/explorer-nextjs/app/components/Footer.tsx
deleted file mode 100644
index 3e69bd3c42..0000000000
--- a/explorer-nextjs/app/components/Footer.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import React from 'react'
-import Box from '@mui/material/Box'
-import MuiLink from '@mui/material/Link'
-import Typography from '@mui/material/Typography'
-import { useIsMobile } from '../hooks/useIsMobile'
-import { NymVpnIcon } from '../icons/NymVpn'
-import { Socials } from './Socials'
-import Link from 'next/link'
-
-export const Footer: FCWithChildren = () => {
- const isMobile = useIsMobile()
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- © {new Date().getFullYear()} Nym Technologies SA, all rights reserved
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Gateways/Gateways.ts b/explorer-nextjs/app/components/Gateways/Gateways.ts
deleted file mode 100644
index f4dbf2743c..0000000000
--- a/explorer-nextjs/app/components/Gateways/Gateways.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import {GatewayResponse, GatewayBond, GatewayReportResponse, LocatedGateway} from '@/app/typeDefs/explorer-api';
-import { toPercentInteger } from '@/app/utils';
-
-export type GatewayRowType = {
- id: string;
- owner: string;
- identity_key: string;
- bond: number;
- host: string;
- location: string;
- version: string;
-// node_performance: number;
-};
-
-export type GatewayEnrichedRowType = GatewayRowType & {
- routingScore: string;
- avgUptime: string;
- clientsPort: number;
- mixPort: number;
-};
-
-export function gatewayToGridRow(arrayOfGateways: GatewayResponse): GatewayRowType[] {
- return !arrayOfGateways
- ? []
- : arrayOfGateways.map((gw) => ({
- id: gw.owner,
- owner: gw.owner,
- identity_key: gw.gateway.identity_key || '',
- location: gw.location?.country_name.toUpperCase() || '',
- bond: gw.pledge_amount.amount || 0,
- host: gw.gateway.host || '',
- version: gw.gateway.version || '',
-// node_performance: toPercentInteger(gw.node_performance.last_24h),
- }));
-}
-
-export function gatewayEnrichedToGridRow(gateway: LocatedGateway, report: GatewayReportResponse): GatewayEnrichedRowType {
- return {
- id: gateway.owner,
- owner: gateway.owner,
- identity_key: gateway.gateway.identity_key || '',
- location: gateway.location?.country_name.toUpperCase() || '',
- bond: gateway.pledge_amount.amount || 0,
- host: gateway.gateway.host || '',
- version: gateway.gateway.version || '',
- clientsPort: gateway.gateway.clients_port || 0,
- mixPort: gateway.gateway.mix_port || 0,
- routingScore: `${report.most_recent}%`,
- avgUptime: `${report.last_day || report.last_hour}%`,
-// node_performance: toPercentInteger(gateway.node_performance.most_recent),
- };
-}
diff --git a/explorer-nextjs/app/components/Gateways/VersionDisplaySelector.tsx b/explorer-nextjs/app/components/Gateways/VersionDisplaySelector.tsx
deleted file mode 100644
index 10f230e26a..0000000000
--- a/explorer-nextjs/app/components/Gateways/VersionDisplaySelector.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import React from 'react'
-import { FormControl, MenuItem, Select } from '@mui/material'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-
-export enum VersionSelectOptions {
- latestVersion = 'Latest versions',
- olderVersions = 'Older versions',
- all = 'All',
-}
-export const VersionDisplaySelector = ({
- selected,
- handleChange,
-}: {
- selected: VersionSelectOptions
- handleChange: (option: VersionSelectOptions) => void
-}) => {
- const isMobile = useIsMobile()
-
- return (
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Icons.ts b/explorer-nextjs/app/components/Icons.ts
deleted file mode 100644
index 88761b9d21..0000000000
--- a/explorer-nextjs/app/components/Icons.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
-import PauseCircleOutlineIcon from '@mui/icons-material/PauseCircleOutline';
-import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined';
-import { MixnodeStatus } from '../typeDefs/explorer-api';
-
-export const Icons = {
- Mixnodes: {
- Status: {
- Active: CheckCircleOutlineIcon,
- Standby: PauseCircleOutlineIcon,
- Inactive: CircleOutlinedIcon,
- },
- },
-};
-
-export const getMixNodeIcon = (value: any) => {
- if (value && typeof value === 'string') {
- switch (value) {
- case MixnodeStatus.active:
- return Icons.Mixnodes.Status.Active;
- case MixnodeStatus.standby:
- return Icons.Mixnodes.Status.Standby;
- default:
- return Icons.Mixnodes.Status.Inactive;
- }
- }
- return Icons.Mixnodes.Status.Inactive;
-};
diff --git a/explorer-nextjs/app/components/MixNodes/BondBreakdown.tsx b/explorer-nextjs/app/components/MixNodes/BondBreakdown.tsx
deleted file mode 100644
index 58ea4c97b2..0000000000
--- a/explorer-nextjs/app/components/MixNodes/BondBreakdown.tsx
+++ /dev/null
@@ -1,213 +0,0 @@
-import * as React from 'react'
-import { Alert, Box, CircularProgress, Typography } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import Table from '@mui/material/Table'
-import TableBody from '@mui/material/TableBody'
-import TableCell from '@mui/material/TableCell'
-import TableContainer from '@mui/material/TableContainer'
-import TableHead from '@mui/material/TableHead'
-import TableRow from '@mui/material/TableRow'
-import Paper from '@mui/material/Paper'
-import { ExpandMore } from '@mui/icons-material'
-import { currencyToString } from '@/app/utils/currency'
-import { useMixnodeContext } from '@/app/context/mixnode'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-
-export const BondBreakdownTable: FCWithChildren = () => {
- const { mixNode, delegations, uniqDelegations } = useMixnodeContext()
- const [showDelegations, toggleShowDelegations] =
- React.useState(false)
-
- const [bonds, setBonds] = React.useState({
- delegations: '0',
- pledges: '0',
- bondsTotal: '0',
- hasLoaded: false,
- })
- const theme = useTheme()
- const isMobile = useIsMobile()
-
- React.useEffect(() => {
- if (mixNode?.data) {
- // delegations
- const decimalisedDelegations = currencyToString({
- amount: mixNode.data.total_delegation.amount.toString(),
- denom: mixNode.data.total_delegation.denom,
- })
-
- // pledges
- const decimalisedPledges = currencyToString({
- amount: mixNode.data.pledge_amount.amount.toString(),
- denom: mixNode.data.pledge_amount.denom,
- })
-
- // bonds total (del + pledges)
- const pledgesSum = Number(mixNode.data.pledge_amount.amount)
- const delegationsSum = Number(mixNode.data.total_delegation.amount)
- const bondsTotal = currencyToString({
- amount: (pledgesSum + delegationsSum).toString(),
- })
-
- setBonds({
- delegations: decimalisedDelegations,
- pledges: decimalisedPledges,
- bondsTotal,
- hasLoaded: true,
- })
- }
- }, [mixNode])
-
- const expandDelegations = () => {
- if (delegations?.data && delegations.data.length > 0) {
- toggleShowDelegations(!showDelegations)
- }
- }
- const calcBondPercentage = (num: number) => {
- if (mixNode?.data) {
- const rawDelegationAmount = Number(mixNode.data.total_delegation.amount)
- const rawPledgeAmount = Number(mixNode.data.pledge_amount.amount)
- const rawTotalBondsAmount = rawDelegationAmount + rawPledgeAmount
- return ((num * 100) / rawTotalBondsAmount).toFixed(1)
- }
- return 0
- }
-
- if (mixNode?.isLoading || delegations?.isLoading) {
- return
- }
-
- if (mixNode?.error) {
- return Mixnode not found
- }
- if (delegations?.error) {
- return Unable to get delegations for mixnode
- }
-
- return (
-
-
-
-
-
- Stake total
-
-
- {bonds.bondsTotal}
-
-
-
- Bond
-
- {bonds.pledges}
-
-
-
-
-
- Delegation total {'\u00A0'}
- {delegations?.data && delegations?.data?.length > 0 && (
-
- )}
-
-
-
- {bonds.delegations}
-
-
-
-
-
- {showDelegations && (
-
-
-
- Delegations
-
-
-
-
-
-
- Delegators
-
-
- Amount
-
-
- Share of stake
-
-
-
-
-
- {uniqDelegations?.data?.map(({ owner, amount: { amount } }) => (
-
-
- {owner}
-
-
- {currencyToString({ amount: amount.toString() })}
-
-
- {calcBondPercentage(amount)}%
-
-
- ))}
-
-
-
- )}
-
- )
-}
diff --git a/explorer-nextjs/app/components/MixNodes/DetailSection.tsx b/explorer-nextjs/app/components/MixNodes/DetailSection.tsx
deleted file mode 100644
index 94a24f338d..0000000000
--- a/explorer-nextjs/app/components/MixNodes/DetailSection.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import * as React from 'react'
-import { Box, Button, Grid, Typography, useTheme } from '@mui/material'
-import Identicon from 'react-identicons'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { MixNodeDescriptionResponse } from '@/app/typeDefs/explorer-api'
-import { getMixNodeStatusText, MixNodeStatus } from './Status'
-import { MixnodeRowType } from '.'
-
-interface MixNodeDetailProps {
- mixNodeRow: MixnodeRowType
- mixnodeDescription: MixNodeDescriptionResponse
-}
-
-export const MixNodeDetailSection: FCWithChildren = ({
- mixNodeRow,
- mixnodeDescription,
-}) => {
- const theme = useTheme()
- const palette = [theme.palette.text.primary]
- const isMobile = useIsMobile()
- const statusText = React.useMemo(
- () => getMixNodeStatusText(mixNodeRow.status),
- [mixNodeRow.status]
- )
-
- return (
-
-
-
-
-
-
-
- {mixnodeDescription.name}
-
- {(mixnodeDescription.description || '').slice(0, 1000)}
-
-
-
-
-
-
-
-
- Node status:
-
-
-
-
-
- This node is {statusText} in this epoch
-
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/Columns.ts b/explorer-nextjs/app/components/MixNodes/Economics/Columns.ts
deleted file mode 100644
index b2115c0749..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/Columns.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { ColumnsType } from '../../DetailTable';
-
-export const EconomicsInfoColumns: ColumnsType[] = [
- {
- field: 'estimatedTotalReward',
- title: 'Estimated Total Reward',
- width: '15%',
- tooltipInfo:
- 'Estimated node reward (total for the operator and delegators) in the current epoch. There are roughly 24 epochs in a day.',
- },
- {
- field: 'estimatedOperatorReward',
- title: 'Estimated Operator Reward',
- width: '15%',
- tooltipInfo:
- "Estimated operator's reward (including PM and Operating Cost) in the current epoch. There are roughly 24 epochs in a day.",
- },
- {
- field: 'selectionChance',
- title: 'Active Set Probability',
- width: '12.5%',
- tooltipInfo:
- 'Probability of getting selected in the reward set (active and standby nodes) in the next epoch. The more your stake, the higher the chances to be selected.',
- },
- {
- field: 'profitMargin',
- title: 'Profit Margin',
- width: '12.5%',
- tooltipInfo:
- 'Percentage of the delegators rewards that the operator takes as fee before rewards are distributed to the delegators.',
- },
- {
- field: 'operatingCost',
- title: 'Operating Cost',
- width: '10%',
- tooltipInfo:
- 'Monthly operational cost of running this node. This cost is set by the operator and it influences how the rewards are split between the operator and delegators.',
- },
- {
- field: 'nodePerformance',
- title: 'Routing Score',
- width: '10%',
- tooltipInfo:
- "Mixnode's most recent score (measured in the last 15 minutes). Routing score is relative to that of the network. Each time a gateway is tested, the test packets have to go through the full path of the network (gateway + 3 nodes). If a node in the path drop packets it will affect the score of the gateway and other nodes in the test.",
- },
- {
- field: 'avgUptime',
- title: 'Avg. Score',
- tooltipInfo: "Mixnode's average routing score in the last 24 hour",
- },
-];
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.stories.tsx b/explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.stories.tsx
deleted file mode 100644
index aef36113df..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.stories.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import * as React from 'react';
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { EconomicsProgress } from './EconomicsProgress';
-
-export default {
- title: 'Mix Node Detail/Economics/ProgressBar',
- component: EconomicsProgress,
-} as ComponentMeta;
-
-const Template: ComponentStory = (args) => ;
-
-export const Empty = Template.bind({});
-Empty.args = {};
-
-export const OverThreshold = Template.bind({});
-OverThreshold.args = {
- threshold: 100,
- value: 120,
-};
-
-export const UnderThreshold = Template.bind({});
-UnderThreshold.args = {
- threshold: 100,
- value: 80,
-};
-
-export const OnThreshold = Template.bind({});
-OnThreshold.args = {
- threshold: 100,
- value: 100,
-};
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.tsx b/explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.tsx
deleted file mode 100644
index 24db62d167..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/EconomicsProgress.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import * as React from 'react';
-import LinearProgress, { LinearProgressProps } from '@mui/material/LinearProgress';
-import { useTheme } from '@mui/material/styles';
-import { Box } from '@mui/system';
-
-const parseToNumber = (value: number | undefined | string) =>
- typeof value === 'string' ? parseInt(value || '', 10) : value || 0;
-
-export const EconomicsProgress: FCWithChildren<
- LinearProgressProps & {
- threshold?: number;
- color: string;
- }
-> = ({ threshold, color, ...props }) => {
- const theme = useTheme();
- const { value } = props;
-
- const valueNumber: number = parseToNumber(value);
- const thresholdNumber: number = parseToNumber(threshold);
- const percentageToDisplay = Math.min(valueNumber, thresholdNumber);
-
- return (
- (threshold || 100) ? theme.palette.warning.main : theme.palette.nym.wallet.fee,
- }}
- >
-
-
- );
-};
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/MixNodeEconomics.stories.tsx b/explorer-nextjs/app/components/MixNodes/Economics/MixNodeEconomics.stories.tsx
deleted file mode 100644
index c9c82c0438..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/MixNodeEconomics.stories.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import * as React from 'react';
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { DelegatorsInfoTable } from './Table';
-import { EconomicsInfoColumns } from './Columns';
-import { EconomicsInfoRowWithIndex } from './types';
-
-export default {
- title: 'Mix Node Detail/Economics',
- component: DelegatorsInfoTable,
-} as ComponentMeta;
-
-const row: EconomicsInfoRowWithIndex = {
- id: 1,
- selectionChance: {
- value: 'High',
- },
-
- estimatedOperatorReward: {
- value: '80000.123456 NYM',
- },
- estimatedTotalReward: {
- value: '80000.123456 NYM',
- },
- profitMargin: {
- value: '10 %',
- },
- operatingCost: {
- value: '11121 NYM',
- },
- avgUptime: {
- value: '-',
- },
- nodePerformance: {
- value: '-',
- },
-};
-
-const rowGoodProbabilitySelection: EconomicsInfoRowWithIndex = {
- ...row,
- selectionChance: {
- value: 'Good',
- },
-};
-
-const rowLowProbabilitySelection: EconomicsInfoRowWithIndex = {
- ...row,
- selectionChance: {
- value: 'Low',
- },
-};
-
-const emptyRow: EconomicsInfoRowWithIndex = {
- id: 1,
- selectionChance: {
- value: '-',
- progressBarValue: 0,
- },
-
- estimatedOperatorReward: {
- value: '-',
- },
- estimatedTotalReward: {
- value: '-',
- },
- profitMargin: {
- value: '-',
- },
- operatingCost: {
- value: '-',
- },
- avgUptime: {
- value: '-',
- },
- nodePerformance: {
- value: '-',
- },
-};
-
-const Template: ComponentStory = (args) => ;
-
-export const Empty = Template.bind({});
-Empty.args = {
- rows: [emptyRow],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
-
-export const selectionChanceHigh = Template.bind({});
-selectionChanceHigh.args = {
- rows: [row],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
-
-export const selectionChanceGood = Template.bind({});
-selectionChanceGood.args = {
- rows: [rowGoodProbabilitySelection],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
-
-export const selectionChanceLow = Template.bind({});
-selectionChanceLow.args = {
- rows: [rowLowProbabilitySelection],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/Rows.ts b/explorer-nextjs/app/components/MixNodes/Economics/Rows.ts
deleted file mode 100644
index 62b27cf229..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/Rows.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { currencyToString, unymToNym } from '@/app/utils/currency';
-import { useMixnodeContext } from '@/app/context/mixnode';
-import { ApiState, MixNodeEconomicDynamicsStatsResponse } from '@/app/typeDefs/explorer-api';
-import { toPercentIntegerString } from '@/app/utils';
-import { EconomicsInfoRowWithIndex } from './types';
-
-const selectionChance = (economicDynamicsStats: ApiState | undefined) =>
- economicDynamicsStats?.data?.active_set_inclusion_probability || '-';
-
-export const EconomicsInfoRows = (): EconomicsInfoRowWithIndex => {
- const { economicDynamicsStats, mixNode } = useMixnodeContext();
-
- const estimatedNodeRewards =
- currencyToString({
- amount: economicDynamicsStats?.data?.estimated_total_node_reward.toString() || '',
- }) || '-';
- const estimatedOperatorRewards =
- currencyToString({
- amount: economicDynamicsStats?.data?.estimated_operator_reward.toString() || '',
- }) || '-';
- const profitMargin = mixNode?.data?.profit_margin_percent
- ? toPercentIntegerString(mixNode?.data?.profit_margin_percent)
- : '-';
- const avgUptime = mixNode?.data?.node_performance
- ? toPercentIntegerString(mixNode?.data?.node_performance.last_24h)
- : '-';
- const nodePerformance = mixNode?.data?.node_performance
- ? toPercentIntegerString(mixNode?.data?.node_performance.most_recent)
- : '-';
-
- const opCost = mixNode?.data?.operating_cost;
-
- return {
- id: 1,
- estimatedTotalReward: {
- value: estimatedNodeRewards,
- },
- estimatedOperatorReward: {
- value: estimatedOperatorRewards,
- },
- selectionChance: {
- value: selectionChance(economicDynamicsStats),
- },
- profitMargin: {
- value: profitMargin ? `${profitMargin} %` : '-',
- },
- operatingCost: {
- value: opCost ? `${unymToNym(opCost.amount, 6)} NYM` : '-',
- },
- avgUptime: {
- value: avgUptime ? `${avgUptime} %` : '-',
- },
- nodePerformance: {
- value: nodePerformance,
- },
- };
-};
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/StakeSaturationProgressBar.tsx b/explorer-nextjs/app/components/MixNodes/Economics/StakeSaturationProgressBar.tsx
deleted file mode 100644
index e497a72edd..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/StakeSaturationProgressBar.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react'
-import { Box, Typography } from '@mui/material'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { EconomicsProgress } from './EconomicsProgress'
-
-export const StakeSaturationProgressBar = ({
- value,
- threshold,
-}: {
- value: number
- threshold: number
-}) => {
- const isTablet = useIsMobile('lg')
- const percentageColor = value > (threshold || 100) ? 'warning' : 'inherit'
- const textColor =
- percentageColor === 'warning' ? 'warning.main' : 'nym.wallet.fee'
-
- return (
-
-
- {value}%
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/Table.tsx b/explorer-nextjs/app/components/MixNodes/Economics/Table.tsx
deleted file mode 100644
index a70a013a24..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/Table.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import * as React from 'react'
-import {
- Paper,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Typography,
-} from '@mui/material'
-import { Box } from '@mui/system'
-import { useTheme } from '@mui/material/styles'
-import { Tooltip } from '@nymproject/react/tooltip/Tooltip'
-import { EconomicsRowsType, EconomicsInfoRowWithIndex } from './types'
-import { UniversalTableProps } from '@/app/components/DetailTable'
-import { textColour } from '@/app/utils'
-
-const formatCellValues = (value: EconomicsRowsType, field: string) => (
-
-
- {value.value}
-
-
-)
-
-export const DelegatorsInfoTable: FCWithChildren<
- UniversalTableProps
-> = ({ tableName, columnsData, rows }) => {
- const theme = useTheme()
-
- return (
-
-
-
-
- {columnsData?.map(({ field, title, tooltipInfo, width }) => (
-
-
- {tooltipInfo && (
-
- )}
- {title}
-
-
- ))}
-
-
-
- {rows?.map((eachRow) => (
-
- {columnsData?.map((_, index: number) => {
- const { field } = columnsData[index]
- const value: EconomicsRowsType = (eachRow as any)[field]
- return (
-
- {formatCellValues(value, columnsData[index].field)}
-
- )
- })}
-
- ))}
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/index.ts b/explorer-nextjs/app/components/MixNodes/Economics/index.ts
deleted file mode 100644
index 6dec752246..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { DelegatorsInfoTable } from './Table';
-export { EconomicsInfoColumns } from './Columns';
-export { EconomicsInfoRows } from './Rows';
diff --git a/explorer-nextjs/app/components/MixNodes/Economics/types.ts b/explorer-nextjs/app/components/MixNodes/Economics/types.ts
deleted file mode 100644
index 0bc550253f..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Economics/types.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export type EconomicsRowsType = {
- progressBarValue?: number;
- value: string;
-};
-
-type TEconomicsInfoProperties =
- | 'estimatedTotalReward'
- | 'estimatedOperatorReward'
- | 'estimatedOperatorReward'
- | 'selectionChance'
- | 'profitMargin'
- | 'avgUptime'
- | 'nodePerformance'
- | 'operatingCost';
-
-export type EconomicsInfoRow = {
- [k in TEconomicsInfoProperties]: EconomicsRowsType;
-};
-
-export type EconomicsInfoRowWithIndex = EconomicsInfoRow & { id: number };
diff --git a/explorer-nextjs/app/components/MixNodes/Status.tsx b/explorer-nextjs/app/components/MixNodes/Status.tsx
deleted file mode 100644
index bc8f1fe660..0000000000
--- a/explorer-nextjs/app/components/MixNodes/Status.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as React from 'react'
-import { Typography } from '@mui/material'
-import { getMixNodeIcon } from '@/app/components/Icons'
-import { MixnodeStatus } from '@/app/typeDefs/explorer-api'
-import { useGetMixNodeStatusColor } from '@/app/hooks/useGetMixnodeStatusColor'
-
-interface MixNodeStatusProps {
- status: MixnodeStatus
-}
-// TODO: should be done with i18n
-export const getMixNodeStatusText = (status: MixnodeStatus) => {
- switch (status) {
- case MixnodeStatus.active:
- return 'active'
- case MixnodeStatus.standby:
- return 'on standby'
- default:
- return 'inactive'
- }
-}
-
-export const MixNodeStatus: FCWithChildren = ({
- status,
-}) => {
- const Icon = React.useMemo(() => getMixNodeIcon(status), [status])
- const color = useGetMixNodeStatusColor(status)
-
- return (
-
-
-
- {`${status[0].toUpperCase()}${status.slice(1)}`}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/MixNodes/StatusDropdown.tsx b/explorer-nextjs/app/components/MixNodes/StatusDropdown.tsx
deleted file mode 100644
index dc505869ed..0000000000
--- a/explorer-nextjs/app/components/MixNodes/StatusDropdown.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import * as React from 'react'
-import { MenuItem } from '@mui/material'
-import Select from '@mui/material/Select'
-import { SelectChangeEvent } from '@mui/material/Select/SelectInput'
-import { SxProps } from '@mui/system'
-import {
- MixnodeStatus,
- MixnodeStatusWithAll,
-} from '@/app/typeDefs/explorer-api'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { MixNodeStatus } from './Status'
-
-// TODO: replace with i18n
-const ALL_NODES = 'All nodes'
-
-interface MixNodeStatusDropdownProps {
- status?: MixnodeStatusWithAll
- sx?: SxProps
- onSelectionChanged?: (status?: MixnodeStatusWithAll) => void
-}
-
-export const MixNodeStatusDropdown: FCWithChildren<
- MixNodeStatusDropdownProps
-> = ({ status, onSelectionChanged, sx }) => {
- const isMobile = useIsMobile()
- const [statusValue, setStatusValue] = React.useState(
- status || MixnodeStatusWithAll.all
- )
- const onChange = React.useCallback(
- (event: SelectChangeEvent) => {
- setStatusValue(event.target.value as MixnodeStatusWithAll)
- if (onSelectionChanged) {
- onSelectionChanged(event.target.value as MixnodeStatusWithAll)
- }
- },
- [onSelectionChanged]
- )
-
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/components/MixNodes/index.ts b/explorer-nextjs/app/components/MixNodes/index.ts
deleted file mode 100644
index ccb6c5a8b3..0000000000
--- a/explorer-nextjs/app/components/MixNodes/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './Status';
-export * from './StatusDropdown';
-export * from './mappings';
diff --git a/explorer-nextjs/app/components/MixNodes/mappings.ts b/explorer-nextjs/app/components/MixNodes/mappings.ts
deleted file mode 100644
index df8558d39b..0000000000
--- a/explorer-nextjs/app/components/MixNodes/mappings.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/* eslint-disable camelcase */
-import { MixNodeResponse, MixNodeResponseItem, MixnodeStatus } from '../../typeDefs/explorer-api';
-import { toPercentInteger, toPercentIntegerString } from '@/app/utils';
-import { unymToNym } from '@/app/utils/currency';
-
-export type MixnodeRowType = {
- mix_id: number;
- id: string;
- status: MixnodeStatus;
- owner: string;
- location: string;
- identity_key: string;
- bond: number;
- self_percentage: string;
- pledge_amount: number;
- host: string;
- layer: string;
- profit_percentage: number;
- avg_uptime: string;
- stake_saturation: React.ReactNode;
- operating_cost: number;
- node_performance: number;
- blacklisted: boolean;
-};
-
-export function mixnodeToGridRow(arrayOfMixnodes?: MixNodeResponse): MixnodeRowType[] {
- return (arrayOfMixnodes || []).map(mixNodeResponseItemToMixnodeRowType);
-}
-
-export function mixNodeResponseItemToMixnodeRowType(item: MixNodeResponseItem): MixnodeRowType {
- const pledge = Number(item.pledge_amount.amount) || 0;
- const delegations = Number(item.total_delegation.amount) || 0;
- const totalBond = pledge + delegations;
- const selfPercentage = ((pledge * 100) / totalBond).toFixed(2);
- const profitPercentage = toPercentInteger(item.profit_margin_percent) || 0;
- const uncappedSaturation = typeof item.uncapped_saturation === 'number' ? item.uncapped_saturation * 100 : 0;
-
- return {
- mix_id: item.mix_id,
- id: item.owner,
- status: item.status,
- owner: item.owner,
- identity_key: item.mix_node.identity_key || '',
- bond: totalBond || 0,
- location: item?.location?.country_name || '',
- self_percentage: selfPercentage,
- pledge_amount: pledge,
- host: item?.mix_node?.host || '',
- layer: item?.layer || '',
- profit_percentage: profitPercentage,
- avg_uptime: `${toPercentIntegerString(item.node_performance.last_24h)}%`,
- stake_saturation: Number(uncappedSaturation.toFixed(2)),
- operating_cost: Number(unymToNym(item.operating_cost?.amount, 6)) || 0,
- node_performance: toPercentInteger(item.node_performance.most_recent),
- blacklisted: item.blacklisted,
- };
-}
diff --git a/explorer-nextjs/app/components/Nav/DesktopNav.tsx b/explorer-nextjs/app/components/Nav/DesktopNav.tsx
deleted file mode 100644
index e1faab46f1..0000000000
--- a/explorer-nextjs/app/components/Nav/DesktopNav.tsx
+++ /dev/null
@@ -1,379 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { ExpandLess, ExpandMore, Menu } from '@mui/icons-material'
-import { CSSObject, styled, Theme, useTheme } from '@mui/material/styles'
-import { Link as MuiLink } from '@mui/material'
-import Button from '@mui/material/Button'
-import Box from '@mui/material/Box'
-import ListItem from '@mui/material/ListItem'
-import MuiDrawer from '@mui/material/Drawer'
-import AppBar from '@mui/material/AppBar'
-import Toolbar from '@mui/material/Toolbar'
-import Typography from '@mui/material/Typography'
-import List from '@mui/material/List'
-import IconButton from '@mui/material/IconButton'
-import ListItemButton from '@mui/material/ListItemButton'
-import ListItemIcon from '@mui/material/ListItemIcon'
-import ListItemText from '@mui/material/ListItemText'
-import { NYM_WEBSITE } from '@/app/api/constants'
-import { useMainContext } from '@/app/context/main'
-import { MobileDrawerClose } from '@/app/icons/MobileDrawerClose'
-import { NavOptionType, originalNavOptions } from '@/app/context/nav'
-import { ReleaseAlert } from '@/app/components/ReleaseAlert'
-import { DarkLightSwitchDesktop } from '@/app/components/Switch'
-import { Footer } from '@/app/components/Footer'
-import { ConnectKeplrWallet } from '@/app/components/Wallet/ConnectKeplrWallet'
-import { usePathname, useRouter } from 'next/navigation'
-import {SearchToolbar} from "@/app/components/Nav/Search";
-
-const drawerWidth = 255
-const bannerHeight = 80
-
-const openedMixin = (theme: Theme): CSSObject => ({
- width: drawerWidth,
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.enteringScreen,
- }),
- overflowX: 'hidden',
-})
-
-const closedMixin = (theme: Theme): CSSObject => ({
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- overflowX: 'hidden',
- width: `calc(${theme.spacing(7)} + 1px)`,
-})
-
-const DrawerHeader = styled('div')(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'flex-end',
- padding: theme.spacing(0, 1),
- height: 64,
-}))
-
-const Drawer = styled(MuiDrawer, {
- shouldForwardProp: (prop) => prop !== 'open',
-})(({ theme, open }) => ({
- width: drawerWidth,
- flexShrink: 0,
- whiteSpace: 'nowrap',
- boxSizing: 'border-box',
- ...(open && {
- ...openedMixin(theme),
- '& .MuiDrawer-paper': openedMixin(theme),
- }),
- ...(!open && {
- ...closedMixin(theme),
- '& .MuiDrawer-paper': closedMixin(theme),
- }),
-}))
-
-type ExpandableButtonType = {
- title: string
- url: string
- isActive?: boolean
- Icon?: React.ReactNode
- nested?: NavOptionType[]
- isChild?: boolean
- isMobile: boolean
- drawIsTempOpen: boolean
- drawIsFixed: boolean
- isExternalLink?: boolean
- openDrawer: () => void
- closeDrawer?: () => void
- fixDrawerClose?: () => void
-}
-
-export const ExpandableButton: FCWithChildren = ({
- title,
- url,
- drawIsTempOpen,
- drawIsFixed,
- Icon,
- nested,
- isMobile,
- isChild,
- isExternalLink,
- openDrawer,
- closeDrawer,
- fixDrawerClose,
-}) => {
- const { palette } = useTheme()
- const pathname = usePathname()
- const router = useRouter()
-
- const handleClick = () => {
- if (title === 'Network Components') {
- return undefined
- }
-
- if (isExternalLink) {
- window.open(url, '_blank')
-
- return undefined
- }
-
- if (!isExternalLink) {
- router.push(url, {})
- }
-
- if (closeDrawer) {
- closeDrawer()
- }
- }
- const selectedStyle = {
- background: palette.nym.networkExplorer.nav.selected.main,
- borderRight: `3px solid ${palette.nym.highlight}`,
- }
-
- return (
- <>
-
- handleClick()}
- sx={{
- pt: 2,
- pb: 2,
- background: isChild
- ? palette.nym.networkExplorer.nav.selected.nested
- : 'none',
- }}
- >
- {Icon}
-
-
-
- {nested?.map((each) => (
-
- ))}
- >
- )
-}
-
-export const Nav: FCWithChildren = ({ children }) => {
- const { environment } = useMainContext()
- const [drawerIsOpen, setDrawerToOpen] = React.useState(false)
- const [fixedOpen, setFixedOpen] = React.useState(false)
- // Set maintenance banner to false by default to don't display it
- const [openMaintenance, setOpenMaintenance] = React.useState(false)
- const theme = useTheme()
-
- const explorerName = environment
- ? `${environment} Explorer`
- : 'Mainnet Explorer'
-
- const switchNetworkText =
- environment === 'mainnet' ? 'Switch to Testnet' : 'Switch to Mainnet'
- const switchNetworkLink =
- environment === 'mainnet'
- ? 'https://sandbox-explorer.nymtech.net'
- : 'https://explorer.nymtech.net'
-
- const fixDrawerOpen = () => {
- setFixedOpen(true)
- setDrawerToOpen(true)
- }
-
- const fixDrawerClose = () => {
- setFixedOpen(false)
- setDrawerToOpen(false)
- }
-
- const tempDrawerOpen = () => {
- if (!fixedOpen) {
- setDrawerToOpen(true)
- }
- }
-
- const tempDrawerClose = () => {
- if (!fixedOpen) {
- setDrawerToOpen(false)
- }
- }
-
- return (
-
-
-
-
-
- {/* */}
-
-
-
- {explorerName}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {drawerIsOpen ? : }
-
-
-
-
- {originalNavOptions.map((props) => (
-
- ))}
-
-
-
-
- {children}
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Nav/MobileNav.tsx b/explorer-nextjs/app/components/Nav/MobileNav.tsx
deleted file mode 100644
index 3d1cfdcbf9..0000000000
--- a/explorer-nextjs/app/components/Nav/MobileNav.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { useTheme } from '@mui/material/styles'
-import {
- AppBar,
- Box,
- Drawer,
- IconButton,
- List,
- ListItem,
- ListItemButton,
- ListItemIcon,
- Toolbar,
-} from '@mui/material'
-import { Menu } from '@mui/icons-material'
-import { MaintenanceBanner } from '@nymproject/react/banners/MaintenanceBanner'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { MobileDrawerClose } from '@/app/icons/MobileDrawerClose'
-import { Footer } from '../Footer'
-import { ExpandableButton } from './DesktopNav'
-import { ConnectKeplrWallet } from '../Wallet/ConnectKeplrWallet'
-import { NetworkTitle } from '../NetworkTitle'
-import { originalNavOptions } from '@/app/context/nav'
-import { ReleaseAlert } from '@/app/components/ReleaseAlert'
-import {SearchToolbar} from "@/app/components/Nav/Search";
-
-export const MobileNav: FCWithChildren = ({ children }) => {
- const theme = useTheme()
- const [drawerOpen, setDrawerOpen] = React.useState(false)
- // Set maintenance banner to false by default to don't display it
- const [openMaintenance, setOpenMaintenance] = React.useState(false)
- const isSmallMobile = useIsMobile(400)
-
- const toggleDrawer = () => {
- setDrawerOpen(!drawerOpen)
- }
-
- const openDrawer = () => {
- setDrawerOpen(true)
- }
-
- return (
-
-
- setOpenMaintenance(false)}
- />
-
-
-
-
-
- {!isSmallMobile && }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {originalNavOptions.map((props) => (
-
- ))}
-
-
-
-
-
-
- {children}
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Nav/Navbar.tsx b/explorer-nextjs/app/components/Nav/Navbar.tsx
deleted file mode 100644
index 15bcd47566..0000000000
--- a/explorer-nextjs/app/components/Nav/Navbar.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-'use client'
-
-import React from 'react'
-import { useIsMobile } from '@/app/hooks'
-import { MobileNav } from './MobileNav'
-import { Nav } from './DesktopNav'
-
-const Navbar = ({ children }: { children: React.ReactNode }) => {
- const isMobile = useIsMobile()
-
- if (isMobile) {
- return {children}
- }
-
- return
-}
-
-export { Navbar }
diff --git a/explorer-nextjs/app/components/Nav/Search.tsx b/explorer-nextjs/app/components/Nav/Search.tsx
deleted file mode 100644
index 888125b84a..0000000000
--- a/explorer-nextjs/app/components/Nav/Search.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from "react";
-import { styled, alpha } from '@mui/material/styles';
-import AppBar from '@mui/material/AppBar';
-import Box from '@mui/material/Box';
-import Toolbar from '@mui/material/Toolbar';
-import IconButton from '@mui/material/IconButton';
-import Typography from '@mui/material/Typography';
-import InputBase from '@mui/material/InputBase';
-import MenuIcon from '@mui/icons-material/Menu';
-import SearchIcon from '@mui/icons-material/Search';
-import {useRouter} from "next/navigation";
-
-const Search = styled('div')(({ theme }) => ({
- position: 'relative',
- borderRadius: theme.shape.borderRadius,
- backgroundColor: alpha(theme.palette.common.white, 0.15),
- '&:hover': {
- backgroundColor: alpha(theme.palette.common.white, 0.25),
- },
- marginLeft: 0,
- width: '100%',
- [theme.breakpoints.up('sm')]: {
- marginLeft: theme.spacing(1),
- width: 'auto',
- },
-}));
-
-const SearchIconWrapper = styled('div')(({ theme }) => ({
- padding: theme.spacing(0, 2),
- height: '100%',
- position: 'absolute',
- pointerEvents: 'none',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
-}));
-
-const StyledInputBase = styled(InputBase)(({ theme }) => ({
- color: 'inherit',
- width: '100%',
- '& .MuiInputBase-input': {
- padding: theme.spacing(1, 1, 1, 0),
- // vertical padding + font size from searchIcon
- paddingLeft: `calc(1em + ${theme.spacing(4)})`,
- [theme.breakpoints.up('sm')]: {
- width: '30ch',
- },
- },
-}));
-
-export const SearchToolbar = () => {
- const [search, setSearch] = React.useState();
- const router = useRouter();
- const handleSubmit = async (e: React.SyntheticEvent) => {
- e.preventDefault();
- if(search?.trim().length) {
- router.push(`/account/${search.trim()}`);
- }
- }
- return (
-
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/explorer-nextjs/app/components/NetworkTitle.tsx b/explorer-nextjs/app/components/NetworkTitle.tsx
deleted file mode 100644
index 0c450007da..0000000000
--- a/explorer-nextjs/app/components/NetworkTitle.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import React from 'react'
-import { Button, Typography, Link as MuiLink } from '@mui/material'
-import { useMainContext } from '@/app/context/main'
-
-type NetworkTitleProps = {
- showToggleNetwork?: boolean
-}
-
-const NetworkTitle = ({ showToggleNetwork }: NetworkTitleProps) => {
- const { environment } = useMainContext()
-
- const explorerName =
- `${
- environment && environment.charAt(0).toUpperCase() + environment.slice(1)
- } Explorer` || 'Mainnet Explorer'
-
- const switchNetworkText =
- environment === 'mainnet' ? 'Switch to Testnet' : 'Switch to Mainnet'
- const switchNetworkLink =
- environment === 'mainnet'
- ? 'https://sandbox-explorer.nymtech.net'
- : 'https://explorer.nymtech.net'
- return (
-
-
- {explorerName}
-
-
- {showToggleNetwork && (
-
- )}
-
- )
-}
-
-export { NetworkTitle }
diff --git a/explorer-nextjs/app/components/ReleaseAlert.tsx b/explorer-nextjs/app/components/ReleaseAlert.tsx
deleted file mode 100644
index 5d974420f9..0000000000
--- a/explorer-nextjs/app/components/ReleaseAlert.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Alert, Box, Typography } from '@mui/material';
-
-export const ReleaseAlert = () => (
-
-
- You are now viewing the legacy Nym mixnet explorer. Explorer 2.0 is coming soon.
-
-
-);
diff --git a/explorer-nextjs/app/components/Socials.tsx b/explorer-nextjs/app/components/Socials.tsx
deleted file mode 100644
index 4a4856c8f2..0000000000
--- a/explorer-nextjs/app/components/Socials.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as React from 'react'
-import { Box, IconButton } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import { TelegramIcon } from '../icons/socials/TelegramIcon'
-import { GitHubIcon } from '../icons/socials/GitHubIcon'
-import { TwitterIcon } from '../icons/socials/TwitterIcon'
-import { DiscordIcon } from '../icons/socials/DiscordIcon'
-
-// socials
-export const TELEGRAM_LINK = 'https://nymtech.net/go/telegram';
-export const TWITTER_LINK = 'https://nymtech.net/go/x';
-export const GITHUB_LINK = 'https://nymtech.net/go/github';
-export const DISCORD_LINK = 'https://nymtech.net/go/discord';
-
-export const Socials: FCWithChildren<{ isFooter?: boolean }> = ({
- isFooter = false,
-}) => {
- const theme = useTheme()
- const color = isFooter
- ? theme.palette.nym.networkExplorer.footer.socialIcons
- : theme.palette.nym.networkExplorer.topNav.socialIcons
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/StatsCard.tsx b/explorer-nextjs/app/components/StatsCard.tsx
deleted file mode 100644
index 2c87998986..0000000000
--- a/explorer-nextjs/app/components/StatsCard.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import * as React from 'react'
-import { Box, Card, CardContent, IconButton, Typography } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import EastIcon from '@mui/icons-material/East'
-
-interface StatsCardProps {
- icon: React.ReactNode
- title: string
- count?: string | number
- errorMsg?: Error | string
- onClick?: () => void
- color?: string
-}
-export const StatsCard: FCWithChildren = ({
- icon,
- title,
- count,
- onClick,
- errorMsg,
- color: colorProp,
-}) => {
- const theme = useTheme()
- const color = colorProp || theme.palette.text.primary
- return (
-
-
-
-
- {icon}
-
- {count === undefined || count === null ? '' : count}
-
-
- {title}
-
-
-
-
-
-
- {errorMsg && (
-
- {typeof errorMsg === 'string'
- ? errorMsg
- : errorMsg.message || 'Oh no! An error occurred'}
-
- )}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/StyledLink.tsx b/explorer-nextjs/app/components/StyledLink.tsx
deleted file mode 100644
index 36dd798180..0000000000
--- a/explorer-nextjs/app/components/StyledLink.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react'
-import { Link as MuiLink, SxProps, Typography } from '@mui/material'
-import Link from 'next/link'
-
-type StyledLinkProps = {
- to: string
- children: React.ReactNode
- target?: React.HTMLAttributeAnchorTarget
- dataTestId?: string
- color?: string
- sx?: SxProps
-}
-
-const StyledLink = ({
- to,
- children,
- dataTestId,
- target,
- color,
- sx,
-}: StyledLinkProps) => (
-
-
- {children}
-
-
-)
-
-export default StyledLink
diff --git a/explorer-nextjs/app/components/Switch.tsx b/explorer-nextjs/app/components/Switch.tsx
deleted file mode 100644
index 840530a327..0000000000
--- a/explorer-nextjs/app/components/Switch.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import * as React from 'react';
-import { styled } from '@mui/material/styles';
-import Switch from '@mui/material/Switch';
-import { Button } from '@mui/material';
-import { useMainContext } from '../context/main';
-import { LightSwitchSVG } from '../icons/LightSwitchSVG';
-
-export const DarkLightSwitch = styled(Switch)(({ theme }) => ({
- width: 55,
- height: 34,
- padding: 7,
- '& .MuiSwitch-switchBase': {
- margin: 1,
- padding: 2,
- transform: 'translateX(4px)',
- '&.Mui-checked': {
- color: '#fff',
- transform: 'translateX(22px)',
- '& .MuiSwitch-thumb:before': {
- backgroundImage:
- 'url(\'data:image/svg+xml;utf8,\')',
- },
- '& + .MuiSwitch-track': {
- opacity: 1,
- backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
- },
- },
- },
- '& .MuiSwitch-thumb': {
- backgroundColor: theme.palette.nym.networkExplorer.nav.text,
- width: 25,
- height: 25,
- marginTop: '2px',
- '&:before': {
- content: "''",
- position: 'absolute',
- width: '100%',
- height: '100%',
- left: 0,
- top: 0,
- backgroundRepeat: 'no-repeat',
- backgroundPosition: 'center',
- backgroundImage:
- 'url(\'data:image/svg+xml;utf8,\')',
- },
- },
- '& .MuiSwitch-track': {
- opacity: 1,
- backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
- borderRadius: 20 / 2,
- },
-}));
-
-export const DarkLightSwitchMobile: FCWithChildren = () => {
- const { toggleMode } = useMainContext();
- return (
-
- );
-};
-
-export const DarkLightSwitchDesktop: FCWithChildren<{ defaultChecked: boolean }> = ({ defaultChecked }) => {
- const { toggleMode } = useMainContext();
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/components/TableToolbar.tsx b/explorer-nextjs/app/components/TableToolbar.tsx
deleted file mode 100644
index f22b84aca9..0000000000
--- a/explorer-nextjs/app/components/TableToolbar.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-'use client'
-
-import React from 'react'
-import { Box, SelectChangeEvent } from '@mui/material'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { Filters } from './Filters/Filters'
-
-const fieldsHeight = '42.25px'
-
-type TableToolBarProps = {
- childrenBefore?: React.ReactNode
- childrenAfter?: React.ReactNode
-}
-
-export const TableToolbar: FCWithChildren = ({
- childrenBefore,
- childrenAfter,
-}) => {
- const isMobile = useIsMobile()
- return (
-
-
-
- {childrenBefore}
-
-
-
-
- {childrenAfter}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Title.tsx b/explorer-nextjs/app/components/Title.tsx
deleted file mode 100644
index 032837d3c8..0000000000
--- a/explorer-nextjs/app/components/Title.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import * as React from 'react';
-import { Typography } from '@mui/material';
-
-export const Title: FCWithChildren<{ text: string }> = ({ text }) => (
-
- {text}
-
-);
diff --git a/explorer-nextjs/app/components/Tooltip.tsx b/explorer-nextjs/app/components/Tooltip.tsx
deleted file mode 100644
index 0febd9f891..0000000000
--- a/explorer-nextjs/app/components/Tooltip.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React, { ReactElement } from 'react';
-import { Tooltip as MUITooltip, TooltipComponentsPropsOverrides, TooltipProps } from '@mui/material';
-
-type ValueType = T[keyof T];
-
-type Props = {
- text: string;
- id: string;
- placement?: ValueType>;
- tooltipSx?: TooltipComponentsPropsOverrides;
- children: React.ReactNode;
-};
-
-export const Tooltip = ({ text, id, placement, tooltipSx, children }: Props) => (
- t.palette.nym.networkExplorer.tooltip.background,
- color: (t) => t.palette.nym.networkExplorer.tooltip.color,
- '& .MuiTooltip-arrow': {
- color: (t) => t.palette.nym.networkExplorer.tooltip.background,
- },
- },
- ...tooltipSx,
- },
- }}
- arrow
- >
- {children as ReactElement}
-
-);
diff --git a/explorer-nextjs/app/components/TwoColSmallTable.tsx b/explorer-nextjs/app/components/TwoColSmallTable.tsx
deleted file mode 100644
index a211c29bdd..0000000000
--- a/explorer-nextjs/app/components/TwoColSmallTable.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import * as React from 'react';
-import { CircularProgress, Typography } from '@mui/material';
-import Table from '@mui/material/Table';
-import TableBody from '@mui/material/TableBody';
-import TableCell from '@mui/material/TableCell';
-import TableContainer from '@mui/material/TableContainer';
-import TableRow from '@mui/material/TableRow';
-import Paper from '@mui/material/Paper';
-import CheckCircleSharpIcon from '@mui/icons-material/CheckCircleSharp';
-import ErrorIcon from '@mui/icons-material/Error';
-
-interface TableProps {
- title?: string;
- icons?: boolean[];
- keys: string[];
- values: number[];
- marginBottom?: boolean;
- error?: string;
- loading: boolean;
-}
-
-export const TwoColSmallTable: FCWithChildren = ({
- loading,
- title,
- icons,
- keys,
- values,
- marginBottom,
- error,
-}) => (
- <>
- {title && {title}}
-
-
-
-
- {keys.map((each: string, i: number) => (
-
- {icons && {icons[i] ? : }}
-
- {each}
-
-
- {values[i]}
-
- {error && (
-
- {values[i]}
-
- )}
- {!error && loading && (
-
-
-
- )}
- {error && !icons && (
-
-
-
- )}
-
- ))}
-
-
-
- >
-);
-
-TwoColSmallTable.defaultProps = {
- title: undefined,
- icons: undefined,
- marginBottom: false,
- error: undefined,
-};
diff --git a/explorer-nextjs/app/components/Universal-DataGrid.tsx b/explorer-nextjs/app/components/Universal-DataGrid.tsx
deleted file mode 100644
index 36e98be9ce..0000000000
--- a/explorer-nextjs/app/components/Universal-DataGrid.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { makeStyles } from '@mui/styles'
-import {
- DataGrid,
- GridColDef,
- GridEventListener,
- useGridApiContext,
-} from '@mui/x-data-grid'
-import Pagination from '@mui/material/Pagination'
-import { LinearProgress } from '@mui/material'
-import { GridInitialStateCommunity } from '@mui/x-data-grid/models/gridStateCommunity'
-
-const useStyles = makeStyles({
- root: {
- display: 'flex',
- },
-})
-
-const CustomPagination = () => {
- const apiRef = useGridApiContext()
- const classes = useStyles()
- console.log(apiRef.current.state)
-
- return (
- apiRef.current.setPage(value - 1)}
- />
- )
-}
-
-type DataGridProps = {
- columns: GridColDef[]
- pagination?: true | undefined
- pageSize?: string | undefined
- rows: any
- loading?: boolean
- initialState?: GridInitialStateCommunity
- onRowClick?: GridEventListener<'rowClick'> | undefined
-}
-export const UniversalDataGrid: FCWithChildren = ({
- rows,
- columns,
- loading,
- pagination,
- pageSize,
- initialState,
- onRowClick,
-}) => {
- if (loading) return
-
- return (
- t.palette.nym.networkExplorer.scroll.backgroud,
- outline: (t) =>
- `1px solid ${t.palette.nym.networkExplorer.scroll.border}`,
- boxShadow: 'auto',
- borderRadius: 'auto',
- },
- '*::-webkit-scrollbar-thumb': {
- backgroundColor: (t) => t.palette.nym.networkExplorer.scroll.color,
- borderRadius: '20px',
- width: '.4em',
- border: (t) =>
- `3px solid ${t.palette.nym.networkExplorer.scroll.backgroud}`,
- shadow: 'auto',
- },
- }}
- />
- )
-}
diff --git a/explorer-nextjs/app/components/UptimeChart.tsx b/explorer-nextjs/app/components/UptimeChart.tsx
deleted file mode 100644
index 00a981a3af..0000000000
--- a/explorer-nextjs/app/components/UptimeChart.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import * as React from 'react';
-import { CircularProgress, Typography } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { Chart } from 'react-google-charts';
-import { format } from 'date-fns';
-import { ApiState, UptimeStoryResponse } from '../typeDefs/explorer-api';
-
-interface ChartProps {
- title?: string;
- xLabel: string;
- yLabel?: string;
- uptimeStory: ApiState;
- loading: boolean;
-}
-
-type FormattedDateRecord = [string, number];
-type FormattedChartHeadings = string[];
-type FormattedChartData = [FormattedChartHeadings | FormattedDateRecord];
-
-export const UptimeChart: FCWithChildren = ({ title, xLabel, yLabel, uptimeStory, loading }) => {
- const [formattedChartData, setFormattedChartData] = React.useState();
- const theme = useTheme();
- const color = theme.palette.text.primary;
- React.useEffect(() => {
- if (uptimeStory.data?.history) {
- const allFormattedChartData: FormattedChartData = [['Date', 'Score']];
- uptimeStory.data.history.forEach((eachDate) => {
- const formattedDateUptimeRecord: FormattedDateRecord = [
- format(new Date(eachDate.date), 'MMM dd'),
- eachDate.uptime,
- ];
- allFormattedChartData.push(formattedDateUptimeRecord);
- });
- setFormattedChartData(allFormattedChartData);
- } else {
- const emptyData: any = [
- ['Date', 'Score'],
- ['Jul 27', 10],
- ];
- setFormattedChartData(emptyData);
- }
- }, [uptimeStory]);
-
- return (
- <>
- {title && {title}}
- {loading && }
-
- {!loading && uptimeStory && (
- ...
}
- data={
- uptimeStory.data
- ? formattedChartData
- : [
- ['Date', 'Routing Score'],
- [format(new Date(Date.now()), 'MMM dd'), 0],
- ]
- }
- options={{
- backgroundColor:
- theme.palette.mode === 'dark' ? theme.palette.nym.networkExplorer.background.tertiary : undefined,
- color: uptimeStory.error ? 'rgba(255, 255, 255, 0.4)' : 'rgba(255, 255, 255, 1)',
- colors: ['#FB7A21'],
- legend: {
- textStyle: {
- color,
- opacity: uptimeStory.error ? 0.4 : 1,
- },
- },
-
- intervals: { style: 'sticks' },
- hAxis: {
- // horizontal / date
- title: xLabel,
- titleTextStyle: {
- color,
- },
- textStyle: {
- color,
- // fontSize: 11
- },
- gridlines: {
- count: -1,
- },
- },
- vAxis: {
- // vertical / % Routing Score
- viewWindow: {
- min: 0,
- max: 100,
- },
- title: yLabel,
- titleTextStyle: {
- color,
- opacity: uptimeStory.error ? 0.4 : 1,
- },
- textStyle: {
- color,
- fontSize: 11,
- opacity: uptimeStory.error ? 0.4 : 1,
- },
- },
- }}
- />
- )}
- >
- );
-};
-
-UptimeChart.defaultProps = {
- title: undefined,
-};
diff --git a/explorer-nextjs/app/components/Wallet/ConnectKeplrWallet.tsx b/explorer-nextjs/app/components/Wallet/ConnectKeplrWallet.tsx
deleted file mode 100644
index 23114f9056..0000000000
--- a/explorer-nextjs/app/components/Wallet/ConnectKeplrWallet.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import { Button, IconButton, Stack, CircularProgress } from '@mui/material'
-import CloseIcon from '@mui/icons-material/Close'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { useWalletContext } from '@/app/context/wallet'
-import { WalletAddress, WalletBalance } from '@/app/components/Wallet'
-
-export const ConnectKeplrWallet = () => {
- const {
- connectWallet,
- disconnectWallet,
- isWalletConnected,
- isWalletConnecting,
- } = useWalletContext()
- const isMobile = useIsMobile(1200)
-
- if (!connectWallet || !disconnectWallet) {
- return null
- }
-
- if (isWalletConnected) {
- return (
-
-
-
- {
- await disconnectWallet()
- }}
- >
-
-
-
- )
- }
-
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/components/Wallet/WalletAddress.tsx b/explorer-nextjs/app/components/Wallet/WalletAddress.tsx
deleted file mode 100644
index 3e251eb2bb..0000000000
--- a/explorer-nextjs/app/components/Wallet/WalletAddress.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react'
-import { Box, Typography } from '@mui/material'
-import { ElipsSVG } from '@/app/icons/ElipsSVG'
-import { trimAddress } from '@/app/utils'
-import { useWalletContext } from '@/app/context/wallet'
-
-export const WalletAddress = () => {
- const { address } = useWalletContext()
-
- const displayAddress = trimAddress(address, 7)
-
- return (
-
-
-
- {displayAddress}
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Wallet/WalletBalance.tsx b/explorer-nextjs/app/components/Wallet/WalletBalance.tsx
deleted file mode 100644
index 7d1c5979bc..0000000000
--- a/explorer-nextjs/app/components/Wallet/WalletBalance.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from 'react'
-import { Box, Typography } from '@mui/material'
-import { useWalletContext } from '@/app/context/wallet'
-import { useIsMobile } from '@/app/hooks'
-import { TokenSVG } from '@/app/icons/TokenSVG'
-
-export const WalletBalance = () => {
- const { balance } = useWalletContext()
- const isMobile = useIsMobile(1200)
-
- const showBalance = !isMobile && balance.status === 'success'
-
- if (!showBalance) {
- return null
- }
-
- return (
-
-
-
- {balance.data} NYM
-
-
- )
-}
diff --git a/explorer-nextjs/app/components/Wallet/index.ts b/explorer-nextjs/app/components/Wallet/index.ts
deleted file mode 100644
index 645c8b4ffb..0000000000
--- a/explorer-nextjs/app/components/Wallet/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './WalletBalance';
-export * from './WalletAddress';
diff --git a/explorer-nextjs/app/components/WorldMap.tsx b/explorer-nextjs/app/components/WorldMap.tsx
deleted file mode 100644
index 9b5c329571..0000000000
--- a/explorer-nextjs/app/components/WorldMap.tsx
+++ /dev/null
@@ -1,129 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { scaleLinear } from 'd3-scale'
-import {
- ComposableMap,
- Geographies,
- Geography,
- Marker,
- ZoomableGroup,
-} from 'react-simple-maps'
-import ReactTooltip from 'react-tooltip'
-import { CircularProgress } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import { ApiState, CountryDataResponse } from '../typeDefs/explorer-api'
-import MAP_TOPOJSON from '../assets/world-110m.json'
-
-type MapProps = {
- userLocation?: [number, number]
- countryData?: ApiState
- loading: boolean
-}
-
-export const WorldMap: FCWithChildren = ({
- countryData,
- userLocation,
- loading,
-}) => {
- const { palette } = useTheme()
-
- const colorScale = React.useMemo(() => {
- if (countryData?.data) {
- const heighestNumberOfNodes = Math.max(
- ...Object.values(countryData.data).map((country) => country.nodes)
- )
- return scaleLinear()
- .domain([
- 0,
- 1,
- heighestNumberOfNodes / 4,
- heighestNumberOfNodes / 2,
- heighestNumberOfNodes,
- ])
- .range(palette.nym.networkExplorer.map.fills)
- .unknown(palette.nym.networkExplorer.map.fills[0])
- }
- return () => palette.nym.networkExplorer.map.fills[0]
- }, [countryData, palette])
-
- const [tooltipContent, setTooltipContent] = React.useState(
- null
- )
-
- if (loading) {
- return
- }
-
- return (
- <>
-
-
-
- {({ geographies }) =>
- geographies.map((geo) => {
- const d = (countryData?.data || {})[geo.properties.ISO_A3]
- return (
- {
- const { NAME_LONG } = geo.properties
- if (!userLocation) {
- setTooltipContent(`${NAME_LONG} | ${d?.nodes || 0}`)
- }
- }}
- onMouseLeave={() => {
- setTooltipContent('')
- }}
- style={{
- hover:
- !userLocation && countryData
- ? {
- fill: palette.nym.highlight,
- outline: 'white',
- }
- : undefined,
- }}
- />
- )
- })
- }
-
-
- {userLocation && (
-
-
-
-
-
- )}
-
-
- {tooltipContent}
- >
- )
-}
diff --git a/explorer-nextjs/app/components/index.ts b/explorer-nextjs/app/components/index.ts
deleted file mode 100644
index 92eeebd010..0000000000
--- a/explorer-nextjs/app/components/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export * from './CustomColumnHeading';
-export * from './Title';
-export * from './Universal-DataGrid';
-export * from './Tooltip';
-export { default as StyledLink } from './StyledLink';
-export * from './Delegations';
-export * from './MixNodes';
-export * from './TableToolbar';
-export * from './Icons';
diff --git a/explorer-nextjs/app/context/cosmos-kit.tsx b/explorer-nextjs/app/context/cosmos-kit.tsx
deleted file mode 100644
index 987d30aa65..0000000000
--- a/explorer-nextjs/app/context/cosmos-kit.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-'use client'
-
-import React from 'react'
-import { ChainProvider } from '@cosmos-kit/react'
-import { wallets as keplr } from '@cosmos-kit/keplr-extension'
-import { assets, chains } from 'chain-registry'
-import { Chain, AssetList } from '@chain-registry/types'
-import { VALIDATOR_BASE_URL } from '@/app/api/constants'
-
-const nymSandbox: Chain = {
- chain_name: 'sandbox',
- chain_id: 'sandbox',
- bech32_prefix: 'n',
- network_type: 'devnet',
- pretty_name: 'Nym Sandbox',
- status: 'active',
- slip44: 118,
- apis: {
- rpc: [
- {
- address: 'https://rpc.sandbox.nymtech.net',
- },
- ],
- },
-}
-
-const nymSandboxAssets = {
- chain_name: 'sandbox',
- assets: [
- {
- name: 'Nym',
- base: 'unym',
- symbol: 'NYM',
- display: 'NYM',
- denom_units: [],
- },
- ],
-}
-
-const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => {
- // Only use the nyx chains
- const chainsFixedUp = React.useMemo(() => {
- const nyx = chains.find((chain) => chain.chain_id === 'nyx')
-
- return nyx ? [nymSandbox, nyx] : [nymSandbox]
- }, [chains])
-
- // Only use the nyx assets
- const assetsFixedUp = React.useMemo(() => {
- const nyx = assets.find((asset) => asset.chain_name === 'nyx')
-
- return nyx ? [nymSandboxAssets, nyx] : [nymSandboxAssets]
- }, [assets]) as AssetList[]
-
- return (
-
- {children}
-
- )
-}
-
-export default CosmosKitProvider
diff --git a/explorer-nextjs/app/context/delegations.tsx b/explorer-nextjs/app/context/delegations.tsx
deleted file mode 100644
index 75a099970c..0000000000
--- a/explorer-nextjs/app/context/delegations.tsx
+++ /dev/null
@@ -1,252 +0,0 @@
-'use client'
-
-import React, {
- createContext,
- useCallback,
- useContext,
- useMemo,
- useState,
-} from 'react'
-import {
- Delegation,
- PendingEpochEvent,
- PendingEpochEventKind,
-} from '@nymproject/contract-clients/Mixnet.types'
-import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'
-import { useWalletContext } from './wallet'
-import { useMainContext } from './main'
-
-const fee = { gas: '1000000', amount: [{ amount: '1000000', denom: 'unym' }] }
-
-export type PendingEvent = ReturnType
-
-export type DelegationWithRewards = Delegation & {
- rewards: string
- identityKey: string
- pending: PendingEvent
-}
-
-const getEventsByAddress = (kind: PendingEpochEventKind, address: String) => {
- if ('delegate' in kind && kind.delegate.owner === address) {
- return {
- kind: 'delegate' as const,
- mixId: kind.delegate.mix_id,
- amount: kind.delegate.amount,
- }
- }
-
- if ('undelegate' in kind && kind.undelegate.owner === address) {
- return {
- kind: 'undelegate' as const,
- mixId: kind.undelegate.mix_id,
- }
- }
-
- return undefined
-}
-
-interface DelegationsState {
- delegations?: DelegationWithRewards[]
- handleGetDelegations: () => Promise
- handleDelegate: (
- mixId: number,
- amount: string
- ) => Promise
- handleUndelegate: (mixId: number) => Promise
-}
-
-export const DelegationsContext = createContext({
- delegations: undefined,
- handleGetDelegations: async () => {
- throw new Error('Please connect your wallet')
- },
- handleDelegate: async () => {
- throw new Error('Please connect your wallet')
- },
- handleUndelegate: async () => {
- throw new Error('Please connect your wallet')
- },
-})
-
-export const DelegationsProvider = ({
- children,
-}: {
- children: React.ReactNode
-}) => {
- const [delegations, setDelegations] = useState()
- const { address, nymQueryClient, nymClient } = useWalletContext()
- const { fetchMixnodes } = useMainContext()
-
- const handleGetPendingEvents = async () => {
- if (!nymQueryClient) {
- return undefined
- }
-
- if (!address) {
- return undefined
- }
-
- const response = await nymQueryClient.getPendingEpochEvents({})
- const pendingEvents: PendingEvent[] = []
-
- response.events.forEach((e: PendingEpochEvent) => {
- const event = getEventsByAddress(e.event.kind, address)
- if (event) {
- pendingEvents.push(event)
- }
- })
-
- return pendingEvents
- }
-
- const handleGetDelegationRewards = async (mixId: number) => {
- if (!nymQueryClient) {
- return undefined
- }
-
- if (!address) {
- return undefined
- }
-
- const response = await nymQueryClient.getPendingDelegatorReward({
- address,
- mixId,
- })
-
- return response
- }
-
- const handleGetDelegations = useCallback(async () => {
- if (!nymQueryClient) {
- setDelegations(undefined)
- return undefined
- }
-
- if (!address) {
- setDelegations(undefined)
- return undefined
- }
-
- // Get all mixnodes - Required to get the identity key for each delegation
- const mixnodes = await fetchMixnodes()
-
- // Get delegations
- const delegationsResponse = await nymQueryClient.getDelegatorDelegations({
- delegator: address,
- })
-
- // Get rewards for each delegation
- const rewardsResponse = await Promise.all(
- delegationsResponse.delegations.map((d: Delegation) =>
- handleGetDelegationRewards(d.mix_id)
- )
- )
-
- // Get all pending events
- const pendingEvents = await handleGetPendingEvents()
-
- const delegationsWithRewards: DelegationWithRewards[] = []
-
- // Merge delegations with rewards and pending events
- delegationsResponse.delegations.forEach((d: Delegation, index: number) => {
- delegationsWithRewards.push({
- ...d,
- pending: pendingEvents?.find((e: PendingEvent) =>
- e?.mixId === d.mix_id ? e.kind : undefined
- ),
- identityKey:
- mixnodes?.find((m) => m.mix_id === d.mix_id)?.mix_node.identity_key ||
- '',
- rewards: rewardsResponse[index]?.amount_earned_detailed || '0',
- })
- })
-
- // Add pending events that are not in the delegations list
- pendingEvents?.forEach((e) => {
- if (
- e &&
- !delegationsWithRewards.find(
- (d: DelegationWithRewards) => d.mix_id === e.mixId
- )
- ) {
- delegationsWithRewards.push({
- mix_id: e.mixId,
- height: 0,
- cumulative_reward_ratio: '0',
- owner: address,
- amount: {
- amount: '0',
- denom: 'unym',
- },
- rewards: '0',
- identityKey:
- mixnodes?.find((m) => m.mix_id === e.mixId)?.mix_node
- .identity_key || '',
- pending: e,
- })
- }
- })
-
- setDelegations(delegationsWithRewards)
-
- return undefined
- }, [address, nymQueryClient])
-
- const handleDelegate = async (mixId: number, amount: string) => {
- if (!address) {
- throw new Error('Please connect your wallet')
- }
-
- const amountToDelegate = (Number(amount) * 1000000).toString()
- const uNymFunds = [{ amount: amountToDelegate, denom: 'unym' }]
- try {
- const tx = await nymClient?.delegateToMixnode(
- { mixId },
- fee,
- 'Delegation from Nym Explorer',
- uNymFunds
- )
-
- return tx as unknown as ExecuteResult
- } catch (e) {
- console.error('Failed to delegate to mixnode', e)
- throw e
- }
- }
-
- const handleUndelegate = async (mixId: number) => {
- const tx = await nymClient?.undelegateFromMixnode(
- { mixId },
- fee,
- 'Undelegation from Nym Explorer'
- )
-
- return tx as unknown as ExecuteResult
- }
-
- const contextValue: DelegationsState = useMemo(
- () => ({
- delegations,
- handleGetDelegations,
- handleDelegate,
- handleUndelegate,
- }),
- [delegations, handleGetDelegations]
- )
-
- return (
-
- {children}
-
- )
-}
-
-export const useDelegationsContext = () => {
- const context = useContext(DelegationsContext)
- if (!context) {
- throw new Error(
- 'useDelegationsContext must be used within a DelegationsProvider'
- )
- }
- return context
-}
diff --git a/explorer-nextjs/app/context/gateway.tsx b/explorer-nextjs/app/context/gateway.tsx
deleted file mode 100644
index 458a9da907..0000000000
--- a/explorer-nextjs/app/context/gateway.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- ApiState,
- GatewayReportResponse,
- UptimeStoryResponse,
-} from '@/app/typeDefs/explorer-api'
-import { Api } from '@/app/api'
-import { useApiState } from './hooks'
-
-/**
- * This context provides the state for a single gateway by identity key.
- */
-
-interface GatewayState {
- uptimeReport?: ApiState
- uptimeStory?: ApiState
-}
-
-export const GatewayContext = React.createContext({})
-
-export const useGatewayContext = (): React.ContextType =>
- React.useContext(GatewayContext)
-
-/**
- * Provides a state context for a gateway by identity
- * @param gatewayIdentityKey The identity key of the gateway
- */
-export const GatewayContextProvider = ({
- gatewayIdentityKey,
- children,
-}: {
- gatewayIdentityKey: string
- children: JSX.Element
-}) => {
- const [uptimeReport, fetchUptimeReportById, clearUptimeReportById] =
- useApiState(
- gatewayIdentityKey,
- Api.fetchGatewayReportById,
- 'Failed to fetch gateway uptime report by id'
- )
-
- const [uptimeStory, fetchUptimeHistory, clearUptimeHistory] =
- useApiState(
- gatewayIdentityKey,
- Api.fetchGatewayUptimeStoryById,
- 'Failed to fetch gateway uptime history'
- )
-
- React.useEffect(() => {
- // when the identity key changes, remove all previous data
- clearUptimeReportById()
- clearUptimeHistory()
- Promise.all([fetchUptimeReportById(), fetchUptimeHistory()])
- }, [gatewayIdentityKey])
-
- const state = React.useMemo(
- () => ({
- uptimeReport,
- uptimeStory,
- }),
- [uptimeReport, uptimeStory]
- )
-
- return (
- {children}
- )
-}
diff --git a/explorer-nextjs/app/context/hooks.ts b/explorer-nextjs/app/context/hooks.ts
deleted file mode 100644
index 55004f89ee..0000000000
--- a/explorer-nextjs/app/context/hooks.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-'use client'
-
-import * as React from 'react';
-import { ApiState } from '@/app/typeDefs/explorer-api';
-
-/**
- * Custom hook to get data from the API by passing an id to a delegate method that fetches the data asynchronously
- * @param id The id to fetch
- * @param fn Delegate the fetching to this method (must take `(id: string)` as a parameter)
- * @param errorMessage A static error message, to use when no dynamic error message is returned
- */
-export const useApiState = (
- id: string,
- fn: (argId: string) => Promise,
- errorMessage: string,
-): [ApiState | undefined, () => Promise>, () => void] => {
- // stores the state
- const [value, setValue] = React.useState>();
-
- // clear the value
- const clearValueFn = () => setValue(undefined);
-
- // this provides a method to trigger the delegate to fetch data
- const wrappedFetchFn = React.useCallback(async () => {
- setValue({ isLoading: true });
- try {
- // keep previous state and set to loading
- setValue((prevState) => ({ ...prevState, isLoading: true }));
-
- // delegate to user function to get data and set if successful
- const data = await fn(id);
- const newValue: ApiState = {
- isLoading: false,
- data,
- };
- setValue(newValue);
- return newValue;
- } catch (error) {
- // return the caught error or create a new error with the static error message
- const newValue: ApiState = {
- error: error instanceof Error ? error : new Error(errorMessage),
- isLoading: false,
- };
- setValue(newValue);
- return newValue;
- }
- }, [setValue, fn, id, errorMessage]);
- return [value, wrappedFetchFn, clearValueFn];
-};
diff --git a/explorer-nextjs/app/context/main.tsx b/explorer-nextjs/app/context/main.tsx
deleted file mode 100644
index 0494b87749..0000000000
--- a/explorer-nextjs/app/context/main.tsx
+++ /dev/null
@@ -1,297 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { PaletteMode } from '@mui/material'
-import {
- ApiState,
- BlockResponse,
- CountryDataResponse,
- GatewayResponse,
- MixNodeResponse,
- MixnodeStatus,
- SummaryOverviewResponse,
- ValidatorsResponse,
- Environment,
- DirectoryServiceProvider,
-} from '@/app/typeDefs/explorer-api'
-import { EnumFilterKey } from '@/app/typeDefs/filters'
-import { Api, getEnvironment } from '@/app/api'
-import { toPercentIntegerString } from '@/app/utils'
-import { NavOptionType, originalNavOptions } from './nav'
-
-interface StateData {
- summaryOverview?: ApiState
- block?: ApiState
- countryData?: ApiState
- gateways?: ApiState
- globalError?: string | undefined
- mixnodes?: ApiState
- nodes?: ApiState
- mode: PaletteMode
- validators?: ApiState
- environment?: Environment
- serviceProviders?: ApiState
-}
-
-interface StateApi {
- fetchMixnodes: (
- status?: MixnodeStatus
- ) => Promise
- filterMixnodes: (filters: any, status: any) => void
- fetchNodes: () => Promise
- fetchNodeById: (id: number) => Promise
- fetchAccountById: (accountAddr: string) => Promise
- toggleMode: () => void
-}
-
-type State = StateData & StateApi
-
-export const MainContext = React.createContext({
- mode: 'dark',
- toggleMode: () => undefined,
- filterMixnodes: () => null,
- fetchMixnodes: () => Promise.resolve(undefined),
- fetchNodes: async () => undefined,
- fetchNodeById: async () => undefined,
- fetchAccountById: async () => undefined,
-})
-
-export const useMainContext = (): React.ContextType =>
- React.useContext(MainContext)
-
-export const MainContextProvider: FCWithChildren = ({ children }) => {
- // network explorer environment
- const [environment, setEnvironment] = React.useState()
-
- // light/dark mode
- const [mode, setMode] = React.useState('dark')
-
- // global / banner error messaging
- const [globalError] = React.useState()
-
- // various APIs for Overview page
- const [summaryOverview, setSummaryOverview] =
- React.useState>()
- const [nodes, setNodes] = React.useState>()
- const [mixnodes, setMixnodes] = React.useState>()
- const [gateways, setGateways] = React.useState>()
- const [validators, setValidators] =
- React.useState>()
- const [block, setBlock] = React.useState>()
- const [countryData, setCountryData] =
- React.useState>()
- const [serviceProviders, setServiceProviders] =
- React.useState>()
-
- const toggleMode = () => setMode((m) => (m !== 'light' ? 'light' : 'dark'))
-
- const fetchOverviewSummary = async () => {
- try {
- const data = await Api.fetchOverviewSummary()
- setSummaryOverview({ data, isLoading: false })
- } catch (error) {
- setSummaryOverview({
- error:
- error instanceof Error
- ? error
- : new Error('Overview summary api fail'),
- isLoading: false,
- })
- }
- }
-
- const fetchMixnodes = async () => {
- let data
- setMixnodes((d) => ({ ...d, isLoading: true }))
- try {
- data = await Api.fetchMixnodes()
- setMixnodes({ data, isLoading: false })
- } catch (error) {
- setMixnodes({
- error: error instanceof Error ? error : new Error('Mixnode api fail'),
- isLoading: false,
- })
- }
- return data
- }
-
- const filterMixnodes = async (
- filters: { [key in EnumFilterKey]: number[] },
- status?: MixnodeStatus
- ) => {
- setMixnodes((d) => ({ ...d, isLoading: true }))
- const mxns = await Api.fetchMixnodes()
-
- const filtered = mxns?.filter(
- (m) =>
- +m.profit_margin_percent >= filters.profitMargin[0] / 100 &&
- +m.profit_margin_percent <= filters.profitMargin[1] / 100 &&
- m.stake_saturation >= filters.stakeSaturation[0] &&
- m.stake_saturation <= filters.stakeSaturation[1] &&
- m.avg_uptime >= filters.routingScore[0] &&
- m.avg_uptime <= filters.routingScore[1]
- )
-
- setMixnodes({ data: filtered, isLoading: false })
- }
-
- const fetchGateways = async () => {
- setGateways((d) => ({ ...d, isLoading: true }))
- try {
- const data = await Api.fetchGateways()
- setGateways({ data, isLoading: false })
- } catch (error) {
- setGateways({
- error: error instanceof Error ? error : new Error('Gateways api fail'),
- isLoading: false,
- })
- }
- }
- const fetchValidators = async () => {
- try {
- const data = await Api.fetchValidators()
- setValidators({ data, isLoading: false })
- } catch (error) {
- setValidators({
- error:
- error instanceof Error ? error : new Error('Validators api fail'),
- isLoading: false,
- })
- }
- }
- const fetchBlock = async () => {
- try {
- const data = await Api.fetchBlock()
- setBlock({ data, isLoading: false })
- } catch (error) {
- setBlock({
- error: error instanceof Error ? error : new Error('Block api fail'),
- isLoading: false,
- })
- }
- }
- const fetchCountryData = async () => {
- setCountryData({ data: undefined, isLoading: true })
- try {
- const res = await Api.fetchCountryData()
- setCountryData({ data: res, isLoading: false })
- } catch (error) {
- setCountryData({
- error:
- error instanceof Error ? error : new Error('Country Data api fail'),
- isLoading: false,
- })
- }
- }
-
- const fetchServiceProviders = async () => {
- setServiceProviders({ data: undefined, isLoading: true })
- try {
- const res = await Api.fetchServiceProviders()
- const resWithRoutingScorePercentage = res.map((item) => ({
- ...item,
- routing_score: item.routing_score
- ? `${toPercentIntegerString(item.routing_score.toString())}%`
- : item.routing_score,
- }))
- setServiceProviders({
- data: resWithRoutingScorePercentage,
- isLoading: false,
- })
- } catch (error) {
- setServiceProviders({
- error:
- error instanceof Error
- ? error
- : new Error('Service provider api fail'),
- isLoading: false,
- })
- }
- }
-
- const fetchNodes = async () => {
- setNodes({ data: undefined, isLoading: true })
- try {
- const res = await Api.fetchNodes();
- res.forEach((node: any) => node.total_stake =
- Math.round(Number.parseFloat(node.rewarding_details?.operator || "0")
- + Number.parseFloat(node.rewarding_details?.delegates || "0"))
- );
- setNodes({
- data: res.sort((a: any, b: any) => b.total_stake - a.total_stake),
- isLoading: false,
- })
- } catch (error) {
- setNodes({
- error:
- error instanceof Error
- ? error
- : new Error('Service provider api fail'),
- isLoading: false,
- })
- } };
-
- const fetchNodeById = async (id: number) => {
- const res = await Api.fetchNodeById(id);
- return res;
- };
-
- const fetchAccountById = async (id: string) => {
- const res = await Api.fetchAccountById(id);
- return res;
- };
-
- React.useEffect(() => {
- if (environment === 'mainnet') {
- fetchServiceProviders()
- }
- }, [environment])
-
- React.useEffect(() => {
- setEnvironment(getEnvironment())
- Promise.all([
- fetchOverviewSummary(),
- fetchGateways(),
- fetchValidators(),
- fetchBlock(),
- fetchCountryData(),
- ])
- }, [])
-
- const state = React.useMemo(
- () => ({
- environment,
- block,
- countryData,
- gateways,
- globalError,
- mixnodes,
- mode,
- nodes,
- summaryOverview,
- validators,
- serviceProviders,
- toggleMode,
- fetchMixnodes,
- filterMixnodes,
- fetchNodes,
- fetchNodeById,
- fetchAccountById,
- }),
- [
- environment,
- block,
- countryData,
- gateways,
- globalError,
- mixnodes,
- mode,
- nodes,
- summaryOverview,
- validators,
- serviceProviders,
- ]
- )
-
- return {children}
-}
diff --git a/explorer-nextjs/app/context/mixnode.tsx b/explorer-nextjs/app/context/mixnode.tsx
deleted file mode 100644
index 71b48fd045..0000000000
--- a/explorer-nextjs/app/context/mixnode.tsx
+++ /dev/null
@@ -1,173 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- ApiState,
- DelegationsResponse,
- UniqDelegationsResponse,
- MixNodeDescriptionResponse,
- MixNodeEconomicDynamicsStatsResponse,
- MixNodeResponseItem,
- StatsResponse,
- StatusResponse,
- UptimeStoryResponse,
-} from '../typeDefs/explorer-api'
-import { Api } from '../api'
-import { useApiState } from './hooks'
-import {
- mixNodeResponseItemToMixnodeRowType,
- MixnodeRowType,
-} from '../components/MixNodes'
-
-/**
- * This context provides the state for a single mixnode by identity key.
- */
-
-interface MixnodeState {
- delegations?: ApiState
- uniqDelegations?: ApiState
- description?: ApiState
- economicDynamicsStats?: ApiState
- mixNode?: ApiState
- mixNodeRow?: MixnodeRowType
- stats?: ApiState
- status?: ApiState
- uptimeStory?: ApiState
-}
-
-export const MixnodeContext = React.createContext({})
-
-export const useMixnodeContext = (): React.ContextType =>
- React.useContext(MixnodeContext)
-
-interface MixnodeContextProviderProps {
- mixId: string
- children: React.ReactNode
-}
-
-/**
- * Provides a state context for a mixnode by identity
- * @param mixId The mixID of the mixnode
- */
-export const MixnodeContextProvider: FCWithChildren<
- MixnodeContextProviderProps
-> = ({ mixId, children }) => {
- const [mixNode, fetchMixnodeById, clearMixnodeById] = useApiState<
- MixNodeResponseItem | undefined
- >(mixId, Api.fetchMixnodeByID, 'Failed to fetch mixnode by id')
-
- const [mixNodeRow, setMixnodeRow] = React.useState<
- MixnodeRowType | undefined
- >()
-
- const [delegations, fetchDelegations, clearDelegations] =
- useApiState(
- mixId,
- Api.fetchDelegationsById,
- 'Failed to fetch delegations for mixnode'
- )
-
- const [uniqDelegations, fetchUniqDelegations, clearUniqDelegations] =
- useApiState(
- mixId,
- Api.fetchUniqDelegationsById,
- 'Failed to fetch delegations for mixnode'
- )
-
- const [status, fetchStatus, clearStatus] = useApiState(
- mixId,
- Api.fetchStatusById,
- 'Failed to fetch mixnode status'
- )
-
- const [stats, fetchStats, clearStats] = useApiState(
- mixId,
- Api.fetchStatsById,
- 'Failed to fetch mixnode stats'
- )
-
- const [description, fetchDescription, clearDescription] =
- useApiState(
- mixId,
- Api.fetchMixnodeDescriptionById,
- 'Failed to fetch mixnode description'
- )
-
- const [
- economicDynamicsStats,
- fetchEconomicDynamicsStats,
- clearEconomicDynamicsStats,
- ] = useApiState(
- mixId,
- Api.fetchMixnodeEconomicDynamicsStatsById,
- 'Failed to fetch mixnode dynamics stats by id'
- )
-
- const [uptimeStory, fetchUptimeHistory, clearUptimeHistory] =
- useApiState(
- mixId,
- Api.fetchUptimeStoryById,
- 'Failed to fetch mixnode uptime history'
- )
-
- React.useEffect(() => {
- // when the identity key changes, remove all previous data
- clearMixnodeById()
- clearDelegations()
- clearUniqDelegations()
- clearStatus()
- clearStats()
- clearDescription()
- clearEconomicDynamicsStats()
- clearUptimeHistory()
-
- // fetch the mixnode, then get all the other stuff
- fetchMixnodeById().then((value) => {
- if (!value.data || value.error) {
- setMixnodeRow(undefined)
- return
- }
- setMixnodeRow(mixNodeResponseItemToMixnodeRowType(value.data))
- Promise.all([
- fetchDelegations(),
- fetchUniqDelegations(),
- fetchStatus(),
- fetchStats(),
- fetchDescription(),
- fetchEconomicDynamicsStats(),
- fetchUptimeHistory(),
- ])
- })
- }, [mixId])
-
- const state = React.useMemo(
- () => ({
- delegations,
- uniqDelegations,
- mixNode,
- mixNodeRow,
- description,
- economicDynamicsStats,
- stats,
- status,
- uptimeStory,
- }),
- [
- {
- delegations,
- uniqDelegations,
- mixNode,
- mixNodeRow,
- description,
- economicDynamicsStats,
- stats,
- status,
- uptimeStory,
- },
- ]
- )
-
- return (
- {children}
- )
-}
diff --git a/explorer-nextjs/app/context/nav.tsx b/explorer-nextjs/app/context/nav.tsx
deleted file mode 100644
index e41882edbb..0000000000
--- a/explorer-nextjs/app/context/nav.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { DelegateIcon } from '@/app/icons/DelevateSVG'
-import { BLOCK_EXPLORER_BASE_URL } from '@/app/api/constants'
-import { OverviewSVG } from '@/app/icons/OverviewSVG'
-import { NodemapSVG } from '@/app/icons/NodemapSVG'
-import { NetworkComponentsSVG } from '@/app/icons/NetworksSVG'
-
-export type NavOptionType = {
- url: string
- title: string
- Icon?: React.ReactNode
- nested?: NavOptionType[]
- isExpandedChild?: boolean
- isExternal?: boolean
-}
-
-export const originalNavOptions: NavOptionType[] = [
- {
- url: '/',
- title: 'Overview',
- Icon: ,
- },
- {
- url: '/network-components',
- title: 'Network Components',
- Icon: ,
- nested: [
- {
- url: '/network-components/nodes',
- title: 'Nodes',
- },
- {
- url: '/network-components/mixnodes',
- title: 'Mixnodes (legacy)',
- },
- {
- url: '/network-components/gateways',
- title: 'Gateways (legacy)',
- },
- {
- url: `${BLOCK_EXPLORER_BASE_URL}/validators`,
- title: 'Validators',
- isExternal: true,
- },
- ],
- },
- {
- url: '/nodemap',
- title: 'Nodemap',
- Icon: ,
- },
- {
- url: '/delegations',
- title: 'Delegations',
- Icon: ,
- },
-]
diff --git a/explorer-nextjs/app/context/node.tsx b/explorer-nextjs/app/context/node.tsx
deleted file mode 100644
index 2aa885439c..0000000000
--- a/explorer-nextjs/app/context/node.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- ApiState,
- NymNodeReportResponse,
- UptimeStoryResponse,
-} from '@/app/typeDefs/explorer-api'
-import { Api } from '@/app/api'
-import { useApiState } from './hooks'
-
-/**
- * This context provides the state for a single gateway by identity key.
- */
-
-interface NymNodeState {
- uptimeReport?: ApiState
- uptimeHistory?: ApiState
-}
-
-export const NymNodeContext = React.createContext({})
-
-export const useNymNodeContext = (): React.ContextType =>
- React.useContext(NymNodeContext)
-
-/**
- * Provides a state context for a gateway by identity
- * @param gatewayIdentityKey The identity key of the gateway
- */
-export const NymNodeContextProvider = ({
- nymNodeId,
- children,
-}: {
- nymNodeId: string
- children: JSX.Element
-}) => {
- const [uptimeReport, fetchUptimeReportById, clearUptimeReportById] =
- useApiState(
- nymNodeId,
- Api.fetchNymNodePerformanceById,
- 'Failed to fetch gateway uptime report by id'
- )
-
- const [uptimeHistory, fetchUptimeHistory, clearUptimeHistory] =
- useApiState(
- nymNodeId,
- async (arg) => {
- const res = await Api.fetchNymNodeUptimeHistoryById(arg);
- const uptimeHistory: UptimeStoryResponse = {
- history: res.history.data,
- identity: '',
- owner: '',
- }
- return uptimeHistory;
- },
- 'Failed to fetch gateway uptime history'
- )
-
- React.useEffect(() => {
- // when the identity key changes, remove all previous data
- clearUptimeReportById()
- clearUptimeHistory()
- Promise.all([fetchUptimeReportById(), fetchUptimeHistory()])
- }, [nymNodeId])
-
- const state = React.useMemo(
- () => ({
- uptimeReport,
- uptimeHistory,
- }),
- [uptimeReport, uptimeHistory]
- )
-
- return (
- {children}
- )
-}
diff --git a/explorer-nextjs/app/context/wallet.tsx b/explorer-nextjs/app/context/wallet.tsx
deleted file mode 100644
index c9acb6b850..0000000000
--- a/explorer-nextjs/app/context/wallet.tsx
+++ /dev/null
@@ -1,123 +0,0 @@
-'use client'
-
-import React, {
- createContext,
- useContext,
- useEffect,
- useMemo,
- useState,
-} from 'react'
-import { useChain } from '@cosmos-kit/react'
-import { Wallet } from '@cosmos-kit/core'
-import { unymToNym } from '@/app/utils/currency'
-import { useNymClient } from '@/app/hooks'
-import {
- MixnetClient,
- MixnetQueryClient,
-} from '@nymproject/contract-clients/Mixnet.client'
-import { COSMOS_KIT_USE_CHAIN } from '@/app/api/constants'
-
-interface WalletState {
- balance: { status: 'loading' | 'success'; data?: string }
- address?: string
- isWalletConnected: boolean
- isWalletConnecting: boolean
- wallet?: Wallet
- nymClient?: MixnetClient
- nymQueryClient?: MixnetQueryClient
- connectWallet: () => Promise
- disconnectWallet: () => Promise
-}
-
-export const WalletContext = createContext({
- address: undefined,
- balance: { status: 'loading', data: undefined },
- isWalletConnected: false,
- isWalletConnecting: false,
- nymClient: undefined,
- nymQueryClient: undefined,
- connectWallet: async () => {
- throw new Error('Please connect your wallet')
- },
- disconnectWallet: async () => {
- throw new Error('Please connect your wallet')
- },
-})
-
-export const WalletProvider = ({ children }: { children: React.ReactNode }) => {
- const [balance, setBalance] = useState({
- status: 'loading',
- data: undefined,
- })
-
- const {
- connect,
- disconnect,
- wallet,
- address,
- isWalletConnected,
- isWalletConnecting,
- getCosmWasmClient,
- } = useChain(COSMOS_KIT_USE_CHAIN)
-
- const { nymClient, nymQueryClient } = useNymClient(address)
-
- const getBalance = async (walletAddress: string) => {
- const account = await getCosmWasmClient()
- const uNYMBalance = await account.getBalance(walletAddress, 'unym')
- const NYMBalance = unymToNym(uNYMBalance.amount)
-
- return NYMBalance
- }
-
- const init = async (walletAddress: string) => {
- const walletBalance = await getBalance(walletAddress)
- setBalance({ status: 'success', data: walletBalance })
- }
-
- useEffect(() => {
- if (isWalletConnected && address) {
- init(address)
- }
- }, [address, isWalletConnected])
-
- const handleConnectWallet = async () => {
- await connect()
- }
-
- const handleDisconnectWallet = async () => {
- await disconnect()
- setBalance({ status: 'loading', data: undefined })
- }
-
- const contextValue: WalletState = useMemo(
- () => ({
- address,
- balance,
- wallet,
- isWalletConnected,
- isWalletConnecting,
- nymClient,
- nymQueryClient,
- connectWallet: handleConnectWallet,
- disconnectWallet: handleDisconnectWallet,
- }),
- [
- address,
- balance,
- wallet,
- isWalletConnected,
- isWalletConnecting,
- nymClient,
- nymQueryClient,
- ]
- )
-
- return (
-
- {children}
-
- )
-}
-
-export const useWalletContext = () => useContext(WalletContext)
diff --git a/explorer-nextjs/app/delegations/page.tsx b/explorer-nextjs/app/delegations/page.tsx
deleted file mode 100644
index 60b27b3c91..0000000000
--- a/explorer-nextjs/app/delegations/page.tsx
+++ /dev/null
@@ -1,311 +0,0 @@
-'use client'
-
-import React, { useCallback, useEffect, useMemo } from 'react'
-import {
- Alert,
- AlertTitle,
- Box,
- Button,
- Card,
- Chip,
- IconButton,
- Tooltip,
- Typography,
-} from '@mui/material'
-import { DelegationModal, DelegationModalProps, Title } from '@/app/components'
-import { useWalletContext } from '@/app/context/wallet'
-import { unymToNym } from '@/app/utils/currency'
-import {
- DelegationWithRewards,
- DelegationsProvider,
- PendingEvent,
- useDelegationsContext,
-} from '@/app/context/delegations'
-import { urls } from '@/app/utils'
-import { useClipboard } from 'use-clipboard-copy'
-import { Close } from '@mui/icons-material'
-import { useRouter } from 'next/navigation'
-import {
- MRT_ColumnDef,
- MaterialReactTable,
- useMaterialReactTable,
-} from 'material-react-table'
-
-const mapToDelegationsRow = (
- delegation: DelegationWithRewards,
- index: number
-) => ({
- identity: delegation.identityKey,
- mix_id: delegation.mix_id,
- amount: `${unymToNym(delegation.amount.amount)} NYM`,
- rewards: `${unymToNym(delegation.rewards)} NYM`,
- id: index,
- pending: delegation.pending,
-})
-
-const Banner = ({ onClose }: { onClose: () => void }) => {
- const { copy } = useClipboard()
-
- return (
-
-
-
- }
- >
- Mobile Delegations Beta
-
-
- This is a beta release for mobile delegations If you have any feedback
- or feature suggestions contact us at support@nymte.ch
-
-
-
-
- )
-}
-
-const DelegationsPage = () => {
- const [confirmationModalProps, setConfirmationModalProps] = React.useState<
- DelegationModalProps | undefined
- >()
- const [isLoading, setIsLoading] = React.useState(false)
- const [showBanner, setShowBanner] = React.useState(true)
-
- const { isWalletConnected } = useWalletContext()
- const { handleGetDelegations, handleUndelegate, delegations } =
- useDelegationsContext()
-
- const router = useRouter()
-
- useEffect(() => {
- let timeoutId: NodeJS.Timeout
-
- const fetchDelegations = async () => {
- setIsLoading(true)
- try {
- await handleGetDelegations()
- } catch (error) {
- setConfirmationModalProps({
- status: 'error',
- message: "Couldn't fetch delegations. Please try again later.",
- })
- } finally {
- setIsLoading(false)
-
- timeoutId = setTimeout(() => {
- fetchDelegations()
- }, 60_000)
- }
- }
-
- fetchDelegations()
-
- return () => {
- clearTimeout(timeoutId)
- }
- }, [handleGetDelegations])
-
- const getTooltipTitle = (pending: PendingEvent) => {
- if (pending?.kind === 'undelegate') {
- return 'You have an undelegation pending'
- }
-
- if (pending?.kind === 'delegate') {
- return `You have a delegation pending worth ${unymToNym(
- pending.amount.amount
- )} NYM`
- }
-
- return undefined
- }
-
- const onUndelegate = useCallback(
- async (mixId: number) => {
- setConfirmationModalProps({ status: 'loading' })
-
- try {
- const tx = await handleUndelegate(mixId)
-
- if (tx) {
- setConfirmationModalProps({
- status: 'success',
- message: 'Undelegation can take up to one hour to process',
- transactions: [
- {
- url: `${urls('MAINNET').blockExplorer}/transaction/${
- tx.transactionHash
- }`,
- hash: tx.transactionHash,
- },
- ],
- })
- }
- } catch (error) {
- if (error instanceof Error) {
- setConfirmationModalProps({ status: 'error', message: error.message })
- }
- }
- },
- [handleUndelegate]
- )
-
- const columns = useMemo<
- MRT_ColumnDef>[]
- >(() => {
- return [
- {
- id: 'delegations-data',
- header: 'Delegations Data',
- columns: [
- {
- id: 'identity',
- accessorKey: 'identity',
- header: 'Identity Key',
- width: 400,
- },
- {
- id: 'mix_id',
- accessorKey: 'mix_id',
- header: 'Mix ID',
- size: 150,
- },
- {
- id: 'amount',
- accessorKey: 'amount',
- header: 'Amount',
- width: 150,
- },
- {
- id: 'rewards',
- accessorKey: 'rewards',
- header: 'Rewards',
- width: 150,
- enableColumnFilters: false,
- },
- {
- id: 'undelegate',
- accessorKey: 'undelegate',
- header: '',
- enableSorting: false,
- enableColumnActions: false,
- Filter: () => null,
- Cell: ({ row }) => {
- return (
-
- {row.original.pending ? (
- e.stopPropagation()}
- PopperProps={{}}
- >
-
-
- ) : (
-
- )}
-
- )
- },
- },
- ],
- },
- ]
- }, [onUndelegate])
-
- const data = useMemo(() => {
- return (delegations || []).map(mapToDelegationsRow)
- }, [delegations])
-
- const table = useMaterialReactTable({
- columns,
- data,
- enableFullScreenToggle: false,
- state: {
- isLoading,
- },
- initialState: {
- columnPinning: { right: ['undelegate'] },
- },
- })
-
- return (
-
- {confirmationModalProps && (
- {
- if (confirmationModalProps.status === 'success') {
- await handleGetDelegations()
- }
- setConfirmationModalProps(undefined)
- }}
- sx={{
- width: {
- xs: '90%',
- sm: 600,
- },
- }}
- />
- )}
- {showBanner && setShowBanner(false)} />}
-
-
-
-
- {!isWalletConnected ? (
-
-
- Connect your wallet to view your delegations.
-
-
- ) : null}
-
-
-
-
-
- )
-}
-
-const Delegations = () => (
-
-
-
-)
-
-export default Delegations
diff --git a/explorer-nextjs/app/errors/ErrorBoundaryContent.tsx b/explorer-nextjs/app/errors/ErrorBoundaryContent.tsx
deleted file mode 100644
index 4dbf9eb16e..0000000000
--- a/explorer-nextjs/app/errors/ErrorBoundaryContent.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import * as React from 'react'
-import { FallbackProps } from 'react-error-boundary'
-import { Alert, AlertTitle, Container } from '@mui/material'
-import { NymThemeProvider } from '@nymproject/mui-theme'
-import { NymLogo } from '@nymproject/react/logo/NymLogo'
-
-export const ErrorBoundaryContent: FCWithChildren = ({
- error,
-}) => (
-
-
-
- Oh no! Sorry, something went wrong
-
- {error.name}
- {error.message}
-
- {process.env.NODE_ENV === 'development' && (
-
- Stack trace
- {error.stack}
-
- )}
-
-
-)
diff --git a/explorer-nextjs/app/hooks/index.ts b/explorer-nextjs/app/hooks/index.ts
deleted file mode 100644
index ba04855f77..0000000000
--- a/explorer-nextjs/app/hooks/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './useIsMobile';
-export * from './useIsMounted';
-export * from './useGetMixnodeStatusColor';
-export * from './useNymClient';
diff --git a/explorer-nextjs/app/hooks/useGetMixnodeStatusColor.ts b/explorer-nextjs/app/hooks/useGetMixnodeStatusColor.ts
deleted file mode 100644
index 3e1762209f..0000000000
--- a/explorer-nextjs/app/hooks/useGetMixnodeStatusColor.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-'use client'
-
-import { useTheme } from '@mui/material';
-import { MixnodeStatus } from '@/app/typeDefs/explorer-api';
-
-export const useGetMixNodeStatusColor = (status: MixnodeStatus) => {
- const theme = useTheme();
-
- switch (status) {
- case MixnodeStatus.active:
- return theme.palette.nym.networkExplorer.mixnodes.status.active;
-
- case MixnodeStatus.standby:
- return theme.palette.nym.networkExplorer.mixnodes.status.standby;
-
- default:
- return theme.palette.nym.networkExplorer.mixnodes.status.inactive;
- }
-};
diff --git a/explorer-nextjs/app/hooks/useIsMobile.ts b/explorer-nextjs/app/hooks/useIsMobile.ts
deleted file mode 100644
index 0948d36cbe..0000000000
--- a/explorer-nextjs/app/hooks/useIsMobile.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-'use client'
-
-import { Breakpoint, useMediaQuery } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-
-export const useIsMobile = (queryInput: number | Breakpoint = 'md') => {
- const theme = useTheme();
- const isMobile = useMediaQuery(theme.breakpoints.down(queryInput));
-
- return isMobile;
-};
diff --git a/explorer-nextjs/app/hooks/useIsMounted.ts b/explorer-nextjs/app/hooks/useIsMounted.ts
deleted file mode 100644
index 5a78ae4fec..0000000000
--- a/explorer-nextjs/app/hooks/useIsMounted.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-'use client'
-
-import { useRef, useEffect, useCallback } from 'react';
-
-export function useIsMounted(): () => boolean {
- const ref = useRef(false);
-
- useEffect(() => {
- ref.current = true;
- return () => {
- ref.current = false;
- };
- }, []);
-
- return useCallback(() => ref.current, [ref]);
-}
diff --git a/explorer-nextjs/app/hooks/useNymClient.tsx b/explorer-nextjs/app/hooks/useNymClient.tsx
deleted file mode 100644
index 2fa400b130..0000000000
--- a/explorer-nextjs/app/hooks/useNymClient.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-'use client'
-
-import { useEffect, useState } from 'react'
-import { useChain } from '@cosmos-kit/react'
-import { contracts } from '@nymproject/contract-clients'
-import {
- MixnetClient,
- MixnetQueryClient,
-} from '@nymproject/contract-clients/Mixnet.client'
-import { COSMOS_KIT_USE_CHAIN, NYM_MIXNET_CONTRACT } from '@/app/api/constants'
-
-export const useNymClient = (address?: string) => {
- const [nymClient, setNymClient] = useState()
- const [nymQueryClient, setNymQueryClient] = useState()
-
- const { getCosmWasmClient, getSigningCosmWasmClient } =
- useChain(COSMOS_KIT_USE_CHAIN)
-
- useEffect(() => {
- if (address) {
- const init = async () => {
- const cosmWasmSigningClient = await getSigningCosmWasmClient()
- const cosmWasmClient = await getCosmWasmClient()
-
- const client = new contracts.Mixnet.MixnetClient(
- cosmWasmSigningClient as any,
- address,
- NYM_MIXNET_CONTRACT
- )
- const queryClient = new contracts.Mixnet.MixnetQueryClient(
- cosmWasmClient as any,
- NYM_MIXNET_CONTRACT
- )
-
- setNymClient(client)
- setNymQueryClient(queryClient)
- }
-
- init()
- }
- }, [address, getCosmWasmClient, getSigningCosmWasmClient])
-
- return { nymClient, nymQueryClient }
-}
diff --git a/explorer-nextjs/app/icons/DelevateSVG.tsx b/explorer-nextjs/app/icons/DelevateSVG.tsx
deleted file mode 100644
index 56180d1b8a..0000000000
--- a/explorer-nextjs/app/icons/DelevateSVG.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import { SvgIcon, SvgIconProps } from '@mui/material';
-
-export const DelegateIcon = (props: SvgIconProps) => (
-
-
-
-
-
-
-
-);
diff --git a/explorer-nextjs/app/icons/ElipsSVG.tsx b/explorer-nextjs/app/icons/ElipsSVG.tsx
deleted file mode 100644
index 4a430d6cb6..0000000000
--- a/explorer-nextjs/app/icons/ElipsSVG.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import * as React from 'react';
-
-export const ElipsSVG: FCWithChildren = () => (
-
-);
diff --git a/explorer-nextjs/app/icons/GatewaysSVG.tsx b/explorer-nextjs/app/icons/GatewaysSVG.tsx
deleted file mode 100644
index 00e4a21198..0000000000
--- a/explorer-nextjs/app/icons/GatewaysSVG.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const GatewaysSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.text.primary;
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/LightSwitchSVG.tsx b/explorer-nextjs/app/icons/LightSwitchSVG.tsx
deleted file mode 100644
index 7a32590dfc..0000000000
--- a/explorer-nextjs/app/icons/LightSwitchSVG.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const LightSwitchSVG: FCWithChildren = () => {
- const { palette } = useTheme();
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/MixnodesSVG.tsx b/explorer-nextjs/app/icons/MixnodesSVG.tsx
deleted file mode 100644
index 56902cb0de..0000000000
--- a/explorer-nextjs/app/icons/MixnodesSVG.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const MixnodesSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.text.primary;
-
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/MobileDrawerClose.tsx b/explorer-nextjs/app/icons/MobileDrawerClose.tsx
deleted file mode 100644
index 6c8ecfacbc..0000000000
--- a/explorer-nextjs/app/icons/MobileDrawerClose.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as React from 'react';
-
-export const MobileDrawerClose: FCWithChildren = (props) => (
-
-);
diff --git a/explorer-nextjs/app/icons/NetworksSVG.tsx b/explorer-nextjs/app/icons/NetworksSVG.tsx
deleted file mode 100644
index 0db2b9bdfb..0000000000
--- a/explorer-nextjs/app/icons/NetworksSVG.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const NetworkComponentsSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.nym.networkExplorer.nav.text;
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/NodemapSVG.tsx b/explorer-nextjs/app/icons/NodemapSVG.tsx
deleted file mode 100644
index 9486d64dcc..0000000000
--- a/explorer-nextjs/app/icons/NodemapSVG.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const NodemapSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.nym.networkExplorer.nav.text;
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/NymVpn.tsx b/explorer-nextjs/app/icons/NymVpn.tsx
deleted file mode 100644
index ab9f484d91..0000000000
--- a/explorer-nextjs/app/icons/NymVpn.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as React from 'react'
-
-interface DiscordIconProps {
- size?: { width: number; height: number }
-}
-
-export const NymVpnIcon: FCWithChildren = ({ size }) => (
-
-)
diff --git a/explorer-nextjs/app/icons/OverviewSVG.tsx b/explorer-nextjs/app/icons/OverviewSVG.tsx
deleted file mode 100644
index 2ced0bb17b..0000000000
--- a/explorer-nextjs/app/icons/OverviewSVG.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const OverviewSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.nym.networkExplorer.nav.text;
-
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/TokenSVG.tsx b/explorer-nextjs/app/icons/TokenSVG.tsx
deleted file mode 100644
index 94ab1468c9..0000000000
--- a/explorer-nextjs/app/icons/TokenSVG.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from 'react';
-
-export const TokenSVG: FCWithChildren = () => {
- const color = 'white';
-
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/ValidatorsSVG.tsx b/explorer-nextjs/app/icons/ValidatorsSVG.tsx
deleted file mode 100644
index cf03f1c330..0000000000
--- a/explorer-nextjs/app/icons/ValidatorsSVG.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const ValidatorsSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.text.primary;
- return (
-
- );
-};
diff --git a/explorer-nextjs/app/icons/socials/DiscordIcon.tsx b/explorer-nextjs/app/icons/socials/DiscordIcon.tsx
deleted file mode 100644
index b81c571c33..0000000000
--- a/explorer-nextjs/app/icons/socials/DiscordIcon.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import * as React from 'react'
-import { useTheme } from '@mui/material/styles'
-
-interface DiscordIconProps {
- size?: number | string
- color?: string
-}
-
-export const DiscordIcon: FCWithChildren = ({
- size,
- color: colorProp,
-}) => {
- const theme = useTheme()
- const color = colorProp || theme.palette.text.primary
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/icons/socials/GitHubIcon.tsx b/explorer-nextjs/app/icons/socials/GitHubIcon.tsx
deleted file mode 100644
index 11389e6969..0000000000
--- a/explorer-nextjs/app/icons/socials/GitHubIcon.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import * as React from 'react'
-import { useTheme } from '@mui/material/styles'
-
-interface GitHubIconProps {
- size?: number | string
- color?: string
-}
-
-export const GitHubIcon: FCWithChildren = ({
- size,
- color: colorProp,
-}) => {
- const theme = useTheme()
- const color = colorProp || theme.palette.text.primary
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/icons/socials/TelegramIcon.tsx b/explorer-nextjs/app/icons/socials/TelegramIcon.tsx
deleted file mode 100644
index a66020a849..0000000000
--- a/explorer-nextjs/app/icons/socials/TelegramIcon.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import * as React from 'react'
-import { useTheme } from '@mui/material/styles'
-
-interface TelegramIconProps {
- size?: number | string
- color?: string
-}
-
-export const TelegramIcon: FCWithChildren = ({
- size,
- color: colorProp,
-}) => {
- const theme = useTheme()
- const color = colorProp || theme.palette.text.primary
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/icons/socials/TwitterIcon.tsx b/explorer-nextjs/app/icons/socials/TwitterIcon.tsx
deleted file mode 100644
index 5d94de99a3..0000000000
--- a/explorer-nextjs/app/icons/socials/TwitterIcon.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as React from 'react'
-import { useTheme } from '@mui/material/styles'
-
-interface TwitterIconProps {
- size?: number | string
- color?: string
-}
-
-export const TwitterIcon: FCWithChildren = ({
- size,
- color: colorProp,
-}) => {
- const theme = useTheme()
- const color = colorProp || theme.palette.text.primary
- return (
-
- )
-}
diff --git a/explorer-nextjs/app/layout.tsx b/explorer-nextjs/app/layout.tsx
deleted file mode 100644
index a532714d84..0000000000
--- a/explorer-nextjs/app/layout.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { Metadata } from 'next'
-import '@interchain-ui/react/styles'
-import { App } from './App'
-
-export const metadata: Metadata = {
- title: 'Nym Network Explorer',
-}
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode
-}>) {
- return (
-
-
- {children}
-
-
- )
-}
diff --git a/explorer-nextjs/app/loading.tsx b/explorer-nextjs/app/loading.tsx
deleted file mode 100644
index bb90466dc5..0000000000
--- a/explorer-nextjs/app/loading.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react'
-import { LinearProgress, Box } from '@mui/material'
-
-export default function Loading() {
- return (
-
-
-
- )
-}
diff --git a/explorer-nextjs/app/network-components/gateways/[id]/page.tsx b/explorer-nextjs/app/network-components/gateways/[id]/page.tsx
deleted file mode 100644
index 87f779872a..0000000000
--- a/explorer-nextjs/app/network-components/gateways/[id]/page.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { Alert, AlertTitle, Box, CircularProgress, Grid } from '@mui/material'
-import { useParams } from 'next/navigation'
-import {GatewayBond, LocatedGateway} from '@/app/typeDefs/explorer-api'
-import { ColumnsType, DetailTable } from '@/app/components/DetailTable'
-import {
- gatewayEnrichedToGridRow,
- GatewayEnrichedRowType,
-} from '@/app/components/Gateways/Gateways'
-import { ComponentError } from '@/app/components/ComponentError'
-import { ContentCard } from '@/app/components/ContentCard'
-import { TwoColSmallTable } from '@/app/components/TwoColSmallTable'
-import { UptimeChart } from '@/app/components/UptimeChart'
-import {
- GatewayContextProvider,
- useGatewayContext,
-} from '@/app/context/gateway'
-import { useMainContext } from '@/app/context/main'
-import { Title } from '@/app/components/Title'
-
-const columns: ColumnsType[] = [
- {
- field: 'identity_key',
- title: 'Identity Key',
- headerAlign: 'left',
- width: 230,
- },
- {
- field: 'bond',
- title: 'Bond',
- headerAlign: 'left',
- },
- {
- field: 'avgUptime',
- title: 'Avg. Score',
- headerAlign: 'left',
- tooltipInfo: "Gateway's average routing score in the last 24 hours",
- },
- {
- field: 'host',
- title: 'IP',
- headerAlign: 'left',
- width: 99,
- },
- {
- field: 'location',
- title: 'Location',
- headerAlign: 'left',
- },
- {
- field: 'owner',
- title: 'Owner',
- headerAlign: 'left',
- },
- {
- field: 'version',
- title: 'Version',
- headerAlign: 'left',
- },
-]
-
-/**
- * Shows gateway details
- */
-const PageGatewayDetailsWithState = ({
- selectedGateway,
-}: {
- selectedGateway: LocatedGateway | undefined
-}) => {
- const [enrichGateway, setEnrichGateway] =
- React.useState()
- const [status, setStatus] = React.useState()
- const { uptimeReport, uptimeStory } = useGatewayContext()
-
- React.useEffect(() => {
- if (uptimeReport?.data && selectedGateway) {
- setEnrichGateway(
- gatewayEnrichedToGridRow(selectedGateway, uptimeReport.data)
- )
- }
- }, [uptimeReport, selectedGateway])
-
- React.useEffect(() => {
- if (enrichGateway) {
- setStatus([enrichGateway.mixPort, enrichGateway.clientsPort])
- }
- }, [enrichGateway])
-
- return (
-
-
-
-
-
- Please update to the latest nym-node binary and migrate your bond and delegations from the wallet
-
-
-
-
-
-
-
-
-
-
-
- {status && (
-
- each)}
- icons={status.map((elem) => !!elem)}
- />
-
- )}
-
-
- {uptimeStory && (
-
- {uptimeStory.error && (
-
- )}
-
-
- )}
-
-
-
- )
-}
-
-/**
- * Guard component to handle loadingW and not found states
- */
-const PageGatewayDetailGuard = () => {
- const [selectedGateway, setSelectedGateway] = React.useState()
- const { gateways } = useMainContext()
- const { id } = useParams()
-
- React.useEffect(() => {
- if (gateways?.data) {
- setSelectedGateway(
- gateways.data.find((g) => g.gateway.identity_key === id)
- )
- }
- }, [gateways, id])
-
- if (gateways?.isLoading) {
- return
- }
-
- if (gateways?.error) {
- // eslint-disable-next-line no-console
- console.error(gateways?.error)
- return (
-
- Oh no! Could not load mixnode {id || ''}
-
- )
- }
-
- // loaded, but not found
- if (gateways && !gateways.isLoading && !gateways.data) {
- return (
-
- Gateway not found
- Sorry, we could not find a mixnode with id {id || ''}
-
- )
- }
-
- return
-}
-
-/**
- * Wrapper component that adds the mixnode content based on the `id` in the address URL
- */
-const PageGatewayDetail = () => {
- const { id } = useParams()
-
- if (!id || typeof id !== 'string') {
- return (
- Oh no! No mixnode identity key specified
- )
- }
-
- return (
-
-
-
- )
-}
-
-export default PageGatewayDetail
diff --git a/explorer-nextjs/app/network-components/gateways/page.tsx b/explorer-nextjs/app/network-components/gateways/page.tsx
deleted file mode 100644
index c2660ce387..0000000000
--- a/explorer-nextjs/app/network-components/gateways/page.tsx
+++ /dev/null
@@ -1,256 +0,0 @@
-'use client'
-
-import React, { useMemo } from 'react'
-import { Box, Card, Grid, Stack } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import {
- MRT_ColumnDef,
- MaterialReactTable,
- useMaterialReactTable,
-} from 'material-react-table'
-import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'
-import { Tooltip as InfoTooltip } from '@nymproject/react/tooltip/Tooltip'
-import { diff, gte, rcompare } from 'semver'
-import { useMainContext } from '@/app/context/main'
-import { TableToolbar } from '@/app/components/TableToolbar'
-import { CustomColumnHeading } from '@/app/components/CustomColumnHeading'
-import { Title } from '@/app/components/Title'
-import { unymToNym } from '@/app/utils/currency'
-import { Tooltip } from '@/app/components/Tooltip'
-import { EXPLORER_FOR_ACCOUNTS } from '@/app/api/constants'
-import { splice } from '@/app/utils'
-import {
- VersionDisplaySelector,
- VersionSelectOptions,
-} from '@/app/components/Gateways/VersionDisplaySelector'
-import StyledLink from '@/app/components/StyledLink'
-import {
- GatewayRowType,
- gatewayToGridRow,
-} from '@/app/components/Gateways/Gateways'
-import {LocatedGateway} from "@/app/typeDefs/explorer-api";
-
-const gatewaySanitize = (g?: LocatedGateway): boolean => {
- if(!g) {
- return false;
- }
-
- if(!g.gateway.version || !g.gateway.version.trim().length) {
- return false;
- }
-
- if(g.gateway.version === "null") {
- return false;
- }
-
- return true;
-}
-
-const PageGateways = () => {
- const { gateways } = useMainContext()
- const [versionFilter, setVersionFilter] =
- React.useState(VersionSelectOptions.all)
-
- const theme = useTheme()
-
- const highestVersion = React.useMemo(() => {
- if (gateways?.data) {
- const versions = gateways.data.filter(gatewaySanitize).reduce(
- (a: string[], b) => [...a, b.gateway.version],
- []
- )
- const [lastestVersion] = versions.sort(rcompare)
- return lastestVersion
- }
- // fallback value
- return '2.0.0'
- }, [gateways])
-
- const filterByLatestVersions = React.useMemo(() => {
- const filtered = gateways?.data?.filter(gatewaySanitize).filter((gw) => {
- const versionDiff = diff(highestVersion, gw.gateway.version)
- return versionDiff === 'patch' || versionDiff === null
- })
- if (filtered) return filtered
- return []
- }, [gateways])
-
- const filterByOlderVersions = React.useMemo(() => {
- const filtered = gateways?.data?.filter(gatewaySanitize).filter((gw) => {
- const versionDiff = diff(highestVersion, gw.gateway.version)
- return versionDiff === 'major' || versionDiff === 'minor'
- })
- if (filtered) return filtered
- return []
- }, [gateways])
-
- const filteredByVersion = React.useMemo(() => {
- switch (versionFilter) {
- case VersionSelectOptions.latestVersion:
- return filterByLatestVersions
- case VersionSelectOptions.olderVersions:
- return filterByOlderVersions
- case VersionSelectOptions.all:
- return gateways?.data || []
- default:
- return []
- }
- }, [versionFilter, gateways])
-
- const data = useMemo(() => {
- return gatewayToGridRow(filteredByVersion || [])
- }, [filteredByVersion])
-
- const columns = useMemo[]>(() => {
- return [
- {
- id: 'gateway-data',
- header: 'Gateways Data',
- columns: [
- {
- id: 'identity_key',
- header: 'Identity Key',
- accessorKey: 'identity_key',
- size: 250,
- Cell: ({ row }) => {
- return (
-
-
-
- {splice(7, 29, row.original.identity_key)}
-
-
- )
- },
- },
- {
- id: 'version',
- header: 'Version',
- accessorKey: 'version',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {row.original.version}
-
- )
- },
- },
- {
- id: 'location',
- header: 'Location',
- accessorKey: 'location',
- size: 150,
- Cell: ({ row }) => {
- return (
-
-
-
- {row.original.location}
-
-
-
- )
- },
- },
- {
- id: 'host',
- header: 'IP:Port',
- accessorKey: 'host',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {row.original.host}
-
- )
- },
- },
- {
- id: 'owner',
- header: 'Owner',
- accessorKey: 'owner',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {splice(7, 29, row.original.owner)}
-
- )
- },
- },
- ],
- },
- ]
- }, [])
-
- const table = useMaterialReactTable({
- columns,
- data,
- })
-
- return (
- <>
-
-
-
-
-
-
- setVersionFilter(option)}
- selected={versionFilter}
- />
- }
- />
-
-
-
-
- >
- )
-}
-
-export default PageGateways
diff --git a/explorer-nextjs/app/network-components/mixnodes/[id]/page.tsx b/explorer-nextjs/app/network-components/mixnodes/[id]/page.tsx
deleted file mode 100644
index 5e03b5d132..0000000000
--- a/explorer-nextjs/app/network-components/mixnodes/[id]/page.tsx
+++ /dev/null
@@ -1,302 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- Alert,
- AlertTitle,
- Box,
- CircularProgress,
- Grid,
- Typography,
-} from '@mui/material'
-import { ColumnsType, DetailTable } from '@/app/components/DetailTable'
-import { BondBreakdownTable } from '@/app/components/MixNodes/BondBreakdown'
-import {
- DelegatorsInfoTable,
- EconomicsInfoColumns,
- EconomicsInfoRows,
-} from '@/app/components/MixNodes/Economics'
-import { ComponentError } from '@/app/components/ComponentError'
-import { ContentCard } from '@/app/components/ContentCard'
-import { TwoColSmallTable } from '@/app/components/TwoColSmallTable'
-import { UptimeChart } from '@/app/components/UptimeChart'
-import { WorldMap } from '@/app/components/WorldMap'
-import { MixNodeDetailSection } from '@/app/components/MixNodes/DetailSection'
-import {
- MixnodeContextProvider,
- useMixnodeContext,
-} from '@/app/context/mixnode'
-import { Title } from '@/app/components/Title'
-import { useIsMobile } from '@/app/hooks/useIsMobile'
-import { useParams } from 'next/navigation'
-
-const columns: ColumnsType[] = [
- {
- field: 'owner',
- title: 'Owner',
- width: '15%',
- },
- {
- field: 'identity_key',
- title: 'Identity Key',
- width: '15%',
- },
-
- {
- field: 'bond',
- title: 'Stake',
- width: '12.5%',
- },
- {
- field: 'stake_saturation',
- title: 'Stake Saturation',
- width: '12.5%',
- tooltipInfo:
- 'Level of stake saturation for this node. Nodes receive more rewards the higher their saturation level, up to 100%. Beyond 100% no additional rewards are granted. The current stake saturation level is 940k NYMs, computed as S/K where S is target amount of tokens staked in the network and K is the number of nodes in the reward set.',
- },
- {
- field: 'self_percentage',
- width: '10%',
- title: 'Bond %',
- tooltipInfo:
- "Percentage of the operator's bond to the total stake on the node",
- },
-
- {
- field: 'host',
- width: '10%',
- title: 'Host',
- },
- {
- field: 'location',
- title: 'Location',
- },
-
- {
- field: 'layer',
- title: 'Layer',
- },
-]
-
-/**
- * Shows mix node details
- */
-const PageMixnodeDetailWithState = () => {
- const {
- mixNode,
- mixNodeRow,
- description,
- stats,
- status,
- uptimeStory,
- uniqDelegations,
- } = useMixnodeContext()
- const isMobile = useIsMobile()
- return (
-
-
-
-
- Please update to the latest nym-node binary and migrate your bond and delegations from the wallet
-
-
-
-
- {mixNodeRow && description?.data && (
-
- )}
- {mixNodeRow?.blacklisted && (
-
- This node is having a poor performance
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {stats && (
- <>
- {stats.error && (
-
- )}
-
-
- >
- )}
- {!stats && No stats information}
-
-
-
- {uptimeStory && (
-
- {uptimeStory.error && (
-
- )}
-
-
- )}
-
-
-
-
- {status && (
-
- {status.error && (
-
- )}
- each)}
- icons={
- (status?.data?.ports && Object.values(status.data.ports)) || [
- false,
- false,
- false,
- ]
- }
- />
-
- )}
-
-
- {mixNode && (
-
- {mixNode?.error && (
-
- )}
- {mixNode?.data?.location?.latitude &&
- mixNode?.data?.location?.longitude && (
-
- )}
-
- )}
-
-
-
- )
-}
-
-/**
- * Guard component to handle loading and not found states
- */
-const PageMixnodeDetailGuard = () => {
- const { mixNode } = useMixnodeContext()
- const { id } = useParams()
-
- if (mixNode?.isLoading) {
- return
- }
-
- if (mixNode?.error) {
- // eslint-disable-next-line no-console
- console.error(mixNode?.error)
- return (
-
- Oh no! Could not load mixnode {id || ''}
-
- )
- }
-
- // loaded, but not found
- if (mixNode && !mixNode.isLoading && !mixNode.data) {
- return (
-
- Mixnode not found
- Sorry, we could not find a mixnode with id {id || ''}
-
- )
- }
-
- return
-}
-
-/**
- * Wrapper component that adds the mixnode content based on the `id` in the address URL
- */
-const PageMixnodeDetail = () => {
- const { id } = useParams()
-
- if (!id || typeof id !== 'string') {
- return (
- Oh no! No mixnode identity key specified
- )
- }
-
- return (
-
-
-
- )
-}
-
-export default PageMixnodeDetail
diff --git a/explorer-nextjs/app/network-components/mixnodes/page.tsx b/explorer-nextjs/app/network-components/mixnodes/page.tsx
deleted file mode 100644
index 2f2774a7f4..0000000000
--- a/explorer-nextjs/app/network-components/mixnodes/page.tsx
+++ /dev/null
@@ -1,382 +0,0 @@
-'use client'
-
-import React, { useCallback, useMemo } from 'react'
-import { useRouter, useSearchParams } from 'next/navigation'
-import {
- MaterialReactTable,
- useMaterialReactTable,
- type MRT_ColumnDef,
-} from 'material-react-table'
-import { Grid, Card, Button, Box, Stack } from '@mui/material'
-import {
- CustomColumnHeading,
- DelegateIconButton,
- DelegateModal,
- DelegationModal,
- DelegationModalProps,
- MixNodeStatusDropdown,
- MixnodeRowType,
- StyledLink,
- TableToolbar,
- Title,
- Tooltip,
- mixnodeToGridRow,
-} from '@/app/components'
-import { DelegationsProvider } from '@/app/context/delegations'
-import { useWalletContext } from '@/app/context/wallet'
-import { useGetMixNodeStatusColor, useIsMobile } from '@/app/hooks'
-import { useMainContext } from '@/app/context/main'
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'
-import { splice } from '@/app/utils'
-import { currencyToString } from '@/app/utils/currency'
-import { EXPLORER_FOR_ACCOUNTS } from '@/app/api/constants'
-import {
- MixnodeStatusWithAll,
- toMixnodeStatus,
-} from '@/app/typeDefs/explorer-api'
-
-export default function MixnodesPage() {
- const isMobile = useIsMobile()
- const { isWalletConnected } = useWalletContext()
- const { mixnodes, fetchMixnodes } = useMainContext()
- const router = useRouter()
-
- const [itemSelectedForDelegation, setItemSelectedForDelegation] =
- React.useState<{
- mixId: number
- identityKey: string
- }>()
- const [confirmationModalProps, setConfirmationModalProps] = React.useState<
- DelegationModalProps | undefined
- >()
-
- const search = useSearchParams()
- const status = search.get('status') as MixnodeStatusWithAll
-
- React.useEffect(() => {
- // when the status changes, get the mixnodes
- fetchMixnodes(toMixnodeStatus(status))
- }, [status])
-
- const handleMixnodeStatusChanged = (newStatus?: MixnodeStatusWithAll) => {
- router.push(
- newStatus && newStatus !== 'all'
- ? `/network-components/mixnodes?status=${newStatus}`
- : '/network-components/mixnodes'
- )
- }
-
- const handleOnDelegate = useCallback(
- ({ identityKey, mixId }: { identityKey: string; mixId: number }) => {
- if (!isWalletConnected) {
- setConfirmationModalProps({
- status: 'info',
- message: 'Please connect your wallet to delegate',
- })
- } else {
- setItemSelectedForDelegation({ identityKey, mixId })
- }
- },
- [isWalletConnected]
- )
-
- const handleNewDelegation = (delegationModalProps: DelegationModalProps) => {
- setItemSelectedForDelegation(undefined)
- setConfirmationModalProps(delegationModalProps)
- }
-
- const columns = useMemo[]>(() => {
- return [
- {
- id: 'mixnode-data',
- header: 'Mixnode Data',
- columns: [
- {
- id: 'delegate',
- accessorKey: 'delegate',
- size: isMobile ? 50 : 150,
- header: '',
- grow: false,
- Cell: ({ row }) => (
-
- handleOnDelegate({
- identityKey: row.original.identity_key,
- mixId: row.original.mix_id,
- })
- }
- />
- ),
- enableSorting: false,
- enableColumnActions: false,
- Filter: () => null,
- },
- {
- id: 'identity_key',
- header: 'Identity Key',
- accessorKey: 'identity_key',
- size: 250,
- Cell: ({ row }) => {
- return (
-
-
-
- {splice(7, 29, row.original.identity_key)}
-
-
- )
- },
- },
- {
- id: 'bond',
- header: 'Stake',
- accessorKey: 'bond',
- Cell: ({ row }) => (
-
- {currencyToString({ amount: row.original.bond.toString() })}
-
- ),
- },
- {
- id: 'stake_saturation',
- header: 'Stake Saturation',
- accessorKey: 'stake_saturation',
- size: 225,
- Header() {
- return (
-
- )
- },
- Cell: ({ row }) => (
- {`${row.original.stake_saturation} %`}
- ),
- },
- {
- id: 'pledge_amount',
- header: 'Bond',
- accessorKey: 'pledge_amount',
- size: 185,
- Header: () => (
-
- ),
- Cell: ({ row }) => (
-
- {currencyToString({
- amount: row.original.pledge_amount.toString(),
- })}
-
- ),
- },
- {
- id: 'profit_percentage',
- accessorKey: 'profit_percentage',
- header: 'Profit Margin',
- size: 145,
- Header: () => (
-
- ),
- Cell: ({ row }) => (
- {`${row.original.profit_percentage}%`}
- ),
- },
- {
- id: 'operating_cost',
- accessorKey: 'operating_cost',
- size: 220,
- header: 'Operating Cost',
- disableColumnMenu: true,
- Header: () => (
-
- ),
- Cell: ({ row }) => (
- {`${row.original.operating_cost} NYM`}
- ),
- },
- {
- id: 'owner',
- accessorKey: 'owner',
- size: 150,
- header: 'Owner',
- Header: () => ,
- Cell: ({ row }) => (
-
- {splice(7, 29, row.original.owner)}
-
- ),
- },
- {
- id: 'location',
- accessorKey: 'location',
- header: 'Location',
- maxSize: 150,
- Header: () => ,
- Cell: ({ row }) => (
-
-
- {row.original.location}
-
-
- ),
- },
- {
- id: 'host',
- accessorKey: 'host',
- header: 'Host',
- size: 130,
- Header: () => ,
- Cell: ({ row }) => (
-
- {row.original.host}
-
- ),
- },
- ],
- },
- ]
- }, [handleOnDelegate, isMobile])
-
- const data = useMemo(() => {
- return mixnodeToGridRow(mixnodes?.data)
- }, [mixnodes?.data])
-
- const table = useMaterialReactTable({
- columns,
- data,
- enableFullScreenToggle: false,
- state: {
- isLoading: mixnodes?.isLoading,
- },
- layoutMode: 'grid-no-grow',
- initialState: {
- columnPinning: { left: ['delegate'] },
- },
- })
-
- return (
-
-
-
-
-
-
-
-
- }
- childrenAfter={
- isWalletConnected && (
-
- )
- }
- />
-
-
-
-
- {itemSelectedForDelegation && (
- {
- setItemSelectedForDelegation(undefined)
- }}
- header="Delegate"
- buttonText="Delegate stake"
- denom="nym"
- onOk={(delegationModalProps: DelegationModalProps) =>
- handleNewDelegation(delegationModalProps)
- }
- identityKey={itemSelectedForDelegation.identityKey}
- mixId={itemSelectedForDelegation.mixId}
- />
- )}
-
- {confirmationModalProps && (
- {
- setConfirmationModalProps(undefined)
- if (confirmationModalProps.status === 'success') {
- router.push('/delegations')
- }
- }}
- sx={{
- width: {
- xs: '90%',
- sm: 600,
- },
- }}
- />
- )}
-
- )
-}
diff --git a/explorer-nextjs/app/network-components/nodes/DeclaredRole.tsx b/explorer-nextjs/app/network-components/nodes/DeclaredRole.tsx
deleted file mode 100644
index fac36689f2..0000000000
--- a/explorer-nextjs/app/network-components/nodes/DeclaredRole.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from "react";
-import { Chip } from "@mui/material";
-
-export const DeclaredRole = ({ declared_role }: { declared_role?: any }) => (
- <>
- {declared_role?.mixnode && }
- {declared_role?.entry && }
- {declared_role?.exit_nr && }
- {declared_role?.exit_ipr && }
- >
-)
\ No newline at end of file
diff --git a/explorer-nextjs/app/network-components/nodes/[id]/NodeDelegationsTable.tsx b/explorer-nextjs/app/network-components/nodes/[id]/NodeDelegationsTable.tsx
deleted file mode 100644
index a1b754ccce..0000000000
--- a/explorer-nextjs/app/network-components/nodes/[id]/NodeDelegationsTable.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import React, {useMemo} from "react";
-import {MaterialReactTable, MRT_ColumnDef, useMaterialReactTable} from "material-react-table";
-import StyledLink from "../../../components/StyledLink";
-import {EXPLORER_FOR_ACCOUNTS} from "@/app/api/constants";
-import {splice} from "@/app/utils";
-import {humanReadableCurrencyToString} from "@/app/utils/currency";
-import {Typography} from "@mui/material";
-import {useTheme} from "@mui/material/styles";
-import WarningIcon from '@mui/icons-material/Warning';
-import { Tooltip } from '@/app/components/Tooltip'
-
-export const NodeDelegationsTable = ({ node }: { node: any}) => {
- const columns = useMemo[]>(() => {
- return [
- {
- id: 'nym-node-delegation-data',
- header: 'Nym Node Delegations',
- columns: [
- {
- id: 'owner',
- header: 'Delegator',
- accessorKey: 'owner',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {splice(7, 29, row.original.owner)}
-
- )
- },
- },
- {
- id: 'amount',
- header: 'Amount',
- accessorKey: 'amount',
- size: 150,
- Cell: ({ row }) => (
- <>{humanReadableCurrencyToString(row.original.amount)}>
- )
- },
- {
- id: 'height',
- header: 'Delegated at height',
- accessorKey: 'height',
- size: 150,
- },
- {
- id: 'proxy',
- header: 'From vesting account?',
- accessorKey: 'proxy',
- size: 250,
- Cell: ({ row }) => {
- if(row.original.proxy?.length) {
- return (
- Please re-delegate from your main account
- )
- }
- }
- },
- ]
- }
- ];
- }, []);
-
- const table = useMaterialReactTable({
- columns,
- data: node ? node.delegations : [],
- });
-
- return (
-
- );
-}
-
-export const VestingDelegationWarning = ({children, plural}: { plural?: boolean, children: React.ReactNode}) => {
- const theme = useTheme();
- return (
-
-
-
- {children}
-
-
- );
-}
\ No newline at end of file
diff --git a/explorer-nextjs/app/network-components/nodes/[id]/page.tsx b/explorer-nextjs/app/network-components/nodes/[id]/page.tsx
deleted file mode 100644
index 95a172d21e..0000000000
--- a/explorer-nextjs/app/network-components/nodes/[id]/page.tsx
+++ /dev/null
@@ -1,336 +0,0 @@
-"use client";
-
-import * as React from "react";
-import { Alert, AlertTitle, Box, CircularProgress, Grid } from "@mui/material";
-import { useParams } from "next/navigation";
-import { ColumnsType, DetailTable } from "@/app/components/DetailTable";
-import { ComponentError } from "@/app/components/ComponentError";
-import { ContentCard } from "@/app/components/ContentCard";
-import { UptimeChart } from "@/app/components/UptimeChart";
-import { NymNodeContextProvider, useNymNodeContext } from "@/app/context/node";
-import { useMainContext } from "@/app/context/main";
-import { Title } from "@/app/components/Title";
-import Paper from "@mui/material/Paper";
-import Table from "@mui/material/Table";
-import TableBody from "@mui/material/TableBody";
-import TableCell from "@mui/material/TableCell";
-import TableContainer from "@mui/material/TableContainer";
-import TableRow from "@mui/material/TableRow";
-import { humanReadableCurrencyToString } from "@/app/utils/currency";
-import { DeclaredRole } from "@/app/network-components/nodes/DeclaredRole";
-import {
- NodeDelegationsTable,
- VestingDelegationWarning,
-} from "@/app/network-components/nodes/[id]/NodeDelegationsTable";
-
-const columns: ColumnsType[] = [
- {
- field: "identity_key",
- title: "Identity Key",
- headerAlign: "left",
- width: 230,
- },
- {
- field: "bond",
- title: "Bond",
- headerAlign: "left",
- },
- {
- field: "host",
- title: "IP",
- headerAlign: "left",
- width: 99,
- },
- {
- field: "location",
- title: "Location",
- headerAlign: "left",
- },
- {
- field: "owner",
- title: "Owner",
- headerAlign: "left",
- },
- {
- field: "version",
- title: "Version",
- headerAlign: "left",
- },
-];
-
-interface NodeEnrichedRowType {
- node_id: number;
- identity_key: string;
- bond: string;
- host: string;
- location: string;
- owner: string;
- version: string;
-}
-
-function nodeEnrichedToGridRow(node: any): NodeEnrichedRowType {
- return {
- node_id: node.node_id,
- owner: node.bond_information?.owner || "",
- identity_key: node.bond_information?.node?.identity_key || "",
- location: node.location?.country_name || "",
- bond: node.bond_information?.original_pledge.amount || 0, // TODO: format
- host: node.bond_information?.node?.host || "",
- version: node.description?.build_information?.build_version || "",
- };
-}
-
-/**
- * Shows nym node details
- */
-const PageNymNodeDetailsWithState = ({
- selectedNymNode,
-}: {
- selectedNymNode?: any;
-}) => {
- const { uptimeHistory } = useNymNodeContext();
- const enrichedData = React.useMemo(
- () => (selectedNymNode ? [nodeEnrichedToGridRow(selectedNymNode)] : []),
- []
- );
-
- const hasVestingContractDelegations = React.useMemo(
- () => selectedNymNode?.delegations?.filter((d: any) => d.proxy)?.length,
- [selectedNymNode]
- );
-
- return (
-
-
-
-
-
-
-
-
-
-
- {selectedNymNode.rewarding_details && (
-
-
-
-
-
- Delegations and Rewards
-
-
-
- Operator
-
-
- {humanReadableCurrencyToString({
- amount:
- selectedNymNode.rewarding_details.operator.split(
- "."
- )[0],
- denom: "unym",
- })}
-
-
-
-
-
- {hasVestingContractDelegations ? (
-
- Delegates (
- {
- selectedNymNode.rewarding_details
- .unique_delegations
- }{" "}
- delegates)
-
- ) : (
- <>
- Delegates (
- {
- selectedNymNode.rewarding_details
- .unique_delegations
- }{" "}
- delegates)
- >
- )}
-
-
-
- {humanReadableCurrencyToString({
- amount:
- selectedNymNode.rewarding_details.delegates.split(
- "."
- )[0],
- denom: "unym",
- })}
-
-
-
-
- Profit margin
-
-
- {selectedNymNode.rewarding_details.cost_params
- .profit_margin_percent * 100}
- %
-
-
-
-
- Operator costs
-
-
- {humanReadableCurrencyToString(
- selectedNymNode.rewarding_details.cost_params
- .interval_operating_cost
- )}
-
-
-
-
-
-
- )}
-
- {selectedNymNode.description?.declared_role && (
-
-
-
-
-
- Node roles
-
-
- Self declared roles
-
-
-
-
-
-
-
-
- )}
-
-
-
-
- {uptimeHistory && (
-
- {uptimeHistory.error && (
-
- )}
-
-
- )}
-
-
-
-
-
-
-
- );
-};
-
-/**
- * Guard component to handle loading and not found states
- */
-const PageNymNodeDetailGuard = () => {
- const [selectedNode, setSelectedNode] = React.useState();
- const [isLoading, setLoading] = React.useState(true);
- const [error, setError] = React.useState();
- const { fetchNodeById } = useMainContext();
- const { id } = useParams();
-
- React.useEffect(() => {
- setSelectedNode(undefined);
- setLoading(true);
- (async () => {
- if (typeof id === "string") {
- try {
- const res = await fetchNodeById(Number.parseInt(id));
- setSelectedNode(res);
- } catch (e: any) {
- setError(e.message);
- } finally {
- setLoading(false);
- }
- }
- })();
- }, [id, fetchNodeById]);
-
- if (isLoading) {
- return ;
- }
-
- // loaded, but not found
- if (error) {
- return (
-
- Nym node not found
- Sorry, we could not find a node with id {id || ""}
-
- );
- }
-
- if (!selectedNode) {
- return (
-
- Legacy Node
- Unable to load details for the selected Nym node.
-
- );
- }
-
- return ;
-};
-
-/**
- * Wrapper component that adds the node content based on the `id` in the address URL
- */
-const PageNymNodeDetail = () => {
- const { id } = useParams();
-
- if (!id || typeof id !== "string") {
- return Oh no! Could not find that node;
- }
-
- return (
-
-
-
- );
-};
-
-export default PageNymNodeDetail;
diff --git a/explorer-nextjs/app/network-components/nodes/page.tsx b/explorer-nextjs/app/network-components/nodes/page.tsx
deleted file mode 100644
index 75e5b97fdd..0000000000
--- a/explorer-nextjs/app/network-components/nodes/page.tsx
+++ /dev/null
@@ -1,254 +0,0 @@
-'use client'
-
-import React, { useMemo } from 'react'
-import { Box, Card, Grid, Stack, Chip } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import {
- MRT_ColumnDef,
- MaterialReactTable,
- useMaterialReactTable,
-} from 'material-react-table'
-import { diff, gte, rcompare } from 'semver'
-import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'
-import { Tooltip as InfoTooltip } from '@nymproject/react/tooltip/Tooltip'
-import { useMainContext } from '@/app/context/main'
-import { CustomColumnHeading } from '@/app/components/CustomColumnHeading'
-import { Title } from '@/app/components/Title'
-import { humanReadableCurrencyToString } from '@/app/utils/currency'
-import { Tooltip } from '@/app/components/Tooltip'
-import { EXPLORER_FOR_ACCOUNTS } from '@/app/api/constants'
-import { splice } from '@/app/utils'
-
-import StyledLink from '@/app/components/StyledLink'
-import {DeclaredRole} from "@/app/network-components/nodes/DeclaredRole";
-
-function getFlagEmoji(countryCode: string) {
- const codePoints = countryCode
- .toUpperCase()
- .split('')
- .map(char => 127397 + char.charCodeAt(0));
- return String.fromCodePoint(...codePoints);
-}
-
-const PageNodes = () => {
- const [isLoading, setLoading] = React.useState(true);
- const { nodes, fetchNodes } = useMainContext()
-
- React.useEffect(() => {
- (async () => {
- try {
- await fetchNodes();
- } finally {
- setLoading(false);
- }
- })();
- }, []);
-
- const columns = useMemo[]>(() => {
- return [
- {
- id: 'nym-node-data',
- header: 'Nym Node Data',
- columns: [
- {
- id: 'node_id',
- header: 'Node Id',
- accessorKey: 'node_id',
- size: 75,
- },
- {
- id: 'identity_key',
- header: 'Identity Key',
- accessorKey: 'identity_key',
- size: 250,
- Cell: ({ row }) => {
- return (
-
-
-
- {splice(7, 29, row.original.bond_information.node.identity_key)}
-
-
- )
- },
- },
- {
- id: 'version',
- header: 'Version',
- accessorKey: 'description.build_information.build_version',
- size: 75,
- Cell: ({ row }) => {
- return (
-
- {row.original.description?.build_information?.build_version || "-"}
-
- )
- },
- },
- {
- id: 'contract_node_type',
- header: 'Kind',
- accessorKey: 'contract_node_type',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {row.original.contract_node_type || "-"}
-
- )
- },
- },
- {
- id: 'declared_role',
- header: 'Declare Role',
- accessorKey: 'description.declared_role',
- size: 250,
- Cell: ({ row }) => {
- return (
-
-
-
- )
- },
- },
- {
- id: 'total_stake',
- header: 'Total Stake',
- accessorKey: 'description.total_stake',
- size: 250,
- Cell: ({ row }) => {
- return (
-
- {humanReadableCurrencyToString({ amount: row.original.total_stake || 0, denom: "unym" })}
-
- )
- },
- },
- {
- id: 'location',
- header: 'Location',
- accessorKey: 'location.country_name',
- size: 75,
- Cell: ({ row }) => {
- return (
-
-
-
- {row.original.location?.country_name ? <>{getFlagEmoji(row.original.location.two_letter_iso_country_code.toUpperCase())} {row.original.location.two_letter_iso_country_code}> : <>-> }
-
-
-
- )
- },
- },
- {
- id: 'host',
- header: 'IP',
- accessorKey: 'bond_information.node.host',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {row.original.bond_information?.node?.host || "-"}
-
- )
- },
- },
- {
- id: 'owner',
- header: 'Owner',
- accessorKey: 'bond_information.owner',
- size: 150,
- Cell: ({ row }) => {
- return (
-
- {splice(7, 29, row.original.bond_information?.owner)}
-
- )
- },
- },
- ],
- },
- ]
- }, [])
-
- const table = useMaterialReactTable({
- columns,
- data: nodes?.data || [],
- state: {
- isLoading,
- showLoadingOverlay: isLoading,
- },
- initialState: {
- isLoading: true,
- showLoadingOverlay: true,
- }
- })
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
- >
- )
-}
-
-export default PageNodes
diff --git a/explorer-nextjs/app/nodemap/page.tsx b/explorer-nextjs/app/nodemap/page.tsx
deleted file mode 100644
index 674ae57a5e..0000000000
--- a/explorer-nextjs/app/nodemap/page.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-'use client'
-
-import React, { useMemo } from 'react'
-import {
- Alert,
- Box,
- CircularProgress,
- Grid,
- SelectChangeEvent,
- Typography,
-} from '@mui/material'
-import { ContentCard } from '@/app/components/ContentCard'
-import { TableToolbar } from '@/app/components/TableToolbar'
-import { Title } from '@/app/components/Title'
-import { WorldMap } from '@/app/components/WorldMap'
-import { useMainContext } from '@/app/context/main'
-import { CountryDataRowType, countryDataToGridRow } from '@/app/utils'
-import {
- MRT_ColumnDef,
- MaterialReactTable,
- useMaterialReactTable,
-} from 'material-react-table'
-
-const PageMixnodesMap = () => {
- const { countryData } = useMainContext()
-
- const data = useMemo(() => {
- return countryDataToGridRow(Object.values(countryData?.data || {}))
- }, [countryData])
-
- const columns = useMemo[]>(() => {
- return [
- {
- id: 'delegations-data',
- header: 'Global Mixnodes Data',
- columns: [
- {
- id: 'country-name',
- header: 'Location',
- accessorKey: 'countryName',
- },
- {
- id: 'nodes',
- header: 'Nodes',
- accessorKey: 'nodes',
- },
- {
- id: 'percentage',
- header: 'Percentage',
- accessorKey: 'percentage',
- },
- ],
- },
- ]
- }, [])
-
- const table = useMaterialReactTable({
- columns,
- data,
- })
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
-
-export default PageMixnodesMap
diff --git a/explorer-nextjs/app/page.tsx b/explorer-nextjs/app/page.tsx
deleted file mode 100644
index 2c6f9f781c..0000000000
--- a/explorer-nextjs/app/page.tsx
+++ /dev/null
@@ -1,144 +0,0 @@
-'use client'
-
-import React, { useEffect } from 'react'
-import { Box, Grid, Link, Typography } from '@mui/material'
-import { useTheme } from '@mui/material/styles'
-import OpenInNewIcon from '@mui/icons-material/OpenInNew'
-import { PeopleAlt } from '@mui/icons-material'
-import { Title } from '@/app/components/Title'
-import { StatsCard } from '@/app/components/StatsCard'
-import { MixnodesSVG } from '@/app/icons/MixnodesSVG'
-import { Icons } from '@/app/components/Icons'
-import { GatewaysSVG } from '@/app/icons/GatewaysSVG'
-import { ValidatorsSVG } from '@/app/icons/ValidatorsSVG'
-import { ContentCard } from '@/app/components/ContentCard'
-import { WorldMap } from '@/app/components/WorldMap'
-import { BLOCK_EXPLORER_BASE_URL } from '@/app/api/constants'
-import { formatNumber } from '@/app/utils'
-import { useMainContext } from './context/main'
-import { useRouter } from 'next/navigation'
-
-const PageOverview = () => {
- const theme = useTheme()
- const router = useRouter()
-
- const {
- summaryOverview,
- gateways,
- validators,
- block,
- countryData,
- serviceProviders,
- } = useMainContext()
- return (
-
-
-
-
-
-
-
- {summaryOverview && (
- <>
-
- router.push('/network-components/nodes')}
- title="Nodes"
- icon={}
- count={summaryOverview.data?.nymnodes?.count || ''}
- errorMsg={summaryOverview?.error}
- />
-
- >
- )}
- {summaryOverview && (
-
- router.push('/network-components/nodes')}
- title="Mixnodes"
- count={summaryOverview.data?.nymnodes?.roles?.mixnode || ''}
- icon={}
- />
-
- )}
- {summaryOverview && (
-
- router.push('/network-components/nodes')}
- title="Entry Gateways"
- count={summaryOverview.data?.nymnodes?.roles?.entry || ''}
- icon={}
- />
-
- )}
- {summaryOverview && (
-
- router.push('/network-components/nodes')}
- title="Exit Gateways"
- count={summaryOverview.data?.nymnodes?.roles?.exit_ipr || ''}
- icon={}
- />
-
- )}
- {summaryOverview && (
-
- router.push('/network-components/nodes')}
- title="SOCKS5 Network Requesters"
- count={summaryOverview.data?.nymnodes?.roles?.exit_nr || ''}
- icon={}
- />
-
- )}
- {validators && (
-
- window.open(`${BLOCK_EXPLORER_BASE_URL}/validators`)}
- title="Validators"
- count={validators?.data?.count || ''}
- errorMsg={validators?.error}
- icon={}
- />
-
- )}
- {block?.data && (
-
-
-
- Current block height is {formatNumber(block.data)}
-
-
-
-
- )}
-
-
-
-
-
-
-
-
-
- )
-}
-
-export default PageOverview
diff --git a/explorer-nextjs/app/providers/index.tsx b/explorer-nextjs/app/providers/index.tsx
deleted file mode 100644
index 346d2fc88e..0000000000
--- a/explorer-nextjs/app/providers/index.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react'
-import CosmosKitProvider from '@/app/context/cosmos-kit'
-import { WalletProvider } from '@/app/context/wallet'
-import { NetworkExplorerThemeProvider } from '@/app/theme'
-import { MainContextProvider } from '@/app/context/main'
-
-const Providers = ({ children }: { children: React.ReactNode }) => {
- return (
-
-
-
- {children}
-
-
-
- )
-}
-
-export { Providers }
diff --git a/explorer-nextjs/app/theme/index.tsx b/explorer-nextjs/app/theme/index.tsx
deleted file mode 100644
index fd072cfc64..0000000000
--- a/explorer-nextjs/app/theme/index.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import { NymNetworkExplorerThemeProvider } from '@nymproject/mui-theme'
-import { useMainContext } from '../context/main'
-
-export const NetworkExplorerThemeProvider: FCWithChildren = ({ children }) => {
- const { mode } = useMainContext()
-
- return (
-
- {children}
-
- )
-}
diff --git a/explorer-nextjs/app/theme/mui-theme.d.ts b/explorer-nextjs/app/theme/mui-theme.d.ts
deleted file mode 100644
index 6d5f9aabf1..0000000000
--- a/explorer-nextjs/app/theme/mui-theme.d.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Theme, ThemeOptions, Palette, PaletteOptions } from '@mui/material/styles';
-import { NymTheme, NymPaletteWithExtensions, NymPaletteWithExtensionsOptions } from '@nymproject/mui-theme';
-
-/**
- * If you are unfamiliar with Material UI theming, please read the following first:
- * - https://mui.com/customization/theming/
- * - https://mui.com/customization/palette/
- * - https://mui.com/customization/dark-mode/#dark-mode-with-custom-palette
- *
- * This file adds typings to the theme using Typescript's module augmentation.
- *
- * Read the following if you are unfamiliar with module augmentation and declaration merging. Then
- * look at the recommendations from Material UI docs for implementation:
- * - https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
- * - https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces
- * - https://mui.com/customization/palette/#adding-new-colors
- *
- *
- * IMPORTANT:
- *
- * The type augmentation must match MUI's definitions. So, notice the use of `interface` rather than
- * `type Foo = { ... }` - this is necessary to merge the definitions.
- */
-
-declare module '@mui/material/styles' {
- /**
- * This augments the definitions of the MUI Theme with the Nym theme, as well as
- * a partial `ThemeOptions` type used by `createTheme`
- *
- * IMPORTANT: only add extensions to the interfaces above, do not modify the lines below
- */
- interface Theme extends NymTheme { }
- interface ThemeOptions extends Partial { }
- interface Palette extends NymPaletteWithExtensions { }
- interface PaletteOptions extends NymPaletteWithExtensionsOptions { }
-}
diff --git a/explorer-nextjs/app/typeDefs/explorer-api.ts b/explorer-nextjs/app/typeDefs/explorer-api.ts
deleted file mode 100644
index b15490008d..0000000000
--- a/explorer-nextjs/app/typeDefs/explorer-api.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-/* eslint-disable camelcase */
-
-export interface ClientConfig {
- url: string;
- version: string;
-}
-
-export interface SummaryOverviewResponse {
- mixnodes: {
- count: number;
- activeset: {
- active: number;
- standby: number;
- inactive: number;
- };
- };
- gateways: {
- count: number;
- };
- validators: {
- count: number;
- };
- nymnodes: {
- count: number;
- roles: {
- mixnode: number;
- entry: number;
- exit_nr: number;
- exit_ipr: number;
- };
- };
-}
-
-export interface MixNode {
- host: string;
- mix_port: number;
- http_api_port: number;
- verloc_port: number;
- sphinx_key: string;
- identity_key: string;
- version: string;
- location: string;
-}
-
-export interface Gateway {
- host: string;
- mix_port: number;
- clients_port: number;
- location: string;
- sphinx_key: string;
- identity_key: string;
- version: string;
-}
-
-export interface Amount {
- denom: string;
- amount: number;
-}
-
-export enum MixnodeStatus {
- active = 'active', // in both the active set and the rewarded set
- standby = 'standby', // only in the rewarded set
- inactive = 'inactive', // in neither the rewarded set nor the active set
-}
-
-export enum MixnodeStatusWithAll {
- active = 'active', // in both the active set and the rewarded set
- standby = 'standby', // only in the rewarded set
- inactive = 'inactive', // in neither the rewarded set nor the active set
- all = 'all', // any status
-}
-
-export const toMixnodeStatus = (status?: MixnodeStatusWithAll): MixnodeStatus | undefined => {
- if (!status || status === MixnodeStatusWithAll.all) {
- return undefined;
- }
- return status as unknown as MixnodeStatus;
-};
-
-export interface MixNodeResponseItem {
- mix_id: number;
- pledge_amount: Amount;
- total_delegation: Amount;
- owner: string;
- layer: string;
- status: MixnodeStatus;
- location: {
- country_name: string;
- latitude?: number;
- longitude?: number;
- three_letter_iso_country_code: string;
- two_letter_iso_country_code: string;
- };
- mix_node: MixNode;
- avg_uptime: number;
- node_performance: NodePerformance;
- stake_saturation: number;
- uncapped_saturation: number;
- operating_cost: Amount;
- profit_margin_percent: string;
- blacklisted: boolean;
-}
-
-export type MixNodeResponse = MixNodeResponseItem[];
-
-export interface MixNodeReportResponse {
- identity: string;
- owner: string;
- most_recent_ipv4: boolean;
- most_recent_ipv6: boolean;
- last_hour_ipv4: number;
- last_hour_ipv6: number;
- last_day_ipv4: number;
- last_day_ipv6: number;
-}
-
-export interface StatsResponse {
- update_time: Date;
- previous_update_time: Date;
- packets_received_since_startup: number;
- packets_sent_since_startup: number;
- packets_explicitly_dropped_since_startup: number;
- packets_received_since_last_update: number;
- packets_sent_since_last_update: number;
- packets_explicitly_dropped_since_last_update: number;
-}
-
-export interface NodePerformance {
- most_recent: string;
- last_hour: string;
- last_24h: string;
-}
-
-export type MixNodeHistoryResponse = StatsResponse;
-
-export interface GatewayBond {
- block_height: number;
- pledge_amount: Amount;
- total_delegation: Amount;
- owner: string;
- gateway: Gateway;
- node_performance: NodePerformance;
- location?: Location;
-}
-
-export interface GatewayBondAnnotated {
- gateway_bond: GatewayBond;
- node_performance: NodePerformance;
-}
-
-export interface Location {
- two_letter_iso_country_code: string;
- three_letter_iso_country_code: string;
- country_name: string;
- latitude?: number;
- longitude?: number;
-}
-
-export interface LocatedGateway {
- pledge_amount: Amount;
- owner: string;
- block_height: number;
- gateway: Gateway;
- proxy?: string;
- location?: Location;
-}
-
-export type GatewayResponse = LocatedGateway[];
-
-export interface NymNodeReportResponse {
- identity: string;
- owner: string;
- most_recent: number;
- last_hour: number;
- last_day: number;
-}
-
-export interface GatewayReportResponse {
- identity: string;
- owner: string;
- most_recent: number;
- last_hour: number;
- last_day: number;
-}
-
-export type GatewayHistoryResponse = StatsResponse;
-
-export interface MixNodeDescriptionResponse {
- name: string;
- description: string;
- link: string;
- location: string;
-}
-
-export type MixNodeStatsResponse = StatsResponse;
-
-export interface Validator {
- address: string;
- proposer_priority: string;
- pub_key: {
- type: string;
- value: string;
- };
-}
-export interface ValidatorsResponse {
- block_height: number;
- count: string;
- total: string;
- validators: Validator[];
-}
-
-export type CountryData = {
- ISO3: string;
- nodes: number;
-};
-
-export type Delegation = {
- owner: string;
- amount: Amount;
- block_height: number;
-};
-
-export type DelegationUniq = {
- owner: string;
- amount: Amount;
-};
-
-export type DelegationsResponse = Delegation[];
-
-export type UniqDelegationsResponse = DelegationUniq[];
-
-export interface CountryDataResponse {
- [threeLetterCountryCode: string]: CountryData;
-}
-
-export type BlockType = number;
-export type BlockResponse = BlockType;
-
-export interface ApiState {
- isLoading: boolean;
- data?: RESPONSE;
- error?: Error;
-}
-
-export type StatusResponse = {
- pending: boolean;
- ports: {
- 1789: boolean;
- 1790: boolean;
- 8000: boolean;
- };
-};
-
-export type UptimeTime = {
- date: string;
- uptime: number;
-};
-
-export type UptimeStoryResponse = {
- history: UptimeTime[];
- identity: string;
- owner: string;
-};
-
-export type MixNodeEconomicDynamicsStatsResponse = {
- stake_saturation: number;
- uncapped_saturation: number;
- // TODO: when v2 will be deployed, remove cases: VeryHigh, Moderate and VeryLow
- active_set_inclusion_probability: 'High' | 'Good' | 'Low';
- reserve_set_inclusion_probability: 'High' | 'Good' | 'Low';
- estimated_total_node_reward: number;
- estimated_operator_reward: number;
- estimated_delegators_reward: number;
- current_interval_uptime: number;
-};
-
-export type Environment = 'mainnet' | 'sandbox' | 'qa';
-
-export type ServiceProviderType = 'Network Requester';
-
-export type DirectoryServiceProvider = {
- id: string;
- description: string;
- address: string;
- gateway: string;
- routing_score: string | null;
- service_type: ServiceProviderType;
-};
-
-export type DirectoryService = {
- id: string;
- description: string;
- items: DirectoryServiceProvider[];
-};
diff --git a/explorer-nextjs/app/typeDefs/filters.ts b/explorer-nextjs/app/typeDefs/filters.ts
deleted file mode 100644
index 53de60cb87..0000000000
--- a/explorer-nextjs/app/typeDefs/filters.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { Mark } from '@mui/base';
-
-export enum EnumFilterKey {
- profitMargin = 'profitMargin',
- stakeSaturation = 'stakeSaturation',
- routingScore = 'routingScore',
-}
-
-export type TFilterItem = {
- label: string;
- id: EnumFilterKey;
- value: number[];
- isSmooth?: boolean;
- marks: Mark[];
- min?: number;
- max?: number;
- scale?: (value: number) => number;
- tooltipInfo?: string;
-};
-
-export type TFilters = { [key in EnumFilterKey]: TFilterItem };
diff --git a/explorer-nextjs/app/typeDefs/network.ts b/explorer-nextjs/app/typeDefs/network.ts
deleted file mode 100644
index f8615cd992..0000000000
--- a/explorer-nextjs/app/typeDefs/network.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type Network = 'QA' | 'SANDBOX' | 'MAINNET';
diff --git a/explorer-nextjs/app/typeDefs/tables.ts b/explorer-nextjs/app/typeDefs/tables.ts
deleted file mode 100644
index 1ab2ffead4..0000000000
--- a/explorer-nextjs/app/typeDefs/tables.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export type TableHeading = {
- id: string;
- numeric: boolean;
- disablePadding: boolean;
- label: string;
-};
-
-export type TableHeadingsType = TableHeading[];
diff --git a/explorer-nextjs/app/typings/FC.d.ts b/explorer-nextjs/app/typings/FC.d.ts
deleted file mode 100644
index 08ebdfa298..0000000000
--- a/explorer-nextjs/app/typings/FC.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare type FCWithChildren = React.FC>;
diff --git a/explorer-nextjs/app/typings/jpeg.d.ts b/explorer-nextjs/app/typings/jpeg.d.ts
deleted file mode 100644
index af2ed72913..0000000000
--- a/explorer-nextjs/app/typings/jpeg.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-declare module '*.jpeg' {
- const value: any;
- export default value;
-}
-
-declare module '*.jpg' {
- const value: any;
- export default value;
-}
diff --git a/explorer-nextjs/app/typings/json.d.ts b/explorer-nextjs/app/typings/json.d.ts
deleted file mode 100644
index b72dd46ee5..0000000000
--- a/explorer-nextjs/app/typings/json.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '*.json' {
- const content: any;
- export default content;
-}
diff --git a/explorer-nextjs/app/typings/png.d.ts b/explorer-nextjs/app/typings/png.d.ts
deleted file mode 100644
index dd84df40a4..0000000000
--- a/explorer-nextjs/app/typings/png.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '*.png' {
- const content: any;
- export default content;
-}
diff --git a/explorer-nextjs/app/typings/react-identicons.d.ts b/explorer-nextjs/app/typings/react-identicons.d.ts
deleted file mode 100644
index 6c460eff99..0000000000
--- a/explorer-nextjs/app/typings/react-identicons.d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-declare module 'react-identicons' {
- import * as React from 'react';
-
- interface IdenticonProps {
- string: string;
- size?: number;
- padding?: number;
- bg?: string;
- fg?: string;
- palette?: string[];
- count?: number;
- // getColor: Function;
- }
-
- declare function Identicon(props: IdenticonProps): React.ReactElement;
-
- export default Identicon;
-}
diff --git a/explorer-nextjs/app/typings/react-tooltip.d.ts b/explorer-nextjs/app/typings/react-tooltip.d.ts
deleted file mode 100644
index 98cb6d592d..0000000000
--- a/explorer-nextjs/app/typings/react-tooltip.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module 'react-tooltip';
diff --git a/explorer-nextjs/app/typings/svg.d.ts b/explorer-nextjs/app/typings/svg.d.ts
deleted file mode 100644
index 091d25e210..0000000000
--- a/explorer-nextjs/app/typings/svg.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '*.svg' {
- const content: any;
- export default content;
-}
diff --git a/explorer-nextjs/app/utils/currency.ts b/explorer-nextjs/app/utils/currency.ts
deleted file mode 100644
index 07bdc890de..0000000000
--- a/explorer-nextjs/app/utils/currency.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import { printableCoin } from '@nymproject/nym-validator-client';
-import Big from 'big.js';
-import { DecCoin, isValidRawCoin } from '@nymproject/types';
-
-const DENOM = process.env.CURRENCY_DENOM || 'unym';
-const DENOM_STAKING = process.env.CURRENCY_STAKING_DENOM || 'unyx';
-
-export const toDisplay = (val: string | number | Big, dp = 4) => {
- let displayValue;
- try {
- displayValue = Big(val).toFixed(dp);
- } catch (e: any) {
- console.warn(`${displayValue} not a valid decimal number: ${e}`);
- }
- return displayValue;
-};
-
-export const currencyToString = ({ amount, dp, denom = DENOM }: { amount: string; dp?: number; denom?: string }) => {
- if (!dp) {
- printableCoin({
- amount,
- denom,
- });
- }
-
- const [printableAmount, printableDenom] = printableCoin({
- amount,
- denom,
- }).split(/\s+/);
-
- return `${toDisplay(printableAmount, dp)} ${printableDenom}`;
-};
-
-function addThousandsSeparator(value: string) {
- return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
-}
-
-export const humanReadableCurrencyToString = ({ amount, denom }: { amount: string, denom: string }) => {
- const str = currencyToString({ amount, denom, dp: 2 });
- const parts = str.split('.');
- return [addThousandsSeparator(parts[0]), parts[1]].join('.');
-}
-
-export const stakingCurrencyToString = (amount: string, denom: string = DENOM_STAKING) =>
- printableCoin({
- amount,
- denom,
- });
-
-/**
- * Converts a decimal number to a pretty representation
- * with fixed decimal places.
- *
- * @param val - a decimal number of string form
- * @param dp - number of decimal places (4 by default ie. 0.0000)
- * @returns A prettyfied decimal number
- */
-
-/**
- * Converts a decimal number of μNYM (micro NYM) to NYM.
- *
- * @param unym - a decimal number of μNYM
- * @param dp - number of decimal places (4 by default ie. 0.0000)
- * @returns The corresponding decimal number in NYM
- */
-export const unymToNym = (unym: string | number | Big, dp = 4) => {
- let nym;
- try {
- nym = Big(unym).div(1_000_000).toFixed(dp);
- } catch (e: any) {
- console.warn(`${unym} not a valid decimal number: ${e}`);
- }
- return nym;
-};
-
-export const validateAmount = async (
- majorAmountAsString: DecCoin['amount'],
- minimumAmountAsString: DecCoin['amount'],
-): Promise => {
- // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc
- if (!Number(majorAmountAsString)) {
- return false;
- }
-
- if (!isValidRawCoin(majorAmountAsString)) {
- return false;
- }
-
- const majorValueFloat = parseInt(majorAmountAsString, Number(10));
-
- return majorValueFloat >= parseInt(minimumAmountAsString, Number(10));
-};
-
-/**
- * Takes a DecCoin and prettify its amount to a representation
- * with fixed decimal places.
- *
- * @param coin - a DecCoin
- * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000)
- * @returns A DecCoin with prettified amount
- */
-export const decCoinToDisplay = (coin: DecCoin, dp = 4) => {
- const displayCoin = { ...coin };
- try {
- displayCoin.amount = Big(coin.amount).toFixed(dp);
- } catch (e: any) {
- console.warn(`${coin.amount} not a valid decimal number: ${e}`);
- }
- return displayCoin;
-};
diff --git a/explorer-nextjs/app/utils/index.ts b/explorer-nextjs/app/utils/index.ts
deleted file mode 100644
index e3c3e4ae19..0000000000
--- a/explorer-nextjs/app/utils/index.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/* eslint-disable camelcase */
-import { MutableRefObject } from 'react';
-import { Theme } from '@mui/material/styles';
-import { registerLocale, getName } from 'i18n-iso-countries';
-import Big from 'big.js';
-import { CountryData } from '@/app/typeDefs/explorer-api';
-import { EconomicsRowsType } from '@/app/components/MixNodes/Economics/types';
-import { Network } from '../typeDefs/network';
-
-registerLocale(require('i18n-iso-countries/langs/en.json'));
-
-export function formatNumber(num: number): string {
- return new Intl.NumberFormat().format(num);
-}
-
-export function scrollToRef(ref: MutableRefObject): void {
- if (ref?.current) ref.current.scrollIntoView();
-}
-
-export type CountryDataRowType = {
- id: number;
- ISO3: string;
- nodes: number;
- countryName: string;
- percentage: string;
-};
-
-export function countryDataToGridRow(countriesData: CountryData[]): CountryDataRowType[] {
- const totalNodes = countriesData.reduce((acc, obj) => acc + obj.nodes, 0);
- const formatted = countriesData.map((each: CountryData, index: number) => {
- const updatedCountryRecord: CountryDataRowType = {
- ...each,
- id: index,
- countryName: getName(each.ISO3, 'en', { select: 'alias' }),
- percentage: ((each.nodes * 100) / totalNodes).toFixed(1),
- };
- return updatedCountryRecord;
- });
-
- const sorted = formatted.sort((a, b) => (a.nodes < b.nodes ? 1 : -1));
- return sorted;
-}
-
-export const splice = (start: number, deleteCount: number, address?: string): string => {
- if (address) {
- const array = address.split('');
- array.splice(start, deleteCount, '...');
- return array.join('');
- }
- return '';
-};
-
-export const trimAddress = (address = '', trimBy = 6) => `${address.slice(0, trimBy)}...${address.slice(-trimBy)}`;
-
-/**
- * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100).
- *
- * @param value - the percentage to convert
- * @returns A stringified integer
- */
-export const toPercentIntegerString = (value: string) => Math.round(Number(value) * 100).toString();
-export const toPercentInteger = (value: string) => Math.round(Number(value) * 100);
-
-export const textColour = (value: EconomicsRowsType, field: string, theme: Theme) => {
- const progressBarValue = value?.progressBarValue || 0;
- const fieldValue = value.value;
-
- if (progressBarValue > 100) {
- return theme.palette.warning.main;
- }
- if (field === 'selectionChance') {
- // TODO: when v2 will be deployed, remove cases: VeryHigh, Moderate and VeryLow
- switch (fieldValue) {
- case 'High':
- case 'VeryHigh':
- return theme.palette.nym.networkExplorer.selectionChance.overModerate;
- case 'Good':
- case 'Moderate':
- return theme.palette.nym.networkExplorer.selectionChance.moderate;
- case 'Low':
- case 'VeryLow':
- return theme.palette.nym.networkExplorer.selectionChance.underModerate;
- default:
- return theme.palette.nym.wallet.fee;
- }
- }
- return theme.palette.nym.wallet.fee;
-};
-
-export const isGreaterThan = (a: number, b: number) => a > b;
-
-export const isLessThan = (a: number, b: number) => a < b;
-
-/**
- *
- * Checks if the user's balance is enough to pay the fee
- * @param balance - The user's current balance
- * @param fee - The fee for the tx
- * @param tx - The amount of the tx
- * @returns boolean
- *
- */
-
-export const isBalanceEnough = (fee: string, tx: string = '0', balance: string = '0') => {
- console.log('balance', balance, fee, tx);
- try {
- return Big(balance).gte(Big(fee).plus(Big(tx)));
- } catch (e) {
- console.log(e);
- return false;
- }
-};
-
-export const urls = (networkName?: Network) =>
- networkName === 'MAINNET'
- ? {
- mixnetExplorer: 'https://mixnet.explorers.guru/',
- blockExplorer: 'https://blocks.nymtech.net',
- networkExplorer: 'https://explorer.nymtech.net',
- }
- : {
- blockExplorer: `https://${networkName}-blocks.nymtech.net`,
- networkExplorer: `https://${networkName}-explorer.nymtech.net`,
- };
diff --git a/explorer-nextjs/next.config.mjs b/explorer-nextjs/next.config.mjs
deleted file mode 100644
index d642290145..0000000000
--- a/explorer-nextjs/next.config.mjs
+++ /dev/null
@@ -1,14 +0,0 @@
-/** @type {import('next').NextConfig} */
-const nextConfig = {
- async redirects() {
- return [
- {
- source: '/network-components/mixnode/:id', // Match the old URL
- destination: '/network-components/nodes/:id', // Redirect to the new URL
- permanent: true,
- },
- ];
- },
-};
-
-export default nextConfig;
diff --git a/explorer-nextjs/package.json b/explorer-nextjs/package.json
deleted file mode 100644
index 555749547b..0000000000
--- a/explorer-nextjs/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "@nymproject/network-explorer",
- "version": "1.0.0",
- "scripts": {
- "dev": "next dev",
- "build": "next build",
- "build:prod": "yarn --cwd .. build && next build",
- "start": "next start",
- "lint": "next lint"
- },
- "dependencies": {
- "@nymproject/react": "^1.0.0",
- "@nymproject/nym-validator-client": "0.18.0",
- "next": "14.2.26",
- "react": "^18",
- "react-dom": "^18",
- "react-error-boundary": "^4.0.13",
- "material-react-table": "^2.12.1",
- "@mui/x-date-pickers": "7.1.1",
- "@mui/x-data-grid": "7.1.1",
- "@mui/x-charts": "^7.22.3"
- },
- "devDependencies": {
- "@types/node": "^20",
- "@types/react": "^18",
- "@types/react-dom": "^18",
- "eslint": "^8",
- "eslint-config-next": "14.1.4",
- "typescript": "^5"
- }
-}
diff --git a/explorer-nextjs/public/favicon.ico b/explorer-nextjs/public/favicon.ico
deleted file mode 100644
index bc951a1c6f2c406072df036cea6e73163f6a687e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 5430
zcmc&%drVtp6tBjAwtraU57|Idos~Ef+d5%b>g&1$p%NeV5&G3m5tT=9hdq_kQ=B
z^E=Xx-n)
zt#yjjH3Lnu{O{}%;^v}6adT0w`qr*D_ca-f4$)@vo5?uW^6<56{qN!y1~PI3zTLhSUpCWL!`J&HO0On^xEC|`)_dLgKOS*tgq5y0@uh0
z;BSon*P>z|U)tMr;?xgzW(`wEUmrAoa>L74Ra^)Q3kz_+=Pvz?&8tfN#-3i>y2xH*
z%bzYQhJTT4U3C?F{Nc3?^0K6+#m(f;RFu-PZ&y{)wrnQPWq+@&hnB6aEcfn%OCHAC7^bOZ*PQf7!rS;)nRo!4?-g)PewDc!POtFA4GSVmZnHXSG
z;ekjcH+#8G$ME!7d?mJE!QPT}aQwl*45$+e4ZNutwI3yn`
z0IjMMj9Q1yq@|(*v4ObYjL*I3bY+)zKrCMn0`9u|rwa?yAT^Yc(|F?d{Ai|c
zO~d%f-~My6(qLkIjK-RGyP-s{q4yC8zBslB
zd36MWpA@6U_{*W-Yffgt)Z`?MJva9l3e-w3HuhPN_(Az!C(VZGsVN%!@$4*^@)SPU
zf#S3LA8`Ctn2j(qGfiX9&dh+3kZ!;Z6yF;A#`Yxl2((_XGUgu2Fc|I$97>yN+wm-++a?{@tqL^a@6^%w1fU8+AZwk%`o
z`V-^h;ZuL_KrI*-ME$*L0kVPJe~6!M|H0Vc+kgFx`mdrO`Y+42`Y*-?OmY9IJ~z~c
z`%jfm|5@^+|J1JbpJ~4Rr#|1&ww?ZyZ3BMB{kNu?GHI#@Tb}gaW2paLM*a7)u554&
W_upg@)k0b*(@yr^>+RU-_x}JZi=y2C
diff --git a/explorer-nextjs/public/next.svg b/explorer-nextjs/public/next.svg
deleted file mode 100644
index 5174b28c56..0000000000
--- a/explorer-nextjs/public/next.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/explorer-nextjs/public/vercel.svg b/explorer-nextjs/public/vercel.svg
deleted file mode 100644
index d2f8422273..0000000000
--- a/explorer-nextjs/public/vercel.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/explorer-nextjs/tsconfig.json b/explorer-nextjs/tsconfig.json
deleted file mode 100644
index 701d0e6984..0000000000
--- a/explorer-nextjs/tsconfig.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "compilerOptions": {
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "CommonJS",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "incremental": true,
- "plugins": [
- {
- "name": "next"
- }
- ],
- "paths": {
- "@/*": [
- "./*"
- ],
- "@assets/*": [
- "../assets/*"
- ]
- },
- "moduleResolution": "node",
- "target": "ES2017"
- },
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- ".next/types/**/*.ts"
- ],
- "exclude": [
- "node_modules"
- ]
-}
diff --git a/explorer/.babelrc b/explorer/.babelrc
deleted file mode 100644
index 85e1f1ba26..0000000000
--- a/explorer/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@babel/env", "@babel/react"]
-}
\ No newline at end of file
diff --git a/explorer/.editorconfig b/explorer/.editorconfig
deleted file mode 100644
index c35daeee9b..0000000000
--- a/explorer/.editorconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://editorconfig.org/
-# EditorConfig helps developers define and maintain consistent coding styles
-# between different editors and IDEs. The EditorConfig project consists of a
-# file format for defining coding styles and a collection of text editor plugins
-# that enable editors to read the file format and adhere to defined styles.
-# EditorConfig files are easily readable and they work nicely with version
-# control systems.
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-trim_trailing_whitespace = false
diff --git a/explorer/.env.dev b/explorer/.env.dev
deleted file mode 100644
index 3cc86ae00c..0000000000
--- a/explorer/.env.dev
+++ /dev/null
@@ -1,9 +0,0 @@
-# When running the explorer API locally
-#EXPLORER_API_URL=http://localhost:8000/v1
-
-EXPLORER_API_URL=https://sandbox-explorer.nymtech.net/api/v1
-NYM_API_URL=https://sandbox-nym-api1.nymtech.net
-VALIDATOR_URL=https://rpc.sandbox.nymtech.net
-BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net
-CURRENCY_DENOM=unym
-CURRENCY_STAKING_DENOM=unyx
diff --git a/explorer/.env.prod b/explorer/.env.prod
deleted file mode 100644
index 2e927b2947..0000000000
--- a/explorer/.env.prod
+++ /dev/null
@@ -1,6 +0,0 @@
-EXPLORER_API_URL=https://explorer.nymtech.net/api/v1
-NYM_API_URL=https://validator.nymtech.net
-VALIDATOR_URL=https://rpc.nymtech.net
-BIG_DIPPER_URL=https://blocks.nymtech.net
-CURRENCY_DENOM=unym
-CURRENCY_STAKING_DENOM=unyx
\ No newline at end of file
diff --git a/explorer/.env.qa b/explorer/.env.qa
deleted file mode 100644
index dd7052ce4d..0000000000
--- a/explorer/.env.qa
+++ /dev/null
@@ -1,6 +0,0 @@
-EXPLORER_API_URL=https://qa-explorer.nymtech.net/api/v1
-NYM_API_URL=https://qa-validator-api.nymtech.net
-VALIDATOR_URL=https://qa-validator.nymtech.net
-BIG_DIPPER_URL=https://qa-blocks.nymtech.net
-CURRENCY_DENOM=unym
-CURRENCY_STAKING_DENOM=unyx
diff --git a/explorer/.eslintrc.js b/explorer/.eslintrc.js
deleted file mode 100644
index 5feba99084..0000000000
--- a/explorer/.eslintrc.js
+++ /dev/null
@@ -1,14 +0,0 @@
-module.exports = {
- extends: [
- '@nymproject/eslint-config-react-typescript'
- ],
- overrides: [
- {
- files: ['*.ts'],
- parserOptions: {
- project: 'tsconfig.json',
- tsconfigRootDir: __dirname,
- }
- }
- ]
-}
diff --git a/explorer/.gitignore b/explorer/.gitignore
deleted file mode 100644
index b8b1827577..0000000000
--- a/explorer/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-dist
-.DS_Store
-detailAPI.md
-!.env.dev
diff --git a/explorer/.nvmrc b/explorer/.nvmrc
deleted file mode 100644
index 3c032078a4..0000000000
--- a/explorer/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-18
diff --git a/explorer/.prettierrc b/explorer/.prettierrc
deleted file mode 100644
index ccf75b89de..0000000000
--- a/explorer/.prettierrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "trailingComma": "all",
- "singleQuote": true,
- "printWidth": 120,
- "tabWidth": 2
-}
diff --git a/explorer/.storybook/main.js b/explorer/.storybook/main.js
deleted file mode 100644
index 1c2a975321..0000000000
--- a/explorer/.storybook/main.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* eslint-disable no-param-reassign */
-const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
-const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
-
-module.exports = {
- stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
- addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'],
- framework: '@storybook/react',
- core: {
- builder: 'webpack5',
- },
- // webpackFinal: async (config, { configType }) => {
- // // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
- // // You can change the configuration based on that.
- // // 'PRODUCTION' is used when building the static version of storybook.
- webpackFinal: async (config) => {
- config.module.rules.forEach((rule) => {
- // look for SVG import rule and replace
- // NOTE: the rule before modification is /\.(svg|ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/
- if (rule.test?.toString().includes('svg')) {
- rule.test = /\.(ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/;
- }
- });
-
- // handle asset loading with this
- config.module.rules.unshift({
- test: /\.svg(\?.*)?$/i,
- issuer: /\.[jt]sx?$/,
- use: ['@svgr/webpack'],
- });
-
- config.resolve.extensions = ['.tsx', '.ts', '.js'];
- config.resolve.plugins = [new TsconfigPathsPlugin()];
-
- config.resolve.fallback = {
- fs: false,
- tls: false,
- path: false,
- http: false,
- https: false,
- stream: false,
- crypto: false,
- net: false,
- zlib: false,
- };
-
- config.plugins.push(new ForkTsCheckerWebpackPlugin({
- typescript: {
- mode: 'write-references',
- diagnosticOptions: {
- semantic: true,
- syntactic: true,
- },
- },
- }));
-
- // Return the altered config
- return config;
- },
- features: {
- emotionAlias: false,
- },
-};
diff --git a/explorer/.storybook/preview.js b/explorer/.storybook/preview.js
deleted file mode 100644
index 5d97f3b5ab..0000000000
--- a/explorer/.storybook/preview.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* eslint-disable react/react-in-jsx-scope */
-import { NymNetworkExplorerThemeProvider } from '@nymproject/mui-theme';
-import { Box } from '@mui/material';
-
-export const parameters = {
- actions: { argTypesRegex: "^on[A-Z].*" },
- controls: {
- matchers: {
- color: /(background|color)$/i,
- date: /Date$/,
- },
- },
-}
-
-const withThemeProvider = (Story, context) => (
-
-
-
- theme.palette.background.default,
- color: (theme) => theme.palette.text.primary,
- }}
- >
-
-
-
- Light mode
-
-
-
-
-
- theme.palette.background.default,
- color: (theme) => theme.palette.text.primary,
- }}
- >
-
-
-
- Dark mode
-
-
-
-
-);
-
-export const decorators = [withThemeProvider];
diff --git a/explorer/.vscode/settings.json b/explorer/.vscode/settings.json
deleted file mode 100644
index 246e9c6e89..0000000000
--- a/explorer/.vscode/settings.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": true
- }
-}
diff --git a/explorer/CHANGELOG.md b/explorer/CHANGELOG.md
deleted file mode 100644
index 8446a3c5b2..0000000000
--- a/explorer/CHANGELOG.md
+++ /dev/null
@@ -1,47 +0,0 @@
-## UNRELEASED
-
-- nothing yet
-
-## [nym-explorer-v1.0.6](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.6) (2023-02-21)
-
-- Allow user to filter gateways but current and old versions
-- Add copy buttons to gateway identity keys
-
-## [nym-explorer-v1.0.5](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.5) (2023-02-14)
-
-- NE - link `Owner` field on the node detail page to the account details on NG explorer ([#2923])
-- NE - Upgrade Sandbox and make below changes: ([#2332])
-
-[#2923]: https://github.com/nymtech/nym/issues/2923
-[#2332]: https://github.com/nymtech/nym/issues/2332
-
-## [nym-explorer-v1.0.4](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.4) (2023-01-31)
-
-- Add routing score on gateway list ([#2913])
-- Add gateway's last Routing Score to the gateways list page ([#2186])
-- Upgrade Sandbox and make below changes: ([#2332])
-
-[#2913]: https://github.com/nymtech/nym/pull/2913
-[#2186]: https://github.com/nymtech/nym/issues/2186
-[#2332]: https://github.com/nymtech/nym/issues/2332
-
-## [nym-explorer-v1.0.3](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.3) (2023-01-24)
-
-- Stake Saturation tooltip on node list and node pages updated ([#2877])
-- Sandbox Upgrade : Name change from "Network Explorer" to "Sandbox Explorer", button to mainnet explorer and link to faucet ([#2332)])
-
-[#2877]: https://github.com/nymtech/nym/issues/2877
-[#2332]: https://github.com/nymtech/nym/issues/2332
-
-## [nym-explorer-v1.0.2](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.2) (2023-01-17)
-
-- changing the explorers guru link ([#2820])
-
-[#2820]: https://github.com/nymtech/nym/pull/2820
-
-## [nym-explorer-v1.0.1](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.1) (2023-01-10)
-
-- Feat/2161 ne gate version by @gala1234 in https://github.com/nymtech/nym/pull/2743
-- fix(explorer): set gateway bond 6 decimals by @doums in https://github.com/nymtech/nym/pull/2741
-- Feat/2130 tables update rebase by @gala1234 in https://github.com/nymtech/nym/pull/2742
-- fix(explorer,explorer-api): mixnode location by @doums in https://github.com/nymtech/nym-api
diff --git a/explorer/README.md b/explorer/README.md
deleted file mode 100644
index a7bbc2346a..0000000000
--- a/explorer/README.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Nym Network Explorer
-
-The network explorer lets you explore the Nym network.
-
-## Getting started
-
-You will need:
-
-- NodeJS (use `nvm install` to automatically install the correct version)
-- `npm`
-- `yarn`
-
-> **Note**: This project ipart of a mono repo, so you will need to build the shared packages before starting. And any time they change, you'll need to rebuild them.
-
-From the [root of the repository](../README.md) run the following to build shared packages:
-
-```
-yarn
-yarn build
-```
-
-From the `explorer` directory of the `nym` monorepo, run:
-
-```
-cd explorer
-yarn start
-```
-
-You can then open a browser to http://localhost:3000 and start development.
-
-## Development
-
-Documentation for developers [can be found here](./docs).
-
-Several environment variables are required. They can be
-provisioned via a `.env` file. For convenience a `.env.dev` is
-provided, just copy its content into `.env`.
-
-#### Required env vars
-
-```
-EXPLORER_API_URL
-NYM_API_URL
-VALIDATOR_URL
-BIG_DIPPER_URL
-CURRENCY_DENOM
-CURRENCY_STAKING_DENOM
-```
-
-## Deployment
-
-Build the UI with (starting in the repository root):
-
-```
-yarn
-yarn build
-cd explorer
-yarn build
-```
-
-The output will be in the `dist` directory. Serve this with `nginx` or `httpd`.
-
-Make sure you have built the [explorer-api](./explorer-api) and are running it as a service proxied through
-`nginx` or `httpd` so that both the UI and API are running on the same host.
-
-## License
-
-Please see the [project README](./README.md) and the [LICENSES directory](../LICENSES) for license details for all Nym software.
-
-## Contributing
-
-If you would like to contribute to the Network Explorer send us a PR or
-[raise an issue on GitHub](https://github.com/nymtech/nym/issues) and tag them with `network-explorer`.
-
-## Development
-
-Please see [development docs](./docs) here for more information on the structure and design of this app.
diff --git a/explorer/docs/README.md b/explorer/docs/README.md
deleted file mode 100644
index bb0d0be99a..0000000000
--- a/explorer/docs/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Nym Network Explorer - Development Docs
-
-## Getting started
-
-You will need:
-
-- NodeJS
-- `nvm`
-
-We use the following:
-
-- Typescript
-- `eslint`
-- `webpack`
-- `jest`
-- `react-material-ui`
-- `react` 17
-
-## Development mode
-
-Copy the `.env.prod` file to `.env` to configure your environment. Using the live sandbox Explorer API is the best way to do development, so the prod settings are good.
-
-Run the following:
-
-```
-npm install
-npm run start
-```
-
-A development server with hot reloading will be running on http://localhost:3000.
-
-## Linting
-
-`eslint` and `prettier` are configured.
-
-You can lint the code by running:
-
-```
-npm run lint
-```
-
-> **Note:** this will only show linting errors and will not fix them
-
-To fix all linting errors automatically run:
-
-```
-npm run lint:fix
-```
diff --git a/explorer/jest.config.js b/explorer/jest.config.js
deleted file mode 100644
index e86e13bab9..0000000000
--- a/explorer/jest.config.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
-module.exports = {
- preset: 'ts-jest',
- testEnvironment: 'node',
-};
diff --git a/explorer/package.json b/explorer/package.json
deleted file mode 100644
index d2426f6122..0000000000
--- a/explorer/package.json
+++ /dev/null
@@ -1,146 +0,0 @@
-{
- "name": "@nym/network-explorer",
- "version": "1.0.7",
- "private": true,
- "license": "Apache-2.0",
- "scripts": {
- "start": "webpack serve --progress --port 3000",
- "build": "webpack build --progress --config webpack.prod.js",
- "ci:dev": "echo 'Building CI for branch preview...' && yarn --cwd .. build && cp .env.dev .env && yarn build",
- "ci:prod": "echo 'Building CI for prod preview...' && yarn --cwd .. build && cp .env.prod .env && yarn build",
- "ci": "[ \"$CI_PROD\" = true ] && yarn ci:prod || yarn ci:dev",
- "build:serve": "npx serve dist",
- "test": "jest",
- "test:watch": "jest --watch",
- "tsc": "tsc --noEmit true",
- "tsc:watch": "tsc --watch --noEmit true",
- "lint": "eslint src",
- "lint:fix": "eslint src --fix",
- "prestorybook": "yarn --cwd .. build",
- "storybook": "start-storybook -p 6006",
- "storybook:build": "build-storybook"
- },
- "dependencies": {
- "@chain-registry/types": "^0.18.0",
- "@cosmjs/cosmwasm-stargate": "^0.32.0",
- "@cosmjs/crypto": "^0.32.0",
- "@cosmjs/encoding": "^0.32.0",
- "@cosmjs/math": "^0.26.2",
- "@cosmjs/stargate": "^0.32.0",
- "@cosmjs/tendermint-rpc": "^0.32.0",
- "@cosmos-kit/core": "^2.8.9",
- "@cosmos-kit/keplr-extension": "^2.7.9",
- "@cosmos-kit/react": "^2.10.11",
- "@emotion/react": "^11.4.1",
- "@emotion/styled": "^11.3.0",
- "@interchain-ui/react": "^1.14.2",
- "@mui/icons-material": "^5.0.0",
- "@mui/material": "^5.0.1",
- "@mui/styles": "^5.0.1",
- "@mui/system": "^5.0.1",
- "@mui/x-data-grid": "^5.0.0-beta.5",
- "@nymproject/contract-clients": "1.2.4-rc.1",
- "@nymproject/mui-theme": "^1.0.0",
- "@nymproject/node-tester": "^1.0.0",
- "@nymproject/nym-validator-client": "^0.18.0",
- "@nymproject/react": "^1.0.0",
- "@nymproject/types": "^1.0.0",
- "@tauri-apps/api": "^1.5.1",
- "big.js": "^6.2.1",
- "bs58": "^5.0.0",
- "buffer": "^6.0.3",
- "chain-registry": "^1.29.1",
- "cosmjs-types": "^0.9.0",
- "d3-scale": "^4.0.0",
- "date-fns": "^2.24.0",
- "i18n-iso-countries": "^6.8.0",
- "lodash": "^4.17.21",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-error-boundary": "^3.1.4",
- "react-google-charts": "^3.0.15",
- "react-identicons": "^1.2.5",
- "react-router-dom": "6",
- "react-simple-maps": "^2.3.0",
- "react-tooltip": "^4.2.21",
- "semver": "^7.3.8",
- "use-clipboard-copy": "^0.2.0"
- },
- "devDependencies": {
- "@babel/core": "^7.15.0",
- "@nymproject/eslint-config-react-typescript": "^1.0.0",
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
- "@storybook/addon-actions": "^6.5.8",
- "@storybook/addon-essentials": "^6.5.8",
- "@storybook/addon-interactions": "^6.5.8",
- "@storybook/addon-links": "^6.5.8",
- "@storybook/react": "^6.5.15",
- "@storybook/testing-library": "^0.0.9",
- "@svgr/webpack": "^6.1.1",
- "@testing-library/jest-dom": "^5.14.1",
- "@testing-library/react": "^12.0.0",
- "@types/d3-fetch": "^3.0.1",
- "@types/d3-geo": "^3.0.2",
- "@types/d3-scale": "^4.0.1",
- "@types/geojson": "^7946.0.8",
- "@types/jest": "^27.0.1",
- "@types/node": "^16.7.13",
- "@types/react": "^18.0.26",
- "@types/react-dom": "^18.0.10",
- "@types/react-simple-maps": "^1.0.6",
- "@types/react-tooltip": "^4.2.4",
- "@types/topojson-client": "^3.1.0",
- "@typescript-eslint/eslint-plugin": "^5.13.0",
- "@typescript-eslint/parser": "^5.13.0",
- "babel-loader": "^8.3.0",
- "babel-plugin-root-import": "^6.6.0",
- "clean-webpack-plugin": "^4.0.0",
- "css-loader": "^6.7.3",
- "css-minimizer-webpack-plugin": "^3.0.2",
- "dotenv-webpack": "^7.0.3",
- "eslint": "^8.10.0",
- "eslint-config-airbnb": "^19.0.4",
- "eslint-config-airbnb-typescript": "^16.1.0",
- "eslint-config-prettier": "^8.5.0",
- "eslint-import-resolver-root-import": "^1.0.4",
- "eslint-plugin-import": "^2.25.4",
- "eslint-plugin-jest": "^26.1.1",
- "eslint-plugin-jsx-a11y": "^6.5.1",
- "eslint-plugin-prettier": "^4.0.0",
- "eslint-plugin-react": "^7.29.2",
- "eslint-plugin-react-hooks": "^4.3.0",
- "eslint-plugin-storybook": "^0.5.12",
- "favicons-webpack-plugin": "^5.0.2",
- "file-loader": "^6.2.0",
- "fork-ts-checker-webpack-plugin": "^7.2.1",
- "html-webpack-plugin": "^5.3.2",
- "jest": "^27.1.0",
- "mini-css-extract-plugin": "^2.2.2",
- "prettier": "^2.8.7",
- "react-refresh": "^0.10.0",
- "react-refresh-typescript": "^2.0.2",
- "style-loader": "^3.3.1",
- "ts-jest": "^27.0.5",
- "ts-loader": "^9.4.2",
- "tsconfig-paths-webpack-plugin": "^3.5.2",
- "typescript": "^4.6.2",
- "url-loader": "^4.1.1",
- "webpack": "^5.75.0",
- "webpack-cli": "^4.8.0",
- "webpack-dev-server": "^4.5.0",
- "webpack-favicons": "^1.3.8",
- "webpack-merge": "^5.8.0"
- },
- "browserslist": {
- "production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
- ],
- "development": [
- "last 1 chrome version",
- "last 1 firefox version",
- "last 1 safari version"
- ]
- }
-}
diff --git a/explorer/src/App.tsx b/explorer/src/App.tsx
deleted file mode 100644
index 4e6fcc41e8..0000000000
--- a/explorer/src/App.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import * as React from 'react';
-import { Nav } from './components/Nav';
-import { MobileNav } from './components/MobileNav';
-import { Routes } from './routes/index';
-import { useIsMobile } from './hooks/useIsMobile';
-
-export const App: FCWithChildren = () => {
- const isMobile = useIsMobile();
-
- if (isMobile) {
- return (
-
-
-
- );
- }
- return (
-
- );
-};
diff --git a/explorer/src/api/constants.ts b/explorer/src/api/constants.ts
deleted file mode 100644
index fbb8c18d6b..0000000000
--- a/explorer/src/api/constants.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-// master APIs
-export const API_BASE_URL = process.env.EXPLORER_API_URL;
-export const NYM_API_BASE_URL = process.env.NYM_API_URL;
-export const VALIDATOR_BASE_URL = process.env.VALIDATOR_URL || 'https://rpc.nymtech.net';
-export const BIG_DIPPER = process.env.BIG_DIPPER_URL;
-
-// specific API routes
-export const OVERVIEW_API = `${API_BASE_URL}/overview`;
-export const MIXNODE_PING = `${API_BASE_URL}/ping`;
-export const MIXNODES_API = `${API_BASE_URL}/mix-nodes`;
-export const MIXNODE_API = `${API_BASE_URL}/mix-node`;
-export const GATEWAYS_EXPLORER_API = `${API_BASE_URL}/gateways`;
-export const GATEWAYS_API = `${NYM_API_BASE_URL}/api/v1/status/gateways/detailed`;
-export const VALIDATORS_API = `${VALIDATOR_BASE_URL}/validators`;
-export const BLOCK_API = `${NYM_API_BASE_URL}/block`;
-export const COUNTRY_DATA_API = `${API_BASE_URL}/countries`;
-export const UPTIME_STORY_API = `${NYM_API_BASE_URL}/api/v1/status/mixnode`; // add ID then '/history' to this.
-export const UPTIME_STORY_API_GATEWAY = `${NYM_API_BASE_URL}/api/v1/status/gateway`; // add ID then '/history' or '/report' to this
-export const SERVICE_PROVIDERS = `${API_BASE_URL}/service-providers`;
-
-// errors
-export const MIXNODE_API_ERROR = "We're having trouble finding that record, please try again or Contact Us.";
-
-export const NYM_WEBSITE = 'https://nymtech.net';
-
-export const NYM_BIG_DIPPER = 'https://mixnet.explorers.guru';
-
-export const NYM_MIXNET_CONTRACT =
- process.env.NYM_MIXNET_CONTRACT || 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr';
-export const COSMOS_KIT_USE_CHAIN = process.env.COSMOS_KIT_USE_CHAIN || 'sandbox';
-export const WALLET_CONNECT_PROJECT_ID = process.env.WALLET_CONNECT_PROJECT_ID || '';
diff --git a/explorer/src/api/index.ts b/explorer/src/api/index.ts
deleted file mode 100644
index a2b134d4ae..0000000000
--- a/explorer/src/api/index.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-import keyBy from 'lodash/keyBy';
-import {
- API_BASE_URL,
- BLOCK_API,
- COUNTRY_DATA_API,
- GATEWAYS_API,
- UPTIME_STORY_API_GATEWAY,
- MIXNODE_API,
- MIXNODE_PING,
- MIXNODES_API,
- OVERVIEW_API,
- UPTIME_STORY_API,
- VALIDATORS_API,
- SERVICE_PROVIDERS,
- GATEWAYS_EXPLORER_API,
-} from './constants';
-
-import {
- CountryDataResponse,
- DelegationsResponse,
- UniqDelegationsResponse,
- GatewayReportResponse,
- UptimeStoryResponse,
- MixNodeDescriptionResponse,
- MixNodeResponse,
- MixNodeResponseItem,
- MixnodeStatus,
- MixNodeEconomicDynamicsStatsResponse,
- StatsResponse,
- StatusResponse,
- SummaryOverviewResponse,
- ValidatorsResponse,
- Environment,
- GatewayBondAnnotated,
- GatewayBond,
- DirectoryServiceProvider,
- LocatedGateway,
-} from '../typeDefs/explorer-api';
-
-function getFromCache(key: string) {
- const ts = Number(localStorage.getItem('ts'));
- const hasExpired = Date.now() - ts > 5000;
- const curr = localStorage.getItem(key);
- if (curr && !hasExpired) {
- return JSON.parse(curr);
- }
- return undefined;
-}
-
-function storeInCache(key: string, data: any) {
- localStorage.setItem(key, data);
- localStorage.setItem('ts', Date.now().toString());
-}
-
-export class Api {
- static fetchOverviewSummary = async (): Promise => {
- const cache = getFromCache('overview-summary');
- if (cache) {
- return cache;
- }
- const res = await fetch(`${OVERVIEW_API}/summary`);
- const json = await res.json();
- storeInCache('overview-summary', JSON.stringify(json));
- return json;
- };
-
- static fetchMixnodes = async (): Promise => {
- const cachedMixnodes = getFromCache('mixnodes');
- if (cachedMixnodes) {
- return cachedMixnodes;
- }
-
- const res = await fetch(MIXNODES_API);
- const json = await res.json();
- storeInCache('mixnodes', JSON.stringify(json));
- return json;
- };
-
- static fetchMixnodesActiveSetByStatus = async (status: MixnodeStatus): Promise => {
- const cachedMixnodes = getFromCache(`mixnodes-${status}`);
- if (cachedMixnodes) {
- return cachedMixnodes;
- }
- const res = await fetch(`${MIXNODES_API}/active-set/${status}`);
- const json = await res.json();
- storeInCache(`mixnodes-${status}`, JSON.stringify(json));
- return json;
- };
-
- static fetchMixnodeByID = async (id: string): Promise => {
- const response = await fetch(`${MIXNODE_API}/${id}`);
-
- // when the mixnode is not found, returned undefined
- if (response.status === 404) {
- return undefined;
- }
-
- return response.json();
- };
-
- static fetchGateways = async (): Promise => {
- const res = await fetch(GATEWAYS_API);
- const gatewaysAnnotated: GatewayBondAnnotated[] = await res.json();
- const res2 = await fetch(GATEWAYS_EXPLORER_API);
- const locatedGateways: LocatedGateway[] = await res2.json();
- const locatedGatewaysByOwner = keyBy(locatedGateways, 'owner');
- return gatewaysAnnotated.map(({ gateway_bond, node_performance }) => ({
- ...gateway_bond,
- node_performance,
- location: locatedGatewaysByOwner[gateway_bond.owner]?.location,
- }));
- };
-
- static fetchGatewayUptimeStoryById = async (id: string): Promise =>
- (await fetch(`${UPTIME_STORY_API_GATEWAY}/${id}/history`)).json();
-
- static fetchGatewayReportById = async (id: string): Promise =>
- (await fetch(`${UPTIME_STORY_API_GATEWAY}/${id}/report`)).json();
-
- static fetchValidators = async (): Promise => {
- const res = await fetch(VALIDATORS_API);
- const json = await res.json();
- return json.result;
- };
-
- static fetchBlock = async (): Promise => {
- const res = await fetch(BLOCK_API);
- const json = await res.json();
- const { height } = json.result.block.header;
- return height;
- };
-
- static fetchCountryData = async (): Promise => {
- const result: CountryDataResponse = {};
- const res = await fetch(COUNTRY_DATA_API);
- const json = await res.json();
- Object.keys(json).forEach((ISO3) => {
- result[ISO3] = { ISO3, nodes: json[ISO3] };
- });
- return result;
- };
-
- static fetchDelegationsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/delegations`)).json();
-
- static fetchUniqDelegationsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/delegations/summed`)).json();
-
- static fetchStatsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/stats`)).json();
-
- static fetchMixnodeDescriptionById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/description`)).json();
-
- static fetchMixnodeEconomicDynamicsStatsById = async (id: string): Promise =>
- (await fetch(`${MIXNODE_API}/${id}/economic-dynamics-stats`)).json();
-
- static fetchStatusById = async (id: string): Promise => (await fetch(`${MIXNODE_PING}/${id}`)).json();
-
- static fetchUptimeStoryById = async (id: string): Promise =>
- (await fetch(`${UPTIME_STORY_API}/${id}/history`)).json();
-
- static fetchServiceProviders = async (): Promise => {
- const res = await fetch(SERVICE_PROVIDERS);
- const json = await res.json();
- return json;
- };
-}
-
-export const getEnvironment = (): Environment => {
- const matchEnv = (env: Environment) => API_BASE_URL?.toLocaleLowerCase().includes(env) && env;
- return matchEnv('sandbox') || matchEnv('qa') || 'mainnet';
-};
diff --git a/explorer/src/assets/world-110m.json b/explorer/src/assets/world-110m.json
deleted file mode 100644
index 5c999c82ca..0000000000
--- a/explorer/src/assets/world-110m.json
+++ /dev/null
@@ -1,39718 +0,0 @@
-{
- "type": "Topology",
- "arcs": [
- [
- [
- 16814,
- 15074
- ],
- [
- 71,
- -45
- ],
- [
- 53,
- 16
- ],
- [
- 15,
- 54
- ],
- [
- 55,
- 18
- ],
- [
- 39,
- 37
- ],
- [
- 14,
- 95
- ],
- [
- 59,
- 24
- ],
- [
- 11,
- 42
- ],
- [
- 32,
- -32
- ],
- [
- 21,
- -3
- ]
- ],
- [
- [
- 17184,
- 15280
- ],
- [
- 39,
- -1
- ],
- [
- 53,
- -26
- ]
- ],
- [
- [
- 17276,
- 15253
- ],
- [
- 21,
- -14
- ],
- [
- 51,
- 38
- ],
- [
- 23,
- -23
- ],
- [
- 23,
- 55
- ],
- [
- 41,
- -2
- ],
- [
- 11,
- 17
- ],
- [
- 7,
- 49
- ],
- [
- 30,
- 41
- ],
- [
- 38,
- -27
- ],
- [
- -8,
- -37
- ],
- [
- 22,
- -5
- ],
- [
- -7,
- -101
- ],
- [
- 28,
- -39
- ],
- [
- 24,
- 25
- ],
- [
- 31,
- 12
- ],
- [
- 43,
- 53
- ],
- [
- 48,
- -8
- ],
- [
- 72,
- -1
- ]
- ],
- [
- [
- 17774,
- 15286
- ],
- [
- 13,
- -34
- ]
- ],
- [
- [
- 17787,
- 15252
- ],
- [
- -41,
- -13
- ],
- [
- -35,
- -23
- ],
- [
- -80,
- -14
- ],
- [
- -75,
- -25
- ],
- [
- -41,
- -52
- ],
- [
- 17,
- -51
- ],
- [
- 8,
- -60
- ],
- [
- -35,
- -50
- ],
- [
- 3,
- -46
- ],
- [
- -19,
- -43
- ],
- [
- -67,
- 4
- ],
- [
- 28,
- -80
- ],
- [
- -45,
- -30
- ],
- [
- -29,
- -73
- ],
- [
- 4,
- -72
- ],
- [
- -28,
- -33
- ],
- [
- -26,
- 11
- ],
- [
- -53,
- -16
- ],
- [
- -7,
- -33
- ],
- [
- -52,
- 0
- ],
- [
- -39,
- -68
- ],
- [
- -3,
- -102
- ],
- [
- -90,
- -50
- ],
- [
- -49,
- 10
- ],
- [
- -14,
- -26
- ],
- [
- -42,
- 15
- ],
- [
- -69,
- -17
- ],
- [
- -117,
- 61
- ]
- ],
- [
- [
- 16791,
- 14376
- ],
- [
- 63,
- 109
- ],
- [
- -6,
- 77
- ],
- [
- -52,
- 20
- ],
- [
- -6,
- 76
- ],
- [
- -23,
- 96
- ],
- [
- 30,
- 66
- ],
- [
- -30,
- 17
- ],
- [
- 19,
- 88
- ],
- [
- 28,
- 149
- ]
- ],
- [
- [
- 14166,
- 8695
- ],
- [
- -128,
- -49
- ],
- [
- -169,
- 17
- ],
- [
- -48,
- 58
- ],
- [
- -283,
- -6
- ],
- [
- -11,
- -8
- ],
- [
- -41,
- 54
- ],
- [
- -45,
- 4
- ],
- [
- -42,
- -21
- ],
- [
- -34,
- -22
- ]
- ],
- [
- [
- 13365,
- 8722
- ],
- [
- -6,
- 75
- ],
- [
- 10,
- 105
- ],
- [
- 24,
- 110
- ],
- [
- 3,
- 52
- ],
- [
- 23,
- 108
- ],
- [
- 16,
- 49
- ],
- [
- 41,
- 79
- ],
- [
- 22,
- 53
- ],
- [
- 7,
- 89
- ],
- [
- -3,
- 68
- ],
- [
- -21,
- 43
- ],
- [
- -19,
- 72
- ],
- [
- -17,
- 72
- ],
- [
- 4,
- 25
- ],
- [
- 21,
- 48
- ],
- [
- -21,
- 116
- ],
- [
- -14,
- 80
- ],
- [
- -35,
- 76
- ],
- [
- 6,
- 23
- ]
- ],
- [
- [
- 13406,
- 10065
- ],
- [
- 29,
- 16
- ],
- [
- 20,
- -2
- ],
- [
- 25,
- 15
- ],
- [
- 206,
- -2
- ],
- [
- 17,
- -89
- ],
- [
- 20,
- -72
- ],
- [
- 16,
- -39
- ],
- [
- 27,
- -63
- ],
- [
- 46,
- 10
- ],
- [
- 23,
- 17
- ],
- [
- 38,
- -17
- ],
- [
- 11,
- 30
- ],
- [
- 17,
- 70
- ],
- [
- 43,
- 4
- ],
- [
- 4,
- 21
- ],
- [
- 36,
- 1
- ],
- [
- -6,
- -44
- ],
- [
- 84,
- 2
- ],
- [
- 1,
- -76
- ],
- [
- 15,
- -46
- ],
- [
- -11,
- -73
- ],
- [
- 5,
- -73
- ],
- [
- 24,
- -45
- ],
- [
- -4,
- -143
- ],
- [
- 17,
- 11
- ],
- [
- 30,
- -3
- ],
- [
- 44,
- 18
- ],
- [
- 31,
- -7
- ]
- ],
- [
- [
- 14214,
- 9486
- ],
- [
- 8,
- -37
- ],
- [
- -8,
- -58
- ],
- [
- 12,
- -56
- ],
- [
- -10,
- -45
- ],
- [
- 6,
- -42
- ],
- [
- -146,
- 2
- ],
- [
- -3,
- -382
- ],
- [
- 47,
- -98
- ],
- [
- 46,
- -75
- ]
- ],
- [
- [
- 13397,
- 10103
- ],
- [
- -19,
- 90
- ]
- ],
- [
- [
- 13378,
- 10193
- ],
- [
- 28,
- 52
- ],
- [
- 21,
- 20
- ],
- [
- 26,
- -41
- ]
- ],
- [
- [
- 13453,
- 10224
- ],
- [
- -25,
- -26
- ],
- [
- -11,
- -30
- ],
- [
- -3,
- -53
- ],
- [
- -17,
- -12
- ]
- ],
- [
- [
- 14013,
- 15697
- ],
- [
- -2,
- -31
- ],
- [
- -22,
- -18
- ],
- [
- -4,
- -39
- ],
- [
- -33,
- -58
- ]
- ],
- [
- [
- 13952,
- 15551
- ],
- [
- -12,
- 8
- ],
- [
- -1,
- 27
- ],
- [
- -39,
- 40
- ],
- [
- -6,
- 57
- ],
- [
- 6,
- 82
- ],
- [
- 10,
- 37
- ],
- [
- -12,
- 19
- ]
- ],
- [
- [
- 13898,
- 15821
- ],
- [
- -5,
- 38
- ],
- [
- 30,
- 59
- ],
- [
- 5,
- -22
- ],
- [
- 19,
- 11
- ]
- ],
- [
- [
- 13947,
- 15907
- ],
- [
- 14,
- -33
- ],
- [
- 17,
- -12
- ],
- [
- 5,
- -43
- ]
- ],
- [
- [
- 13983,
- 15819
- ],
- [
- -9,
- -41
- ],
- [
- 10,
- -52
- ],
- [
- 29,
- -29
- ]
- ],
- [
- [
- 16143,
- 13706
- ],
- [
- 12,
- 6
- ],
- [
- 3,
- -33
- ],
- [
- 55,
- 19
- ],
- [
- 57,
- -3
- ],
- [
- 42,
- -4
- ],
- [
- 48,
- 81
- ],
- [
- 52,
- 77
- ],
- [
- 44,
- 74
- ]
- ],
- [
- [
- 16456,
- 13923
- ],
- [
- 13,
- -41
- ]
- ],
- [
- [
- 16469,
- 13882
- ],
- [
- 10,
- -95
- ]
- ],
- [
- [
- 16479,
- 13787
- ],
- [
- -36,
- 0
- ],
- [
- -5,
- -78
- ],
- [
- 12,
- -17
- ],
- [
- -32,
- -24
- ],
- [
- 0,
- -49
- ],
- [
- -20,
- -49
- ],
- [
- -2,
- -49
- ]
- ],
- [
- [
- 16396,
- 13521
- ],
- [
- -14,
- -25
- ],
- [
- -210,
- 61
- ],
- [
- -26,
- 121
- ],
- [
- -3,
- 28
- ]
- ],
- [
- [
- 7880,
- 4211
- ],
- [
- -42,
- 4
- ],
- [
- -75,
- 0
- ],
- [
- 0,
- 267
- ]
- ],
- [
- [
- 7763,
- 4482
- ],
- [
- 27,
- -55
- ],
- [
- 35,
- -90
- ],
- [
- 90,
- -72
- ],
- [
- 98,
- -30
- ],
- [
- -31,
- -60
- ],
- [
- -67,
- -6
- ],
- [
- -35,
- 42
- ]
- ],
- [
- [
- 7767,
- 4523
- ],
- [
- -64,
- 19
- ],
- [
- -169,
- 16
- ],
- [
- -28,
- 70
- ],
- [
- 1,
- 90
- ],
- [
- -47,
- -8
- ],
- [
- -24,
- 43
- ],
- [
- -6,
- 128
- ],
- [
- 53,
- 52
- ],
- [
- 22,
- 76
- ],
- [
- -8,
- 61
- ],
- [
- 37,
- 102
- ],
- [
- 26,
- 159
- ],
- [
- -8,
- 71
- ],
- [
- 31,
- 22
- ],
- [
- -8,
- 46
- ],
- [
- -32,
- 24
- ],
- [
- 23,
- 50
- ],
- [
- -32,
- 46
- ],
- [
- -16,
- 138
- ],
- [
- 28,
- 24
- ],
- [
- -12,
- 147
- ],
- [
- 17,
- 122
- ],
- [
- 18,
- 107
- ],
- [
- 42,
- 44
- ],
- [
- -21,
- 117
- ],
- [
- 0,
- 110
- ],
- [
- 52,
- 79
- ],
- [
- -1,
- 100
- ],
- [
- 40,
- 117
- ],
- [
- 0,
- 110
- ],
- [
- -18,
- 22
- ],
- [
- -32,
- 207
- ],
- [
- 43,
- 124
- ],
- [
- -7,
- 116
- ],
- [
- 25,
- 109
- ],
- [
- 46,
- 113
- ],
- [
- 49,
- 74
- ],
- [
- -21,
- 47
- ],
- [
- 14,
- 39
- ],
- [
- -2,
- 200
- ],
- [
- 76,
- 59
- ],
- [
- 24,
- 125
- ],
- [
- -8,
- 30
- ]
- ],
- [
- [
- 7870,
- 8070
- ],
- [
- 58,
- 108
- ],
- [
- 91,
- -29
- ],
- [
- 41,
- -87
- ],
- [
- 27,
- 97
- ],
- [
- 80,
- -5
- ],
- [
- 11,
- -26
- ]
- ],
- [
- [
- 8178,
- 8128
- ],
- [
- 128,
- -196
- ],
- [
- 57,
- -18
- ],
- [
- 85,
- -89
- ],
- [
- 72,
- -47
- ],
- [
- 10,
- -52
- ],
- [
- -69,
- -183
- ],
- [
- 71,
- -32
- ],
- [
- 78,
- -19
- ],
- [
- 55,
- 20
- ],
- [
- 63,
- 91
- ],
- [
- 12,
- 106
- ]
- ],
- [
- [
- 8740,
- 7709
- ],
- [
- 34,
- 23
- ],
- [
- 35,
- -69
- ],
- [
- -1,
- -96
- ],
- [
- -59,
- -66
- ],
- [
- -47,
- -49
- ],
- [
- -78,
- -116
- ],
- [
- -93,
- -164
- ]
- ],
- [
- [
- 8531,
- 7172
- ],
- [
- -18,
- -96
- ],
- [
- -19,
- -123
- ],
- [
- 1,
- -120
- ],
- [
- -15,
- -26
- ],
- [
- -5,
- -78
- ]
- ],
- [
- [
- 8475,
- 6729
- ],
- [
- -5,
- -63
- ],
- [
- 88,
- -102
- ],
- [
- -9,
- -83
- ],
- [
- 43,
- -52
- ],
- [
- -3,
- -59
- ],
- [
- -67,
- -154
- ],
- [
- -103,
- -64
- ],
- [
- -140,
- -25
- ],
- [
- -77,
- 12
- ],
- [
- 15,
- -71
- ],
- [
- -14,
- -90
- ],
- [
- 12,
- -61
- ],
- [
- -41,
- -42
- ],
- [
- -72,
- -17
- ],
- [
- -67,
- 44
- ],
- [
- -27,
- -31
- ],
- [
- 10,
- -119
- ],
- [
- 47,
- -37
- ],
- [
- 38,
- 38
- ],
- [
- 21,
- -62
- ],
- [
- -64,
- -37
- ],
- [
- -56,
- -75
- ],
- [
- -10,
- -121
- ],
- [
- -17,
- -64
- ],
- [
- -66,
- 0
- ],
- [
- -54,
- -62
- ],
- [
- -20,
- -90
- ],
- [
- 68,
- -87
- ],
- [
- 67,
- -25
- ],
- [
- -24,
- -107
- ],
- [
- -83,
- -68
- ],
- [
- -45,
- -141
- ],
- [
- -63,
- -47
- ],
- [
- -29,
- -56
- ],
- [
- 22,
- -125
- ],
- [
- 47,
- -69
- ],
- [
- -30,
- 6
- ]
- ],
- [
- [
- 15586,
- 15727
- ],
- [
- 96,
- 19
- ]
- ],
- [
- [
- 15682,
- 15746
- ],
- [
- 15,
- -32
- ],
- [
- 26,
- -21
- ],
- [
- -14,
- -30
- ],
- [
- 38,
- -41
- ],
- [
- -20,
- -38
- ],
- [
- 29,
- -33
- ],
- [
- 32,
- -19
- ],
- [
- 1,
- -84
- ]
- ],
- [
- [
- 15789,
- 15448
- ],
- [
- -25,
- -3
- ]
- ],
- [
- [
- 15764,
- 15445
- ],
- [
- -28,
- 69
- ],
- [
- 0,
- 19
- ],
- [
- -31,
- 0
- ],
- [
- -20,
- 32
- ],
- [
- -15,
- -3
- ]
- ],
- [
- [
- 15670,
- 15562
- ],
- [
- -27,
- 35
- ],
- [
- -52,
- 29
- ],
- [
- 6,
- 59
- ],
- [
- -11,
- 42
- ]
- ],
- [
- [
- 8395,
- 1195
- ],
- [
- -21,
- -61
- ],
- [
- -20,
- -54
- ],
- [
- -146,
- 16
- ],
- [
- -156,
- -7
- ],
- [
- -87,
- 40
- ],
- [
- 0,
- 5
- ],
- [
- -38,
- 35
- ],
- [
- 157,
- -5
- ],
- [
- 150,
- -11
- ],
- [
- 52,
- 49
- ],
- [
- 36,
- 42
- ],
- [
- 73,
- -49
- ]
- ],
- [
- [
- 1449,
- 1260
- ],
- [
- -133,
- -16
- ],
- [
- -92,
- 42
- ],
- [
- -41,
- 42
- ],
- [
- -3,
- 7
- ],
- [
- -45,
- 33
- ],
- [
- 43,
- 45
- ],
- [
- 129,
- -19
- ],
- [
- 70,
- -38
- ],
- [
- 53,
- -42
- ],
- [
- 19,
- -54
- ]
- ],
- [
- [
- 9400,
- 1434
- ],
- [
- 86,
- -52
- ],
- [
- 30,
- -73
- ],
- [
- 8,
- -51
- ],
- [
- 3,
- -61
- ],
- [
- -108,
- -38
- ],
- [
- -113,
- -31
- ],
- [
- -131,
- -28
- ],
- [
- -147,
- -23
- ],
- [
- -165,
- 7
- ],
- [
- -91,
- 40
- ],
- [
- 12,
- 49
- ],
- [
- 149,
- 33
- ],
- [
- 60,
- 40
- ],
- [
- 44,
- 52
- ],
- [
- 31,
- 44
- ],
- [
- 42,
- 43
- ],
- [
- 45,
- 49
- ],
- [
- 36,
- 0
- ],
- [
- 104,
- 26
- ],
- [
- 105,
- -26
- ]
- ],
- [
- [
- 4098,
- 1979
- ],
- [
- 90,
- -18
- ],
- [
- 83,
- 21
- ],
- [
- -39,
- -43
- ],
- [
- -66,
- -30
- ],
- [
- -97,
- 9
- ],
- [
- -69,
- 43
- ],
- [
- 15,
- 40
- ],
- [
- 83,
- -22
- ]
- ],
- [
- [
- 3795,
- 1982
- ],
- [
- 106,
- -47
- ],
- [
- -41,
- 4
- ],
- [
- -90,
- 12
- ],
- [
- -95,
- 33
- ],
- [
- 50,
- 26
- ],
- [
- 70,
- -28
- ]
- ],
- [
- [
- 5648,
- 2167
- ],
- [
- 76,
- -16
- ],
- [
- 77,
- 14
- ],
- [
- 41,
- -68
- ],
- [
- -55,
- 9
- ],
- [
- -85,
- -4
- ],
- [
- -86,
- 4
- ],
- [
- -94,
- -7
- ],
- [
- -71,
- 24
- ],
- [
- -37,
- 49
- ],
- [
- 44,
- 21
- ],
- [
- 89,
- -16
- ],
- [
- 101,
- -10
- ]
- ],
- [
- [
- 7776,
- 2285
- ],
- [
- 8,
- -54
- ],
- [
- -12,
- -47
- ],
- [
- -19,
- -45
- ],
- [
- -82,
- -16
- ],
- [
- -78,
- -24
- ],
- [
- -92,
- 2
- ],
- [
- 35,
- 47
- ],
- [
- -82,
- -16
- ],
- [
- -78,
- -17
- ],
- [
- -53,
- 36
- ],
- [
- -5,
- 49
- ],
- [
- 77,
- 47
- ],
- [
- 48,
- 14
- ],
- [
- 80,
- -5
- ],
- [
- 21,
- 62
- ],
- [
- 4,
- 44
- ],
- [
- -2,
- 97
- ],
- [
- 40,
- 56
- ],
- [
- 64,
- 19
- ],
- [
- 37,
- -45
- ],
- [
- 17,
- -44
- ],
- [
- 30,
- -55
- ],
- [
- 23,
- -51
- ],
- [
- 19,
- -54
- ]
- ],
- [
- [
- 8462,
- 3101
- ],
- [
- -30,
- -26
- ],
- [
- -52,
- 19
- ],
- [
- -58,
- -12
- ],
- [
- -47,
- -28
- ],
- [
- -51,
- -31
- ],
- [
- -34,
- -35
- ],
- [
- -10,
- -47
- ],
- [
- 4,
- -45
- ],
- [
- 33,
- -40
- ],
- [
- -48,
- -28
- ],
- [
- -65,
- -9
- ],
- [
- -38,
- -40
- ],
- [
- -41,
- -38
- ],
- [
- -44,
- -51
- ],
- [
- -11,
- -45
- ],
- [
- 25,
- -50
- ],
- [
- 37,
- -37
- ],
- [
- 57,
- -28
- ],
- [
- 53,
- -38
- ],
- [
- 29,
- -47
- ],
- [
- 15,
- -45
- ],
- [
- 20,
- -47
- ],
- [
- 33,
- -40
- ],
- [
- 21,
- -44
- ],
- [
- 9,
- -111
- ],
- [
- 21,
- -44
- ],
- [
- 5,
- -47
- ],
- [
- 22,
- -47
- ],
- [
- -10,
- -64
- ],
- [
- -38,
- -49
- ],
- [
- -41,
- -40
- ],
- [
- -93,
- -17
- ],
- [
- -31,
- -42
- ],
- [
- -42,
- -40
- ],
- [
- -106,
- -45
- ],
- [
- -92,
- -18
- ],
- [
- -88,
- -26
- ],
- [
- -94,
- -26
- ],
- [
- -56,
- -50
- ],
- [
- -112,
- -4
- ],
- [
- -123,
- 4
- ],
- [
- -110,
- -9
- ],
- [
- -118,
- 0
- ],
- [
- 22,
- -47
- ],
- [
- 107,
- -21
- ],
- [
- 77,
- -33
- ],
- [
- 44,
- -42
- ],
- [
- -78,
- -38
- ],
- [
- -120,
- 12
- ],
- [
- -100,
- -31
- ],
- [
- -4,
- -49
- ],
- [
- -2,
- -47
- ],
- [
- 82,
- -40
- ],
- [
- 15,
- -45
- ],
- [
- 88,
- -44
- ],
- [
- 148,
- -19
- ],
- [
- 125,
- -33
- ],
- [
- 100,
- -38
- ],
- [
- 127,
- -37
- ],
- [
- 173,
- -19
- ],
- [
- 171,
- -33
- ],
- [
- 119,
- -35
- ],
- [
- 130,
- -40
- ],
- [
- 68,
- -57
- ],
- [
- 34,
- -44
- ],
- [
- 85,
- 42
- ],
- [
- 114,
- 35
- ],
- [
- 122,
- 38
- ],
- [
- 144,
- 30
- ],
- [
- 125,
- 33
- ],
- [
- 173,
- 3
- ],
- [
- 171,
- -17
- ],
- [
- 140,
- -28
- ],
- [
- 45,
- 52
- ],
- [
- 97,
- 35
- ],
- [
- 177,
- 2
- ],
- [
- 137,
- 26
- ],
- [
- 131,
- 26
- ],
- [
- 145,
- 16
- ],
- [
- 154,
- 22
- ],
- [
- 108,
- 30
- ],
- [
- -49,
- 42
- ],
- [
- -30,
- 43
- ],
- [
- 0,
- 44
- ],
- [
- -135,
- -4
- ],
- [
- -143,
- -19
- ],
- [
- -137,
- 0
- ],
- [
- -19,
- 45
- ],
- [
- 10,
- 89
- ],
- [
- 31,
- 26
- ],
- [
- 100,
- 28
- ],
- [
- 117,
- 28
- ],
- [
- 85,
- 35
- ],
- [
- 84,
- 36
- ],
- [
- 63,
- 47
- ],
- [
- 96,
- 21
- ],
- [
- 94,
- 16
- ],
- [
- 48,
- 10
- ],
- [
- 108,
- 4
- ],
- [
- 102,
- 17
- ],
- [
- 86,
- 23
- ],
- [
- 85,
- 29
- ],
- [
- 76,
- 28
- ],
- [
- 97,
- 37
- ],
- [
- 61,
- 40
- ],
- [
- 66,
- 36
- ],
- [
- 20,
- 47
- ],
- [
- -73,
- 28
- ],
- [
- 24,
- 49
- ],
- [
- 47,
- 38
- ],
- [
- 72,
- 23
- ],
- [
- 77,
- 29
- ],
- [
- 71,
- 37
- ],
- [
- 54,
- 47
- ],
- [
- 34,
- 57
- ],
- [
- 51,
- 33
- ],
- [
- 83,
- -7
- ],
- [
- 34,
- -40
- ],
- [
- 83,
- -5
- ],
- [
- 3,
- 45
- ],
- [
- 36,
- 47
- ],
- [
- 75,
- -12
- ],
- [
- 18,
- -45
- ],
- [
- 83,
- -7
- ],
- [
- 90,
- 21
- ],
- [
- 87,
- 14
- ],
- [
- 80,
- -7
- ],
- [
- 30,
- -49
- ],
- [
- 76,
- 40
- ],
- [
- 71,
- 21
- ],
- [
- 79,
- 16
- ],
- [
- 78,
- 17
- ],
- [
- 71,
- 28
- ],
- [
- 78,
- 19
- ],
- [
- 60,
- 26
- ],
- [
- 42,
- 42
- ],
- [
- 52,
- -30
- ],
- [
- 72,
- 16
- ],
- [
- 51,
- -56
- ],
- [
- 40,
- -43
- ],
- [
- 79,
- 24
- ],
- [
- 31,
- 47
- ],
- [
- 71,
- 33
- ],
- [
- 92,
- -7
- ],
- [
- 27,
- -45
- ],
- [
- 57,
- 45
- ],
- [
- 75,
- 14
- ],
- [
- 82,
- 4
- ],
- [
- 74,
- -2
- ],
- [
- 78,
- -14
- ],
- [
- 75,
- -7
- ],
- [
- 33,
- -40
- ],
- [
- 45,
- -35
- ],
- [
- 76,
- 21
- ],
- [
- 82,
- 5
- ],
- [
- 79,
- 0
- ],
- [
- 78,
- 2
- ],
- [
- 70,
- 16
- ],
- [
- 74,
- 15
- ],
- [
- 61,
- 32
- ],
- [
- 65,
- 22
- ],
- [
- 71,
- 11
- ],
- [
- 54,
- 33
- ],
- [
- 38,
- 66
- ],
- [
- 40,
- 40
- ],
- [
- 72,
- -19
- ],
- [
- 27,
- -42
- ],
- [
- 60,
- -28
- ],
- [
- 73,
- 9
- ],
- [
- 49,
- -42
- ],
- [
- 52,
- -31
- ],
- [
- 71,
- 28
- ],
- [
- 24,
- 52
- ],
- [
- 63,
- 21
- ],
- [
- 72,
- 40
- ],
- [
- 69,
- 17
- ],
- [
- 82,
- 23
- ],
- [
- 54,
- 26
- ],
- [
- 58,
- 28
- ],
- [
- 54,
- 26
- ],
- [
- 66,
- -14
- ],
- [
- 63,
- 42
- ],
- [
- 45,
- 33
- ],
- [
- 65,
- -2
- ],
- [
- 57,
- 28
- ],
- [
- 14,
- 42
- ],
- [
- 59,
- 33
- ],
- [
- 57,
- 24
- ],
- [
- 70,
- 19
- ],
- [
- 64,
- 9
- ],
- [
- 61,
- -7
- ],
- [
- 66,
- -12
- ],
- [
- 56,
- -33
- ],
- [
- 7,
- -51
- ],
- [
- 61,
- -40
- ],
- [
- 42,
- -33
- ],
- [
- 84,
- -14
- ],
- [
- 46,
- -33
- ],
- [
- 58,
- -33
- ],
- [
- 66,
- -7
- ],
- [
- 56,
- 23
- ],
- [
- 60,
- 50
- ],
- [
- 66,
- -26
- ],
- [
- 68,
- -14
- ],
- [
- 66,
- -14
- ],
- [
- 68,
- -10
- ],
- [
- 70,
- 0
- ],
- [
- 57,
- -124
- ],
- [
- -3,
- -31
- ],
- [
- -8,
- -54
- ],
- [
- -67,
- -31
- ],
- [
- -54,
- -44
- ],
- [
- 9,
- -47
- ],
- [
- 78,
- 2
- ],
- [
- -10,
- -47
- ],
- [
- -35,
- -45
- ],
- [
- -33,
- -49
- ],
- [
- 53,
- -38
- ],
- [
- 81,
- -11
- ],
- [
- 81,
- 21
- ],
- [
- 38,
- 47
- ],
- [
- 23,
- 45
- ],
- [
- 38,
- 37
- ],
- [
- 44,
- 35
- ],
- [
- 18,
- 43
- ],
- [
- 36,
- 58
- ],
- [
- 44,
- 12
- ],
- [
- 79,
- 5
- ],
- [
- 70,
- 14
- ],
- [
- 71,
- 19
- ],
- [
- 34,
- 47
- ],
- [
- 21,
- 45
- ],
- [
- 47,
- 44
- ],
- [
- 69,
- 31
- ],
- [
- 58,
- 23
- ],
- [
- 39,
- 40
- ],
- [
- 39,
- 21
- ],
- [
- 51,
- 19
- ],
- [
- 69,
- -12
- ],
- [
- 63,
- 12
- ],
- [
- 68,
- 14
- ],
- [
- 77,
- -7
- ],
- [
- 50,
- 33
- ],
- [
- 36,
- 80
- ],
- [
- 26,
- -33
- ],
- [
- 33,
- -56
- ],
- [
- 58,
- -24
- ],
- [
- 67,
- -9
- ],
- [
- 67,
- 14
- ],
- [
- 71,
- -9
- ],
- [
- 66,
- -3
- ],
- [
- 43,
- 12
- ],
- [
- 59,
- -7
- ],
- [
- 53,
- -26
- ],
- [
- 63,
- 16
- ],
- [
- 75,
- 0
- ],
- [
- 64,
- 17
- ],
- [
- 73,
- -17
- ],
- [
- 46,
- 40
- ],
- [
- 36,
- 40
- ],
- [
- 47,
- 33
- ],
- [
- 88,
- 90
- ],
- [
- 45,
- -17
- ],
- [
- 53,
- -33
- ],
- [
- 46,
- -42
- ],
- [
- 89,
- -73
- ],
- [
- 69,
- -2
- ],
- [
- 64,
- 0
- ],
- [
- 75,
- 14
- ],
- [
- 75,
- 16
- ],
- [
- 57,
- 33
- ],
- [
- 48,
- 35
- ],
- [
- 78,
- 5
- ],
- [
- 52,
- 26
- ],
- [
- 54,
- -23
- ],
- [
- 36,
- -38
- ],
- [
- 49,
- -38
- ],
- [
- 76,
- 5
- ],
- [
- 48,
- -31
- ],
- [
- 83,
- -30
- ],
- [
- 88,
- -12
- ],
- [
- 72,
- 10
- ],
- [
- 55,
- 37
- ],
- [
- 46,
- 38
- ],
- [
- 63,
- 9
- ],
- [
- 63,
- -16
- ],
- [
- 72,
- -12
- ],
- [
- 66,
- 19
- ],
- [
- 63,
- 0
- ],
- [
- 61,
- -12
- ],
- [
- 64,
- -12
- ],
- [
- 63,
- 21
- ],
- [
- 75,
- 19
- ],
- [
- 71,
- 5
- ],
- [
- 79,
- 0
- ],
- [
- 64,
- 12
- ],
- [
- 63,
- 9
- ],
- [
- 19,
- 59
- ],
- [
- 3,
- 49
- ],
- [
- 44,
- -33
- ],
- [
- 12,
- -54
- ],
- [
- 23,
- -49
- ],
- [
- 29,
- -40
- ],
- [
- 59,
- -21
- ],
- [
- 79,
- 7
- ],
- [
- 91,
- 2
- ],
- [
- 63,
- 7
- ],
- [
- 92,
- 0
- ],
- [
- 65,
- 3
- ],
- [
- 92,
- -5
- ],
- [
- 77,
- -10
- ],
- [
- 50,
- -37
- ],
- [
- -14,
- -45
- ],
- [
- 45,
- -35
- ],
- [
- 75,
- -28
- ],
- [
- 78,
- -31
- ],
- [
- 90,
- -21
- ],
- [
- 94,
- -19
- ],
- [
- 71,
- -19
- ],
- [
- 79,
- -2
- ],
- [
- 45,
- 40
- ],
- [
- 62,
- -33
- ],
- [
- 53,
- -38
- ],
- [
- 62,
- -28
- ],
- [
- 84,
- -12
- ],
- [
- 81,
- -14
- ],
- [
- 34,
- -47
- ],
- [
- 79,
- -28
- ],
- [
- 53,
- -42
- ],
- [
- 78,
- -19
- ],
- [
- 81,
- 2
- ],
- [
- 75,
- -7
- ],
- [
- 83,
- 3
- ],
- [
- 83,
- -10
- ],
- [
- 78,
- -16
- ],
- [
- 73,
- -28
- ],
- [
- 72,
- -24
- ],
- [
- 49,
- -35
- ],
- [
- -8,
- -47
- ],
- [
- -37,
- -42
- ],
- [
- -31,
- -55
- ],
- [
- -25,
- -42
- ],
- [
- -33,
- -49
- ],
- [
- -91,
- -19
- ],
- [
- -41,
- -42
- ],
- [
- -90,
- -26
- ],
- [
- -32,
- -47
- ],
- [
- -47,
- -45
- ],
- [
- -51,
- -38
- ],
- [
- -29,
- -49
- ],
- [
- -17,
- -45
- ],
- [
- -7,
- -54
- ],
- [
- 1,
- -44
- ],
- [
- 40,
- -47
- ],
- [
- 15,
- -45
- ],
- [
- 32,
- -42
- ],
- [
- 130,
- -17
- ],
- [
- 27,
- -51
- ],
- [
- -125,
- -19
- ],
- [
- -107,
- -26
- ],
- [
- -132,
- -5
- ],
- [
- -59,
- -68
- ],
- [
- -12,
- -56
- ],
- [
- -30,
- -45
- ],
- [
- -37,
- -45
- ],
- [
- 93,
- -40
- ],
- [
- 35,
- -49
- ],
- [
- 60,
- -45
- ],
- [
- 85,
- -40
- ],
- [
- 97,
- -37
- ],
- [
- 105,
- -38
- ],
- [
- 160,
- -38
- ],
- [
- 35,
- -58
- ],
- [
- 201,
- -26
- ],
- [
- 14,
- -9
- ],
- [
- 52,
- -36
- ],
- [
- 192,
- 31
- ],
- [
- 160,
- -38
- ],
- [
- 120,
- -29
- ],
- [
- 0,
- -634
- ],
- [
- -25095,
- 0
- ],
- [
- 0,
- 634
- ],
- [
- 4,
- -1
- ],
- [
- 62,
- 70
- ],
- [
- 125,
- -38
- ],
- [
- 8,
- 5
- ],
- [
- 74,
- 38
- ],
- [
- 10,
- -1
- ],
- [
- 8,
- -1
- ],
- [
- 101,
- -50
- ],
- [
- 88,
- 50
- ],
- [
- 16,
- 6
- ],
- [
- 204,
- 22
- ],
- [
- 67,
- -28
- ],
- [
- 33,
- -15
- ],
- [
- 105,
- -40
- ],
- [
- 198,
- -30
- ],
- [
- 157,
- -38
- ],
- [
- 269,
- -28
- ],
- [
- 200,
- 33
- ],
- [
- 297,
- -24
- ],
- [
- 168,
- -37
- ],
- [
- 184,
- 35
- ],
- [
- 194,
- 33
- ],
- [
- 15,
- 56
- ],
- [
- -275,
- 5
- ],
- [
- -225,
- 28
- ],
- [
- -59,
- 47
- ],
- [
- -187,
- 26
- ],
- [
- 13,
- 54
- ],
- [
- 25,
- 50
- ],
- [
- 26,
- 44
- ],
- [
- -13,
- 50
- ],
- [
- -116,
- 33
- ],
- [
- -54,
- 42
- ],
- [
- -107,
- 37
- ],
- [
- 169,
- -7
- ],
- [
- 161,
- 19
- ],
- [
- 101,
- -40
- ],
- [
- 124,
- 36
- ],
- [
- 115,
- 44
- ],
- [
- 56,
- 40
- ],
- [
- -25,
- 50
- ],
- [
- -90,
- 32
- ],
- [
- -102,
- 36
- ],
- [
- -143,
- 7
- ],
- [
- -126,
- 16
- ],
- [
- -135,
- 12
- ],
- [
- -45,
- 45
- ],
- [
- -90,
- 37
- ],
- [
- -55,
- 43
- ],
- [
- -22,
- 136
- ],
- [
- 34,
- -12
- ],
- [
- 63,
- -37
- ],
- [
- 115,
- 11
- ],
- [
- 110,
- 17
- ],
- [
- 58,
- -52
- ],
- [
- 110,
- 12
- ],
- [
- 93,
- 26
- ],
- [
- 87,
- 33
- ],
- [
- 80,
- 39
- ],
- [
- 105,
- 12
- ],
- [
- -3,
- 45
- ],
- [
- -24,
- 45
- ],
- [
- 20,
- 42
- ],
- [
- 90,
- 21
- ],
- [
- 41,
- -40
- ],
- [
- 107,
- 24
- ],
- [
- 80,
- 30
- ],
- [
- 100,
- 3
- ],
- [
- 94,
- 11
- ],
- [
- 94,
- 28
- ],
- [
- 75,
- 26
- ],
- [
- 85,
- 26
- ],
- [
- 55,
- -7
- ],
- [
- 47,
- -9
- ],
- [
- 104,
- 16
- ],
- [
- 93,
- -21
- ],
- [
- 95,
- 2
- ],
- [
- 92,
- 17
- ],
- [
- 94,
- -12
- ],
- [
- 104,
- -12
- ],
- [
- 97,
- 5
- ],
- [
- 101,
- -2
- ],
- [
- 104,
- -3
- ],
- [
- 95,
- 5
- ],
- [
- 71,
- 35
- ],
- [
- 85,
- 19
- ],
- [
- 87,
- -26
- ],
- [
- 84,
- 21
- ],
- [
- 75,
- 43
- ],
- [
- 45,
- -38
- ],
- [
- 24,
- -42
- ],
- [
- 45,
- -40
- ],
- [
- 73,
- 35
- ],
- [
- 83,
- -45
- ],
- [
- 94,
- -14
- ],
- [
- 81,
- -33
- ],
- [
- 98,
- 7
- ],
- [
- 89,
- 22
- ],
- [
- 105,
- -5
- ],
- [
- 94,
- -17
- ],
- [
- 96,
- -21
- ],
- [
- 37,
- 52
- ],
- [
- -46,
- 40
- ],
- [
- -34,
- 42
- ],
- [
- -90,
- 10
- ],
- [
- -39,
- 44
- ],
- [
- -15,
- 45
- ],
- [
- -25,
- 89
- ],
- [
- 53,
- -16
- ],
- [
- 92,
- -7
- ],
- [
- 90,
- 7
- ],
- [
- 82,
- -19
- ],
- [
- 71,
- -35
- ],
- [
- 30,
- -42
- ],
- [
- 94,
- -8
- ],
- [
- 90,
- 17
- ],
- [
- 96,
- 23
- ],
- [
- 86,
- 15
- ],
- [
- 71,
- -29
- ],
- [
- 93,
- 10
- ],
- [
- 60,
- 91
- ],
- [
- 56,
- -54
- ],
- [
- 80,
- -21
- ],
- [
- 88,
- 12
- ],
- [
- 57,
- -47
- ],
- [
- 91,
- -5
- ],
- [
- 85,
- -14
- ],
- [
- 83,
- -26
- ],
- [
- 55,
- 45
- ],
- [
- 27,
- 42
- ],
- [
- 70,
- -47
- ],
- [
- 95,
- 12
- ],
- [
- 71,
- -26
- ],
- [
- 48,
- -40
- ],
- [
- 93,
- 12
- ],
- [
- 72,
- 26
- ],
- [
- 71,
- 30
- ],
- [
- 85,
- 17
- ],
- [
- 98,
- 14
- ],
- [
- 89,
- 16
- ],
- [
- 68,
- 26
- ],
- [
- 41,
- 38
- ],
- [
- 17,
- 52
- ],
- [
- -8,
- 49
- ],
- [
- -22,
- 47
- ],
- [
- -25,
- 47
- ],
- [
- -22,
- 47
- ],
- [
- -18,
- 42
- ],
- [
- -4,
- 47
- ],
- [
- 7,
- 47
- ],
- [
- 33,
- 45
- ],
- [
- 27,
- 49
- ],
- [
- 11,
- 47
- ],
- [
- -13,
- 52
- ],
- [
- -9,
- 47
- ],
- [
- 35,
- 54
- ],
- [
- 38,
- 35
- ],
- [
- 45,
- 45
- ],
- [
- 48,
- 38
- ],
- [
- 56,
- 35
- ],
- [
- 27,
- 52
- ],
- [
- 38,
- 33
- ],
- [
- 44,
- 30
- ],
- [
- 67,
- 7
- ],
- [
- 43,
- 38
- ],
- [
- 50,
- 23
- ],
- [
- 57,
- 14
- ],
- [
- 50,
- 31
- ],
- [
- 40,
- 38
- ],
- [
- 55,
- 14
- ],
- [
- 41,
- -31
- ],
- [
- -26,
- -40
- ],
- [
- -71,
- -35
- ]
- ],
- [
- [
- 17353,
- 4964
- ],
- [
- 45,
- -38
- ],
- [
- 66,
- -15
- ],
- [
- 2,
- -23
- ],
- [
- -19,
- -54
- ],
- [
- -107,
- -8
- ],
- [
- -2,
- 64
- ],
- [
- 10,
- 49
- ],
- [
- 5,
- 25
- ]
- ],
- [
- [
- 22683,
- 5903
- ],
- [
- 67,
- -41
- ],
- [
- 38,
- 16
- ],
- [
- 55,
- 23
- ],
- [
- 41,
- -8
- ],
- [
- 5,
- -142
- ],
- [
- -23,
- -41
- ],
- [
- -8,
- -97
- ],
- [
- -24,
- 33
- ],
- [
- -48,
- -84
- ],
- [
- -15,
- 7
- ],
- [
- -43,
- 4
- ],
- [
- -43,
- 102
- ],
- [
- -9,
- 79
- ],
- [
- -40,
- 105
- ],
- [
- 1,
- 55
- ],
- [
- 46,
- -11
- ]
- ],
- [
- [
- 22555,
- 9146
- ],
- [
- 25,
- -94
- ],
- [
- 45,
- 45
- ],
- [
- 23,
- -51
- ],
- [
- 33,
- -47
- ],
- [
- -7,
- -53
- ],
- [
- 15,
- -103
- ],
- [
- 11,
- -59
- ],
- [
- 17,
- -15
- ],
- [
- 19,
- -103
- ],
- [
- -7,
- -62
- ],
- [
- 23,
- -81
- ],
- [
- 75,
- -63
- ],
- [
- 50,
- -57
- ],
- [
- 46,
- -52
- ],
- [
- -9,
- -29
- ],
- [
- 40,
- -75
- ],
- [
- 27,
- -130
- ],
- [
- 28,
- 26
- ],
- [
- 28,
- -52
- ],
- [
- 17,
- 19
- ],
- [
- 12,
- -128
- ],
- [
- 50,
- -73
- ],
- [
- 32,
- -46
- ],
- [
- 55,
- -97
- ],
- [
- 19,
- -97
- ],
- [
- 2,
- -68
- ],
- [
- -5,
- -74
- ],
- [
- 34,
- -102
- ],
- [
- -4,
- -106
- ],
- [
- -12,
- -56
- ],
- [
- -19,
- -107
- ],
- [
- 1,
- -69
- ],
- [
- -14,
- -86
- ],
- [
- -30,
- -109
- ],
- [
- -52,
- -59
- ],
- [
- -26,
- -93
- ],
- [
- -23,
- -59
- ],
- [
- -20,
- -104
- ],
- [
- -27,
- -59
- ],
- [
- -18,
- -90
- ],
- [
- -9,
- -83
- ],
- [
- 4,
- -38
- ],
- [
- -40,
- -41
- ],
- [
- -78,
- -5
- ],
- [
- -65,
- -49
- ],
- [
- -32,
- -46
- ],
- [
- -42,
- -52
- ],
- [
- -58,
- 53
- ],
- [
- -42,
- 21
- ],
- [
- 10,
- 63
- ],
- [
- -38,
- -23
- ],
- [
- -61,
- -87
- ],
- [
- -60,
- 33
- ],
- [
- -39,
- 19
- ],
- [
- -40,
- 8
- ],
- [
- -68,
- 35
- ],
- [
- -45,
- 74
- ],
- [
- -13,
- 91
- ],
- [
- -16,
- 61
- ],
- [
- -34,
- 48
- ],
- [
- -67,
- 15
- ],
- [
- 23,
- 58
- ],
- [
- -17,
- 89
- ],
- [
- -34,
- -83
- ],
- [
- -62,
- -22
- ],
- [
- 36,
- 66
- ],
- [
- 11,
- 70
- ],
- [
- 27,
- 58
- ],
- [
- -6,
- 89
- ],
- [
- -57,
- -102
- ],
- [
- -43,
- -41
- ],
- [
- -27,
- -96
- ],
- [
- -54,
- 50
- ],
- [
- 2,
- 63
- ],
- [
- -44,
- 87
- ],
- [
- -37,
- 45
- ],
- [
- 14,
- 28
- ],
- [
- -90,
- 73
- ],
- [
- -49,
- 3
- ],
- [
- -67,
- 59
- ],
- [
- -125,
- -12
- ],
- [
- -90,
- -43
- ],
- [
- -79,
- -40
- ],
- [
- -67,
- 8
- ],
- [
- -74,
- -61
- ],
- [
- -60,
- -28
- ],
- [
- -14,
- -63
- ],
- [
- -25,
- -49
- ],
- [
- -60,
- -2
- ],
- [
- -43,
- -11
- ],
- [
- -62,
- 22
- ],
- [
- -50,
- -13
- ],
- [
- -48,
- -6
- ],
- [
- -41,
- -64
- ],
- [
- -21,
- 6
- ],
- [
- -35,
- -34
- ],
- [
- -33,
- -38
- ],
- [
- -51,
- 4
- ],
- [
- -47,
- 0
- ],
- [
- -74,
- 77
- ],
- [
- -37,
- 23
- ],
- [
- 1,
- 68
- ],
- [
- 35,
- 17
- ],
- [
- 12,
- 27
- ],
- [
- -3,
- 43
- ],
- [
- 9,
- 84
- ],
- [
- -8,
- 71
- ],
- [
- -37,
- 121
- ],
- [
- -11,
- 68
- ],
- [
- 3,
- 69
- ],
- [
- -28,
- 78
- ],
- [
- -2,
- 35
- ],
- [
- -31,
- 48
- ],
- [
- -8,
- 94
- ],
- [
- -40,
- 95
- ],
- [
- -10,
- 51
- ],
- [
- 31,
- -52
- ],
- [
- -24,
- 111
- ],
- [
- 35,
- -34
- ],
- [
- 20,
- -47
- ],
- [
- -1,
- 62
- ],
- [
- -34,
- 94
- ],
- [
- -7,
- 38
- ],
- [
- -16,
- 36
- ],
- [
- 8,
- 69
- ],
- [
- 14,
- 30
- ],
- [
- 9,
- 60
- ],
- [
- -7,
- 70
- ],
- [
- 29,
- 86
- ],
- [
- 5,
- -91
- ],
- [
- 29,
- 82
- ],
- [
- 57,
- 40
- ],
- [
- 34,
- 52
- ],
- [
- 53,
- 44
- ],
- [
- 32,
- 9
- ],
- [
- 19,
- -15
- ],
- [
- 55,
- 45
- ],
- [
- 42,
- 13
- ],
- [
- 11,
- 27
- ],
- [
- 18,
- 10
- ],
- [
- 39,
- -2
- ],
- [
- 73,
- 35
- ],
- [
- 38,
- 53
- ],
- [
- 18,
- 64
- ],
- [
- 41,
- 61
- ],
- [
- 3,
- 48
- ],
- [
- 2,
- 65
- ],
- [
- 49,
- 102
- ],
- [
- 29,
- -103
- ],
- [
- 30,
- 23
- ],
- [
- -25,
- 57
- ],
- [
- 22,
- 58
- ],
- [
- 30,
- -26
- ],
- [
- 9,
- 92
- ],
- [
- 38,
- 59
- ],
- [
- 17,
- 47
- ],
- [
- 35,
- 20
- ],
- [
- 1,
- 34
- ],
- [
- 30,
- -14
- ],
- [
- 2,
- 30
- ],
- [
- 30,
- 17
- ],
- [
- 34,
- 16
- ],
- [
- 52,
- -55
- ],
- [
- 38,
- -71
- ],
- [
- 44,
- 0
- ],
- [
- 44,
- -12
- ],
- [
- -15,
- 66
- ],
- [
- 34,
- 96
- ],
- [
- 31,
- 32
- ],
- [
- -11,
- 30
- ],
- [
- 31,
- 68
- ],
- [
- 42,
- 43
- ],
- [
- 36,
- -15
- ],
- [
- 58,
- 23
- ],
- [
- -1,
- 61
- ],
- [
- -51,
- 40
- ],
- [
- 37,
- 17
- ],
- [
- 46,
- -30
- ],
- [
- 37,
- -49
- ],
- [
- 59,
- -31
- ],
- [
- 20,
- 13
- ],
- [
- 43,
- -37
- ],
- [
- 41,
- 34
- ],
- [
- 26,
- -10
- ],
- [
- 16,
- 23
- ],
- [
- 32,
- -60
- ],
- [
- -18,
- -64
- ],
- [
- -27,
- -48
- ],
- [
- -24,
- -4
- ],
- [
- 8,
- -48
- ],
- [
- -20,
- -60
- ],
- [
- -25,
- -59
- ],
- [
- 5,
- -34
- ],
- [
- 55,
- -66
- ],
- [
- 54,
- -39
- ],
- [
- 36,
- -41
- ],
- [
- 50,
- -71
- ],
- [
- 20,
- 0
- ],
- [
- 37,
- -31
- ],
- [
- 10,
- -37
- ],
- [
- 67,
- -41
- ],
- [
- 46,
- 41
- ],
- [
- 13,
- 65
- ],
- [
- 14,
- 53
- ],
- [
- 9,
- 66
- ],
- [
- 21,
- 95
- ],
- [
- -9,
- 58
- ],
- [
- 5,
- 35
- ],
- [
- -8,
- 69
- ],
- [
- 9,
- 90
- ],
- [
- 13,
- 25
- ],
- [
- -11,
- 40
- ],
- [
- 17,
- 63
- ],
- [
- 13,
- 66
- ],
- [
- 2,
- 34
- ],
- [
- 26,
- 45
- ],
- [
- 20,
- -58
- ],
- [
- 5,
- -76
- ],
- [
- 17,
- -14
- ],
- [
- 3,
- -51
- ],
- [
- 25,
- -61
- ],
- [
- 5,
- -67
- ],
- [
- -2,
- -44
- ]
- ],
- [
- [
- 13731,
- 16571
- ],
- [
- -5,
- -50
- ],
- [
- -39,
- 0
- ],
- [
- 13,
- -26
- ],
- [
- -23,
- -77
- ]
- ],
- [
- [
- 13677,
- 16418
- ],
- [
- -13,
- -20
- ],
- [
- -61,
- -3
- ],
- [
- -35,
- -27
- ],
- [
- -58,
- 9
- ]
- ],
- [
- [
- 13510,
- 16377
- ],
- [
- -100,
- 31
- ],
- [
- -15,
- 42
- ],
- [
- -69,
- -21
- ],
- [
- -8,
- -23
- ],
- [
- -43,
- 17
- ]
- ],
- [
- [
- 13275,
- 16423
- ],
- [
- -35,
- 3
- ],
- [
- -32,
- 22
- ],
- [
- 11,
- 29
- ],
- [
- -3,
- 22
- ]
- ],
- [
- [
- 13216,
- 16499
- ],
- [
- 21,
- 6
- ],
- [
- 36,
- -33
- ],
- [
- 10,
- 32
- ],
- [
- 61,
- -5
- ],
- [
- 50,
- 21
- ],
- [
- 33,
- -4
- ],
- [
- 22,
- -24
- ],
- [
- 7,
- 20
- ],
- [
- -10,
- 78
- ],
- [
- 25,
- 16
- ],
- [
- 24,
- 55
- ]
- ],
- [
- [
- 13495,
- 16661
- ],
- [
- 52,
- -39
- ],
- [
- 39,
- 49
- ],
- [
- 25,
- 9
- ],
- [
- 54,
- -36
- ],
- [
- 33,
- 6
- ],
- [
- 32,
- -23
- ]
- ],
- [
- [
- 13730,
- 16627
- ],
- [
- -6,
- -15
- ],
- [
- 7,
- -41
- ]
- ],
- [
- [
- 15682,
- 15746
- ],
- [
- 18,
- 19
- ],
- [
- 51,
- -34
- ],
- [
- 38,
- -7
- ],
- [
- 10,
- 14
- ],
- [
- -35,
- 65
- ],
- [
- 18,
- 16
- ]
- ],
- [
- [
- 15782,
- 15819
- ],
- [
- 20,
- -4
- ],
- [
- 48,
- -73
- ],
- [
- 31,
- -8
- ],
- [
- 12,
- 31
- ],
- [
- 41,
- 48
- ]
- ],
- [
- [
- 15934,
- 15813
- ],
- [
- 37,
- -63
- ],
- [
- 35,
- -85
- ],
- [
- 33,
- -6
- ],
- [
- 21,
- -32
- ],
- [
- -57,
- -10
- ],
- [
- -12,
- -93
- ],
- [
- -12,
- -42
- ],
- [
- -26,
- -28
- ],
- [
- 2,
- -60
- ]
- ],
- [
- [
- 15955,
- 15394
- ],
- [
- -17,
- -6
- ],
- [
- -44,
- 63
- ],
- [
- 24,
- 60
- ],
- [
- -20,
- 35
- ],
- [
- -26,
- -9
- ],
- [
- -83,
- -89
- ]
- ],
- [
- [
- 15764,
- 15445
- ],
- [
- -48,
- 16
- ],
- [
- -35,
- 55
- ],
- [
- -11,
- 46
- ]
- ],
- [
- [
- 14593,
- 10257
- ],
- [
- -5,
- 145
- ],
- [
- -17,
- 55
- ]
- ],
- [
- [
- 14571,
- 10457
- ],
- [
- 42,
- -10
- ],
- [
- 21,
- 68
- ],
- [
- 37,
- -7
- ]
- ],
- [
- [
- 14671,
- 10508
- ],
- [
- 5,
- -48
- ],
- [
- 15,
- -27
- ],
- [
- 0,
- -39
- ],
- [
- -17,
- -25
- ],
- [
- -27,
- -62
- ],
- [
- -25,
- -44
- ],
- [
- -29,
- -6
- ]
- ],
- [
- [
- 12977,
- 16892
- ],
- [
- -8,
- -81
- ]
- ],
- [
- [
- 12969,
- 16811
- ],
- [
- -18,
- -5
- ],
- [
- -8,
- -67
- ]
- ],
- [
- [
- 12943,
- 16739
- ],
- [
- -61,
- 55
- ],
- [
- -36,
- -9
- ],
- [
- -48,
- 56
- ],
- [
- -33,
- 48
- ],
- [
- -32,
- 2
- ],
- [
- -10,
- 42
- ]
- ],
- [
- [
- 12723,
- 16933
- ],
- [
- 56,
- 24
- ]
- ],
- [
- [
- 12779,
- 16957
- ],
- [
- 51,
- -9
- ],
- [
- 64,
- 25
- ],
- [
- 44,
- -53
- ],
- [
- 39,
- -28
- ]
- ],
- [
- [
- 12735,
- 11548
- ],
- [
- -57,
- -14
- ]
- ],
- [
- [
- 12678,
- 11534
- ],
- [
- -18,
- 83
- ],
- [
- 4,
- 275
- ],
- [
- -15,
- 25
- ],
- [
- -2,
- 59
- ],
- [
- -24,
- 42
- ],
- [
- -22,
- 35
- ],
- [
- 9,
- 64
- ]
- ],
- [
- [
- 12610,
- 12117
- ],
- [
- 24,
- 13
- ],
- [
- 14,
- 53
- ],
- [
- 34,
- 11
- ],
- [
- 16,
- 36
- ]
- ],
- [
- [
- 12698,
- 12230
- ],
- [
- 23,
- 35
- ],
- [
- 25,
- 0
- ],
- [
- 53,
- -69
- ]
- ],
- [
- [
- 12799,
- 12196
- ],
- [
- -2,
- -40
- ],
- [
- 15,
- -71
- ],
- [
- -14,
- -48
- ],
- [
- 8,
- -33
- ],
- [
- -34,
- -74
- ],
- [
- -21,
- -37
- ],
- [
- -14,
- -75
- ],
- [
- 2,
- -77
- ],
- [
- -4,
- -193
- ]
- ],
- [
- [
- 12610,
- 12117
- ],
- [
- -61,
- 2
- ]
- ],
- [
- [
- 12549,
- 12119
- ],
- [
- -32,
- 10
- ],
- [
- -23,
- -20
- ],
- [
- -30,
- 9
- ],
- [
- -121,
- -6
- ],
- [
- -2,
- -68
- ],
- [
- 9,
- -90
- ]
- ],
- [
- [
- 12350,
- 11954
- ],
- [
- -47,
- 31
- ],
- [
- -33,
- -5
- ],
- [
- -24,
- -30
- ],
- [
- -32,
- 26
- ],
- [
- -12,
- 39
- ],
- [
- -31,
- 26
- ]
- ],
- [
- [
- 12171,
- 12041
- ],
- [
- -5,
- 70
- ],
- [
- 19,
- 51
- ],
- [
- -1,
- 40
- ],
- [
- 55,
- 100
- ],
- [
- 10,
- 82
- ],
- [
- 19,
- 29
- ],
- [
- 34,
- -16
- ],
- [
- 29,
- 25
- ],
- [
- 10,
- 31
- ],
- [
- 54,
- 53
- ],
- [
- 13,
- 38
- ],
- [
- 65,
- 50
- ],
- [
- 39,
- 17
- ],
- [
- 17,
- -23
- ],
- [
- 45,
- 0
- ]
- ],
- [
- [
- 12574,
- 12588
- ],
- [
- -6,
- -58
- ],
- [
- 9,
- -55
- ],
- [
- 40,
- -78
- ],
- [
- 2,
- -58
- ],
- [
- 80,
- -27
- ],
- [
- -1,
- -82
- ]
- ],
- [
- [
- 19008,
- 13441
- ],
- [
- -2,
- -86
- ],
- [
- -24,
- 19
- ],
- [
- 4,
- -97
- ]
- ],
- [
- [
- 18986,
- 13277
- ],
- [
- -20,
- 63
- ],
- [
- -4,
- 61
- ],
- [
- -13,
- 57
- ],
- [
- -29,
- 70
- ],
- [
- -64,
- 5
- ],
- [
- 6,
- -49
- ],
- [
- -22,
- -67
- ],
- [
- -29,
- 24
- ],
- [
- -11,
- -22
- ],
- [
- -19,
- 13
- ],
- [
- -27,
- 11
- ]
- ],
- [
- [
- 18754,
- 13443
- ],
- [
- -11,
- 99
- ],
- [
- -24,
- 90
- ],
- [
- 12,
- 72
- ],
- [
- -43,
- 33
- ],
- [
- 15,
- 43
- ],
- [
- 44,
- 45
- ],
- [
- -51,
- 64
- ],
- [
- 25,
- 81
- ],
- [
- 55,
- -52
- ],
- [
- 34,
- -6
- ],
- [
- 6,
- -83
- ],
- [
- 66,
- -17
- ],
- [
- 65,
- 2
- ],
- [
- 40,
- -20
- ],
- [
- -32,
- -102
- ],
- [
- -31,
- -7
- ],
- [
- -22,
- -68
- ],
- [
- 38,
- -62
- ],
- [
- 12,
- 76
- ],
- [
- 19,
- 1
- ],
- [
- 37,
- -191
- ]
- ],
- [
- [
- 14127,
- 16104
- ],
- [
- 20,
- -49
- ],
- [
- 27,
- 8
- ],
- [
- 54,
- -18
- ],
- [
- 102,
- -7
- ],
- [
- 34,
- 31
- ],
- [
- 83,
- 28
- ],
- [
- 50,
- -44
- ],
- [
- 41,
- -12
- ]
- ],
- [
- [
- 14538,
- 16041
- ],
- [
- -36,
- -50
- ],
- [
- -25,
- -86
- ],
- [
- 22,
- -68
- ]
- ],
- [
- [
- 14499,
- 15837
- ],
- [
- -60,
- 16
- ],
- [
- -71,
- -38
- ]
- ],
- [
- [
- 14368,
- 15815
- ],
- [
- -1,
- -60
- ],
- [
- -63,
- -11
- ],
- [
- -49,
- 42
- ],
- [
- -56,
- -33
- ],
- [
- -52,
- 3
- ]
- ],
- [
- [
- 14147,
- 15756
- ],
- [
- -4,
- 80
- ],
- [
- -35,
- 38
- ]
- ],
- [
- [
- 14108,
- 15874
- ],
- [
- 11,
- 17
- ],
- [
- -7,
- 15
- ],
- [
- 11,
- 38
- ],
- [
- 27,
- 37
- ],
- [
- -34,
- 52
- ],
- [
- -6,
- 44
- ],
- [
- 17,
- 27
- ]
- ],
- [
- [
- 7143,
- 13648
- ],
- [
- -17,
- -6
- ],
- [
- -18,
- 69
- ],
- [
- -26,
- 35
- ],
- [
- 15,
- 76
- ],
- [
- 21,
- -5
- ],
- [
- 24,
- -100
- ],
- [
- 1,
- -69
- ]
- ],
- [
- [
- 7123,
- 13986
- ],
- [
- -76,
- -19
- ],
- [
- -5,
- 44
- ],
- [
- 33,
- 10
- ],
- [
- 46,
- -4
- ],
- [
- 2,
- -31
- ]
- ],
- [
- [
- 7180,
- 13987
- ],
- [
- -12,
- -85
- ],
- [
- -13,
- 15
- ],
- [
- 1,
- 63
- ],
- [
- -31,
- 47
- ],
- [
- 0,
- 14
- ],
- [
- 55,
- -54
- ]
- ],
- [
- [
- 13887,
- 16019
- ],
- [
- -13,
- -11
- ],
- [
- -23,
- -28
- ],
- [
- -10,
- -66
- ]
- ],
- [
- [
- 13841,
- 15914
- ],
- [
- -61,
- 45
- ],
- [
- -27,
- 50
- ],
- [
- -26,
- 27
- ],
- [
- -32,
- 45
- ],
- [
- -15,
- 37
- ],
- [
- -35,
- 56
- ],
- [
- 15,
- 50
- ],
- [
- 25,
- -28
- ],
- [
- 15,
- 25
- ],
- [
- 33,
- 3
- ],
- [
- 60,
- -20
- ],
- [
- 48,
- 2
- ],
- [
- 31,
- -27
- ]
- ],
- [
- [
- 13872,
- 16179
- ],
- [
- 26,
- 0
- ],
- [
- -18,
- -52
- ],
- [
- 34,
- -47
- ],
- [
- -10,
- -56
- ],
- [
- -17,
- -5
- ]
- ],
- [
- [
- 14185,
- 17265
- ],
- [
- 67,
- -1
- ],
- [
- 76,
- 45
- ],
- [
- 16,
- 68
- ],
- [
- 57,
- 39
- ],
- [
- -7,
- 53
- ]
- ],
- [
- [
- 14394,
- 17469
- ],
- [
- 43,
- 20
- ],
- [
- 75,
- 47
- ]
- ],
- [
- [
- 14512,
- 17536
- ],
- [
- 73,
- -30
- ],
- [
- 10,
- -30
- ],
- [
- 37,
- 14
- ],
- [
- 68,
- -28
- ],
- [
- 6,
- -57
- ],
- [
- -14,
- -32
- ],
- [
- 43,
- -79
- ],
- [
- 29,
- -22
- ],
- [
- -5,
- -21
- ],
- [
- 47,
- -21
- ],
- [
- 21,
- -32
- ],
- [
- -28,
- -27
- ],
- [
- -56,
- 5
- ],
- [
- -13,
- -12
- ],
- [
- 16,
- -39
- ],
- [
- 17,
- -77
- ]
- ],
- [
- [
- 14763,
- 17048
- ],
- [
- -60,
- -7
- ],
- [
- -21,
- -27
- ],
- [
- -5,
- -60
- ],
- [
- -27,
- 12
- ],
- [
- -63,
- -6
- ],
- [
- -18,
- 28
- ],
- [
- -27,
- -21
- ],
- [
- -26,
- 17
- ],
- [
- -55,
- 3
- ],
- [
- -78,
- 28
- ],
- [
- -70,
- 10
- ],
- [
- -54,
- -3
- ],
- [
- -38,
- -32
- ],
- [
- -33,
- -5
- ]
- ],
- [
- [
- 14188,
- 16985
- ],
- [
- -2,
- 53
- ],
- [
- -21,
- 56
- ],
- [
- 42,
- 24
- ],
- [
- 0,
- 48
- ],
- [
- -19,
- 46
- ],
- [
- -3,
- 53
- ]
- ],
- [
- [
- 6333,
- 12934
- ],
- [
- 0,
- 17
- ],
- [
- 8,
- 6
- ],
- [
- 13,
- -14
- ],
- [
- 25,
- 72
- ],
- [
- 13,
- 2
- ]
- ],
- [
- [
- 6392,
- 13017
- ],
- [
- 1,
- -18
- ],
- [
- 13,
- -1
- ],
- [
- -1,
- -32
- ],
- [
- -12,
- -52
- ],
- [
- 6,
- -19
- ],
- [
- -7,
- -43
- ],
- [
- 4,
- -11
- ],
- [
- -8,
- -61
- ],
- [
- -13,
- -31
- ],
- [
- -13,
- -4
- ],
- [
- -14,
- -42
- ]
- ],
- [
- [
- 6348,
- 12703
- ],
- [
- -21,
- 0
- ],
- [
- 6,
- 136
- ],
- [
- 0,
- 95
- ]
- ],
- [
- [
- 7870,
- 8070
- ],
- [
- -51,
- -17
- ],
- [
- -27,
- 166
- ],
- [
- -37,
- 134
- ],
- [
- 22,
- 116
- ],
- [
- -37,
- 51
- ],
- [
- -9,
- 87
- ],
- [
- -35,
- 81
- ]
- ],
- [
- [
- 7696,
- 8688
- ],
- [
- 44,
- 130
- ],
- [
- -30,
- 100
- ],
- [
- 16,
- 41
- ],
- [
- -12,
- 44
- ],
- [
- 27,
- 60
- ],
- [
- 2,
- 102
- ],
- [
- 3,
- 85
- ],
- [
- 15,
- 40
- ],
- [
- -60,
- 193
- ]
- ],
- [
- [
- 7701,
- 9483
- ],
- [
- 52,
- -10
- ],
- [
- 35,
- 3
- ],
- [
- 16,
- 36
- ],
- [
- 61,
- 49
- ],
- [
- 37,
- 45
- ],
- [
- 91,
- 20
- ],
- [
- -8,
- -90
- ],
- [
- 9,
- -46
- ],
- [
- -6,
- -80
- ],
- [
- 76,
- -108
- ],
- [
- 78,
- -20
- ],
- [
- 28,
- -44
- ],
- [
- 47,
- -24
- ],
- [
- 29,
- -35
- ],
- [
- 43,
- 1
- ],
- [
- 41,
- -35
- ],
- [
- 3,
- -70
- ],
- [
- 14,
- -35
- ],
- [
- 0,
- -52
- ],
- [
- -20,
- -2
- ],
- [
- 27,
- -139
- ],
- [
- 134,
- -5
- ],
- [
- -11,
- -70
- ],
- [
- 8,
- -47
- ],
- [
- 38,
- -34
- ],
- [
- 16,
- -74
- ],
- [
- -12,
- -95
- ],
- [
- -19,
- -52
- ],
- [
- 7,
- -69
- ],
- [
- -22,
- -24
- ]
- ],
- [
- [
- 8493,
- 8377
- ],
- [
- -1,
- 37
- ],
- [
- -65,
- 61
- ],
- [
- -65,
- 2
- ],
- [
- -122,
- -35
- ],
- [
- -33,
- -106
- ],
- [
- -2,
- -64
- ],
- [
- -27,
- -144
- ]
- ],
- [
- [
- 8740,
- 7709
- ],
- [
- 13,
- 70
- ],
- [
- 10,
- 70
- ],
- [
- 0,
- 66
- ],
- [
- -25,
- 22
- ],
- [
- -26,
- -19
- ],
- [
- -26,
- 5
- ],
- [
- -9,
- 46
- ],
- [
- -6,
- 110
- ],
- [
- -13,
- 36
- ],
- [
- -47,
- 33
- ],
- [
- -29,
- -24
- ],
- [
- -73,
- 23
- ],
- [
- 4,
- 163
- ],
- [
- -20,
- 67
- ]
- ],
- [
- [
- 7701,
- 9483
- ],
- [
- -40,
- -20
- ],
- [
- -31,
- 13
- ],
- [
- 4,
- 183
- ],
- [
- -57,
- -71
- ],
- [
- -61,
- 3
- ],
- [
- -27,
- 64
- ],
- [
- -46,
- 7
- ],
- [
- 15,
- 52
- ],
- [
- -39,
- 73
- ],
- [
- -29,
- 108
- ],
- [
- 18,
- 22
- ],
- [
- 0,
- 50
- ],
- [
- 42,
- 35
- ],
- [
- -7,
- 65
- ],
- [
- 18,
- 41
- ],
- [
- 5,
- 56
- ],
- [
- 80,
- 82
- ],
- [
- 57,
- 23
- ],
- [
- 10,
- 18
- ],
- [
- 62,
- -5
- ]
- ],
- [
- [
- 7675,
- 10282
- ],
- [
- 32,
- 328
- ],
- [
- 1,
- 53
- ],
- [
- -11,
- 68
- ],
- [
- -31,
- 44
- ],
- [
- 1,
- 87
- ],
- [
- 39,
- 20
- ],
- [
- 14,
- -13
- ],
- [
- 2,
- 46
- ],
- [
- -40,
- 13
- ],
- [
- -1,
- 75
- ],
- [
- 135,
- -3
- ],
- [
- 24,
- 42
- ],
- [
- 19,
- -38
- ],
- [
- 14,
- -71
- ],
- [
- 13,
- 15
- ]
- ],
- [
- [
- 7886,
- 10948
- ],
- [
- 38,
- -64
- ],
- [
- 54,
- 8
- ],
- [
- 14,
- 37
- ],
- [
- 52,
- 28
- ],
- [
- 28,
- 19
- ],
- [
- 8,
- 51
- ],
- [
- 50,
- 34
- ],
- [
- -4,
- 25
- ],
- [
- -59,
- 11
- ],
- [
- -9,
- 75
- ],
- [
- 2,
- 81
- ],
- [
- -31,
- 31
- ],
- [
- 13,
- 11
- ],
- [
- 52,
- -15
- ],
- [
- 55,
- -30
- ],
- [
- 21,
- 28
- ],
- [
- 50,
- 19
- ],
- [
- 78,
- 44
- ],
- [
- 25,
- 46
- ],
- [
- -9,
- 34
- ]
- ],
- [
- [
- 8314,
- 11421
- ],
- [
- 36,
- 5
- ],
- [
- 16,
- -27
- ],
- [
- -9,
- -53
- ],
- [
- 24,
- -18
- ],
- [
- 16,
- -56
- ],
- [
- -19,
- -42
- ],
- [
- -11,
- -102
- ],
- [
- 18,
- -61
- ],
- [
- 5,
- -55
- ],
- [
- 43,
- -57
- ],
- [
- 34,
- -6
- ],
- [
- 7,
- 24
- ],
- [
- 23,
- 5
- ],
- [
- 31,
- 21
- ],
- [
- 23,
- 32
- ],
- [
- 38,
- -10
- ],
- [
- 17,
- 4
- ]
- ],
- [
- [
- 8606,
- 11025
- ],
- [
- 38,
- -10
- ],
- [
- 6,
- 25
- ],
- [
- -11,
- 24
- ],
- [
- 7,
- 34
- ],
- [
- 28,
- -10
- ],
- [
- 33,
- 12
- ],
- [
- 40,
- -25
- ]
- ],
- [
- [
- 8747,
- 11075
- ],
- [
- 30,
- -25
- ],
- [
- 22,
- 32
- ],
- [
- 15,
- -5
- ],
- [
- 10,
- -33
- ],
- [
- 33,
- 8
- ],
- [
- 27,
- 46
- ],
- [
- 21,
- 88
- ],
- [
- 42,
- 110
- ]
- ],
- [
- [
- 8947,
- 11296
- ],
- [
- 23,
- 5
- ],
- [
- 18,
- -66
- ],
- [
- 39,
- -210
- ],
- [
- 37,
- -19
- ],
- [
- 2,
- -83
- ],
- [
- -53,
- -99
- ],
- [
- 22,
- -36
- ],
- [
- 123,
- -19
- ],
- [
- 3,
- -120
- ],
- [
- 53,
- 78
- ],
- [
- 87,
- -43
- ],
- [
- 116,
- -73
- ],
- [
- 34,
- -70
- ],
- [
- -11,
- -67
- ],
- [
- 81,
- 37
- ],
- [
- 136,
- -63
- ],
- [
- 104,
- 5
- ],
- [
- 103,
- -100
- ],
- [
- 89,
- -134
- ],
- [
- 53,
- -35
- ],
- [
- 60,
- -5
- ],
- [
- 25,
- -37
- ],
- [
- 24,
- -153
- ],
- [
- 12,
- -73
- ],
- [
- -28,
- -198
- ],
- [
- -36,
- -78
- ],
- [
- -98,
- -167
- ],
- [
- -44,
- -136
- ],
- [
- -52,
- -104
- ],
- [
- -17,
- -2
- ],
- [
- -20,
- -89
- ],
- [
- 5,
- -224
- ],
- [
- -19,
- -185
- ],
- [
- -8,
- -79
- ],
- [
- -22,
- -48
- ],
- [
- -12,
- -160
- ],
- [
- -71,
- -157
- ],
- [
- -12,
- -124
- ],
- [
- -56,
- -52
- ],
- [
- -16,
- -71
- ],
- [
- -76,
- 0
- ],
- [
- -110,
- -46
- ],
- [
- -49,
- -54
- ],
- [
- -78,
- -35
- ],
- [
- -82,
- -95
- ],
- [
- -59,
- -119
- ],
- [
- -10,
- -90
- ],
- [
- 11,
- -66
- ],
- [
- -13,
- -121
- ],
- [
- -15,
- -59
- ],
- [
- -49,
- -66
- ],
- [
- -77,
- -211
- ],
- [
- -62,
- -95
- ],
- [
- -47,
- -56
- ],
- [
- -32,
- -114
- ],
- [
- -46,
- -69
- ]
- ],
- [
- [
- 8827,
- 6746
- ],
- [
- -19,
- 68
- ],
- [
- 30,
- 57
- ],
- [
- -40,
- 82
- ],
- [
- -55,
- 66
- ],
- [
- -71,
- 77
- ],
- [
- -26,
- -4
- ],
- [
- -70,
- 93
- ],
- [
- -45,
- -13
- ]
- ],
- [
- [
- 20508,
- 11340
- ],
- [
- 28,
- 45
- ],
- [
- 59,
- 66
- ]
- ],
- [
- [
- 20595,
- 11451
- ],
- [
- -3,
- -59
- ],
- [
- -4,
- -77
- ],
- [
- -33,
- 4
- ],
- [
- -15,
- -41
- ],
- [
- -32,
- 62
- ]
- ],
- [
- [
- 18940,
- 14129
- ],
- [
- 28,
- -38
- ],
- [
- -5,
- -74
- ],
- [
- -57,
- -4
- ],
- [
- -59,
- 8
- ],
- [
- -44,
- -18
- ],
- [
- -63,
- 45
- ],
- [
- -1,
- 24
- ]
- ],
- [
- [
- 18739,
- 14072
- ],
- [
- 46,
- 89
- ],
- [
- 37,
- 31
- ],
- [
- 50,
- -28
- ],
- [
- 37,
- -3
- ],
- [
- 31,
- -32
- ]
- ],
- [
- [
- 14599,
- 8147
- ],
- [
- -98,
- -88
- ],
- [
- -63,
- -90
- ],
- [
- -23,
- -80
- ],
- [
- -21,
- -45
- ],
- [
- -38,
- -10
- ],
- [
- -12,
- -57
- ],
- [
- -7,
- -37
- ],
- [
- -45,
- -28
- ],
- [
- -57,
- 6
- ],
- [
- -33,
- 33
- ],
- [
- -29,
- 15
- ],
- [
- -34,
- -28
- ],
- [
- -18,
- -58
- ],
- [
- -33,
- -36
- ],
- [
- -34,
- -53
- ],
- [
- -50,
- -12
- ],
- [
- -16,
- 42
- ],
- [
- 7,
- 73
- ],
- [
- -42,
- 114
- ],
- [
- -19,
- 18
- ]
- ],
- [
- [
- 13934,
- 7826
- ],
- [
- 0,
- 350
- ],
- [
- 69,
- 4
- ],
- [
- 2,
- 427
- ],
- [
- 52,
- 4
- ],
- [
- 108,
- 42
- ],
- [
- 26,
- -49
- ],
- [
- 45,
- 47
- ],
- [
- 21,
- 0
- ],
- [
- 39,
- 27
- ]
- ],
- [
- [
- 14296,
- 8678
- ],
- [
- 13,
- -9
- ]
- ],
- [
- [
- 14309,
- 8669
- ],
- [
- 26,
- -96
- ],
- [
- 14,
- -21
- ],
- [
- 22,
- -69
- ],
- [
- 79,
- -132
- ],
- [
- 30,
- -13
- ],
- [
- 0,
- -42
- ],
- [
- 21,
- -76
- ],
- [
- 54,
- -19
- ],
- [
- 44,
- -54
- ]
- ],
- [
- [
- 13613,
- 11688
- ],
- [
- 57,
- 9
- ],
- [
- 13,
- 30
- ],
- [
- 12,
- -2
- ],
- [
- 17,
- -27
- ],
- [
- 88,
- 46
- ],
- [
- 29,
- 47
- ],
- [
- 37,
- 42
- ],
- [
- -7,
- 42
- ],
- [
- 20,
- 11
- ],
- [
- 67,
- -8
- ],
- [
- 65,
- 56
- ],
- [
- 51,
- 131
- ],
- [
- 35,
- 48
- ],
- [
- 44,
- 21
- ]
- ],
- [
- [
- 14141,
- 12134
- ],
- [
- 8,
- -51
- ],
- [
- 40,
- -75
- ],
- [
- 1,
- -49
- ],
- [
- -12,
- -50
- ],
- [
- 5,
- -38
- ],
- [
- 24,
- -34
- ],
- [
- 53,
- -53
- ]
- ],
- [
- [
- 14260,
- 11784
- ],
- [
- 38,
- -48
- ],
- [
- 1,
- -39
- ],
- [
- 47,
- -63
- ],
- [
- 29,
- -51
- ],
- [
- 17,
- -72
- ],
- [
- 53,
- -48
- ],
- [
- 11,
- -38
- ]
- ],
- [
- [
- 14456,
- 11425
- ],
- [
- -23,
- -13
- ],
- [
- -45,
- 3
- ],
- [
- -52,
- 13
- ],
- [
- -26,
- -11
- ],
- [
- -11,
- -29
- ],
- [
- -22,
- -3
- ],
- [
- -28,
- 25
- ],
- [
- -77,
- -60
- ],
- [
- -32,
- 12
- ],
- [
- -10,
- -9
- ],
- [
- -21,
- -72
- ],
- [
- -52,
- 23
- ],
- [
- -51,
- 12
- ],
- [
- -44,
- 44
- ],
- [
- -57,
- 41
- ],
- [
- -38,
- -39
- ],
- [
- -27,
- -61
- ],
- [
- -6,
- -83
- ]
- ],
- [
- [
- 13834,
- 11218
- ],
- [
- -45,
- 6
- ],
- [
- -47,
- 20
- ],
- [
- -42,
- -63
- ],
- [
- -36,
- -112
- ]
- ],
- [
- [
- 13664,
- 11069
- ],
- [
- -8,
- 35
- ],
- [
- -3,
- 55
- ],
- [
- -32,
- 38
- ],
- [
- -25,
- 62
- ],
- [
- -6,
- 43
- ],
- [
- -33,
- 63
- ],
- [
- 5,
- 36
- ],
- [
- -7,
- 50
- ],
- [
- 6,
- 93
- ],
- [
- 17,
- 22
- ],
- [
- 35,
- 122
- ]
- ],
- [
- [
- 8110,
- 16382
- ],
- [
- 50,
- -16
- ],
- [
- 65,
- 3
- ],
- [
- -35,
- -49
- ],
- [
- -25,
- -8
- ],
- [
- -89,
- 51
- ],
- [
- -17,
- 40
- ],
- [
- 26,
- 37
- ],
- [
- 25,
- -58
- ]
- ],
- [
- [
- 8239,
- 16688
- ],
- [
- -34,
- -2
- ],
- [
- -90,
- 38
- ],
- [
- -65,
- 56
- ],
- [
- 24,
- 10
- ],
- [
- 92,
- -30
- ],
- [
- 71,
- -50
- ],
- [
- 2,
- -22
- ]
- ],
- [
- [
- 3938,
- 16617
- ],
- [
- -35,
- -17
- ],
- [
- -115,
- 55
- ],
- [
- -21,
- 42
- ],
- [
- -62,
- 42
- ],
- [
- -13,
- 34
- ],
- [
- -71,
- 22
- ],
- [
- -27,
- 65
- ],
- [
- 6,
- 28
- ],
- [
- 73,
- -26
- ],
- [
- 43,
- -18
- ],
- [
- 65,
- -13
- ],
- [
- 24,
- -41
- ],
- [
- 34,
- -57
- ],
- [
- 70,
- -50
- ],
- [
- 29,
- -66
- ]
- ],
- [
- [
- 8634,
- 16878
- ],
- [
- -46,
- -105
- ],
- [
- 46,
- 41
- ],
- [
- 47,
- -26
- ],
- [
- -25,
- -42
- ],
- [
- 62,
- -33
- ],
- [
- 32,
- 29
- ],
- [
- 70,
- -36
- ],
- [
- -22,
- -88
- ],
- [
- 49,
- 20
- ],
- [
- 9,
- -63
- ],
- [
- 21,
- -75
- ],
- [
- -29,
- -106
- ],
- [
- -31,
- -4
- ],
- [
- -46,
- 23
- ],
- [
- 15,
- 98
- ],
- [
- -20,
- 15
- ],
- [
- -80,
- -104
- ],
- [
- -42,
- 4
- ],
- [
- 49,
- 56
- ],
- [
- -67,
- 30
- ],
- [
- -75,
- -8
- ],
- [
- -135,
- 4
- ],
- [
- -11,
- 36
- ],
- [
- 44,
- 42
- ],
- [
- -30,
- 32
- ],
- [
- 58,
- 73
- ],
- [
- 72,
- 191
- ],
- [
- 43,
- 68
- ],
- [
- 61,
- 41
- ],
- [
- 32,
- -5
- ],
- [
- -13,
- -32
- ],
- [
- -38,
- -76
- ]
- ],
- [
- [
- 3264,
- 17296
- ],
- [
- 33,
- -16
- ],
- [
- 66,
- 10
- ],
- [
- -20,
- -136
- ],
- [
- 60,
- -97
- ],
- [
- -28,
- 0
- ],
- [
- -42,
- 55
- ],
- [
- -25,
- 56
- ],
- [
- -36,
- 37
- ],
- [
- -12,
- 53
- ],
- [
- 4,
- 38
- ]
- ],
- [
- [
- 7022,
- 18254
- ],
- [
- -27,
- -63
- ],
- [
- -31,
- 10
- ],
- [
- -18,
- 36
- ],
- [
- 3,
- 9
- ],
- [
- 27,
- 36
- ],
- [
- 28,
- -3
- ],
- [
- 18,
- -25
- ]
- ],
- [
- [
- 6839,
- 18321
- ],
- [
- -82,
- -67
- ],
- [
- -49,
- 3
- ],
- [
- -16,
- 33
- ],
- [
- 52,
- 55
- ],
- [
- 96,
- -1
- ],
- [
- -1,
- -23
- ]
- ],
- [
- [
- 6611,
- 18674
- ],
- [
- 13,
- -53
- ],
- [
- 36,
- 19
- ],
- [
- 40,
- -32
- ],
- [
- 77,
- -41
- ],
- [
- 79,
- -37
- ],
- [
- 7,
- -57
- ],
- [
- 51,
- 9
- ],
- [
- 50,
- -40
- ],
- [
- -62,
- -37
- ],
- [
- -109,
- 28
- ],
- [
- -39,
- 54
- ],
- [
- -69,
- -63
- ],
- [
- -99,
- -62
- ],
- [
- -24,
- 70
- ],
- [
- -95,
- -12
- ],
- [
- 61,
- 59
- ],
- [
- 9,
- 95
- ],
- [
- 24,
- 110
- ],
- [
- 50,
- -10
- ]
- ],
- [
- [
- 7259,
- 18853
- ],
- [
- -78,
- -6
- ],
- [
- -18,
- 59
- ],
- [
- 30,
- 67
- ],
- [
- 64,
- 17
- ],
- [
- 54,
- -34
- ],
- [
- 1,
- -51
- ],
- [
- -8,
- -17
- ],
- [
- -45,
- -35
- ]
- ],
- [
- [
- 5880,
- 19088
- ],
- [
- -43,
- -42
- ],
- [
- -94,
- 36
- ],
- [
- -57,
- -13
- ],
- [
- -95,
- 54
- ],
- [
- 61,
- 37
- ],
- [
- 49,
- 52
- ],
- [
- 74,
- -34
- ],
- [
- 42,
- -21
- ],
- [
- 21,
- -23
- ],
- [
- 42,
- -46
- ]
- ],
- [
- [
- 3985,
- 16676
- ],
- [
- -10,
- 0
- ],
- [
- -135,
- 118
- ],
- [
- -50,
- 52
- ],
- [
- -126,
- 49
- ],
- [
- -39,
- 106
- ],
- [
- 10,
- 74
- ],
- [
- -89,
- 51
- ],
- [
- -12,
- 97
- ],
- [
- -84,
- 87
- ],
- [
- -2,
- 62
- ]
- ],
- [
- [
- 3448,
- 17372
- ],
- [
- 39,
- 58
- ],
- [
- -2,
- 75
- ],
- [
- -119,
- 77
- ],
- [
- -71,
- 137
- ],
- [
- -43,
- 86
- ],
- [
- -64,
- 54
- ],
- [
- -47,
- 49
- ],
- [
- -37,
- 62
- ],
- [
- -70,
- -39
- ],
- [
- -68,
- -67
- ],
- [
- -62,
- 79
- ],
- [
- -49,
- 52
- ],
- [
- -68,
- 34
- ],
- [
- -68,
- 3
- ],
- [
- 0,
- 683
- ],
- [
- 1,
- 445
- ]
- ],
- [
- [
- 2720,
- 19160
- ],
- [
- 130,
- -28
- ],
- [
- 109,
- -58
- ],
- [
- 73,
- -11
- ],
- [
- 61,
- 50
- ],
- [
- 85,
- 37
- ],
- [
- 103,
- -14
- ],
- [
- 105,
- 52
- ],
- [
- 114,
- 30
- ],
- [
- 48,
- -49
- ],
- [
- 52,
- 28
- ],
- [
- 15,
- 56
- ],
- [
- 48,
- -13
- ],
- [
- 118,
- -107
- ],
- [
- 93,
- 81
- ],
- [
- 9,
- -91
- ],
- [
- 86,
- 20
- ],
- [
- 26,
- 35
- ],
- [
- 85,
- -7
- ],
- [
- 106,
- -51
- ],
- [
- 164,
- -44
- ],
- [
- 96,
- -20
- ],
- [
- 68,
- 8
- ],
- [
- 94,
- -61
- ],
- [
- -98,
- -60
- ],
- [
- 126,
- -25
- ],
- [
- 188,
- 14
- ],
- [
- 59,
- 21
- ],
- [
- 75,
- -72
- ],
- [
- 75,
- 61
- ],
- [
- -71,
- 50
- ],
- [
- 45,
- 42
- ],
- [
- 85,
- 5
- ],
- [
- 56,
- 12
- ],
- [
- 56,
- -29
- ],
- [
- 70,
- -65
- ],
- [
- 78,
- 10
- ],
- [
- 123,
- -54
- ],
- [
- 109,
- 19
- ],
- [
- 101,
- -3
- ],
- [
- -8,
- 75
- ],
- [
- 62,
- 20
- ],
- [
- 108,
- -40
- ],
- [
- 0,
- -114
- ],
- [
- 44,
- 96
- ],
- [
- 56,
- -3
- ],
- [
- 32,
- 120
- ],
- [
- -75,
- 74
- ],
- [
- -81,
- 49
- ],
- [
- 5,
- 132
- ],
- [
- 83,
- 87
- ],
- [
- 92,
- -19
- ],
- [
- 70,
- -53
- ],
- [
- 95,
- -135
- ],
- [
- -62,
- -59
- ],
- [
- 130,
- -24
- ],
- [
- -1,
- -123
- ],
- [
- 93,
- 94
- ],
- [
- 84,
- -77
- ],
- [
- -21,
- -89
- ],
- [
- 67,
- -81
- ],
- [
- 73,
- 87
- ],
- [
- 51,
- 103
- ],
- [
- 4,
- 132
- ],
- [
- 99,
- -9
- ],
- [
- 103,
- -18
- ],
- [
- 94,
- -60
- ],
- [
- 4,
- -59
- ],
- [
- -52,
- -64
- ],
- [
- 49,
- -64
- ],
- [
- -9,
- -59
- ],
- [
- -136,
- -83
- ],
- [
- -97,
- -19
- ],
- [
- -72,
- 36
- ],
- [
- -21,
- -60
- ],
- [
- -67,
- -101
- ],
- [
- -21,
- -53
- ],
- [
- -80,
- -81
- ],
- [
- -100,
- -8
- ],
- [
- -55,
- -51
- ],
- [
- -5,
- -78
- ],
- [
- -81,
- -15
- ],
- [
- -85,
- -97
- ],
- [
- -76,
- -135
- ],
- [
- -27,
- -94
- ],
- [
- -4,
- -140
- ],
- [
- 103,
- -20
- ],
- [
- 31,
- -112
- ],
- [
- 33,
- -91
- ],
- [
- 97,
- 24
- ],
- [
- 130,
- -52
- ],
- [
- 69,
- -46
- ],
- [
- 50,
- -57
- ],
- [
- 88,
- -33
- ],
- [
- 73,
- -50
- ],
- [
- 116,
- -7
- ],
- [
- 75,
- -12
- ],
- [
- -11,
- -104
- ],
- [
- 22,
- -120
- ],
- [
- 50,
- -134
- ],
- [
- 104,
- -114
- ],
- [
- 54,
- 39
- ],
- [
- 37,
- 123
- ],
- [
- -36,
- 189
- ],
- [
- -49,
- 64
- ],
- [
- 111,
- 56
- ],
- [
- 79,
- 84
- ],
- [
- 39,
- 84
- ],
- [
- -6,
- 80
- ],
- [
- -47,
- 102
- ],
- [
- -85,
- 90
- ],
- [
- 82,
- 126
- ],
- [
- -30,
- 108
- ],
- [
- -23,
- 188
- ],
- [
- 48,
- 27
- ],
- [
- 120,
- -32
- ],
- [
- 72,
- -12
- ],
- [
- 57,
- 32
- ],
- [
- 65,
- -41
- ],
- [
- 86,
- -70
- ],
- [
- 21,
- -46
- ],
- [
- 124,
- -9
- ],
- [
- -2,
- -101
- ],
- [
- 24,
- -152
- ],
- [
- 63,
- -19
- ],
- [
- 51,
- -70
- ],
- [
- 101,
- 66
- ],
- [
- 66,
- 133
- ],
- [
- 46,
- 56
- ],
- [
- 55,
- -108
- ],
- [
- 91,
- -153
- ],
- [
- 77,
- -143
- ],
- [
- -28,
- -76
- ],
- [
- 92,
- -67
- ],
- [
- 63,
- -69
- ],
- [
- 111,
- -31
- ],
- [
- 45,
- -38
- ],
- [
- 28,
- -102
- ],
- [
- 54,
- -16
- ],
- [
- 28,
- -45
- ],
- [
- 5,
- -135
- ],
- [
- -51,
- -45
- ],
- [
- -50,
- -42
- ],
- [
- -115,
- -43
- ],
- [
- -87,
- -98
- ],
- [
- -118,
- -20
- ],
- [
- -149,
- 26
- ],
- [
- -105,
- 0
- ],
- [
- -72,
- -8
- ],
- [
- -58,
- -86
- ],
- [
- -89,
- -53
- ],
- [
- -101,
- -159
- ],
- [
- -80,
- -111
- ],
- [
- 59,
- 20
- ],
- [
- 112,
- 158
- ],
- [
- 146,
- 100
- ],
- [
- 105,
- 12
- ],
- [
- 61,
- -59
- ],
- [
- -66,
- -81
- ],
- [
- 23,
- -129
- ],
- [
- 22,
- -91
- ],
- [
- 91,
- -60
- ],
- [
- 115,
- 18
- ],
- [
- 70,
- 135
- ],
- [
- 5,
- -87
- ],
- [
- 45,
- -44
- ],
- [
- -86,
- -78
- ],
- [
- -155,
- -72
- ],
- [
- -69,
- -48
- ],
- [
- -78,
- -87
- ],
- [
- -53,
- 9
- ],
- [
- -3,
- 102
- ],
- [
- 122,
- 99
- ],
- [
- -112,
- -4
- ],
- [
- -78,
- -15
- ]
- ],
- [
- [
- 7867,
- 16212
- ],
- [
- -45,
- 68
- ],
- [
- 0,
- 164
- ],
- [
- -31,
- 34
- ],
- [
- -47,
- -20
- ],
- [
- -23,
- 31
- ],
- [
- -53,
- -90
- ],
- [
- -21,
- -93
- ],
- [
- -25,
- -55
- ],
- [
- -30,
- -19
- ],
- [
- -22,
- -6
- ],
- [
- -7,
- -29
- ],
- [
- -128,
- 0
- ],
- [
- -106,
- -1
- ],
- [
- -32,
- -22
- ],
- [
- -73,
- -87
- ],
- [
- -9,
- -9
- ],
- [
- -22,
- -47
- ],
- [
- -64,
- 0
- ],
- [
- -69,
- 0
- ],
- [
- -31,
- -19
- ],
- [
- 11,
- -24
- ],
- [
- 6,
- -36
- ],
- [
- -1,
- -13
- ],
- [
- -91,
- -59
- ],
- [
- -72,
- -19
- ],
- [
- -81,
- -64
- ],
- [
- -18,
- 0
- ],
- [
- -23,
- 19
- ],
- [
- -8,
- 17
- ],
- [
- 1,
- 12
- ],
- [
- 16,
- 42
- ],
- [
- 32,
- 66
- ],
- [
- 21,
- 71
- ],
- [
- -14,
- 105
- ],
- [
- -15,
- 108
- ],
- [
- -73,
- 57
- ],
- [
- 9,
- 21
- ],
- [
- -10,
- 15
- ],
- [
- -19,
- 0
- ],
- [
- -14,
- 19
- ],
- [
- -4,
- 28
- ],
- [
- -13,
- -12
- ],
- [
- -19,
- 3
- ],
- [
- 4,
- 12
- ],
- [
- -16,
- 12
- ],
- [
- -7,
- 32
- ],
- [
- -54,
- 38
- ],
- [
- -57,
- 40
- ],
- [
- -68,
- 46
- ],
- [
- -65,
- 44
- ],
- [
- -63,
- -34
- ],
- [
- -22,
- -1
- ],
- [
- -86,
- 31
- ],
- [
- -57,
- -16
- ],
- [
- -67,
- 38
- ],
- [
- -71,
- 19
- ],
- [
- -49,
- 7
- ],
- [
- -22,
- 20
- ],
- [
- -12,
- 66
- ],
- [
- -24,
- 0
- ],
- [
- 0,
- -46
- ],
- [
- -144,
- 0
- ],
- [
- -239,
- 0
- ],
- [
- -237,
- 0
- ],
- [
- -209,
- 0
- ],
- [
- -209,
- 0
- ],
- [
- -206,
- 0
- ],
- [
- -212,
- 0
- ],
- [
- -69,
- 0
- ],
- [
- -207,
- 0
- ],
- [
- -197,
- 0
- ]
- ],
- [
- [
- 4589,
- 19569
- ],
- [
- -35,
- -56
- ],
- [
- 155,
- 37
- ],
- [
- 97,
- -61
- ],
- [
- 79,
- 61
- ],
- [
- 64,
- -39
- ],
- [
- 57,
- -118
- ],
- [
- 35,
- 50
- ],
- [
- -50,
- 123
- ],
- [
- 62,
- 17
- ],
- [
- 69,
- -19
- ],
- [
- 78,
- -48
- ],
- [
- 44,
- -117
- ],
- [
- 21,
- -85
- ],
- [
- 118,
- -59
- ],
- [
- 125,
- -57
- ],
- [
- -7,
- -53
- ],
- [
- -115,
- -9
- ],
- [
- 45,
- -47
- ],
- [
- -24,
- -44
- ],
- [
- -126,
- 19
- ],
- [
- -120,
- 33
- ],
- [
- -81,
- -8
- ],
- [
- -131,
- -40
- ],
- [
- -176,
- -18
- ],
- [
- -124,
- -12
- ],
- [
- -38,
- 57
- ],
- [
- -95,
- 33
- ],
- [
- -62,
- -14
- ],
- [
- -86,
- 95
- ],
- [
- 46,
- 13
- ],
- [
- 108,
- 20
- ],
- [
- 98,
- -5
- ],
- [
- 91,
- 21
- ],
- [
- -135,
- 28
- ],
- [
- -149,
- -10
- ],
- [
- -98,
- 3
- ],
- [
- -37,
- 44
- ],
- [
- 161,
- 48
- ],
- [
- -107,
- -2
- ],
- [
- -122,
- 32
- ],
- [
- 59,
- 90
- ],
- [
- 48,
- 48
- ],
- [
- 187,
- 73
- ],
- [
- 71,
- -24
- ]
- ],
- [
- [
- 5263,
- 19605
- ],
- [
- -61,
- -79
- ],
- [
- -109,
- 84
- ],
- [
- 24,
- 17
- ],
- [
- 93,
- 5
- ],
- [
- 53,
- -27
- ]
- ],
- [
- [
- 7226,
- 19567
- ],
- [
- 6,
- -33
- ],
- [
- -74,
- 4
- ],
- [
- -75,
- 2
- ],
- [
- -76,
- -16
- ],
- [
- -21,
- 7
- ],
- [
- -76,
- 64
- ],
- [
- 3,
- 43
- ],
- [
- 33,
- 8
- ],
- [
- 160,
- -13
- ],
- [
- 120,
- -66
- ]
- ],
- [
- [
- 6513,
- 19574
- ],
- [
- 55,
- -75
- ],
- [
- 65,
- 97
- ],
- [
- 176,
- 49
- ],
- [
- 120,
- -124
- ],
- [
- -10,
- -79
- ],
- [
- 138,
- 35
- ],
- [
- 65,
- 48
- ],
- [
- 155,
- -61
- ],
- [
- 96,
- -57
- ],
- [
- 9,
- -52
- ],
- [
- 130,
- 27
- ],
- [
- 72,
- -77
- ],
- [
- 169,
- -47
- ],
- [
- 60,
- -48
- ],
- [
- 66,
- -113
- ],
- [
- -128,
- -56
- ],
- [
- 164,
- -78
- ],
- [
- 111,
- -26
- ],
- [
- 100,
- -110
- ],
- [
- 110,
- -8
- ],
- [
- -22,
- -85
- ],
- [
- -122,
- -139
- ],
- [
- -86,
- 51
- ],
- [
- -110,
- 116
- ],
- [
- -90,
- -15
- ],
- [
- -9,
- -69
- ],
- [
- 74,
- -70
- ],
- [
- 94,
- -55
- ],
- [
- 29,
- -32
- ],
- [
- 46,
- -119
- ],
- [
- -25,
- -86
- ],
- [
- -87,
- 33
- ],
- [
- -175,
- 96
- ],
- [
- 98,
- -104
- ],
- [
- 73,
- -72
- ],
- [
- 11,
- -42
- ],
- [
- -189,
- 48
- ],
- [
- -149,
- 70
- ],
- [
- -85,
- 58
- ],
- [
- 24,
- 34
- ],
- [
- -104,
- 61
- ],
- [
- -101,
- 59
- ],
- [
- 1,
- -35
- ],
- [
- -202,
- -19
- ],
- [
- -59,
- 41
- ],
- [
- 46,
- 88
- ],
- [
- 131,
- 2
- ],
- [
- 144,
- 16
- ],
- [
- -23,
- 43
- ],
- [
- 24,
- 59
- ],
- [
- 90,
- 117
- ],
- [
- -19,
- 53
- ],
- [
- -27,
- 41
- ],
- [
- -107,
- 59
- ],
- [
- -141,
- 40
- ],
- [
- 45,
- 31
- ],
- [
- -74,
- 74
- ],
- [
- -62,
- 7
- ],
- [
- -54,
- 41
- ],
- [
- -38,
- -35
- ],
- [
- -126,
- -16
- ],
- [
- -254,
- 27
- ],
- [
- -147,
- 35
- ],
- [
- -113,
- 18
- ],
- [
- -58,
- 42
- ],
- [
- 73,
- 55
- ],
- [
- -99,
- 1
- ],
- [
- -23,
- 121
- ],
- [
- 54,
- 107
- ],
- [
- 72,
- 49
- ],
- [
- 180,
- 32
- ],
- [
- -52,
- -77
- ]
- ],
- [
- [
- 5552,
- 19656
- ],
- [
- 83,
- -25
- ],
- [
- 124,
- 15
- ],
- [
- 18,
- -35
- ],
- [
- -65,
- -57
- ],
- [
- 106,
- -52
- ],
- [
- -13,
- -108
- ],
- [
- -114,
- -46
- ],
- [
- -67,
- 10
- ],
- [
- -48,
- 46
- ],
- [
- -174,
- 92
- ],
- [
- 2,
- 39
- ],
- [
- 142,
- -15
- ],
- [
- -77,
- 78
- ],
- [
- 83,
- 58
- ]
- ],
- [
- [
- 6051,
- 19528
- ],
- [
- -75,
- -90
- ],
- [
- -79,
- 4
- ],
- [
- -44,
- 106
- ],
- [
- 1,
- 59
- ],
- [
- 37,
- 51
- ],
- [
- 69,
- 33
- ],
- [
- 145,
- -4
- ],
- [
- 133,
- -29
- ],
- [
- -104,
- -107
- ],
- [
- -83,
- -23
- ]
- ],
- [
- [
- 4150,
- 19361
- ],
- [
- -183,
- -58
- ],
- [
- -37,
- 53
- ],
- [
- -161,
- 63
- ],
- [
- 30,
- 51
- ],
- [
- 48,
- 88
- ],
- [
- 61,
- 78
- ],
- [
- -68,
- 74
- ],
- [
- 235,
- 19
- ],
- [
- 100,
- -25
- ],
- [
- 178,
- -7
- ],
- [
- 68,
- -35
- ],
- [
- 74,
- -50
- ],
- [
- -87,
- -30
- ],
- [
- -171,
- -85
- ],
- [
- -87,
- -84
- ],
- [
- 0,
- -52
- ]
- ],
- [
- [
- 6022,
- 19792
- ],
- [
- -38,
- -46
- ],
- [
- -101,
- 9
- ],
- [
- -85,
- 31
- ],
- [
- 37,
- 54
- ],
- [
- 101,
- 32
- ],
- [
- 60,
- -42
- ],
- [
- 26,
- -38
- ]
- ],
- [
- [
- 5681,
- 20001
- ],
- [
- 54,
- -55
- ],
- [
- 2,
- -62
- ],
- [
- -32,
- -89
- ],
- [
- -115,
- -12
- ],
- [
- -75,
- 19
- ],
- [
- 2,
- 70
- ],
- [
- -115,
- -10
- ],
- [
- -4,
- 93
- ],
- [
- 75,
- -4
- ],
- [
- 105,
- 41
- ],
- [
- 98,
- -7
- ],
- [
- 5,
- 16
- ]
- ],
- [
- [
- 5004,
- 19939
- ],
- [
- 28,
- -43
- ],
- [
- 62,
- 20
- ],
- [
- 73,
- -5
- ],
- [
- 12,
- -59
- ],
- [
- -42,
- -57
- ],
- [
- -237,
- -18
- ],
- [
- -175,
- -52
- ],
- [
- -106,
- -3
- ],
- [
- -9,
- 39
- ],
- [
- 145,
- 53
- ],
- [
- -315,
- -14
- ],
- [
- -98,
- 22
- ],
- [
- 95,
- 117
- ],
- [
- 66,
- 33
- ],
- [
- 196,
- -40
- ],
- [
- 124,
- -71
- ],
- [
- 122,
- -9
- ],
- [
- -100,
- 114
- ],
- [
- 64,
- 44
- ],
- [
- 72,
- -14
- ],
- [
- 23,
- -57
- ]
- ],
- [
- [
- 5947,
- 20047
- ],
- [
- 78,
- -39
- ],
- [
- 137,
- 0
- ],
- [
- 60,
- -39
- ],
- [
- -16,
- -45
- ],
- [
- 80,
- -27
- ],
- [
- 44,
- -29
- ],
- [
- 94,
- -5
- ],
- [
- 102,
- -10
- ],
- [
- 111,
- 26
- ],
- [
- 142,
- 10
- ],
- [
- 113,
- -8
- ],
- [
- 75,
- -46
- ],
- [
- 15,
- -49
- ],
- [
- -43,
- -32
- ],
- [
- -104,
- -26
- ],
- [
- -89,
- 15
- ],
- [
- -200,
- -19
- ],
- [
- -143,
- -2
- ],
- [
- -113,
- 15
- ],
- [
- -185,
- 38
- ],
- [
- -24,
- 66
- ],
- [
- -9,
- 60
- ],
- [
- -70,
- 52
- ],
- [
- -144,
- 15
- ],
- [
- -81,
- 37
- ],
- [
- 27,
- 49
- ],
- [
- 143,
- -7
- ]
- ],
- [
- [
- 4447,
- 20112
- ],
- [
- -9,
- -92
- ],
- [
- -54,
- -42
- ],
- [
- -65,
- -5
- ],
- [
- -129,
- -52
- ],
- [
- -112,
- -18
- ],
- [
- -95,
- 26
- ],
- [
- 119,
- 90
- ],
- [
- 143,
- 77
- ],
- [
- 107,
- -1
- ],
- [
- 95,
- 17
- ]
- ],
- [
- [
- 6006,
- 20097
- ],
- [
- -32,
- -3
- ],
- [
- -130,
- 7
- ],
- [
- -19,
- 34
- ],
- [
- 140,
- -2
- ],
- [
- 49,
- -22
- ],
- [
- -8,
- -14
- ]
- ],
- [
- [
- 4867,
- 20118
- ],
- [
- -130,
- -34
- ],
- [
- -104,
- 39
- ],
- [
- 57,
- 38
- ],
- [
- 101,
- 12
- ],
- [
- 99,
- -19
- ],
- [
- -23,
- -36
- ]
- ],
- [
- [
- 4903,
- 20227
- ],
- [
- -85,
- -23
- ],
- [
- -116,
- 0
- ],
- [
- 2,
- 17
- ],
- [
- 71,
- 36
- ],
- [
- 37,
- -6
- ],
- [
- 91,
- -24
- ]
- ],
- [
- [
- 5867,
- 20162
- ],
- [
- -103,
- -25
- ],
- [
- -57,
- 28
- ],
- [
- -29,
- 45
- ],
- [
- -6,
- 49
- ],
- [
- 90,
- -4
- ],
- [
- 41,
- -8
- ],
- [
- 83,
- -42
- ],
- [
- -19,
- -43
- ]
- ],
- [
- [
- 5572,
- 20194
- ],
- [
- 28,
- -50
- ],
- [
- -114,
- 13
- ],
- [
- -115,
- 39
- ],
- [
- -155,
- 4
- ],
- [
- 67,
- 36
- ],
- [
- -84,
- 29
- ],
- [
- -5,
- 46
- ],
- [
- 137,
- -16
- ],
- [
- 188,
- -44
- ],
- [
- 53,
- -57
- ]
- ],
- [
- [
- 6481,
- 20354
- ],
- [
- 85,
- -39
- ],
- [
- -96,
- -36
- ],
- [
- -129,
- -90
- ],
- [
- -123,
- -8
- ],
- [
- -145,
- 15
- ],
- [
- -75,
- 49
- ],
- [
- 1,
- 43
- ],
- [
- 56,
- 32
- ],
- [
- -128,
- -1
- ],
- [
- -77,
- 40
- ],
- [
- -44,
- 55
- ],
- [
- 48,
- 53
- ],
- [
- 49,
- 37
- ],
- [
- 71,
- 8
- ],
- [
- -30,
- 27
- ],
- [
- 162,
- 7
- ],
- [
- 89,
- -65
- ],
- [
- 117,
- -25
- ],
- [
- 114,
- -23
- ],
- [
- 55,
- -79
- ]
- ],
- [
- [
- 7772,
- 20767
- ],
- [
- 187,
- -9
- ],
- [
- 149,
- -15
- ],
- [
- 128,
- -33
- ],
- [
- -3,
- -32
- ],
- [
- -170,
- -52
- ],
- [
- -169,
- -24
- ],
- [
- -63,
- -27
- ],
- [
- 152,
- 0
- ],
- [
- -165,
- -72
- ],
- [
- -113,
- -34
- ],
- [
- -119,
- -98
- ],
- [
- -144,
- -20
- ],
- [
- -45,
- -25
- ],
- [
- -211,
- -13
- ],
- [
- 96,
- -15
- ],
- [
- -48,
- -21
- ],
- [
- 58,
- -59
- ],
- [
- -66,
- -41
- ],
- [
- -108,
- -34
- ],
- [
- -33,
- -47
- ],
- [
- -97,
- -36
- ],
- [
- 9,
- -27
- ],
- [
- 119,
- 4
- ],
- [
- 2,
- -29
- ],
- [
- -186,
- -72
- ],
- [
- -182,
- 33
- ],
- [
- -205,
- -18
- ],
- [
- -104,
- 14
- ],
- [
- -132,
- 6
- ],
- [
- -8,
- 58
- ],
- [
- 128,
- 27
- ],
- [
- -34,
- 87
- ],
- [
- 43,
- 8
- ],
- [
- 186,
- -52
- ],
- [
- -95,
- 77
- ],
- [
- -113,
- 23
- ],
- [
- 56,
- 47
- ],
- [
- 124,
- 28
- ],
- [
- 20,
- 42
- ],
- [
- -99,
- 47
- ],
- [
- -29,
- 62
- ],
- [
- 190,
- -5
- ],
- [
- 55,
- -13
- ],
- [
- 109,
- 43
- ],
- [
- -157,
- 14
- ],
- [
- -244,
- -7
- ],
- [
- -123,
- 40
- ],
- [
- -58,
- 49
- ],
- [
- -82,
- 35
- ],
- [
- -15,
- 41
- ],
- [
- 104,
- 23
- ],
- [
- 81,
- 4
- ],
- [
- 137,
- 19
- ],
- [
- 102,
- 45
- ],
- [
- 87,
- -6
- ],
- [
- 75,
- -34
- ],
- [
- 53,
- 65
- ],
- [
- 92,
- 19
- ],
- [
- 125,
- 13
- ],
- [
- 213,
- 5
- ],
- [
- 37,
- -13
- ],
- [
- 202,
- 21
- ],
- [
- 151,
- -8
- ],
- [
- 150,
- -8
- ]
- ],
- [
- [
- 13275,
- 16423
- ],
- [
- -5,
- -49
- ],
- [
- -31,
- -20
- ],
- [
- -51,
- 15
- ],
- [
- -15,
- -49
- ],
- [
- -34,
- -4
- ],
- [
- -12,
- 19
- ],
- [
- -39,
- -40
- ],
- [
- -33,
- -6
- ],
- [
- -30,
- 26
- ]
- ],
- [
- [
- 13025,
- 16315
- ],
- [
- -24,
- 52
- ],
- [
- -34,
- -18
- ],
- [
- 1,
- 54
- ],
- [
- 51,
- 67
- ],
- [
- -2,
- 31
- ],
- [
- 32,
- -11
- ],
- [
- 19,
- 20
- ]
- ],
- [
- [
- 13068,
- 16510
- ],
- [
- 59,
- -1
- ],
- [
- 15,
- 26
- ],
- [
- 74,
- -36
- ]
- ],
- [
- [
- 7880,
- 4211
- ],
- [
- -23,
- -48
- ],
- [
- -60,
- -37
- ],
- [
- -34,
- 3
- ],
- [
- -42,
- 10
- ],
- [
- -50,
- 36
- ],
- [
- -73,
- 17
- ],
- [
- -88,
- 67
- ],
- [
- -71,
- 65
- ],
- [
- -96,
- 134
- ],
- [
- 57,
- -25
- ],
- [
- 98,
- -80
- ],
- [
- 93,
- -43
- ],
- [
- 36,
- 55
- ],
- [
- 22,
- 82
- ],
- [
- 65,
- 50
- ],
- [
- 49,
- -15
- ]
- ],
- [
- [
- 7767,
- 4523
- ],
- [
- -62,
- 1
- ],
- [
- -33,
- -30
- ],
- [
- -63,
- -43
- ],
- [
- -11,
- -112
- ],
- [
- -30,
- -3
- ],
- [
- -78,
- 39
- ],
- [
- -80,
- 84
- ],
- [
- -87,
- 68
- ],
- [
- -22,
- 76
- ],
- [
- 20,
- 71
- ],
- [
- -35,
- 79
- ],
- [
- -9,
- 205
- ],
- [
- 30,
- 115
- ],
- [
- 73,
- 93
- ],
- [
- -106,
- 35
- ],
- [
- 67,
- 106
- ],
- [
- 24,
- 199
- ],
- [
- 77,
- -42
- ],
- [
- 36,
- 249
- ],
- [
- -46,
- 31
- ],
- [
- -22,
- -149
- ],
- [
- -44,
- 17
- ],
- [
- 22,
- 171
- ],
- [
- 24,
- 222
- ],
- [
- 32,
- 82
- ],
- [
- -20,
- 117
- ],
- [
- -6,
- 136
- ],
- [
- 29,
- 3
- ],
- [
- 43,
- 194
- ],
- [
- 48,
- 192
- ],
- [
- 30,
- 179
- ],
- [
- -16,
- 180
- ],
- [
- 20,
- 99
- ],
- [
- -8,
- 148
- ],
- [
- 41,
- 146
- ],
- [
- 12,
- 232
- ],
- [
- 23,
- 249
- ],
- [
- 22,
- 269
- ],
- [
- -6,
- 196
- ],
- [
- -14,
- 169
- ]
- ],
- [
- [
- 7642,
- 8596
- ],
- [
- 36,
- 31
- ],
- [
- 18,
- 61
- ]
- ],
- [
- [
- 17774,
- 15286
- ],
- [
- -10,
- 69
- ],
- [
- 2,
- 46
- ],
- [
- -42,
- 28
- ],
- [
- -23,
- -12
- ],
- [
- -18,
- 111
- ]
- ],
- [
- [
- 17683,
- 15528
- ],
- [
- 20,
- 27
- ],
- [
- -9,
- 28
- ],
- [
- 66,
- 57
- ],
- [
- 48,
- 23
- ],
- [
- 74,
- -16
- ],
- [
- 26,
- 77
- ],
- [
- 90,
- 14
- ],
- [
- 25,
- 48
- ],
- [
- 109,
- 65
- ],
- [
- 10,
- 27
- ]
- ],
- [
- [
- 18142,
- 15878
- ],
- [
- -5,
- 68
- ],
- [
- 48,
- 31
- ],
- [
- -63,
- 209
- ],
- [
- 138,
- 48
- ],
- [
- 36,
- 27
- ],
- [
- 50,
- 214
- ],
- [
- 138,
- -39
- ],
- [
- 39,
- 54
- ],
- [
- 3,
- 120
- ],
- [
- 58,
- 12
- ],
- [
- 53,
- 79
- ]
- ],
- [
- [
- 18637,
- 16701
- ],
- [
- 27,
- 10
- ]
- ],
- [
- [
- 18664,
- 16711
- ],
- [
- 19,
- -83
- ],
- [
- 58,
- -64
- ],
- [
- 100,
- -45
- ],
- [
- 48,
- -97
- ],
- [
- -27,
- -140
- ],
- [
- 25,
- -52
- ],
- [
- 83,
- -20
- ],
- [
- 94,
- -17
- ],
- [
- 84,
- -75
- ],
- [
- 43,
- -13
- ],
- [
- 32,
- -111
- ],
- [
- 41,
- -71
- ],
- [
- 77,
- 3
- ],
- [
- 144,
- -27
- ],
- [
- 92,
- 17
- ],
- [
- 69,
- -18
- ],
- [
- 103,
- -73
- ],
- [
- 85,
- 0
- ],
- [
- 30,
- -37
- ],
- [
- 82,
- 64
- ],
- [
- 112,
- 42
- ],
- [
- 105,
- 4
- ],
- [
- 81,
- 42
- ],
- [
- 50,
- 65
- ],
- [
- 49,
- 40
- ],
- [
- -11,
- 40
- ],
- [
- -23,
- 46
- ],
- [
- 37,
- 77
- ],
- [
- 39,
- -11
- ],
- [
- 72,
- -24
- ],
- [
- 69,
- 64
- ],
- [
- 107,
- 46
- ],
- [
- 51,
- 79
- ],
- [
- 49,
- 34
- ],
- [
- 101,
- 16
- ],
- [
- 55,
- -13
- ],
- [
- 8,
- 42
- ],
- [
- -64,
- 84
- ],
- [
- -55,
- 39
- ],
- [
- -54,
- -45
- ],
- [
- -69,
- 19
- ],
- [
- -39,
- -15
- ],
- [
- -18,
- 49
- ],
- [
- 49,
- 120
- ],
- [
- 34,
- 90
- ]
- ],
- [
- [
- 20681,
- 16782
- ],
- [
- 84,
- -45
- ],
- [
- 98,
- 76
- ],
- [
- -1,
- 53
- ],
- [
- 63,
- 127
- ],
- [
- 39,
- 38
- ],
- [
- -1,
- 67
- ],
- [
- -38,
- 28
- ],
- [
- 57,
- 60
- ],
- [
- 87,
- 21
- ],
- [
- 92,
- 4
- ],
- [
- 105,
- -36
- ],
- [
- 61,
- -44
- ],
- [
- 43,
- -121
- ],
- [
- 26,
- -52
- ],
- [
- 24,
- -74
- ],
- [
- 26,
- -117
- ],
- [
- 122,
- -38
- ],
- [
- 82,
- -86
- ],
- [
- 28,
- -112
- ],
- [
- 106,
- -1
- ],
- [
- 61,
- 48
- ],
- [
- 115,
- 35
- ],
- [
- -37,
- -108
- ],
- [
- -27,
- -44
- ],
- [
- -24,
- -131
- ],
- [
- -47,
- -117
- ],
- [
- -84,
- 21
- ],
- [
- -60,
- -42
- ],
- [
- 18,
- -103
- ],
- [
- -10,
- -142
- ],
- [
- -35,
- -3
- ],
- [
- 0,
- -61
- ]
- ],
- [
- [
- 21654,
- 15883
- ],
- [
- -45,
- 71
- ],
- [
- -28,
- -67
- ],
- [
- -107,
- -52
- ],
- [
- 11,
- -63
- ],
- [
- -61,
- 4
- ],
- [
- -33,
- 38
- ],
- [
- -48,
- -85
- ],
- [
- -76,
- -65
- ],
- [
- -57,
- -77
- ]
- ],
- [
- [
- 21210,
- 15587
- ],
- [
- -98,
- -35
- ],
- [
- -51,
- -56
- ],
- [
- -75,
- -32
- ],
- [
- 37,
- 55
- ],
- [
- -15,
- 47
- ],
- [
- 56,
- 81
- ],
- [
- -37,
- 62
- ],
- [
- -61,
- -42
- ],
- [
- -79,
- -83
- ],
- [
- -43,
- -78
- ],
- [
- -68,
- -6
- ],
- [
- -35,
- -55
- ],
- [
- 36,
- -82
- ],
- [
- 57,
- -19
- ],
- [
- 3,
- -54
- ],
- [
- 55,
- -35
- ],
- [
- 78,
- 85
- ],
- [
- 62,
- -46
- ],
- [
- 45,
- -3
- ],
- [
- 11,
- -63
- ],
- [
- -99,
- -34
- ],
- [
- -32,
- -65
- ],
- [
- -68,
- -60
- ],
- [
- -36,
- -84
- ],
- [
- 75,
- -66
- ],
- [
- 28,
- -118
- ],
- [
- 42,
- -110
- ],
- [
- 48,
- -92
- ],
- [
- -2,
- -89
- ],
- [
- -43,
- -33
- ],
- [
- 16,
- -64
- ],
- [
- 41,
- -37
- ],
- [
- -10,
- -98
- ],
- [
- -18,
- -95
- ],
- [
- -39,
- -10
- ],
- [
- -51,
- -130
- ],
- [
- -56,
- -158
- ],
- [
- -65,
- -143
- ],
- [
- -96,
- -111
- ],
- [
- -97,
- -101
- ],
- [
- -79,
- -13
- ],
- [
- -42,
- -54
- ],
- [
- -24,
- 39
- ],
- [
- -40,
- -59
- ],
- [
- -97,
- -60
- ],
- [
- -74,
- -19
- ],
- [
- -24,
- -127
- ],
- [
- -38,
- -7
- ],
- [
- -19,
- 88
- ],
- [
- 17,
- 46
- ],
- [
- -94,
- 38
- ],
- [
- -33,
- -19
- ]
- ],
- [
- [
- 20079,
- 13383
- ],
- [
- -70,
- 31
- ],
- [
- -33,
- 49
- ],
- [
- 11,
- 69
- ],
- [
- -64,
- 22
- ],
- [
- -33,
- 45
- ],
- [
- -60,
- -64
- ],
- [
- -67,
- -14
- ],
- [
- -56,
- 1
- ],
- [
- -37,
- -30
- ]
- ],
- [
- [
- 19670,
- 13492
- ],
- [
- -37,
- -17
- ],
- [
- 11,
- -138
- ],
- [
- -37,
- 4
- ],
- [
- -6,
- 28
- ]
- ],
- [
- [
- 19601,
- 13369
- ],
- [
- -2,
- 50
- ],
- [
- -52,
- -35
- ],
- [
- -30,
- 22
- ],
- [
- -52,
- 45
- ],
- [
- 21,
- 99
- ],
- [
- -44,
- 24
- ],
- [
- -17,
- 110
- ],
- [
- -74,
- -20
- ],
- [
- 9,
- 142
- ],
- [
- 66,
- 101
- ],
- [
- 3,
- 99
- ],
- [
- -2,
- 91
- ],
- [
- -31,
- 29
- ],
- [
- -23,
- 71
- ],
- [
- -41,
- -9
- ]
- ],
- [
- [
- 19332,
- 14188
- ],
- [
- -75,
- 18
- ],
- [
- 23,
- 50
- ],
- [
- -32,
- 75
- ],
- [
- -50,
- -51
- ],
- [
- -58,
- 30
- ],
- [
- -81,
- -77
- ],
- [
- -63,
- -89
- ],
- [
- -56,
- -15
- ]
- ],
- [
- [
- 18739,
- 14072
- ],
- [
- -6,
- 95
- ],
- [
- -43,
- -25
- ]
- ],
- [
- [
- 18690,
- 14142
- ],
- [
- -81,
- 11
- ],
- [
- -79,
- 28
- ],
- [
- -56,
- 52
- ],
- [
- -55,
- 24
- ],
- [
- -23,
- 58
- ],
- [
- -39,
- 17
- ],
- [
- -71,
- 78
- ],
- [
- -55,
- 37
- ],
- [
- -29,
- -29
- ]
- ],
- [
- [
- 18202,
- 14418
- ],
- [
- -97,
- 84
- ],
- [
- -69,
- 76
- ],
- [
- -19,
- 132
- ],
- [
- 50,
- -16
- ],
- [
- 2,
- 61
- ],
- [
- -28,
- 62
- ],
- [
- 7,
- 98
- ],
- [
- -75,
- 140
- ]
- ],
- [
- [
- 17973,
- 15055
- ],
- [
- -114,
- 49
- ],
- [
- -21,
- 92
- ],
- [
- -51,
- 56
- ]
- ],
- [
- [
- 20239,
- 13038
- ],
- [
- -60,
- -58
- ],
- [
- -57,
- 38
- ],
- [
- -2,
- 103
- ],
- [
- 34,
- 54
- ],
- [
- 76,
- 34
- ],
- [
- 40,
- -3
- ],
- [
- 16,
- -46
- ],
- [
- -31,
- -53
- ],
- [
- -16,
- -69
- ]
- ],
- [
- [
- 12350,
- 11954
- ],
- [
- 19,
- -171
- ],
- [
- -29,
- -100
- ],
- [
- -19,
- -136
- ],
- [
- 31,
- -103
- ],
- [
- -4,
- -48
- ]
- ],
- [
- [
- 12348,
- 11396
- ],
- [
- -31,
- -1
- ],
- [
- -49,
- 24
- ],
- [
- -45,
- -2
- ],
- [
- -82,
- -21
- ],
- [
- -49,
- -34
- ],
- [
- -69,
- -44
- ],
- [
- -13,
- 3
- ]
- ],
- [
- [
- 12010,
- 11321
- ],
- [
- 5,
- 99
- ],
- [
- 7,
- 15
- ],
- [
- -2,
- 47
- ],
- [
- -30,
- 50
- ],
- [
- -22,
- 8
- ],
- [
- -20,
- 33
- ],
- [
- 15,
- 53
- ],
- [
- -7,
- 58
- ],
- [
- 3,
- 35
- ]
- ],
- [
- [
- 11959,
- 11719
- ],
- [
- 11,
- 0
- ],
- [
- 4,
- 53
- ],
- [
- -5,
- 23
- ],
- [
- 7,
- 17
- ],
- [
- 26,
- 14
- ],
- [
- -18,
- 96
- ],
- [
- -16,
- 50
- ],
- [
- 6,
- 40
- ],
- [
- 14,
- 10
- ]
- ],
- [
- [
- 11988,
- 12022
- ],
- [
- 9,
- 11
- ],
- [
- 19,
- -18
- ],
- [
- 54,
- -1
- ],
- [
- 13,
- 35
- ],
- [
- 12,
- -3
- ],
- [
- 20,
- 14
- ],
- [
- 11,
- -52
- ],
- [
- 16,
- 16
- ],
- [
- 29,
- 17
- ]
- ],
- [
- [
- 13664,
- 11069
- ],
- [
- -5,
- -65
- ],
- [
- -56,
- 29
- ],
- [
- -56,
- 31
- ],
- [
- -88,
- 5
- ]
- ],
- [
- [
- 13459,
- 11069
- ],
- [
- -9,
- 7
- ],
- [
- -41,
- -16
- ],
- [
- -42,
- 16
- ],
- [
- -33,
- -8
- ]
- ],
- [
- [
- 13334,
- 11068
- ],
- [
- -114,
- 3
- ]
- ],
- [
- [
- 13220,
- 11071
- ],
- [
- 10,
- 95
- ],
- [
- -27,
- 79
- ],
- [
- -32,
- 21
- ],
- [
- -14,
- 53
- ],
- [
- -18,
- 18
- ],
- [
- 1,
- 33
- ]
- ],
- [
- [
- 13140,
- 11370
- ],
- [
- 18,
- 85
- ],
- [
- 33,
- 115
- ],
- [
- 20,
- 1
- ],
- [
- 42,
- 71
- ],
- [
- 26,
- 2
- ],
- [
- 39,
- -50
- ],
- [
- 48,
- 41
- ],
- [
- 7,
- 50
- ],
- [
- 15,
- 48
- ],
- [
- 11,
- 61
- ],
- [
- 38,
- 49
- ],
- [
- 14,
- 84
- ],
- [
- 14,
- 27
- ],
- [
- 10,
- 62
- ],
- [
- 19,
- 77
- ],
- [
- 58,
- 93
- ],
- [
- 4,
- 39
- ],
- [
- 8,
- 22
- ],
- [
- -28,
- 48
- ]
- ],
- [
- [
- 13536,
- 12295
- ],
- [
- 2,
- 38
- ],
- [
- 20,
- 7
- ]
- ],
- [
- [
- 13558,
- 12340
- ],
- [
- 28,
- -77
- ],
- [
- 4,
- -79
- ],
- [
- -2,
- -80
- ],
- [
- 38,
- -109
- ],
- [
- -39,
- 1
- ],
- [
- -20,
- -9
- ],
- [
- -32,
- 12
- ],
- [
- -15,
- -56
- ],
- [
- 41,
- -70
- ],
- [
- 31,
- -21
- ],
- [
- 10,
- -49
- ],
- [
- 22,
- -83
- ],
- [
- -11,
- -32
- ]
- ],
- [
- [
- 13406,
- 10065
- ],
- [
- -9,
- 38
- ]
- ],
- [
- [
- 13453,
- 10224
- ],
- [
- 19,
- -13
- ],
- [
- 24,
- 46
- ],
- [
- 38,
- -1
- ],
- [
- 4,
- -34
- ],
- [
- 26,
- -21
- ],
- [
- 41,
- 75
- ],
- [
- 41,
- 59
- ],
- [
- 17,
- 38
- ],
- [
- -2,
- 99
- ],
- [
- 30,
- 116
- ],
- [
- 32,
- 62
- ],
- [
- 46,
- 58
- ],
- [
- 8,
- 38
- ],
- [
- 2,
- 44
- ],
- [
- 11,
- 42
- ],
- [
- -3,
- 68
- ],
- [
- 8,
- 106
- ],
- [
- 14,
- 75
- ],
- [
- 21,
- 64
- ],
- [
- 4,
- 73
- ]
- ],
- [
- [
- 14456,
- 11425
- ],
- [
- 42,
- -99
- ],
- [
- 31,
- -14
- ],
- [
- 19,
- 20
- ],
- [
- 32,
- -8
- ],
- [
- 39,
- 25
- ],
- [
- 17,
- -51
- ],
- [
- 61,
- -80
- ]
- ],
- [
- [
- 14697,
- 11218
- ],
- [
- -4,
- -140
- ],
- [
- 28,
- -16
- ],
- [
- -23,
- -43
- ],
- [
- -27,
- -32
- ],
- [
- -26,
- -62
- ],
- [
- -15,
- -56
- ],
- [
- -4,
- -96
- ],
- [
- -16,
- -46
- ],
- [
- -1,
- -91
- ]
- ],
- [
- [
- 14609,
- 10636
- ],
- [
- -20,
- -33
- ],
- [
- -2,
- -72
- ],
- [
- -10,
- -9
- ],
- [
- -6,
- -65
- ]
- ],
- [
- [
- 14593,
- 10257
- ],
- [
- 12,
- -110
- ],
- [
- -7,
- -62
- ],
- [
- 14,
- -70
- ],
- [
- 41,
- -67
- ],
- [
- 37,
- -151
- ]
- ],
- [
- [
- 14690,
- 9797
- ],
- [
- -27,
- 12
- ],
- [
- -94,
- -20
- ],
- [
- -18,
- -15
- ],
- [
- -20,
- -76
- ],
- [
- 15,
- -53
- ],
- [
- -12,
- -142
- ],
- [
- -9,
- -121
- ],
- [
- 19,
- -21
- ],
- [
- 49,
- -47
- ],
- [
- 19,
- 22
- ],
- [
- 6,
- -129
- ],
- [
- -54,
- 1
- ],
- [
- -28,
- 66
- ],
- [
- -26,
- 51
- ],
- [
- -53,
- 17
- ],
- [
- -16,
- 63
- ],
- [
- -43,
- -38
- ],
- [
- -55,
- 16
- ],
- [
- -24,
- 55
- ],
- [
- -44,
- 11
- ],
- [
- -33,
- -3
- ],
- [
- -4,
- 37
- ],
- [
- -24,
- 3
- ]
- ],
- [
- [
- 13378,
- 10193
- ],
- [
- -57,
- 127
- ]
- ],
- [
- [
- 13321,
- 10320
- ],
- [
- 53,
- 66
- ],
- [
- -26,
- 79
- ],
- [
- 24,
- 31
- ],
- [
- 47,
- 14
- ],
- [
- 5,
- 53
- ],
- [
- 37,
- -57
- ],
- [
- 62,
- -5
- ],
- [
- 21,
- 56
- ],
- [
- 9,
- 80
- ],
- [
- -8,
- 94
- ],
- [
- -33,
- 71
- ],
- [
- 31,
- 139
- ],
- [
- -18,
- 24
- ],
- [
- -52,
- -10
- ],
- [
- -19,
- 62
- ],
- [
- 5,
- 52
- ]
- ],
- [
- [
- 7675,
- 10282
- ],
- [
- -35,
- 63
- ],
- [
- -20,
- 3
- ],
- [
- 45,
- 122
- ],
- [
- -54,
- 56
- ],
- [
- -42,
- -10
- ],
- [
- -25,
- 21
- ],
- [
- -38,
- -32
- ],
- [
- -52,
- 15
- ],
- [
- -41,
- 126
- ],
- [
- -32,
- 31
- ],
- [
- -23,
- 57
- ],
- [
- -46,
- 56
- ],
- [
- -19,
- -11
- ]
- ],
- [
- [
- 7293,
- 10779
- ],
- [
- -29,
- 28
- ],
- [
- -35,
- 40
- ],
- [
- -20,
- -19
- ],
- [
- -59,
- 17
- ],
- [
- -17,
- 51
- ],
- [
- -13,
- -2
- ],
- [
- -69,
- 69
- ]
- ],
- [
- [
- 7051,
- 10963
- ],
- [
- -10,
- 37
- ],
- [
- 26,
- 9
- ],
- [
- -3,
- 60
- ],
- [
- 16,
- 44
- ],
- [
- 35,
- 8
- ],
- [
- 29,
- 75
- ],
- [
- 27,
- 63
- ],
- [
- -26,
- 29
- ],
- [
- 14,
- 69
- ],
- [
- -16,
- 110
- ],
- [
- 15,
- 31
- ],
- [
- -11,
- 102
- ],
- [
- -28,
- 64
- ]
- ],
- [
- [
- 7119,
- 11664
- ],
- [
- 8,
- 58
- ],
- [
- 23,
- -8
- ],
- [
- 13,
- 35
- ],
- [
- -16,
- 71
- ],
- [
- 8,
- 17
- ]
- ],
- [
- [
- 7155,
- 11837
- ],
- [
- 36,
- -3
- ],
- [
- 53,
- 83
- ],
- [
- 28,
- 13
- ],
- [
- 1,
- 40
- ],
- [
- 13,
- 101
- ],
- [
- 40,
- 56
- ],
- [
- 44,
- 2
- ],
- [
- 5,
- 25
- ],
- [
- 55,
- -10
- ],
- [
- 55,
- 61
- ],
- [
- 27,
- 26
- ],
- [
- 34,
- 58
- ],
- [
- 24,
- -7
- ],
- [
- 19,
- -32
- ],
- [
- -14,
- -40
- ]
- ],
- [
- [
- 7575,
- 12210
- ],
- [
- -45,
- -20
- ],
- [
- -17,
- -60
- ],
- [
- -27,
- -35
- ],
- [
- -21,
- -44
- ],
- [
- -8,
- -86
- ],
- [
- -19,
- -70
- ],
- [
- 36,
- -8
- ],
- [
- 8,
- -55
- ],
- [
- 16,
- -26
- ],
- [
- 5,
- -49
- ],
- [
- -8,
- -44
- ],
- [
- 3,
- -25
- ],
- [
- 17,
- -10
- ],
- [
- 16,
- -42
- ],
- [
- 90,
- 12
- ],
- [
- 40,
- -16
- ],
- [
- 49,
- -103
- ],
- [
- 29,
- 13
- ],
- [
- 50,
- -7
- ],
- [
- 40,
- 14
- ],
- [
- 24,
- -21
- ],
- [
- -12,
- -64
- ],
- [
- -16,
- -40
- ],
- [
- -5,
- -86
- ],
- [
- 14,
- -80
- ],
- [
- 20,
- -36
- ],
- [
- 2,
- -27
- ],
- [
- -35,
- -59
- ],
- [
- 25,
- -27
- ],
- [
- 18,
- -42
- ],
- [
- 22,
- -119
- ]
- ],
- [
- [
- 6764,
- 11784
- ],
- [
- -38,
- 27
- ],
- [
- -14,
- 25
- ],
- [
- 8,
- 21
- ],
- [
- -2,
- 26
- ],
- [
- -20,
- 29
- ],
- [
- -27,
- 23
- ],
- [
- -24,
- 16
- ],
- [
- -5,
- 35
- ],
- [
- -18,
- 21
- ],
- [
- 4,
- -35
- ],
- [
- -13,
- -28
- ],
- [
- -16,
- 33
- ],
- [
- -23,
- 12
- ],
- [
- -9,
- 24
- ],
- [
- 0,
- 37
- ],
- [
- 9,
- 37
- ],
- [
- -19,
- 17
- ],
- [
- 16,
- 23
- ]
- ],
- [
- [
- 6573,
- 12127
- ],
- [
- 10,
- 16
- ],
- [
- 46,
- -32
- ],
- [
- 16,
- 16
- ],
- [
- 22,
- -10
- ],
- [
- 12,
- -25
- ],
- [
- 20,
- -8
- ],
- [
- 17,
- 26
- ]
- ],
- [
- [
- 6716,
- 12110
- ],
- [
- 18,
- -66
- ],
- [
- 27,
- -48
- ],
- [
- 32,
- -51
- ]
- ],
- [
- [
- 6793,
- 11945
- ],
- [
- -27,
- -11
- ],
- [
- 1,
- -48
- ],
- [
- 14,
- -18
- ],
- [
- -10,
- -14
- ],
- [
- 3,
- -22
- ],
- [
- -6,
- -24
- ],
- [
- -4,
- -24
- ]
- ],
- [
- [
- 6813,
- 13579
- ],
- [
- 60,
- -8
- ],
- [
- 55,
- -2
- ],
- [
- 65,
- -41
- ],
- [
- 28,
- -44
- ],
- [
- 65,
- 14
- ],
- [
- 25,
- -28
- ],
- [
- 59,
- -75
- ],
- [
- 43,
- -54
- ],
- [
- 23,
- 2
- ],
- [
- 42,
- -24
- ],
- [
- -5,
- -34
- ],
- [
- 51,
- -5
- ],
- [
- 53,
- -49
- ],
- [
- -9,
- -28
- ],
- [
- -46,
- -16
- ],
- [
- -47,
- -6
- ],
- [
- -48,
- 10
- ],
- [
- -100,
- -12
- ],
- [
- 47,
- 67
- ],
- [
- -28,
- 31
- ],
- [
- -45,
- 8
- ],
- [
- -24,
- 35
- ],
- [
- -17,
- 68
- ],
- [
- -39,
- -4
- ],
- [
- -65,
- 32
- ],
- [
- -21,
- 25
- ],
- [
- -91,
- 19
- ],
- [
- -24,
- 23
- ],
- [
- 26,
- 30
- ],
- [
- -69,
- 6
- ],
- [
- -50,
- -62
- ],
- [
- -29,
- -2
- ],
- [
- -10,
- -29
- ],
- [
- -34,
- -13
- ],
- [
- -30,
- 11
- ],
- [
- 37,
- 37
- ],
- [
- 15,
- 43
- ],
- [
- 31,
- 27
- ],
- [
- 36,
- 23
- ],
- [
- 53,
- 12
- ],
- [
- 17,
- 13
- ]
- ],
- [
- [
- 14829,
- 15013
- ],
- [
- 5,
- 1
- ],
- [
- 10,
- 28
- ],
- [
- 50,
- -1
- ],
- [
- 64,
- 36
- ],
- [
- -47,
- -51
- ],
- [
- 5,
- -23
- ]
- ],
- [
- [
- 14916,
- 15003
- ],
- [
- -8,
- 4
- ],
- [
- -13,
- -9
- ],
- [
- -10,
- 3
- ],
- [
- -4,
- -5
- ],
- [
- -1,
- 12
- ],
- [
- -5,
- 8
- ],
- [
- -14,
- 1
- ],
- [
- -19,
- -10
- ],
- [
- -13,
- 6
- ]
- ],
- [
- [
- 14916,
- 15003
- ],
- [
- 2,
- -10
- ],
- [
- -72,
- -48
- ],
- [
- -34,
- 15
- ],
- [
- -16,
- 48
- ],
- [
- 33,
- 5
- ]
- ],
- [
- [
- 13495,
- 16661
- ],
- [
- -39,
- 52
- ],
- [
- -36,
- 28
- ],
- [
- -7,
- 51
- ],
- [
- -12,
- 36
- ],
- [
- 50,
- 26
- ],
- [
- 26,
- 30
- ],
- [
- 50,
- 23
- ],
- [
- 18,
- 23
- ],
- [
- 18,
- -14
- ],
- [
- 31,
- 12
- ]
- ],
- [
- [
- 13594,
- 16928
- ],
- [
- 33,
- -38
- ],
- [
- 52,
- -11
- ],
- [
- -4,
- -33
- ],
- [
- 38,
- -24
- ],
- [
- 10,
- 30
- ],
- [
- 48,
- -13
- ],
- [
- 7,
- -37
- ],
- [
- 52,
- -8
- ],
- [
- 32,
- -59
- ]
- ],
- [
- [
- 13862,
- 16735
- ],
- [
- -21,
- 0
- ],
- [
- -11,
- -22
- ],
- [
- -16,
- -5
- ],
- [
- -4,
- -27
- ],
- [
- -14,
- -6
- ],
- [
- -2,
- -11
- ],
- [
- -23,
- -12
- ],
- [
- -31,
- 2
- ],
- [
- -10,
- -27
- ]
- ],
- [
- [
- 13068,
- 16510
- ],
- [
- 9,
- 86
- ],
- [
- 35,
- 82
- ],
- [
- -100,
- 22
- ],
- [
- -33,
- 31
- ]
- ],
- [
- [
- 12979,
- 16731
- ],
- [
- 4,
- 53
- ],
- [
- -14,
- 27
- ]
- ],
- [
- [
- 12977,
- 16892
- ],
- [
- -12,
- 126
- ],
- [
- 42,
- 0
- ],
- [
- 18,
- 45
- ],
- [
- 17,
- 110
- ],
- [
- -13,
- 40
- ]
- ],
- [
- [
- 13029,
- 17213
- ],
- [
- 13,
- 26
- ],
- [
- 59,
- 6
- ],
- [
- 13,
- -26
- ],
- [
- 47,
- 59
- ],
- [
- -16,
- 45
- ],
- [
- -3,
- 68
- ]
- ],
- [
- [
- 13142,
- 17391
- ],
- [
- 53,
- -16
- ],
- [
- 44,
- 18
- ]
- ],
- [
- [
- 13239,
- 17393
- ],
- [
- 1,
- -46
- ],
- [
- 71,
- -28
- ],
- [
- -1,
- -42
- ],
- [
- 71,
- 22
- ],
- [
- 39,
- 33
- ],
- [
- 79,
- -47
- ],
- [
- 33,
- -39
- ]
- ],
- [
- [
- 13532,
- 17246
- ],
- [
- 16,
- -61
- ],
- [
- -19,
- -32
- ],
- [
- 25,
- -42
- ],
- [
- 17,
- -65
- ],
- [
- -5,
- -41
- ],
- [
- 28,
- -77
- ]
- ],
- [
- [
- 15551,
- 12321
- ],
- [
- 16,
- -37
- ],
- [
- -2,
- -50
- ],
- [
- -40,
- -29
- ],
- [
- 30,
- -33
- ]
- ],
- [
- [
- 15555,
- 12172
- ],
- [
- -26,
- -64
- ]
- ],
- [
- [
- 15529,
- 12108
- ],
- [
- -15,
- 21
- ],
- [
- -17,
- -8
- ],
- [
- -39,
- 2
- ],
- [
- -1,
- 36
- ],
- [
- -5,
- 34
- ],
- [
- 23,
- 56
- ],
- [
- 25,
- 53
- ]
- ],
- [
- [
- 15500,
- 12302
- ],
- [
- 30,
- -11
- ],
- [
- 21,
- 30
- ]
- ],
- [
- [
- 13142,
- 17391
- ],
- [
- -28,
- 67
- ],
- [
- -3,
- 122
- ],
- [
- 12,
- 33
- ],
- [
- 20,
- 36
- ],
- [
- 61,
- 7
- ],
- [
- 25,
- 33
- ],
- [
- 56,
- 34
- ],
- [
- -2,
- -62
- ],
- [
- -21,
- -39
- ],
- [
- 8,
- -33
- ],
- [
- 38,
- -19
- ],
- [
- -17,
- -45
- ],
- [
- -21,
- 13
- ],
- [
- -50,
- -86
- ],
- [
- 19,
- -59
- ]
- ],
- [
- [
- 13432,
- 17469
- ],
- [
- -42,
- -98
- ],
- [
- -73,
- 68
- ],
- [
- -9,
- 50
- ],
- [
- 102,
- 40
- ],
- [
- 22,
- -60
- ]
- ],
- [
- [
- 7549,
- 13162
- ],
- [
- 8,
- 21
- ],
- [
- 55,
- -1
- ],
- [
- 41,
- -31
- ],
- [
- 18,
- 3
- ],
- [
- 13,
- -42
- ],
- [
- 38,
- 2
- ],
- [
- -2,
- -36
- ],
- [
- 31,
- -4
- ],
- [
- 34,
- -44
- ],
- [
- -26,
- -49
- ],
- [
- -33,
- 26
- ],
- [
- -32,
- -5
- ],
- [
- -23,
- 6
- ],
- [
- -12,
- -22
- ],
- [
- -27,
- -7
- ],
- [
- -11,
- 29
- ],
- [
- -23,
- -17
- ],
- [
- -28,
- -83
- ],
- [
- -18,
- 20
- ],
- [
- -3,
- 34
- ]
- ],
- [
- [
- 7549,
- 12962
- ],
- [
- 1,
- 33
- ],
- [
- -18,
- 36
- ],
- [
- 17,
- 20
- ],
- [
- 6,
- 46
- ],
- [
- -6,
- 65
- ]
- ],
- [
- [
- 12845,
- 13095
- ],
- [
- -77,
- -12
- ],
- [
- -1,
- 77
- ],
- [
- -32,
- 19
- ],
- [
- -44,
- 35
- ],
- [
- -16,
- 56
- ],
- [
- -236,
- 262
- ],
- [
- -235,
- 261
- ]
- ],
- [
- [
- 12204,
- 13793
- ],
- [
- -262,
- 291
- ]
- ],
- [
- [
- 11942,
- 14084
- ],
- [
- 1,
- 23
- ],
- [
- 0,
- 8
- ]
- ],
- [
- [
- 11943,
- 14115
- ],
- [
- 0,
- 142
- ],
- [
- 112,
- 89
- ],
- [
- 70,
- 18
- ],
- [
- 57,
- 32
- ],
- [
- 27,
- 60
- ],
- [
- 81,
- 48
- ],
- [
- 3,
- 89
- ],
- [
- 41,
- 10
- ],
- [
- 31,
- 45
- ],
- [
- 91,
- 20
- ],
- [
- 13,
- 46
- ],
- [
- -18,
- 26
- ],
- [
- -24,
- 127
- ],
- [
- -4,
- 72
- ],
- [
- -27,
- 77
- ]
- ],
- [
- [
- 12396,
- 15016
- ],
- [
- 67,
- 66
- ],
- [
- 76,
- 21
- ],
- [
- 44,
- 49
- ],
- [
- 67,
- 37
- ],
- [
- 118,
- 21
- ],
- [
- 115,
- 10
- ],
- [
- 35,
- -18
- ],
- [
- 66,
- 47
- ],
- [
- 74,
- 1
- ],
- [
- 29,
- -28
- ],
- [
- 48,
- 8
- ]
- ],
- [
- [
- 13135,
- 15230
- ],
- [
- -15,
- -62
- ],
- [
- 11,
- -114
- ],
- [
- -16,
- -99
- ],
- [
- -43,
- -67
- ],
- [
- 6,
- -91
- ],
- [
- 57,
- -71
- ],
- [
- 1,
- -29
- ],
- [
- 43,
- -48
- ],
- [
- 29,
- -216
- ]
- ],
- [
- [
- 13208,
- 14433
- ],
- [
- 23,
- -106
- ],
- [
- 4,
- -56
- ],
- [
- -12,
- -97
- ],
- [
- 5,
- -55
- ],
- [
- -9,
- -66
- ],
- [
- 6,
- -75
- ],
- [
- -28,
- -50
- ],
- [
- 41,
- -88
- ],
- [
- 3,
- -51
- ],
- [
- 25,
- -67
- ],
- [
- 32,
- 22
- ],
- [
- 55,
- -56
- ],
- [
- 31,
- -75
- ]
- ],
- [
- [
- 13384,
- 13613
- ],
- [
- -239,
- -229
- ],
- [
- -202,
- -235
- ],
- [
- -98,
- -54
- ]
- ],
- [
- [
- 7293,
- 10779
- ],
- [
- 10,
- -91
- ],
- [
- -22,
- -78
- ],
- [
- -76,
- -126
- ],
- [
- -83,
- -47
- ],
- [
- -43,
- -104
- ],
- [
- -13,
- -81
- ],
- [
- -40,
- -50
- ],
- [
- -29,
- 61
- ],
- [
- -28,
- 13
- ],
- [
- -29,
- -10
- ],
- [
- -2,
- 44
- ],
- [
- 20,
- 29
- ],
- [
- -8,
- 50
- ]
- ],
- [
- [
- 6950,
- 10389
- ],
- [
- 37,
- 89
- ],
- [
- -15,
- 53
- ],
- [
- -27,
- -56
- ],
- [
- -42,
- 53
- ],
- [
- 15,
- 33
- ],
- [
- -12,
- 109
- ],
- [
- 24,
- 18
- ],
- [
- 13,
- 75
- ],
- [
- 26,
- 77
- ],
- [
- -4,
- 49
- ],
- [
- 38,
- 26
- ],
- [
- 48,
- 48
- ]
- ],
- [
- [
- 15117,
- 13437
- ],
- [
- -276,
- 0
- ],
- [
- -271,
- 0
- ],
- [
- -280,
- 0
- ]
- ],
- [
- [
- 14290,
- 13437
- ],
- [
- 0,
- 441
- ],
- [
- 0,
- 427
- ],
- [
- -21,
- 97
- ],
- [
- 18,
- 74
- ],
- [
- -11,
- 51
- ],
- [
- 26,
- 58
- ]
- ],
- [
- [
- 14302,
- 14585
- ],
- [
- 92,
- 1
- ],
- [
- 68,
- -31
- ],
- [
- 69,
- -36
- ],
- [
- 32,
- -18
- ],
- [
- 54,
- 38
- ],
- [
- 28,
- 34
- ],
- [
- 62,
- 10
- ],
- [
- 49,
- -15
- ],
- [
- 19,
- -60
- ],
- [
- 17,
- 39
- ],
- [
- 55,
- -28
- ],
- [
- 55,
- -7
- ],
- [
- 34,
- 31
- ]
- ],
- [
- [
- 14936,
- 14543
- ],
- [
- 39,
- -175
- ],
- [
- 7,
- -32
- ]
- ],
- [
- [
- 14982,
- 14336
- ],
- [
- -20,
- -48
- ],
- [
- -15,
- -90
- ],
- [
- -19,
- -63
- ],
- [
- -16,
- -21
- ],
- [
- -23,
- 39
- ],
- [
- -32,
- 53
- ],
- [
- -49,
- 172
- ],
- [
- -7,
- -10
- ],
- [
- 28,
- -127
- ],
- [
- 43,
- -121
- ],
- [
- 53,
- -187
- ],
- [
- 26,
- -65
- ],
- [
- 22,
- -68
- ],
- [
- 63,
- -132
- ],
- [
- -14,
- -21
- ],
- [
- 2,
- -78
- ],
- [
- 81,
- -108
- ],
- [
- 12,
- -24
- ]
- ],
- [
- [
- 15500,
- 12302
- ],
- [
- -24,
- 39
- ],
- [
- -29,
- 70
- ],
- [
- -31,
- 39
- ],
- [
- -18,
- 41
- ],
- [
- -60,
- 48
- ],
- [
- -48,
- 2
- ],
- [
- -17,
- 25
- ],
- [
- -41,
- -29
- ],
- [
- -42,
- 55
- ],
- [
- -22,
- -90
- ],
- [
- -81,
- 25
- ]
- ],
- [
- [
- 15087,
- 12527
- ],
- [
- -7,
- 48
- ],
- [
- 30,
- 177
- ],
- [
- 6,
- 79
- ],
- [
- 22,
- 37
- ],
- [
- 52,
- 20
- ],
- [
- 35,
- 68
- ]
- ],
- [
- [
- 15225,
- 12956
- ],
- [
- 40,
- -138
- ],
- [
- 20,
- -111
- ],
- [
- 38,
- -58
- ],
- [
- 95,
- -113
- ],
- [
- 39,
- -69
- ],
- [
- 38,
- -69
- ],
- [
- 21,
- -41
- ],
- [
- 35,
- -36
- ]
- ],
- [
- [
- 11918,
- 15822
- ],
- [
- 3,
- 85
- ],
- [
- -28,
- 52
- ],
- [
- 98,
- 87
- ],
- [
- 86,
- -22
- ],
- [
- 93,
- 1
- ],
- [
- 74,
- -21
- ],
- [
- 58,
- 7
- ],
- [
- 113,
- -4
- ]
- ],
- [
- [
- 12415,
- 16007
- ],
- [
- 28,
- -47
- ],
- [
- 128,
- -55
- ],
- [
- 25,
- 26
- ],
- [
- 79,
- -54
- ],
- [
- 81,
- 16
- ]
- ],
- [
- [
- 12756,
- 15893
- ],
- [
- 3,
- -70
- ],
- [
- -66,
- -80
- ],
- [
- -89,
- -25
- ],
- [
- -6,
- -41
- ],
- [
- -43,
- -66
- ],
- [
- -27,
- -98
- ],
- [
- 27,
- -68
- ],
- [
- -40,
- -54
- ],
- [
- -15,
- -78
- ],
- [
- -53,
- -24
- ],
- [
- -49,
- -92
- ],
- [
- -89,
- -2
- ],
- [
- -66,
- 2
- ],
- [
- -44,
- -42
- ],
- [
- -26,
- -45
- ],
- [
- -34,
- 10
- ],
- [
- -26,
- 40
- ],
- [
- -20,
- 69
- ],
- [
- -65,
- 19
- ]
- ],
- [
- [
- 12028,
- 15248
- ],
- [
- -6,
- 39
- ],
- [
- 26,
- 45
- ],
- [
- 10,
- 33
- ],
- [
- -25,
- 36
- ],
- [
- 20,
- 79
- ],
- [
- -28,
- 72
- ],
- [
- 30,
- 9
- ],
- [
- 3,
- 57
- ],
- [
- 11,
- 18
- ],
- [
- 1,
- 93
- ],
- [
- 32,
- 33
- ],
- [
- -19,
- 60
- ],
- [
- -41,
- 4
- ],
- [
- -12,
- -15
- ],
- [
- -41,
- 0
- ],
- [
- -18,
- 59
- ],
- [
- -28,
- -18
- ],
- [
- -25,
- -30
- ]
- ],
- [
- [
- 14242,
- 17731
- ],
- [
- 8,
- 70
- ],
- [
- -25,
- -15
- ],
- [
- -44,
- 43
- ],
- [
- -7,
- 69
- ],
- [
- 89,
- 33
- ],
- [
- 87,
- 18
- ],
- [
- 76,
- -20
- ],
- [
- 72,
- 3
- ]
- ],
- [
- [
- 14498,
- 17932
- ],
- [
- 11,
- -21
- ],
- [
- -50,
- -69
- ],
- [
- 21,
- -112
- ],
- [
- -30,
- -38
- ]
- ],
- [
- [
- 14450,
- 17692
- ],
- [
- -58,
- 1
- ],
- [
- -60,
- 44
- ],
- [
- -30,
- 15
- ],
- [
- -60,
- -21
- ]
- ],
- [
- [
- 15529,
- 12108
- ],
- [
- -15,
- -42
- ],
- [
- 26,
- -66
- ],
- [
- 26,
- -58
- ],
- [
- 26,
- -43
- ],
- [
- 228,
- -142
- ],
- [
- 59,
- 0
- ]
- ],
- [
- [
- 15879,
- 11757
- ],
- [
- -197,
- -360
- ],
- [
- -91,
- -5
- ],
- [
- -62,
- -85
- ],
- [
- -45,
- -2
- ],
- [
- -19,
- -38
- ]
- ],
- [
- [
- 15465,
- 11267
- ],
- [
- -47,
- 0
- ],
- [
- -29,
- 41
- ],
- [
- -63,
- -50
- ],
- [
- -21,
- -50
- ],
- [
- -46,
- 9
- ],
- [
- -16,
- 14
- ],
- [
- -16,
- -3
- ],
- [
- -22,
- 1
- ],
- [
- -88,
- 102
- ],
- [
- -49,
- 0
- ],
- [
- -24,
- 39
- ],
- [
- 0,
- 68
- ],
- [
- -36,
- 20
- ]
- ],
- [
- [
- 15008,
- 11458
- ],
- [
- -41,
- 130
- ],
- [
- -32,
- 28
- ],
- [
- -12,
- 48
- ],
- [
- -36,
- 59
- ],
- [
- -42,
- 8
- ],
- [
- 23,
- 68
- ],
- [
- 37,
- 3
- ],
- [
- 11,
- 37
- ]
- ],
- [
- [
- 14916,
- 11839
- ],
- [
- -1,
- 108
- ],
- [
- 21,
- 125
- ],
- [
- 33,
- 34
- ],
- [
- 7,
- 49
- ],
- [
- 29,
- 92
- ],
- [
- 42,
- 59
- ],
- [
- 29,
- 118
- ],
- [
- 11,
- 103
- ]
- ],
- [
- [
- 14214,
- 18716
- ],
- [
- -24,
- 47
- ],
- [
- -2,
- 184
- ],
- [
- -108,
- 82
- ],
- [
- -93,
- 59
- ]
- ],
- [
- [
- 13987,
- 19088
- ],
- [
- 41,
- 31
- ],
- [
- 78,
- -63
- ],
- [
- 91,
- 6
- ],
- [
- 75,
- -29
- ],
- [
- 66,
- 53
- ],
- [
- 34,
- 88
- ],
- [
- 109,
- 41
- ],
- [
- 89,
- -48
- ],
- [
- -29,
- -84
- ]
- ],
- [
- [
- 14541,
- 19083
- ],
- [
- -11,
- -84
- ],
- [
- 107,
- -80
- ],
- [
- -64,
- -91
- ],
- [
- 81,
- -136
- ],
- [
- -47,
- -103
- ],
- [
- 63,
- -89
- ],
- [
- -29,
- -78
- ],
- [
- 103,
- -83
- ],
- [
- -26,
- -61
- ],
- [
- -65,
- -69
- ],
- [
- -149,
- -153
- ]
- ],
- [
- [
- 14504,
- 18056
- ],
- [
- -126,
- -10
- ],
- [
- -123,
- -44
- ],
- [
- -113,
- -25
- ],
- [
- -41,
- 65
- ],
- [
- -67,
- 40
- ],
- [
- 15,
- 118
- ],
- [
- -33,
- 108
- ],
- [
- 33,
- 70
- ],
- [
- 63,
- 75
- ],
- [
- 159,
- 130
- ],
- [
- 47,
- 26
- ],
- [
- -7,
- 50
- ],
- [
- -97,
- 57
- ]
- ],
- [
- [
- 24982,
- 8717
- ],
- [
- 24,
- -35
- ],
- [
- -12,
- -62
- ],
- [
- -43,
- -17
- ],
- [
- -39,
- 15
- ],
- [
- -6,
- 53
- ],
- [
- 27,
- 41
- ],
- [
- 31,
- -15
- ],
- [
- 18,
- 20
- ]
- ],
- [
- [
- 25051,
- 8782
- ],
- [
- -45,
- -26
- ],
- [
- -9,
- 45
- ],
- [
- 35,
- 25
- ],
- [
- 22,
- 6
- ],
- [
- 41,
- 38
- ],
- [
- 0,
- -59
- ],
- [
- -44,
- -29
- ]
- ],
- [
- [
- 6,
- 8817
- ],
- [
- -6,
- -6
- ],
- [
- 0,
- 59
- ],
- [
- 14,
- 5
- ],
- [
- -8,
- -58
- ]
- ],
- [
- [
- 8281,
- 4577
- ],
- [
- 84,
- 72
- ],
- [
- 59,
- -30
- ],
- [
- 42,
- 48
- ],
- [
- 56,
- -54
- ],
- [
- -21,
- -42
- ],
- [
- -94,
- -36
- ],
- [
- -32,
- 42
- ],
- [
- -59,
- -54
- ],
- [
- -35,
- 54
- ]
- ],
- [
- [
- 12943,
- 16739
- ],
- [
- 16,
- -10
- ],
- [
- 20,
- 2
- ]
- ],
- [
- [
- 13025,
- 16315
- ],
- [
- -3,
- -34
- ],
- [
- 20,
- -45
- ],
- [
- -24,
- -37
- ],
- [
- 18,
- -93
- ],
- [
- 38,
- -15
- ],
- [
- -8,
- -52
- ]
- ],
- [
- [
- 13066,
- 16039
- ],
- [
- -63,
- -68
- ],
- [
- -138,
- 33
- ],
- [
- -101,
- -39
- ],
- [
- -8,
- -72
- ]
- ],
- [
- [
- 12415,
- 16007
- ],
- [
- 36,
- 72
- ],
- [
- 13,
- 239
- ],
- [
- -72,
- 125
- ],
- [
- -51,
- 61
- ],
- [
- -107,
- 46
- ],
- [
- -7,
- 88
- ],
- [
- 91,
- 26
- ],
- [
- 117,
- -31
- ],
- [
- -22,
- 136
- ],
- [
- 66,
- -52
- ],
- [
- 162,
- 94
- ],
- [
- 21,
- 98
- ],
- [
- 61,
- 24
- ]
- ],
- [
- [
- 8747,
- 11075
- ],
- [
- 17,
- 51
- ],
- [
- 6,
- 54
- ],
- [
- 12,
- 52
- ],
- [
- -27,
- 71
- ],
- [
- -5,
- 82
- ],
- [
- 36,
- 103
- ]
- ],
- [
- [
- 8786,
- 11488
- ],
- [
- 24,
- -13
- ],
- [
- 51,
- -29
- ],
- [
- 74,
- -101
- ],
- [
- 12,
- -49
- ]
- ],
- [
- [
- 13214,
- 15854
- ],
- [
- -23,
- -92
- ],
- [
- -32,
- 24
- ],
- [
- -16,
- 81
- ],
- [
- 14,
- 44
- ],
- [
- 45,
- 46
- ],
- [
- 12,
- -103
- ]
- ],
- [
- [
- 13321,
- 10320
- ],
- [
- -72,
- 121
- ],
- [
- -46,
- 99
- ],
- [
- -42,
- 124
- ],
- [
- 2,
- 40
- ],
- [
- 15,
- 38
- ],
- [
- 17,
- 87
- ],
- [
- 14,
- 89
- ]
- ],
- [
- [
- 13209,
- 10918
- ],
- [
- 24,
- 7
- ],
- [
- 101,
- -1
- ],
- [
- 0,
- 144
- ]
- ],
- [
- [
- 12115,
- 17260
- ],
- [
- -52,
- 24
- ],
- [
- -43,
- -1
- ],
- [
- 14,
- 64
- ],
- [
- -14,
- 64
- ]
- ],
- [
- [
- 12020,
- 17411
- ],
- [
- 58,
- 5
- ],
- [
- 75,
- -74
- ],
- [
- -38,
- -82
- ]
- ],
- [
- [
- 12338,
- 17832
- ],
- [
- -74,
- -130
- ],
- [
- 71,
- 16
- ],
- [
- 76,
- 0
- ],
- [
- -18,
- -98
- ],
- [
- -63,
- -108
- ],
- [
- 72,
- -7
- ],
- [
- 6,
- -13
- ],
- [
- 62,
- -142
- ],
- [
- 47,
- -19
- ],
- [
- 43,
- -136
- ],
- [
- 20,
- -48
- ],
- [
- 85,
- -23
- ],
- [
- -9,
- -76
- ],
- [
- -35,
- -36
- ],
- [
- 28,
- -62
- ],
- [
- -63,
- -63
- ],
- [
- -93,
- 2
- ],
- [
- -119,
- -33
- ],
- [
- -33,
- 23
- ],
- [
- -46,
- -56
- ],
- [
- -64,
- 14
- ],
- [
- -49,
- -46
- ],
- [
- -37,
- 24
- ],
- [
- 102,
- 126
- ],
- [
- 62,
- 26
- ],
- [
- 0,
- 0
- ],
- [
- -109,
- 20
- ],
- [
- -20,
- 48
- ],
- [
- 73,
- 37
- ],
- [
- -38,
- 64
- ],
- [
- 13,
- 79
- ],
- [
- 104,
- -11
- ],
- [
- 10,
- 70
- ],
- [
- -46,
- 74
- ],
- [
- -2,
- 1
- ],
- [
- -84,
- 21
- ],
- [
- -17,
- 33
- ],
- [
- 26,
- 53
- ],
- [
- -23,
- 34
- ],
- [
- -38,
- -57
- ],
- [
- -4,
- 115
- ],
- [
- -35,
- 62
- ],
- [
- 25,
- 124
- ],
- [
- 54,
- 97
- ],
- [
- 56,
- -10
- ],
- [
- 84,
- 11
- ]
- ],
- [
- [
- 15586,
- 15727
- ],
- [
- -68,
- 59
- ],
- [
- -74,
- -6
- ]
- ],
- [
- [
- 15444,
- 15780
- ],
- [
- 11,
- 51
- ],
- [
- -18,
- 82
- ],
- [
- -40,
- 44
- ],
- [
- -39,
- 14
- ],
- [
- -25,
- 37
- ]
- ],
- [
- [
- 15333,
- 16008
- ],
- [
- 8,
- 14
- ],
- [
- 59,
- -20
- ],
- [
- 103,
- -20
- ],
- [
- 95,
- -57
- ],
- [
- 12,
- -23
- ],
- [
- 42,
- 19
- ],
- [
- 65,
- -25
- ],
- [
- 21,
- -49
- ],
- [
- 44,
- -28
- ]
- ],
- [
- [
- 12549,
- 12119
- ],
- [
- -5,
- -37
- ],
- [
- 29,
- -62
- ],
- [
- 0,
- -87
- ],
- [
- 7,
- -95
- ],
- [
- 17,
- -44
- ],
- [
- -15,
- -108
- ],
- [
- 5,
- -59
- ],
- [
- 19,
- -76
- ],
- [
- 15,
- -43
- ]
- ],
- [
- [
- 12621,
- 11508
- ],
- [
- -109,
- -70
- ],
- [
- -39,
- -41
- ],
- [
- -62,
- -35
- ],
- [
- -63,
- 34
- ]
- ],
- [
- [
- 11959,
- 11719
- ],
- [
- -20,
- 3
- ],
- [
- -14,
- -48
- ],
- [
- -19,
- 1
- ],
- [
- -14,
- 25
- ],
- [
- 5,
- 48
- ],
- [
- -30,
- 74
- ],
- [
- -18,
- -14
- ],
- [
- -15,
- -2
- ]
- ],
- [
- [
- 11834,
- 11806
- ],
- [
- -19,
- -7
- ],
- [
- 1,
- 44
- ],
- [
- -11,
- 31
- ],
- [
- 2,
- 35
- ],
- [
- -15,
- 50
- ],
- [
- -19,
- 43
- ],
- [
- -56,
- 1
- ],
- [
- -16,
- -23
- ],
- [
- -20,
- -3
- ],
- [
- -12,
- -26
- ],
- [
- -8,
- -33
- ],
- [
- -37,
- -53
- ]
- ],
- [
- [
- 11624,
- 11865
- ],
- [
- -30,
- 71
- ],
- [
- -28,
- 47
- ],
- [
- -17,
- 16
- ],
- [
- -18,
- 24
- ],
- [
- -8,
- 53
- ],
- [
- -10,
- 26
- ],
- [
- -20,
- 20
- ]
- ],
- [
- [
- 11493,
- 12122
- ],
- [
- 31,
- 58
- ],
- [
- 21,
- -2
- ],
- [
- 18,
- 20
- ],
- [
- 15,
- 0
- ],
- [
- 11,
- 16
- ],
- [
- -5,
- 40
- ],
- [
- 7,
- 12
- ],
- [
- 1,
- 41
- ]
- ],
- [
- [
- 11592,
- 12307
- ],
- [
- 34,
- -1
- ],
- [
- 50,
- -29
- ],
- [
- 16,
- 2
- ],
- [
- 5,
- 14
- ],
- [
- 38,
- -10
- ],
- [
- 10,
- 7
- ]
- ],
- [
- [
- 11745,
- 12290
- ],
- [
- 4,
- -44
- ],
- [
- 11,
- 0
- ],
- [
- 18,
- 16
- ],
- [
- 12,
- -4
- ],
- [
- 19,
- -30
- ],
- [
- 30,
- -10
- ],
- [
- 19,
- 26
- ],
- [
- 23,
- 16
- ],
- [
- 16,
- 17
- ],
- [
- 14,
- -3
- ],
- [
- 16,
- -27
- ],
- [
- 8,
- -33
- ],
- [
- 29,
- -50
- ],
- [
- -15,
- -31
- ],
- [
- -2,
- -39
- ],
- [
- 14,
- 12
- ],
- [
- 9,
- -14
- ],
- [
- -4,
- -36
- ],
- [
- 22,
- -34
- ]
- ],
- [
- [
- 11374,
- 12375
- ],
- [
- 8,
- 53
- ]
- ],
- [
- [
- 11382,
- 12428
- ],
- [
- 76,
- 4
- ],
- [
- 16,
- 28
- ],
- [
- 22,
- 2
- ],
- [
- 28,
- -30
- ],
- [
- 21,
- 0
- ],
- [
- 23,
- 20
- ],
- [
- 14,
- -35
- ],
- [
- -30,
- -27
- ],
- [
- -30,
- 3
- ],
- [
- -30,
- 25
- ],
- [
- -26,
- -28
- ],
- [
- -12,
- -1
- ],
- [
- -17,
- -17
- ],
- [
- -63,
- 3
- ]
- ],
- [
- [
- 11493,
- 12122
- ],
- [
- -37,
- 50
- ],
- [
- -30,
- 8
- ],
- [
- -16,
- 34
- ],
- [
- 1,
- 18
- ],
- [
- -22,
- 25
- ],
- [
- -4,
- 26
- ]
- ],
- [
- [
- 11385,
- 12283
- ],
- [
- 37,
- 20
- ],
- [
- 23,
- -4
- ],
- [
- 19,
- 13
- ],
- [
- 128,
- -5
- ]
- ],
- [
- [
- 13209,
- 10918
- ],
- [
- -13,
- 18
- ],
- [
- 24,
- 135
- ]
- ],
- [
- [
- 14013,
- 15697
- ],
- [
- 45,
- 11
- ],
- [
- 27,
- 26
- ],
- [
- 38,
- -2
- ],
- [
- 11,
- 20
- ],
- [
- 13,
- 4
- ]
- ],
- [
- [
- 14368,
- 15815
- ],
- [
- 34,
- -32
- ],
- [
- -22,
- -75
- ],
- [
- -16,
- -13
- ]
- ],
- [
- [
- 14364,
- 15695
- ],
- [
- -43,
- 3
- ],
- [
- -36,
- 12
- ],
- [
- -84,
- -32
- ],
- [
- 48,
- -67
- ],
- [
- -35,
- -20
- ],
- [
- -39,
- 0
- ],
- [
- -37,
- 62
- ],
- [
- -13,
- -26
- ],
- [
- 15,
- -72
- ],
- [
- 35,
- -56
- ],
- [
- -26,
- -27
- ],
- [
- 39,
- -55
- ],
- [
- 34,
- -35
- ],
- [
- 1,
- -67
- ],
- [
- -64,
- 31
- ],
- [
- 20,
- -61
- ],
- [
- -44,
- -12
- ],
- [
- 27,
- -106
- ],
- [
- -47,
- -2
- ],
- [
- -57,
- 52
- ],
- [
- -26,
- 96
- ],
- [
- -12,
- 80
- ],
- [
- -27,
- 55
- ],
- [
- -36,
- 69
- ],
- [
- -5,
- 34
- ]
- ],
- [
- [
- 14200,
- 15081
- ],
- [
- 38,
- -41
- ],
- [
- 54,
- 7
- ],
- [
- 52,
- -8
- ],
- [
- -2,
- -21
- ],
- [
- 38,
- 14
- ],
- [
- -9,
- -35
- ],
- [
- -100,
- -10
- ],
- [
- 1,
- 19
- ],
- [
- -85,
- 24
- ],
- [
- 13,
- 51
- ]
- ],
- [
- [
- 9288,
- 20710
- ],
- [
- 234,
- 72
- ],
- [
- 244,
- -6
- ],
- [
- 89,
- 44
- ],
- [
- 247,
- 12
- ],
- [
- 556,
- -15
- ],
- [
- 436,
- -95
- ],
- [
- -128,
- -46
- ],
- [
- -267,
- -6
- ],
- [
- -375,
- -11
- ],
- [
- 35,
- -22
- ],
- [
- 247,
- 13
- ],
- [
- 210,
- -41
- ],
- [
- 135,
- 37
- ],
- [
- 58,
- -43
- ],
- [
- -77,
- -70
- ],
- [
- 178,
- 45
- ],
- [
- 338,
- 46
- ],
- [
- 209,
- -23
- ],
- [
- 39,
- -51
- ],
- [
- -284,
- -86
- ],
- [
- -39,
- -27
- ],
- [
- -223,
- -21
- ],
- [
- 162,
- -6
- ],
- [
- -82,
- -87
- ],
- [
- -56,
- -78
- ],
- [
- 2,
- -134
- ],
- [
- 84,
- -78
- ],
- [
- -109,
- -5
- ],
- [
- -115,
- -38
- ],
- [
- 129,
- -63
- ],
- [
- 16,
- -102
- ],
- [
- -74,
- -11
- ],
- [
- 90,
- -104
- ],
- [
- -155,
- -8
- ],
- [
- 81,
- -49
- ],
- [
- -23,
- -42
- ],
- [
- -98,
- -19
- ],
- [
- -97,
- 0
- ],
- [
- 87,
- -82
- ],
- [
- 1,
- -53
- ],
- [
- -138,
- 50
- ],
- [
- -36,
- -32
- ],
- [
- 94,
- -30
- ],
- [
- 92,
- -74
- ],
- [
- 26,
- -96
- ],
- [
- -124,
- -23
- ],
- [
- -54,
- 46
- ],
- [
- -86,
- 69
- ],
- [
- 24,
- -82
- ],
- [
- -81,
- -63
- ],
- [
- 184,
- -5
- ],
- [
- 96,
- -6
- ],
- [
- -187,
- -105
- ],
- [
- -190,
- -94
- ],
- [
- -204,
- -42
- ],
- [
- -77,
- 0
- ],
- [
- -72,
- -47
- ],
- [
- -97,
- -126
- ],
- [
- -150,
- -84
- ],
- [
- -48,
- -5
- ],
- [
- -93,
- -30
- ],
- [
- -100,
- -28
- ],
- [
- -59,
- -74
- ],
- [
- -1,
- -84
- ],
- [
- -36,
- -79
- ],
- [
- -113,
- -96
- ],
- [
- 28,
- -94
- ],
- [
- -32,
- -99
- ],
- [
- -35,
- -117
- ],
- [
- -99,
- -7
- ],
- [
- -102,
- 98
- ],
- [
- -140,
- 0
- ],
- [
- -67,
- 66
- ],
- [
- -47,
- 117
- ],
- [
- -121,
- 149
- ],
- [
- -35,
- 79
- ],
- [
- -10,
- 107
- ],
- [
- -96,
- 111
- ],
- [
- 25,
- 88
- ],
- [
- -47,
- 43
- ],
- [
- 69,
- 140
- ],
- [
- 105,
- 45
- ],
- [
- 28,
- 50
- ],
- [
- 14,
- 94
- ],
- [
- -79,
- -43
- ],
- [
- -38,
- -18
- ],
- [
- -63,
- -17
- ],
- [
- -85,
- 39
- ],
- [
- -5,
- 82
- ],
- [
- 27,
- 64
- ],
- [
- 65,
- 1
- ],
- [
- 142,
- -32
- ],
- [
- -120,
- 77
- ],
- [
- -62,
- 41
- ],
- [
- -69,
- -17
- ],
- [
- -59,
- 29
- ],
- [
- 78,
- 112
- ],
- [
- -42,
- 45
- ],
- [
- -56,
- 83
- ],
- [
- -83,
- 127
- ],
- [
- -89,
- 47
- ],
- [
- 1,
- 50
- ],
- [
- -187,
- 70
- ],
- [
- -148,
- 9
- ],
- [
- -187,
- -5
- ],
- [
- -170,
- -9
- ],
- [
- -81,
- 38
- ],
- [
- -121,
- 76
- ],
- [
- 183,
- 38
- ],
- [
- 140,
- 6
- ],
- [
- -298,
- 31
- ],
- [
- -157,
- 49
- ],
- [
- 10,
- 47
- ],
- [
- 264,
- 57
- ],
- [
- 255,
- 58
- ],
- [
- 27,
- 44
- ],
- [
- -188,
- 43
- ],
- [
- 60,
- 48
- ],
- [
- 242,
- 83
- ],
- [
- 101,
- 13
- ],
- [
- -29,
- 54
- ],
- [
- 165,
- 32
- ],
- [
- 215,
- 19
- ],
- [
- 214,
- 1
- ],
- [
- 76,
- -38
- ],
- [
- 185,
- 66
- ],
- [
- 166,
- -45
- ],
- [
- 98,
- -9
- ],
- [
- 145,
- -39
- ],
- [
- -166,
- 65
- ],
- [
- 10,
- 51
- ]
- ],
- [
- [
- 6348,
- 12703
- ],
- [
- 23,
- -22
- ],
- [
- 6,
- 18
- ],
- [
- 20,
- -15
- ]
- ],
- [
- [
- 6397,
- 12684
- ],
- [
- -31,
- -46
- ],
- [
- -33,
- -33
- ],
- [
- -5,
- -23
- ],
- [
- 5,
- -24
- ],
- [
- -14,
- -30
- ]
- ],
- [
- [
- 6319,
- 12528
- ],
- [
- -16,
- -8
- ],
- [
- 3,
- -14
- ],
- [
- -13,
- -13
- ],
- [
- -24,
- -30
- ],
- [
- -2,
- -18
- ]
- ],
- [
- [
- 6267,
- 12445
- ],
- [
- -36,
- 21
- ],
- [
- -43,
- 2
- ],
- [
- -32,
- 24
- ],
- [
- -38,
- 49
- ]
- ],
- [
- [
- 6118,
- 12541
- ],
- [
- 2,
- 35
- ],
- [
- 8,
- 28
- ],
- [
- -10,
- 23
- ],
- [
- 34,
- 98
- ],
- [
- 89,
- 0
- ],
- [
- 2,
- 41
- ],
- [
- -11,
- 7
- ],
- [
- -8,
- 26
- ],
- [
- -26,
- 28
- ],
- [
- -26,
- 40
- ],
- [
- 32,
- 0
- ],
- [
- 0,
- 68
- ],
- [
- 65,
- 0
- ],
- [
- 64,
- -1
- ]
- ],
- [
- [
- 8314,
- 11421
- ],
- [
- -47,
- 91
- ],
- [
- 19,
- 33
- ],
- [
- -2,
- 56
- ],
- [
- 43,
- 19
- ],
- [
- 17,
- 22
- ],
- [
- -23,
- 45
- ],
- [
- 6,
- 44
- ],
- [
- 55,
- 70
- ]
- ],
- [
- [
- 8382,
- 11801
- ],
- [
- 46,
- -44
- ],
- [
- 43,
- -78
- ],
- [
- 2,
- -62
- ],
- [
- 26,
- -3
- ],
- [
- 37,
- -58
- ],
- [
- 28,
- -42
- ]
- ],
- [
- [
- 8564,
- 11514
- ],
- [
- -11,
- -108
- ],
- [
- -43,
- -31
- ],
- [
- 4,
- -29
- ],
- [
- -13,
- -62
- ],
- [
- 31,
- -87
- ],
- [
- 23,
- 0
- ],
- [
- 9,
- -68
- ],
- [
- 42,
- -104
- ]
- ],
- [
- [
- 6397,
- 12684
- ],
- [
- 8,
- -5
- ],
- [
- 15,
- 21
- ],
- [
- 20,
- 2
- ],
- [
- 6,
- -10
- ],
- [
- 11,
- 6
- ],
- [
- 33,
- -10
- ],
- [
- 32,
- 3
- ],
- [
- 22,
- 13
- ],
- [
- 8,
- 13
- ],
- [
- 23,
- -6
- ],
- [
- 16,
- -8
- ],
- [
- 19,
- 3
- ],
- [
- 13,
- 10
- ],
- [
- 32,
- -16
- ],
- [
- 11,
- -3
- ],
- [
- 22,
- -23
- ],
- [
- 20,
- -26
- ],
- [
- 25,
- -19
- ],
- [
- 18,
- -33
- ]
- ],
- [
- [
- 6751,
- 12596
- ],
- [
- -23,
- 3
- ],
- [
- -10,
- -17
- ],
- [
- -24,
- -15
- ],
- [
- -18,
- 0
- ],
- [
- -15,
- -16
- ],
- [
- -14,
- 6
- ],
- [
- -12,
- 18
- ],
- [
- -7,
- -3
- ],
- [
- -9,
- -29
- ],
- [
- -7,
- 1
- ],
- [
- -1,
- -25
- ],
- [
- -25,
- -33
- ],
- [
- -12,
- -14
- ],
- [
- -8,
- -15
- ],
- [
- -20,
- 24
- ],
- [
- -15,
- -32
- ],
- [
- -15,
- 1
- ],
- [
- -16,
- -3
- ],
- [
- 1,
- -59
- ],
- [
- -10,
- -1
- ],
- [
- -9,
- -27
- ],
- [
- -21,
- -5
- ]
- ],
- [
- [
- 6461,
- 12355
- ],
- [
- -12,
- 37
- ],
- [
- -21,
- 11
- ]
- ],
- [
- [
- 6428,
- 12403
- ],
- [
- 4,
- 48
- ],
- [
- -9,
- 13
- ],
- [
- -14,
- 9
- ],
- [
- -31,
- -15
- ],
- [
- -3,
- 16
- ],
- [
- -21,
- 20
- ],
- [
- -15,
- 24
- ],
- [
- -20,
- 10
- ]
- ],
- [
- [
- 13841,
- 15914
- ],
- [
- -7,
- -21
- ]
- ],
- [
- [
- 13834,
- 15893
- ],
- [
- -66,
- 45
- ],
- [
- -40,
- 43
- ],
- [
- -64,
- 36
- ],
- [
- -59,
- 88
- ],
- [
- 14,
- 9
- ],
- [
- -31,
- 50
- ],
- [
- -2,
- 41
- ],
- [
- -45,
- 19
- ],
- [
- -21,
- -52
- ],
- [
- -20,
- 40
- ],
- [
- 1,
- 42
- ],
- [
- 3,
- 2
- ]
- ],
- [
- [
- 13504,
- 16256
- ],
- [
- 48,
- -4
- ],
- [
- 13,
- 20
- ],
- [
- 24,
- -20
- ],
- [
- 27,
- -2
- ],
- [
- 0,
- 34
- ],
- [
- 24,
- 12
- ],
- [
- 7,
- 48
- ],
- [
- 55,
- 32
- ]
- ],
- [
- [
- 13702,
- 16376
- ],
- [
- 22,
- -15
- ],
- [
- 52,
- -51
- ],
- [
- 58,
- -23
- ],
- [
- 26,
- 18
- ]
- ],
- [
- [
- 13860,
- 16305
- ],
- [
- 17,
- -47
- ],
- [
- 22,
- -34
- ],
- [
- -27,
- -45
- ]
- ],
- [
- [
- 7549,
- 12962
- ],
- [
- -46,
- 20
- ],
- [
- -33,
- -8
- ],
- [
- -43,
- 9
- ],
- [
- -33,
- -23
- ],
- [
- -37,
- 38
- ],
- [
- 6,
- 38
- ],
- [
- 64,
- -16
- ],
- [
- 53,
- -10
- ],
- [
- 25,
- 27
- ],
- [
- -32,
- 52
- ],
- [
- 1,
- 46
- ],
- [
- -44,
- 18
- ],
- [
- 16,
- 33
- ],
- [
- 42,
- -5
- ],
- [
- 61,
- -19
- ]
- ],
- [
- [
- 13731,
- 16571
- ],
- [
- 36,
- -31
- ],
- [
- 25,
- -13
- ],
- [
- 59,
- 14
- ],
- [
- 5,
- 25
- ],
- [
- 28,
- 3
- ],
- [
- 34,
- 19
- ],
- [
- 8,
- -8
- ],
- [
- 32,
- 15
- ],
- [
- 17,
- 28
- ],
- [
- 23,
- 8
- ],
- [
- 74,
- -37
- ],
- [
- 15,
- 12
- ]
- ],
- [
- [
- 14087,
- 16606
- ],
- [
- 39,
- -32
- ],
- [
- 5,
- -32
- ]
- ],
- [
- [
- 14131,
- 16542
- ],
- [
- -43,
- -26
- ],
- [
- -33,
- -81
- ],
- [
- -42,
- -81
- ],
- [
- -56,
- -23
- ]
- ],
- [
- [
- 13957,
- 16331
- ],
- [
- -43,
- 5
- ],
- [
- -54,
- -31
- ]
- ],
- [
- [
- 13702,
- 16376
- ],
- [
- -13,
- 41
- ],
- [
- -12,
- 1
- ]
- ],
- [
- [
- 20962,
- 9569
- ],
- [
- -29,
- -3
- ],
- [
- -92,
- 85
- ],
- [
- 65,
- 23
- ],
- [
- 36,
- -36
- ],
- [
- 25,
- -37
- ],
- [
- -5,
- -32
- ]
- ],
- [
- [
- 21259,
- 9730
- ],
- [
- 7,
- -23
- ],
- [
- 1,
- -37
- ]
- ],
- [
- [
- 21267,
- 9670
- ],
- [
- -45,
- -89
- ],
- [
- -60,
- -27
- ],
- [
- -8,
- 15
- ],
- [
- 6,
- 40
- ],
- [
- 30,
- 74
- ],
- [
- 69,
- 47
- ]
- ],
- [
- [
- 20766,
- 9826
- ],
- [
- 25,
- -32
- ],
- [
- 43,
- 10
- ],
- [
- 18,
- -51
- ],
- [
- -81,
- -24
- ],
- [
- -48,
- -16
- ],
- [
- -38,
- 1
- ],
- [
- 24,
- 69
- ],
- [
- 38,
- 1
- ],
- [
- 19,
- 42
- ]
- ],
- [
- [
- 21115,
- 9826
- ],
- [
- -10,
- -67
- ],
- [
- -105,
- -34
- ],
- [
- -93,
- 15
- ],
- [
- 0,
- 44
- ],
- [
- 55,
- 25
- ],
- [
- 44,
- -36
- ],
- [
- 46,
- 9
- ],
- [
- 63,
- 44
- ]
- ],
- [
- [
- 20119,
- 9984
- ],
- [
- 134,
- -12
- ],
- [
- 15,
- 50
- ],
- [
- 130,
- -58
- ],
- [
- 25,
- -78
- ],
- [
- 105,
- -22
- ],
- [
- 85,
- -71
- ],
- [
- -79,
- -46
- ],
- [
- -77,
- 49
- ],
- [
- -63,
- -4
- ],
- [
- -72,
- 9
- ],
- [
- -66,
- 22
- ],
- [
- -80,
- 46
- ],
- [
- -52,
- 11
- ],
- [
- -29,
- -15
- ],
- [
- -127,
- 50
- ],
- [
- -12,
- 51
- ],
- [
- -64,
- 9
- ],
- [
- 48,
- 115
- ],
- [
- 85,
- -7
- ],
- [
- 56,
- -47
- ],
- [
- 29,
- -9
- ],
- [
- 9,
- -43
- ]
- ],
- [
- [
- 21939,
- 10052
- ],
- [
- -36,
- -82
- ],
- [
- -7,
- 90
- ],
- [
- 13,
- 43
- ],
- [
- 14,
- 41
- ],
- [
- 16,
- -35
- ],
- [
- 0,
- -57
- ]
- ],
- [
- [
- 21418,
- 10382
- ],
- [
- -26,
- -40
- ],
- [
- -48,
- 22
- ],
- [
- -14,
- 52
- ],
- [
- 71,
- 6
- ],
- [
- 17,
- -40
- ]
- ],
- [
- [
- 21642,
- 10426
- ],
- [
- 26,
- -92
- ],
- [
- -59,
- 50
- ],
- [
- -58,
- 10
- ],
- [
- -40,
- -8
- ],
- [
- -48,
- 4
- ],
- [
- 17,
- 66
- ],
- [
- 86,
- 5
- ],
- [
- 76,
- -35
- ]
- ],
- [
- [
- 22376,
- 10485
- ],
- [
- 2,
- -391
- ],
- [
- 1,
- -391
- ]
- ],
- [
- [
- 22379,
- 9703
- ],
- [
- -62,
- 99
- ],
- [
- -71,
- 24
- ],
- [
- -17,
- -34
- ],
- [
- -89,
- -4
- ],
- [
- 30,
- 98
- ],
- [
- 44,
- 33
- ],
- [
- -18,
- 130
- ],
- [
- -34,
- 101
- ],
- [
- -135,
- 102
- ],
- [
- -57,
- 10
- ],
- [
- -105,
- 111
- ],
- [
- -21,
- -59
- ],
- [
- -26,
- -10
- ],
- [
- -16,
- 44
- ],
- [
- 0,
- 52
- ],
- [
- -54,
- 59
- ],
- [
- 75,
- 43
- ],
- [
- 50,
- -2
- ],
- [
- -6,
- 32
- ],
- [
- -102,
- 0
- ],
- [
- -27,
- 71
- ],
- [
- -63,
- 22
- ],
- [
- -29,
- 60
- ],
- [
- 94,
- 29
- ],
- [
- 35,
- 39
- ],
- [
- 112,
- -49
- ],
- [
- 11,
- -45
- ],
- [
- 20,
- -194
- ],
- [
- 72,
- -72
- ],
- [
- 58,
- 127
- ],
- [
- 80,
- 73
- ],
- [
- 62,
- 0
- ],
- [
- 60,
- -42
- ],
- [
- 52,
- -43
- ],
- [
- 74,
- -23
- ]
- ],
- [
- [
- 21278,
- 10968
- ],
- [
- -56,
- -119
- ],
- [
- -53,
- -24
- ],
- [
- -67,
- 24
- ],
- [
- -116,
- -6
- ],
- [
- -61,
- -17
- ],
- [
- -10,
- -91
- ],
- [
- 63,
- -107
- ],
- [
- 37,
- 55
- ],
- [
- 130,
- 40
- ],
- [
- -5,
- -55
- ],
- [
- -31,
- 18
- ],
- [
- -30,
- -71
- ],
- [
- -61,
- -46
- ],
- [
- 66,
- -154
- ],
- [
- -13,
- -41
- ],
- [
- 63,
- -139
- ],
- [
- -1,
- -79
- ],
- [
- -37,
- -35
- ],
- [
- -28,
- 42
- ],
- [
- 34,
- 99
- ],
- [
- -68,
- -47
- ],
- [
- -18,
- 33
- ],
- [
- 9,
- 47
- ],
- [
- -50,
- 70
- ],
- [
- 5,
- 117
- ],
- [
- -46,
- -37
- ],
- [
- 6,
- -139
- ],
- [
- 3,
- -172
- ],
- [
- -45,
- -17
- ],
- [
- -30,
- 35
- ],
- [
- 20,
- 110
- ],
- [
- -10,
- 116
- ],
- [
- -30,
- 1
- ],
- [
- -21,
- 82
- ],
- [
- 28,
- 79
- ],
- [
- 10,
- 95
- ],
- [
- 35,
- 181
- ],
- [
- 15,
- 49
- ],
- [
- 59,
- 89
- ],
- [
- 55,
- -35
- ],
- [
- 88,
- -17
- ],
- [
- 80,
- 5
- ],
- [
- 69,
- 87
- ],
- [
- 12,
- -26
- ]
- ],
- [
- [
- 21518,
- 10933
- ],
- [
- -4,
- -105
- ],
- [
- -35,
- 12
- ],
- [
- -11,
- -73
- ],
- [
- 29,
- -63
- ],
- [
- -20,
- -15
- ],
- [
- -28,
- 76
- ],
- [
- -21,
- 154
- ],
- [
- 14,
- 95
- ],
- [
- 23,
- 44
- ],
- [
- 5,
- -65
- ],
- [
- 42,
- -11
- ],
- [
- 6,
- -49
- ]
- ],
- [
- [
- 20192,
- 11038
- ],
- [
- 12,
- -80
- ],
- [
- 47,
- -68
- ],
- [
- 45,
- 24
- ],
- [
- 45,
- -8
- ],
- [
- 40,
- 60
- ],
- [
- 34,
- 11
- ],
- [
- 66,
- -34
- ],
- [
- 57,
- 26
- ],
- [
- 35,
- 167
- ],
- [
- 27,
- 41
- ],
- [
- 24,
- 137
- ],
- [
- 80,
- 0
- ],
- [
- 61,
- -20
- ]
- ],
- [
- [
- 20765,
- 11294
- ],
- [
- -40,
- -109
- ],
- [
- 51,
- -113
- ],
- [
- -12,
- -56
- ],
- [
- 79,
- -111
- ],
- [
- -83,
- -14
- ],
- [
- -23,
- -82
- ],
- [
- 3,
- -108
- ],
- [
- -67,
- -82
- ],
- [
- -2,
- -120
- ],
- [
- -27,
- -183
- ],
- [
- -10,
- 42
- ],
- [
- -79,
- -54
- ],
- [
- -28,
- 74
- ],
- [
- -50,
- 7
- ],
- [
- -35,
- 38
- ],
- [
- -82,
- -43
- ],
- [
- -26,
- 58
- ],
- [
- -46,
- -7
- ],
- [
- -57,
- 14
- ],
- [
- -11,
- 161
- ],
- [
- -34,
- 33
- ],
- [
- -34,
- 103
- ],
- [
- -10,
- 105
- ],
- [
- 9,
- 111
- ],
- [
- 41,
- 80
- ]
- ],
- [
- [
- 19924,
- 10095
- ],
- [
- -77,
- -2
- ],
- [
- -59,
- 100
- ],
- [
- -90,
- 98
- ],
- [
- -29,
- 73
- ],
- [
- -53,
- 97
- ],
- [
- -35,
- 90
- ],
- [
- -53,
- 168
- ],
- [
- -61,
- 100
- ],
- [
- -20,
- 103
- ],
- [
- -26,
- 94
- ],
- [
- -63,
- 75
- ],
- [
- -36,
- 103
- ],
- [
- -53,
- 67
- ],
- [
- -73,
- 133
- ],
- [
- -6,
- 61
- ],
- [
- 45,
- -5
- ],
- [
- 108,
- -23
- ],
- [
- 62,
- -118
- ],
- [
- 54,
- -81
- ],
- [
- 38,
- -50
- ],
- [
- 66,
- -129
- ],
- [
- 71,
- -2
- ],
- [
- 58,
- -82
- ],
- [
- 41,
- -100
- ],
- [
- 53,
- -55
- ],
- [
- -28,
- -98
- ],
- [
- 40,
- -42
- ],
- [
- 25,
- -3
- ],
- [
- 12,
- -84
- ],
- [
- 24,
- -67
- ],
- [
- 51,
- -10
- ],
- [
- 34,
- -76
- ],
- [
- -17,
- -149
- ],
- [
- -3,
- -186
- ]
- ],
- [
- [
- 18754,
- 13443
- ],
- [
- -10,
- -44
- ],
- [
- -48,
- 2
- ],
- [
- -86,
- -25
- ],
- [
- 4,
- -90
- ],
- [
- -37,
- -71
- ],
- [
- -100,
- -81
- ],
- [
- -78,
- -141
- ],
- [
- -53,
- -76
- ],
- [
- -69,
- -78
- ],
- [
- 0,
- -56
- ],
- [
- -35,
- -29
- ],
- [
- -63,
- -43
- ],
- [
- -32,
- -6
- ],
- [
- -21,
- -92
- ],
- [
- 14,
- -156
- ],
- [
- 4,
- -99
- ],
- [
- -29,
- -114
- ],
- [
- -1,
- -204
- ],
- [
- -36,
- -6
- ],
- [
- -32,
- -92
- ],
- [
- 22,
- -39
- ],
- [
- -64,
- -34
- ],
- [
- -23,
- -82
- ],
- [
- -28,
- -34
- ],
- [
- -66,
- 112
- ],
- [
- -33,
- 168
- ],
- [
- -26,
- 121
- ],
- [
- -25,
- 57
- ],
- [
- -37,
- 115
- ],
- [
- -17,
- 150
- ],
- [
- -12,
- 75
- ],
- [
- -64,
- 165
- ],
- [
- -28,
- 232
- ],
- [
- -21,
- 154
- ],
- [
- 0,
- 145
- ],
- [
- -14,
- 112
- ],
- [
- -101,
- -72
- ],
- [
- -49,
- 15
- ],
- [
- -91,
- 145
- ],
- [
- 33,
- 44
- ],
- [
- -20,
- 47
- ],
- [
- -82,
- 101
- ]
- ],
- [
- [
- 17300,
- 13639
- ],
- [
- 46,
- 81
- ],
- [
- 154,
- -1
- ],
- [
- -14,
- 103
- ],
- [
- -39,
- 61
- ],
- [
- -8,
- 92
- ],
- [
- -46,
- 54
- ],
- [
- 77,
- 126
- ],
- [
- 81,
- -9
- ],
- [
- 73,
- 126
- ],
- [
- 44,
- 121
- ],
- [
- 67,
- 121
- ],
- [
- -1,
- 85
- ],
- [
- 60,
- 70
- ],
- [
- -57,
- 59
- ],
- [
- -24,
- 81
- ],
- [
- -25,
- 105
- ],
- [
- 35,
- 52
- ],
- [
- 105,
- -29
- ],
- [
- 78,
- 18
- ],
- [
- 67,
- 100
- ]
- ],
- [
- [
- 18202,
- 14418
- ],
- [
- -45,
- -54
- ],
- [
- -27,
- -112
- ],
- [
- 68,
- -46
- ],
- [
- 66,
- -59
- ],
- [
- 91,
- -67
- ],
- [
- 95,
- -15
- ],
- [
- 40,
- -61
- ],
- [
- 54,
- -12
- ],
- [
- 84,
- -28
- ],
- [
- 58,
- 2
- ],
- [
- 8,
- 48
- ],
- [
- -9,
- 76
- ],
- [
- 5,
- 52
- ]
- ],
- [
- [
- 19332,
- 14188
- ],
- [
- 5,
- -46
- ],
- [
- -24,
- -22
- ],
- [
- 6,
- -74
- ],
- [
- -50,
- 22
- ],
- [
- -91,
- -83
- ],
- [
- 3,
- -68
- ],
- [
- -39,
- -101
- ],
- [
- -3,
- -59
- ],
- [
- -31,
- -98
- ],
- [
- -55,
- 27
- ],
- [
- -3,
- -124
- ],
- [
- -15,
- -41
- ],
- [
- 7,
- -51
- ],
- [
- -34,
- -29
- ]
- ],
- [
- [
- 12115,
- 17260
- ],
- [
- 12,
- -86
- ],
- [
- -53,
- -107
- ],
- [
- -123,
- -71
- ],
- [
- -99,
- 18
- ],
- [
- 57,
- 125
- ],
- [
- -37,
- 122
- ],
- [
- 95,
- 94
- ],
- [
- 53,
- 56
- ]
- ],
- [
- [
- 16791,
- 14376
- ],
- [
- 34,
- -63
- ],
- [
- 29,
- -73
- ],
- [
- 66,
- -53
- ],
- [
- 2,
- -105
- ],
- [
- 33,
- -20
- ],
- [
- 6,
- -55
- ],
- [
- -100,
- -62
- ],
- [
- -27,
- -139
- ]
- ],
- [
- [
- 16834,
- 13806
- ],
- [
- -131,
- 36
- ],
- [
- -76,
- 28
- ],
- [
- -78,
- 15
- ],
- [
- -30,
- 147
- ],
- [
- -34,
- 22
- ],
- [
- -53,
- -22
- ],
- [
- -70,
- -58
- ],
- [
- -86,
- 40
- ],
- [
- -70,
- 92
- ],
- [
- -67,
- 34
- ],
- [
- -47,
- 114
- ],
- [
- -51,
- 160
- ],
- [
- -38,
- -19
- ],
- [
- -44,
- 39
- ],
- [
- -26,
- -47
- ]
- ],
- [
- [
- 15933,
- 14387
- ],
- [
- -38,
- 64
- ],
- [
- -1,
- 63
- ],
- [
- -22,
- 0
- ],
- [
- 11,
- 87
- ],
- [
- -36,
- 91
- ],
- [
- -85,
- 66
- ],
- [
- -49,
- 114
- ],
- [
- 17,
- 94
- ],
- [
- 35,
- 41
- ],
- [
- -6,
- 70
- ],
- [
- -45,
- 36
- ],
- [
- -45,
- 143
- ]
- ],
- [
- [
- 15669,
- 15256
- ],
- [
- -39,
- 97
- ],
- [
- 14,
- 37
- ],
- [
- -22,
- 137
- ],
- [
- 48,
- 35
- ]
- ],
- [
- [
- 15955,
- 15394
- ],
- [
- 22,
- -88
- ],
- [
- 66,
- -25
- ],
- [
- 49,
- -60
- ],
- [
- 99,
- -21
- ],
- [
- 109,
- 32
- ],
- [
- 6,
- 28
- ]
- ],
- [
- [
- 16306,
- 15260
- ],
- [
- 62,
- 23
- ],
- [
- 49,
- 69
- ],
- [
- 47,
- -4
- ],
- [
- 30,
- 23
- ],
- [
- 50,
- -11
- ],
- [
- 77,
- -61
- ],
- [
- 56,
- -13
- ],
- [
- 79,
- -107
- ],
- [
- 52,
- -4
- ],
- [
- 6,
- -101
- ]
- ],
- [
- [
- 15933,
- 14387
- ],
- [
- -41,
- 6
- ]
- ],
- [
- [
- 15892,
- 14393
- ],
- [
- -47,
- 10
- ],
- [
- -51,
- -115
- ]
- ],
- [
- [
- 15794,
- 14288
- ],
- [
- -130,
- 10
- ],
- [
- -196,
- 241
- ],
- [
- -104,
- 84
- ],
- [
- -84,
- 33
- ]
- ],
- [
- [
- 15280,
- 14656
- ],
- [
- -28,
- 146
- ]
- ],
- [
- [
- 15252,
- 14802
- ],
- [
- 154,
- 124
- ],
- [
- 26,
- 145
- ],
- [
- -6,
- 88
- ],
- [
- 38,
- 30
- ],
- [
- 36,
- 75
- ]
- ],
- [
- [
- 15500,
- 15264
- ],
- [
- 30,
- 18
- ],
- [
- 81,
- -15
- ],
- [
- 24,
- -31
- ],
- [
- 34,
- 20
- ]
- ],
- [
- [
- 11536,
- 18770
- ],
- [
- -16,
- -78
- ],
- [
- 79,
- -82
- ],
- [
- -91,
- -91
- ],
- [
- -201,
- -82
- ],
- [
- -60,
- -22
- ],
- [
- -92,
- 17
- ],
- [
- -194,
- 38
- ],
- [
- 68,
- 53
- ],
- [
- -151,
- 59
- ],
- [
- 123,
- 23
- ],
- [
- -3,
- 36
- ],
- [
- -146,
- 27
- ],
- [
- 47,
- 79
- ],
- [
- 106,
- 17
- ],
- [
- 108,
- -81
- ],
- [
- 106,
- 65
- ],
- [
- 88,
- -34
- ],
- [
- 113,
- 64
- ],
- [
- 116,
- -8
- ]
- ],
- [
- [
- 14936,
- 14543
- ],
- [
- 20,
- 39
- ],
- [
- -4,
- 7
- ],
- [
- 18,
- 56
- ],
- [
- 14,
- 90
- ],
- [
- 10,
- 31
- ],
- [
- 2,
- 1
- ]
- ],
- [
- [
- 14996,
- 14767
- ],
- [
- 23,
- 0
- ],
- [
- 7,
- 21
- ],
- [
- 19,
- 1
- ]
- ],
- [
- [
- 15045,
- 14789
- ],
- [
- 1,
- -49
- ],
- [
- -10,
- -18
- ],
- [
- 1,
- -1
- ]
- ],
- [
- [
- 15037,
- 14721
- ],
- [
- -12,
- -38
- ]
- ],
- [
- [
- 15025,
- 14683
- ],
- [
- -25,
- 17
- ],
- [
- -14,
- -80
- ],
- [
- 17,
- -13
- ],
- [
- -18,
- -17
- ],
- [
- -3,
- -31
- ],
- [
- 33,
- 16
- ]
- ],
- [
- [
- 15015,
- 14575
- ],
- [
- 2,
- -47
- ],
- [
- -35,
- -192
- ]
- ],
- [
- [
- 13510,
- 16377
- ],
- [
- -8,
- -59
- ],
- [
- 17,
- -51
- ]
- ],
- [
- [
- 13519,
- 16267
- ],
- [
- -55,
- 17
- ],
- [
- -57,
- -42
- ],
- [
- 4,
- -60
- ],
- [
- -9,
- -34
- ],
- [
- 23,
- -61
- ],
- [
- 65,
- -61
- ],
- [
- 35,
- -99
- ],
- [
- 78,
- -96
- ],
- [
- 55,
- 0
- ],
- [
- 17,
- -26
- ],
- [
- -20,
- -24
- ],
- [
- 63,
- -44
- ],
- [
- 51,
- -36
- ],
- [
- 60,
- -62
- ],
- [
- 7,
- -23
- ],
- [
- -13,
- -43
- ],
- [
- -39,
- 56
- ],
- [
- -61,
- 20
- ],
- [
- -29,
- -78
- ],
- [
- 50,
- -44
- ],
- [
- -8,
- -63
- ],
- [
- -29,
- -7
- ],
- [
- -37,
- -103
- ],
- [
- -29,
- -9
- ],
- [
- 0,
- 37
- ],
- [
- 14,
- 64
- ],
- [
- 15,
- 26
- ],
- [
- -27,
- 69
- ],
- [
- -21,
- 61
- ],
- [
- -29,
- 15
- ],
- [
- -21,
- 51
- ],
- [
- -44,
- 22
- ],
- [
- -31,
- 49
- ],
- [
- -51,
- 7
- ],
- [
- -55,
- 54
- ],
- [
- -63,
- 79
- ],
- [
- -48,
- 69
- ],
- [
- -21,
- 118
- ],
- [
- -35,
- 14
- ],
- [
- -57,
- 40
- ],
- [
- -32,
- -16
- ],
- [
- -40,
- -56
- ],
- [
- -29,
- -9
- ]
- ],
- [
- [
- 13629,
- 15384
- ],
- [
- -25,
- -95
- ],
- [
- 11,
- -37
- ],
- [
- -15,
- -62
- ],
- [
- -53,
- 46
- ],
- [
- -36,
- 13
- ],
- [
- -97,
- 61
- ],
- [
- 10,
- 61
- ],
- [
- 81,
- -11
- ],
- [
- 71,
- 13
- ],
- [
- 53,
- 11
- ]
- ],
- [
- [
- 13190,
- 15741
- ],
- [
- 41,
- -85
- ],
- [
- -9,
- -159
- ],
- [
- -32,
- 8
- ],
- [
- -29,
- -40
- ],
- [
- -26,
- 32
- ],
- [
- -3,
- 144
- ],
- [
- -16,
- 69
- ],
- [
- 39,
- -6
- ],
- [
- 35,
- 37
- ]
- ],
- [
- [
- 7140,
- 13015
- ],
- [
- 47,
- -10
- ],
- [
- 37,
- -29
- ],
- [
- 12,
- -33
- ],
- [
- -49,
- -2
- ],
- [
- -21,
- -20
- ],
- [
- -39,
- 19
- ],
- [
- -40,
- 44
- ],
- [
- 8,
- 27
- ],
- [
- 29,
- 9
- ],
- [
- 16,
- -5
- ]
- ],
- [
- [
- 15280,
- 14656
- ],
- [
- -14,
- -19
- ],
- [
- -139,
- -60
- ],
- [
- 69,
- -120
- ],
- [
- -23,
- -20
- ],
- [
- -11,
- -40
- ],
- [
- -53,
- -17
- ],
- [
- -17,
- -43
- ],
- [
- -30,
- -37
- ],
- [
- -78,
- 19
- ]
- ],
- [
- [
- 14984,
- 14319
- ],
- [
- -2,
- 17
- ]
- ],
- [
- [
- 15015,
- 14575
- ],
- [
- 10,
- 35
- ],
- [
- 0,
- 73
- ]
- ],
- [
- [
- 15037,
- 14721
- ],
- [
- 78,
- -47
- ],
- [
- 137,
- 128
- ]
- ],
- [
- [
- 21933,
- 14894
- ],
- [
- 9,
- -41
- ],
- [
- -39,
- -73
- ],
- [
- -29,
- 39
- ],
- [
- -36,
- -28
- ],
- [
- -18,
- -70
- ],
- [
- -46,
- 34
- ],
- [
- 1,
- 57
- ],
- [
- 38,
- 71
- ],
- [
- 40,
- -14
- ],
- [
- 29,
- 51
- ],
- [
- 51,
- -26
- ]
- ],
- [
- [
- 22375,
- 15253
- ],
- [
- -27,
- -96
- ],
- [
- 13,
- -60
- ],
- [
- -37,
- -84
- ],
- [
- -89,
- -57
- ],
- [
- -122,
- -7
- ],
- [
- -100,
- -137
- ],
- [
- -46,
- 46
- ],
- [
- -3,
- 90
- ],
- [
- -122,
- -27
- ],
- [
- -82,
- -56
- ],
- [
- -82,
- -3
- ],
- [
- 71,
- -88
- ],
- [
- -47,
- -204
- ],
- [
- -45,
- -50
- ],
- [
- -33,
- 46
- ],
- [
- 17,
- 109
- ],
- [
- -44,
- 34
- ],
- [
- -29,
- 83
- ],
- [
- 66,
- 37
- ],
- [
- 37,
- 75
- ],
- [
- 70,
- 62
- ],
- [
- 51,
- 82
- ],
- [
- 139,
- 36
- ],
- [
- 74,
- -25
- ],
- [
- 73,
- 214
- ],
- [
- 47,
- -58
- ],
- [
- 102,
- 120
- ],
- [
- 40,
- 47
- ],
- [
- 43,
- 147
- ],
- [
- -11,
- 135
- ],
- [
- 29,
- 75
- ],
- [
- 74,
- 22
- ],
- [
- 38,
- -166
- ],
- [
- -2,
- -97
- ],
- [
- -64,
- -121
- ],
- [
- 1,
- -124
- ]
- ],
- [
- [
- 22579,
- 16097
- ],
- [
- 49,
- -26
- ],
- [
- 50,
- 51
- ],
- [
- 15,
- -135
- ],
- [
- -103,
- -33
- ],
- [
- -61,
- -119
- ],
- [
- -110,
- 82
- ],
- [
- -38,
- -131
- ],
- [
- -77,
- -2
- ],
- [
- -10,
- 120
- ],
- [
- 34,
- 92
- ],
- [
- 75,
- 6
- ],
- [
- 20,
- 166
- ],
- [
- 21,
- 94
- ],
- [
- 82,
- -125
- ],
- [
- 53,
- -40
- ]
- ],
- [
- [
- 18142,
- 15878
- ],
- [
- -43,
- 17
- ],
- [
- -35,
- 44
- ],
- [
- -103,
- 12
- ],
- [
- -116,
- 3
- ],
- [
- -25,
- -13
- ],
- [
- -99,
- 51
- ],
- [
- -40,
- -25
- ],
- [
- -11,
- -71
- ],
- [
- -114,
- 41
- ],
- [
- -46,
- -17
- ],
- [
- -16,
- -52
- ]
- ],
- [
- [
- 17494,
- 15868
- ],
- [
- -40,
- -22
- ],
- [
- -92,
- -84
- ],
- [
- -30,
- -86
- ],
- [
- -26,
- -1
- ],
- [
- -19,
- 57
- ],
- [
- -89,
- 4
- ],
- [
- -14,
- 98
- ],
- [
- -34,
- 1
- ],
- [
- 5,
- 121
- ],
- [
- -83,
- 87
- ],
- [
- -120,
- -9
- ],
- [
- -82,
- -18
- ],
- [
- -66,
- 109
- ],
- [
- -57,
- 45
- ],
- [
- -108,
- 86
- ],
- [
- -13,
- 10
- ],
- [
- -180,
- -71
- ],
- [
- 3,
- -442
- ]
- ],
- [
- [
- 16449,
- 15753
- ],
- [
- -36,
- -6
- ],
- [
- -49,
- 94
- ],
- [
- -47,
- 34
- ],
- [
- -79,
- -25
- ],
- [
- -31,
- -40
- ]
- ],
- [
- [
- 16207,
- 15810
- ],
- [
- -4,
- 29
- ],
- [
- 18,
- 50
- ],
- [
- -14,
- 42
- ],
- [
- -81,
- 41
- ],
- [
- -31,
- 108
- ],
- [
- -38,
- 30
- ],
- [
- -3,
- 39
- ],
- [
- 68,
- -11
- ],
- [
- 3,
- 87
- ],
- [
- 59,
- 20
- ],
- [
- 61,
- -18
- ],
- [
- 12,
- 117
- ],
- [
- -12,
- 74
- ],
- [
- -70,
- -6
- ],
- [
- -59,
- 30
- ],
- [
- -81,
- -53
- ],
- [
- -65,
- -25
- ]
- ],
- [
- [
- 15970,
- 16364
- ],
- [
- -35,
- 19
- ],
- [
- 7,
- 62
- ],
- [
- -45,
- 80
- ],
- [
- -51,
- -3
- ],
- [
- -59,
- 81
- ],
- [
- 40,
- 91
- ],
- [
- -21,
- 24
- ],
- [
- 56,
- 132
- ],
- [
- 72,
- -69
- ],
- [
- 8,
- 87
- ],
- [
- 144,
- 131
- ],
- [
- 109,
- 3
- ],
- [
- 154,
- -83
- ],
- [
- 82,
- -49
- ],
- [
- 74,
- 51
- ],
- [
- 111,
- 2
- ],
- [
- 89,
- -62
- ],
- [
- 20,
- 36
- ],
- [
- 98,
- -6
- ],
- [
- 18,
- 57
- ],
- [
- -113,
- 83
- ],
- [
- 67,
- 58
- ],
- [
- -13,
- 33
- ],
- [
- 67,
- 31
- ],
- [
- -51,
- 82
- ],
- [
- 32,
- 41
- ],
- [
- 261,
- 42
- ],
- [
- 34,
- 30
- ],
- [
- 174,
- 44
- ],
- [
- 63,
- 50
- ],
- [
- 125,
- -26
- ],
- [
- 22,
- -125
- ],
- [
- 73,
- 30
- ],
- [
- 90,
- -41
- ],
- [
- -6,
- -66
- ],
- [
- 67,
- 7
- ],
- [
- 174,
- 113
- ],
- [
- -25,
- -37
- ],
- [
- 89,
- -93
- ],
- [
- 156,
- -305
- ],
- [
- 37,
- 63
- ],
- [
- 96,
- -69
- ],
- [
- 100,
- 31
- ],
- [
- 38,
- -22
- ],
- [
- 34,
- -69
- ],
- [
- 49,
- -23
- ],
- [
- 29,
- -51
- ],
- [
- 90,
- 16
- ],
- [
- 37,
- -74
- ]
- ],
- [
- [
- 15465,
- 11267
- ],
- [
- -61,
- -136
- ],
- [
- 1,
- -437
- ],
- [
- 41,
- -99
- ]
- ],
- [
- [
- 15446,
- 10595
- ],
- [
- -48,
- -48
- ],
- [
- -18,
- -50
- ],
- [
- -26,
- -8
- ],
- [
- -10,
- -85
- ],
- [
- -22,
- -48
- ],
- [
- -14,
- -80
- ],
- [
- -28,
- -40
- ]
- ],
- [
- [
- 15280,
- 10236
- ],
- [
- -100,
- 120
- ],
- [
- -5,
- 70
- ],
- [
- -252,
- 244
- ],
- [
- -12,
- 13
- ]
- ],
- [
- [
- 14911,
- 10683
- ],
- [
- -1,
- 127
- ],
- [
- 20,
- 49
- ],
- [
- 34,
- 79
- ],
- [
- 26,
- 88
- ],
- [
- -31,
- 138
- ],
- [
- -8,
- 60
- ],
- [
- -33,
- 83
- ]
- ],
- [
- [
- 14918,
- 11307
- ],
- [
- 43,
- 72
- ],
- [
- 47,
- 79
- ]
- ],
- [
- [
- 17683,
- 15528
- ],
- [
- -132,
- -18
- ],
- [
- -86,
- 38
- ],
- [
- -75,
- -9
- ],
- [
- 6,
- 69
- ],
- [
- 76,
- -20
- ],
- [
- 26,
- 37
- ]
- ],
- [
- [
- 17498,
- 15625
- ],
- [
- 53,
- -12
- ],
- [
- 89,
- 87
- ],
- [
- -83,
- 63
- ],
- [
- -49,
- -30
- ],
- [
- -52,
- 45
- ],
- [
- 59,
- 78
- ],
- [
- -21,
- 12
- ]
- ],
- [
- [
- 19699,
- 12259
- ],
- [
- -17,
- 145
- ],
- [
- 45,
- 100
- ],
- [
- 90,
- 23
- ],
- [
- 65,
- -17
- ]
- ],
- [
- [
- 19882,
- 12510
- ],
- [
- 58,
- -48
- ],
- [
- 31,
- 83
- ],
- [
- 62,
- -44
- ]
- ],
- [
- [
- 20033,
- 12501
- ],
- [
- 16,
- -80
- ],
- [
- -8,
- -144
- ],
- [
- -118,
- -92
- ],
- [
- 31,
- -73
- ],
- [
- -73,
- -8
- ],
- [
- -61,
- -49
- ]
- ],
- [
- [
- 19820,
- 12055
- ],
- [
- -58,
- 18
- ],
- [
- -28,
- 62
- ],
- [
- -35,
- 124
- ]
- ],
- [
- [
- 21495,
- 15429
- ],
- [
- 60,
- -141
- ],
- [
- 17,
- -78
- ],
- [
- 1,
- -138
- ],
- [
- -27,
- -66
- ],
- [
- -63,
- -23
- ],
- [
- -56,
- -50
- ],
- [
- -62,
- -10
- ],
- [
- -8,
- 65
- ],
- [
- 13,
- 90
- ],
- [
- -31,
- 125
- ],
- [
- 52,
- 20
- ],
- [
- -48,
- 103
- ]
- ],
- [
- [
- 21343,
- 15326
- ],
- [
- 4,
- 11
- ],
- [
- 31,
- -4
- ],
- [
- 28,
- 54
- ],
- [
- 49,
- 6
- ],
- [
- 30,
- 7
- ],
- [
- 10,
- 29
- ]
- ],
- [
- [
- 13947,
- 15907
- ],
- [
- 13,
- 26
- ]
- ],
- [
- [
- 13960,
- 15933
- ],
- [
- 16,
- 9
- ],
- [
- 10,
- 40
- ],
- [
- 12,
- 6
- ],
- [
- 10,
- -16
- ],
- [
- 13,
- -8
- ],
- [
- 9,
- -19
- ],
- [
- 12,
- -6
- ],
- [
- 14,
- -22
- ],
- [
- 9,
- 1
- ],
- [
- -7,
- -29
- ],
- [
- -9,
- -15
- ],
- [
- 3,
- -9
- ]
- ],
- [
- [
- 14052,
- 15865
- ],
- [
- -16,
- -4
- ],
- [
- -41,
- -19
- ],
- [
- -3,
- -24
- ],
- [
- -9,
- 1
- ]
- ],
- [
- [
- 15892,
- 14393
- ],
- [
- 14,
- -53
- ],
- [
- -6,
- -27
- ],
- [
- 23,
- -90
- ]
- ],
- [
- [
- 15923,
- 14223
- ],
- [
- -50,
- -4
- ],
- [
- -17,
- 58
- ],
- [
- -62,
- 11
- ]
- ],
- [
- [
- 19670,
- 13492
- ],
- [
- 40,
- -94
- ],
- [
- 32,
- -109
- ],
- [
- 85,
- -1
- ],
- [
- 28,
- -105
- ],
- [
- -45,
- -31
- ],
- [
- -20,
- -44
- ],
- [
- 83,
- -71
- ],
- [
- 58,
- -142
- ],
- [
- 44,
- -106
- ],
- [
- 53,
- -83
- ],
- [
- 18,
- -85
- ],
- [
- -13,
- -120
- ]
- ],
- [
- [
- 19882,
- 12510
- ],
- [
- 23,
- 54
- ],
- [
- 3,
- 101
- ],
- [
- -57,
- 105
- ],
- [
- -4,
- 118
- ],
- [
- -53,
- 98
- ],
- [
- -53,
- 8
- ],
- [
- -14,
- -42
- ],
- [
- -40,
- -3
- ],
- [
- -21,
- 21
- ],
- [
- -74,
- -72
- ],
- [
- -1,
- 108
- ],
- [
- 17,
- 126
- ],
- [
- -47,
- 6
- ],
- [
- -4,
- 72
- ],
- [
- -31,
- 37
- ]
- ],
- [
- [
- 19526,
- 13247
- ],
- [
- 15,
- 44
- ],
- [
- 60,
- 78
- ]
- ],
- [
- [
- 14996,
- 14767
- ],
- [
- 25,
- 98
- ],
- [
- 35,
- 84
- ],
- [
- 1,
- 5
- ]
- ],
- [
- [
- 15057,
- 14954
- ],
- [
- 31,
- -7
- ],
- [
- 12,
- -47
- ],
- [
- -38,
- -45
- ],
- [
- -17,
- -66
- ]
- ],
- [
- [
- 12010,
- 11321
- ],
- [
- -18,
- -1
- ],
- [
- -72,
- 57
- ],
- [
- -64,
- 91
- ],
- [
- -59,
- 66
- ],
- [
- -47,
- 77
- ]
- ],
- [
- [
- 11750,
- 11611
- ],
- [
- 17,
- 39
- ],
- [
- 3,
- 35
- ],
- [
- 32,
- 65
- ],
- [
- 32,
- 56
- ]
- ],
- [
- [
- 13208,
- 14433
- ],
- [
- 34,
- 28
- ],
- [
- 7,
- 51
- ],
- [
- -8,
- 49
- ],
- [
- 48,
- 47
- ],
- [
- 21,
- 38
- ],
- [
- 34,
- 34
- ],
- [
- 4,
- 93
- ]
- ],
- [
- [
- 13348,
- 14773
- ],
- [
- 82,
- -42
- ],
- [
- 30,
- 11
- ],
- [
- 58,
- -20
- ],
- [
- 92,
- -54
- ],
- [
- 33,
- -107
- ],
- [
- 62,
- -23
- ],
- [
- 99,
- -50
- ],
- [
- 74,
- -60
- ],
- [
- 34,
- 31
- ],
- [
- 33,
- 56
- ],
- [
- -16,
- 91
- ],
- [
- 22,
- 59
- ],
- [
- 50,
- 56
- ],
- [
- 48,
- 16
- ],
- [
- 95,
- -24
- ],
- [
- 23,
- -54
- ],
- [
- 26,
- 0
- ],
- [
- 22,
- -21
- ],
- [
- 70,
- -14
- ],
- [
- 17,
- -39
- ]
- ],
- [
- [
- 14290,
- 13437
- ],
- [
- 0,
- -240
- ],
- [
- -80,
- 0
- ],
- [
- -1,
- -51
- ]
- ],
- [
- [
- 14209,
- 13146
- ],
- [
- -278,
- 230
- ],
- [
- -278,
- 230
- ],
- [
- -70,
- -66
- ]
- ],
- [
- [
- 13583,
- 13540
- ],
- [
- -50,
- -45
- ],
- [
- -39,
- 66
- ],
- [
- -110,
- 52
- ]
- ],
- [
- [
- 18249,
- 11700
- ],
- [
- -11,
- -125
- ],
- [
- -29,
- -34
- ],
- [
- -61,
- -28
- ],
- [
- -33,
- 96
- ],
- [
- -12,
- 172
- ],
- [
- 31,
- 195
- ],
- [
- 49,
- -67
- ],
- [
- 32,
- -84
- ],
- [
- 34,
- -125
- ]
- ],
- [
- [
- 14568,
- 7323
- ],
- [
- 24,
- -36
- ],
- [
- -22,
- -58
- ],
- [
- -12,
- -39
- ],
- [
- -38,
- -19
- ],
- [
- -13,
- -38
- ],
- [
- -25,
- -12
- ],
- [
- -52,
- 92
- ],
- [
- 37,
- 76
- ],
- [
- 38,
- 47
- ],
- [
- 32,
- 24
- ],
- [
- 31,
- -37
- ]
- ],
- [
- [
- 14185,
- 17265
- ],
- [
- -17,
- 37
- ],
- [
- -36,
- 13
- ]
- ],
- [
- [
- 14132,
- 17315
- ],
- [
- -6,
- 30
- ],
- [
- 8,
- 33
- ],
- [
- -31,
- 19
- ],
- [
- -73,
- 21
- ]
- ],
- [
- [
- 14030,
- 17418
- ],
- [
- -15,
- 101
- ]
- ],
- [
- [
- 14015,
- 17519
- ],
- [
- 80,
- 37
- ],
- [
- 117,
- -8
- ],
- [
- 68,
- 12
- ],
- [
- 10,
- -25
- ],
- [
- 37,
- -8
- ],
- [
- 67,
- -58
- ]
- ],
- [
- [
- 14015,
- 17519
- ],
- [
- 3,
- 90
- ],
- [
- 34,
- 76
- ],
- [
- 66,
- 41
- ],
- [
- 55,
- -90
- ],
- [
- 56,
- 2
- ],
- [
- 13,
- 93
- ]
- ],
- [
- [
- 14450,
- 17692
- ],
- [
- 33,
- -27
- ],
- [
- 6,
- -58
- ],
- [
- 23,
- -71
- ]
- ],
- [
- [
- 11943,
- 14115
- ],
- [
- -10,
- 0
- ],
- [
- 1,
- -64
- ],
- [
- -43,
- -4
- ],
- [
- -22,
- -27
- ],
- [
- -32,
- 0
- ],
- [
- -25,
- 15
- ],
- [
- -59,
- -13
- ],
- [
- -22,
- -93
- ],
- [
- -22,
- -9
- ],
- [
- -33,
- -151
- ],
- [
- -97,
- -130
- ],
- [
- -23,
- -165
- ],
- [
- -28,
- -54
- ],
- [
- -9,
- -43
- ],
- [
- -157,
- -10
- ],
- [
- -1,
- 0
- ]
- ],
- [
- [
- 11361,
- 13367
- ],
- [
- 3,
- 56
- ],
- [
- 27,
- 32
- ],
- [
- 23,
- 63
- ],
- [
- -5,
- 41
- ],
- [
- 24,
- 84
- ],
- [
- 39,
- 77
- ],
- [
- 24,
- 19
- ],
- [
- 18,
- 70
- ],
- [
- 2,
- 64
- ],
- [
- 25,
- 74
- ],
- [
- 46,
- 44
- ],
- [
- 45,
- 122
- ],
- [
- 1,
- 2
- ],
- [
- 35,
- 46
- ],
- [
- 65,
- 13
- ],
- [
- 55,
- 82
- ],
- [
- 35,
- 32
- ],
- [
- 58,
- 100
- ],
- [
- -18,
- 150
- ],
- [
- 27,
- 103
- ],
- [
- 9,
- 63
- ],
- [
- 45,
- 81
- ],
- [
- 70,
- 55
- ],
- [
- 52,
- 49
- ],
- [
- 46,
- 125
- ],
- [
- 22,
- 73
- ],
- [
- 51,
- 0
- ],
- [
- 42,
- -51
- ],
- [
- 67,
- 8
- ],
- [
- 72,
- -26
- ],
- [
- 30,
- -2
- ]
- ],
- [
- [
- 14403,
- 16582
- ],
- [
- 17,
- 18
- ],
- [
- 46,
- 12
- ],
- [
- 51,
- -38
- ],
- [
- 29,
- -4
- ],
- [
- 32,
- -32
- ],
- [
- -5,
- -41
- ],
- [
- 25,
- -20
- ],
- [
- 10,
- -50
- ],
- [
- 24,
- -30
- ],
- [
- -5,
- -18
- ],
- [
- 13,
- -12
- ],
- [
- -18,
- -9
- ],
- [
- -41,
- 3
- ],
- [
- -7,
- 17
- ],
- [
- -15,
- -10
- ],
- [
- 5,
- -21
- ],
- [
- -19,
- -38
- ],
- [
- -12,
- -42
- ],
- [
- -17,
- -13
- ]
- ],
- [
- [
- 14516,
- 16254
- ],
- [
- -13,
- 55
- ],
- [
- 7,
- 51
- ],
- [
- -2,
- 53
- ],
- [
- -40,
- 71
- ],
- [
- -22,
- 51
- ],
- [
- -22,
- 35
- ],
- [
- -21,
- 12
- ]
- ],
- [
- [
- 16001,
- 9301
- ],
- [
- 19,
- -51
- ],
- [
- 17,
- -79
- ],
- [
- 11,
- -144
- ],
- [
- 18,
- -57
- ],
- [
- -7,
- -57
- ],
- [
- -12,
- -35
- ],
- [
- -24,
- 70
- ],
- [
- -13,
- -36
- ],
- [
- 13,
- -88
- ],
- [
- -6,
- -51
- ],
- [
- -19,
- -28
- ],
- [
- -4,
- -102
- ],
- [
- -28,
- -139
- ],
- [
- -34,
- -166
- ],
- [
- -43,
- -227
- ],
- [
- -27,
- -167
- ],
- [
- -32,
- -139
- ],
- [
- -56,
- -28
- ],
- [
- -61,
- -51
- ],
- [
- -40,
- 30
- ],
- [
- -56,
- 43
- ],
- [
- -19,
- 64
- ],
- [
- -4,
- 106
- ],
- [
- -25,
- 96
- ],
- [
- -6,
- 86
- ],
- [
- 12,
- 86
- ],
- [
- 32,
- 21
- ],
- [
- 0,
- 40
- ],
- [
- 34,
- 91
- ],
- [
- 6,
- 77
- ],
- [
- -16,
- 56
- ],
- [
- -13,
- 76
- ],
- [
- -6,
- 111
- ],
- [
- 24,
- 67
- ],
- [
- 10,
- 76
- ],
- [
- 35,
- 4
- ],
- [
- 38,
- 25
- ],
- [
- 26,
- 21
- ],
- [
- 31,
- 2
- ],
- [
- 40,
- 68
- ],
- [
- 57,
- 74
- ],
- [
- 21,
- 61
- ],
- [
- -10,
- 51
- ],
- [
- 30,
- -14
- ],
- [
- 38,
- 83
- ],
- [
- 2,
- 72
- ],
- [
- 23,
- 54
- ],
- [
- 24,
- -52
- ]
- ],
- [
- [
- 6118,
- 12541
- ],
- [
- -78,
- 130
- ],
- [
- -36,
- 39
- ],
- [
- -57,
- 31
- ],
- [
- -39,
- -9
- ],
- [
- -56,
- -45
- ],
- [
- -35,
- -12
- ],
- [
- -50,
- 32
- ],
- [
- -52,
- 23
- ],
- [
- -65,
- 55
- ],
- [
- -52,
- 16
- ],
- [
- -79,
- 56
- ],
- [
- -58,
- 58
- ],
- [
- -18,
- 32
- ],
- [
- -39,
- 7
- ],
- [
- -71,
- 38
- ],
- [
- -29,
- 54
- ],
- [
- -75,
- 69
- ],
- [
- -35,
- 75
- ],
- [
- -17,
- 59
- ],
- [
- 23,
- 11
- ],
- [
- -7,
- 35
- ],
- [
- 16,
- 31
- ],
- [
- 1,
- 41
- ],
- [
- -24,
- 54
- ],
- [
- -6,
- 48
- ],
- [
- -24,
- 60
- ],
- [
- -61,
- 120
- ],
- [
- -70,
- 93
- ],
- [
- -34,
- 75
- ],
- [
- -60,
- 49
- ],
- [
- -13,
- 29
- ],
- [
- 11,
- 75
- ],
- [
- -36,
- 28
- ],
- [
- -41,
- 58
- ],
- [
- -17,
- 84
- ],
- [
- -38,
- 9
- ],
- [
- -40,
- 63
- ],
- [
- -33,
- 59
- ],
- [
- -3,
- 37
- ],
- [
- -37,
- 91
- ],
- [
- -25,
- 92
- ],
- [
- 1,
- 46
- ],
- [
- -50,
- 47
- ],
- [
- -24,
- -5
- ],
- [
- -39,
- 33
- ],
- [
- -12,
- -49
- ],
- [
- 12,
- -57
- ],
- [
- 7,
- -90
- ],
- [
- 24,
- -50
- ],
- [
- 51,
- -82
- ],
- [
- 12,
- -29
- ],
- [
- 10,
- -8
- ],
- [
- 10,
- -41
- ],
- [
- 12,
- 1
- ],
- [
- 14,
- -77
- ],
- [
- 21,
- -31
- ],
- [
- 15,
- -42
- ],
- [
- 44,
- -61
- ],
- [
- 23,
- -112
- ],
- [
- 21,
- -52
- ],
- [
- 19,
- -56
- ],
- [
- 4,
- -64
- ],
- [
- 34,
- -4
- ],
- [
- 27,
- -54
- ],
- [
- 26,
- -54
- ],
- [
- -2,
- -21
- ],
- [
- -29,
- -44
- ],
- [
- -13,
- 0
- ],
- [
- -18,
- 73
- ],
- [
- -46,
- 69
- ],
- [
- -50,
- 58
- ],
- [
- -36,
- 30
- ],
- [
- 3,
- 88
- ],
- [
- -11,
- 65
- ],
- [
- -33,
- 37
- ],
- [
- -48,
- 54
- ],
- [
- -9,
- -16
- ],
- [
- -18,
- 31
- ],
- [
- -43,
- 29
- ],
- [
- -41,
- 70
- ],
- [
- 5,
- 9
- ],
- [
- 29,
- -7
- ],
- [
- 26,
- 45
- ],
- [
- 2,
- 54
- ],
- [
- -53,
- 86
- ],
- [
- -41,
- 33
- ],
- [
- -26,
- 75
- ],
- [
- -26,
- 79
- ],
- [
- -32,
- 95
- ],
- [
- -28,
- 108
- ]
- ],
- [
- [
- 4383,
- 14700
- ],
- [
- 79,
- 10
- ],
- [
- 88,
- 13
- ],
- [
- -6,
- -24
- ],
- [
- 105,
- -58
- ],
- [
- 159,
- -85
- ],
- [
- 139,
- 1
- ],
- [
- 55,
- 0
- ],
- [
- 0,
- 50
- ],
- [
- 121,
- 0
- ],
- [
- 25,
- -43
- ],
- [
- 36,
- -38
- ],
- [
- 42,
- -52
- ],
- [
- 23,
- -63
- ],
- [
- 17,
- -66
- ],
- [
- 36,
- -36
- ],
- [
- 58,
- -36
- ],
- [
- 44,
- 94
- ],
- [
- 57,
- 3
- ],
- [
- 49,
- -48
- ],
- [
- 35,
- -82
- ],
- [
- 24,
- -70
- ],
- [
- 41,
- -69
- ],
- [
- 15,
- -84
- ],
- [
- 20,
- -56
- ],
- [
- 54,
- -37
- ],
- [
- 50,
- -27
- ],
- [
- 27,
- 4
- ]
- ],
- [
- [
- 5776,
- 13901
- ],
- [
- -27,
- -106
- ],
- [
- -12,
- -86
- ],
- [
- -5,
- -161
- ],
- [
- -7,
- -58
- ],
- [
- 12,
- -66
- ],
- [
- 22,
- -58
- ],
- [
- 14,
- -93
- ],
- [
- 46,
- -90
- ],
- [
- 16,
- -68
- ],
- [
- 27,
- -59
- ],
- [
- 74,
- -32
- ],
- [
- 29,
- -50
- ],
- [
- 61,
- 33
- ],
- [
- 54,
- 13
- ],
- [
- 52,
- 21
- ],
- [
- 44,
- 21
- ],
- [
- 44,
- 49
- ],
- [
- 17,
- 70
- ],
- [
- 5,
- 100
- ],
- [
- 12,
- 36
- ],
- [
- 48,
- 31
- ],
- [
- 73,
- 28
- ],
- [
- 62,
- -4
- ],
- [
- 42,
- 10
- ],
- [
- 17,
- -26
- ],
- [
- -2,
- -57
- ],
- [
- -38,
- -72
- ],
- [
- -16,
- -73
- ],
- [
- 12,
- -21
- ],
- [
- -10,
- -52
- ],
- [
- -17,
- -93
- ],
- [
- -18,
- 31
- ],
- [
- -15,
- -2
- ]
- ],
- [
- [
- 14052,
- 15865
- ],
- [
- 23,
- 7
- ],
- [
- 33,
- 2
- ]
- ],
- [
- [
- 11745,
- 12290
- ],
- [
- 3,
- 37
- ],
- [
- -6,
- 47
- ],
- [
- -26,
- 33
- ],
- [
- -14,
- 69
- ],
- [
- -3,
- 75
- ]
- ],
- [
- [
- 11699,
- 12551
- ],
- [
- 24,
- 22
- ],
- [
- 11,
- 70
- ],
- [
- 22,
- 3
- ],
- [
- 49,
- -33
- ],
- [
- 39,
- 23
- ],
- [
- 27,
- -8
- ],
- [
- 11,
- 27
- ],
- [
- 279,
- 2
- ],
- [
- 16,
- 84
- ],
- [
- -12,
- 15
- ],
- [
- -34,
- 517
- ],
- [
- -33,
- 518
- ],
- [
- 106,
- 2
- ]
- ],
- [
- [
- 12845,
- 13095
- ],
- [
- 0,
- -276
- ],
- [
- -38,
- -80
- ],
- [
- -6,
- -74
- ],
- [
- -62,
- -19
- ],
- [
- -95,
- -10
- ],
- [
- -26,
- -43
- ],
- [
- -44,
- -5
- ]
- ],
- [
- [
- 19526,
- 13247
- ],
- [
- -40,
- -28
- ],
- [
- -40,
- -52
- ],
- [
- -49,
- -5
- ],
- [
- -32,
- -130
- ],
- [
- -30,
- -22
- ],
- [
- 34,
- -105
- ],
- [
- 44,
- -88
- ],
- [
- 29,
- -79
- ],
- [
- -26,
- -104
- ],
- [
- -24,
- -22
- ],
- [
- 17,
- -61
- ],
- [
- 46,
- -95
- ],
- [
- 8,
- -67
- ],
- [
- -1,
- -56
- ],
- [
- 28,
- -109
- ],
- [
- -39,
- -112
- ],
- [
- -33,
- -123
- ]
- ],
- [
- [
- 19418,
- 11989
- ],
- [
- -7,
- 89
- ],
- [
- 21,
- 92
- ],
- [
- -23,
- 71
- ],
- [
- 5,
- 130
- ],
- [
- -28,
- 63
- ],
- [
- -23,
- 143
- ],
- [
- -12,
- 152
- ],
- [
- -30,
- 99
- ],
- [
- -46,
- -60
- ],
- [
- -79,
- -86
- ],
- [
- -40,
- 11
- ],
- [
- -43,
- 28
- ],
- [
- 24,
- 149
- ],
- [
- -14,
- 112
- ],
- [
- -55,
- 139
- ],
- [
- 9,
- 43
- ],
- [
- -41,
- 15
- ],
- [
- -50,
- 98
- ]
- ],
- [
- [
- 13898,
- 15821
- ],
- [
- -15,
- 9
- ],
- [
- -19,
- 40
- ],
- [
- -30,
- 23
- ]
- ],
- [
- [
- 13887,
- 16019
- ],
- [
- 19,
- -21
- ],
- [
- 10,
- -17
- ],
- [
- 23,
- -12
- ],
- [
- 26,
- -25
- ],
- [
- -5,
- -11
- ]
- ],
- [
- [
- 18664,
- 16711
- ],
- [
- 74,
- 21
- ],
- [
- 133,
- 103
- ],
- [
- 106,
- 57
- ],
- [
- 61,
- -37
- ],
- [
- 72,
- -2
- ],
- [
- 47,
- -56
- ],
- [
- 70,
- -4
- ],
- [
- 100,
- -30
- ],
- [
- 68,
- 83
- ],
- [
- -28,
- 71
- ],
- [
- 72,
- 124
- ],
- [
- 78,
- -49
- ],
- [
- 63,
- -14
- ],
- [
- 82,
- -31
- ],
- [
- 14,
- -90
- ],
- [
- 99,
- -51
- ],
- [
- 65,
- 23
- ],
- [
- 89,
- 15
- ],
- [
- 70,
- -15
- ],
- [
- 68,
- -58
- ],
- [
- 42,
- -61
- ],
- [
- 65,
- 1
- ],
- [
- 88,
- -20
- ],
- [
- 64,
- 30
- ],
- [
- 91,
- 20
- ],
- [
- 103,
- 84
- ],
- [
- 41,
- -13
- ],
- [
- 37,
- -40
- ],
- [
- 83,
- 10
- ]
- ],
- [
- [
- 14957,
- 9415
- ],
- [
- 52,
- 10
- ],
- [
- 84,
- -34
- ],
- [
- 18,
- 15
- ],
- [
- 49,
- 3
- ],
- [
- 24,
- 36
- ],
- [
- 42,
- -2
- ],
- [
- 76,
- 47
- ],
- [
- 56,
- 69
- ]
- ],
- [
- [
- 15358,
- 9559
- ],
- [
- 11,
- -53
- ],
- [
- -3,
- -120
- ],
- [
- 9,
- -105
- ],
- [
- 3,
- -188
- ],
- [
- 12,
- -58
- ],
- [
- -21,
- -86
- ],
- [
- -27,
- -83
- ],
- [
- -44,
- -75
- ],
- [
- -64,
- -45
- ],
- [
- -79,
- -59
- ],
- [
- -78,
- -128
- ],
- [
- -27,
- -22
- ],
- [
- -49,
- -86
- ],
- [
- -29,
- -27
- ],
- [
- -5,
- -86
- ],
- [
- 33,
- -91
- ],
- [
- 13,
- -70
- ],
- [
- 1,
- -36
- ],
- [
- 13,
- 6
- ],
- [
- -2,
- -118
- ],
- [
- -12,
- -55
- ],
- [
- 17,
- -21
- ],
- [
- -11,
- -50
- ],
- [
- -29,
- -42
- ],
- [
- -57,
- -41
- ],
- [
- -84,
- -65
- ],
- [
- -31,
- -44
- ],
- [
- 6,
- -51
- ],
- [
- 18,
- -8
- ],
- [
- -6,
- -63
- ]
- ],
- [
- [
- 14836,
- 7589
- ],
- [
- -53,
- 1
- ]
- ],
- [
- [
- 14783,
- 7590
- ],
- [
- -6,
- 53
- ],
- [
- -10,
- 54
- ]
- ],
- [
- [
- 14767,
- 7697
- ],
- [
- -6,
- 43
- ],
- [
- 12,
- 134
- ],
- [
- -18,
- 85
- ],
- [
- -33,
- 169
- ]
- ],
- [
- [
- 14722,
- 8128
- ],
- [
- 73,
- 136
- ],
- [
- 19,
- 86
- ],
- [
- 10,
- 11
- ],
- [
- 8,
- 71
- ],
- [
- -11,
- 35
- ],
- [
- 3,
- 90
- ],
- [
- 13,
- 83
- ],
- [
- 0,
- 152
- ],
- [
- -36,
- 39
- ],
- [
- -33,
- 8
- ],
- [
- -15,
- 30
- ],
- [
- -32,
- 25
- ],
- [
- -59,
- -2
- ],
- [
- -4,
- 45
- ]
- ],
- [
- [
- 14658,
- 8937
- ],
- [
- -7,
- 85
- ],
- [
- 212,
- 99
- ]
- ],
- [
- [
- 14863,
- 9121
- ],
- [
- 40,
- -58
- ],
- [
- 19,
- 11
- ],
- [
- 28,
- -30
- ],
- [
- 4,
- -48
- ],
- [
- -15,
- -56
- ],
- [
- 5,
- -84
- ],
- [
- 46,
- -74
- ],
- [
- 21,
- 83
- ],
- [
- 30,
- 25
- ],
- [
- -6,
- 154
- ],
- [
- -29,
- 87
- ],
- [
- -25,
- 39
- ],
- [
- -24,
- -2
- ],
- [
- -20,
- 156
- ],
- [
- 20,
- 91
- ]
- ],
- [
- [
- 11699,
- 12551
- ],
- [
- -46,
- 82
- ],
- [
- -42,
- 88
- ],
- [
- -46,
- 32
- ],
- [
- -34,
- 35
- ],
- [
- -39,
- -1
- ],
- [
- -34,
- -26
- ],
- [
- -34,
- 10
- ],
- [
- -24,
- -38
- ]
- ],
- [
- [
- 11400,
- 12733
- ],
- [
- -6,
- 65
- ],
- [
- 19,
- 59
- ],
- [
- 9,
- 113
- ],
- [
- -8,
- 118
- ],
- [
- -8,
- 60
- ],
- [
- 7,
- 60
- ],
- [
- -18,
- 57
- ],
- [
- -37,
- 52
- ]
- ],
- [
- [
- 11358,
- 13317
- ],
- [
- 15,
- 40
- ],
- [
- 273,
- -1
- ],
- [
- -13,
- 173
- ],
- [
- 17,
- 62
- ],
- [
- 65,
- 10
- ],
- [
- -2,
- 307
- ],
- [
- 229,
- -6
- ],
- [
- 0,
- 182
- ]
- ],
- [
- [
- 14863,
- 9121
- ],
- [
- -37,
- 31
- ],
- [
- 21,
- 112
- ],
- [
- 22,
- 41
- ],
- [
- -13,
- 100
- ],
- [
- 14,
- 97
- ],
- [
- 12,
- 32
- ],
- [
- -18,
- 102
- ],
- [
- -33,
- 54
- ]
- ],
- [
- [
- 14831,
- 9690
- ],
- [
- 68,
- -23
- ],
- [
- 14,
- -33
- ],
- [
- 24,
- -56
- ],
- [
- 20,
- -163
- ]
- ],
- [
- [
- 20595,
- 11451
- ],
- [
- 54,
- 83
- ],
- [
- 35,
- 94
- ],
- [
- 28,
- 0
- ],
- [
- 36,
- -60
- ],
- [
- 3,
- -52
- ],
- [
- 46,
- -34
- ],
- [
- 58,
- -36
- ],
- [
- -4,
- -47
- ],
- [
- -47,
- -6
- ],
- [
- 12,
- -59
- ],
- [
- -51,
- -40
- ]
- ],
- [
- [
- 20192,
- 11038
- ],
- [
- 51,
- -41
- ],
- [
- 54,
- 22
- ],
- [
- 14,
- 102
- ],
- [
- 30,
- 22
- ],
- [
- 83,
- 26
- ],
- [
- 50,
- 95
- ],
- [
- 34,
- 76
- ]
- ],
- [
- [
- 19668,
- 11544
- ],
- [
- 16,
- -12
- ],
- [
- 41,
- -72
- ],
- [
- 29,
- -80
- ],
- [
- 4,
- -81
- ],
- [
- -7,
- -55
- ],
- [
- 6,
- -41
- ],
- [
- 5,
- -71
- ],
- [
- 25,
- -33
- ],
- [
- 27,
- -106
- ],
- [
- -1,
- -41
- ],
- [
- -49,
- -8
- ],
- [
- -66,
- 89
- ],
- [
- -83,
- 95
- ],
- [
- -8,
- 62
- ],
- [
- -40,
- 80
- ],
- [
- -10,
- 99
- ],
- [
- -25,
- 66
- ],
- [
- 8,
- 87
- ],
- [
- -16,
- 51
- ]
- ],
- [
- [
- 19524,
- 11573
- ],
- [
- 12,
- 21
- ],
- [
- 57,
- -52
- ],
- [
- 6,
- -62
- ],
- [
- 46,
- 14
- ],
- [
- 23,
- 50
- ]
- ],
- [
- [
- 14166,
- 8695
- ],
- [
- 57,
- 27
- ],
- [
- 45,
- -7
- ],
- [
- 28,
- -27
- ],
- [
- 0,
- -10
- ]
- ],
- [
- [
- 13934,
- 7826
- ],
- [
- 0,
- -443
- ],
- [
- -62,
- -62
- ],
- [
- -37,
- -8
- ],
- [
- -44,
- 22
- ],
- [
- -31,
- 9
- ],
- [
- -12,
- 51
- ],
- [
- -28,
- 33
- ],
- [
- -33,
- -59
- ]
- ],
- [
- [
- 13687,
- 7369
- ],
- [
- -52,
- 91
- ],
- [
- -27,
- 87
- ],
- [
- -16,
- 117
- ],
- [
- -17,
- 87
- ],
- [
- -23,
- 185
- ],
- [
- -2,
- 143
- ],
- [
- -9,
- 66
- ],
- [
- -27,
- 49
- ],
- [
- -36,
- 99
- ],
- [
- -36,
- 144
- ],
- [
- -16,
- 75
- ],
- [
- -56,
- 117
- ],
- [
- -5,
- 93
- ]
- ],
- [
- [
- 24104,
- 8268
- ],
- [
- 57,
- -74
- ],
- [
- 36,
- -55
- ],
- [
- -26,
- -29
- ],
- [
- -39,
- 32
- ],
- [
- -50,
- 54
- ],
- [
- -44,
- 64
- ],
- [
- -47,
- 84
- ],
- [
- -9,
- 41
- ],
- [
- 30,
- -2
- ],
- [
- 39,
- -40
- ],
- [
- 30,
- -41
- ],
- [
- 23,
- -34
- ]
- ],
- [
- [
- 13583,
- 13540
- ],
- [
- 17,
- -186
- ],
- [
- 26,
- -32
- ],
- [
- 1,
- -38
- ],
- [
- 29,
- -41
- ],
- [
- -15,
- -52
- ],
- [
- -27,
- -243
- ],
- [
- -4,
- -156
- ],
- [
- -89,
- -113
- ],
- [
- -30,
- -158
- ],
- [
- 29,
- -45
- ],
- [
- 0,
- -77
- ],
- [
- 45,
- -3
- ],
- [
- -7,
- -56
- ]
- ],
- [
- [
- 13536,
- 12295
- ],
- [
- -13,
- -3
- ],
- [
- -47,
- 132
- ],
- [
- -16,
- 4
- ],
- [
- -55,
- -67
- ],
- [
- -54,
- 35
- ],
- [
- -37,
- 7
- ],
- [
- -21,
- -17
- ],
- [
- -40,
- 4
- ],
- [
- -42,
- -51
- ],
- [
- -35,
- -3
- ],
- [
- -84,
- 62
- ],
- [
- -33,
- -29
- ],
- [
- -36,
- 2
- ],
- [
- -26,
- 45
- ],
- [
- -70,
- 45
- ],
- [
- -75,
- -15
- ],
- [
- -18,
- -25
- ],
- [
- -10,
- -69
- ],
- [
- -20,
- -49
- ],
- [
- -5,
- -107
- ]
- ],
- [
- [
- 13140,
- 11370
- ],
- [
- -72,
- -43
- ],
- [
- -27,
- 6
- ],
- [
- -27,
- -27
- ],
- [
- -55,
- 3
- ],
- [
- -38,
- 75
- ],
- [
- -23,
- 86
- ],
- [
- -49,
- 79
- ],
- [
- -52,
- -1
- ],
- [
- -62,
- 0
- ]
- ],
- [
- [
- 6573,
- 12127
- ],
- [
- -24,
- 38
- ],
- [
- -33,
- 49
- ],
- [
- -15,
- 40
- ],
- [
- -30,
- 38
- ],
- [
- -35,
- 54
- ],
- [
- 8,
- 19
- ],
- [
- 12,
- -19
- ],
- [
- 5,
- 9
- ]
- ],
- [
- [
- 6751,
- 12596
- ],
- [
- -6,
- -11
- ],
- [
- -3,
- -27
- ],
- [
- 7,
- -44
- ],
- [
- -16,
- -41
- ],
- [
- -8,
- -48
- ],
- [
- -2,
- -53
- ],
- [
- 4,
- -31
- ],
- [
- 2,
- -54
- ],
- [
- -11,
- -12
- ],
- [
- -6,
- -51
- ],
- [
- 4,
- -32
- ],
- [
- -14,
- -30
- ],
- [
- 3,
- -33
- ],
- [
- 11,
- -19
- ]
- ],
- [
- [
- 12779,
- 16957
- ],
- [
- 36,
- 33
- ],
- [
- 61,
- 177
- ],
- [
- 95,
- 50
- ],
- [
- 58,
- -4
- ]
- ],
- [
- [
- 13987,
- 19088
- ],
- [
- -44,
- -5
- ],
- [
- -10,
- -79
- ],
- [
- -131,
- 19
- ],
- [
- -19,
- -67
- ],
- [
- -67,
- 1
- ],
- [
- -46,
- -86
- ],
- [
- -69,
- -133
- ],
- [
- -109,
- -168
- ],
- [
- 26,
- -41
- ],
- [
- -24,
- -48
- ],
- [
- -70,
- 2
- ],
- [
- -45,
- -112
- ],
- [
- 4,
- -160
- ],
- [
- 45,
- -60
- ],
- [
- -23,
- -142
- ],
- [
- -58,
- -82
- ],
- [
- -31,
- -69
- ]
- ],
- [
- [
- 13316,
- 17858
- ],
- [
- -47,
- 74
- ],
- [
- -137,
- -139
- ],
- [
- -93,
- -28
- ],
- [
- -97,
- 61
- ],
- [
- -24,
- 129
- ],
- [
- -23,
- 277
- ],
- [
- 65,
- 77
- ],
- [
- 184,
- 101
- ],
- [
- 137,
- 124
- ],
- [
- 128,
- 167
- ],
- [
- 167,
- 231
- ],
- [
- 117,
- 91
- ],
- [
- 192,
- 150
- ],
- [
- 153,
- 53
- ],
- [
- 114,
- -7
- ],
- [
- 107,
- 100
- ],
- [
- 127,
- -6
- ],
- [
- 125,
- 24
- ],
- [
- 218,
- -88
- ],
- [
- -90,
- -32
- ],
- [
- 77,
- -75
- ]
- ],
- [
- [
- 14716,
- 19142
- ],
- [
- -119,
- -48
- ],
- [
- -56,
- -11
- ]
- ],
- [
- [
- 14271,
- 20137
- ],
- [
- -156,
- -49
- ],
- [
- -123,
- 28
- ],
- [
- 48,
- 31
- ],
- [
- -42,
- 38
- ],
- [
- 145,
- 24
- ],
- [
- 27,
- -45
- ],
- [
- 101,
- -27
- ]
- ],
- [
- [
- 13820,
- 20359
- ],
- [
- 229,
- -90
- ],
- [
- -175,
- -47
- ],
- [
- -39,
- -88
- ],
- [
- -61,
- -23
- ],
- [
- -33,
- -99
- ],
- [
- -84,
- -5
- ],
- [
- -150,
- 73
- ],
- [
- 63,
- 43
- ],
- [
- -104,
- 35
- ],
- [
- -136,
- 101
- ],
- [
- -54,
- 94
- ],
- [
- 190,
- 43
- ],
- [
- 38,
- -42
- ],
- [
- 99,
- 2
- ],
- [
- 27,
- 41
- ],
- [
- 102,
- 4
- ],
- [
- 88,
- -42
- ]
- ],
- [
- [
- 14321,
- 20444
- ],
- [
- 137,
- -43
- ],
- [
- -103,
- -64
- ],
- [
- -203,
- -14
- ],
- [
- -205,
- 20
- ],
- [
- -12,
- 33
- ],
- [
- -101,
- 2
- ],
- [
- -76,
- 55
- ],
- [
- 215,
- 33
- ],
- [
- 102,
- -28
- ],
- [
- 70,
- 36
- ],
- [
- 176,
- -30
- ]
- ],
- [
- [
- 24608,
- 5888
- ],
- [
- 16,
- -49
- ],
- [
- 50,
- 48
- ],
- [
- 20,
- -50
- ],
- [
- 0,
- -51
- ],
- [
- -26,
- -55
- ],
- [
- -45,
- -89
- ],
- [
- -36,
- -48
- ],
- [
- 26,
- -58
- ],
- [
- -54,
- -1
- ],
- [
- -60,
- -46
- ],
- [
- -18,
- -78
- ],
- [
- -40,
- -121
- ],
- [
- -55,
- -54
- ],
- [
- -35,
- -34
- ],
- [
- -64,
- 2
- ],
- [
- -45,
- 40
- ],
- [
- -76,
- 8
- ],
- [
- -11,
- 44
- ],
- [
- 37,
- 89
- ],
- [
- 88,
- 119
- ],
- [
- 45,
- 22
- ],
- [
- 50,
- 46
- ],
- [
- 60,
- 63
- ],
- [
- 41,
- 62
- ],
- [
- 31,
- 89
- ],
- [
- 27,
- 31
- ],
- [
- 10,
- 67
- ],
- [
- 49,
- 55
- ],
- [
- 15,
- -51
- ]
- ],
- [
- [
- 24719,
- 6460
- ],
- [
- 51,
- -127
- ],
- [
- 1,
- 82
- ],
- [
- 32,
- -33
- ],
- [
- 10,
- -90
- ],
- [
- 56,
- -39
- ],
- [
- 47,
- -10
- ],
- [
- 40,
- 46
- ],
- [
- 36,
- -14
- ],
- [
- -17,
- -107
- ],
- [
- -21,
- -70
- ],
- [
- -54,
- 3
- ],
- [
- -18,
- -37
- ],
- [
- 6,
- -51
- ],
- [
- -10,
- -22
- ],
- [
- -26,
- -65
- ],
- [
- -35,
- -82
- ],
- [
- -54,
- -48
- ],
- [
- -12,
- 31
- ],
- [
- -29,
- 18
- ],
- [
- 40,
- 98
- ],
- [
- -23,
- 66
- ],
- [
- -75,
- 48
- ],
- [
- 2,
- 44
- ],
- [
- 51,
- 42
- ],
- [
- 12,
- 92
- ],
- [
- -4,
- 78
- ],
- [
- -28,
- 80
- ],
- [
- 2,
- 21
- ],
- [
- -33,
- 50
- ],
- [
- -55,
- 106
- ],
- [
- -29,
- 85
- ],
- [
- 26,
- 9
- ],
- [
- 37,
- -66
- ],
- [
- 55,
- -32
- ],
- [
- 19,
- -106
- ]
- ],
- [
- [
- 16456,
- 13923
- ],
- [
- 20,
- 41
- ],
- [
- 9,
- -11
- ],
- [
- -7,
- -49
- ],
- [
- -9,
- -22
- ]
- ],
- [
- [
- 16479,
- 13787
- ],
- [
- 31,
- -82
- ],
- [
- 39,
- -43
- ],
- [
- 51,
- -16
- ],
- [
- 41,
- -22
- ],
- [
- 32,
- -68
- ],
- [
- 19,
- -40
- ],
- [
- 25,
- -15
- ],
- [
- -1,
- -27
- ],
- [
- -25,
- -72
- ],
- [
- -11,
- -33
- ],
- [
- -29,
- -39
- ],
- [
- -26,
- -82
- ],
- [
- -32,
- 6
- ],
- [
- -15,
- -28
- ],
- [
- -11,
- -61
- ],
- [
- 9,
- -80
- ],
- [
- -7,
- -15
- ],
- [
- -32,
- 0
- ],
- [
- -43,
- -44
- ],
- [
- -7,
- -59
- ],
- [
- -16,
- -25
- ],
- [
- -43,
- 1
- ],
- [
- -28,
- -30
- ],
- [
- 1,
- -49
- ],
- [
- -34,
- -33
- ],
- [
- -39,
- 11
- ],
- [
- -46,
- -40
- ],
- [
- -32,
- -7
- ]
- ],
- [
- [
- 16250,
- 12795
- ],
- [
- -23,
- 84
- ],
- [
- -55,
- 198
- ]
- ],
- [
- [
- 16172,
- 13077
- ],
- [
- 209,
- 120
- ],
- [
- 47,
- 240
- ],
- [
- -32,
- 84
- ]
- ],
- [
- [
- 17300,
- 13639
- ],
- [
- -51,
- 31
- ],
- [
- -21,
- 86
- ],
- [
- -54,
- 91
- ],
- [
- -128,
- -22
- ],
- [
- -113,
- -2
- ],
- [
- -99,
- -17
- ]
- ],
- [
- [
- 7119,
- 11664
- ],
- [
- -24,
- 34
- ],
- [
- -15,
- 65
- ],
- [
- 18,
- 32
- ],
- [
- -18,
- 8
- ],
- [
- -13,
- 40
- ],
- [
- -35,
- 33
- ],
- [
- -30,
- -7
- ],
- [
- -14,
- -42
- ],
- [
- -29,
- -30
- ],
- [
- -15,
- -4
- ],
- [
- -7,
- -25
- ],
- [
- 34,
- -65
- ],
- [
- -19,
- -16
- ],
- [
- -11,
- -17
- ],
- [
- -32,
- -7
- ],
- [
- -12,
- 72
- ],
- [
- -9,
- -20
- ],
- [
- -23,
- 7
- ],
- [
- -14,
- 48
- ],
- [
- -29,
- 8
- ],
- [
- -18,
- 14
- ],
- [
- -30,
- 0
- ],
- [
- -2,
- -26
- ],
- [
- -8,
- 18
- ]
- ],
- [
- [
- 6793,
- 11945
- ],
- [
- 25,
- -43
- ],
- [
- -1,
- -26
- ],
- [
- 28,
- -5
- ],
- [
- 6,
- 10
- ],
- [
- 20,
- -30
- ],
- [
- 34,
- 9
- ],
- [
- 29,
- 30
- ],
- [
- 43,
- 24
- ],
- [
- 24,
- 36
- ],
- [
- 38,
- -7
- ],
- [
- -3,
- -12
- ],
- [
- 39,
- -4
- ],
- [
- 31,
- -20
- ],
- [
- 23,
- -36
- ],
- [
- 26,
- -34
- ]
- ],
- [
- [
- 7642,
- 8596
- ],
- [
- -70,
- 69
- ],
- [
- -6,
- 49
- ],
- [
- -138,
- 121
- ],
- [
- -125,
- 131
- ],
- [
- -54,
- 74
- ],
- [
- -29,
- 99
- ],
- [
- 12,
- 34
- ],
- [
- -59,
- 158
- ],
- [
- -69,
- 221
- ],
- [
- -66,
- 239
- ],
- [
- -29,
- 55
- ],
- [
- -21,
- 88
- ],
- [
- -55,
- 78
- ],
- [
- -49,
- 49
- ],
- [
- 22,
- 54
- ],
- [
- -34,
- 114
- ],
- [
- 22,
- 84
- ],
- [
- 56,
- 76
- ]
- ],
- [
- [
- 21357,
- 11807
- ],
- [
- 7,
- -80
- ],
- [
- 4,
- -67
- ],
- [
- -24,
- -110
- ],
- [
- -25,
- 122
- ],
- [
- -33,
- -61
- ],
- [
- 23,
- -88
- ],
- [
- -20,
- -56
- ],
- [
- -82,
- 69
- ],
- [
- -20,
- 87
- ],
- [
- 21,
- 57
- ],
- [
- -44,
- 57
- ],
- [
- -22,
- -50
- ],
- [
- -33,
- 5
- ],
- [
- -51,
- -67
- ],
- [
- -12,
- 35
- ],
- [
- 28,
- 101
- ],
- [
- 44,
- 34
- ],
- [
- 38,
- 45
- ],
- [
- 24,
- -54
- ],
- [
- 53,
- 33
- ],
- [
- 12,
- 53
- ],
- [
- 49,
- 3
- ],
- [
- -4,
- 93
- ],
- [
- 56,
- -57
- ],
- [
- 6,
- -60
- ],
- [
- 5,
- -44
- ]
- ],
- [
- [
- 21190,
- 12030
- ],
- [
- -25,
- -39
- ],
- [
- -22,
- -76
- ],
- [
- -22,
- -35
- ],
- [
- -43,
- 82
- ],
- [
- 15,
- 33
- ],
- [
- 17,
- 33
- ],
- [
- 8,
- 75
- ],
- [
- 38,
- 7
- ],
- [
- -11,
- -81
- ],
- [
- 52,
- 116
- ],
- [
- -7,
- -115
- ]
- ],
- [
- [
- 20808,
- 11915
- ],
- [
- -92,
- -114
- ],
- [
- 34,
- 84
- ],
- [
- 50,
- 74
- ],
- [
- 42,
- 83
- ],
- [
- 36,
- 119
- ],
- [
- 13,
- -98
- ],
- [
- -46,
- -66
- ],
- [
- -37,
- -82
- ]
- ],
- [
- [
- 21044,
- 12224
- ],
- [
- 42,
- -37
- ],
- [
- 44,
- 0
- ],
- [
- -1,
- -50
- ],
- [
- -33,
- -51
- ],
- [
- -44,
- -36
- ],
- [
- -2,
- 56
- ],
- [
- 5,
- 61
- ],
- [
- -11,
- 57
- ]
- ],
- [
- [
- 21296,
- 12256
- ],
- [
- 20,
- -134
- ],
- [
- -54,
- 32
- ],
- [
- 1,
- -40
- ],
- [
- 17,
- -74
- ],
- [
- -33,
- -27
- ],
- [
- -3,
- 84
- ],
- [
- -21,
- 7
- ],
- [
- -11,
- 72
- ],
- [
- 41,
- -9
- ],
- [
- 0,
- 45
- ],
- [
- -43,
- 92
- ],
- [
- 67,
- -3
- ],
- [
- 19,
- -45
- ]
- ],
- [
- [
- 21019,
- 12365
- ],
- [
- -19,
- -104
- ],
- [
- -29,
- 60
- ],
- [
- -36,
- 92
- ],
- [
- 60,
- -5
- ],
- [
- 24,
- -43
- ]
- ],
- [
- [
- 21005,
- 13017
- ],
- [
- 43,
- -34
- ],
- [
- 21,
- 31
- ],
- [
- 6,
- -30
- ],
- [
- -11,
- -50
- ],
- [
- 24,
- -86
- ],
- [
- -18,
- -100
- ],
- [
- -42,
- -40
- ],
- [
- -11,
- -96
- ],
- [
- 16,
- -96
- ],
- [
- 37,
- -13
- ],
- [
- 31,
- 14
- ],
- [
- 87,
- -66
- ],
- [
- -7,
- -66
- ],
- [
- 23,
- -29
- ],
- [
- -7,
- -55
- ],
- [
- -55,
- 59
- ],
- [
- -25,
- 63
- ],
- [
- -18,
- -44
- ],
- [
- -45,
- 72
- ],
- [
- -63,
- -18
- ],
- [
- -35,
- 27
- ],
- [
- 4,
- 49
- ],
- [
- 22,
- 31
- ],
- [
- -21,
- 28
- ],
- [
- -9,
- -44
- ],
- [
- -35,
- 69
- ],
- [
- -10,
- 52
- ],
- [
- -3,
- 115
- ],
- [
- 28,
- -39
- ],
- [
- 8,
- 188
- ],
- [
- 22,
- 108
- ],
- [
- 43,
- 0
- ]
- ],
- [
- [
- 22376,
- 10485
- ],
- [
- 121,
- -82
- ],
- [
- 129,
- -69
- ],
- [
- 48,
- -62
- ],
- [
- 39,
- -60
- ],
- [
- 11,
- -71
- ],
- [
- 116,
- -74
- ],
- [
- 17,
- -63
- ],
- [
- -64,
- -13
- ],
- [
- 15,
- -80
- ],
- [
- 62,
- -79
- ],
- [
- 46,
- -127
- ],
- [
- 39,
- 4
- ],
- [
- -2,
- -53
- ],
- [
- 53,
- -21
- ],
- [
- -20,
- -22
- ],
- [
- 74,
- -51
- ],
- [
- -8,
- -34
- ],
- [
- -46,
- -9
- ],
- [
- -17,
- 31
- ],
- [
- -60,
- 14
- ],
- [
- -71,
- 18
- ],
- [
- -54,
- 76
- ],
- [
- -39,
- 66
- ],
- [
- -37,
- 105
- ],
- [
- -91,
- 53
- ],
- [
- -59,
- -34
- ],
- [
- -42,
- -40
- ],
- [
- 9,
- -88
- ],
- [
- -55,
- -42
- ],
- [
- -39,
- 20
- ],
- [
- -72,
- 5
- ]
- ],
- [
- [
- 23414,
- 9979
- ],
- [
- -20,
- -12
- ],
- [
- -30,
- 46
- ],
- [
- -31,
- 76
- ],
- [
- -15,
- 92
- ],
- [
- 10,
- 11
- ],
- [
- 8,
- -35
- ],
- [
- 21,
- -28
- ],
- [
- 33,
- -76
- ],
- [
- 33,
- -40
- ],
- [
- -9,
- -34
- ]
- ],
- [
- [
- 23142,
- 10140
- ],
- [
- -37,
- -10
- ],
- [
- -11,
- -34
- ],
- [
- -38,
- -29
- ],
- [
- -35,
- -28
- ],
- [
- -37,
- 0
- ],
- [
- -58,
- 35
- ],
- [
- -39,
- 34
- ],
- [
- 5,
- 37
- ],
- [
- 63,
- -18
- ],
- [
- 38,
- 10
- ],
- [
- 10,
- 57
- ],
- [
- 10,
- 3
- ],
- [
- 7,
- -64
- ],
- [
- 40,
- 10
- ],
- [
- 20,
- 41
- ],
- [
- 39,
- 42
- ],
- [
- -8,
- 71
- ],
- [
- 42,
- 2
- ],
- [
- 14,
- -19
- ],
- [
- -2,
- -67
- ],
- [
- -23,
- -73
- ]
- ],
- [
- [
- 23223,
- 10257
- ],
- [
- -22,
- -32
- ],
- [
- -13,
- 71
- ],
- [
- -17,
- 47
- ],
- [
- -31,
- 39
- ],
- [
- -40,
- 51
- ],
- [
- -50,
- 35
- ],
- [
- 19,
- 29
- ],
- [
- 38,
- -33
- ],
- [
- 24,
- -27
- ],
- [
- 29,
- -29
- ],
- [
- 28,
- -50
- ],
- [
- 26,
- -38
- ],
- [
- 9,
- -63
- ]
- ],
- [
- [
- 14188,
- 16985
- ],
- [
- 35,
- -105
- ],
- [
- -8,
- -33
- ],
- [
- -34,
- -14
- ],
- [
- -64,
- -100
- ],
- [
- 18,
- -54
- ],
- [
- -15,
- 7
- ]
- ],
- [
- [
- 14120,
- 16686
- ],
- [
- -66,
- 46
- ],
- [
- -50,
- -17
- ],
- [
- -33,
- 12
- ],
- [
- -42,
- -25
- ],
- [
- -35,
- 42
- ],
- [
- -28,
- -16
- ],
- [
- -4,
- 7
- ]
- ],
- [
- [
- 13532,
- 17246
- ],
- [
- 47,
- 36
- ],
- [
- 109,
- 55
- ],
- [
- 88,
- 41
- ],
- [
- 70,
- -21
- ],
- [
- 5,
- -29
- ],
- [
- 67,
- -1
- ]
- ],
- [
- [
- 13918,
- 17327
- ],
- [
- 86,
- -14
- ],
- [
- 128,
- 2
- ]
- ],
- [
- [
- 7927,
- 13018
- ],
- [
- 36,
- -10
- ],
- [
- 12,
- -24
- ],
- [
- -18,
- -30
- ],
- [
- -52,
- 0
- ],
- [
- -41,
- -4
- ],
- [
- -4,
- 52
- ],
- [
- 10,
- 17
- ],
- [
- 57,
- -1
- ]
- ],
- [
- [
- 21654,
- 15883
- ],
- [
- 10,
- -21
- ]
- ],
- [
- [
- 21664,
- 15862
- ],
- [
- -27,
- 7
- ],
- [
- -30,
- -40
- ],
- [
- -21,
- -41
- ],
- [
- 3,
- -86
- ],
- [
- -36,
- -27
- ],
- [
- -12,
- -21
- ],
- [
- -27,
- -35
- ],
- [
- -46,
- -20
- ],
- [
- -30,
- -32
- ],
- [
- -3,
- -52
- ],
- [
- -8,
- -13
- ],
- [
- 28,
- -20
- ],
- [
- 40,
- -53
- ]
- ],
- [
- [
- 21343,
- 15326
- ],
- [
- -34,
- 23
- ],
- [
- -8,
- -23
- ],
- [
- -21,
- -10
- ],
- [
- -2,
- 23
- ],
- [
- -18,
- 11
- ],
- [
- -19,
- 19
- ],
- [
- 19,
- 53
- ],
- [
- 17,
- 14
- ],
- [
- -7,
- 22
- ],
- [
- 18,
- 65
- ],
- [
- -5,
- 19
- ],
- [
- -40,
- 13
- ],
- [
- -33,
- 32
- ]
- ],
- [
- [
- 12028,
- 15248
- ],
- [
- -28,
- -31
- ],
- [
- -37,
- 17
- ],
- [
- -36,
- -14
- ],
- [
- 11,
- 94
- ],
- [
- -7,
- 74
- ],
- [
- -31,
- 11
- ],
- [
- -17,
- 45
- ],
- [
- 6,
- 79
- ],
- [
- 28,
- 44
- ],
- [
- 5,
- 48
- ],
- [
- 14,
- 72
- ],
- [
- -1,
- 51
- ],
- [
- -14,
- 43
- ],
- [
- -3,
- 41
- ]
- ],
- [
- [
- 16089,
- 13767
- ],
- [
- -4,
- 87
- ],
- [
- 19,
- 63
- ],
- [
- 19,
- 13
- ],
- [
- 21,
- -37
- ],
- [
- 1,
- -71
- ],
- [
- -15,
- -70
- ]
- ],
- [
- [
- 16130,
- 13752
- ],
- [
- -20,
- -9
- ],
- [
- -21,
- 24
- ]
- ],
- [
- [
- 14127,
- 16104
- ],
- [
- -13,
- 21
- ],
- [
- 16,
- 20
- ],
- [
- -17,
- 15
- ],
- [
- -22,
- -27
- ],
- [
- -40,
- 35
- ],
- [
- -6,
- 50
- ],
- [
- -42,
- 28
- ],
- [
- -8,
- 38
- ],
- [
- -38,
- 47
- ]
- ],
- [
- [
- 14131,
- 16542
- ],
- [
- 30,
- 25
- ],
- [
- 43,
- -13
- ],
- [
- 45,
- 0
- ],
- [
- 32,
- -30
- ],
- [
- 24,
- 19
- ],
- [
- 51,
- 11
- ],
- [
- 18,
- 28
- ],
- [
- 29,
- 0
- ]
- ],
- [
- [
- 14516,
- 16254
- ],
- [
- 31,
- -22
- ],
- [
- 32,
- 20
- ],
- [
- 32,
- -21
- ]
- ],
- [
- [
- 14611,
- 16231
- ],
- [
- 2,
- -31
- ],
- [
- -34,
- -26
- ],
- [
- -21,
- 11
- ],
- [
- -20,
- -144
- ]
- ],
- [
- [
- 15333,
- 16008
- ],
- [
- -89,
- 101
- ],
- [
- -80,
- 46
- ],
- [
- -60,
- 70
- ],
- [
- 51,
- 19
- ],
- [
- 58,
- 101
- ],
- [
- -39,
- 47
- ],
- [
- 102,
- 49
- ],
- [
- -1,
- 26
- ],
- [
- -63,
- -19
- ]
- ],
- [
- [
- 15212,
- 16448
- ],
- [
- 2,
- 53
- ],
- [
- 36,
- 34
- ],
- [
- 68,
- 9
- ],
- [
- 11,
- 40
- ],
- [
- -16,
- 66
- ],
- [
- 28,
- 63
- ],
- [
- 0,
- 35
- ],
- [
- -103,
- 39
- ],
- [
- -41,
- -1
- ],
- [
- -43,
- 56
- ],
- [
- -53,
- -19
- ],
- [
- -89,
- 42
- ],
- [
- 2,
- 23
- ],
- [
- -25,
- 53
- ],
- [
- -56,
- 5
- ],
- [
- -6,
- 38
- ],
- [
- 18,
- 24
- ],
- [
- -45,
- 68
- ],
- [
- -72,
- -12
- ],
- [
- -21,
- 6
- ],
- [
- -18,
- -27
- ],
- [
- -26,
- 5
- ]
- ],
- [
- [
- 14498,
- 17932
- ],
- [
- 79,
- 67
- ],
- [
- -73,
- 57
- ]
- ],
- [
- [
- 14716,
- 19142
- ],
- [
- 71,
- 42
- ],
- [
- 115,
- -73
- ],
- [
- 191,
- -28
- ],
- [
- 263,
- -136
- ],
- [
- 54,
- -57
- ],
- [
- 4,
- -80
- ],
- [
- -77,
- -63
- ],
- [
- -114,
- -32
- ],
- [
- -311,
- 91
- ],
- [
- -51,
- -15
- ],
- [
- 113,
- -88
- ],
- [
- 5,
- -56
- ],
- [
- 4,
- -122
- ],
- [
- 90,
- -37
- ],
- [
- 55,
- -31
- ],
- [
- 9,
- 58
- ],
- [
- -42,
- 52
- ],
- [
- 44,
- 45
- ],
- [
- 168,
- -74
- ],
- [
- 59,
- 29
- ],
- [
- -47,
- 88
- ],
- [
- 163,
- 117
- ],
- [
- 64,
- -7
- ],
- [
- 65,
- -42
- ],
- [
- 41,
- 83
- ],
- [
- -58,
- 71
- ],
- [
- 34,
- 72
- ],
- [
- -51,
- 75
- ],
- [
- 195,
- -39
- ],
- [
- 39,
- -67
- ],
- [
- -88,
- -15
- ],
- [
- 1,
- -67
- ],
- [
- 54,
- -41
- ],
- [
- 108,
- 26
- ],
- [
- 17,
- 77
- ],
- [
- 146,
- 57
- ],
- [
- 243,
- 103
- ],
- [
- 53,
- -6
- ],
- [
- -69,
- -73
- ],
- [
- 86,
- -12
- ],
- [
- 50,
- 41
- ],
- [
- 131,
- 3
- ],
- [
- 103,
- 50
- ],
- [
- 80,
- -73
- ],
- [
- 79,
- 80
- ],
- [
- -73,
- 69
- ],
- [
- 36,
- 40
- ],
- [
- 206,
- -36
- ],
- [
- 97,
- -38
- ],
- [
- 252,
- -137
- ],
- [
- 47,
- 63
- ],
- [
- -71,
- 63
- ],
- [
- -2,
- 26
- ],
- [
- -84,
- 12
- ],
- [
- 23,
- 56
- ],
- [
- -37,
- 94
- ],
- [
- -2,
- 38
- ],
- [
- 128,
- 109
- ],
- [
- 46,
- 109
- ],
- [
- 52,
- 24
- ],
- [
- 184,
- -32
- ],
- [
- 15,
- -67
- ],
- [
- -66,
- -97
- ],
- [
- 43,
- -38
- ],
- [
- 23,
- -84
- ],
- [
- -16,
- -164
- ],
- [
- 77,
- -74
- ],
- [
- -30,
- -80
- ],
- [
- -137,
- -170
- ],
- [
- 80,
- -18
- ],
- [
- 28,
- 43
- ],
- [
- 76,
- 31
- ],
- [
- 19,
- 59
- ],
- [
- 60,
- 57
- ],
- [
- -40,
- 69
- ],
- [
- 32,
- 79
- ],
- [
- -76,
- 10
- ],
- [
- -17,
- 66
- ],
- [
- 56,
- 121
- ],
- [
- -91,
- 98
- ],
- [
- 125,
- 80
- ],
- [
- -16,
- 86
- ],
- [
- 35,
- 3
- ],
- [
- 36,
- -67
- ],
- [
- -27,
- -116
- ],
- [
- 74,
- -22
- ],
- [
- -31,
- 87
- ],
- [
- 116,
- 47
- ],
- [
- 145,
- 6
- ],
- [
- 129,
- -68
- ],
- [
- -62,
- 100
- ],
- [
- -7,
- 128
- ],
- [
- 121,
- 24
- ],
- [
- 168,
- -5
- ],
- [
- 151,
- 15
- ],
- [
- -57,
- 63
- ],
- [
- 81,
- 79
- ],
- [
- 80,
- 3
- ],
- [
- 135,
- 60
- ],
- [
- 184,
- 16
- ],
- [
- 24,
- 32
- ],
- [
- 183,
- 12
- ],
- [
- 57,
- -27
- ],
- [
- 156,
- 63
- ],
- [
- 128,
- -2
- ],
- [
- 20,
- 52
- ],
- [
- 66,
- 51
- ],
- [
- 165,
- 50
- ],
- [
- 119,
- -39
- ],
- [
- -95,
- -30
- ],
- [
- 158,
- -18
- ],
- [
- 19,
- -60
- ],
- [
- 64,
- 30
- ],
- [
- 204,
- -2
- ],
- [
- 157,
- -59
- ],
- [
- 56,
- -44
- ],
- [
- -18,
- -63
- ],
- [
- -77,
- -35
- ],
- [
- -183,
- -67
- ],
- [
- -52,
- -36
- ],
- [
- 86,
- -16
- ],
- [
- 103,
- -31
- ],
- [
- 63,
- 23
- ],
- [
- 35,
- -77
- ],
- [
- 31,
- 31
- ],
- [
- 112,
- 19
- ],
- [
- 223,
- -20
- ],
- [
- 17,
- -56
- ],
- [
- 292,
- -18
- ],
- [
- 4,
- 92
- ],
- [
- 148,
- -21
- ],
- [
- 111,
- 1
- ],
- [
- 112,
- -63
- ],
- [
- 32,
- -77
- ],
- [
- -41,
- -50
- ],
- [
- 88,
- -95
- ],
- [
- 109,
- -49
- ],
- [
- 68,
- 126
- ],
- [
- 111,
- -54
- ],
- [
- 119,
- 33
- ],
- [
- 135,
- -37
- ],
- [
- 52,
- 33
- ],
- [
- 114,
- -16
- ],
- [
- -51,
- 111
- ],
- [
- 92,
- 52
- ],
- [
- 630,
- -78
- ],
- [
- 59,
- -71
- ],
- [
- 183,
- -92
- ],
- [
- 281,
- 23
- ],
- [
- 139,
- -20
- ],
- [
- 58,
- -50
- ],
- [
- -8,
- -87
- ],
- [
- 85,
- -34
- ],
- [
- 94,
- 24
- ],
- [
- 123,
- 3
- ],
- [
- 132,
- -23
- ],
- [
- 132,
- 13
- ],
- [
- 121,
- -107
- ],
- [
- 87,
- 39
- ],
- [
- -57,
- 76
- ],
- [
- 32,
- 54
- ],
- [
- 222,
- -34
- ],
- [
- 145,
- 7
- ],
- [
- 200,
- -57
- ],
- [
- 98,
- -52
- ],
- [
- 0,
- -478
- ],
- [
- -1,
- -1
- ],
- [
- -89,
- -53
- ],
- [
- -90,
- 9
- ],
- [
- 62,
- -64
- ],
- [
- 42,
- -99
- ],
- [
- 32,
- -32
- ],
- [
- 8,
- -49
- ],
- [
- -18,
- -32
- ],
- [
- -130,
- 26
- ],
- [
- -195,
- -90
- ],
- [
- -62,
- -14
- ],
- [
- -106,
- -85
- ],
- [
- -101,
- -73
- ],
- [
- -26,
- -55
- ],
- [
- -100,
- 83
- ],
- [
- -181,
- -94
- ],
- [
- -32,
- 45
- ],
- [
- -67,
- -52
- ],
- [
- -93,
- 17
- ],
- [
- -23,
- -79
- ],
- [
- -84,
- -116
- ],
- [
- 3,
- -49
- ],
- [
- 79,
- -27
- ],
- [
- -9,
- -174
- ],
- [
- -65,
- -5
- ],
- [
- -30,
- -100
- ],
- [
- 29,
- -52
- ],
- [
- -121,
- -61
- ],
- [
- -25,
- -137
- ],
- [
- -104,
- -29
- ],
- [
- -20,
- -122
- ],
- [
- -101,
- -112
- ],
- [
- -26,
- 83
- ],
- [
- -30,
- 175
- ],
- [
- -38,
- 266
- ],
- [
- 33,
- 167
- ],
- [
- 59,
- 71
- ],
- [
- 3,
- 56
- ],
- [
- 109,
- 27
- ],
- [
- 124,
- 151
- ],
- [
- 120,
- 123
- ],
- [
- 126,
- 96
- ],
- [
- 56,
- 169
- ],
- [
- -85,
- -10
- ],
- [
- -42,
- -99
- ],
- [
- -177,
- -131
- ],
- [
- -57,
- 147
- ],
- [
- -180,
- -41
- ],
- [
- -174,
- -201
- ],
- [
- 57,
- -73
- ],
- [
- -155,
- -32
- ],
- [
- -108,
- -12
- ],
- [
- 5,
- 87
- ],
- [
- -108,
- 18
- ],
- [
- -87,
- -59
- ],
- [
- -213,
- 21
- ],
- [
- -229,
- -36
- ],
- [
- -226,
- -234
- ],
- [
- -267,
- -283
- ],
- [
- 110,
- -15
- ],
- [
- 34,
- -75
- ],
- [
- 68,
- -27
- ],
- [
- 44,
- 60
- ],
- [
- 77,
- -8
- ],
- [
- 100,
- -132
- ],
- [
- 3,
- -102
- ],
- [
- -55,
- -120
- ],
- [
- -6,
- -143
- ],
- [
- -31,
- -192
- ],
- [
- -105,
- -173
- ],
- [
- -23,
- -83
- ],
- [
- -95,
- -140
- ],
- [
- -94,
- -138
- ],
- [
- -45,
- -71
- ],
- [
- -93,
- -71
- ],
- [
- -44,
- -1
- ],
- [
- -44,
- 58
- ],
- [
- -93,
- -88
- ],
- [
- -11,
- -40
- ]
- ],
- [
- [
- 15970,
- 16364
- ],
- [
- -32,
- -71
- ],
- [
- -67,
- -20
- ],
- [
- -69,
- -124
- ],
- [
- 63,
- -114
- ],
- [
- -7,
- -81
- ],
- [
- 76,
- -141
- ]
- ],
- [
- [
- 13918,
- 17327
- ],
- [
- 16,
- 52
- ],
- [
- 96,
- 39
- ]
- ],
- [
- [
- 14878,
- 16312
- ],
- [
- 19,
- 30
- ],
- [
- 49,
- -26
- ],
- [
- 23,
- -4
- ],
- [
- 9,
- -24
- ],
- [
- 10,
- -4
- ]
- ],
- [
- [
- 14988,
- 16284
- ],
- [
- 1,
- -10
- ],
- [
- 34,
- -29
- ],
- [
- 71,
- 7
- ],
- [
- -14,
- -43
- ],
- [
- -76,
- -20
- ],
- [
- -95,
- -70
- ],
- [
- -38,
- 25
- ],
- [
- 15,
- 56
- ],
- [
- -76,
- 35
- ],
- [
- 12,
- 23
- ],
- [
- 67,
- 40
- ],
- [
- -11,
- 14
- ]
- ],
- [
- [
- 22561,
- 16885
- ],
- [
- 70,
- -212
- ],
- [
- -103,
- 39
- ],
- [
- -43,
- -173
- ],
- [
- 68,
- -123
- ],
- [
- -2,
- -84
- ],
- [
- -53,
- 73
- ],
- [
- -46,
- -93
- ],
- [
- -12,
- 100
- ],
- [
- 7,
- 117
- ],
- [
- -8,
- 130
- ],
- [
- 17,
- 90
- ],
- [
- 3,
- 161
- ],
- [
- -41,
- 118
- ],
- [
- 6,
- 164
- ],
- [
- 64,
- 55
- ],
- [
- -27,
- 56
- ],
- [
- 31,
- 16
- ],
- [
- 18,
- -79
- ],
- [
- 24,
- -116
- ],
- [
- -2,
- -118
- ],
- [
- 29,
- -121
- ]
- ],
- [
- [
- 348,
- 18785
- ],
- [
- 47,
- -30
- ],
- [
- -17,
- 88
- ],
- [
- 190,
- -18
- ],
- [
- 136,
- -113
- ],
- [
- -69,
- -52
- ],
- [
- -114,
- -12
- ],
- [
- -2,
- -118
- ],
- [
- -28,
- -24
- ],
- [
- -65,
- 3
- ],
- [
- -53,
- 42
- ],
- [
- -93,
- 35
- ],
- [
- -16,
- 52
- ],
- [
- -70,
- 20
- ],
- [
- -80,
- -16
- ],
- [
- -38,
- 42
- ],
- [
- 16,
- 45
- ],
- [
- -84,
- -29
- ],
- [
- 32,
- -56
- ],
- [
- -40,
- -51
- ],
- [
- 0,
- 478
- ],
- [
- 171,
- -92
- ],
- [
- 183,
- -119
- ],
- [
- -6,
- -75
- ]
- ],
- [
- [
- 25095,
- 19295
- ],
- [
- -76,
- -6
- ],
- [
- -13,
- 38
- ],
- [
- 89,
- 50
- ],
- [
- 0,
- -82
- ]
- ],
- [
- [
- 91,
- 19302
- ],
- [
- -91,
- -7
- ],
- [
- 0,
- 82
- ],
- [
- 9,
- 5
- ],
- [
- 59,
- 0
- ],
- [
- 101,
- -35
- ],
- [
- -6,
- -16
- ],
- [
- -72,
- -29
- ]
- ],
- [
- [
- 22558,
- 19580
- ],
- [
- -106,
- 0
- ],
- [
- -143,
- 13
- ],
- [
- -12,
- 6
- ],
- [
- 66,
- 48
- ],
- [
- 87,
- 11
- ],
- [
- 99,
- -46
- ],
- [
- 9,
- -32
- ]
- ],
- [
- [
- 23055,
- 19805
- ],
- [
- -81,
- -47
- ],
- [
- -111,
- 10
- ],
- [
- -130,
- 48
- ],
- [
- 17,
- 38
- ],
- [
- 130,
- -18
- ],
- [
- 175,
- -31
- ]
- ],
- [
- [
- 22661,
- 19862
- ],
- [
- -55,
- -89
- ],
- [
- -257,
- 4
- ],
- [
- -115,
- -29
- ],
- [
- -138,
- 78
- ],
- [
- 37,
- 83
- ],
- [
- 92,
- 22
- ],
- [
- 184,
- -5
- ],
- [
- 252,
- -64
- ]
- ],
- [
- [
- 16558,
- 19281
- ],
- [
- -41,
- -10
- ],
- [
- -228,
- 16
- ],
- [
- -18,
- 53
- ],
- [
- -126,
- 32
- ],
- [
- -11,
- 65
- ],
- [
- 72,
- 25
- ],
- [
- -3,
- 66
- ],
- [
- 139,
- 102
- ],
- [
- -65,
- 15
- ],
- [
- 167,
- 105
- ],
- [
- -18,
- 55
- ],
- [
- 155,
- 63
- ],
- [
- 231,
- 77
- ],
- [
- 232,
- 22
- ],
- [
- 119,
- 45
- ],
- [
- 136,
- 16
- ],
- [
- 48,
- -48
- ],
- [
- -47,
- -37
- ],
- [
- -247,
- -60
- ],
- [
- -213,
- -57
- ],
- [
- -216,
- -114
- ],
- [
- -104,
- -117
- ],
- [
- -109,
- -116
- ],
- [
- 14,
- -99
- ],
- [
- 133,
- -99
- ]
- ],
- [
- [
- 19872,
- 20192
- ],
- [
- -393,
- -47
- ],
- [
- 128,
- 158
- ],
- [
- 57,
- 13
- ],
- [
- 52,
- -8
- ],
- [
- 177,
- -68
- ],
- [
- -21,
- -48
- ]
- ],
- [
- [
- 16112,
- 20460
- ],
- [
- -93,
- -15
- ],
- [
- -63,
- -10
- ],
- [
- -10,
- -19
- ],
- [
- -81,
- -20
- ],
- [
- -76,
- 28
- ],
- [
- 40,
- 38
- ],
- [
- -155,
- 3
- ],
- [
- 136,
- 22
- ],
- [
- 106,
- 2
- ],
- [
- 14,
- -33
- ],
- [
- 40,
- 29
- ],
- [
- 66,
- 20
- ],
- [
- 103,
- -26
- ],
- [
- -27,
- -19
- ]
- ],
- [
- [
- 19514,
- 20260
- ],
- [
- -152,
- -15
- ],
- [
- -194,
- 35
- ],
- [
- -116,
- 46
- ],
- [
- -53,
- 86
- ],
- [
- -95,
- 24
- ],
- [
- 181,
- 82
- ],
- [
- 150,
- 27
- ],
- [
- 136,
- -61
- ],
- [
- 160,
- -116
- ],
- [
- -17,
- -108
- ]
- ],
- [
- [
- 14609,
- 10636
- ],
- [
- 17,
- -12
- ],
- [
- 42,
- 37
- ]
- ],
- [
- [
- 14668,
- 10661
- ],
- [
- 28,
- -68
- ],
- [
- -4,
- -70
- ],
- [
- -21,
- -15
- ]
- ],
- [
- [
- 11358,
- 13317
- ],
- [
- 3,
- 50
- ]
- ],
- [
- [
- 16172,
- 13077
- ],
- [
- -201,
- -46
- ],
- [
- -65,
- -54
- ],
- [
- -50,
- -126
- ],
- [
- -32,
- -20
- ],
- [
- -18,
- 40
- ],
- [
- -26,
- -6
- ],
- [
- -68,
- 12
- ],
- [
- -13,
- 12
- ],
- [
- -80,
- -3
- ],
- [
- -19,
- -11
- ],
- [
- -28,
- 31
- ],
- [
- -19,
- -59
- ],
- [
- 7,
- -50
- ],
- [
- -30,
- -39
- ]
- ],
- [
- [
- 15530,
- 12758
- ],
- [
- -9,
- 52
- ],
- [
- -21,
- 36
- ],
- [
- -6,
- 48
- ],
- [
- -36,
- 43
- ],
- [
- -37,
- 100
- ],
- [
- -20,
- 98
- ],
- [
- -48,
- 83
- ],
- [
- -31,
- 19
- ],
- [
- -46,
- 115
- ],
- [
- -8,
- 83
- ],
- [
- 3,
- 71
- ],
- [
- -40,
- 133
- ],
- [
- -33,
- 47
- ],
- [
- -38,
- 25
- ],
- [
- -22,
- 68
- ],
- [
- 3,
- 28
- ],
- [
- -19,
- 62
- ],
- [
- -20,
- 27
- ],
- [
- -28,
- 89
- ],
- [
- -42,
- 97
- ],
- [
- -36,
- 82
- ],
- [
- -34,
- -1
- ],
- [
- 10,
- 66
- ],
- [
- 4,
- 42
- ],
- [
- 8,
- 48
- ]
- ],
- [
- [
- 15923,
- 14223
- ],
- [
- 27,
- -104
- ],
- [
- 34,
- -27
- ],
- [
- 12,
- -42
- ],
- [
- 48,
- -51
- ],
- [
- 4,
- -49
- ],
- [
- -7,
- -40
- ],
- [
- 9,
- -41
- ],
- [
- 20,
- -33
- ],
- [
- 9,
- -40
- ],
- [
- 10,
- -29
- ]
- ],
- [
- [
- 16130,
- 13752
- ],
- [
- 13,
- -46
- ]
- ],
- [
- [
- 14141,
- 12134
- ],
- [
- 1,
- 29
- ],
- [
- -25,
- 35
- ],
- [
- -1,
- 70
- ],
- [
- -15,
- 46
- ],
- [
- -24,
- -7
- ],
- [
- 7,
- 44
- ],
- [
- 18,
- 50
- ],
- [
- -8,
- 50
- ],
- [
- 23,
- 37
- ],
- [
- -15,
- 28
- ],
- [
- 19,
- 74
- ],
- [
- 32,
- 88
- ],
- [
- 60,
- -8
- ],
- [
- -4,
- 476
- ]
- ],
- [
- [
- 15117,
- 13437
- ],
- [
- 23,
- -118
- ],
- [
- -15,
- -22
- ],
- [
- 10,
- -123
- ],
- [
- 25,
- -144
- ],
- [
- 27,
- -29
- ],
- [
- 38,
- -45
- ]
- ],
- [
- [
- 14916,
- 11839
- ],
- [
- -1,
- 94
- ],
- [
- -10,
- 2
- ],
- [
- 2,
- 60
- ],
- [
- -9,
- 41
- ],
- [
- -36,
- 47
- ],
- [
- -8,
- 87
- ],
- [
- 8,
- 88
- ],
- [
- -32,
- 9
- ],
- [
- -5,
- -27
- ],
- [
- -42,
- -6
- ],
- [
- 17,
- -35
- ],
- [
- 6,
- -72
- ],
- [
- -38,
- -66
- ],
- [
- -35,
- -87
- ],
- [
- -36,
- -12
- ],
- [
- -58,
- 70
- ],
- [
- -27,
- -25
- ],
- [
- -7,
- -35
- ],
- [
- -36,
- -23
- ],
- [
- -2,
- -24
- ],
- [
- -70,
- 0
- ],
- [
- -9,
- 24
- ],
- [
- -51,
- 5
- ],
- [
- -25,
- -21
- ],
- [
- -19,
- 10
- ],
- [
- -36,
- 70
- ],
- [
- -12,
- 33
- ],
- [
- -50,
- -16
- ],
- [
- -19,
- -56
- ],
- [
- -18,
- -107
- ],
- [
- -24,
- -23
- ],
- [
- -21,
- -13
- ],
- [
- 47,
- -47
- ]
- ],
- [
- [
- 14918,
- 11307
- ],
- [
- -43,
- -55
- ],
- [
- -49,
- 0
- ],
- [
- -56,
- -28
- ],
- [
- -44,
- 27
- ],
- [
- -29,
- -33
- ]
- ],
- [
- [
- 11385,
- 12283
- ],
- [
- -11,
- 92
- ]
- ],
- [
- [
- 11382,
- 12428
- ],
- [
- -28,
- 94
- ],
- [
- -35,
- 42
- ],
- [
- 31,
- 23
- ],
- [
- 33,
- 84
- ],
- [
- 17,
- 62
- ]
- ],
- [
- [
- 23849,
- 9540
- ],
- [
- 19,
- -42
- ],
- [
- -49,
- 1
- ],
- [
- -26,
- 74
- ],
- [
- 41,
- -29
- ],
- [
- 15,
- -4
- ]
- ],
- [
- [
- 23760,
- 9613
- ],
- [
- -27,
- -3
- ],
- [
- -43,
- 12
- ],
- [
- -14,
- 19
- ],
- [
- 4,
- 47
- ],
- [
- 46,
- -19
- ],
- [
- 23,
- -25
- ],
- [
- 11,
- -31
- ]
- ],
- [
- [
- 23818,
- 9645
- ],
- [
- -11,
- -22
- ],
- [
- -51,
- 104
- ],
- [
- -15,
- 72
- ],
- [
- 24,
- 0
- ],
- [
- 25,
- -96
- ],
- [
- 28,
- -58
- ]
- ],
- [
- [
- 23692,
- 9797
- ],
- [
- 3,
- -24
- ],
- [
- -55,
- 51
- ],
- [
- -38,
- 43
- ],
- [
- -26,
- 40
- ],
- [
- 11,
- 12
- ],
- [
- 32,
- -29
- ],
- [
- 57,
- -55
- ],
- [
- 16,
- -38
- ]
- ],
- [
- [
- 23529,
- 9916
- ],
- [
- -14,
- -7
- ],
- [
- -30,
- 27
- ],
- [
- -29,
- 49
- ],
- [
- 4,
- 20
- ],
- [
- 41,
- -50
- ],
- [
- 28,
- -39
- ]
- ],
- [
- [
- 11750,
- 11611
- ],
- [
- -19,
- 9
- ],
- [
- -50,
- 49
- ],
- [
- -36,
- 64
- ],
- [
- -12,
- 44
- ],
- [
- -9,
- 88
- ]
- ],
- [
- [
- 6428,
- 12403
- ],
- [
- -8,
- -28
- ],
- [
- -41,
- 1
- ],
- [
- -25,
- 12
- ],
- [
- -28,
- 24
- ],
- [
- -39,
- 7
- ],
- [
- -20,
- 26
- ]
- ],
- [
- [
- 15555,
- 12172
- ],
- [
- 23,
- -22
- ],
- [
- 13,
- -49
- ],
- [
- 32,
- -51
- ],
- [
- 34,
- 0
- ],
- [
- 66,
- 31
- ],
- [
- 76,
- 14
- ],
- [
- 61,
- 37
- ],
- [
- 35,
- 8
- ],
- [
- 25,
- 22
- ],
- [
- 40,
- 4
- ]
- ],
- [
- [
- 15960,
- 12166
- ],
- [
- -1,
- -2
- ],
- [
- 0,
- -49
- ],
- [
- 0,
- -121
- ],
- [
- 0,
- -63
- ],
- [
- -32,
- -74
- ],
- [
- -48,
- -100
- ]
- ],
- [
- [
- 15960,
- 12166
- ],
- [
- 22,
- 2
- ],
- [
- 32,
- 18
- ],
- [
- 37,
- 12
- ],
- [
- 33,
- 41
- ],
- [
- 26,
- 1
- ],
- [
- 2,
- -33
- ],
- [
- -6,
- -70
- ],
- [
- 0,
- -63
- ],
- [
- -15,
- -44
- ],
- [
- -20,
- -129
- ],
- [
- -33,
- -134
- ],
- [
- -43,
- -153
- ],
- [
- -60,
- -176
- ],
- [
- -60,
- -135
- ],
- [
- -82,
- -163
- ],
- [
- -69,
- -97
- ],
- [
- -105,
- -120
- ],
- [
- -65,
- -91
- ],
- [
- -76,
- -145
- ],
- [
- -16,
- -63
- ],
- [
- -16,
- -29
- ]
- ],
- [
- [
- 8564,
- 11514
- ],
- [
- 83,
- -24
- ],
- [
- 8,
- 21
- ],
- [
- 56,
- 9
- ],
- [
- 75,
- -32
- ]
- ],
- [
- [
- 14120,
- 16686
- ],
- [
- -19,
- -31
- ],
- [
- -14,
- -49
- ]
- ],
- [
- [
- 13504,
- 16256
- ],
- [
- 15,
- 11
- ]
- ],
- [
- [
- 14214,
- 18716
- ],
- [
- -120,
- -34
- ],
- [
- -68,
- -84
- ],
- [
- 11,
- -73
- ],
- [
- -111,
- -97
- ],
- [
- -134,
- -103
- ],
- [
- -51,
- -169
- ],
- [
- 49,
- -84
- ],
- [
- 67,
- -67
- ],
- [
- -64,
- -135
- ],
- [
- -72,
- -28
- ],
- [
- -27,
- -202
- ],
- [
- -40,
- -112
- ],
- [
- -84,
- 12
- ],
- [
- -40,
- -96
- ],
- [
- -80,
- -5
- ],
- [
- -22,
- 113
- ],
- [
- -59,
- 136
- ],
- [
- -53,
- 170
- ]
- ],
- [
- [
- 14783,
- 7590
- ],
- [
- -14,
- -53
- ],
- [
- -41,
- -13
- ],
- [
- -41,
- 65
- ],
- [
- -1,
- 41
- ],
- [
- 19,
- 45
- ],
- [
- 7,
- 35
- ],
- [
- 20,
- 9
- ],
- [
- 35,
- -22
- ]
- ],
- [
- [
- 15057,
- 14954
- ],
- [
- -7,
- 91
- ],
- [
- 17,
- 50
- ]
- ],
- [
- [
- 15067,
- 15095
- ],
- [
- 19,
- 26
- ],
- [
- 19,
- 26
- ],
- [
- 4,
- 67
- ],
- [
- 22,
- -23
- ],
- [
- 77,
- 33
- ],
- [
- 37,
- -22
- ],
- [
- 58,
- 0
- ],
- [
- 80,
- 45
- ],
- [
- 37,
- -2
- ],
- [
- 80,
- 19
- ]
- ],
- [
- [
- 12678,
- 11534
- ],
- [
- -57,
- -26
- ]
- ],
- [
- [
- 19699,
- 12259
- ],
- [
- -63,
- 55
- ],
- [
- -60,
- -2
- ],
- [
- 11,
- 94
- ],
- [
- -62,
- 0
- ],
- [
- -5,
- -132
- ],
- [
- -38,
- -176
- ],
- [
- -23,
- -106
- ],
- [
- 5,
- -86
- ],
- [
- 46,
- -4
- ],
- [
- 28,
- -110
- ],
- [
- 12,
- -103
- ],
- [
- 39,
- -69
- ],
- [
- 42,
- -14
- ],
- [
- 37,
- -62
- ]
- ],
- [
- [
- 19524,
- 11573
- ],
- [
- -27,
- 46
- ],
- [
- -12,
- 59
- ],
- [
- -37,
- 68
- ],
- [
- -34,
- 57
- ],
- [
- -11,
- -71
- ],
- [
- -14,
- 67
- ],
- [
- 8,
- 75
- ],
- [
- 21,
- 115
- ]
- ],
- [
- [
- 17276,
- 15253
- ],
- [
- 39,
- 122
- ],
- [
- -15,
- 89
- ],
- [
- -51,
- 29
- ],
- [
- 18,
- 53
- ],
- [
- 58,
- -6
- ],
- [
- 33,
- 66
- ],
- [
- 22,
- 77
- ],
- [
- 94,
- 28
- ],
- [
- -15,
- -55
- ],
- [
- 10,
- -34
- ],
- [
- 29,
- 3
- ]
- ],
- [
- [
- 16306,
- 15260
- ],
- [
- -13,
- 85
- ],
- [
- 10,
- 125
- ],
- [
- -54,
- 41
- ],
- [
- 18,
- 82
- ],
- [
- -46,
- 7
- ],
- [
- 15,
- 101
- ],
- [
- 66,
- -29
- ],
- [
- 61,
- 38
- ],
- [
- -51,
- 72
- ],
- [
- -20,
- 69
- ],
- [
- -56,
- -31
- ],
- [
- -7,
- -88
- ],
- [
- -22,
- 78
- ]
- ],
- [
- [
- 16449,
- 15753
- ],
- [
- 79,
- 2
- ],
- [
- -12,
- 60
- ],
- [
- 60,
- 41
- ],
- [
- 58,
- 70
- ],
- [
- 94,
- -63
- ],
- [
- 8,
- -96
- ],
- [
- 26,
- -25
- ],
- [
- 76,
- 6
- ],
- [
- 23,
- -22
- ],
- [
- 35,
- -124
- ],
- [
- 79,
- -82
- ],
- [
- 46,
- -57
- ],
- [
- 73,
- -59
- ],
- [
- 92,
- -51
- ],
- [
- -2,
- -73
- ]
- ],
- [
- [
- 21259,
- 9730
- ],
- [
- 8,
- 29
- ],
- [
- 60,
- 27
- ],
- [
- 49,
- 4
- ],
- [
- 21,
- 15
- ],
- [
- 27,
- -15
- ],
- [
- -26,
- -33
- ],
- [
- -72,
- -52
- ],
- [
- -59,
- -35
- ]
- ],
- [
- [
- 8248,
- 12088
- ],
- [
- 40,
- 16
- ],
- [
- 15,
- -5
- ],
- [
- -3,
- -89
- ],
- [
- -58,
- -13
- ],
- [
- -13,
- 11
- ],
- [
- 20,
- 33
- ],
- [
- -1,
- 47
- ]
- ],
- [
- [
- 13135,
- 15230
- ],
- [
- 75,
- 48
- ],
- [
- 49,
- -14
- ],
- [
- -2,
- -61
- ],
- [
- 59,
- 44
- ],
- [
- 5,
- -23
- ],
- [
- -35,
- -59
- ],
- [
- 0,
- -55
- ],
- [
- 24,
- -30
- ],
- [
- -9,
- -104
- ],
- [
- -46,
- -60
- ],
- [
- 13,
- -66
- ],
- [
- 36,
- -2
- ],
- [
- 18,
- -57
- ],
- [
- 26,
- -18
- ]
- ],
- [
- [
- 15067,
- 15095
- ],
- [
- -25,
- 54
- ],
- [
- 26,
- 45
- ],
- [
- -42,
- -10
- ],
- [
- -59,
- 28
- ],
- [
- -48,
- -70
- ],
- [
- -105,
- -13
- ],
- [
- -57,
- 64
- ],
- [
- -75,
- 4
- ],
- [
- -16,
- -49
- ],
- [
- -48,
- -15
- ],
- [
- -68,
- 64
- ],
- [
- -76,
- -2
- ],
- [
- -41,
- 119
- ],
- [
- -51,
- 67
- ],
- [
- 34,
- 93
- ],
- [
- -44,
- 58
- ],
- [
- 77,
- 114
- ],
- [
- 107,
- 5
- ],
- [
- 30,
- 91
- ],
- [
- 133,
- -16
- ],
- [
- 83,
- 78
- ],
- [
- 82,
- 34
- ],
- [
- 115,
- 3
- ],
- [
- 122,
- -85
- ],
- [
- 100,
- -46
- ],
- [
- 81,
- 18
- ],
- [
- 60,
- -10
- ],
- [
- 82,
- 62
- ]
- ],
- [
- [
- 14499,
- 15837
- ],
- [
- 8,
- -46
- ],
- [
- 61,
- -39
- ],
- [
- -12,
- -29
- ],
- [
- -83,
- -7
- ],
- [
- -30,
- -37
- ],
- [
- -58,
- -65
- ],
- [
- -22,
- 56
- ],
- [
- 1,
- 25
- ]
- ],
- [
- [
- 21036,
- 13724
- ],
- [
- -42,
- -193
- ],
- [
- -29,
- -98
- ],
- [
- -37,
- 101
- ],
- [
- -8,
- 89
- ],
- [
- 41,
- 118
- ],
- [
- 56,
- 91
- ],
- [
- 32,
- -36
- ],
- [
- -13,
- -72
- ]
- ],
- [
- [
- 14668,
- 10661
- ],
- [
- 24,
- 14
- ],
- [
- 77,
- -1
- ],
- [
- 142,
- 9
- ]
- ],
- [
- [
- 15280,
- 10236
- ],
- [
- -32,
- -148
- ],
- [
- 4,
- -68
- ],
- [
- 45,
- -43
- ],
- [
- 2,
- -32
- ],
- [
- -19,
- -72
- ],
- [
- 4,
- -36
- ],
- [
- -5,
- -58
- ],
- [
- 24,
- -75
- ],
- [
- 29,
- -118
- ],
- [
- 26,
- -27
- ]
- ],
- [
- [
- 14831,
- 9690
- ],
- [
- -39,
- 36
- ],
- [
- -45,
- 20
- ],
- [
- -28,
- 20
- ],
- [
- -29,
- 31
- ]
- ],
- [
- [
- 15212,
- 16448
- ],
- [
- -56,
- -10
- ],
- [
- -46,
- -38
- ],
- [
- -65,
- -7
- ],
- [
- -60,
- -44
- ],
- [
- 3,
- -65
- ]
- ],
- [
- [
- 14878,
- 16312
- ],
- [
- -9,
- 13
- ],
- [
- -109,
- 31
- ],
- [
- -4,
- 44
- ],
- [
- -65,
- -14
- ],
- [
- -26,
- -66
- ],
- [
- -54,
- -89
- ]
- ],
- [
- [
- 8827,
- 6746
- ],
- [
- -30,
- -75
- ],
- [
- -79,
- -67
- ],
- [
- -51,
- 24
- ],
- [
- -38,
- -13
- ],
- [
- -65,
- 52
- ],
- [
- -47,
- -4
- ],
- [
- -42,
- 66
- ]
- ],
- [
- [
- 7867,
- 16212
- ],
- [
- 13,
- -39
- ],
- [
- -75,
- -58
- ],
- [
- -72,
- -42
- ],
- [
- -73,
- -35
- ],
- [
- -37,
- -71
- ],
- [
- -12,
- -27
- ],
- [
- -1,
- -64
- ],
- [
- 23,
- -64
- ],
- [
- 29,
- -3
- ],
- [
- -7,
- 44
- ],
- [
- 21,
- -26
- ],
- [
- -6,
- -35
- ],
- [
- -47,
- -19
- ],
- [
- -33,
- 2
- ],
- [
- -52,
- -21
- ],
- [
- -30,
- -6
- ],
- [
- -41,
- -6
- ],
- [
- -58,
- -34
- ],
- [
- 103,
- 22
- ],
- [
- 20,
- -22
- ],
- [
- -97,
- -36
- ],
- [
- -45,
- -1
- ],
- [
- 2,
- 15
- ],
- [
- -21,
- -33
- ],
- [
- 21,
- -6
- ],
- [
- -15,
- -86
- ],
- [
- -51,
- -92
- ],
- [
- -5,
- 31
- ],
- [
- -16,
- 6
- ],
- [
- -22,
- 30
- ],
- [
- 14,
- -65
- ],
- [
- 17,
- -21
- ],
- [
- 1,
- -46
- ],
- [
- -22,
- -46
- ],
- [
- -39,
- -96
- ],
- [
- -7,
- 5
- ],
- [
- 22,
- 81
- ],
- [
- -36,
- 46
- ],
- [
- -8,
- 100
- ],
- [
- -13,
- -52
- ],
- [
- 15,
- -76
- ],
- [
- -46,
- 19
- ],
- [
- 48,
- -39
- ],
- [
- 3,
- -114
- ],
- [
- 20,
- -8
- ],
- [
- 7,
- -42
- ],
- [
- 10,
- -120
- ],
- [
- -45,
- -89
- ],
- [
- -72,
- -35
- ],
- [
- -46,
- -71
- ],
- [
- -34,
- -8
- ],
- [
- -36,
- -44
- ],
- [
- -10,
- -40
- ],
- [
- -76,
- -78
- ],
- [
- -39,
- -57
- ],
- [
- -33,
- -71
- ],
- [
- -11,
- -85
- ],
- [
- 12,
- -83
- ],
- [
- 24,
- -103
- ],
- [
- 30,
- -85
- ],
- [
- 1,
- -52
- ],
- [
- 33,
- -139
- ],
- [
- -2,
- -81
- ],
- [
- -3,
- -47
- ],
- [
- -18,
- -73
- ],
- [
- -21,
- -15
- ],
- [
- -34,
- 15
- ],
- [
- -11,
- 52
- ],
- [
- -26,
- 28
- ],
- [
- -37,
- 103
- ],
- [
- -33,
- 92
- ],
- [
- -10,
- 47
- ],
- [
- 14,
- 79
- ],
- [
- -19,
- 66
- ],
- [
- -55,
- 101
- ],
- [
- -27,
- 18
- ],
- [
- -70,
- -54
- ],
- [
- -13,
- 6
- ],
- [
- -34,
- 56
- ],
- [
- -43,
- 29
- ],
- [
- -79,
- -15
- ],
- [
- -62,
- 13
- ],
- [
- -53,
- -8
- ],
- [
- -29,
- -19
- ],
- [
- 13,
- -31
- ],
- [
- -2,
- -49
- ],
- [
- 15,
- -24
- ],
- [
- -13,
- -16
- ],
- [
- -26,
- 18
- ],
- [
- -26,
- -23
- ],
- [
- -51,
- 4
- ],
- [
- -52,
- 64
- ],
- [
- -60,
- -15
- ],
- [
- -51,
- 27
- ],
- [
- -44,
- -8
- ],
- [
- -58,
- -28
- ],
- [
- -64,
- -89
- ],
- [
- -69,
- -52
- ],
- [
- -38,
- -57
- ],
- [
- -16,
- -54
- ],
- [
- -1,
- -83
- ],
- [
- 4,
- -57
- ],
- [
- 13,
- -41
- ]
- ],
- [
- [
- 4383,
- 14700
- ],
- [
- -12,
- 62
- ],
- [
- -45,
- 69
- ],
- [
- -33,
- 14
- ],
- [
- -7,
- 34
- ],
- [
- -39,
- 6
- ],
- [
- -25,
- 33
- ],
- [
- -65,
- 12
- ],
- [
- -18,
- 19
- ],
- [
- -8,
- 66
- ],
- [
- -68,
- 120
- ],
- [
- -58,
- 167
- ],
- [
- 2,
- 28
- ],
- [
- -30,
- 40
- ],
- [
- -54,
- 100
- ],
- [
- -10,
- 98
- ],
- [
- -37,
- 66
- ],
- [
- 15,
- 99
- ],
- [
- -2,
- 103
- ],
- [
- -22,
- 92
- ],
- [
- 27,
- 113
- ],
- [
- 8,
- 109
- ],
- [
- 9,
- 109
- ],
- [
- -13,
- 161
- ],
- [
- -22,
- 102
- ],
- [
- -20,
- 56
- ],
- [
- 8,
- 23
- ],
- [
- 101,
- -41
- ],
- [
- 37,
- -113
- ],
- [
- 17,
- 32
- ],
- [
- -11,
- 98
- ],
- [
- -23,
- 99
- ]
- ],
- [
- [
- 3448,
- 17372
- ],
- [
- -38,
- 45
- ],
- [
- -62,
- 38
- ],
- [
- -19,
- 105
- ],
- [
- -90,
- 97
- ],
- [
- -38,
- 113
- ],
- [
- -67,
- 8
- ],
- [
- -111,
- 3
- ],
- [
- -81,
- 34
- ],
- [
- -144,
- 125
- ],
- [
- -67,
- 23
- ],
- [
- -122,
- 42
- ],
- [
- -97,
- -10
- ],
- [
- -137,
- 55
- ],
- [
- -83,
- 51
- ],
- [
- -77,
- -25
- ],
- [
- 14,
- -83
- ],
- [
- -38,
- -8
- ],
- [
- -81,
- -25
- ],
- [
- -61,
- -40
- ],
- [
- -77,
- -26
- ],
- [
- -10,
- 71
- ],
- [
- 31,
- 117
- ],
- [
- 74,
- 37
- ],
- [
- -19,
- 30
- ],
- [
- -89,
- -66
- ],
- [
- -47,
- -80
- ],
- [
- -101,
- -86
- ],
- [
- 51,
- -58
- ],
- [
- -66,
- -86
- ],
- [
- -75,
- -50
- ],
- [
- -69,
- -37
- ],
- [
- -18,
- -53
- ],
- [
- -109,
- -62
- ],
- [
- -22,
- -56
- ],
- [
- -81,
- -52
- ],
- [
- -48,
- 10
- ],
- [
- -65,
- -34
- ],
- [
- -71,
- -41
- ],
- [
- -58,
- -40
- ],
- [
- -119,
- -34
- ],
- [
- -11,
- 20
- ],
- [
- 76,
- 56
- ],
- [
- 68,
- 37
- ],
- [
- 74,
- 66
- ],
- [
- 87,
- 13
- ],
- [
- 34,
- 50
- ],
- [
- 97,
- 71
- ],
- [
- 15,
- 24
- ],
- [
- 52,
- 43
- ],
- [
- 12,
- 91
- ],
- [
- 35,
- 71
- ],
- [
- -80,
- -37
- ],
- [
- -22,
- 21
- ],
- [
- -38,
- -44
- ],
- [
- -46,
- 61
- ],
- [
- -19,
- -43
- ],
- [
- -26,
- 60
- ],
- [
- -69,
- -48
- ],
- [
- -43,
- 0
- ],
- [
- -6,
- 71
- ],
- [
- 13,
- 44
- ],
- [
- -45,
- 43
- ],
- [
- -91,
- -23
- ],
- [
- -59,
- 56
- ],
- [
- -48,
- 29
- ],
- [
- 0,
- 68
- ],
- [
- -54,
- 51
- ],
- [
- 27,
- 69
- ],
- [
- 57,
- 67
- ],
- [
- 25,
- 62
- ],
- [
- 57,
- 9
- ],
- [
- 47,
- -20
- ],
- [
- 57,
- 58
- ],
- [
- 50,
- -10
- ],
- [
- 53,
- 37
- ],
- [
- -13,
- 55
- ],
- [
- -39,
- 22
- ],
- [
- 52,
- 46
- ],
- [
- -43,
- -2
- ],
- [
- -74,
- -26
- ],
- [
- -21,
- -26
- ],
- [
- -55,
- 26
- ],
- [
- -99,
- -13
- ],
- [
- -102,
- 29
- ],
- [
- -29,
- 48
- ],
- [
- -88,
- 70
- ],
- [
- 98,
- 50
- ],
- [
- 155,
- 58
- ],
- [
- 58,
- 0
- ],
- [
- -10,
- -60
- ],
- [
- 147,
- 5
- ],
- [
- -56,
- 74
- ],
- [
- -86,
- 46
- ],
- [
- -50,
- 60
- ],
- [
- -67,
- 51
- ],
- [
- -95,
- 38
- ],
- [
- 39,
- 63
- ],
- [
- 123,
- 4
- ],
- [
- 88,
- 55
- ],
- [
- 17,
- 58
- ],
- [
- 71,
- 57
- ],
- [
- 68,
- 14
- ],
- [
- 132,
- 53
- ],
- [
- 64,
- -8
- ],
- [
- 108,
- 64
- ],
- [
- 105,
- -25
- ],
- [
- 50,
- -54
- ],
- [
- 31,
- 23
- ],
- [
- 118,
- -7
- ],
- [
- -4,
- -28
- ],
- [
- 107,
- -20
- ],
- [
- 71,
- 12
- ],
- [
- 147,
- -38
- ],
- [
- 134,
- -12
- ],
- [
- 53,
- -15
- ],
- [
- 93,
- 19
- ],
- [
- 106,
- -36
- ],
- [
- 76,
- -17
- ]
- ],
- [
- [
- 1705,
- 13087
- ],
- [
- -10,
- -20
- ],
- [
- -18,
- 17
- ],
- [
- 2,
- 33
- ],
- [
- -11,
- 44
- ],
- [
- 3,
- 13
- ],
- [
- 12,
- 20
- ],
- [
- -4,
- 23
- ],
- [
- 4,
- 12
- ],
- [
- 5,
- -3
- ],
- [
- 27,
- -20
- ],
- [
- 12,
- -10
- ],
- [
- 11,
- -16
- ],
- [
- 18,
- -42
- ],
- [
- -2,
- -7
- ],
- [
- -27,
- -26
- ],
- [
- -22,
- -18
- ]
- ],
- [
- [
- 1667,
- 13274
- ],
- [
- -23,
- -9
- ],
- [
- -12,
- 26
- ],
- [
- -8,
- 9
- ],
- [
- -1,
- 8
- ],
- [
- 7,
- 10
- ],
- [
- 25,
- -11
- ],
- [
- 18,
- -19
- ],
- [
- -6,
- -14
- ]
- ],
- [
- [
- 1620,
- 13338
- ],
- [
- -2,
- -13
- ],
- [
- -37,
- 3
- ],
- [
- 5,
- 15
- ],
- [
- 34,
- -5
- ]
- ],
- [
- [
- 1558,
- 13355
- ],
- [
- -4,
- -7
- ],
- [
- -5,
- 2
- ],
- [
- -24,
- 4
- ],
- [
- -9,
- 27
- ],
- [
- -3,
- 5
- ],
- [
- 19,
- 17
- ],
- [
- 6,
- -8
- ],
- [
- 20,
- -40
- ]
- ],
- [
- [
- 1440,
- 13434
- ],
- [
- -8,
- -12
- ],
- [
- -24,
- 22
- ],
- [
- 4,
- 9
- ],
- [
- 10,
- 12
- ],
- [
- 16,
- -3
- ],
- [
- 2,
- -28
- ]
- ],
- [
- [
- 1882,
- 17649
- ],
- [
- -70,
- -45
- ],
- [
- -36,
- 31
- ],
- [
- -10,
- 56
- ],
- [
- 63,
- 42
- ],
- [
- 37,
- 19
- ],
- [
- 46,
- -8
- ],
- [
- 30,
- -38
- ],
- [
- -60,
- -57
- ]
- ],
- [
- [
- 1005,
- 17985
- ],
- [
- -43,
- -19
- ],
- [
- -45,
- 22
- ],
- [
- -43,
- 33
- ],
- [
- 69,
- 20
- ],
- [
- 56,
- -10
- ],
- [
- 6,
- -46
- ]
- ],
- [
- [
- 576,
- 18449
- ],
- [
- 43,
- -23
- ],
- [
- 44,
- 13
- ],
- [
- 56,
- -32
- ],
- [
- 69,
- -16
- ],
- [
- -5,
- -13
- ],
- [
- -53,
- -26
- ],
- [
- -53,
- 27
- ],
- [
- -27,
- 21
- ],
- [
- -61,
- -7
- ],
- [
- -17,
- 11
- ],
- [
- 4,
- 45
- ]
- ],
- [
- [
- 7575,
- 12210
- ],
- [
- -2,
- -28
- ],
- [
- -41,
- -14
- ],
- [
- 23,
- -55
- ],
- [
- -1,
- -63
- ],
- [
- -31,
- -69
- ],
- [
- 27,
- -95
- ],
- [
- 30,
- 7
- ],
- [
- 15,
- 87
- ],
- [
- -21,
- 42
- ],
- [
- -4,
- 91
- ],
- [
- 87,
- 49
- ],
- [
- -10,
- 56
- ],
- [
- 25,
- 38
- ],
- [
- 25,
- -84
- ],
- [
- 49,
- -2
- ],
- [
- 45,
- -67
- ],
- [
- 3,
- -40
- ],
- [
- 62,
- -1
- ],
- [
- 75,
- 13
- ],
- [
- 40,
- -54
- ],
- [
- 53,
- -15
- ],
- [
- 39,
- 38
- ],
- [
- 1,
- 30
- ],
- [
- 86,
- 7
- ],
- [
- 84,
- 2
- ],
- [
- -59,
- -36
- ],
- [
- 24,
- -56
- ],
- [
- 55,
- -9
- ],
- [
- 53,
- -59
- ],
- [
- 11,
- -96
- ],
- [
- 37,
- 2
- ],
- [
- 27,
- -28
- ]
- ],
- [
- [
- 20079,
- 13383
- ],
- [
- -93,
- -103
- ],
- [
- -58,
- -113
- ],
- [
- -15,
- -83
- ],
- [
- 53,
- -127
- ],
- [
- 66,
- -157
- ],
- [
- 63,
- -74
- ],
- [
- 42,
- -96
- ],
- [
- 32,
- -222
- ],
- [
- -9,
- -211
- ],
- [
- -58,
- -79
- ],
- [
- -80,
- -77
- ],
- [
- -57,
- -100
- ],
- [
- -87,
- -112
- ],
- [
- -25,
- 77
- ],
- [
- 19,
- 81
- ],
- [
- -52,
- 68
- ]
- ],
- [
- [
- 24248,
- 8822
- ],
- [
- -23,
- -16
- ],
- [
- -24,
- 52
- ],
- [
- 3,
- 33
- ],
- [
- 44,
- -69
- ]
- ],
- [
- [
- 24196,
- 9006
- ],
- [
- 12,
- -97
- ],
- [
- -19,
- 15
- ],
- [
- -15,
- -7
- ],
- [
- -10,
- 34
- ],
- [
- -1,
- 91
- ],
- [
- 33,
- -36
- ]
- ],
- [
- [
- 16250,
- 12795
- ],
- [
- -51,
- -32
- ],
- [
- -13,
- -54
- ],
- [
- -2,
- -41
- ],
- [
- -69,
- -50
- ],
- [
- -112,
- -56
- ],
- [
- -62,
- -85
- ],
- [
- -31,
- -6
- ],
- [
- -21,
- 7
- ],
- [
- -40,
- -50
- ],
- [
- -45,
- -23
- ],
- [
- -58,
- -6
- ],
- [
- -18,
- -7
- ],
- [
- -15,
- -32
- ],
- [
- -19,
- -9
- ],
- [
- -10,
- -30
- ],
- [
- -35,
- 2
- ],
- [
- -22,
- -16
- ],
- [
- -48,
- 6
- ],
- [
- -19,
- 70
- ],
- [
- 2,
- 66
- ],
- [
- -11,
- 35
- ],
- [
- -14,
- 89
- ],
- [
- -20,
- 49
- ],
- [
- 14,
- 6
- ],
- [
- -7,
- 55
- ],
- [
- 9,
- 23
- ],
- [
- -3,
- 52
- ]
- ],
- [
- [
- 14599,
- 8147
- ],
- [
- 29,
- -1
- ],
- [
- 33,
- -21
- ],
- [
- 24,
- 15
- ],
- [
- 37,
- -12
- ]
- ],
- [
- [
- 14836,
- 7589
- ],
- [
- -17,
- -87
- ],
- [
- -9,
- -100
- ],
- [
- -18,
- -54
- ],
- [
- -47,
- -61
- ],
- [
- -14,
- -17
- ],
- [
- -29,
- -61
- ],
- [
- -20,
- -62
- ],
- [
- -39,
- -86
- ],
- [
- -79,
- -123
- ],
- [
- -49,
- -72
- ],
- [
- -53,
- -55
- ],
- [
- -73,
- -47
- ],
- [
- -35,
- -6
- ],
- [
- -9,
- -33
- ],
- [
- -43,
- 18
- ],
- [
- -34,
- -23
- ],
- [
- -76,
- 23
- ],
- [
- -42,
- -15
- ],
- [
- -29,
- 7
- ],
- [
- -72,
- -48
- ],
- [
- -59,
- -19
- ],
- [
- -43,
- -45
- ],
- [
- -32,
- -3
- ],
- [
- -30,
- 43
- ],
- [
- -23,
- 2
- ],
- [
- -30,
- 54
- ],
- [
- -3,
- -17
- ],
- [
- -10,
- 32
- ],
- [
- 1,
- 70
- ],
- [
- -23,
- 81
- ],
- [
- 23,
- 22
- ],
- [
- -2,
- 92
- ],
- [
- -46,
- 112
- ],
- [
- -35,
- 102
- ],
- [
- 0,
- 0
- ],
- [
- -50,
- 156
- ]
- ],
- [
- [
- 14658,
- 8937
- ],
- [
- -53,
- -17
- ],
- [
- -40,
- -47
- ],
- [
- -8,
- -42
- ],
- [
- -25,
- -10
- ],
- [
- -61,
- -98
- ],
- [
- -38,
- -78
- ],
- [
- -24,
- -3
- ],
- [
- -22,
- 14
- ],
- [
- -78,
- 13
- ]
- ]
- ],
- "transform": {
- "scale": [
- 0.01434548714883443,
- 0.008335499711981569
- ],
- "translate": [
- -180,
- -90
- ]
- },
- "objects": {
- "ne_110m_admin_0_countries": {
- "type": "GeometryCollection",
- "geometries": [
- {
- "arcs": [
- [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Afghanistan",
- "NAME_LONG": "Afghanistan",
- "ABBREV": "Afg.",
- "FORMAL_EN": "Islamic State of Afghanistan",
- "POP_EST": 34124811,
- "POP_RANK": 15,
- "GDP_MD_EST": 64080,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AF",
- "ISO_A3": "AFG",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 6,
- 7,
- 8,
- 9
- ]
- ],
- [
- [
- 10,
- 11,
- 12
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Angola",
- "NAME_LONG": "Angola",
- "ABBREV": "Ang.",
- "FORMAL_EN": "People's Republic of Angola",
- "POP_EST": 29310273,
- "POP_RANK": 15,
- "GDP_MD_EST": 189000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AO",
- "ISO_A3": "AGO",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- 13,
- 14,
- 15,
- 16,
- 17
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Albania",
- "NAME_LONG": "Albania",
- "ABBREV": "Alb.",
- "FORMAL_EN": "Republic of Albania",
- "POP_EST": 3047987,
- "POP_RANK": 12,
- "GDP_MD_EST": 33900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AL",
- "ISO_A3": "ALB",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 18,
- 19,
- 20,
- 21,
- 22
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "United Arab Emirates",
- "NAME_LONG": "United Arab Emirates",
- "ABBREV": "U.A.E.",
- "FORMAL_EN": "United Arab Emirates",
- "POP_EST": 6072475,
- "POP_RANK": 13,
- "GDP_MD_EST": 667200,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AE",
- "ISO_A3": "ARE",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 23,
- 24
- ]
- ],
- [
- [
- 25,
- 26,
- 27,
- 28,
- 29,
- 30
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Argentina",
- "NAME_LONG": "Argentina",
- "ABBREV": "Arg.",
- "FORMAL_EN": "Argentine Republic",
- "POP_EST": 44293293,
- "POP_RANK": 15,
- "GDP_MD_EST": 879400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AR",
- "ISO_A3": "ARG",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 31,
- 32,
- 33,
- 34,
- 35
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Armenia",
- "NAME_LONG": "Armenia",
- "ABBREV": "Arm.",
- "FORMAL_EN": "Republic of Armenia",
- "POP_EST": 3045191,
- "POP_RANK": 12,
- "GDP_MD_EST": 26300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AM",
- "ISO_A3": "ARM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 36
- ]
- ],
- [
- [
- 37
- ]
- ],
- [
- [
- 38
- ]
- ],
- [
- [
- 39
- ]
- ],
- [
- [
- 40
- ]
- ],
- [
- [
- 41
- ]
- ],
- [
- [
- 42
- ]
- ],
- [
- [
- 43
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Antarctica",
- "NAME_LONG": "Antarctica",
- "ABBREV": "Ant.",
- "FORMAL_EN": "",
- "POP_EST": 4050,
- "POP_RANK": 4,
- "GDP_MD_EST": 810,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2013,
- "ISO_A2": "AQ",
- "ISO_A3": "ATA",
- "CONTINENT": "Antarctica",
- "REGION_UN": "Antarctica",
- "SUBREGION": "Antarctica"
- }
- },
- {
- "arcs": [
- [
- 44
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Fr. S. Antarctic Lands",
- "NAME_LONG": "French Southern and Antarctic Lands",
- "ABBREV": "Fr. S.A.L.",
- "FORMAL_EN": "Territory of the French Southern and Antarctic Lands",
- "POP_EST": 140,
- "POP_RANK": 1,
- "GDP_MD_EST": 16,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TF",
- "ISO_A3": "ATF",
- "CONTINENT": "Seven seas (open ocean)",
- "REGION_UN": "Seven seas (open ocean)",
- "SUBREGION": "Seven seas (open ocean)"
- }
- },
- {
- "arcs": [
- [
- [
- 45
- ]
- ],
- [
- [
- 46
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Australia",
- "NAME_LONG": "Australia",
- "ABBREV": "Auz.",
- "FORMAL_EN": "Commonwealth of Australia",
- "POP_EST": 23232413,
- "POP_RANK": 15,
- "GDP_MD_EST": 1189000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AU",
- "ISO_A3": "AUS",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Australia and New Zealand"
- }
- },
- {
- "arcs": [
- [
- 47,
- 48,
- 49,
- 50,
- 51,
- 52,
- 53
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Austria",
- "NAME_LONG": "Austria",
- "ABBREV": "Aust.",
- "FORMAL_EN": "Republic of Austria",
- "POP_EST": 8754413,
- "POP_RANK": 13,
- "GDP_MD_EST": 416600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AT",
- "ISO_A3": "AUT",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -33,
- 54,
- 55,
- 56,
- 57
- ]
- ],
- [
- [
- -35,
- 58
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Azerbaijan",
- "NAME_LONG": "Azerbaijan",
- "ABBREV": "Aze.",
- "FORMAL_EN": "Republic of Azerbaijan",
- "POP_EST": 9961396,
- "POP_RANK": 13,
- "GDP_MD_EST": 167900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "AZ",
- "ISO_A3": "AZE",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 59,
- 60,
- 61
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Burundi",
- "NAME_LONG": "Burundi",
- "ABBREV": "Bur.",
- "FORMAL_EN": "Republic of Burundi",
- "POP_EST": 11466756,
- "POP_RANK": 14,
- "GDP_MD_EST": 7892,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BI",
- "ISO_A3": "BDI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- 62,
- 63,
- 64,
- 65,
- 66
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Belgium",
- "NAME_LONG": "Belgium",
- "ABBREV": "Belg.",
- "FORMAL_EN": "Kingdom of Belgium",
- "POP_EST": 11491346,
- "POP_RANK": 14,
- "GDP_MD_EST": 508600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BE",
- "ISO_A3": "BEL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- 67,
- 68,
- 69,
- 70,
- 71
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Benin",
- "NAME_LONG": "Benin",
- "ABBREV": "Benin",
- "FORMAL_EN": "Republic of Benin",
- "POP_EST": 11038805,
- "POP_RANK": 14,
- "GDP_MD_EST": 24310,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BJ",
- "ISO_A3": "BEN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -70,
- 72,
- 73,
- 74,
- 75,
- 76
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Burkina Faso",
- "NAME_LONG": "Burkina Faso",
- "ABBREV": "B.F.",
- "FORMAL_EN": "Burkina Faso",
- "POP_EST": 20107509,
- "POP_RANK": 15,
- "GDP_MD_EST": 32990,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BF",
- "ISO_A3": "BFA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- 77,
- 78,
- 79
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bangladesh",
- "NAME_LONG": "Bangladesh",
- "ABBREV": "Bang.",
- "FORMAL_EN": "People's Republic of Bangladesh",
- "POP_EST": 157826578,
- "POP_RANK": 17,
- "GDP_MD_EST": 628400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BD",
- "ISO_A3": "BGD",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- 80,
- 81,
- 82,
- 83,
- 84,
- 85
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bulgaria",
- "NAME_LONG": "Bulgaria",
- "ABBREV": "Bulg.",
- "FORMAL_EN": "Republic of Bulgaria",
- "POP_EST": 7101510,
- "POP_RANK": 13,
- "GDP_MD_EST": 143100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BG",
- "ISO_A3": "BGR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- 86
- ]
- ],
- [
- [
- 87
- ]
- ],
- [
- [
- 88
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Bahamas",
- "NAME_LONG": "Bahamas",
- "ABBREV": "Bhs.",
- "FORMAL_EN": "Commonwealth of the Bahamas",
- "POP_EST": 329988,
- "POP_RANK": 10,
- "GDP_MD_EST": 9066,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BS",
- "ISO_A3": "BHS",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- 89,
- 90,
- 91
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bosnia and Herz.",
- "NAME_LONG": "Bosnia and Herzegovina",
- "ABBREV": "B.H.",
- "FORMAL_EN": "Bosnia and Herzegovina",
- "POP_EST": 3856181,
- "POP_RANK": 12,
- "GDP_MD_EST": 42530,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BA",
- "ISO_A3": "BIH",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 92,
- 93,
- 94,
- 95,
- 96
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Belarus",
- "NAME_LONG": "Belarus",
- "ABBREV": "Bela.",
- "FORMAL_EN": "Republic of Belarus",
- "POP_EST": 9549747,
- "POP_RANK": 13,
- "GDP_MD_EST": 165400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BY",
- "ISO_A3": "BLR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- 97,
- 98,
- 99
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Belize",
- "NAME_LONG": "Belize",
- "ABBREV": "Belize",
- "FORMAL_EN": "Belize",
- "POP_EST": 360346,
- "POP_RANK": 10,
- "GDP_MD_EST": 3088,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BZ",
- "ISO_A3": "BLZ",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -27,
- 100,
- 101,
- 102,
- 103
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bolivia",
- "NAME_LONG": "Bolivia",
- "ABBREV": "Bolivia",
- "FORMAL_EN": "Plurinational State of Bolivia",
- "POP_EST": 11138234,
- "POP_RANK": 14,
- "GDP_MD_EST": 78350,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BO",
- "ISO_A3": "BOL",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -29,
- 104,
- -103,
- 105,
- 106,
- 107,
- 108,
- 109,
- 110,
- 111,
- 112
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Brazil",
- "NAME_LONG": "Brazil",
- "ABBREV": "Brazil",
- "FORMAL_EN": "Federative Republic of Brazil",
- "POP_EST": 207353391,
- "POP_RANK": 17,
- "GDP_MD_EST": 3081000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BR",
- "ISO_A3": "BRA",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 113,
- 114
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Brunei",
- "NAME_LONG": "Brunei Darussalam",
- "ABBREV": "Brunei",
- "FORMAL_EN": "Negara Brunei Darussalam",
- "POP_EST": 443593,
- "POP_RANK": 10,
- "GDP_MD_EST": 33730,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BN",
- "ISO_A3": "BRN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 115,
- 116
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Bhutan",
- "NAME_LONG": "Bhutan",
- "ABBREV": "Bhutan",
- "FORMAL_EN": "Kingdom of Bhutan",
- "POP_EST": 758288,
- "POP_RANK": 11,
- "GDP_MD_EST": 6432,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BT",
- "ISO_A3": "BTN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- 117,
- 118,
- 119,
- 120
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Botswana",
- "NAME_LONG": "Botswana",
- "ABBREV": "Bwa.",
- "FORMAL_EN": "Republic of Botswana",
- "POP_EST": 2214858,
- "POP_RANK": 12,
- "GDP_MD_EST": 35900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "BW",
- "ISO_A3": "BWA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- 121,
- 122,
- 123,
- 124,
- 125,
- 126
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Central African Rep.",
- "NAME_LONG": "Central African Republic",
- "ABBREV": "C.A.R.",
- "FORMAL_EN": "Central African Republic",
- "POP_EST": 5625118,
- "POP_RANK": 13,
- "GDP_MD_EST": 3206,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CF",
- "ISO_A3": "CAF",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- [
- 127
- ]
- ],
- [
- [
- 128
- ]
- ],
- [
- [
- 129
- ]
- ],
- [
- [
- 130
- ]
- ],
- [
- [
- 131
- ]
- ],
- [
- [
- 132
- ]
- ],
- [
- [
- 133
- ]
- ],
- [
- [
- 134
- ]
- ],
- [
- [
- 135
- ]
- ],
- [
- [
- 136
- ]
- ],
- [
- [
- 137,
- 138,
- 139,
- 140
- ]
- ],
- [
- [
- 141
- ]
- ],
- [
- [
- 142
- ]
- ],
- [
- [
- 143
- ]
- ],
- [
- [
- 144
- ]
- ],
- [
- [
- 145
- ]
- ],
- [
- [
- 146
- ]
- ],
- [
- [
- 147
- ]
- ],
- [
- [
- 148
- ]
- ],
- [
- [
- 149
- ]
- ],
- [
- [
- 150
- ]
- ],
- [
- [
- 151
- ]
- ],
- [
- [
- 152
- ]
- ],
- [
- [
- 153
- ]
- ],
- [
- [
- 154
- ]
- ],
- [
- [
- 155
- ]
- ],
- [
- [
- 156
- ]
- ],
- [
- [
- 157
- ]
- ],
- [
- [
- 158
- ]
- ],
- [
- [
- 159
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Canada",
- "NAME_LONG": "Canada",
- "ABBREV": "Can.",
- "FORMAL_EN": "Canada",
- "POP_EST": 35623680,
- "POP_RANK": 15,
- "GDP_MD_EST": 1674000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CA",
- "ISO_A3": "CAN",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Northern America"
- }
- },
- {
- "arcs": [
- [
- -51,
- 160,
- 161,
- 162
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Switzerland",
- "NAME_LONG": "Switzerland",
- "ABBREV": "Switz.",
- "FORMAL_EN": "Swiss Confederation",
- "POP_EST": 8236303,
- "POP_RANK": 13,
- "GDP_MD_EST": 496300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CH",
- "ISO_A3": "CHE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -24,
- 163
- ]
- ],
- [
- [
- -26,
- 164,
- 165,
- -101
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Chile",
- "NAME_LONG": "Chile",
- "ABBREV": "Chile",
- "FORMAL_EN": "Republic of Chile",
- "POP_EST": 17789267,
- "POP_RANK": 14,
- "GDP_MD_EST": 436100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CL",
- "ISO_A3": "CHL",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- -4,
- 166,
- 167,
- 168,
- 169,
- 170,
- 171,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- -117,
- 178,
- 179,
- 180,
- 181
- ]
- ],
- [
- [
- 182
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "China",
- "NAME_LONG": "China",
- "ABBREV": "China",
- "FORMAL_EN": "People's Republic of China",
- "POP_EST": 1379302771,
- "POP_RANK": 18,
- "GDP_MD_EST": 21140000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CN",
- "ISO_A3": "CHN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -75,
- 183,
- 184,
- 185,
- 186,
- 187
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Côte d'Ivoire",
- "NAME_LONG": "Côte d'Ivoire",
- "ABBREV": "I.C.",
- "FORMAL_EN": "Republic of Ivory Coast",
- "POP_EST": 24184810,
- "POP_RANK": 15,
- "GDP_MD_EST": 87120,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CI",
- "ISO_A3": "CIV",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -127,
- 188,
- 189,
- 190,
- 191,
- 192,
- 193,
- 194
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cameroon",
- "NAME_LONG": "Cameroon",
- "ABBREV": "Cam.",
- "FORMAL_EN": "Republic of Cameroon",
- "POP_EST": 24994885,
- "POP_RANK": 15,
- "GDP_MD_EST": 77240,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CM",
- "ISO_A3": "CMR",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -9,
- 195,
- -13,
- 196,
- -125,
- 197,
- 198,
- 199,
- -60,
- 200,
- 201
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Dem. Rep. Congo",
- "NAME_LONG": "Democratic Republic of the Congo",
- "ABBREV": "D.R.C.",
- "FORMAL_EN": "Democratic Republic of the Congo",
- "POP_EST": 83301151,
- "POP_RANK": 16,
- "GDP_MD_EST": 66010,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CD",
- "ISO_A3": "COD",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -12,
- 202,
- 203,
- -189,
- -126,
- -197
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Congo",
- "NAME_LONG": "Republic of the Congo",
- "ABBREV": "Rep. Congo",
- "FORMAL_EN": "Republic of the Congo",
- "POP_EST": 4954674,
- "POP_RANK": 12,
- "GDP_MD_EST": 30270,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CG",
- "ISO_A3": "COG",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -107,
- 204,
- 205,
- 206,
- 207,
- 208,
- 209
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Colombia",
- "NAME_LONG": "Colombia",
- "ABBREV": "Col.",
- "FORMAL_EN": "Republic of Colombia",
- "POP_EST": 47698524,
- "POP_RANK": 15,
- "GDP_MD_EST": 688000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CO",
- "ISO_A3": "COL",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 210,
- 211,
- 212,
- 213
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Costa Rica",
- "NAME_LONG": "Costa Rica",
- "ABBREV": "C.R.",
- "FORMAL_EN": "Republic of Costa Rica",
- "POP_EST": 4930258,
- "POP_RANK": 12,
- "GDP_MD_EST": 79260,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CR",
- "ISO_A3": "CRI",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- 214
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cuba",
- "NAME_LONG": "Cuba",
- "ABBREV": "Cuba",
- "FORMAL_EN": "Republic of Cuba",
- "POP_EST": 11147407,
- "POP_RANK": 14,
- "GDP_MD_EST": 132900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CU",
- "ISO_A3": "CUB",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- 215,
- 216
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "N. Cyprus",
- "NAME_LONG": "Northern Cyprus",
- "ABBREV": "N. Cy.",
- "FORMAL_EN": "Turkish Republic of Northern Cyprus",
- "POP_EST": 265100,
- "POP_RANK": 10,
- "GDP_MD_EST": 3600,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2013,
- "ISO_A2": "-99",
- "ISO_A3": "-99",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -217,
- 217
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cyprus",
- "NAME_LONG": "Cyprus",
- "ABBREV": "Cyp.",
- "FORMAL_EN": "Republic of Cyprus",
- "POP_EST": 1221549,
- "POP_RANK": 12,
- "GDP_MD_EST": 29260,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CY",
- "ISO_A3": "CYP",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -53,
- 218,
- 219,
- 220
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Czechia",
- "NAME_LONG": "Czech Republic",
- "ABBREV": "Cz.",
- "FORMAL_EN": "Czech Republic",
- "POP_EST": 10674723,
- "POP_RANK": 14,
- "GDP_MD_EST": 350900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "CZ",
- "ISO_A3": "CZE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -52,
- -163,
- 221,
- 222,
- -63,
- 223,
- 224,
- 225,
- 226,
- 227,
- -219
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Germany",
- "NAME_LONG": "Germany",
- "ABBREV": "Ger.",
- "FORMAL_EN": "Federal Republic of Germany",
- "POP_EST": 80594017,
- "POP_RANK": 16,
- "GDP_MD_EST": 3979000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DE",
- "ISO_A3": "DEU",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- 228,
- 229,
- 230,
- 231
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Djibouti",
- "NAME_LONG": "Djibouti",
- "ABBREV": "Dji.",
- "FORMAL_EN": "Republic of Djibouti",
- "POP_EST": 865267,
- "POP_RANK": 11,
- "GDP_MD_EST": 3345,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DJ",
- "ISO_A3": "DJI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -226,
- 232
- ]
- ],
- [
- [
- 233
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Denmark",
- "NAME_LONG": "Denmark",
- "ABBREV": "Den.",
- "FORMAL_EN": "Kingdom of Denmark",
- "POP_EST": 5605948,
- "POP_RANK": 13,
- "GDP_MD_EST": 264800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DK",
- "ISO_A3": "DNK",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- 234,
- 235
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Dominican Rep.",
- "NAME_LONG": "Dominican Republic",
- "ABBREV": "Dom. Rep.",
- "FORMAL_EN": "Dominican Republic",
- "POP_EST": 10734247,
- "POP_RANK": 14,
- "GDP_MD_EST": 161900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DO",
- "ISO_A3": "DOM",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- 236,
- 237,
- 238,
- 239,
- 240,
- 241,
- 242,
- 243
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Algeria",
- "NAME_LONG": "Algeria",
- "ABBREV": "Alg.",
- "FORMAL_EN": "People's Democratic Republic of Algeria",
- "POP_EST": 40969443,
- "POP_RANK": 15,
- "GDP_MD_EST": 609400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "DZ",
- "ISO_A3": "DZA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -206,
- 244,
- 245
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ecuador",
- "NAME_LONG": "Ecuador",
- "ABBREV": "Ecu.",
- "FORMAL_EN": "Republic of Ecuador",
- "POP_EST": 16290913,
- "POP_RANK": 14,
- "GDP_MD_EST": 182400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "EC",
- "ISO_A3": "ECU",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- 246,
- 247,
- 248,
- 249,
- 250
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Egypt",
- "NAME_LONG": "Egypt",
- "ABBREV": "Egypt",
- "FORMAL_EN": "Arab Republic of Egypt",
- "POP_EST": 97041072,
- "POP_RANK": 16,
- "GDP_MD_EST": 1105000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "EG",
- "ISO_A3": "EGY",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -232,
- 251,
- 252,
- 253
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Eritrea",
- "NAME_LONG": "Eritrea",
- "ABBREV": "Erit.",
- "FORMAL_EN": "State of Eritrea",
- "POP_EST": 5918919,
- "POP_RANK": 13,
- "GDP_MD_EST": 9169,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ER",
- "ISO_A3": "ERI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- 254,
- 255,
- 256,
- 257
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Spain",
- "NAME_LONG": "Spain",
- "ABBREV": "Sp.",
- "FORMAL_EN": "Kingdom of Spain",
- "POP_EST": 48958159,
- "POP_RANK": 15,
- "GDP_MD_EST": 1690000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ES",
- "ISO_A3": "ESP",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 258,
- 259,
- 260
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Estonia",
- "NAME_LONG": "Estonia",
- "ABBREV": "Est.",
- "FORMAL_EN": "Republic of Estonia",
- "POP_EST": 1251581,
- "POP_RANK": 12,
- "GDP_MD_EST": 38700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "EE",
- "ISO_A3": "EST",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -231,
- 261,
- 262,
- 263,
- 264,
- 265,
- -252
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ethiopia",
- "NAME_LONG": "Ethiopia",
- "ABBREV": "Eth.",
- "FORMAL_EN": "Federal Democratic Republic of Ethiopia",
- "POP_EST": 105350020,
- "POP_RANK": 17,
- "GDP_MD_EST": 174700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ET",
- "ISO_A3": "ETH",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- 266,
- 267,
- 268,
- 269
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Finland",
- "NAME_LONG": "Finland",
- "ABBREV": "Fin.",
- "FORMAL_EN": "Republic of Finland",
- "POP_EST": 5491218,
- "POP_RANK": 13,
- "GDP_MD_EST": 224137,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "FI",
- "ISO_A3": "FIN",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- 270
- ]
- ],
- [
- [
- 271
- ]
- ],
- [
- [
- 272
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Fiji",
- "NAME_LONG": "Fiji",
- "ABBREV": "Fiji",
- "FORMAL_EN": "Republic of Fiji",
- "POP_EST": 920938,
- "POP_RANK": 11,
- "GDP_MD_EST": 8374,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "FJ",
- "ISO_A3": "FJI",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- 273
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Falkland Is.",
- "NAME_LONG": "Falkland Islands",
- "ABBREV": "Flk. Is.",
- "FORMAL_EN": "Falkland Islands",
- "POP_EST": 2931,
- "POP_RANK": 4,
- "GDP_MD_EST": 281.8,
- "POP_YEAR": 2014,
- "GDP_YEAR": 2012,
- "ISO_A2": "FK",
- "ISO_A3": "FLK",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- -65,
- 274,
- -222,
- -162,
- 275,
- 276,
- -256,
- 277
- ]
- ],
- [
- [
- -111,
- 278,
- 279
- ]
- ],
- [
- [
- 280
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "France",
- "NAME_LONG": "France",
- "ABBREV": "Fr.",
- "FORMAL_EN": "French Republic",
- "POP_EST": 67106161,
- "POP_RANK": 16,
- "GDP_MD_EST": 2699000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "FR",
- "ISO_A3": "FRA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- -190,
- -204,
- 281,
- 282
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Gabon",
- "NAME_LONG": "Gabon",
- "ABBREV": "Gabon",
- "FORMAL_EN": "Gabonese Republic",
- "POP_EST": 1772255,
- "POP_RANK": 12,
- "GDP_MD_EST": 35980,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GA",
- "ISO_A3": "GAB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- [
- 283,
- 284
- ]
- ],
- [
- [
- 285
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "United Kingdom",
- "NAME_LONG": "United Kingdom",
- "ABBREV": "U.K.",
- "FORMAL_EN": "United Kingdom of Great Britain and Northern Ireland",
- "POP_EST": 64769452,
- "POP_RANK": 16,
- "GDP_MD_EST": 2788000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GB",
- "ISO_A3": "GBR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -32,
- 286,
- 287,
- 288,
- -55
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Georgia",
- "NAME_LONG": "Georgia",
- "ABBREV": "Geo.",
- "FORMAL_EN": "Georgia",
- "POP_EST": 4926330,
- "POP_RANK": 12,
- "GDP_MD_EST": 37270,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GE",
- "ISO_A3": "GEO",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -74,
- 289,
- 290,
- -184
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ghana",
- "NAME_LONG": "Ghana",
- "ABBREV": "Ghana",
- "FORMAL_EN": "Republic of Ghana",
- "POP_EST": 27499924,
- "POP_RANK": 15,
- "GDP_MD_EST": 120800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GH",
- "ISO_A3": "GHA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -187,
- 291,
- 292,
- 293,
- 294,
- 295,
- 296
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guinea",
- "NAME_LONG": "Guinea",
- "ABBREV": "Gin.",
- "FORMAL_EN": "Republic of Guinea",
- "POP_EST": 12413867,
- "POP_RANK": 14,
- "GDP_MD_EST": 16080,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GN",
- "ISO_A3": "GIN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- 297,
- 298
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Gambia",
- "NAME_LONG": "The Gambia",
- "ABBREV": "Gambia",
- "FORMAL_EN": "Republic of the Gambia",
- "POP_EST": 2051363,
- "POP_RANK": 12,
- "GDP_MD_EST": 3387,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GM",
- "ISO_A3": "GMB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -295,
- 299,
- 300
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guinea-Bissau",
- "NAME_LONG": "Guinea-Bissau",
- "ABBREV": "GnB.",
- "FORMAL_EN": "Republic of Guinea-Bissau",
- "POP_EST": 1792338,
- "POP_RANK": 12,
- "GDP_MD_EST": 2851,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GW",
- "ISO_A3": "GNB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -191,
- -283,
- 301
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Eq. Guinea",
- "NAME_LONG": "Equatorial Guinea",
- "ABBREV": "Eq. G.",
- "FORMAL_EN": "Republic of Equatorial Guinea",
- "POP_EST": 778358,
- "POP_RANK": 11,
- "GDP_MD_EST": 31770,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GQ",
- "ISO_A3": "GNQ",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -14,
- 302,
- -84,
- 303,
- 304
- ]
- ],
- [
- [
- 305
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Greece",
- "NAME_LONG": "Greece",
- "ABBREV": "Greece",
- "FORMAL_EN": "Hellenic Republic",
- "POP_EST": 10768477,
- "POP_RANK": 14,
- "GDP_MD_EST": 290500,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GR",
- "ISO_A3": "GRC",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 306
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Greenland",
- "NAME_LONG": "Greenland",
- "ABBREV": "Grlnd.",
- "FORMAL_EN": "Greenland",
- "POP_EST": 57713,
- "POP_RANK": 8,
- "GDP_MD_EST": 2173,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2015,
- "ISO_A2": "GL",
- "ISO_A3": "GRL",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Northern America"
- }
- },
- {
- "arcs": [
- [
- -100,
- 307,
- 308,
- 309,
- 310,
- 311
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guatemala",
- "NAME_LONG": "Guatemala",
- "ABBREV": "Guat.",
- "FORMAL_EN": "Republic of Guatemala",
- "POP_EST": 15460732,
- "POP_RANK": 14,
- "GDP_MD_EST": 131800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GT",
- "ISO_A3": "GTM",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -109,
- 312,
- 313,
- 314
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Guyana",
- "NAME_LONG": "Guyana",
- "ABBREV": "Guy.",
- "FORMAL_EN": "Co-operative Republic of Guyana",
- "POP_EST": 737718,
- "POP_RANK": 11,
- "GDP_MD_EST": 6093,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "GY",
- "ISO_A3": "GUY",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -309,
- 315,
- 316,
- 317,
- 318
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Honduras",
- "NAME_LONG": "Honduras",
- "ABBREV": "Hond.",
- "FORMAL_EN": "Republic of Honduras",
- "POP_EST": 9038741,
- "POP_RANK": 13,
- "GDP_MD_EST": 43190,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HN",
- "ISO_A3": "HND",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -91,
- 319,
- 320,
- 321,
- 322,
- 323
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Croatia",
- "NAME_LONG": "Croatia",
- "ABBREV": "Cro.",
- "FORMAL_EN": "Republic of Croatia",
- "POP_EST": 4292095,
- "POP_RANK": 12,
- "GDP_MD_EST": 94240,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HR",
- "ISO_A3": "HRV",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -236,
- 324
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Haiti",
- "NAME_LONG": "Haiti",
- "ABBREV": "Haiti",
- "FORMAL_EN": "Republic of Haiti",
- "POP_EST": 10646714,
- "POP_RANK": 14,
- "GDP_MD_EST": 19340,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HT",
- "ISO_A3": "HTI",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -48,
- 325,
- 326,
- 327,
- 328,
- -323,
- 329
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Hungary",
- "NAME_LONG": "Hungary",
- "ABBREV": "Hun.",
- "FORMAL_EN": "Republic of Hungary",
- "POP_EST": 9850845,
- "POP_RANK": 13,
- "GDP_MD_EST": 267600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "HU",
- "ISO_A3": "HUN",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- 330
- ]
- ],
- [
- [
- 331,
- 332
- ]
- ],
- [
- [
- 333
- ]
- ],
- [
- [
- 334
- ]
- ],
- [
- [
- 335
- ]
- ],
- [
- [
- 336
- ]
- ],
- [
- [
- 337
- ]
- ],
- [
- [
- 338
- ]
- ],
- [
- [
- 339,
- 340
- ]
- ],
- [
- [
- 341
- ]
- ],
- [
- [
- 342
- ]
- ],
- [
- [
- 343,
- 344
- ]
- ],
- [
- [
- 345
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Indonesia",
- "NAME_LONG": "Indonesia",
- "ABBREV": "Indo.",
- "FORMAL_EN": "Republic of Indonesia",
- "POP_EST": 260580739,
- "POP_RANK": 17,
- "GDP_MD_EST": 3028000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ID",
- "ISO_A3": "IDN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -80,
- 346,
- 347,
- -181,
- 348,
- -179,
- -116,
- -178,
- 349
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "India",
- "NAME_LONG": "India",
- "ABBREV": "India",
- "FORMAL_EN": "Republic of India",
- "POP_EST": 1281935911,
- "POP_RANK": 18,
- "GDP_MD_EST": 8721000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IN",
- "ISO_A3": "IND",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- -284,
- 350
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ireland",
- "NAME_LONG": "Ireland",
- "ABBREV": "Ire.",
- "FORMAL_EN": "Ireland",
- "POP_EST": 5011102,
- "POP_RANK": 13,
- "GDP_MD_EST": 322000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IE",
- "ISO_A3": "IRL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -6,
- 351,
- 352,
- 353,
- 354,
- -59,
- -34,
- -58,
- 355,
- 356
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Iran",
- "NAME_LONG": "Iran",
- "ABBREV": "Iran",
- "FORMAL_EN": "Islamic Republic of Iran",
- "POP_EST": 82021564,
- "POP_RANK": 16,
- "GDP_MD_EST": 1459000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IR",
- "ISO_A3": "IRN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- -354,
- 357,
- 358,
- 359,
- 360,
- 361,
- 362
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Iraq",
- "NAME_LONG": "Iraq",
- "ABBREV": "Iraq",
- "FORMAL_EN": "Republic of Iraq",
- "POP_EST": 39192111,
- "POP_RANK": 15,
- "GDP_MD_EST": 596700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IQ",
- "ISO_A3": "IRQ",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 363
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Iceland",
- "NAME_LONG": "Iceland",
- "ABBREV": "Iceland",
- "FORMAL_EN": "Republic of Iceland",
- "POP_EST": 339747,
- "POP_RANK": 10,
- "GDP_MD_EST": 16150,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IS",
- "ISO_A3": "ISL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- 364,
- 365,
- 366,
- 367,
- 368,
- 369,
- -250
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Israel",
- "NAME_LONG": "Israel",
- "ABBREV": "Isr.",
- "FORMAL_EN": "State of Israel",
- "POP_EST": 8299706,
- "POP_RANK": 13,
- "GDP_MD_EST": 297000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IL",
- "ISO_A3": "ISR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- -50,
- 370,
- 371,
- -276,
- -161
- ]
- ],
- [
- [
- 372
- ]
- ],
- [
- [
- 373
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Italy",
- "NAME_LONG": "Italy",
- "ABBREV": "Italy",
- "FORMAL_EN": "Italian Republic",
- "POP_EST": 62137802,
- "POP_RANK": 16,
- "GDP_MD_EST": 2221000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "IT",
- "ISO_A3": "ITA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- 374
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Jamaica",
- "NAME_LONG": "Jamaica",
- "ABBREV": "Jam.",
- "FORMAL_EN": "Jamaica",
- "POP_EST": 2990561,
- "POP_RANK": 12,
- "GDP_MD_EST": 25390,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "JM",
- "ISO_A3": "JAM",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -361,
- 375,
- 376,
- -370,
- 377,
- -368,
- 378
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Jordan",
- "NAME_LONG": "Jordan",
- "ABBREV": "Jord.",
- "FORMAL_EN": "Hashemite Kingdom of Jordan",
- "POP_EST": 10248069,
- "POP_RANK": 14,
- "GDP_MD_EST": 86190,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "JO",
- "ISO_A3": "JOR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 379
- ]
- ],
- [
- [
- 380
- ]
- ],
- [
- [
- 381
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Japan",
- "NAME_LONG": "Japan",
- "ABBREV": "Japan",
- "FORMAL_EN": "Japan",
- "POP_EST": 126451398,
- "POP_RANK": 17,
- "GDP_MD_EST": 4932000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "JP",
- "ISO_A3": "JPN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -169,
- 382,
- 383,
- 384,
- 385,
- 386
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kazakhstan",
- "NAME_LONG": "Kazakhstan",
- "ABBREV": "Kaz.",
- "FORMAL_EN": "Republic of Kazakhstan",
- "POP_EST": 18556698,
- "POP_RANK": 14,
- "GDP_MD_EST": 460700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KZ",
- "ISO_A3": "KAZ",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -264,
- 387,
- 388,
- 389,
- 390,
- 391
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kenya",
- "NAME_LONG": "Kenya",
- "ABBREV": "Ken.",
- "FORMAL_EN": "Republic of Kenya",
- "POP_EST": 47615739,
- "POP_RANK": 15,
- "GDP_MD_EST": 152700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KE",
- "ISO_A3": "KEN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -168,
- 392,
- 393,
- -383
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kyrgyzstan",
- "NAME_LONG": "Kyrgyzstan",
- "ABBREV": "Kgz.",
- "FORMAL_EN": "Kyrgyz Republic",
- "POP_EST": 5789122,
- "POP_RANK": 13,
- "GDP_MD_EST": 21010,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KG",
- "ISO_A3": "KGZ",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- 394,
- 395,
- 396,
- 397
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Cambodia",
- "NAME_LONG": "Cambodia",
- "ABBREV": "Camb.",
- "FORMAL_EN": "Kingdom of Cambodia",
- "POP_EST": 16204486,
- "POP_RANK": 14,
- "GDP_MD_EST": 58940,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KH",
- "ISO_A3": "KHM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 398,
- 399
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "South Korea",
- "NAME_LONG": "Republic of Korea",
- "ABBREV": "S.K.",
- "FORMAL_EN": "Republic of Korea",
- "POP_EST": 51181299,
- "POP_RANK": 16,
- "GDP_MD_EST": 1929000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KR",
- "ISO_A3": "KOR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -17,
- 400,
- 401,
- 402
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kosovo",
- "NAME_LONG": "Kosovo",
- "ABBREV": "Kos.",
- "FORMAL_EN": "Republic of Kosovo",
- "POP_EST": 1895250,
- "POP_RANK": 12,
- "GDP_MD_EST": 18490,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "XK",
- "ISO_A3": "-99",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -359,
- 403,
- 404
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Kuwait",
- "NAME_LONG": "Kuwait",
- "ABBREV": "Kwt.",
- "FORMAL_EN": "State of Kuwait",
- "POP_EST": 2875422,
- "POP_RANK": 12,
- "GDP_MD_EST": 301100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "KW",
- "ISO_A3": "KWT",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -176,
- 405,
- -396,
- 406,
- 407
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Laos",
- "NAME_LONG": "Lao PDR",
- "ABBREV": "Laos",
- "FORMAL_EN": "Lao People's Democratic Republic",
- "POP_EST": 7126706,
- "POP_RANK": 13,
- "GDP_MD_EST": 40960,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LA",
- "ISO_A3": "LAO",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -366,
- 408,
- 409
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Lebanon",
- "NAME_LONG": "Lebanon",
- "ABBREV": "Leb.",
- "FORMAL_EN": "Lebanese Republic",
- "POP_EST": 6229794,
- "POP_RANK": 13,
- "GDP_MD_EST": 85160,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LB",
- "ISO_A3": "LBN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -186,
- 410,
- 411,
- -292
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Liberia",
- "NAME_LONG": "Liberia",
- "ABBREV": "Liberia",
- "FORMAL_EN": "Republic of Liberia",
- "POP_EST": 4689021,
- "POP_RANK": 12,
- "GDP_MD_EST": 3881,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LR",
- "ISO_A3": "LBR",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -243,
- 412,
- 413,
- -248,
- 414,
- 415,
- 416
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Libya",
- "NAME_LONG": "Libya",
- "ABBREV": "Libya",
- "FORMAL_EN": "Libya",
- "POP_EST": 6653210,
- "POP_RANK": 13,
- "GDP_MD_EST": 90890,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LY",
- "ISO_A3": "LBY",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- 417
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sri Lanka",
- "NAME_LONG": "Sri Lanka",
- "ABBREV": "Sri L.",
- "FORMAL_EN": "Democratic Socialist Republic of Sri Lanka",
- "POP_EST": 22409381,
- "POP_RANK": 15,
- "GDP_MD_EST": 236700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LK",
- "ISO_A3": "LKA",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- 418
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Lesotho",
- "NAME_LONG": "Lesotho",
- "ABBREV": "Les.",
- "FORMAL_EN": "Kingdom of Lesotho",
- "POP_EST": 1958042,
- "POP_RANK": 12,
- "GDP_MD_EST": 6019,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LS",
- "ISO_A3": "LSO",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- -93,
- 419,
- 420,
- 421,
- 422
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Lithuania",
- "NAME_LONG": "Lithuania",
- "ABBREV": "Lith.",
- "FORMAL_EN": "Republic of Lithuania",
- "POP_EST": 2823859,
- "POP_RANK": 12,
- "GDP_MD_EST": 85620,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LT",
- "ISO_A3": "LTU",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -64,
- -223,
- -275
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Luxembourg",
- "NAME_LONG": "Luxembourg",
- "ABBREV": "Lux.",
- "FORMAL_EN": "Grand Duchy of Luxembourg",
- "POP_EST": 594130,
- "POP_RANK": 11,
- "GDP_MD_EST": 58740,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LU",
- "ISO_A3": "LUX",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- -94,
- -423,
- 423,
- -261,
- 424
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Latvia",
- "NAME_LONG": "Latvia",
- "ABBREV": "Lat.",
- "FORMAL_EN": "Republic of Latvia",
- "POP_EST": 1944643,
- "POP_RANK": 12,
- "GDP_MD_EST": 50650,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "LV",
- "ISO_A3": "LVA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -240,
- 425,
- 426
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Morocco",
- "NAME_LONG": "Morocco",
- "ABBREV": "Mor.",
- "FORMAL_EN": "Kingdom of Morocco",
- "POP_EST": 33986655,
- "POP_RANK": 15,
- "GDP_MD_EST": 282800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MA",
- "ISO_A3": "MAR",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- 427,
- 428
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Moldova",
- "NAME_LONG": "Moldova",
- "ABBREV": "Mda.",
- "FORMAL_EN": "Republic of Moldova",
- "POP_EST": 3474121,
- "POP_RANK": 12,
- "GDP_MD_EST": 18540,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MD",
- "ISO_A3": "MDA",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- 429
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Madagascar",
- "NAME_LONG": "Madagascar",
- "ABBREV": "Mad.",
- "FORMAL_EN": "Republic of Madagascar",
- "POP_EST": 25054161,
- "POP_RANK": 15,
- "GDP_MD_EST": 36860,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MG",
- "ISO_A3": "MDG",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -98,
- -312,
- 430,
- 431,
- 432
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mexico",
- "NAME_LONG": "Mexico",
- "ABBREV": "Mex.",
- "FORMAL_EN": "United Mexican States",
- "POP_EST": 124574795,
- "POP_RANK": 17,
- "GDP_MD_EST": 2307000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MX",
- "ISO_A3": "MEX",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -18,
- -403,
- 433,
- -85,
- -303
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Macedonia",
- "NAME_LONG": "Macedonia",
- "ABBREV": "Mkd.",
- "FORMAL_EN": "Former Yugoslav Republic of Macedonia",
- "POP_EST": 2103721,
- "POP_RANK": 12,
- "GDP_MD_EST": 29520,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MK",
- "ISO_A3": "MKD",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -76,
- -188,
- -297,
- 434,
- 435,
- -237,
- 436
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mali",
- "NAME_LONG": "Mali",
- "ABBREV": "Mali",
- "FORMAL_EN": "Republic of Mali",
- "POP_EST": 17885245,
- "POP_RANK": 14,
- "GDP_MD_EST": 38090,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ML",
- "ISO_A3": "MLI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -78,
- -350,
- -177,
- -408,
- 437,
- 438
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Myanmar",
- "NAME_LONG": "Myanmar",
- "ABBREV": "Myan.",
- "FORMAL_EN": "Republic of the Union of Myanmar",
- "POP_EST": 55123814,
- "POP_RANK": 16,
- "GDP_MD_EST": 311100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MM",
- "ISO_A3": "MMR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -16,
- 439,
- -320,
- -90,
- 440,
- -401
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Montenegro",
- "NAME_LONG": "Montenegro",
- "ABBREV": "Mont.",
- "FORMAL_EN": "Montenegro",
- "POP_EST": 642550,
- "POP_RANK": 11,
- "GDP_MD_EST": 10610,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ME",
- "ISO_A3": "MNE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -171,
- 441
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mongolia",
- "NAME_LONG": "Mongolia",
- "ABBREV": "Mong.",
- "FORMAL_EN": "Mongolia",
- "POP_EST": 3068243,
- "POP_RANK": 12,
- "GDP_MD_EST": 37000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MN",
- "ISO_A3": "MNG",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 442,
- 443,
- 444,
- 445,
- 446,
- 447,
- 448,
- 449
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mozambique",
- "NAME_LONG": "Mozambique",
- "ABBREV": "Moz.",
- "FORMAL_EN": "Republic of Mozambique",
- "POP_EST": 26573706,
- "POP_RANK": 15,
- "GDP_MD_EST": 35010,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MZ",
- "ISO_A3": "MOZ",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -238,
- -436,
- 450,
- 451,
- 452
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Mauritania",
- "NAME_LONG": "Mauritania",
- "ABBREV": "Mrt.",
- "FORMAL_EN": "Islamic Republic of Mauritania",
- "POP_EST": 3758571,
- "POP_RANK": 12,
- "GDP_MD_EST": 16710,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MR",
- "ISO_A3": "MRT",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -450,
- 453,
- 454
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Malawi",
- "NAME_LONG": "Malawi",
- "ABBREV": "Mal.",
- "FORMAL_EN": "Republic of Malawi",
- "POP_EST": 19196246,
- "POP_RANK": 14,
- "GDP_MD_EST": 21200,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MW",
- "ISO_A3": "MWI",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -115,
- 455,
- -344,
- 456
- ]
- ],
- [
- [
- 457,
- 458
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Malaysia",
- "NAME_LONG": "Malaysia",
- "ABBREV": "Malay.",
- "FORMAL_EN": "Malaysia",
- "POP_EST": 31381992,
- "POP_RANK": 15,
- "GDP_MD_EST": 863000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "MY",
- "ISO_A3": "MYS",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -7,
- 459,
- -119,
- 460,
- 461
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Namibia",
- "NAME_LONG": "Namibia",
- "ABBREV": "Nam.",
- "FORMAL_EN": "Republic of Namibia",
- "POP_EST": 2484780,
- "POP_RANK": 12,
- "GDP_MD_EST": 25990,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NA",
- "ISO_A3": "NAM",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- 462
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "New Caledonia",
- "NAME_LONG": "New Caledonia",
- "ABBREV": "New C.",
- "FORMAL_EN": "New Caledonia",
- "POP_EST": 279070,
- "POP_RANK": 10,
- "GDP_MD_EST": 10770,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NC",
- "ISO_A3": "NCL",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -71,
- -77,
- -437,
- -244,
- -417,
- 463,
- -194,
- 464
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Niger",
- "NAME_LONG": "Niger",
- "ABBREV": "Niger",
- "FORMAL_EN": "Republic of Niger",
- "POP_EST": 19245344,
- "POP_RANK": 14,
- "GDP_MD_EST": 20150,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NE",
- "ISO_A3": "NER",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -72,
- -465,
- -193,
- 465
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Nigeria",
- "NAME_LONG": "Nigeria",
- "ABBREV": "Nigeria",
- "FORMAL_EN": "Federal Republic of Nigeria",
- "POP_EST": 190632261,
- "POP_RANK": 17,
- "GDP_MD_EST": 1089000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NG",
- "ISO_A3": "NGA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -212,
- 466,
- -317,
- 467
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Nicaragua",
- "NAME_LONG": "Nicaragua",
- "ABBREV": "Nic.",
- "FORMAL_EN": "Republic of Nicaragua",
- "POP_EST": 6025951,
- "POP_RANK": 13,
- "GDP_MD_EST": 33550,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NI",
- "ISO_A3": "NIC",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -67,
- 468,
- -224
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Netherlands",
- "NAME_LONG": "Netherlands",
- "ABBREV": "Neth.",
- "FORMAL_EN": "Kingdom of the Netherlands",
- "POP_EST": 17084719,
- "POP_RANK": 14,
- "GDP_MD_EST": 870800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NL",
- "ISO_A3": "NLD",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Western Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -268,
- 469,
- 470,
- 471
- ]
- ],
- [
- [
- 472
- ]
- ],
- [
- [
- 473
- ]
- ],
- [
- [
- 474
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Norway",
- "NAME_LONG": "Norway",
- "ABBREV": "Nor.",
- "FORMAL_EN": "Kingdom of Norway",
- "POP_EST": 5320045,
- "POP_RANK": 13,
- "GDP_MD_EST": 364700,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NO",
- "ISO_A3": "NOR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -180,
- -349
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Nepal",
- "NAME_LONG": "Nepal",
- "ABBREV": "Nepal",
- "FORMAL_EN": "Nepal",
- "POP_EST": 29384297,
- "POP_RANK": 15,
- "GDP_MD_EST": 71520,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NP",
- "ISO_A3": "NPL",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 475
- ]
- ],
- [
- [
- 476
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "New Zealand",
- "NAME_LONG": "New Zealand",
- "ABBREV": "N.Z.",
- "FORMAL_EN": "New Zealand",
- "POP_EST": 4510327,
- "POP_RANK": 12,
- "GDP_MD_EST": 174800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "NZ",
- "ISO_A3": "NZL",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Australia and New Zealand"
- }
- },
- {
- "arcs": [
- [
- [
- -20,
- 477
- ]
- ],
- [
- [
- -22,
- 478,
- 479,
- 480
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Oman",
- "NAME_LONG": "Oman",
- "ABBREV": "Oman",
- "FORMAL_EN": "Sultanate of Oman",
- "POP_EST": 3424386,
- "POP_RANK": 12,
- "GDP_MD_EST": 173100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "OM",
- "ISO_A3": "OMN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -5,
- -182,
- -348,
- 481,
- -352
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Pakistan",
- "NAME_LONG": "Pakistan",
- "ABBREV": "Pak.",
- "FORMAL_EN": "Islamic Republic of Pakistan",
- "POP_EST": 204924861,
- "POP_RANK": 17,
- "GDP_MD_EST": 988200,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PK",
- "ISO_A3": "PAK",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Southern Asia"
- }
- },
- {
- "arcs": [
- [
- -208,
- 482,
- -214,
- 483
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Panama",
- "NAME_LONG": "Panama",
- "ABBREV": "Pan.",
- "FORMAL_EN": "Republic of Panama",
- "POP_EST": 3753142,
- "POP_RANK": 12,
- "GDP_MD_EST": 93120,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PA",
- "ISO_A3": "PAN",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -102,
- -166,
- 484,
- -245,
- -205,
- -106
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Peru",
- "NAME_LONG": "Peru",
- "ABBREV": "Peru",
- "FORMAL_EN": "Republic of Peru",
- "POP_EST": 31036656,
- "POP_RANK": 15,
- "GDP_MD_EST": 410400,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PE",
- "ISO_A3": "PER",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- 485
- ]
- ],
- [
- [
- 486
- ]
- ],
- [
- [
- 487
- ]
- ],
- [
- [
- 488
- ]
- ],
- [
- [
- 489
- ]
- ],
- [
- [
- 490
- ]
- ],
- [
- [
- 491
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Philippines",
- "NAME_LONG": "Philippines",
- "ABBREV": "Phil.",
- "FORMAL_EN": "Republic of the Philippines",
- "POP_EST": 104256076,
- "POP_RANK": 17,
- "GDP_MD_EST": 801900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PH",
- "ISO_A3": "PHL",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- -340,
- 492
- ]
- ],
- [
- [
- 493
- ]
- ],
- [
- [
- 494
- ]
- ],
- [
- [
- 495
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Papua New Guinea",
- "NAME_LONG": "Papua New Guinea",
- "ABBREV": "P.N.G.",
- "FORMAL_EN": "Independent State of Papua New Guinea",
- "POP_EST": 6909701,
- "POP_RANK": 13,
- "GDP_MD_EST": 28020,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PG",
- "ISO_A3": "PNG",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -97,
- 496,
- 497,
- -220,
- -228,
- 498,
- 499,
- -420
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Poland",
- "NAME_LONG": "Poland",
- "ABBREV": "Pol.",
- "FORMAL_EN": "Republic of Poland",
- "POP_EST": 38476269,
- "POP_RANK": 15,
- "GDP_MD_EST": 1052000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PL",
- "ISO_A3": "POL",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- 500
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Puerto Rico",
- "NAME_LONG": "Puerto Rico",
- "ABBREV": "P.R.",
- "FORMAL_EN": "Commonwealth of Puerto Rico",
- "POP_EST": 3351827,
- "POP_RANK": 12,
- "GDP_MD_EST": 131000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PR",
- "ISO_A3": "PRI",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -173,
- 501,
- 502,
- -400,
- 503
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "North Korea",
- "NAME_LONG": "Dem. Rep. Korea",
- "ABBREV": "N.K.",
- "FORMAL_EN": "Democratic People's Republic of Korea",
- "POP_EST": 25248140,
- "POP_RANK": 15,
- "GDP_MD_EST": 40000,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2016,
- "ISO_A2": "KP",
- "ISO_A3": "PRK",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -258,
- 504
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Portugal",
- "NAME_LONG": "Portugal",
- "ABBREV": "Port.",
- "FORMAL_EN": "Portuguese Republic",
- "POP_EST": 10839514,
- "POP_RANK": 14,
- "GDP_MD_EST": 297100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PT",
- "ISO_A3": "PRT",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -28,
- -104,
- -105
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Paraguay",
- "NAME_LONG": "Paraguay",
- "ABBREV": "Para.",
- "FORMAL_EN": "Republic of Paraguay",
- "POP_EST": 6943739,
- "POP_RANK": 13,
- "GDP_MD_EST": 64670,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PY",
- "ISO_A3": "PRY",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -369,
- -378
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Palestine",
- "NAME_LONG": "Palestine",
- "ABBREV": "Pal.",
- "FORMAL_EN": "West Bank and Gaza",
- "POP_EST": 4543126,
- "POP_RANK": 12,
- "GDP_MD_EST": 21220.77,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "PS",
- "ISO_A3": "PSE",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 505,
- 506
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Qatar",
- "NAME_LONG": "Qatar",
- "ABBREV": "Qatar",
- "FORMAL_EN": "State of Qatar",
- "POP_EST": 2314307,
- "POP_RANK": 12,
- "GDP_MD_EST": 334500,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "QA",
- "ISO_A3": "QAT",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -81,
- 507,
- -328,
- 508,
- -429,
- 509,
- 510
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Romania",
- "NAME_LONG": "Romania",
- "ABBREV": "Rom.",
- "FORMAL_EN": "Romania",
- "POP_EST": 21529967,
- "POP_RANK": 15,
- "GDP_MD_EST": 441000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RO",
- "ISO_A3": "ROU",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- [
- -56,
- -289,
- 511,
- 512,
- -95,
- -425,
- -260,
- 513,
- -269,
- -472,
- 514,
- -502,
- -172,
- -442,
- -170,
- -387,
- 515
- ]
- ],
- [
- [
- -421,
- -500,
- 516
- ]
- ],
- [
- [
- 519
- ]
- ],
- [
- [
- 520
- ]
- ],
- [
- [
- 521
- ]
- ],
- [
- [
- 522
- ]
- ],
- [
- [
- 523
- ]
- ],
- [
- [
- 524
- ]
- ],
- [
- [
- 525
- ]
- ],
- [
- [
- 526
- ]
- ],
- [
- [
- 527
- ]
- ],
- [
- [
- 528
- ]
- ],
- [
- [
- 529
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Russia",
- "NAME_LONG": "Russian Federation",
- "ABBREV": "Rus.",
- "FORMAL_EN": "Russian Federation",
- "POP_EST": 142257519,
- "POP_RANK": 17,
- "GDP_MD_EST": 3745000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RU",
- "ISO_A3": "RUS",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -61,
- -200,
- 530,
- 531
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Rwanda",
- "NAME_LONG": "Rwanda",
- "ABBREV": "Rwa.",
- "FORMAL_EN": "Republic of Rwanda",
- "POP_EST": 11901484,
- "POP_RANK": 14,
- "GDP_MD_EST": 21970,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RW",
- "ISO_A3": "RWA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -239,
- -453,
- 532,
- -426
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "W. Sahara",
- "NAME_LONG": "Western Sahara",
- "ABBREV": "W. Sah.",
- "FORMAL_EN": "Sahrawi Arab Democratic Republic",
- "POP_EST": 603253,
- "POP_RANK": 11,
- "GDP_MD_EST": 906.5,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2007,
- "ISO_A2": "EH",
- "ISO_A3": "ESH",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -23,
- -481,
- 533,
- 534,
- -376,
- -360,
- -405,
- 535,
- -507,
- 536
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Saudi Arabia",
- "NAME_LONG": "Saudi Arabia",
- "ABBREV": "Saud.",
- "FORMAL_EN": "Kingdom of Saudi Arabia",
- "POP_EST": 28571770,
- "POP_RANK": 15,
- "GDP_MD_EST": 1731000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SA",
- "ISO_A3": "SAU",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -123,
- 537,
- -415,
- -247,
- 538,
- -253,
- -266,
- 539
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sudan",
- "NAME_LONG": "Sudan",
- "ABBREV": "Sudan",
- "FORMAL_EN": "Republic of the Sudan",
- "POP_EST": 37345935,
- "POP_RANK": 15,
- "GDP_MD_EST": 176300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SD",
- "ISO_A3": "SDN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- -124,
- -540,
- -265,
- -392,
- 540,
- -198
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "S. Sudan",
- "NAME_LONG": "South Sudan",
- "ABBREV": "S. Sud.",
- "FORMAL_EN": "Republic of South Sudan",
- "POP_EST": 13026129,
- "POP_RANK": 14,
- "GDP_MD_EST": 20880,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SS",
- "ISO_A3": "SSD",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -296,
- -301,
- 541,
- -299,
- 542,
- -451,
- -435
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Senegal",
- "NAME_LONG": "Senegal",
- "ABBREV": "Sen.",
- "FORMAL_EN": "Republic of Senegal",
- "POP_EST": 14668522,
- "POP_RANK": 14,
- "GDP_MD_EST": 39720,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SN",
- "ISO_A3": "SEN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- [
- 543
- ]
- ],
- [
- [
- 544
- ]
- ],
- [
- [
- 545
- ]
- ],
- [
- [
- 546
- ]
- ],
- [
- [
- 547
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Solomon Is.",
- "NAME_LONG": "Solomon Islands",
- "ABBREV": "S. Is.",
- "FORMAL_EN": "",
- "POP_EST": 647581,
- "POP_RANK": 11,
- "GDP_MD_EST": 1198,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SB",
- "ISO_A3": "SLB",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -293,
- -412,
- 548
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sierra Leone",
- "NAME_LONG": "Sierra Leone",
- "ABBREV": "S.L.",
- "FORMAL_EN": "Republic of Sierra Leone",
- "POP_EST": 6163195,
- "POP_RANK": 13,
- "GDP_MD_EST": 10640,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SL",
- "ISO_A3": "SLE",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -310,
- -319,
- 549
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "El Salvador",
- "NAME_LONG": "El Salvador",
- "ABBREV": "El. S.",
- "FORMAL_EN": "Republic of El Salvador",
- "POP_EST": 6172011,
- "POP_RANK": 13,
- "GDP_MD_EST": 54790,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SV",
- "ISO_A3": "SLV",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Central America"
- }
- },
- {
- "arcs": [
- [
- -230,
- 550,
- 551,
- -262
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Somaliland",
- "NAME_LONG": "Somaliland",
- "ABBREV": "Solnd.",
- "FORMAL_EN": "Republic of Somaliland",
- "POP_EST": 3500000,
- "POP_RANK": 12,
- "GDP_MD_EST": 12250,
- "POP_YEAR": 2013,
- "GDP_YEAR": 2013,
- "ISO_A2": "-99",
- "ISO_A3": "-99",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -263,
- -552,
- 552,
- -388
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Somalia",
- "NAME_LONG": "Somalia",
- "ABBREV": "Som.",
- "FORMAL_EN": "Federal Republic of Somalia",
- "POP_EST": 7531386,
- "POP_RANK": 13,
- "GDP_MD_EST": 4719,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SO",
- "ISO_A3": "SOM",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -86,
- -434,
- -402,
- -441,
- -92,
- -324,
- -329,
- -508
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Serbia",
- "NAME_LONG": "Serbia",
- "ABBREV": "Serb.",
- "FORMAL_EN": "Republic of Serbia",
- "POP_EST": 7111024,
- "POP_RANK": 13,
- "GDP_MD_EST": 101800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "RS",
- "ISO_A3": "SRB",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -110,
- -315,
- 553,
- -279
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Suriname",
- "NAME_LONG": "Suriname",
- "ABBREV": "Sur.",
- "FORMAL_EN": "Republic of Suriname",
- "POP_EST": 591919,
- "POP_RANK": 11,
- "GDP_MD_EST": 8547,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SR",
- "ISO_A3": "SUR",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -54,
- -221,
- -498,
- 554,
- -326
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Slovakia",
- "NAME_LONG": "Slovakia",
- "ABBREV": "Svk.",
- "FORMAL_EN": "Slovak Republic",
- "POP_EST": 5445829,
- "POP_RANK": 13,
- "GDP_MD_EST": 168800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SK",
- "ISO_A3": "SVK",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -49,
- -330,
- -322,
- 555,
- -371
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Slovenia",
- "NAME_LONG": "Slovenia",
- "ABBREV": "Slo.",
- "FORMAL_EN": "Republic of Slovenia",
- "POP_EST": 1972126,
- "POP_RANK": 12,
- "GDP_MD_EST": 68350,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SI",
- "ISO_A3": "SVN",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Southern Europe"
- }
- },
- {
- "arcs": [
- [
- -267,
- 556,
- -470
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Sweden",
- "NAME_LONG": "Sweden",
- "ABBREV": "Swe.",
- "FORMAL_EN": "Kingdom of Sweden",
- "POP_EST": 9960487,
- "POP_RANK": 13,
- "GDP_MD_EST": 498100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SE",
- "ISO_A3": "SWE",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Northern Europe"
- }
- },
- {
- "arcs": [
- [
- -446,
- 557
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Swaziland",
- "NAME_LONG": "Swaziland",
- "ABBREV": "Swz.",
- "FORMAL_EN": "Kingdom of Swaziland",
- "POP_EST": 1467152,
- "POP_RANK": 12,
- "GDP_MD_EST": 11060,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "SZ",
- "ISO_A3": "SWZ",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- -362,
- -379,
- -367,
- -410,
- 558,
- 559
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Syria",
- "NAME_LONG": "Syria",
- "ABBREV": "Syria",
- "FORMAL_EN": "Syrian Arab Republic",
- "POP_EST": 18028549,
- "POP_RANK": 14,
- "GDP_MD_EST": 50280,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2015,
- "ISO_A2": "SY",
- "ISO_A3": "SYR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -122,
- -195,
- -464,
- -416,
- -538
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Chad",
- "NAME_LONG": "Chad",
- "ABBREV": "Chad",
- "FORMAL_EN": "Republic of Chad",
- "POP_EST": 12075985,
- "POP_RANK": 14,
- "GDP_MD_EST": 30590,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TD",
- "ISO_A3": "TCD",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Middle Africa"
- }
- },
- {
- "arcs": [
- [
- -69,
- 560,
- -290,
- -73
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Togo",
- "NAME_LONG": "Togo",
- "ABBREV": "Togo",
- "FORMAL_EN": "Togolese Republic",
- "POP_EST": 7965055,
- "POP_RANK": 13,
- "GDP_MD_EST": 11610,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TG",
- "ISO_A3": "TGO",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Western Africa"
- }
- },
- {
- "arcs": [
- [
- -395,
- 561,
- -459,
- 562,
- -438,
- -407
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Thailand",
- "NAME_LONG": "Thailand",
- "ABBREV": "Thai.",
- "FORMAL_EN": "Kingdom of Thailand",
- "POP_EST": 68414135,
- "POP_RANK": 16,
- "GDP_MD_EST": 1161000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TH",
- "ISO_A3": "THA",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -3,
- 563,
- -393,
- -167
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Tajikistan",
- "NAME_LONG": "Tajikistan",
- "ABBREV": "Tjk.",
- "FORMAL_EN": "Republic of Tajikistan",
- "POP_EST": 8468555,
- "POP_RANK": 13,
- "GDP_MD_EST": 25810,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TJ",
- "ISO_A3": "TJK",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -1,
- -357,
- 564,
- -385,
- 565
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Turkmenistan",
- "NAME_LONG": "Turkmenistan",
- "ABBREV": "Turkm.",
- "FORMAL_EN": "Turkmenistan",
- "POP_EST": 5351277,
- "POP_RANK": 13,
- "GDP_MD_EST": 94720,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TM",
- "ISO_A3": "TKM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -332,
- 566
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Timor-Leste",
- "NAME_LONG": "Timor-Leste",
- "ABBREV": "T.L.",
- "FORMAL_EN": "Democratic Republic of Timor-Leste",
- "POP_EST": 1291358,
- "POP_RANK": 12,
- "GDP_MD_EST": 4975,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TL",
- "ISO_A3": "TLS",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- 567
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Trinidad and Tobago",
- "NAME_LONG": "Trinidad and Tobago",
- "ABBREV": "Tr.T.",
- "FORMAL_EN": "Republic of Trinidad and Tobago",
- "POP_EST": 1218208,
- "POP_RANK": 12,
- "GDP_MD_EST": 43570,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TT",
- "ISO_A3": "TTO",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Caribbean"
- }
- },
- {
- "arcs": [
- [
- -242,
- 568,
- -413
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Tunisia",
- "NAME_LONG": "Tunisia",
- "ABBREV": "Tun.",
- "FORMAL_EN": "Republic of Tunisia",
- "POP_EST": 11403800,
- "POP_RANK": 14,
- "GDP_MD_EST": 130800,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TN",
- "ISO_A3": "TUN",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Northern Africa"
- }
- },
- {
- "arcs": [
- [
- [
- -36,
- -355,
- -363,
- -560,
- 569,
- -287
- ]
- ],
- [
- [
- -83,
- 570,
- -304
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Turkey",
- "NAME_LONG": "Turkey",
- "ABBREV": "Tur.",
- "FORMAL_EN": "Republic of Turkey",
- "POP_EST": 80845215,
- "POP_RANK": 16,
- "GDP_MD_EST": 1670000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TR",
- "ISO_A3": "TUR",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- 571
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Taiwan",
- "NAME_LONG": "Taiwan",
- "ABBREV": "Taiwan",
- "FORMAL_EN": "",
- "POP_EST": 23508428,
- "POP_RANK": 15,
- "GDP_MD_EST": 1127000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TW",
- "ISO_A3": "TWN",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- -62,
- -532,
- 572,
- -390,
- 573,
- -443,
- -455,
- 574,
- -201
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Tanzania",
- "NAME_LONG": "Tanzania",
- "ABBREV": "Tanz.",
- "FORMAL_EN": "United Republic of Tanzania",
- "POP_EST": 53950935,
- "POP_RANK": 16,
- "GDP_MD_EST": 150600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "TZ",
- "ISO_A3": "TZA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -199,
- -541,
- -391,
- -573,
- -531
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Uganda",
- "NAME_LONG": "Uganda",
- "ABBREV": "Uga.",
- "FORMAL_EN": "Republic of Uganda",
- "POP_EST": 39570125,
- "POP_RANK": 15,
- "GDP_MD_EST": 84930,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UG",
- "ISO_A3": "UGA",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -96,
- -513,
- 575,
- -518,
- 576,
- -510,
- -428,
- -509,
- -327,
- -555,
- -497
- ],
- [
- 517,
- 518
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Ukraine",
- "NAME_LONG": "Ukraine",
- "ABBREV": "Ukr.",
- "FORMAL_EN": "Ukraine",
- "POP_EST": 44033874,
- "POP_RANK": 15,
- "GDP_MD_EST": 352600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UA",
- "ISO_A3": "UKR",
- "CONTINENT": "Europe",
- "REGION_UN": "Europe",
- "SUBREGION": "Eastern Europe"
- }
- },
- {
- "arcs": [
- [
- -30,
- -113,
- 577
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Uruguay",
- "NAME_LONG": "Uruguay",
- "ABBREV": "Ury.",
- "FORMAL_EN": "Oriental Republic of Uruguay",
- "POP_EST": 3360148,
- "POP_RANK": 12,
- "GDP_MD_EST": 73250,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UY",
- "ISO_A3": "URY",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- [
- -141,
- 578,
- -432,
- 579
- ]
- ],
- [
- [
- -139,
- 580
- ]
- ],
- [
- [
- 581
- ]
- ],
- [
- [
- 582
- ]
- ],
- [
- [
- 583
- ]
- ],
- [
- [
- 584
- ]
- ],
- [
- [
- 585
- ]
- ],
- [
- [
- 586
- ]
- ],
- [
- [
- 587
- ]
- ],
- [
- [
- 588
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "United States of America",
- "NAME_LONG": "United States",
- "ABBREV": "U.S.A.",
- "FORMAL_EN": "United States of America",
- "POP_EST": 326625791,
- "POP_RANK": 17,
- "GDP_MD_EST": 18560000,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "US",
- "ISO_A3": "USA",
- "CONTINENT": "North America",
- "REGION_UN": "Americas",
- "SUBREGION": "Northern America"
- }
- },
- {
- "arcs": [
- [
- -2,
- -566,
- -384,
- -394,
- -564
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Uzbekistan",
- "NAME_LONG": "Uzbekistan",
- "ABBREV": "Uzb.",
- "FORMAL_EN": "Republic of Uzbekistan",
- "POP_EST": 29748859,
- "POP_RANK": 15,
- "GDP_MD_EST": 202300,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "UZ",
- "ISO_A3": "UZB",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Central Asia"
- }
- },
- {
- "arcs": [
- [
- -108,
- -210,
- 589,
- -313
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Venezuela",
- "NAME_LONG": "Venezuela",
- "ABBREV": "Ven.",
- "FORMAL_EN": "Bolivarian Republic of Venezuela",
- "POP_EST": 31304016,
- "POP_RANK": 15,
- "GDP_MD_EST": 468600,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "VE",
- "ISO_A3": "VEN",
- "CONTINENT": "South America",
- "REGION_UN": "Americas",
- "SUBREGION": "South America"
- }
- },
- {
- "arcs": [
- [
- -175,
- 590,
- -397,
- -406
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Vietnam",
- "NAME_LONG": "Vietnam",
- "ABBREV": "Viet.",
- "FORMAL_EN": "Socialist Republic of Vietnam",
- "POP_EST": 96160163,
- "POP_RANK": 16,
- "GDP_MD_EST": 594900,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "VN",
- "ISO_A3": "VNM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "South-Eastern Asia"
- }
- },
- {
- "arcs": [
- [
- [
- 591
- ]
- ],
- [
- [
- 592
- ]
- ]
- ],
- "type": "MultiPolygon",
- "properties": {
- "NAME": "Vanuatu",
- "NAME_LONG": "Vanuatu",
- "ABBREV": "Van.",
- "FORMAL_EN": "Republic of Vanuatu",
- "POP_EST": 282814,
- "POP_RANK": 10,
- "GDP_MD_EST": 723,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "VU",
- "ISO_A3": "VUT",
- "CONTINENT": "Oceania",
- "REGION_UN": "Oceania",
- "SUBREGION": "Melanesia"
- }
- },
- {
- "arcs": [
- [
- -480,
- 593,
- -534
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Yemen",
- "NAME_LONG": "Yemen",
- "ABBREV": "Yem.",
- "FORMAL_EN": "Republic of Yemen",
- "POP_EST": 28036829,
- "POP_RANK": 15,
- "GDP_MD_EST": 73450,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "YE",
- "ISO_A3": "YEM",
- "CONTINENT": "Asia",
- "REGION_UN": "Asia",
- "SUBREGION": "Western Asia"
- }
- },
- {
- "arcs": [
- [
- -118,
- 594,
- -447,
- -558,
- -445,
- 595,
- -461
- ],
- [
- -419
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "South Africa",
- "NAME_LONG": "South Africa",
- "ABBREV": "S.Af.",
- "FORMAL_EN": "Republic of South Africa",
- "POP_EST": 54841552,
- "POP_RANK": 16,
- "GDP_MD_EST": 739100,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ZA",
- "ISO_A3": "ZAF",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Southern Africa"
- }
- },
- {
- "arcs": [
- [
- -10,
- -202,
- -575,
- -454,
- -449,
- 596,
- -120,
- -460
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Zambia",
- "NAME_LONG": "Zambia",
- "ABBREV": "Zambia",
- "FORMAL_EN": "Republic of Zambia",
- "POP_EST": 15972000,
- "POP_RANK": 14,
- "GDP_MD_EST": 65170,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ZM",
- "ISO_A3": "ZMB",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- },
- {
- "arcs": [
- [
- -121,
- -597,
- -448,
- -595
- ]
- ],
- "type": "Polygon",
- "properties": {
- "NAME": "Zimbabwe",
- "NAME_LONG": "Zimbabwe",
- "ABBREV": "Zimb.",
- "FORMAL_EN": "Republic of Zimbabwe",
- "POP_EST": 13805084,
- "POP_RANK": 14,
- "GDP_MD_EST": 28330,
- "POP_YEAR": 2017,
- "GDP_YEAR": 2016,
- "ISO_A2": "ZW",
- "ISO_A3": "ZWE",
- "CONTINENT": "Africa",
- "REGION_UN": "Africa",
- "SUBREGION": "Eastern Africa"
- }
- }
- ]
- }
- }
-}
diff --git a/explorer/src/components/ComponentError.tsx b/explorer/src/components/ComponentError.tsx
deleted file mode 100644
index 00b448fb9e..0000000000
--- a/explorer/src/components/ComponentError.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Typography } from '@mui/material';
-import * as React from 'react';
-
-export const ComponentError: FCWithChildren<{ text: string }> = ({ text }) => (
-
- {text}
-
-);
diff --git a/explorer/src/components/ContentCard.tsx b/explorer/src/components/ContentCard.tsx
deleted file mode 100644
index c78c719ca7..0000000000
--- a/explorer/src/components/ContentCard.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Card, CardHeader, CardContent, Typography } from '@mui/material';
-import React, { ReactEventHandler } from 'react';
-
-type ContentCardProps = {
- title?: React.ReactNode;
- subtitle?: string;
- Icon?: React.ReactNode;
- Action?: React.ReactNode;
- errorMsg?: string;
- onClick?: ReactEventHandler;
-};
-
-export const ContentCard: FCWithChildren = ({
- title,
- Icon,
- Action,
- subtitle,
- errorMsg,
- children,
- onClick,
-}) => (
-
- {title && }
- {children && {children}}
- {errorMsg && (
-
- {errorMsg}
-
- )}
-
-);
-
-ContentCard.defaultProps = {
- title: undefined,
- subtitle: undefined,
- Icon: null,
- Action: null,
- errorMsg: undefined,
- onClick: () => null,
-};
diff --git a/explorer/src/components/CustomColumnHeading.tsx b/explorer/src/components/CustomColumnHeading.tsx
deleted file mode 100644
index 1f85806fa2..0000000000
--- a/explorer/src/components/CustomColumnHeading.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as React from 'react';
-import { Box, Typography } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { Tooltip } from '@nymproject/react/tooltip/Tooltip';
-
-export const CustomColumnHeading: FCWithChildren<{ headingTitle: string; tooltipInfo?: string }> = ({
- headingTitle,
- tooltipInfo,
-}) => {
- const theme = useTheme();
-
- return (
-
- {tooltipInfo && (
-
- )}
-
- {headingTitle}
-
-
- );
-};
diff --git a/explorer/src/components/Delegations/ConfirmationModal.tsx b/explorer/src/components/Delegations/ConfirmationModal.tsx
deleted file mode 100644
index 8e859f5eba..0000000000
--- a/explorer/src/components/Delegations/ConfirmationModal.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import React from 'react';
-import {
- Breakpoint,
- Button,
- Paper,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- SxProps,
- Typography,
-} from '@mui/material';
-
-export interface ConfirmationModalProps {
- open: boolean;
- onConfirm: () => void;
- onClose?: () => void;
- children?: React.ReactNode;
- title: React.ReactNode | string;
- subTitle?: React.ReactNode | string;
- confirmButton: React.ReactNode | string;
- disabled?: boolean;
- sx?: SxProps;
- fullWidth?: boolean;
- maxWidth?: Breakpoint;
- backdropProps?: object;
-}
-
-export const ConfirmationModal = ({
- open,
- onConfirm,
- onClose,
- children,
- title,
- subTitle,
- confirmButton,
- disabled,
- sx,
- fullWidth,
- maxWidth,
- backdropProps,
-}: ConfirmationModalProps) => {
- const Title = (
-
- {title}
- {subTitle &&
- (typeof subTitle === 'string' ? (
-
- {subTitle}
-
- ) : (
- subTitle
- ))}
-
- );
- const ConfirmButton =
- typeof confirmButton === 'string' ? (
-
- ) : (
- confirmButton
- );
- return (
-
- );
-};
diff --git a/explorer/src/components/Delegations/DelegateIconButton.tsx b/explorer/src/components/Delegations/DelegateIconButton.tsx
deleted file mode 100644
index 36b581a010..0000000000
--- a/explorer/src/components/Delegations/DelegateIconButton.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import * as React from 'react';
-import { Button, IconButton } from '@mui/material';
-import { SxProps } from '@mui/system';
-import { useIsMobile } from '@src/hooks';
-import { DelegateIcon } from '@src/icons/DelevateSVG';
-
-export const DelegateIconButton: FCWithChildren<{
- size?: 'small' | 'medium';
- disabled?: boolean;
- tooltip?: React.ReactNode;
- sx?: SxProps;
- onDelegate: () => void;
-}> = ({ onDelegate, sx, disabled, size = 'medium' }) => {
- const isMobile = useIsMobile();
-
- const handleOnDelegate = () => {
- onDelegate();
- };
-
- if (isMobile) {
- return (
-
-
-
- );
- }
-
- return (
-
- );
-};
diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx
deleted file mode 100644
index 3bafd1888f..0000000000
--- a/explorer/src/components/Delegations/DelegateModal.tsx
+++ /dev/null
@@ -1,166 +0,0 @@
-import React, { useState } from 'react';
-import { Box, SxProps } from '@mui/material';
-import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
-import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
-import { CurrencyDenom, DecCoin } from '@nymproject/types';
-import { useWalletContext } from '@src/context/wallet';
-import { useDelegationsContext } from '@src/context/delegations';
-import { SimpleModal } from './SimpleModal';
-import { ModalListItem } from './ModalListItem';
-import { DelegationModalProps } from './DelegationModal';
-import { validateAmount } from '../../utils/currency';
-import { urls } from '../../utils';
-
-const MIN_AMOUNT_TO_DELEGATE = 10;
-
-export const DelegateModal: FCWithChildren<{
- mixId: number;
- identityKey: string;
- header?: string;
- buttonText?: string;
- rewardInterval?: string;
- estimatedReward?: number;
- profitMarginPercentage?: string | null;
- nodeUptimePercentage?: number | null;
- denom: CurrencyDenom;
- sx?: SxProps;
- backdropProps?: object;
- onClose: () => void;
- onOk?: (delegationModalProps: DelegationModalProps) => void;
-}> = ({ mixId, identityKey, onClose, onOk, denom, sx }) => {
- const [amount, setAmount] = useState({ amount: '10', denom: 'nym' });
- const [isValidated, setValidated] = useState(false);
- const [errorAmount, setErrorAmount] = useState();
-
- const { address, balance } = useWalletContext();
- const { handleDelegate } = useDelegationsContext();
-
- const validate = async () => {
- let newValidatedValue = true;
- let errorAmountMessage;
-
- if (amount && !(await validateAmount(amount.amount, '0'))) {
- newValidatedValue = false;
- errorAmountMessage = 'Please enter a valid amount';
- }
-
- if (amount && +amount.amount < MIN_AMOUNT_TO_DELEGATE) {
- errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}`;
- newValidatedValue = false;
- }
-
- if (!amount?.amount.length) {
- newValidatedValue = false;
- }
-
- if (amount && balance.data && +balance.data - +amount.amount <= 0) {
- errorAmountMessage = 'Not enough funds';
- newValidatedValue = false;
- }
-
- setErrorAmount(errorAmountMessage);
- setValidated(newValidatedValue);
- };
-
- const delegateToMixnode = async ({
- delegationMixId,
- delegationAmount,
- }: {
- delegationMixId: number;
- delegationAmount: string;
- }) => {
- try {
- const tx = await handleDelegate(delegationMixId, delegationAmount);
- return tx;
- } catch (e) {
- console.error('Failed to delegate to mixnode', e);
- throw e;
- }
- };
-
- const handleConfirm = async () => {
- if (mixId && amount && onOk) {
- onOk({
- status: 'loading',
- });
- try {
- if (!address) {
- throw new Error('Please connect your wallet');
- }
-
- const tx = await delegateToMixnode({
- delegationMixId: mixId,
- delegationAmount: amount.amount,
- });
-
- if (!tx) {
- throw new Error('Failed to delegate');
- }
-
- onOk({
- status: 'success',
- message: 'Delegation can take up to one hour to process',
- transactions: [
- { url: `${urls('MAINNET').blockExplorer}/tx/${tx.transactionHash}`, hash: tx.transactionHash },
- ],
- });
- } catch (e) {
- console.error('Failed to delegate', e);
- onOk({
- status: 'error',
- message: (e as Error).message,
- });
- }
- }
- };
-
- const handleAmountChanged = (newAmount: DecCoin) => {
- setAmount(newAmount);
- };
-
- React.useEffect(() => {
- validate();
- }, [amount, identityKey, mixId]);
-
- return (
-
-
- undefined}
- initialValue={identityKey}
- readOnly
- showTickOnValid={false}
- />
-
-
-
-
-
-
-
-
-
-
-
- );
-};
diff --git a/explorer/src/components/Delegations/DelegationModal.tsx b/explorer/src/components/Delegations/DelegationModal.tsx
deleted file mode 100644
index db5b51aefe..0000000000
--- a/explorer/src/components/Delegations/DelegationModal.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import React from 'react';
-import { Typography, SxProps, Stack } from '@mui/material';
-import { Link } from '@nymproject/react/link/Link';
-import { LoadingModal } from './LoadingModal';
-import { ConfirmationModal } from './ConfirmationModal';
-import { ErrorModal } from './ErrorModal';
-
-export type DelegationModalProps = {
- status: 'loading' | 'success' | 'error' | 'info';
- message?: string;
- transactions?: {
- url: string;
- hash: string;
- }[];
-};
-
-export const DelegationModal: FCWithChildren<
- DelegationModalProps & {
- open: boolean;
- onClose: () => void;
- sx?: SxProps;
- backdropProps?: object;
- children?: React.ReactNode;
- }
-> = ({ status, message, transactions, open, onClose, children, sx, backdropProps }) => {
- if (status === 'loading') return ;
-
- if (status === 'error') {
- return (
-
- {children}
-
- );
- }
-
- if (status === 'info') {
- return (
-
- {message}
-
- );
- }
-
- return (
- {})}
- title="Transaction successful"
- confirmButton="Done"
- >
-
- {message && {message}}
- {transactions?.length === 1 && (
-
- )}
- {transactions && transactions.length > 1 && (
-
- View the transactions on blockchain:
- {transactions.map(({ url, hash }) => (
-
- ))}
-
- )}
-
-
- );
-};
diff --git a/explorer/src/components/Delegations/ErrorModal.tsx b/explorer/src/components/Delegations/ErrorModal.tsx
deleted file mode 100644
index b9218d1e1e..0000000000
--- a/explorer/src/components/Delegations/ErrorModal.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import { Box, Button, Modal, SxProps, Typography } from '@mui/material';
-import { modalStyle } from './SimpleModal';
-
-export const ErrorModal: FCWithChildren<{
- open: boolean;
- title?: string;
- message?: string;
- sx?: SxProps;
- backdropProps?: object;
- onClose: () => void;
- children?: React.ReactNode;
-}> = ({ children, open, title, message, sx, backdropProps, onClose }) => (
-
-
- theme.palette.error.main} mb={1}>
- {title || 'Oh no! Something went wrong...'}
-
-
- {message}
-
- {children}
-
-
-
-);
diff --git a/explorer/src/components/Delegations/LoadingModal.tsx b/explorer/src/components/Delegations/LoadingModal.tsx
deleted file mode 100644
index eda13938d4..0000000000
--- a/explorer/src/components/Delegations/LoadingModal.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { Box, CircularProgress, Modal, Stack, Typography, SxProps } from '@mui/material';
-import { modalStyle } from './SimpleModal';
-
-export const LoadingModal: FCWithChildren<{
- text?: string;
- sx?: SxProps;
- backdropProps?: object;
-}> = ({ sx, text = 'Please wait...' }) => (
-
-
-
-
- {text}
-
-
-
-);
diff --git a/explorer/src/components/Delegations/ModalDivider.tsx b/explorer/src/components/Delegations/ModalDivider.tsx
deleted file mode 100644
index 6258e0bfac..0000000000
--- a/explorer/src/components/Delegations/ModalDivider.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react';
-import { Box, SxProps } from '@mui/material';
-
-export const ModalDivider: FCWithChildren<{
- sx?: SxProps;
-}> = ({ sx }) => ;
diff --git a/explorer/src/components/Delegations/ModalListItem.tsx b/explorer/src/components/Delegations/ModalListItem.tsx
deleted file mode 100644
index 830c25705e..0000000000
--- a/explorer/src/components/Delegations/ModalListItem.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react';
-import { Box, Stack, SxProps, Typography, TypographyProps } from '@mui/material';
-import { ModalDivider } from './ModalDivider';
-
-export const ModalListItem: FCWithChildren<{
- label: string;
- divider?: boolean;
- hidden?: boolean;
- fontWeight?: TypographyProps['fontWeight'];
- fontSize?: TypographyProps['fontSize'];
- light?: boolean;
- value?: React.ReactNode;
- sxValue?: SxProps;
-}> = ({ label, value, hidden, fontWeight, fontSize, divider, sxValue }) => (
-
-
-
- {label}
-
- {value && (
-
- {value}
-
- )}
-
- {divider && }
-
-);
diff --git a/explorer/src/components/Delegations/SimpleModal.tsx b/explorer/src/components/Delegations/SimpleModal.tsx
deleted file mode 100644
index 88dff4d9d7..0000000000
--- a/explorer/src/components/Delegations/SimpleModal.tsx
+++ /dev/null
@@ -1,112 +0,0 @@
-import React from 'react';
-import { Box, Button, Modal, Stack, SxProps, Typography } from '@mui/material';
-import CloseIcon from '@mui/icons-material/Close';
-import ErrorOutline from '@mui/icons-material/ErrorOutline';
-import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
-import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
-import { useIsMobile } from '../../hooks/useIsMobile';
-
-export const modalStyle = (width: number | string = 600) => ({
- position: 'absolute' as 'absolute',
- top: '50%',
- left: '50%',
- width,
- transform: 'translate(-50%, -50%)',
- bgcolor: 'background.paper',
- boxShadow: 24,
- borderRadius: '16px',
- p: 4,
-});
-
-export const StyledBackButton = ({
- onBack,
- label,
- fullWidth,
- sx,
-}: {
- onBack: () => void;
- label?: string;
- fullWidth?: boolean;
- sx?: SxProps;
-}) => (
-
-);
-
-export const SimpleModal: FCWithChildren<{
- open: boolean;
- hideCloseIcon?: boolean;
- displayErrorIcon?: boolean;
- displayInfoIcon?: boolean;
- headerStyles?: SxProps;
- subHeaderStyles?: SxProps;
- buttonFullWidth?: boolean;
- onClose?: () => void;
- onOk?: () => Promise;
- onBack?: () => void;
- header: string | React.ReactNode;
- subHeader?: string;
- okLabel: string;
- backLabel?: string;
- backButtonFullWidth?: boolean;
- okDisabled?: boolean;
- sx?: SxProps;
- children?: React.ReactNode;
-}> = ({
- open,
- hideCloseIcon,
- displayErrorIcon,
- displayInfoIcon,
- headerStyles,
- buttonFullWidth,
- onClose,
- okDisabled,
- onOk,
- onBack,
- header,
- subHeader,
- okLabel,
- backLabel,
- backButtonFullWidth,
- sx,
- children,
-}) => {
- const isMobile = useIsMobile();
-
- return (
-
-
- {displayErrorIcon && }
- {displayInfoIcon && }
-
- {typeof header === 'string' ? (
-
- {header}
-
- ) : (
- header
- )}
- {!hideCloseIcon && }
-
-
- theme.palette.text.secondary}>
- {subHeader}
-
-
- {children}
-
- {(onOk || onBack) && (
-
- {onBack && }
- {onOk && (
-
- )}
-
- )}
-
-
- );
-};
diff --git a/explorer/src/components/Delegations/index.ts b/explorer/src/components/Delegations/index.ts
deleted file mode 100644
index da51de9bd9..0000000000
--- a/explorer/src/components/Delegations/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export * from './ConfirmationModal';
-export * from './DelegateIconButton';
-export * from './DelegationModal';
-export * from './DelegateModal';
-export * from './ErrorModal';
-export * from './LoadingModal';
-export * from './ModalDivider';
-export * from './ModalListItem';
-export * from './SimpleModal';
-export * from './styles';
diff --git a/explorer/src/components/Delegations/styles.ts b/explorer/src/components/Delegations/styles.ts
deleted file mode 100644
index 9b26551767..0000000000
--- a/explorer/src/components/Delegations/styles.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Theme } from '@mui/material/styles';
-
-export const backDropStyles = (theme: Theme) => {
- const { mode } = theme.palette;
- return {
- style: {
- left: mode === 'light' ? '0' : '50%',
- width: '50%',
- },
- };
-};
-
-export const modalStyles = (theme: Theme) => {
- const { mode } = theme.palette;
- return { left: mode === 'light' ? '25%' : '75%' };
-};
-
-export const dialogStyles = (theme: Theme) => {
- const { mode } = theme.palette;
- return { left: mode === 'light' ? '-50%' : '50%' };
-};
diff --git a/explorer/src/components/DetailTable.tsx b/explorer/src/components/DetailTable.tsx
deleted file mode 100644
index 39355d0607..0000000000
--- a/explorer/src/components/DetailTable.tsx
+++ /dev/null
@@ -1,127 +0,0 @@
-import * as React from 'react';
-import {
- Link,
- Paper,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- TableCellProps,
-} from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { Tooltip } from '@nymproject/react/tooltip/Tooltip';
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard';
-import { Box } from '@mui/system';
-import { unymToNym } from '../utils/currency';
-import { GatewayEnrichedRowType } from './Gateways';
-import { MixnodeRowType } from './MixNodes';
-import { StakeSaturationProgressBar } from './MixNodes/Economics/StakeSaturationProgressBar';
-
-export type ColumnsType = {
- field: string;
- title: string;
- headerAlign?: TableCellProps['align'];
- width?: string | number;
- tooltipInfo?: string;
-};
-
-export interface UniversalTableProps {
- tableName: string;
- columnsData: ColumnsType[];
- rows: T[];
-}
-
-function formatCellValues(val: string | number, field: string) {
- if (field === 'identity_key' && typeof val === 'string') {
- return (
-
-
- {val}
-
- );
- }
-
- if (field === 'bond') {
- return unymToNym(val, 6);
- }
-
- if (field === 'owner') {
- return (
-
- {val}
-
- );
- }
-
- if (field === 'stake_saturation') {
- return ;
- }
-
- return val;
-}
-
-export const DetailTable: FCWithChildren<{
- tableName: string;
- columnsData: ColumnsType[];
- rows: MixnodeRowType[] | GatewayEnrichedRowType[];
-}> = ({ tableName, columnsData, rows }: UniversalTableProps) => {
- const theme = useTheme();
- return (
-
-
-
-
- {columnsData?.map(({ field, title, width, tooltipInfo }) => (
-
-
- {tooltipInfo && (
-
-
-
- )}
- {title}
-
-
- ))}
-
-
-
- {rows.map((eachRow) => (
-
- {columnsData?.map((data, index) => (
-
- {formatCellValues(eachRow[columnsData[index].field], columnsData[index].field)}
-
- ))}
-
- ))}
-
-
-
- );
-};
diff --git a/explorer/src/components/Filters/Filters.tsx b/explorer/src/components/Filters/Filters.tsx
deleted file mode 100644
index 0823ef6579..0000000000
--- a/explorer/src/components/Filters/Filters.tsx
+++ /dev/null
@@ -1,172 +0,0 @@
-import React, { useState, useEffect, useRef, useCallback } from 'react';
-import {
- Button,
- Dialog,
- DialogContent,
- DialogActions,
- DialogTitle,
- Slider,
- Typography,
- Box,
- Snackbar,
- Slide,
- Alert,
-} from '@mui/material';
-import { useParams } from 'react-router-dom';
-import { useMainContext } from '../../context/main';
-import { MixnodeStatusWithAll, toMixnodeStatus } from '../../typeDefs/explorer-api';
-import { EnumFilterKey, TFilterItem, TFilters } from '../../typeDefs/filters';
-import { formatOnSave, generateFilterSchema } from './filterSchema';
-import { Api } from '../../api';
-import { useIsMobile } from '../../hooks/useIsMobile';
-import FiltersButton from './FiltersButton';
-
-const FilterItem = ({
- label,
- id,
- tooltipInfo,
- value,
- isSmooth,
- marks,
- scale,
- min,
- max,
- onChange,
-}: TFilterItem & {
- onChange: (id: EnumFilterKey, newValue: number[]) => void;
-}) => (
-
- {label}
- {tooltipInfo}
- onChange(id, newValue as number[])}
- valueLabelDisplay={isSmooth ? 'auto' : 'off'}
- marks={marks}
- step={isSmooth ? 1 : null}
- scale={scale}
- min={min}
- max={max}
- valueLabelFormat={(val: number) => (val === 100 && id === 'stakeSaturation' ? '>100' : val)}
- />
-
-);
-
-export const Filters = () => {
- const { filterMixnodes, fetchMixnodes, mixnodes } = useMainContext();
- const { status } = useParams<{ status: MixnodeStatusWithAll | undefined }>();
- const isMobile = useIsMobile();
-
- const [showFilters, setShowFilters] = useState(false);
- const [isFiltered, setIsFiltered] = useState(false);
- const [filters, setFilters] = React.useState();
- const [upperSaturationValue, setUpperSaturationValue] = React.useState(100);
-
- const baseFilters = useRef();
- const prevFilters = useRef();
-
- const handleToggleShowFilters = () => setShowFilters(!showFilters);
-
- const initialiseFilters = useCallback(async () => {
- const allMixnodes = await Api.fetchMixnodes();
- if (allMixnodes) {
- setUpperSaturationValue(Math.round(Math.max(...allMixnodes.map((m) => m.stake_saturation)) * 100 + 1));
- const initFilters = generateFilterSchema();
- baseFilters.current = initFilters;
- prevFilters.current = initFilters;
- setFilters(initFilters);
- }
- }, []);
-
- const handleOnChange = (id: EnumFilterKey, newValue: number[]) => {
- if (id === 'stakeSaturation' && newValue[1] === 100) {
- newValue.splice(1, 1, upperSaturationValue);
- }
- setFilters((ftrs) => {
- if (ftrs)
- return {
- ...ftrs,
- [id]: {
- ...ftrs[id],
- value: newValue,
- },
- };
- return undefined;
- });
- };
-
- const handleOnSave = async () => {
- setShowFilters(false);
- await filterMixnodes(formatOnSave(filters!), status);
- setIsFiltered(true);
- prevFilters.current = filters;
- };
-
- const handleOnCancel = () => {
- setShowFilters(false);
- setFilters(prevFilters.current);
- };
-
- const resetFilters = () => {
- setFilters(baseFilters.current);
- setIsFiltered(false);
- prevFilters.current = baseFilters.current;
- };
-
- const onClearFilters = async () => {
- await fetchMixnodes(toMixnodeStatus(status));
- resetFilters();
- };
-
- useEffect(() => {
- initialiseFilters();
- }, [initialiseFilters]);
-
- useEffect(() => {
- resetFilters();
- }, [status]);
-
- if (!filters) return null;
-
- return (
- <>
-
- t.palette.info.light }}
- action={
-
- }
- >
- {mixnodes?.data?.length} mixnodes matched your criteria
-
-
-
-
- >
- );
-};
diff --git a/explorer/src/components/Filters/FiltersButton.tsx b/explorer/src/components/Filters/FiltersButton.tsx
deleted file mode 100644
index 1e6d3e2940..0000000000
--- a/explorer/src/components/Filters/FiltersButton.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react';
-import { Button, IconButton } from '@mui/material';
-import { Tune } from '@mui/icons-material';
-
-type FiltersButtonProps = {
- iconOnly?: boolean;
- fullWidth?: boolean;
- onClick: () => void;
-};
-
-const FiltersButton = ({ iconOnly, fullWidth, onClick }: FiltersButtonProps) => {
- if (iconOnly) {
- return (
-
-
-
- );
- }
-
- return (
- }
- onClick={onClick}
- sx={{ textTransform: 'none' }}
- >
- Filters
-
- );
-};
-
-export default FiltersButton;
diff --git a/explorer/src/components/Filters/filterSchema.ts b/explorer/src/components/Filters/filterSchema.ts
deleted file mode 100644
index c5011114b1..0000000000
--- a/explorer/src/components/Filters/filterSchema.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { EnumFilterKey, TFilters } from '../../typeDefs/filters';
-
-export const generateFilterSchema = () => ({
- profitMargin: {
- label: 'Profit margin (%)',
- id: EnumFilterKey.profitMargin,
- value: [0, 100],
- isSmooth: true,
- marks: [
- { label: '0', value: 0 },
- { label: '10', value: 10 },
- { label: '20', value: 20 },
- { label: '30', value: 30 },
- { label: '40', value: 40 },
- { label: '50', value: 50 },
- { label: '60', value: 60 },
- { label: '70', value: 70 },
- { label: '80', value: 80 },
- { label: '90', value: 90 },
- { label: '100', value: 100 },
- ],
- tooltipInfo:
- 'As a delegator you want to chose nodes with lower profit margin, meaning more payout for their delegators',
- },
- stakeSaturation: {
- label: 'Stake saturation (%)',
- id: EnumFilterKey.stakeSaturation,
- value: [0, 100],
- isSmooth: true,
- marks: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) => ({
- value: value < 100 ? value : 100,
- label: value < 100 ? value : '>100',
- })),
- tooltipInfo: "Select nodes with <100% saturation. Any additional stake above 100% saturation won't get rewards",
- },
- routingScore: {
- label: 'Routing score (%)',
- id: EnumFilterKey.routingScore,
- value: [0, 100],
- isSmooth: true,
- marks: [
- { label: '0', value: 0 },
- { label: '10', value: 10 },
- { label: '20', value: 20 },
- { label: '30', value: 30 },
- { label: '40', value: 40 },
- { label: '50', value: 50 },
- { label: '60', value: 60 },
- { label: '70', value: 70 },
- { label: '80', value: 80 },
- { label: '90', value: 90 },
- { label: '100', value: 100 },
- ],
- tooltipInfo: 'The higher the routing score the better the performance of the node and so its rewards',
- },
-});
-
-const formatStakeSaturationValues = ([value_1, value_2]: number[]) => {
- const lowerValue = value_1 / 100;
- const upperValue = value_2 / 100;
-
- return [lowerValue, upperValue];
-};
-
-export const formatOnSave = (filters: TFilters) => ({
- routingScore: filters.routingScore.value,
- profitMargin: filters.profitMargin.value,
- stakeSaturation: formatStakeSaturationValues(filters.stakeSaturation.value),
-});
diff --git a/explorer/src/components/Footer.tsx b/explorer/src/components/Footer.tsx
deleted file mode 100644
index 375b5c9b1a..0000000000
--- a/explorer/src/components/Footer.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import React from 'react';
-import Box from '@mui/material/Box';
-import MuiLink from '@mui/material/Link';
-import { Link } from 'react-router-dom';
-import Typography from '@mui/material/Typography';
-import { Socials } from './Socials';
-import { useIsMobile } from '../hooks/useIsMobile';
-import { NymVpnIcon } from '../icons/NymVpn';
-
-export const Footer: FCWithChildren = () => {
- const isMobile = useIsMobile();
-
- return (
-
-
-
-
-
-
-
-
-
- © {new Date().getFullYear()} Nym Technologies SA, all rights reserved
-
-
- );
-};
diff --git a/explorer/src/components/Gateways.ts b/explorer/src/components/Gateways.ts
deleted file mode 100644
index 966a3c987e..0000000000
--- a/explorer/src/components/Gateways.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { GatewayResponse, GatewayBond, GatewayReportResponse } from '../typeDefs/explorer-api';
-import { toPercentInteger } from '../utils';
-
-export type GatewayRowType = {
- id: string;
- owner: string;
- identity_key: string;
- bond: number;
- host: string;
- location: string;
- version: string;
- node_performance: number;
-};
-
-export type GatewayEnrichedRowType = GatewayRowType & {
- routingScore: string;
- avgUptime: string;
- clientsPort: number;
- mixPort: number;
-};
-
-export function gatewayToGridRow(arrayOfGateways: GatewayResponse): GatewayRowType[] {
- return !arrayOfGateways
- ? []
- : arrayOfGateways.map((gw) => ({
- id: gw.owner,
- owner: gw.owner,
- identity_key: gw.gateway.identity_key || '',
- location: gw.location?.country_name.toUpperCase() || '',
- bond: gw.pledge_amount.amount || 0,
- host: gw.gateway.host || '',
- version: gw.gateway.version || '',
- node_performance: toPercentInteger(gw.node_performance.last_24h),
- }));
-}
-
-export function gatewayEnrichedToGridRow(gateway: GatewayBond, report: GatewayReportResponse): GatewayEnrichedRowType {
- return {
- id: gateway.owner,
- owner: gateway.owner,
- identity_key: gateway.gateway.identity_key || '',
- location: gateway.location?.country_name.toUpperCase() || '',
- bond: gateway.pledge_amount.amount || 0,
- host: gateway.gateway.host || '',
- version: gateway.gateway.version || '',
- clientsPort: gateway.gateway.clients_port || 0,
- mixPort: gateway.gateway.mix_port || 0,
- routingScore: `${report.most_recent}%`,
- avgUptime: `${report.last_day || report.last_hour}%`,
- node_performance: toPercentInteger(gateway.node_performance.most_recent),
- };
-}
diff --git a/explorer/src/components/Gateways/VersionDisplaySelector.tsx b/explorer/src/components/Gateways/VersionDisplaySelector.tsx
deleted file mode 100644
index e9be02b419..0000000000
--- a/explorer/src/components/Gateways/VersionDisplaySelector.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import { FormControl, MenuItem, Select } from '@mui/material';
-import { useIsMobile } from '../../hooks/useIsMobile';
-
-export enum VersionSelectOptions {
- latestVersion = 'Latest versions',
- olderVersions = 'Older versions',
- all = 'All',
-}
-export const VersionDisplaySelector = ({
- selected,
- handleChange,
-}: {
- selected: VersionSelectOptions;
- handleChange: (option: VersionSelectOptions) => void;
-}) => {
- const isMobile = useIsMobile();
-
- return (
-
-
-
- );
-};
diff --git a/explorer/src/components/Icons.ts b/explorer/src/components/Icons.ts
deleted file mode 100644
index 88761b9d21..0000000000
--- a/explorer/src/components/Icons.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
-import PauseCircleOutlineIcon from '@mui/icons-material/PauseCircleOutline';
-import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined';
-import { MixnodeStatus } from '../typeDefs/explorer-api';
-
-export const Icons = {
- Mixnodes: {
- Status: {
- Active: CheckCircleOutlineIcon,
- Standby: PauseCircleOutlineIcon,
- Inactive: CircleOutlinedIcon,
- },
- },
-};
-
-export const getMixNodeIcon = (value: any) => {
- if (value && typeof value === 'string') {
- switch (value) {
- case MixnodeStatus.active:
- return Icons.Mixnodes.Status.Active;
- case MixnodeStatus.standby:
- return Icons.Mixnodes.Status.Standby;
- default:
- return Icons.Mixnodes.Status.Inactive;
- }
- }
- return Icons.Mixnodes.Status.Inactive;
-};
diff --git a/explorer/src/components/MixNodes/BondBreakdown.tsx b/explorer/src/components/MixNodes/BondBreakdown.tsx
deleted file mode 100644
index 7fd66efb24..0000000000
--- a/explorer/src/components/MixNodes/BondBreakdown.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-import * as React from 'react';
-import { Alert, Box, CircularProgress, Typography } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import Table from '@mui/material/Table';
-import TableBody from '@mui/material/TableBody';
-import TableCell from '@mui/material/TableCell';
-import TableContainer from '@mui/material/TableContainer';
-import TableHead from '@mui/material/TableHead';
-import TableRow from '@mui/material/TableRow';
-import Paper from '@mui/material/Paper';
-import { ExpandMore } from '@mui/icons-material';
-import { currencyToString } from '../../utils/currency';
-import { useMixnodeContext } from '../../context/mixnode';
-import { useIsMobile } from '../../hooks/useIsMobile';
-
-export const BondBreakdownTable: FCWithChildren = () => {
- const { mixNode, delegations, uniqDelegations } = useMixnodeContext();
- const [showDelegations, toggleShowDelegations] = React.useState(false);
-
- const [bonds, setBonds] = React.useState({
- delegations: '0',
- pledges: '0',
- bondsTotal: '0',
- hasLoaded: false,
- });
- const theme = useTheme();
- const isMobile = useIsMobile();
-
- React.useEffect(() => {
- if (mixNode?.data) {
- // delegations
- const decimalisedDelegations = currencyToString({
- amount: mixNode.data.total_delegation.amount.toString(),
- denom: mixNode.data.total_delegation.denom,
- });
-
- // pledges
- const decimalisedPledges = currencyToString({
- amount: mixNode.data.pledge_amount.amount.toString(),
- denom: mixNode.data.pledge_amount.denom,
- });
-
- // bonds total (del + pledges)
- const pledgesSum = Number(mixNode.data.pledge_amount.amount);
- const delegationsSum = Number(mixNode.data.total_delegation.amount);
- const bondsTotal = currencyToString({
- amount: (pledgesSum + delegationsSum).toString(),
- });
-
- setBonds({
- delegations: decimalisedDelegations,
- pledges: decimalisedPledges,
- bondsTotal,
- hasLoaded: true,
- });
- }
- }, [mixNode]);
-
- const expandDelegations = () => {
- if (delegations?.data && delegations.data.length > 0) {
- toggleShowDelegations(!showDelegations);
- }
- };
- const calcBondPercentage = (num: number) => {
- if (mixNode?.data) {
- const rawDelegationAmount = Number(mixNode.data.total_delegation.amount);
- const rawPledgeAmount = Number(mixNode.data.pledge_amount.amount);
- const rawTotalBondsAmount = rawDelegationAmount + rawPledgeAmount;
- return ((num * 100) / rawTotalBondsAmount).toFixed(1);
- }
- return 0;
- };
-
- if (mixNode?.isLoading || delegations?.isLoading) {
- return ;
- }
-
- if (mixNode?.error) {
- return Mixnode not found;
- }
- if (delegations?.error) {
- return Unable to get delegations for mixnode;
- }
-
- return (
-
-
-
-
-
- Stake total
-
-
- {bonds.bondsTotal}
-
-
-
- Bond
-
- {bonds.pledges}
-
-
-
-
-
- Delegation total {'\u00A0'}
- {delegations?.data && delegations?.data?.length > 0 && }
-
-
-
- {bonds.delegations}
-
-
-
-
-
- {showDelegations && (
-
-
-
- Delegations
-
-
-
-
-
-
- Delegators
-
-
- Amount
-
-
- Share of stake
-
-
-
-
-
- {uniqDelegations?.data?.map(({ owner, amount: { amount } }) => (
-
-
- {owner}
-
- {currencyToString({ amount: amount.toString() })}
- {calcBondPercentage(amount)}%
-
- ))}
-
-
-
- )}
-
- );
-};
diff --git a/explorer/src/components/MixNodes/DetailSection.tsx b/explorer/src/components/MixNodes/DetailSection.tsx
deleted file mode 100644
index 6becf5efe4..0000000000
--- a/explorer/src/components/MixNodes/DetailSection.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import * as React from 'react';
-import { Box, Button, Grid, Typography, useTheme } from '@mui/material';
-import Identicon from 'react-identicons';
-import { useIsMobile } from '@src/hooks/useIsMobile';
-import { MixnodeRowType } from '.';
-import { getMixNodeStatusText, MixNodeStatus } from './Status';
-import { MixNodeDescriptionResponse } from '../../typeDefs/explorer-api';
-
-interface MixNodeDetailProps {
- mixNodeRow: MixnodeRowType;
- mixnodeDescription: MixNodeDescriptionResponse;
-}
-
-export const MixNodeDetailSection: FCWithChildren = ({ mixNodeRow, mixnodeDescription }) => {
- const theme = useTheme();
- const palette = [theme.palette.text.primary];
- const isMobile = useIsMobile();
- const statusText = React.useMemo(() => getMixNodeStatusText(mixNodeRow.status), [mixNodeRow.status]);
-
- return (
-
-
-
-
-
-
-
- {mixnodeDescription.name}
- {(mixnodeDescription.description || '').slice(0, 1000)}
-
-
-
-
-
-
-
- Node status:
-
-
-
-
-
- This node is {statusText} in this epoch
-
-
-
-
- );
-};
diff --git a/explorer/src/components/MixNodes/Economics/Columns.ts b/explorer/src/components/MixNodes/Economics/Columns.ts
deleted file mode 100644
index b2115c0749..0000000000
--- a/explorer/src/components/MixNodes/Economics/Columns.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { ColumnsType } from '../../DetailTable';
-
-export const EconomicsInfoColumns: ColumnsType[] = [
- {
- field: 'estimatedTotalReward',
- title: 'Estimated Total Reward',
- width: '15%',
- tooltipInfo:
- 'Estimated node reward (total for the operator and delegators) in the current epoch. There are roughly 24 epochs in a day.',
- },
- {
- field: 'estimatedOperatorReward',
- title: 'Estimated Operator Reward',
- width: '15%',
- tooltipInfo:
- "Estimated operator's reward (including PM and Operating Cost) in the current epoch. There are roughly 24 epochs in a day.",
- },
- {
- field: 'selectionChance',
- title: 'Active Set Probability',
- width: '12.5%',
- tooltipInfo:
- 'Probability of getting selected in the reward set (active and standby nodes) in the next epoch. The more your stake, the higher the chances to be selected.',
- },
- {
- field: 'profitMargin',
- title: 'Profit Margin',
- width: '12.5%',
- tooltipInfo:
- 'Percentage of the delegators rewards that the operator takes as fee before rewards are distributed to the delegators.',
- },
- {
- field: 'operatingCost',
- title: 'Operating Cost',
- width: '10%',
- tooltipInfo:
- 'Monthly operational cost of running this node. This cost is set by the operator and it influences how the rewards are split between the operator and delegators.',
- },
- {
- field: 'nodePerformance',
- title: 'Routing Score',
- width: '10%',
- tooltipInfo:
- "Mixnode's most recent score (measured in the last 15 minutes). Routing score is relative to that of the network. Each time a gateway is tested, the test packets have to go through the full path of the network (gateway + 3 nodes). If a node in the path drop packets it will affect the score of the gateway and other nodes in the test.",
- },
- {
- field: 'avgUptime',
- title: 'Avg. Score',
- tooltipInfo: "Mixnode's average routing score in the last 24 hour",
- },
-];
diff --git a/explorer/src/components/MixNodes/Economics/EconomicsProgress.stories.tsx b/explorer/src/components/MixNodes/Economics/EconomicsProgress.stories.tsx
deleted file mode 100644
index aef36113df..0000000000
--- a/explorer/src/components/MixNodes/Economics/EconomicsProgress.stories.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import * as React from 'react';
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { EconomicsProgress } from './EconomicsProgress';
-
-export default {
- title: 'Mix Node Detail/Economics/ProgressBar',
- component: EconomicsProgress,
-} as ComponentMeta;
-
-const Template: ComponentStory = (args) => ;
-
-export const Empty = Template.bind({});
-Empty.args = {};
-
-export const OverThreshold = Template.bind({});
-OverThreshold.args = {
- threshold: 100,
- value: 120,
-};
-
-export const UnderThreshold = Template.bind({});
-UnderThreshold.args = {
- threshold: 100,
- value: 80,
-};
-
-export const OnThreshold = Template.bind({});
-OnThreshold.args = {
- threshold: 100,
- value: 100,
-};
diff --git a/explorer/src/components/MixNodes/Economics/EconomicsProgress.tsx b/explorer/src/components/MixNodes/Economics/EconomicsProgress.tsx
deleted file mode 100644
index 24db62d167..0000000000
--- a/explorer/src/components/MixNodes/Economics/EconomicsProgress.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import * as React from 'react';
-import LinearProgress, { LinearProgressProps } from '@mui/material/LinearProgress';
-import { useTheme } from '@mui/material/styles';
-import { Box } from '@mui/system';
-
-const parseToNumber = (value: number | undefined | string) =>
- typeof value === 'string' ? parseInt(value || '', 10) : value || 0;
-
-export const EconomicsProgress: FCWithChildren<
- LinearProgressProps & {
- threshold?: number;
- color: string;
- }
-> = ({ threshold, color, ...props }) => {
- const theme = useTheme();
- const { value } = props;
-
- const valueNumber: number = parseToNumber(value);
- const thresholdNumber: number = parseToNumber(threshold);
- const percentageToDisplay = Math.min(valueNumber, thresholdNumber);
-
- return (
- (threshold || 100) ? theme.palette.warning.main : theme.palette.nym.wallet.fee,
- }}
- >
-
-
- );
-};
diff --git a/explorer/src/components/MixNodes/Economics/MixNodeEconomics.stories.tsx b/explorer/src/components/MixNodes/Economics/MixNodeEconomics.stories.tsx
deleted file mode 100644
index c9c82c0438..0000000000
--- a/explorer/src/components/MixNodes/Economics/MixNodeEconomics.stories.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import * as React from 'react';
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { DelegatorsInfoTable } from './Table';
-import { EconomicsInfoColumns } from './Columns';
-import { EconomicsInfoRowWithIndex } from './types';
-
-export default {
- title: 'Mix Node Detail/Economics',
- component: DelegatorsInfoTable,
-} as ComponentMeta;
-
-const row: EconomicsInfoRowWithIndex = {
- id: 1,
- selectionChance: {
- value: 'High',
- },
-
- estimatedOperatorReward: {
- value: '80000.123456 NYM',
- },
- estimatedTotalReward: {
- value: '80000.123456 NYM',
- },
- profitMargin: {
- value: '10 %',
- },
- operatingCost: {
- value: '11121 NYM',
- },
- avgUptime: {
- value: '-',
- },
- nodePerformance: {
- value: '-',
- },
-};
-
-const rowGoodProbabilitySelection: EconomicsInfoRowWithIndex = {
- ...row,
- selectionChance: {
- value: 'Good',
- },
-};
-
-const rowLowProbabilitySelection: EconomicsInfoRowWithIndex = {
- ...row,
- selectionChance: {
- value: 'Low',
- },
-};
-
-const emptyRow: EconomicsInfoRowWithIndex = {
- id: 1,
- selectionChance: {
- value: '-',
- progressBarValue: 0,
- },
-
- estimatedOperatorReward: {
- value: '-',
- },
- estimatedTotalReward: {
- value: '-',
- },
- profitMargin: {
- value: '-',
- },
- operatingCost: {
- value: '-',
- },
- avgUptime: {
- value: '-',
- },
- nodePerformance: {
- value: '-',
- },
-};
-
-const Template: ComponentStory = (args) => ;
-
-export const Empty = Template.bind({});
-Empty.args = {
- rows: [emptyRow],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
-
-export const selectionChanceHigh = Template.bind({});
-selectionChanceHigh.args = {
- rows: [row],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
-
-export const selectionChanceGood = Template.bind({});
-selectionChanceGood.args = {
- rows: [rowGoodProbabilitySelection],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
-
-export const selectionChanceLow = Template.bind({});
-selectionChanceLow.args = {
- rows: [rowLowProbabilitySelection],
- columnsData: EconomicsInfoColumns,
- tableName: 'storybook',
-};
diff --git a/explorer/src/components/MixNodes/Economics/Rows.ts b/explorer/src/components/MixNodes/Economics/Rows.ts
deleted file mode 100644
index ce947b0a4f..0000000000
--- a/explorer/src/components/MixNodes/Economics/Rows.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { currencyToString, unymToNym } from '../../../utils/currency';
-import { useMixnodeContext } from '../../../context/mixnode';
-import { ApiState, MixNodeEconomicDynamicsStatsResponse } from '../../../typeDefs/explorer-api';
-import { EconomicsInfoRowWithIndex } from './types';
-import { toPercentIntegerString } from '../../../utils';
-
-const selectionChance = (economicDynamicsStats: ApiState | undefined) =>
- economicDynamicsStats?.data?.active_set_inclusion_probability || '-';
-
-export const EconomicsInfoRows = (): EconomicsInfoRowWithIndex => {
- const { economicDynamicsStats, mixNode } = useMixnodeContext();
-
- const estimatedNodeRewards =
- currencyToString({
- amount: economicDynamicsStats?.data?.estimated_total_node_reward.toString() || '',
- }) || '-';
- const estimatedOperatorRewards =
- currencyToString({
- amount: economicDynamicsStats?.data?.estimated_operator_reward.toString() || '',
- }) || '-';
- const profitMargin = mixNode?.data?.profit_margin_percent
- ? toPercentIntegerString(mixNode?.data?.profit_margin_percent)
- : '-';
- const avgUptime = mixNode?.data?.node_performance
- ? toPercentIntegerString(mixNode?.data?.node_performance.last_24h)
- : '-';
- const nodePerformance = mixNode?.data?.node_performance
- ? toPercentIntegerString(mixNode?.data?.node_performance.most_recent)
- : '-';
-
- const opCost = mixNode?.data?.operating_cost;
-
- return {
- id: 1,
- estimatedTotalReward: {
- value: estimatedNodeRewards,
- },
- estimatedOperatorReward: {
- value: estimatedOperatorRewards,
- },
- selectionChance: {
- value: selectionChance(economicDynamicsStats),
- },
- profitMargin: {
- value: profitMargin ? `${profitMargin} %` : '-',
- },
- operatingCost: {
- value: opCost ? `${unymToNym(opCost.amount, 6)} NYM` : '-',
- },
- avgUptime: {
- value: avgUptime ? `${avgUptime} %` : '-',
- },
- nodePerformance: {
- value: nodePerformance,
- },
- };
-};
diff --git a/explorer/src/components/MixNodes/Economics/StakeSaturationProgressBar.tsx b/explorer/src/components/MixNodes/Economics/StakeSaturationProgressBar.tsx
deleted file mode 100644
index 918d024643..0000000000
--- a/explorer/src/components/MixNodes/Economics/StakeSaturationProgressBar.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react';
-import { Box, Typography } from '@mui/material';
-import { useIsMobile } from '../../../hooks/useIsMobile';
-import { EconomicsProgress } from './EconomicsProgress';
-
-export const StakeSaturationProgressBar = ({ value, threshold }: { value: number; threshold: number }) => {
- const isTablet = useIsMobile('lg');
- const percentageColor = value > (threshold || 100) ? 'warning' : 'inherit';
- const textColor = percentageColor === 'warning' ? 'warning.main' : 'nym.wallet.fee';
-
- return (
-
-
- {value}%
-
-
-
- );
-};
diff --git a/explorer/src/components/MixNodes/Economics/Table.tsx b/explorer/src/components/MixNodes/Economics/Table.tsx
deleted file mode 100644
index e6630334db..0000000000
--- a/explorer/src/components/MixNodes/Economics/Table.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import * as React from 'react';
-import { Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material';
-import { Box } from '@mui/system';
-import { useTheme } from '@mui/material/styles';
-import { Tooltip } from '@nymproject/react/tooltip/Tooltip';
-import { EconomicsRowsType, EconomicsInfoRowWithIndex } from './types';
-import { UniversalTableProps } from '../../DetailTable';
-import { textColour } from '../../../utils';
-
-const formatCellValues = (value: EconomicsRowsType, field: string) => (
-
-
- {value.value}
-
-
-);
-
-export const DelegatorsInfoTable: FCWithChildren> = ({
- tableName,
- columnsData,
- rows,
-}) => {
- const theme = useTheme();
-
- return (
-
-
-
-
- {columnsData?.map(({ field, title, tooltipInfo, width }) => (
-
-
- {tooltipInfo && (
-
- )}
- {title}
-
-
- ))}
-
-
-
- {rows?.map((eachRow) => (
-
- {columnsData?.map((_, index: number) => {
- const { field } = columnsData[index];
- const value: EconomicsRowsType = (eachRow as any)[field];
- return (
-
- {formatCellValues(value, columnsData[index].field)}
-
- );
- })}
-
- ))}
-
-
-
- );
-};
diff --git a/explorer/src/components/MixNodes/Economics/index.ts b/explorer/src/components/MixNodes/Economics/index.ts
deleted file mode 100644
index 6dec752246..0000000000
--- a/explorer/src/components/MixNodes/Economics/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { DelegatorsInfoTable } from './Table';
-export { EconomicsInfoColumns } from './Columns';
-export { EconomicsInfoRows } from './Rows';
diff --git a/explorer/src/components/MixNodes/Economics/types.ts b/explorer/src/components/MixNodes/Economics/types.ts
deleted file mode 100644
index 0bc550253f..0000000000
--- a/explorer/src/components/MixNodes/Economics/types.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export type EconomicsRowsType = {
- progressBarValue?: number;
- value: string;
-};
-
-type TEconomicsInfoProperties =
- | 'estimatedTotalReward'
- | 'estimatedOperatorReward'
- | 'estimatedOperatorReward'
- | 'selectionChance'
- | 'profitMargin'
- | 'avgUptime'
- | 'nodePerformance'
- | 'operatingCost';
-
-export type EconomicsInfoRow = {
- [k in TEconomicsInfoProperties]: EconomicsRowsType;
-};
-
-export type EconomicsInfoRowWithIndex = EconomicsInfoRow & { id: number };
diff --git a/explorer/src/components/MixNodes/Status.tsx b/explorer/src/components/MixNodes/Status.tsx
deleted file mode 100644
index 627b1f5964..0000000000
--- a/explorer/src/components/MixNodes/Status.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Typography } from '@mui/material';
-import * as React from 'react';
-import { getMixNodeIcon } from '@src/components/Icons';
-import { MixnodeStatus } from '@src/typeDefs/explorer-api';
-import { useGetMixNodeStatusColor } from '@src/hooks/useGetMixnodeStatusColor';
-
-interface MixNodeStatusProps {
- status: MixnodeStatus;
-}
-// TODO: should be done with i18n
-export const getMixNodeStatusText = (status: MixnodeStatus) => {
- switch (status) {
- case MixnodeStatus.active:
- return 'active';
- case MixnodeStatus.standby:
- return 'on standby';
- default:
- return 'inactive';
- }
-};
-
-export const MixNodeStatus: FCWithChildren = ({ status }) => {
- const Icon = React.useMemo(() => getMixNodeIcon(status), [status]);
- const color = useGetMixNodeStatusColor(status);
-
- return (
-
-
-
- {`${status[0].toUpperCase()}${status.slice(1)}`}
-
-
- );
-};
diff --git a/explorer/src/components/MixNodes/StatusDropdown.tsx b/explorer/src/components/MixNodes/StatusDropdown.tsx
deleted file mode 100644
index 9cb34a2f0c..0000000000
--- a/explorer/src/components/MixNodes/StatusDropdown.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import * as React from 'react';
-import { MenuItem } from '@mui/material';
-import Select from '@mui/material/Select';
-import { SelectChangeEvent } from '@mui/material/Select/SelectInput';
-import { SxProps } from '@mui/system';
-import { MixNodeStatus } from './Status';
-import { MixnodeStatus, MixnodeStatusWithAll } from '../../typeDefs/explorer-api';
-import { useIsMobile } from '../../hooks/useIsMobile';
-
-// TODO: replace with i18n
-const ALL_NODES = 'All nodes';
-
-interface MixNodeStatusDropdownProps {
- status?: MixnodeStatusWithAll;
- sx?: SxProps;
- onSelectionChanged?: (status?: MixnodeStatusWithAll) => void;
-}
-
-export const MixNodeStatusDropdown: FCWithChildren = ({
- status,
- onSelectionChanged,
- sx,
-}) => {
- const isMobile = useIsMobile();
- const [statusValue, setStatusValue] = React.useState(status || MixnodeStatusWithAll.all);
- const onChange = React.useCallback(
- (event: SelectChangeEvent) => {
- setStatusValue(event.target.value as MixnodeStatusWithAll);
- if (onSelectionChanged) {
- onSelectionChanged(event.target.value as MixnodeStatusWithAll);
- }
- },
- [onSelectionChanged],
- );
-
- return (
-
- );
-};
-
-MixNodeStatusDropdown.defaultProps = {
- onSelectionChanged: undefined,
- status: undefined,
- sx: undefined,
-};
diff --git a/explorer/src/components/MixNodes/index.ts b/explorer/src/components/MixNodes/index.ts
deleted file mode 100644
index ccb6c5a8b3..0000000000
--- a/explorer/src/components/MixNodes/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './Status';
-export * from './StatusDropdown';
-export * from './mappings';
diff --git a/explorer/src/components/MixNodes/mappings.ts b/explorer/src/components/MixNodes/mappings.ts
deleted file mode 100644
index aba4c6fdca..0000000000
--- a/explorer/src/components/MixNodes/mappings.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/* eslint-disable camelcase */
-import { MixNodeResponse, MixNodeResponseItem, MixnodeStatus } from '../../typeDefs/explorer-api';
-import { toPercentInteger, toPercentIntegerString } from '../../utils';
-import { unymToNym } from '../../utils/currency';
-
-export type MixnodeRowType = {
- mix_id: number;
- id: string;
- status: MixnodeStatus;
- owner: string;
- location: string;
- identity_key: string;
- bond: number;
- self_percentage: string;
- pledge_amount: number;
- host: string;
- layer: string;
- profit_percentage: number;
- avg_uptime: string;
- stake_saturation: React.ReactNode;
- operating_cost: number;
- node_performance: number;
- blacklisted: boolean;
-};
-
-export function mixnodeToGridRow(arrayOfMixnodes?: MixNodeResponse): MixnodeRowType[] {
- return (arrayOfMixnodes || []).map(mixNodeResponseItemToMixnodeRowType);
-}
-
-export function mixNodeResponseItemToMixnodeRowType(item: MixNodeResponseItem): MixnodeRowType {
- const pledge = Number(item.pledge_amount.amount) || 0;
- const delegations = Number(item.total_delegation.amount) || 0;
- const totalBond = pledge + delegations;
- const selfPercentage = ((pledge * 100) / totalBond).toFixed(2);
- const profitPercentage = toPercentInteger(item.profit_margin_percent) || 0;
- const uncappedSaturation = typeof item.uncapped_saturation === 'number' ? item.uncapped_saturation * 100 : 0;
-
- return {
- mix_id: item.mix_id,
- id: item.owner,
- status: item.status,
- owner: item.owner,
- identity_key: item.mix_node.identity_key || '',
- bond: totalBond || 0,
- location: item?.location?.country_name || '',
- self_percentage: selfPercentage,
- pledge_amount: pledge,
- host: item?.mix_node?.host || '',
- layer: item?.layer || '',
- profit_percentage: profitPercentage,
- avg_uptime: `${toPercentIntegerString(item.node_performance.last_24h)}%`,
- stake_saturation: Number(uncappedSaturation.toFixed(2)),
- operating_cost: Number(unymToNym(item.operating_cost?.amount, 6)) || 0,
- node_performance: toPercentInteger(item.node_performance.most_recent),
- blacklisted: item.blacklisted,
- };
-}
diff --git a/explorer/src/components/MobileNav.tsx b/explorer/src/components/MobileNav.tsx
deleted file mode 100644
index ac4b313467..0000000000
--- a/explorer/src/components/MobileNav.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-import { AppBar, Box, Drawer, IconButton, List, ListItem, ListItemButton, ListItemIcon, Toolbar } from '@mui/material';
-import { Menu } from '@mui/icons-material';
-import { MaintenanceBanner } from '@nymproject/react/banners/MaintenanceBanner';
-import { useIsMobile } from '@src/hooks/useIsMobile';
-import { useMainContext } from '../context/main';
-import { MobileDrawerClose } from '../icons/MobileDrawerClose';
-import { Footer } from './Footer';
-import { ExpandableButton } from './Nav';
-import { ConnectKeplrWallet } from './Wallet/ConnectKeplrWallet';
-import NetworkTitle from './NetworkTitle';
-
-export const MobileNav: FCWithChildren = ({ children }) => {
- const theme = useTheme();
- const { navState, updateNavState } = useMainContext();
- const [drawerOpen, setDrawerOpen] = React.useState(false);
- // Set maintenance banner to false by default to don't display it
- const [openMaintenance, setOpenMaintenance] = React.useState(false);
- const isSmallMobile = useIsMobile(400);
-
- const toggleDrawer = () => {
- setDrawerOpen(!drawerOpen);
- };
-
- const handleClick = (url: string) => {
- updateNavState(url);
- toggleDrawer();
- };
-
- const openDrawer = () => {
- setDrawerOpen(true);
- };
-
- return (
-
-
- setOpenMaintenance(false)} />
-
-
-
-
-
- {!isSmallMobile && }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {navState.map((props) => (
-
- ))}
-
-
-
-
-
- {children}
-
-
-
- );
-};
diff --git a/explorer/src/components/Nav.tsx b/explorer/src/components/Nav.tsx
deleted file mode 100644
index a0f5b16fec..0000000000
--- a/explorer/src/components/Nav.tsx
+++ /dev/null
@@ -1,401 +0,0 @@
-import * as React from 'react';
-import { Link } from 'react-router-dom';
-import { ExpandLess, ExpandMore, Menu } from '@mui/icons-material';
-import { CSSObject, styled, Theme, useTheme } from '@mui/material/styles';
-import Button from '@mui/material/Button';
-import MuiLink from '@mui/material/Link';
-import Box from '@mui/material/Box';
-import ListItem from '@mui/material/ListItem';
-import MuiDrawer from '@mui/material/Drawer';
-import AppBar from '@mui/material/AppBar';
-import Toolbar from '@mui/material/Toolbar';
-import List from '@mui/material/List';
-import Typography from '@mui/material/Typography';
-import IconButton from '@mui/material/IconButton';
-import ListItemButton from '@mui/material/ListItemButton';
-import ListItemIcon from '@mui/material/ListItemIcon';
-import ListItemText from '@mui/material/ListItemText';
-import { NymLogo } from '@nymproject/react/logo/NymLogo';
-import { MaintenanceBanner } from '@nymproject/react/banners/MaintenanceBanner';
-import { NYM_WEBSITE } from '../api/constants';
-import { useMainContext } from '../context/main';
-import { MobileDrawerClose } from '../icons/MobileDrawerClose';
-import { Footer } from './Footer';
-import { DarkLightSwitchDesktop } from './Switch';
-import { NavOptionType } from '../context/nav';
-import { ConnectKeplrWallet } from './Wallet/ConnectKeplrWallet';
-
-const drawerWidth = 255;
-const bannerHeight = 80;
-
-const openedMixin = (theme: Theme): CSSObject => ({
- width: drawerWidth,
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.enteringScreen,
- }),
- overflowX: 'hidden',
-});
-
-const closedMixin = (theme: Theme): CSSObject => ({
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- overflowX: 'hidden',
- width: `calc(${theme.spacing(7)} + 1px)`,
-});
-
-const DrawerHeader = styled('div')(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'flex-end',
- padding: theme.spacing(0, 1),
- height: 64,
-}));
-
-const Drawer = styled(MuiDrawer, {
- shouldForwardProp: (prop) => prop !== 'open',
-})(({ theme, open }) => ({
- width: drawerWidth,
- flexShrink: 0,
- whiteSpace: 'nowrap',
- boxSizing: 'border-box',
- ...(open && {
- ...openedMixin(theme),
- '& .MuiDrawer-paper': openedMixin(theme),
- }),
- ...(!open && {
- ...closedMixin(theme),
- '& .MuiDrawer-paper': closedMixin(theme),
- }),
-}));
-
-type ExpandableButtonType = {
- title: string;
- url: string;
- isActive?: boolean;
- Icon?: React.ReactNode;
- nested?: NavOptionType[];
- isChild?: boolean;
- openDrawer: () => void;
- closeDrawer?: () => void;
- drawIsTempOpen: boolean;
- drawIsFixed: boolean;
- fixDrawerClose?: () => void;
- isMobile: boolean;
- setToActive: (url: string) => void;
-};
-
-export const ExpandableButton: FCWithChildren = ({
- url,
- setToActive,
- isActive,
- openDrawer,
- closeDrawer,
- drawIsTempOpen,
- drawIsFixed,
- fixDrawerClose,
- Icon,
- title,
- nested,
- isMobile,
- isChild,
-}) => {
- const [dynamicStyle, setDynamicStyle] = React.useState({});
- const [nestedOptions, toggleNestedOptions] = React.useState(false);
- const [isExternal, setIsExternal] = React.useState(false);
- const { palette } = useTheme();
-
- const handleClick = () => {
- setToActive(url);
- if (title === 'Network Components' && nested) {
- openDrawer();
- toggleNestedOptions(!nestedOptions);
- }
- if (!nested && !drawIsFixed) {
- closeDrawer?.();
- }
- if (!nested && isMobile) {
- fixDrawerClose?.();
- }
- };
-
- React.useEffect(() => {
- if (url) {
- setIsExternal(url.includes('http'));
- }
- if (nested) {
- setDynamicStyle({
- background: palette.nym.networkExplorer.nav.selected.main,
- borderRight: `3px solid ${palette.nym.highlight}`,
- });
- }
- if (isChild) {
- setDynamicStyle({
- background: palette.nym.networkExplorer.nav.selected.nested,
- fontWeight: 600,
- });
- }
- if (!nested && !isChild) {
- setDynamicStyle({
- background: palette.nym.networkExplorer.nav.selected.main,
- borderRight: `3px solid ${palette.nym.highlight}`,
- });
- }
- }, [url]);
-
- React.useEffect(() => {
- if (!drawIsTempOpen && nestedOptions) {
- toggleNestedOptions(false);
- }
- }, [drawIsTempOpen]);
-
- const linkProps = isExternal
- ? {
- component: 'a',
- href: url,
- target: '_blank',
- }
- : { component: !nested ? Link : 'div', to: url };
-
- return (
- <>
-
-
- {Icon}
-
- {nested && nestedOptions && }
- {nested && !nestedOptions && }
-
-
- {nestedOptions &&
- nested?.map((each) => (
-
- ))}
- >
- );
-};
-
-ExpandableButton.defaultProps = {
- Icon: null,
- nested: undefined,
- isChild: false,
- isActive: false,
- fixDrawerClose: undefined,
- closeDrawer: undefined,
-};
-
-export const Nav: FCWithChildren = ({ children }) => {
- const { updateNavState, navState, environment } = useMainContext();
- const [drawerIsOpen, setDrawerToOpen] = React.useState(false);
- const [fixedOpen, setFixedOpen] = React.useState(false);
- // Set maintenance banner to false by default to don't display it
- const [openMaintenance, setOpenMaintenance] = React.useState(false);
- const theme = useTheme();
-
- const explorerName =
- `${environment && environment.charAt(0).toUpperCase() + environment.slice(1)} Explorer` || 'Mainnet Explorer';
-
- const switchNetworkText = environment === 'mainnet' ? 'Switch to Testnet' : 'Switch to Mainnet';
- const switchNetworkLink =
- environment === 'mainnet' ? 'https://sandbox-explorer.nymtech.net' : 'https://explorer.nymtech.net';
-
- const setToActive = (url: string) => {
- updateNavState(url);
- };
-
- const fixDrawerOpen = () => {
- setFixedOpen(true);
- setDrawerToOpen(true);
- };
-
- const fixDrawerClose = () => {
- setFixedOpen(false);
- setDrawerToOpen(false);
- };
-
- const tempDrawerOpen = () => {
- if (!fixedOpen) {
- setDrawerToOpen(true);
- }
- };
-
- const tempDrawerClose = () => {
- if (!fixedOpen) {
- setDrawerToOpen(false);
- }
- };
-
- return (
-
-
- setOpenMaintenance(false)} height={bannerHeight} />
-
-
-
-
-
-
-
- {explorerName}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {drawerIsOpen ? : }
-
-
-
-
- {navState.map((props) => (
-
- ))}
-
-
-
- {children}
-
-
-
- );
-};
diff --git a/explorer/src/components/NetworkTitle.tsx b/explorer/src/components/NetworkTitle.tsx
deleted file mode 100644
index 7dd87d7e42..0000000000
--- a/explorer/src/components/NetworkTitle.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-import { Button, Typography } from '@mui/material';
-import { Link } from 'react-router-dom';
-import MuiLink from '@mui/material/Link';
-import { useMainContext } from '@src/context/main';
-
-type NetworkTitleProps = {
- showToggleNetwork?: boolean;
-};
-
-const NetworkTitle = ({ showToggleNetwork }: NetworkTitleProps) => {
- const { environment } = useMainContext();
-
- const explorerName =
- `${environment && environment.charAt(0).toUpperCase() + environment.slice(1)} Explorer` || 'Mainnet Explorer';
-
- const switchNetworkText = environment === 'mainnet' ? 'Switch to Testnet' : 'Switch to Mainnet';
- const switchNetworkLink =
- environment === 'mainnet' ? 'https://sandbox-explorer.nymtech.net' : 'https://explorer.nymtech.net';
- return (
-
-
- {explorerName}
-
- {showToggleNetwork && (
-
- )}
-
- );
-};
-
-export default NetworkTitle;
diff --git a/explorer/src/components/Socials.tsx b/explorer/src/components/Socials.tsx
deleted file mode 100644
index e1bb33970b..0000000000
--- a/explorer/src/components/Socials.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import * as React from 'react';
-import { Box, IconButton } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { TelegramIcon } from '../icons/socials/TelegramIcon';
-import { GitHubIcon } from '../icons/socials/GitHubIcon';
-import { TwitterIcon } from '../icons/socials/TwitterIcon';
-import { DiscordIcon } from '../icons/socials/DiscordIcon';
-
-// socials
-export const TELEGRAM_LINK = 'https://nymtech.net/go/telegram';
-export const TWITTER_LINK = 'https://nymtech.net/go/x';
-export const GITHUB_LINK = 'https://nymtech.net/go/github';
-export const DISCORD_LINK = 'https://nymtech.net/go/discord';
-
-export const Socials: FCWithChildren<{ isFooter?: boolean }> = ({ isFooter }) => {
- const theme = useTheme();
- const color = isFooter
- ? theme.palette.nym.networkExplorer.footer.socialIcons
- : theme.palette.nym.networkExplorer.topNav.socialIcons;
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-Socials.defaultProps = {
- isFooter: false,
-};
diff --git a/explorer/src/components/StatsCard.tsx b/explorer/src/components/StatsCard.tsx
deleted file mode 100644
index 36355b1759..0000000000
--- a/explorer/src/components/StatsCard.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import * as React from 'react';
-import { Box, Card, CardContent, IconButton, Typography } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import EastIcon from '@mui/icons-material/East';
-
-interface StatsCardProps {
- icon: React.ReactNode;
- title: string;
- count?: string | number;
- errorMsg?: Error | string;
- onClick?: () => void;
- color?: string;
-}
-export const StatsCard: FCWithChildren = ({
- icon,
- title,
- count,
- onClick,
- errorMsg,
- color: colorProp,
-}) => {
- const theme = useTheme();
- const color = colorProp || theme.palette.text.primary;
- return (
-
-
-
-
- {icon}
-
- {count === undefined || count === null ? '' : count}
-
-
- {title}
-
-
-
-
-
-
- {errorMsg && (
-
- {typeof errorMsg === 'string' ? errorMsg : errorMsg.message || 'Oh no! An error occurred'}
-
- )}
-
-
- );
-};
-
-StatsCard.defaultProps = {
- onClick: undefined,
- errorMsg: undefined,
- color: undefined,
- count: undefined,
-};
diff --git a/explorer/src/components/StyledLink.tsx b/explorer/src/components/StyledLink.tsx
deleted file mode 100644
index fd101e5b4a..0000000000
--- a/explorer/src/components/StyledLink.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import { Link as MuiLink, SxProps } from '@mui/material';
-import { Link as RRDL } from 'react-router-dom';
-
-type StyledLinkProps = {
- to: string;
- children: string;
- target?: React.HTMLAttributeAnchorTarget;
- dataTestId?: string;
- color?: string;
- sx?: SxProps;
-};
-
-const StyledLink = ({ to, children, dataTestId, target, color = 'inherit', sx }: StyledLinkProps) => (
-
- {children}
-
-);
-
-export default StyledLink;
diff --git a/explorer/src/components/Switch.tsx b/explorer/src/components/Switch.tsx
deleted file mode 100644
index 840530a327..0000000000
--- a/explorer/src/components/Switch.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import * as React from 'react';
-import { styled } from '@mui/material/styles';
-import Switch from '@mui/material/Switch';
-import { Button } from '@mui/material';
-import { useMainContext } from '../context/main';
-import { LightSwitchSVG } from '../icons/LightSwitchSVG';
-
-export const DarkLightSwitch = styled(Switch)(({ theme }) => ({
- width: 55,
- height: 34,
- padding: 7,
- '& .MuiSwitch-switchBase': {
- margin: 1,
- padding: 2,
- transform: 'translateX(4px)',
- '&.Mui-checked': {
- color: '#fff',
- transform: 'translateX(22px)',
- '& .MuiSwitch-thumb:before': {
- backgroundImage:
- 'url(\'data:image/svg+xml;utf8,\')',
- },
- '& + .MuiSwitch-track': {
- opacity: 1,
- backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
- },
- },
- },
- '& .MuiSwitch-thumb': {
- backgroundColor: theme.palette.nym.networkExplorer.nav.text,
- width: 25,
- height: 25,
- marginTop: '2px',
- '&:before': {
- content: "''",
- position: 'absolute',
- width: '100%',
- height: '100%',
- left: 0,
- top: 0,
- backgroundRepeat: 'no-repeat',
- backgroundPosition: 'center',
- backgroundImage:
- 'url(\'data:image/svg+xml;utf8,\')',
- },
- },
- '& .MuiSwitch-track': {
- opacity: 1,
- backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
- borderRadius: 20 / 2,
- },
-}));
-
-export const DarkLightSwitchMobile: FCWithChildren = () => {
- const { toggleMode } = useMainContext();
- return (
-
- );
-};
-
-export const DarkLightSwitchDesktop: FCWithChildren<{ defaultChecked: boolean }> = ({ defaultChecked }) => {
- const { toggleMode } = useMainContext();
- return (
-
- );
-};
diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx
deleted file mode 100644
index d3af522168..0000000000
--- a/explorer/src/components/TableToolbar.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-import React from 'react';
-import { Box, TextField, MenuItem, FormControl, IconButton, Select, SelectChangeEvent } from '@mui/material';
-import { Close } from '@mui/icons-material';
-import { Filters } from './Filters/Filters';
-import { useIsMobile } from '../hooks/useIsMobile';
-
-const fieldsHeight = '42.25px';
-
-type TableToolBarProps = {
- onChangeSearch?: (arg: string) => void;
- onChangePageSize: (event: SelectChangeEvent) => void;
- pageSize: string;
- searchTerm?: string;
- withFilters?: boolean;
- childrenBefore?: React.ReactNode;
- childrenAfter?: React.ReactNode;
-};
-
-export const TableToolbar: FCWithChildren = ({
- searchTerm,
- onChangeSearch,
- onChangePageSize,
- pageSize,
- childrenBefore,
- childrenAfter,
- withFilters,
-}) => {
- const isMobile = useIsMobile();
- return (
-
-
-
- {childrenBefore}
-
-
-
-
- {!!onChangeSearch && (
- onChangeSearch('')}>
-
-
- ) : undefined,
- }}
- onChange={(event) => onChangeSearch(event.target.value)}
- />
- )}
-
-
-
- {withFilters && }
- {childrenAfter}
-
-
- );
-};
diff --git a/explorer/src/components/Title.tsx b/explorer/src/components/Title.tsx
deleted file mode 100644
index 032837d3c8..0000000000
--- a/explorer/src/components/Title.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import * as React from 'react';
-import { Typography } from '@mui/material';
-
-export const Title: FCWithChildren<{ text: string }> = ({ text }) => (
-
- {text}
-
-);
diff --git a/explorer/src/components/Tooltip.tsx b/explorer/src/components/Tooltip.tsx
deleted file mode 100644
index 0febd9f891..0000000000
--- a/explorer/src/components/Tooltip.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React, { ReactElement } from 'react';
-import { Tooltip as MUITooltip, TooltipComponentsPropsOverrides, TooltipProps } from '@mui/material';
-
-type ValueType = T[keyof T];
-
-type Props = {
- text: string;
- id: string;
- placement?: ValueType>;
- tooltipSx?: TooltipComponentsPropsOverrides;
- children: React.ReactNode;
-};
-
-export const Tooltip = ({ text, id, placement, tooltipSx, children }: Props) => (
- t.palette.nym.networkExplorer.tooltip.background,
- color: (t) => t.palette.nym.networkExplorer.tooltip.color,
- '& .MuiTooltip-arrow': {
- color: (t) => t.palette.nym.networkExplorer.tooltip.background,
- },
- },
- ...tooltipSx,
- },
- }}
- arrow
- >
- {children as ReactElement}
-
-);
diff --git a/explorer/src/components/TwoColSmallTable.tsx b/explorer/src/components/TwoColSmallTable.tsx
deleted file mode 100644
index a211c29bdd..0000000000
--- a/explorer/src/components/TwoColSmallTable.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import * as React from 'react';
-import { CircularProgress, Typography } from '@mui/material';
-import Table from '@mui/material/Table';
-import TableBody from '@mui/material/TableBody';
-import TableCell from '@mui/material/TableCell';
-import TableContainer from '@mui/material/TableContainer';
-import TableRow from '@mui/material/TableRow';
-import Paper from '@mui/material/Paper';
-import CheckCircleSharpIcon from '@mui/icons-material/CheckCircleSharp';
-import ErrorIcon from '@mui/icons-material/Error';
-
-interface TableProps {
- title?: string;
- icons?: boolean[];
- keys: string[];
- values: number[];
- marginBottom?: boolean;
- error?: string;
- loading: boolean;
-}
-
-export const TwoColSmallTable: FCWithChildren = ({
- loading,
- title,
- icons,
- keys,
- values,
- marginBottom,
- error,
-}) => (
- <>
- {title && {title}}
-
-
-
-
- {keys.map((each: string, i: number) => (
-
- {icons && {icons[i] ? : }}
-
- {each}
-
-
- {values[i]}
-
- {error && (
-
- {values[i]}
-
- )}
- {!error && loading && (
-
-
-
- )}
- {error && !icons && (
-
-
-
- )}
-
- ))}
-
-
-
- >
-);
-
-TwoColSmallTable.defaultProps = {
- title: undefined,
- icons: undefined,
- marginBottom: false,
- error: undefined,
-};
diff --git a/explorer/src/components/Universal-DataGrid.tsx b/explorer/src/components/Universal-DataGrid.tsx
deleted file mode 100644
index 6598dfb485..0000000000
--- a/explorer/src/components/Universal-DataGrid.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import * as React from 'react';
-import { makeStyles } from '@mui/styles';
-import { DataGrid, GridColDef, GridEventListener, useGridApiContext, useGridState } from '@mui/x-data-grid';
-import Pagination from '@mui/material/Pagination';
-import { LinearProgress } from '@mui/material';
-import { GridInitialStateCommunity } from '@mui/x-data-grid/models/gridStateCommunity';
-
-const useStyles = makeStyles({
- root: {
- display: 'flex',
- },
-});
-
-const CustomPagination = () => {
- const apiRef = useGridApiContext();
- const [state] = useGridState(apiRef);
-
- const classes = useStyles();
-
- return (
- apiRef.current.setPage(value - 1)}
- />
- );
-};
-
-type DataGridProps = {
- columns: GridColDef[];
- pagination?: true | undefined;
- pageSize?: string | undefined;
- rows: any;
- loading?: boolean;
- initialState?: GridInitialStateCommunity;
- onRowClick?: GridEventListener<'rowClick'> | undefined;
-};
-export const UniversalDataGrid: FCWithChildren = ({
- rows,
- columns,
- loading,
- pagination,
- pageSize,
- initialState,
- onRowClick,
-}) => {
- if (loading) return ;
-
- return (
- t.palette.nym.networkExplorer.scroll.backgroud,
- outline: (t) => `1px solid ${t.palette.nym.networkExplorer.scroll.border}`,
- boxShadow: 'auto',
- borderRadius: 'auto',
- },
- '*::-webkit-scrollbar-thumb': {
- backgroundColor: (t) => t.palette.nym.networkExplorer.scroll.color,
- borderRadius: '20px',
- width: '.4em',
- border: (t) => `3px solid ${t.palette.nym.networkExplorer.scroll.backgroud}`,
- shadow: 'auto',
- },
- }}
- />
- );
-};
-
-UniversalDataGrid.defaultProps = {
- loading: false,
- pagination: undefined,
- pageSize: '10',
-};
diff --git a/explorer/src/components/UptimeChart.tsx b/explorer/src/components/UptimeChart.tsx
deleted file mode 100644
index 00a981a3af..0000000000
--- a/explorer/src/components/UptimeChart.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import * as React from 'react';
-import { CircularProgress, Typography } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { Chart } from 'react-google-charts';
-import { format } from 'date-fns';
-import { ApiState, UptimeStoryResponse } from '../typeDefs/explorer-api';
-
-interface ChartProps {
- title?: string;
- xLabel: string;
- yLabel?: string;
- uptimeStory: ApiState;
- loading: boolean;
-}
-
-type FormattedDateRecord = [string, number];
-type FormattedChartHeadings = string[];
-type FormattedChartData = [FormattedChartHeadings | FormattedDateRecord];
-
-export const UptimeChart: FCWithChildren = ({ title, xLabel, yLabel, uptimeStory, loading }) => {
- const [formattedChartData, setFormattedChartData] = React.useState();
- const theme = useTheme();
- const color = theme.palette.text.primary;
- React.useEffect(() => {
- if (uptimeStory.data?.history) {
- const allFormattedChartData: FormattedChartData = [['Date', 'Score']];
- uptimeStory.data.history.forEach((eachDate) => {
- const formattedDateUptimeRecord: FormattedDateRecord = [
- format(new Date(eachDate.date), 'MMM dd'),
- eachDate.uptime,
- ];
- allFormattedChartData.push(formattedDateUptimeRecord);
- });
- setFormattedChartData(allFormattedChartData);
- } else {
- const emptyData: any = [
- ['Date', 'Score'],
- ['Jul 27', 10],
- ];
- setFormattedChartData(emptyData);
- }
- }, [uptimeStory]);
-
- return (
- <>
- {title && {title}}
- {loading && }
-
- {!loading && uptimeStory && (
- ...
}
- data={
- uptimeStory.data
- ? formattedChartData
- : [
- ['Date', 'Routing Score'],
- [format(new Date(Date.now()), 'MMM dd'), 0],
- ]
- }
- options={{
- backgroundColor:
- theme.palette.mode === 'dark' ? theme.palette.nym.networkExplorer.background.tertiary : undefined,
- color: uptimeStory.error ? 'rgba(255, 255, 255, 0.4)' : 'rgba(255, 255, 255, 1)',
- colors: ['#FB7A21'],
- legend: {
- textStyle: {
- color,
- opacity: uptimeStory.error ? 0.4 : 1,
- },
- },
-
- intervals: { style: 'sticks' },
- hAxis: {
- // horizontal / date
- title: xLabel,
- titleTextStyle: {
- color,
- },
- textStyle: {
- color,
- // fontSize: 11
- },
- gridlines: {
- count: -1,
- },
- },
- vAxis: {
- // vertical / % Routing Score
- viewWindow: {
- min: 0,
- max: 100,
- },
- title: yLabel,
- titleTextStyle: {
- color,
- opacity: uptimeStory.error ? 0.4 : 1,
- },
- textStyle: {
- color,
- fontSize: 11,
- opacity: uptimeStory.error ? 0.4 : 1,
- },
- },
- }}
- />
- )}
- >
- );
-};
-
-UptimeChart.defaultProps = {
- title: undefined,
-};
diff --git a/explorer/src/components/Wallet/ConnectKeplrWallet.tsx b/explorer/src/components/Wallet/ConnectKeplrWallet.tsx
deleted file mode 100644
index ff5d2691c6..0000000000
--- a/explorer/src/components/Wallet/ConnectKeplrWallet.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { Button, IconButton, Stack, CircularProgress } from '@mui/material';
-import CloseIcon from '@mui/icons-material/Close';
-import { useIsMobile } from '@src/hooks/useIsMobile';
-import { useWalletContext } from '@src/context/wallet';
-import { WalletAddress, WalletBalance } from '@src/components/Wallet';
-
-export const ConnectKeplrWallet = () => {
- const { connectWallet, disconnectWallet, isWalletConnected, isWalletConnecting } = useWalletContext();
- const isMobile = useIsMobile(1200);
-
- if (!connectWallet || !disconnectWallet) {
- return null;
- }
-
- if (isWalletConnected) {
- return (
-
-
-
- {
- await disconnectWallet();
- }}
- >
-
-
-
- );
- }
-
- return (
-
- );
-};
diff --git a/explorer/src/components/Wallet/WalletAddress.tsx b/explorer/src/components/Wallet/WalletAddress.tsx
deleted file mode 100644
index 8be6c9f291..0000000000
--- a/explorer/src/components/Wallet/WalletAddress.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import { Box, Typography } from '@mui/material';
-import { ElipsSVG } from '@src/icons/ElipsSVG';
-import { trimAddress } from '@src/utils';
-import { useWalletContext } from '@src/context/wallet';
-
-export const WalletAddress = () => {
- const { address } = useWalletContext();
-
- const displayAddress = trimAddress(address, 7);
-
- return (
-
-
-
- {displayAddress}
-
-
- );
-};
diff --git a/explorer/src/components/Wallet/WalletBalance.tsx b/explorer/src/components/Wallet/WalletBalance.tsx
deleted file mode 100644
index f94935ac23..0000000000
--- a/explorer/src/components/Wallet/WalletBalance.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from 'react';
-import { Box, Typography } from '@mui/material';
-import { useWalletContext } from '@src/context/wallet';
-import { useIsMobile } from '@src/hooks';
-import { TokenSVG } from '@src/icons/TokenSVG';
-
-export const WalletBalance = () => {
- const { balance } = useWalletContext();
- const isMobile = useIsMobile(1200);
-
- const showBalance = !isMobile && balance.status === 'success';
-
- if (!showBalance) {
- return null;
- }
-
- return (
-
-
-
- {balance.data} NYM
-
-
- );
-};
diff --git a/explorer/src/components/Wallet/index.ts b/explorer/src/components/Wallet/index.ts
deleted file mode 100644
index 645c8b4ffb..0000000000
--- a/explorer/src/components/Wallet/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './WalletBalance';
-export * from './WalletAddress';
diff --git a/explorer/src/components/WorldMap.tsx b/explorer/src/components/WorldMap.tsx
deleted file mode 100644
index 7a86f34095..0000000000
--- a/explorer/src/components/WorldMap.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-/* eslint-disable @typescript-eslint/ban-ts-comment */
-import * as React from 'react';
-import { scaleLinear } from 'd3-scale';
-import { ComposableMap, Geographies, Geography, Marker, ZoomableGroup } from 'react-simple-maps';
-import ReactTooltip from 'react-tooltip';
-import { CircularProgress } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { ApiState, CountryDataResponse } from '../typeDefs/explorer-api';
-import MAP_TOPOJSON from '../assets/world-110m.json';
-
-type MapProps = {
- userLocation?: [number, number];
- countryData?: ApiState;
- loading: boolean;
-};
-
-export const WorldMap: FCWithChildren = ({ countryData, userLocation, loading }) => {
- const { palette } = useTheme();
-
- const colorScale = React.useMemo(() => {
- if (countryData?.data) {
- const heighestNumberOfNodes = Math.max(...Object.values(countryData.data).map((country) => country.nodes));
- return scaleLinear()
- .domain([0, 1, heighestNumberOfNodes / 4, heighestNumberOfNodes / 2, heighestNumberOfNodes])
- .range(palette.nym.networkExplorer.map.fills)
- .unknown(palette.nym.networkExplorer.map.fills[0]);
- }
- return () => palette.nym.networkExplorer.map.fills[0];
- }, [countryData, palette]);
-
- const [tooltipContent, setTooltipContent] = React.useState(null);
-
- if (loading) {
- return ;
- }
-
- return (
- <>
-
-
-
- {({ geographies }) =>
- geographies.map((geo) => {
- const d = (countryData?.data || {})[geo.properties.ISO_A3];
- return (
- {
- const { NAME_LONG } = geo.properties;
- if (!userLocation) {
- setTooltipContent(`${NAME_LONG} | ${d?.nodes || 0}`);
- }
- }}
- onMouseLeave={() => {
- setTooltipContent('');
- }}
- style={{
- hover:
- !userLocation && countryData
- ? {
- fill: palette.nym.highlight,
- outline: 'white',
- }
- : undefined,
- }}
- />
- );
- })
- }
-
-
- {userLocation && (
-
-
-
-
-
- )}
-
-
- {tooltipContent}
- >
- );
-};
-
-WorldMap.defaultProps = {
- userLocation: undefined,
- countryData: undefined,
-};
diff --git a/explorer/src/components/delegatorsInfo/types.ts b/explorer/src/components/delegatorsInfo/types.ts
deleted file mode 100644
index b0e3fd6e99..0000000000
--- a/explorer/src/components/delegatorsInfo/types.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export type RowsType = {
- value?: string | number;
- visualProgressValue?: number;
-};
-
-export interface DelegatorsInfoRow {
- estimated_total_reward: RowsType;
- estimated_operator_reward: RowsType;
- active_set_probability: RowsType;
- stake_saturation: RowsType;
- profit_margin: RowsType;
- avg_uptime: RowsType;
-}
-
-export type DelegatorsInfoRowWithIndex = DelegatorsInfoRow & { id: number };
diff --git a/explorer/src/components/index.ts b/explorer/src/components/index.ts
deleted file mode 100644
index 92eeebd010..0000000000
--- a/explorer/src/components/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export * from './CustomColumnHeading';
-export * from './Title';
-export * from './Universal-DataGrid';
-export * from './Tooltip';
-export { default as StyledLink } from './StyledLink';
-export * from './Delegations';
-export * from './MixNodes';
-export * from './TableToolbar';
-export * from './Icons';
diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx
deleted file mode 100644
index ce82b21a17..0000000000
--- a/explorer/src/context/cosmos-kit.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import React from 'react';
-import { ChainProvider } from '@cosmos-kit/react';
-import { wallets as keplr } from '@cosmos-kit/keplr-extension';
-import { assets, chains } from 'chain-registry';
-import { Chain, AssetList } from '@chain-registry/types';
-import { VALIDATOR_BASE_URL } from '@src/api/constants';
-
-const nymSandbox: Chain = {
- chain_name: 'sandbox',
- chain_id: 'sandbox',
- bech32_prefix: 'n',
- network_type: 'devnet',
- pretty_name: 'Nym Sandbox',
- status: 'active',
- slip44: 118,
- apis: {
- rpc: [
- {
- address: 'https://rpc.sandbox.nymtech.net',
- },
- ],
- },
-};
-
-const nymSandboxAssets = {
- chain_name: 'sandbox',
- assets: [
- {
- name: 'Nym',
- base: 'unym',
- symbol: 'NYM',
- display: 'NYM',
- denom_units: [],
- },
- ],
-};
-
-const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => {
- // Only use the nyx chains
- const chainsFixedUp = React.useMemo(() => {
- const nyx = chains.find((chain) => chain.chain_id === 'nyx');
-
- return nyx ? [nymSandbox, nyx] : [nymSandbox];
- }, [chains]);
-
- // Only use the nyx assets
- const assetsFixedUp = React.useMemo(() => {
- const nyx = assets.find((asset) => asset.chain_name === 'nyx');
-
- return nyx ? [nyx] : [nymSandboxAssets];
- }, [assets]) as AssetList[];
-
- return (
-
- {children}
-
- );
-};
-
-export default CosmosKitProvider;
diff --git a/explorer/src/context/delegations.tsx b/explorer/src/context/delegations.tsx
deleted file mode 100644
index 28a50345e0..0000000000
--- a/explorer/src/context/delegations.tsx
+++ /dev/null
@@ -1,200 +0,0 @@
-import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
-import { Delegation, PendingEpochEvent, PendingEpochEventKind } from '@nymproject/contract-clients/Mixnet.types';
-import { ExecuteResult } from '@cosmjs/cosmwasm-stargate';
-import { useWalletContext } from './wallet';
-import { useMainContext } from './main';
-
-const fee = { gas: '1000000', amount: [{ amount: '1000000', denom: 'unym' }] };
-
-export type PendingEvent = ReturnType;
-
-export type DelegationWithRewards = Delegation & {
- rewards: string;
- identityKey: string;
- pending: PendingEvent;
-};
-
-const getEventsByAddress = (kind: PendingEpochEventKind, address: String) => {
- if ('delegate' in kind && kind.delegate.owner === address) {
- return {
- kind: 'delegate' as const,
- mixId: kind.delegate.mix_id,
- amount: kind.delegate.amount,
- };
- }
-
- if ('undelegate' in kind && kind.undelegate.owner === address) {
- return {
- kind: 'undelegate' as const,
- mixId: kind.undelegate.mix_id,
- };
- }
-
- return undefined;
-};
-
-interface DelegationsState {
- delegations?: DelegationWithRewards[];
- handleGetDelegations: () => Promise;
- handleDelegate: (mixId: number, amount: string) => Promise;
- handleUndelegate: (mixId: number) => Promise;
-}
-
-export const DelegationsContext = createContext({
- delegations: undefined,
- handleGetDelegations: async () => {
- throw new Error('Please connect your wallet');
- },
- handleDelegate: async () => {
- throw new Error('Please connect your wallet');
- },
- handleUndelegate: async () => {
- throw new Error('Please connect your wallet');
- },
-});
-
-export const DelegationsProvider = ({ children }: { children: React.ReactNode }) => {
- const [delegations, setDelegations] = useState();
- const { address, nymQueryClient, nymClient } = useWalletContext();
- const { fetchMixnodes } = useMainContext();
-
- const handleGetPendingEvents = async () => {
- if (!nymQueryClient) {
- return undefined;
- }
-
- if (!address) {
- return undefined;
- }
-
- const response = await nymQueryClient.getPendingEpochEvents({});
- const pendingEvents: PendingEvent[] = [];
-
- response.events.forEach((e: PendingEpochEvent) => {
- const event = getEventsByAddress(e.event.kind, address);
- if (event) {
- pendingEvents.push(event);
- }
- });
-
- return pendingEvents;
- };
-
- const handleGetDelegationRewards = async (mixId: number) => {
- if (!nymQueryClient) {
- return undefined;
- }
-
- if (!address) {
- return undefined;
- }
-
- const response = await nymQueryClient.getPendingDelegatorReward({ address, mixId });
-
- return response;
- };
-
- const handleGetDelegations = useCallback(async () => {
- if (!nymQueryClient) {
- setDelegations(undefined);
- return undefined;
- }
-
- if (!address) {
- setDelegations(undefined);
- return undefined;
- }
-
- // Get all mixnodes - Required to get the identity key for each delegation
- const mixnodes = await fetchMixnodes();
-
- // Get delegations
- const delegationsResponse = await nymQueryClient.getDelegatorDelegations({ delegator: address });
-
- // Get rewards for each delegation
- const rewardsResponse = await Promise.all(
- delegationsResponse.delegations.map((d: Delegation) => handleGetDelegationRewards(d.mix_id)),
- );
-
- // Get all pending events
- const pendingEvents = await handleGetPendingEvents();
-
- const delegationsWithRewards: DelegationWithRewards[] = [];
-
- // Merge delegations with rewards and pending events
- delegationsResponse.delegations.forEach((d: Delegation, index: number) => {
- delegationsWithRewards.push({
- ...d,
- pending: pendingEvents?.find((e: PendingEvent) => (e?.mixId === d.mix_id ? e.kind : undefined)),
- identityKey: mixnodes?.find((m) => m.mix_id === d.mix_id)?.mix_node.identity_key || '',
- rewards: rewardsResponse[index]?.amount_earned_detailed || '0',
- });
- });
-
- // Add pending events that are not in the delegations list
- pendingEvents?.forEach((e) => {
- if (e && !delegationsWithRewards.find((d: DelegationWithRewards) => d.mix_id === e.mixId)) {
- delegationsWithRewards.push({
- mix_id: e.mixId,
- height: 0,
- cumulative_reward_ratio: '0',
- owner: address,
- amount: {
- amount: '0',
- denom: 'unym',
- },
- rewards: '0',
- identityKey: mixnodes?.find((m) => m.mix_id === e.mixId)?.mix_node.identity_key || '',
- pending: e,
- });
- }
- });
-
- setDelegations(delegationsWithRewards);
-
- return undefined;
- }, [address, nymQueryClient]);
-
- const handleDelegate = async (mixId: number, amount: string) => {
- if (!address) {
- throw new Error('Please connect your wallet');
- }
-
- const amountToDelegate = (Number(amount) * 1000000).toString();
- const uNymFunds = [{ amount: amountToDelegate, denom: 'unym' }];
- try {
- const tx = await nymClient?.delegateToMixnode({ mixId }, fee, 'Delegation from Nym Explorer', uNymFunds);
-
- return tx as unknown as ExecuteResult;
- } catch (e) {
- console.error('Failed to delegate to mixnode', e);
- throw e;
- }
- };
-
- const handleUndelegate = async (mixId: number) => {
- const tx = await nymClient?.undelegateFromMixnode({ mixId }, fee, 'Undelegation from Nym Explorer');
-
- return tx as unknown as ExecuteResult;
- };
-
- const contextValue: DelegationsState = useMemo(
- () => ({
- delegations,
- handleGetDelegations,
- handleDelegate,
- handleUndelegate,
- }),
- [delegations, handleGetDelegations],
- );
-
- return {children};
-};
-
-export const useDelegationsContext = () => {
- const context = useContext(DelegationsContext);
- if (!context) {
- throw new Error('useDelegationsContext must be used within a DelegationsProvider');
- }
- return context;
-};
diff --git a/explorer/src/context/gateway.tsx b/explorer/src/context/gateway.tsx
deleted file mode 100644
index dd96634518..0000000000
--- a/explorer/src/context/gateway.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as React from 'react';
-import { ApiState, GatewayReportResponse, UptimeStoryResponse } from '../typeDefs/explorer-api';
-import { Api } from '../api';
-import { useApiState } from './hooks';
-
-/**
- * This context provides the state for a single gateway by identity key.
- */
-
-interface GatewayState {
- uptimeReport?: ApiState;
- uptimeStory?: ApiState;
-}
-
-export const GatewayContext = React.createContext({});
-
-export const useGatewayContext = (): React.ContextType =>
- React.useContext(GatewayContext);
-
-/**
- * Provides a state context for a gateway by identity
- * @param gatewayIdentityKey The identity key of the gateway
- */
-export const GatewayContextProvider = ({
- gatewayIdentityKey,
- children,
-}: {
- gatewayIdentityKey: string;
- children: JSX.Element;
-}) => {
- const [uptimeReport, fetchUptimeReportById, clearUptimeReportById] = useApiState(
- gatewayIdentityKey,
- Api.fetchGatewayReportById,
- 'Failed to fetch gateway uptime report by id',
- );
-
- const [uptimeStory, fetchUptimeHistory, clearUptimeHistory] = useApiState(
- gatewayIdentityKey,
- Api.fetchGatewayUptimeStoryById,
- 'Failed to fetch gateway uptime history',
- );
-
- React.useEffect(() => {
- // when the identity key changes, remove all previous data
- clearUptimeReportById();
- clearUptimeHistory();
- Promise.all([fetchUptimeReportById(), fetchUptimeHistory()]);
- }, [gatewayIdentityKey]);
-
- const state = React.useMemo(
- () => ({
- uptimeReport,
- uptimeStory,
- }),
- [uptimeReport, uptimeStory],
- );
-
- return {children};
-};
diff --git a/explorer/src/context/hooks.ts b/explorer/src/context/hooks.ts
deleted file mode 100644
index 9c5579c899..0000000000
--- a/explorer/src/context/hooks.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import * as React from 'react';
-import { ApiState } from '../typeDefs/explorer-api';
-
-/**
- * Custom hook to get data from the API by passing an id to a delegate method that fetches the data asynchronously
- * @param id The id to fetch
- * @param fn Delegate the fetching to this method (must take `(id: string)` as a parameter)
- * @param errorMessage A static error message, to use when no dynamic error message is returned
- */
-export const useApiState = (
- id: string,
- fn: (argId: string) => Promise,
- errorMessage: string,
-): [ApiState | undefined, () => Promise>, () => void] => {
- // stores the state
- const [value, setValue] = React.useState>();
-
- // clear the value
- const clearValueFn = () => setValue(undefined);
-
- // this provides a method to trigger the delegate to fetch data
- const wrappedFetchFn = React.useCallback(async () => {
- setValue({ isLoading: true });
- try {
- // keep previous state and set to loading
- setValue((prevState) => ({ ...prevState, isLoading: true }));
-
- // delegate to user function to get data and set if successful
- const data = await fn(id);
- const newValue: ApiState = {
- isLoading: false,
- data,
- };
- setValue(newValue);
- return newValue;
- } catch (error) {
- // return the caught error or create a new error with the static error message
- const newValue: ApiState = {
- error: error instanceof Error ? error : new Error(errorMessage),
- isLoading: false,
- };
- setValue(newValue);
- return newValue;
- }
- }, [setValue, fn, id, errorMessage]);
- return [value, wrappedFetchFn, clearValueFn];
-};
diff --git a/explorer/src/context/main.tsx b/explorer/src/context/main.tsx
deleted file mode 100644
index c7a74a3d0d..0000000000
--- a/explorer/src/context/main.tsx
+++ /dev/null
@@ -1,241 +0,0 @@
-import * as React from 'react';
-import { PaletteMode } from '@mui/material';
-import {
- ApiState,
- BlockResponse,
- CountryDataResponse,
- GatewayResponse,
- MixNodeResponse,
- MixnodeStatus,
- SummaryOverviewResponse,
- ValidatorsResponse,
- Environment,
- DirectoryServiceProvider,
-} from '../typeDefs/explorer-api';
-import { EnumFilterKey } from '../typeDefs/filters';
-import { Api, getEnvironment } from '../api';
-import { NavOptionType, originalNavOptions } from './nav';
-import { toPercentIntegerString } from '../utils';
-
-interface StateData {
- summaryOverview?: ApiState;
- block?: ApiState;
- countryData?: ApiState;
- gateways?: ApiState;
- globalError?: string | undefined;
- mixnodes?: ApiState;
- mode: PaletteMode;
- navState: NavOptionType[];
- validators?: ApiState;
- environment?: Environment;
- serviceProviders?: ApiState;
-}
-
-interface StateApi {
- fetchMixnodes: (status?: MixnodeStatus) => Promise;
- filterMixnodes: (filters: any, status: any) => void;
- toggleMode: () => void;
- updateNavState: (title: string) => void;
-}
-
-type State = StateData & StateApi;
-
-export const MainContext = React.createContext({
- mode: 'dark',
- updateNavState: () => null,
- navState: originalNavOptions,
- toggleMode: () => undefined,
- filterMixnodes: () => null,
- fetchMixnodes: () => Promise.resolve(undefined),
-});
-
-export const useMainContext = (): React.ContextType => React.useContext(MainContext);
-
-export const MainContextProvider: FCWithChildren = ({ children }) => {
- // network explorer environment
- const [environment, setEnvironment] = React.useState();
-
- // light/dark mode
- const [mode, setMode] = React.useState('dark');
-
- // nav state
- const [navState, updateNav] = React.useState(originalNavOptions);
-
- // global / banner error messaging
- const [globalError] = React.useState();
-
- // various APIs for Overview page
- const [summaryOverview, setSummaryOverview] = React.useState>();
- const [mixnodes, setMixnodes] = React.useState>();
- const [gateways, setGateways] = React.useState>();
- const [validators, setValidators] = React.useState>();
- const [block, setBlock] = React.useState>();
- const [countryData, setCountryData] = React.useState>();
- const [serviceProviders, setServiceProviders] = React.useState>();
-
- const toggleMode = () => setMode((m) => (m !== 'light' ? 'light' : 'dark'));
-
- const fetchOverviewSummary = async () => {
- try {
- const data = await Api.fetchOverviewSummary();
- setSummaryOverview({ data, isLoading: false });
- } catch (error) {
- setSummaryOverview({
- error: error instanceof Error ? error : new Error('Overview summary api fail'),
- isLoading: false,
- });
- }
- };
-
- const fetchMixnodes = async (status?: MixnodeStatus) => {
- let data;
- setMixnodes((d) => ({ ...d, isLoading: true }));
- try {
- data = status ? await Api.fetchMixnodesActiveSetByStatus(status) : await Api.fetchMixnodes();
- setMixnodes({ data, isLoading: false });
- } catch (error) {
- setMixnodes({
- error: error instanceof Error ? error : new Error('Mixnode api fail'),
- isLoading: false,
- });
- }
- return data;
- };
-
- const filterMixnodes = async (filters: { [key in EnumFilterKey]: number[] }, status?: MixnodeStatus) => {
- setMixnodes((d) => ({ ...d, isLoading: true }));
- const mxns = status ? await Api.fetchMixnodesActiveSetByStatus(status) : await Api.fetchMixnodes();
-
- const filtered = mxns?.filter(
- (m) =>
- +m.profit_margin_percent >= filters.profitMargin[0] / 100 &&
- +m.profit_margin_percent <= filters.profitMargin[1] / 100 &&
- m.stake_saturation >= filters.stakeSaturation[0] &&
- m.stake_saturation <= filters.stakeSaturation[1] &&
- m.avg_uptime >= filters.routingScore[0] &&
- m.avg_uptime <= filters.routingScore[1],
- );
-
- setMixnodes({ data: filtered, isLoading: false });
- };
-
- const fetchGateways = async () => {
- setGateways((d) => ({ ...d, isLoading: true }));
- try {
- const data = await Api.fetchGateways();
- setGateways({ data, isLoading: false });
- } catch (error) {
- setGateways({
- error: error instanceof Error ? error : new Error('Gateways api fail'),
- isLoading: false,
- });
- }
- };
- const fetchValidators = async () => {
- try {
- const data = await Api.fetchValidators();
- setValidators({ data, isLoading: false });
- } catch (error) {
- setValidators({
- error: error instanceof Error ? error : new Error('Validators api fail'),
- isLoading: false,
- });
- }
- };
- const fetchBlock = async () => {
- try {
- const data = await Api.fetchBlock();
- setBlock({ data, isLoading: false });
- } catch (error) {
- setBlock({
- error: error instanceof Error ? error : new Error('Block api fail'),
- isLoading: false,
- });
- }
- };
- const fetchCountryData = async () => {
- setCountryData({ data: undefined, isLoading: true });
- try {
- const res = await Api.fetchCountryData();
- setCountryData({ data: res, isLoading: false });
- } catch (error) {
- setCountryData({
- error: error instanceof Error ? error : new Error('Country Data api fail'),
- isLoading: false,
- });
- }
- };
-
- const fetchServiceProviders = async () => {
- setServiceProviders({ data: undefined, isLoading: true });
- try {
- const res = await Api.fetchServiceProviders();
- const resWithRoutingScorePercentage = res.map((item) => ({
- ...item,
- routing_score: item.routing_score
- ? `${toPercentIntegerString(item.routing_score.toString())}%`
- : item.routing_score,
- }));
- setServiceProviders({ data: resWithRoutingScorePercentage, isLoading: false });
- } catch (error) {
- setServiceProviders({
- error: error instanceof Error ? error : new Error('Service provider api fail'),
- isLoading: false,
- });
- }
- };
-
- const updateNavState = (url: string) => {
- const updated = navState.map((option) => ({
- ...option,
- isActive: option.url === url,
- }));
- updateNav(updated);
- };
-
- React.useEffect(() => {
- if (environment === 'mainnet') {
- fetchServiceProviders();
- }
- }, [environment]);
-
- React.useEffect(() => {
- setEnvironment(getEnvironment());
- Promise.all([fetchOverviewSummary(), fetchGateways(), fetchValidators(), fetchBlock(), fetchCountryData()]);
- }, []);
-
- const state = React.useMemo(
- () => ({
- environment,
- block,
- countryData,
- fetchMixnodes,
- filterMixnodes,
- gateways,
- globalError,
- mixnodes,
- mode,
- navState,
- summaryOverview,
- toggleMode,
- updateNavState,
- validators,
- serviceProviders,
- }),
- [
- environment,
- block,
- countryData,
- gateways,
- globalError,
- mixnodes,
- mode,
- navState,
- summaryOverview,
- validators,
- serviceProviders,
- ],
- );
-
- return {children};
-};
diff --git a/explorer/src/context/mixnode.tsx b/explorer/src/context/mixnode.tsx
deleted file mode 100644
index 36e43d568b..0000000000
--- a/explorer/src/context/mixnode.tsx
+++ /dev/null
@@ -1,157 +0,0 @@
-import * as React from 'react';
-import {
- ApiState,
- DelegationsResponse,
- UniqDelegationsResponse,
- MixNodeDescriptionResponse,
- MixNodeEconomicDynamicsStatsResponse,
- MixNodeResponseItem,
- StatsResponse,
- StatusResponse,
- UptimeStoryResponse,
-} from '../typeDefs/explorer-api';
-import { Api } from '../api';
-import { useApiState } from './hooks';
-import { mixNodeResponseItemToMixnodeRowType, MixnodeRowType } from '../components/MixNodes';
-
-/**
- * This context provides the state for a single mixnode by identity key.
- */
-
-interface MixnodeState {
- delegations?: ApiState;
- uniqDelegations?: ApiState;
- description?: ApiState;
- economicDynamicsStats?: ApiState;
- mixNode?: ApiState;
- mixNodeRow?: MixnodeRowType;
- stats?: ApiState;
- status?: ApiState;
- uptimeStory?: ApiState;
-}
-
-export const MixnodeContext = React.createContext({});
-
-export const useMixnodeContext = (): React.ContextType =>
- React.useContext(MixnodeContext);
-
-interface MixnodeContextProviderProps {
- mixId: string;
- children: React.ReactNode;
-}
-
-/**
- * Provides a state context for a mixnode by identity
- * @param mixId The mixID of the mixnode
- */
-export const MixnodeContextProvider: FCWithChildren = ({ mixId, children }) => {
- const [mixNode, fetchMixnodeById, clearMixnodeById] = useApiState(
- mixId,
- Api.fetchMixnodeByID,
- 'Failed to fetch mixnode by id',
- );
-
- const [mixNodeRow, setMixnodeRow] = React.useState();
-
- const [delegations, fetchDelegations, clearDelegations] = useApiState(
- mixId,
- Api.fetchDelegationsById,
- 'Failed to fetch delegations for mixnode',
- );
-
- const [uniqDelegations, fetchUniqDelegations, clearUniqDelegations] = useApiState(
- mixId,
- Api.fetchUniqDelegationsById,
- 'Failed to fetch delegations for mixnode',
- );
-
- const [status, fetchStatus, clearStatus] = useApiState(
- mixId,
- Api.fetchStatusById,
- 'Failed to fetch mixnode status',
- );
-
- const [stats, fetchStats, clearStats] = useApiState(
- mixId,
- Api.fetchStatsById,
- 'Failed to fetch mixnode stats',
- );
-
- const [description, fetchDescription, clearDescription] = useApiState(
- mixId,
- Api.fetchMixnodeDescriptionById,
- 'Failed to fetch mixnode description',
- );
-
- const [economicDynamicsStats, fetchEconomicDynamicsStats, clearEconomicDynamicsStats] =
- useApiState(
- mixId,
- Api.fetchMixnodeEconomicDynamicsStatsById,
- 'Failed to fetch mixnode dynamics stats by id',
- );
-
- const [uptimeStory, fetchUptimeHistory, clearUptimeHistory] = useApiState(
- mixId,
- Api.fetchUptimeStoryById,
- 'Failed to fetch mixnode uptime history',
- );
-
- React.useEffect(() => {
- // when the identity key changes, remove all previous data
- clearMixnodeById();
- clearDelegations();
- clearUniqDelegations();
- clearStatus();
- clearStats();
- clearDescription();
- clearEconomicDynamicsStats();
- clearUptimeHistory();
-
- // fetch the mixnode, then get all the other stuff
- fetchMixnodeById().then((value) => {
- if (!value.data || value.error) {
- setMixnodeRow(undefined);
- return;
- }
- setMixnodeRow(mixNodeResponseItemToMixnodeRowType(value.data));
- Promise.all([
- fetchDelegations(),
- fetchUniqDelegations(),
- fetchStatus(),
- fetchStats(),
- fetchDescription(),
- fetchEconomicDynamicsStats(),
- fetchUptimeHistory(),
- ]);
- });
- }, [mixId]);
-
- const state = React.useMemo(
- () => ({
- delegations,
- uniqDelegations,
- mixNode,
- mixNodeRow,
- description,
- economicDynamicsStats,
- stats,
- status,
- uptimeStory,
- }),
- [
- {
- delegations,
- uniqDelegations,
- mixNode,
- mixNodeRow,
- description,
- economicDynamicsStats,
- stats,
- status,
- uptimeStory,
- },
- ],
- );
-
- return {children};
-};
diff --git a/explorer/src/context/nav.tsx b/explorer/src/context/nav.tsx
deleted file mode 100644
index 6df749f585..0000000000
--- a/explorer/src/context/nav.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import * as React from 'react';
-import { DelegateIcon } from '@src/icons/DelevateSVG';
-import { BIG_DIPPER } from '../api/constants';
-import { OverviewSVG } from '../icons/OverviewSVG';
-import { NodemapSVG } from '../icons/NodemapSVG';
-import { NetworkComponentsSVG } from '../icons/NetworksSVG';
-
-export type NavOptionType = {
- isActive?: boolean;
- url: string;
- title: string;
- Icon?: React.ReactNode;
- nested?: NavOptionType[];
- isExpandedChild?: boolean;
-};
-
-export const originalNavOptions: NavOptionType[] = [
- {
- isActive: false,
- url: '/',
- title: 'Overview',
- Icon: ,
- },
- {
- isActive: false,
- url: '/network-components',
- title: 'Network Components',
- Icon: ,
- nested: [
- {
- url: '/network-components/mixnodes',
- title: 'Mixnodes',
- },
- {
- url: '/network-components/gateways',
- title: 'Gateways',
- },
- {
- url: `${BIG_DIPPER}/validators`,
- title: 'Validators',
- },
- {
- url: 'network-components/service-providers',
- title: 'Service Providers',
- },
- ],
- },
- {
- isActive: false,
- url: '/nodemap',
- title: 'Nodemap',
- Icon: ,
- },
- {
- isActive: false,
- url: '/delegations',
- title: 'Delegations',
- Icon: ,
- },
-];
diff --git a/explorer/src/context/wallet.tsx b/explorer/src/context/wallet.tsx
deleted file mode 100644
index 8ac26ee7ca..0000000000
--- a/explorer/src/context/wallet.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
-import { useChain } from '@cosmos-kit/react';
-import { Wallet } from '@cosmos-kit/core';
-import { unymToNym } from '@src/utils/currency';
-import { useNymClient } from '@src/hooks';
-import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client';
-import { COSMOS_KIT_USE_CHAIN } from '@src/api/constants';
-
-interface WalletState {
- balance: { status: 'loading' | 'success'; data?: string };
- address?: string;
- isWalletConnected: boolean;
- isWalletConnecting: boolean;
- wallet?: Wallet;
- nymClient?: MixnetClient;
- nymQueryClient?: MixnetQueryClient;
- connectWallet: () => Promise;
- disconnectWallet: () => Promise;
-}
-
-export const WalletContext = createContext({
- address: undefined,
- balance: { status: 'loading', data: undefined },
- isWalletConnected: false,
- isWalletConnecting: false,
- nymClient: undefined,
- nymQueryClient: undefined,
- connectWallet: async () => {
- throw new Error('Please connect your wallet');
- },
- disconnectWallet: async () => {
- throw new Error('Please connect your wallet');
- },
-});
-
-export const WalletProvider = ({ children }: { children: React.ReactNode }) => {
- const [balance, setBalance] = useState({ status: 'loading', data: undefined });
-
- const { connect, disconnect, wallet, address, isWalletConnected, isWalletConnecting, getCosmWasmClient } =
- useChain(COSMOS_KIT_USE_CHAIN);
-
- const { nymClient, nymQueryClient } = useNymClient(address);
-
- const getBalance = async (walletAddress: string) => {
- const account = await getCosmWasmClient();
- const uNYMBalance = await account.getBalance(walletAddress, 'unym');
- const NYMBalance = unymToNym(uNYMBalance.amount);
-
- return NYMBalance;
- };
-
- const init = async (walletAddress: string) => {
- const walletBalance = await getBalance(walletAddress);
- setBalance({ status: 'success', data: walletBalance });
- };
-
- useEffect(() => {
- if (isWalletConnected && address) {
- init(address);
- }
- }, [address, isWalletConnected]);
-
- const handleConnectWallet = async () => {
- await connect();
- };
-
- const handleDisconnectWallet = async () => {
- await disconnect();
- setBalance({ status: 'loading', data: undefined });
- };
-
- const contextValue: WalletState = useMemo(
- () => ({
- address,
- balance,
- wallet,
- isWalletConnected,
- isWalletConnecting,
- nymClient,
- nymQueryClient,
- connectWallet: handleConnectWallet,
- disconnectWallet: handleDisconnectWallet,
- }),
- [address, balance, wallet, isWalletConnected, isWalletConnecting, nymClient, nymQueryClient],
- );
-
- return {children};
-};
-
-export const useWalletContext = () => useContext(WalletContext);
diff --git a/explorer/src/errors/ErrorBoundaryContent.tsx b/explorer/src/errors/ErrorBoundaryContent.tsx
deleted file mode 100644
index 0389588e26..0000000000
--- a/explorer/src/errors/ErrorBoundaryContent.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as React from 'react';
-import { FallbackProps } from 'react-error-boundary';
-import { Alert, AlertTitle, Container } from '@mui/material';
-import { NymThemeProvider } from '@nymproject/mui-theme';
-import { NymLogo } from '@nymproject/react/logo/NymLogo';
-
-export const ErrorBoundaryContent: FCWithChildren = ({ error }) => (
-
-
-
- Oh no! Sorry, something went wrong
-
- {error.name}
- {error.message}
-
- {process.env.NODE_ENV === 'development' && (
-
- Stack trace
- {error.stack}
-
- )}
-
-
-);
diff --git a/explorer/src/hooks/index.ts b/explorer/src/hooks/index.ts
deleted file mode 100644
index ba04855f77..0000000000
--- a/explorer/src/hooks/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './useIsMobile';
-export * from './useIsMounted';
-export * from './useGetMixnodeStatusColor';
-export * from './useNymClient';
diff --git a/explorer/src/hooks/useGetMixnodeStatusColor.ts b/explorer/src/hooks/useGetMixnodeStatusColor.ts
deleted file mode 100644
index d9d71fe7e1..0000000000
--- a/explorer/src/hooks/useGetMixnodeStatusColor.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useTheme } from '@mui/material';
-import { MixnodeStatus } from '@src/typeDefs/explorer-api';
-
-export const useGetMixNodeStatusColor = (status: MixnodeStatus) => {
- const theme = useTheme();
-
- switch (status) {
- case MixnodeStatus.active:
- return theme.palette.nym.networkExplorer.mixnodes.status.active;
-
- case MixnodeStatus.standby:
- return theme.palette.nym.networkExplorer.mixnodes.status.standby;
-
- default:
- return theme.palette.nym.networkExplorer.mixnodes.status.inactive;
- }
-};
diff --git a/explorer/src/hooks/useIsMobile.ts b/explorer/src/hooks/useIsMobile.ts
deleted file mode 100644
index 225964b464..0000000000
--- a/explorer/src/hooks/useIsMobile.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Breakpoint, useMediaQuery } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-
-export const useIsMobile = (queryInput: number | Breakpoint = 'md') => {
- const theme = useTheme();
- const isMobile = useMediaQuery(theme.breakpoints.down(queryInput));
-
- return isMobile;
-};
diff --git a/explorer/src/hooks/useIsMounted.ts b/explorer/src/hooks/useIsMounted.ts
deleted file mode 100644
index b18f3a72b7..0000000000
--- a/explorer/src/hooks/useIsMounted.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useRef, useEffect, useCallback } from 'react';
-
-export function useIsMounted(): () => boolean {
- const ref = useRef(false);
-
- useEffect(() => {
- ref.current = true;
- return () => {
- ref.current = false;
- };
- }, []);
-
- return useCallback(() => ref.current, [ref]);
-}
diff --git a/explorer/src/hooks/useNymClient.tsx b/explorer/src/hooks/useNymClient.tsx
deleted file mode 100644
index 26b2f529db..0000000000
--- a/explorer/src/hooks/useNymClient.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useEffect, useState } from 'react';
-import { useChain } from '@cosmos-kit/react';
-import { contracts } from '@nymproject/contract-clients';
-import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client';
-import { COSMOS_KIT_USE_CHAIN, NYM_MIXNET_CONTRACT } from '@src/api/constants';
-
-export const useNymClient = (address?: string) => {
- const [nymClient, setNymClient] = useState();
- const [nymQueryClient, setNymQueryClient] = useState();
-
- const { getCosmWasmClient, getSigningCosmWasmClient } = useChain(COSMOS_KIT_USE_CHAIN);
-
- useEffect(() => {
- if (address) {
- const init = async () => {
- const cosmWasmSigningClient = await getSigningCosmWasmClient();
- const cosmWasmClient = await getCosmWasmClient();
-
- const client = new contracts.Mixnet.MixnetClient(cosmWasmSigningClient as any, address, NYM_MIXNET_CONTRACT);
- const queryClient = new contracts.Mixnet.MixnetQueryClient(cosmWasmClient as any, NYM_MIXNET_CONTRACT);
-
- setNymClient(client);
- setNymQueryClient(queryClient);
- };
-
- init();
- }
- }, [address, getCosmWasmClient, getSigningCosmWasmClient]);
-
- return { nymClient, nymQueryClient };
-};
diff --git a/explorer/src/icons/DelevateSVG.tsx b/explorer/src/icons/DelevateSVG.tsx
deleted file mode 100644
index 56180d1b8a..0000000000
--- a/explorer/src/icons/DelevateSVG.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import { SvgIcon, SvgIconProps } from '@mui/material';
-
-export const DelegateIcon = (props: SvgIconProps) => (
-
-
-
-
-
-
-
-);
diff --git a/explorer/src/icons/ElipsSVG.tsx b/explorer/src/icons/ElipsSVG.tsx
deleted file mode 100644
index 4a430d6cb6..0000000000
--- a/explorer/src/icons/ElipsSVG.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import * as React from 'react';
-
-export const ElipsSVG: FCWithChildren = () => (
-
-);
diff --git a/explorer/src/icons/GatewaysSVG.tsx b/explorer/src/icons/GatewaysSVG.tsx
deleted file mode 100644
index 00e4a21198..0000000000
--- a/explorer/src/icons/GatewaysSVG.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const GatewaysSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.text.primary;
- return (
-
- );
-};
diff --git a/explorer/src/icons/LightSwitchSVG.tsx b/explorer/src/icons/LightSwitchSVG.tsx
deleted file mode 100644
index 7a32590dfc..0000000000
--- a/explorer/src/icons/LightSwitchSVG.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const LightSwitchSVG: FCWithChildren = () => {
- const { palette } = useTheme();
- return (
-
- );
-};
diff --git a/explorer/src/icons/MixnodesSVG.tsx b/explorer/src/icons/MixnodesSVG.tsx
deleted file mode 100644
index 56902cb0de..0000000000
--- a/explorer/src/icons/MixnodesSVG.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const MixnodesSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.text.primary;
-
- return (
-
- );
-};
diff --git a/explorer/src/icons/MobileDrawerClose.tsx b/explorer/src/icons/MobileDrawerClose.tsx
deleted file mode 100644
index 6c8ecfacbc..0000000000
--- a/explorer/src/icons/MobileDrawerClose.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as React from 'react';
-
-export const MobileDrawerClose: FCWithChildren = (props) => (
-
-);
diff --git a/explorer/src/icons/NetworksSVG.tsx b/explorer/src/icons/NetworksSVG.tsx
deleted file mode 100644
index 0db2b9bdfb..0000000000
--- a/explorer/src/icons/NetworksSVG.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const NetworkComponentsSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.nym.networkExplorer.nav.text;
- return (
-
- );
-};
diff --git a/explorer/src/icons/NodemapSVG.tsx b/explorer/src/icons/NodemapSVG.tsx
deleted file mode 100644
index 9486d64dcc..0000000000
--- a/explorer/src/icons/NodemapSVG.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const NodemapSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.nym.networkExplorer.nav.text;
- return (
-
- );
-};
diff --git a/explorer/src/icons/NymVpn.tsx b/explorer/src/icons/NymVpn.tsx
deleted file mode 100644
index 788b78a4f9..0000000000
--- a/explorer/src/icons/NymVpn.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as React from 'react';
-
-interface DiscordIconProps {
- size?: { width: number; height: number };
-}
-
-export const NymVpnIcon: FCWithChildren = ({ size }) => (
-
-);
-
-NymVpnIcon.defaultProps = {
- size: { width: 80, height: 12 },
-};
diff --git a/explorer/src/icons/OverviewSVG.tsx b/explorer/src/icons/OverviewSVG.tsx
deleted file mode 100644
index 2ced0bb17b..0000000000
--- a/explorer/src/icons/OverviewSVG.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const OverviewSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.nym.networkExplorer.nav.text;
-
- return (
-
- );
-};
diff --git a/explorer/src/icons/TokenSVG.tsx b/explorer/src/icons/TokenSVG.tsx
deleted file mode 100644
index 94ab1468c9..0000000000
--- a/explorer/src/icons/TokenSVG.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from 'react';
-
-export const TokenSVG: FCWithChildren = () => {
- const color = 'white';
-
- return (
-
- );
-};
diff --git a/explorer/src/icons/ValidatorsSVG.tsx b/explorer/src/icons/ValidatorsSVG.tsx
deleted file mode 100644
index cf03f1c330..0000000000
--- a/explorer/src/icons/ValidatorsSVG.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-export const ValidatorsSVG: FCWithChildren = () => {
- const theme = useTheme();
- const color = theme.palette.text.primary;
- return (
-
- );
-};
diff --git a/explorer/src/icons/socials/DiscordIcon.tsx b/explorer/src/icons/socials/DiscordIcon.tsx
deleted file mode 100644
index 11a9fd1c67..0000000000
--- a/explorer/src/icons/socials/DiscordIcon.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-interface DiscordIconProps {
- size?: number | string;
- color?: string;
-}
-
-export const DiscordIcon: FCWithChildren = ({ size, color: colorProp }) => {
- const theme = useTheme();
- const color = colorProp || theme.palette.text.primary;
- return (
-
- );
-};
-
-DiscordIcon.defaultProps = {
- size: 24,
- color: undefined,
-};
diff --git a/explorer/src/icons/socials/GitHubIcon.tsx b/explorer/src/icons/socials/GitHubIcon.tsx
deleted file mode 100644
index a8fde9b0a9..0000000000
--- a/explorer/src/icons/socials/GitHubIcon.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-interface GitHubIconProps {
- size?: number | string;
- color?: string;
-}
-
-export const GitHubIcon: FCWithChildren = ({ size, color: colorProp }) => {
- const theme = useTheme();
- const color = colorProp || theme.palette.text.primary;
- return (
-
- );
-};
-
-GitHubIcon.defaultProps = {
- size: 24,
- color: undefined,
-};
diff --git a/explorer/src/icons/socials/TelegramIcon.tsx b/explorer/src/icons/socials/TelegramIcon.tsx
deleted file mode 100644
index cf150a4a2f..0000000000
--- a/explorer/src/icons/socials/TelegramIcon.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-interface TelegramIconProps {
- size?: number | string;
- color?: string;
-}
-
-export const TelegramIcon: FCWithChildren = ({ size, color: colorProp }) => {
- const theme = useTheme();
- const color = colorProp || theme.palette.text.primary;
- return (
-
- );
-};
-
-TelegramIcon.defaultProps = {
- size: 24,
- color: undefined,
-};
diff --git a/explorer/src/icons/socials/TwitterIcon.tsx b/explorer/src/icons/socials/TwitterIcon.tsx
deleted file mode 100644
index 6f0b545f56..0000000000
--- a/explorer/src/icons/socials/TwitterIcon.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import * as React from 'react';
-import { useTheme } from '@mui/material/styles';
-
-interface TwitterIconProps {
- size?: number | string;
- color?: string;
-}
-
-export const TwitterIcon: FCWithChildren = ({ size, color: colorProp }) => {
- const theme = useTheme();
- const color = colorProp || theme.palette.text.primary;
- return (
-
- );
-};
-
-TwitterIcon.defaultProps = {
- size: 24,
- color: undefined,
-};
diff --git a/explorer/src/index.html b/explorer/src/index.html
deleted file mode 100644
index dd5a4761ee..0000000000
--- a/explorer/src/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
- Nym Network Explorer
-
-
-
-
-
-
-
-
diff --git a/explorer/src/index.tsx b/explorer/src/index.tsx
deleted file mode 100644
index 0b76be7ab1..0000000000
--- a/explorer/src/index.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import * as React from 'react';
-import { createRoot } from 'react-dom/client';
-import { BrowserRouter as Router } from 'react-router-dom';
-import { ErrorBoundary } from 'react-error-boundary';
-import { MainContextProvider } from './context/main';
-import { NetworkExplorerThemeProvider } from './theme';
-import { ErrorBoundaryContent } from './errors/ErrorBoundaryContent';
-import CosmosKitProvider from './context/cosmos-kit';
-import '@interchain-ui/react/styles';
-import { App } from './App';
-import { WalletProvider } from './context/wallet';
-import './styles.css';
-
-const elem = document.getElementById('app');
-
-if (elem) {
- const root = createRoot(elem);
- root.render(
-
-
-
-
-
-
-
-
-
-
-
-
- ,
- );
-}
diff --git a/explorer/src/pages/404/index.tsx b/explorer/src/pages/404/index.tsx
deleted file mode 100644
index 02f4247fc5..0000000000
--- a/explorer/src/pages/404/index.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import * as React from 'react';
-import { Box, Button, Grid, Paper, Typography } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { useNavigate } from 'react-router-dom';
-import { NymLogo } from '@nymproject/react/logo/NymLogo';
-import { useMainContext } from '../../context/main';
-
-export const Page404 = () => {
- const navigate = useNavigate();
- const { mode } = useMainContext();
- const theme = useTheme();
- return (
-
-
-
-
-
- Oh No!
- It looks like you might be lost.
-
- Please try the link again or navigate back to{' '}
-
-
-
-
-
-
- );
-};
diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx
deleted file mode 100644
index 32e178f2fc..0000000000
--- a/explorer/src/pages/Delegations/index.tsx
+++ /dev/null
@@ -1,264 +0,0 @@
-import React, { useEffect } from 'react';
-import { Alert, AlertTitle, Box, Button, Card, Chip, IconButton, Tooltip, Typography } from '@mui/material';
-import { Link, useNavigate } from 'react-router-dom';
-import { DelegationModal, DelegationModalProps, Title, UniversalDataGrid } from '@src/components';
-import { useWalletContext } from '@src/context/wallet';
-import { GridColDef } from '@mui/x-data-grid';
-import { unymToNym } from '@src/utils/currency';
-import {
- DelegationWithRewards,
- DelegationsProvider,
- PendingEvent,
- useDelegationsContext,
-} from '@src/context/delegations';
-import { urls } from '@src/utils';
-import { useClipboard } from 'use-clipboard-copy';
-import { Close } from '@mui/icons-material';
-
-const mapToDelegationsRow = (delegation: DelegationWithRewards, index: number) => ({
- identity: delegation.identityKey,
- mix_id: delegation.mix_id,
- amount: `${unymToNym(delegation.amount.amount)} NYM`,
- rewards: `${unymToNym(delegation.rewards)} NYM`,
- id: index,
- pending: delegation.pending,
-});
-
-const Banner = ({ onClose }: { onClose: () => void }) => {
- const { copy } = useClipboard();
-
- return (
-
-
-
- }
- >
- Mobile Delegations Beta
-
-
- This is a beta release for mobile delegations If you have any feedback or feature suggestions contact us at
- support@nymte.ch
-
-
-
-
- );
-};
-
-const DelegationsPage = () => {
- const [confirmationModalProps, setConfirmationModalProps] = React.useState();
- const [isLoading, setIsLoading] = React.useState(false);
- const [showBanner, setShowBanner] = React.useState(true);
-
- const { isWalletConnected } = useWalletContext();
- const { handleGetDelegations, handleUndelegate, delegations } = useDelegationsContext();
- const navigate = useNavigate();
-
- useEffect(() => {
- let timeoutId: NodeJS.Timeout;
-
- const fetchDelegations = async () => {
- setIsLoading(true);
- try {
- await handleGetDelegations();
- } catch (error) {
- setConfirmationModalProps({
- status: 'error',
- message: "Couldn't fetch delegations. Please try again later.",
- });
- } finally {
- setIsLoading(false);
-
- timeoutId = setTimeout(() => {
- fetchDelegations();
- }, 60_000);
- }
- };
-
- fetchDelegations();
-
- return () => {
- clearTimeout(timeoutId);
- };
- }, [handleGetDelegations]);
-
- const getTooltipTitle = (pending: PendingEvent) => {
- if (pending?.kind === 'undelegate') {
- return 'You have an undelegation pending';
- }
-
- if (pending?.kind === 'delegate') {
- return `You have a delegation pending worth ${unymToNym(pending.amount.amount)} NYM`;
- }
-
- return undefined;
- };
-
- const onUndelegate = async (mixId: number) => {
- setConfirmationModalProps({ status: 'loading' });
-
- try {
- const tx = await handleUndelegate(mixId);
-
- if (tx) {
- setConfirmationModalProps({
- status: 'success',
- message: 'Undelegation can take up to one hour to process',
- transactions: [
- { url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash },
- ],
- });
- }
- } catch (error) {
- if (error instanceof Error) {
- setConfirmationModalProps({ status: 'error', message: error.message });
- }
- }
- };
-
- const columns: GridColDef[] = [
- {
- field: 'identity',
- headerName: 'Identity Key',
- width: 400,
- disableColumnMenu: true,
- disableReorder: true,
- sortable: false,
- headerAlign: 'left',
- },
- {
- field: 'mix_id',
- headerName: 'Mix ID',
- width: 150,
- disableColumnMenu: true,
- disableReorder: true,
- sortable: false,
- headerAlign: 'left',
- },
- {
- field: 'amount',
- headerName: 'Amount',
- width: 150,
- disableColumnMenu: true,
- disableReorder: true,
- sortable: false,
- headerAlign: 'left',
- },
- {
- field: 'rewards',
- headerName: 'Rewards',
- width: 150,
- disableColumnMenu: true,
- disableReorder: true,
- sortable: false,
- headerAlign: 'left',
- },
- {
- field: 'undelegate',
- headerName: '',
- minWidth: 150,
- flex: 1,
- disableColumnMenu: true,
- disableReorder: true,
- sortable: false,
- headerAlign: 'right',
- renderCell: (params) => {
- const { pending } = params.row;
-
- return (
-
- {pending ? (
- e.stopPropagation()}
- PopperProps={{}}
- >
-
-
- ) : (
-
- )}
-
- );
- },
- },
- ];
-
- const handleRowClick = (params: any) => {
- navigate(`/network-components/mixnode/${params.row.mix_id}`);
- };
-
- return (
-
- {confirmationModalProps && (
- {
- if (confirmationModalProps.status === 'success') {
- await handleGetDelegations();
- }
- setConfirmationModalProps(undefined);
- }}
- sx={{
- width: {
- xs: '90%',
- sm: 600,
- },
- }}
- />
- )}
- {showBanner && setShowBanner(false)} />}
-
-
-
-
- {!isWalletConnected ? (
-
-
- Connect your wallet to view your delegations.
-
-
- ) : null}
-
-
-
-
-
- );
-};
-
-export const Delegations = () => (
-
-
-
-);
diff --git a/explorer/src/pages/GatewayDetail/index.tsx b/explorer/src/pages/GatewayDetail/index.tsx
deleted file mode 100644
index 3382947512..0000000000
--- a/explorer/src/pages/GatewayDetail/index.tsx
+++ /dev/null
@@ -1,184 +0,0 @@
-import * as React from 'react';
-import { Alert, AlertTitle, Box, CircularProgress, Grid } from '@mui/material';
-import { useParams } from 'react-router-dom';
-import { GatewayBond } from '../../typeDefs/explorer-api';
-import { ColumnsType, DetailTable } from '../../components/DetailTable';
-import { gatewayEnrichedToGridRow, GatewayEnrichedRowType } from '../../components/Gateways';
-import { ComponentError } from '../../components/ComponentError';
-import { ContentCard } from '../../components/ContentCard';
-import { TwoColSmallTable } from '../../components/TwoColSmallTable';
-import { UptimeChart } from '../../components/UptimeChart';
-import { GatewayContextProvider, useGatewayContext } from '../../context/gateway';
-import { useMainContext } from '../../context/main';
-import { Title } from '../../components/Title';
-
-const columns: ColumnsType[] = [
- {
- field: 'identity_key',
- title: 'Identity Key',
- headerAlign: 'left',
- width: 230,
- },
- {
- field: 'bond',
- title: 'Bond',
- headerAlign: 'left',
- },
- {
- field: 'node_performance',
- title: 'Routing Score',
- headerAlign: 'left',
- tooltipInfo:
- "Gateway's most recent score (measured in the last 15 minutes). Routing score is relative to that of the network. Each time a gateway is tested, the test packets have to go through the full path of the network (gateway + 3 nodes). If a node in the path drop packets it will affect the score of the gateway and other nodes in the test",
- },
- {
- field: 'avgUptime',
- title: 'Avg. Score',
- headerAlign: 'left',
- tooltipInfo: "Gateway's average routing score in the last 24 hours",
- },
- {
- field: 'host',
- title: 'IP',
- headerAlign: 'left',
- width: 99,
- },
- {
- field: 'location',
- title: 'Location',
- headerAlign: 'left',
- },
- {
- field: 'owner',
- title: 'Owner',
- headerAlign: 'left',
- },
- {
- field: 'version',
- title: 'Version',
- headerAlign: 'left',
- },
-];
-
-/**
- * Shows gateway details
- */
-const PageGatewayDetailsWithState = ({ selectedGateway }: { selectedGateway: GatewayBond | undefined }) => {
- const [enrichGateway, setEnrichGateway] = React.useState();
- const [status, setStatus] = React.useState();
- const { uptimeReport, uptimeStory } = useGatewayContext();
-
- React.useEffect(() => {
- if (uptimeReport?.data && selectedGateway) {
- setEnrichGateway(gatewayEnrichedToGridRow(selectedGateway, uptimeReport.data));
- }
- }, [uptimeReport, selectedGateway]);
-
- React.useEffect(() => {
- if (enrichGateway) {
- setStatus([enrichGateway.mixPort, enrichGateway.clientsPort]);
- }
- }, [enrichGateway]);
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- {status && (
-
- each)}
- icons={status.map((elem) => !!elem)}
- />
-
- )}
-
-
- {uptimeStory && (
-
- {uptimeStory.error && }
-
-
- )}
-
-
-
- );
-};
-
-/**
- * Guard component to handle loading and not found states
- */
-const PageGatewayDetailGuard: FCWithChildren = () => {
- const [selectedGateway, setSelectedGateway] = React.useState();
- const { gateways } = useMainContext();
- const { id } = useParams<{ id: string | undefined }>();
-
- React.useEffect(() => {
- if (gateways?.data) {
- setSelectedGateway(gateways.data.find((g) => g.gateway.identity_key === id));
- }
- }, [gateways, id]);
-
- if (gateways?.isLoading) {
- return ;
- }
-
- if (gateways?.error) {
- // eslint-disable-next-line no-console
- console.error(gateways?.error);
- return (
-
- Oh no! Could not load mixnode {id || ''}
-
- );
- }
-
- // loaded, but not found
- if (gateways && !gateways.isLoading && !gateways.data) {
- return (
-
- Gateway not found
- Sorry, we could not find a mixnode with id {id || ''}
-
- );
- }
-
- return ;
-};
-
-/**
- * Wrapper component that adds the mixnode content based on the `id` in the address URL
- */
-export const PageGatewayDetail: FCWithChildren = () => {
- const { id } = useParams<{ id: string | undefined }>();
-
- if (!id) {
- return Oh no! No mixnode identity key specified;
- }
-
- return (
-
-
-
- );
-};
diff --git a/explorer/src/pages/Gateways/index.tsx b/explorer/src/pages/Gateways/index.tsx
deleted file mode 100644
index c04b7eaf40..0000000000
--- a/explorer/src/pages/Gateways/index.tsx
+++ /dev/null
@@ -1,271 +0,0 @@
-import * as React from 'react';
-import { Box, Card, Grid, Stack } from '@mui/material';
-import { useTheme } from '@mui/material/styles';
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard';
-import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
-import { SelectChangeEvent } from '@mui/material/Select';
-import { diff, gte, rcompare } from 'semver';
-import { Tooltip as InfoTooltip } from '@nymproject/react/tooltip/Tooltip';
-import { useMainContext } from '../../context/main';
-import { gatewayToGridRow } from '../../components/Gateways';
-import { GatewayResponse } from '../../typeDefs/explorer-api';
-import { TableToolbar } from '../../components/TableToolbar';
-import { CustomColumnHeading } from '../../components/CustomColumnHeading';
-import { Title } from '../../components/Title';
-import { UniversalDataGrid } from '../../components/Universal-DataGrid';
-import { unymToNym } from '../../utils/currency';
-import { Tooltip } from '../../components/Tooltip';
-import { NYM_BIG_DIPPER } from '../../api/constants';
-import { splice } from '../../utils';
-import { VersionDisplaySelector, VersionSelectOptions } from '../../components/Gateways/VersionDisplaySelector';
-import StyledLink from '../../components/StyledLink';
-
-export const PageGateways: FCWithChildren = () => {
- const { gateways } = useMainContext();
- const [filteredGateways, setFilteredGateways] = React.useState([]);
- const [pageSize, setPageSize] = React.useState('50');
- const [searchTerm, setSearchTerm] = React.useState('');
- const [versionFilter, setVersionFilter] = React.useState(VersionSelectOptions.all);
-
- const theme = useTheme();
-
- const handleSearch = (str: string) => {
- setSearchTerm(str.toLowerCase());
- };
-
- const highestVersion = React.useMemo(() => {
- if (gateways?.data) {
- const versions = gateways.data.reduce((a: string[], b) => [...a, b.gateway.version], []);
- const [lastestVersion] = versions.sort(rcompare);
- return lastestVersion;
- }
- // fallback value
- return '2.0.0';
- }, [gateways]);
-
- const filterByLatestVersions = React.useMemo(() => {
- const filtered = gateways?.data?.filter((gw) => {
- const versionDiff = diff(highestVersion, gw.gateway.version);
- return versionDiff === 'patch' || versionDiff === null;
- });
- if (filtered) return filtered;
- return [];
- }, [gateways]);
-
- const filterByOlderVersions = React.useMemo(() => {
- const filtered = gateways?.data?.filter((gw) => {
- const versionDiff = diff(highestVersion, gw.gateway.version);
- return versionDiff === 'major' || versionDiff === 'minor';
- });
- if (filtered) return filtered;
- return [];
- }, [gateways]);
-
- const filteredByVersion = React.useMemo(() => {
- switch (versionFilter) {
- case VersionSelectOptions.latestVersion:
- return filterByLatestVersions;
- case VersionSelectOptions.olderVersions:
- return filterByOlderVersions;
- case VersionSelectOptions.all:
- return gateways?.data || [];
- default:
- return [];
- }
- }, [versionFilter, gateways]);
-
- React.useEffect(() => {
- if (searchTerm === '') {
- setFilteredGateways(filteredByVersion);
- } else {
- const filtered = filteredByVersion.filter((g) => {
- if (
- g.gateway.location.toLowerCase().includes(searchTerm) ||
- g.gateway.identity_key.toLocaleLowerCase().includes(searchTerm) ||
- g.owner.toLowerCase().includes(searchTerm)
- ) {
- return g;
- }
- return null;
- });
-
- if (filtered) {
- setFilteredGateways(filtered);
- }
- }
- }, [searchTerm, gateways?.data, versionFilter]);
-
- const columns: GridColDef[] = [
- {
- field: 'identity_key',
- renderHeader: () => ,
- headerClassName: 'MuiDataGrid-header-override',
- width: 400,
- disableColumnMenu: true,
- headerAlign: 'center',
- renderCell: (params: GridRenderCellParams) => (
-
-
- {params.value}
-
- ),
- },
- {
- field: 'node_performance',
- align: 'center',
- renderHeader: () => (
- <>
-
-
- >
- ),
- width: 120,
- disableColumnMenu: true,
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => (
-
- {`${params.value}%`}
-
- ),
- },
- {
- field: 'version',
- align: 'center',
- renderHeader: () => ,
- width: 150,
- disableColumnMenu: true,
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => (
-
- {params.value}
-
- ),
- sortComparator: (a, b) => {
- if (gte(a, b)) return 1;
- return -1;
- },
- },
- {
- field: 'location',
- renderHeader: () => ,
- width: 180,
- disableColumnMenu: true,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => (
- handleSearch(params.value as string)}
- sx={{ justifyContent: 'flex-start', cursor: 'pointer' }}
- data-testid="location-button"
- >
-
-
- {params.value}
-
-
-
- ),
- },
- {
- field: 'host',
- renderHeader: () => ,
- width: 180,
- disableColumnMenu: true,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => (
-
- {params.value}
-
- ),
- },
- {
- field: 'owner',
- headerName: 'Owner',
- renderHeader: () => ,
- width: 180,
- disableColumnMenu: true,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => (
-
- {splice(7, 29, params.value)}
-
- ),
- },
- {
- field: 'bond',
- width: 150,
- disableColumnMenu: true,
- type: 'number',
- renderHeader: () => ,
- headerClassName: 'MuiDataGrid-header-override',
- headerAlign: 'left',
- renderCell: (params: GridRenderCellParams) => (
-
- {`${unymToNym(params.value, 6)}`}
-
- ),
- },
- ];
-
- const handlePageSize = (event: SelectChangeEvent) => {
- setPageSize(event.target.value);
- };
-
- if (gateways?.data) {
- return (
- <>
-
-
-
-
-
-
- setVersionFilter(option)}
- selected={versionFilter}
- />
- }
- />
-
-
-
-
- >
- );
- }
- return null;
-};
diff --git a/explorer/src/pages/MixnodeDetail/index.tsx b/explorer/src/pages/MixnodeDetail/index.tsx
deleted file mode 100644
index 5ceaa36867..0000000000
--- a/explorer/src/pages/MixnodeDetail/index.tsx
+++ /dev/null
@@ -1,236 +0,0 @@
-import * as React from 'react';
-import { Alert, AlertTitle, Box, CircularProgress, Grid, Typography } from '@mui/material';
-import { useParams } from 'react-router-dom';
-import { ColumnsType, DetailTable } from '../../components/DetailTable';
-import { BondBreakdownTable } from '../../components/MixNodes/BondBreakdown';
-import { DelegatorsInfoTable, EconomicsInfoColumns, EconomicsInfoRows } from '../../components/MixNodes/Economics';
-import { ComponentError } from '../../components/ComponentError';
-import { ContentCard } from '../../components/ContentCard';
-import { TwoColSmallTable } from '../../components/TwoColSmallTable';
-import { UptimeChart } from '../../components/UptimeChart';
-import { WorldMap } from '../../components/WorldMap';
-import { MixNodeDetailSection } from '../../components/MixNodes/DetailSection';
-import { MixnodeContextProvider, useMixnodeContext } from '../../context/mixnode';
-import { Title } from '../../components/Title';
-import { useIsMobile } from '../../hooks/useIsMobile';
-
-const columns: ColumnsType[] = [
- {
- field: 'owner',
- title: 'Owner',
- width: '15%',
- },
- {
- field: 'identity_key',
- title: 'Identity Key',
- width: '15%',
- },
-
- {
- field: 'bond',
- title: 'Stake',
- width: '12.5%',
- },
- {
- field: 'stake_saturation',
- title: 'Stake Saturation',
- width: '12.5%',
- tooltipInfo:
- 'Level of stake saturation for this node. Nodes receive more rewards the higher their saturation level, up to 100%. Beyond 100% no additional rewards are granted. The current stake saturation level is 940k NYMs, computed as S/K where S is target amount of tokens staked in the network and K is the number of nodes in the reward set.',
- },
- {
- field: 'self_percentage',
- width: '10%',
- title: 'Bond %',
- tooltipInfo: "Percentage of the operator's bond to the total stake on the node",
- },
-
- {
- field: 'host',
- width: '10%',
- title: 'Host',
- },
- {
- field: 'location',
- title: 'Location',
- },
-
- {
- field: 'layer',
- title: 'Layer',
- },
-];
-
-/**
- * Shows mix node details
- */
-const PageMixnodeDetailWithState: FCWithChildren = () => {
- const { mixNode, mixNodeRow, description, stats, status, uptimeStory, uniqDelegations } = useMixnodeContext();
- const isMobile = useIsMobile();
- return (
-
-
-
-
- {mixNodeRow && description?.data && (
-
- )}
- {mixNodeRow?.blacklisted && (
-
- This node is having a poor performance
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {stats && (
- <>
- {stats.error && }
-
-
- >
- )}
- {!stats && No stats information}
-
-
-
- {uptimeStory && (
-
- {uptimeStory.error && }
-
-
- )}
-
-
-
-
- {status && (
-
- {status.error && }
- each)}
- icons={(status?.data?.ports && Object.values(status.data.ports)) || [false, false, false]}
- />
-
- )}
-
-
- {mixNode && (
-
- {mixNode?.error && }
- {mixNode?.data?.location?.latitude && mixNode?.data?.location?.longitude && (
-
- )}
-
- )}
-
-
-
- );
-};
-
-/**
- * Guard component to handle loading and not found states
- */
-const PageMixnodeDetailGuard: FCWithChildren = () => {
- const { mixNode } = useMixnodeContext();
- const { id } = useParams<{ id: string | undefined }>();
-
- if (mixNode?.isLoading) {
- return ;
- }
-
- if (mixNode?.error) {
- // eslint-disable-next-line no-console
- console.error(mixNode?.error);
- return (
-
- Oh no! Could not load mixnode {id || ''}
-
- );
- }
-
- // loaded, but not found
- if (mixNode && !mixNode.isLoading && !mixNode.data) {
- return (
-
- Mixnode not found
- Sorry, we could not find a mixnode with id {id || ''}
-
- );
- }
-
- return ;
-};
-
-/**
- * Wrapper component that adds the mixnode content based on the `id` in the address URL
- */
-export const PageMixnodeDetail: FCWithChildren = () => {
- const { id } = useParams<{ id: string | undefined }>();
-
- if (!id) {
- return Oh no! No mixnode identity key specified;
- }
-
- return (
-
-
-
- );
-};
diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx
deleted file mode 100644
index 79a88f7053..0000000000
--- a/explorer/src/pages/Mixnodes/index.tsx
+++ /dev/null
@@ -1,427 +0,0 @@
-import * as React from 'react';
-import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
-import { Stack, Card, Grid, Box, Button } from '@mui/material';
-import { useParams, useNavigate, Link } from 'react-router-dom';
-import { SelectChangeEvent } from '@mui/material/Select';
-import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard';
-import { useMainContext } from '@src/context/main';
-import {
- DelegateIconButton,
- DelegationModal,
- DelegationModalProps,
- DelegateModal,
- CustomColumnHeading,
- StyledLink,
- Title,
- UniversalDataGrid,
- TableToolbar,
- Tooltip,
- MixNodeStatusDropdown,
- mixnodeToGridRow,
-} from '@src/components';
-import { MixNodeResponse, MixnodeStatusWithAll, toMixnodeStatus } from '@src/typeDefs/explorer-api';
-import { NYM_BIG_DIPPER } from '@src/api/constants';
-import { currencyToString } from '@src/utils/currency';
-import { splice } from '@src/utils';
-import { useGetMixNodeStatusColor, useIsMobile } from '@src/hooks';
-import { useWalletContext } from '@src/context/wallet';
-import { DelegationsProvider } from '@src/context/delegations';
-
-export const PageMixnodes: FCWithChildren = () => {
- const { mixnodes, fetchMixnodes } = useMainContext();
- const [filteredMixnodes, setFilteredMixnodes] = React.useState([]);
- const [pageSize, setPageSize] = React.useState('10');
- const [searchTerm, setSearchTerm] = React.useState('');
- const [itemSelectedForDelegation, setItemSelectedForDelegation] = React.useState<{
- mixId: number;
- identityKey: string;
- }>();
- const [confirmationModalProps, setConfirmationModalProps] = React.useState();
- const { status } = useParams<{ status: MixnodeStatusWithAll | undefined }>();
-
- const navigate = useNavigate();
- const { isWalletConnected } = useWalletContext();
- const isMobile = useIsMobile();
-
- const handleNewDelegation = (delegationModalProps: DelegationModalProps) => {
- setItemSelectedForDelegation(undefined);
- setConfirmationModalProps(delegationModalProps);
- };
-
- const handleSearch = (str: string) => {
- setSearchTerm(str.toLowerCase());
- };
-
- React.useEffect(() => {
- if (searchTerm === '' && mixnodes?.data) {
- setFilteredMixnodes(mixnodes?.data);
- } else {
- const filtered = mixnodes?.data?.filter((m) => {
- if (
- m.location?.country_name.toLowerCase().includes(searchTerm) ||
- m.mix_node.identity_key.toLocaleLowerCase().includes(searchTerm) ||
- m.owner.toLowerCase().includes(searchTerm)
- ) {
- return m;
- }
- return null;
- });
- if (filtered) {
- setFilteredMixnodes(filtered);
- }
- }
- }, [searchTerm, mixnodes?.data, mixnodes?.isLoading]);
-
- React.useEffect(() => {
- // when the status changes, get the mixnodes
- fetchMixnodes(toMixnodeStatus(status));
- }, [status]);
-
- const handleMixnodeStatusChanged = (newStatus?: MixnodeStatusWithAll) => {
- navigate(
- newStatus && newStatus !== MixnodeStatusWithAll.all
- ? `/network-components/mixnodes/${newStatus}`
- : '/network-components/mixnodes',
- );
- };
-
- const handleOnDelegate = ({ identityKey, mixId }: { identityKey: string; mixId: number }) => {
- if (!isWalletConnected) {
- setConfirmationModalProps({
- status: 'info',
- message: 'Please connect your wallet to delegate',
- });
- } else {
- setItemSelectedForDelegation({ identityKey, mixId });
- }
- };
-
- const columns: GridColDef[] = [
- {
- field: 'delegate',
- disableColumnMenu: true,
- disableReorder: true,
- sortable: false,
- width: isMobile ? 25 : 100,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderHeader: () => null,
- renderCell: (params: GridRenderCellParams) => (
- handleOnDelegate({ identityKey: params.row.identity_key, mixId: params.row.mix_id })}
- />
- ),
- },
- {
- field: 'identity_key',
- width: 325,
- headerName: 'Identity Key',
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
-
-
- {splice(7, 29, params.value)}
-
-
- ),
- },
- {
- field: 'mix_id',
- width: 85,
- align: 'center',
- hide: true,
- headerName: 'Mix ID',
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
- {params.value}
-
- ),
- },
-
- {
- field: 'bond',
- width: 150,
- align: 'left',
- type: 'number',
- disableColumnMenu: true,
- headerName: 'Stake',
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
- {currencyToString({ amount: params.value })}
-
- ),
- },
- {
- field: 'stake_saturation',
- width: 185,
- align: 'center',
- headerName: 'Stake Saturation',
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => (
-
- ),
- renderCell: (params: GridRenderCellParams) => (
- {`${params.value} %`}
- ),
- },
- {
- field: 'pledge_amount',
- width: 150,
- align: 'left',
- type: 'number',
- headerName: 'Bond',
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
- {currencyToString({ amount: params.value })}
-
- ),
- },
- {
- field: 'profit_percentage',
- width: 145,
- align: 'center',
- headerName: 'Profit Margin',
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => (
-
- ),
- renderCell: (params: GridRenderCellParams) => (
- {`${params.value}%`}
- ),
- },
- {
- field: 'operating_cost',
- width: 170,
- align: 'center',
- headerName: 'Operating Cost',
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => (
-
- ),
- renderCell: (params: GridRenderCellParams) => (
- {`${params.value} NYM`}
- ),
- },
- {
- field: 'node_performance',
- width: 165,
- align: 'center',
- headerName: 'Routing Score',
- headerAlign: 'center',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => (
-
- ),
- renderCell: (params: GridRenderCellParams) => (
- {`${params.value}%`}
- ),
- },
- {
- field: 'owner',
- width: 120,
- headerName: 'Owner',
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
- {splice(7, 29, params.value)}
-
- ),
- },
- {
- field: 'location',
- width: 150,
- headerName: 'Location',
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
- handleSearch(params.value)}
- >
- {params.value}
-
-
- ),
- },
- {
- field: 'host',
- width: 130,
- headerName: 'Host',
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- disableColumnMenu: true,
- renderHeader: () => ,
- renderCell: (params: GridRenderCellParams) => (
-
- {params.value}
-
- ),
- },
- ];
-
- const handlePageSize = (event: SelectChangeEvent) => {
- setPageSize(event.target.value);
- };
-
- return (
-
-
-
-
-
-
-
-
- }
- childrenAfter={
- isWalletConnected && (
-
- )
- }
- onChangeSearch={handleSearch}
- onChangePageSize={handlePageSize}
- pageSize={pageSize}
- searchTerm={searchTerm}
- withFilters
- />
-
-
-
-
-
- {itemSelectedForDelegation && (
- {
- setItemSelectedForDelegation(undefined);
- }}
- header="Delegate"
- buttonText="Delegate stake"
- denom="nym"
- onOk={(delegationModalProps: DelegationModalProps) => handleNewDelegation(delegationModalProps)}
- identityKey={itemSelectedForDelegation.identityKey}
- mixId={itemSelectedForDelegation.mixId}
- />
- )}
-
- {confirmationModalProps && (
- {
- setConfirmationModalProps(undefined);
- if (confirmationModalProps.status === 'success') {
- navigate('/delegations');
- }
- }}
- sx={{
- width: {
- xs: '90%',
- sm: 600,
- },
- }}
- />
- )}
-
- );
-};
diff --git a/explorer/src/pages/MixnodesMap/index.tsx b/explorer/src/pages/MixnodesMap/index.tsx
deleted file mode 100644
index a7c0048a11..0000000000
--- a/explorer/src/pages/MixnodesMap/index.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import * as React from 'react';
-import { Alert, Box, CircularProgress, Grid, SelectChangeEvent, Typography } from '@mui/material';
-import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
-import { ContentCard } from '../../components/ContentCard';
-import { CustomColumnHeading } from '../../components/CustomColumnHeading';
-import { TableToolbar } from '../../components/TableToolbar';
-import { Title } from '../../components/Title';
-import { UniversalDataGrid } from '../../components/Universal-DataGrid';
-import { WorldMap } from '../../components/WorldMap';
-import { useMainContext } from '../../context/main';
-import { CountryDataRowType, countryDataToGridRow } from '../../utils';
-
-export const PageMixnodesMap: FCWithChildren = () => {
- const { countryData } = useMainContext();
- const [pageSize, setPageSize] = React.useState('10');
- const [formattedCountries, setFormattedCountries] = React.useState([]);
- const [searchTerm, setSearchTerm] = React.useState('');
-
- const handleSearch = (str: string) => {
- setSearchTerm(str.toLowerCase());
- };
-
- const handlePageSize = (event: SelectChangeEvent) => {
- setPageSize(event.target.value);
- };
-
- const columns: GridColDef[] = [
- {
- field: 'countryName',
- renderHeader: () => ,
- flex: 1,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => {params.value},
- },
- {
- field: 'nodes',
- renderHeader: () => ,
- flex: 1,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => (
- {params.value}
- ),
- },
- {
- field: 'percentage',
- renderHeader: () => ,
- flex: 1,
- headerAlign: 'left',
- headerClassName: 'MuiDataGrid-header-override',
- renderCell: (params: GridRenderCellParams) => {params.value},
- },
- ];
-
- React.useEffect(() => {
- if (countryData?.data && searchTerm === '') {
- setFormattedCountries(countryDataToGridRow(Object.values(countryData.data)));
- } else if (countryData?.data !== undefined && searchTerm !== '') {
- const formatted = countryDataToGridRow(Object.values(countryData?.data));
- const filtered = formatted.filter(
- (m) => m?.countryName?.toLowerCase().includes(searchTerm) || m?.ISO3?.toLowerCase().includes(searchTerm),
- );
- if (filtered) {
- setFormattedCountries(filtered);
- }
- }
- }, [searchTerm, countryData?.data]);
-
- if (countryData?.isLoading) {
- return ;
- }
-
- if (countryData?.data && !countryData.isLoading) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-
- if (countryData?.error) {
- return {countryData.error.message};
- }
-
- return null;
-};
diff --git a/explorer/src/pages/Overview/index.tsx b/explorer/src/pages/Overview/index.tsx
deleted file mode 100644
index 9bc2ebade7..0000000000
--- a/explorer/src/pages/Overview/index.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-import * as React from 'react';
-import { Box, Grid, Link, Typography } from '@mui/material';
-import OpenInNewIcon from '@mui/icons-material/OpenInNew';
-import { useTheme } from '@mui/material/styles';
-import { useNavigate } from 'react-router-dom';
-import { PeopleAlt } from '@mui/icons-material';
-import { WorldMap } from '../../components/WorldMap';
-import { useMainContext } from '../../context/main';
-import { formatNumber } from '../../utils';
-import { BIG_DIPPER } from '../../api/constants';
-import { ValidatorsSVG } from '../../icons/ValidatorsSVG';
-import { GatewaysSVG } from '../../icons/GatewaysSVG';
-import { MixnodesSVG } from '../../icons/MixnodesSVG';
-import { Title } from '../../components/Title';
-import { ContentCard } from '../../components/ContentCard';
-import { StatsCard } from '../../components/StatsCard';
-import { Icons } from '../../components/Icons';
-
-export const PageOverview: FCWithChildren = () => {
- const theme = useTheme();
- const navigate = useNavigate();
- const { summaryOverview, gateways, validators, block, countryData, serviceProviders } = useMainContext();
- return (
-
-
-
-
-
-
-
- {summaryOverview && (
- <>
-
- navigate('/network-components/mixnodes')}
- title="Mixnodes"
- icon={}
- count={summaryOverview.data?.mixnodes.count || ''}
- errorMsg={summaryOverview?.error}
- />
-
-
- navigate('/network-components/mixnodes/active')}
- title="Active nodes"
- icon={}
- color={theme.palette.nym.networkExplorer.mixnodes.status.active}
- count={summaryOverview.data?.mixnodes.activeset.active}
- errorMsg={summaryOverview?.error}
- />
-
-
- navigate('/network-components/mixnodes/standby')}
- title="Standby nodes"
- color={theme.palette.nym.networkExplorer.mixnodes.status.standby}
- icon={}
- count={summaryOverview.data?.mixnodes.activeset.standby}
- errorMsg={summaryOverview?.error}
- />
-
- >
- )}
- {gateways && (
-
- navigate('/network-components/gateways')}
- title="Gateways"
- count={gateways?.data?.length || ''}
- errorMsg={gateways?.error}
- icon={}
- />
-
- )}
- {serviceProviders && (
-
- navigate('/network-components/service-providers')}
- title="Service providers"
- icon={}
- count={serviceProviders.data?.length}
- errorMsg={summaryOverview?.error}
- />
-
- )}
- {validators && (
-
- window.open(`${BIG_DIPPER}/validators`)}
- title="Validators"
- count={validators?.data?.count || ''}
- errorMsg={validators?.error}
- icon={}
- />
-
- )}
- {block?.data && (
-
-
-
- Current block height is {formatNumber(block.data)}
-
-
-
-
- )}
-
-
-
-
-
-
-
-
-
- );
-};
diff --git a/explorer/src/pages/ServiceProviders/index.tsx b/explorer/src/pages/ServiceProviders/index.tsx
deleted file mode 100644
index 618aa72924..0000000000
--- a/explorer/src/pages/ServiceProviders/index.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import React from 'react';
-import { Box, Button, Card, FormControl, Grid, ListItem, Menu, SelectChangeEvent, Typography } from '@mui/material';
-import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
-import { TableToolbar } from '../../components/TableToolbar';
-import { Title } from '../../components/Title';
-import { UniversalDataGrid } from '../../components/Universal-DataGrid';
-import { useMainContext } from '../../context/main';
-import { CustomColumnHeading } from '../../components/CustomColumnHeading';
-
-const columns: GridColDef[] = [
- {
- headerName: 'Client ID',
- field: 'address',
- disableColumnMenu: true,
- flex: 3,
- },
- {
- headerName: 'Type',
- field: 'service_type',
- disableColumnMenu: true,
- flex: 1,
- },
- {
- headerName: 'Routing score',
- field: 'routing_score',
- disableColumnMenu: true,
- flex: 2,
- sortingOrder: ['asc', 'desc'],
- sortComparator: (a?: string, b?: string) => {
- if (!a) return -1; // Place undefined values at the end
- if (!b) return 1; // Place undefined values at the end
-
- const aToNum = parseInt(a, 10);
- const bToNum = parseInt(b, 10);
-
- if (aToNum > bToNum) return 1;
-
- return -1; // Sort numbers in ascending order
- },
- renderCell: (params: GridRenderCellParams) => (!params.value ? '-' : params.value),
- renderHeader: () => (
-
- ),
- },
-];
-
-const SupportedApps = () => {
- const [anchorEl, setAnchorEl] = React.useState(null);
- const open = Boolean(anchorEl);
- const handleClick = (event: React.MouseEvent) => {
- setAnchorEl(event.currentTarget);
- };
- const handleClose = () => {
- setAnchorEl(null);
- };
- const anchorRef = React.useRef(null);
-
- return (
-
-
-
-
- );
-};
-
-export const ServiceProviders = () => {
- const { serviceProviders } = useMainContext();
- const [pageSize, setPageSize] = React.useState('10');
-
- const handleOnPageSizeChange = (event: SelectChangeEvent) => {
- setPageSize(event.target.value);
- };
-
- return (
- <>
-
-
-
-
-
-
- {serviceProviders?.data ? (
- <>
- }
- />
-
- >
- ) : (
- No service providers to display
- )}
-
-
-
- >
- );
-};
diff --git a/explorer/src/routes/index.tsx b/explorer/src/routes/index.tsx
deleted file mode 100644
index 67ef8b4621..0000000000
--- a/explorer/src/routes/index.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as React from 'react';
-import { Routes as ReactRouterRoutes, Route } from 'react-router-dom';
-import { Delegations } from '@src/pages/Delegations';
-import { PageOverview } from '../pages/Overview';
-import { PageMixnodesMap } from '../pages/MixnodesMap';
-import { Page404 } from '../pages/404';
-import { NetworkComponentsRoutes } from './network-components';
-
-export const Routes: FCWithChildren = () => (
-
- } />
- } />
- } />
- } />
- } />
-
-);
diff --git a/explorer/src/routes/network-components.tsx b/explorer/src/routes/network-components.tsx
deleted file mode 100644
index 266a75aa2f..0000000000
--- a/explorer/src/routes/network-components.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as React from 'react';
-import { Routes as ReactRouterRoutes, Route, useNavigate } from 'react-router-dom';
-import { BIG_DIPPER } from '../api/constants';
-import { PageGateways } from '../pages/Gateways';
-import { PageGatewayDetail } from '../pages/GatewayDetail';
-import { PageMixnodeDetail } from '../pages/MixnodeDetail';
-import { PageMixnodes } from '../pages/Mixnodes';
-import { ServiceProviders } from '../pages/ServiceProviders';
-
-const ValidatorRoute: FCWithChildren = () => {
- const navigate = useNavigate();
- window.open(`${BIG_DIPPER}/validators`);
- navigate(-1);
- return null;
-};
-
-export const NetworkComponentsRoutes: FCWithChildren = () => (
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-);
diff --git a/explorer/src/stories/Introduction.stories.mdx b/explorer/src/stories/Introduction.stories.mdx
deleted file mode 100644
index dafab13de0..0000000000
--- a/explorer/src/stories/Introduction.stories.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Meta } from '@storybook/addon-docs';
-
-
-
-# Nym Network Explorer Storybook
-
-This is the Storybook for the Nym Network Explorer.
diff --git a/explorer/src/styles.css b/explorer/src/styles.css
deleted file mode 100644
index 818211ccea..0000000000
--- a/explorer/src/styles.css
+++ /dev/null
@@ -1,30 +0,0 @@
-/* last resort for styles that cannot be handled by Material UI and Emotion JS */
-
-/* TODO - this override should take place in either
-the theme declaration in index.tsx or the style prop
-in */
-
-.MuiDataGrid-columnSeparator {
- visibility: hidden;
-}
-
-/* TODO - this should be managed somehow in MUI DataGrid
-but documentation doesnt offer a way to do it. Possibly only
-included in Data Grid Pro package */
-.MuiDataGrid-header-override {
- height: 55px;
- min-height: 55px;
-}
-
-/* Again, no offered way to add sx to this specific div to kill the padding
-which puts it out of sync with other (sx styled) cells */
-div div.MuiDataGrid-root .MuiDataGrid-columnHeaderTitleContainer {
- padding-left: 0;
-}
-
-@media screen and (max-width: 900px) {
- .MuiDrawer-paperAnchorLeft {
- min-width: 100vw;
- margin-top: 58px;
- }
-}
diff --git a/explorer/src/tests/Nav.test.tsx b/explorer/src/tests/Nav.test.tsx
deleted file mode 100644
index c3e5e949d0..0000000000
--- a/explorer/src/tests/Nav.test.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import React, { render } from '@testing-library/react';
-import '@testing-library/jest-dom/extend-expect';
-import { Nav } from '../components/Nav';
-
-describe('Nav', () => {
- beforeEach(() => {
- render();
- });
- it('should render without exploding', () => {
- const { container } = render();
- expect(container.firstChild).toBeInTheDocument();
- });
-});
diff --git a/explorer/src/tests/WorldMap.test.tsx b/explorer/src/tests/WorldMap.test.tsx
deleted file mode 100644
index 1a5b37d25d..0000000000
--- a/explorer/src/tests/WorldMap.test.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React, { render, screen } from '@testing-library/react';
-import '@testing-library/jest-dom/extend-expect';
-import { WorldMap } from '../components/WorldMap';
-
-describe('WorldMap', () => {
- beforeEach(() => {
- render();
- });
- it('should render without exploding', () => {
- const { container } = render();
- expect(container.firstChild).toBeInTheDocument();
- });
- it('should render the expected container/child element', () => {
- expect(screen.getByTestId('worldMap__container')).toBeInTheDocument();
- });
- it('should render the title', () => {
- expect(screen.getByText('mix-nodes around the globe')).toBeTruthy();
- });
- it('should render the map/SVG', () => {
- expect(screen.getByTestId('svg')).toBeInTheDocument();
- });
- it('should render map at correct size/dims', () => {
- const expectedWidth = '1000';
- const expectedHeight = '800';
- expect(screen.getByTestId('svg')).toHaveAttribute('width', expectedWidth);
- expect(screen.getByTestId('svg')).toHaveAttribute('height', expectedHeight);
- });
-});
diff --git a/explorer/src/tests/todo.test.ts b/explorer/src/tests/todo.test.ts
deleted file mode 100644
index 0580a22ccc..0000000000
--- a/explorer/src/tests/todo.test.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-describe('testing jest config', () => {
- test('jest works with typescript', () => {
- const foo = () => 42;
-
- expect(foo()).toBe(42);
- });
-});
diff --git a/explorer/src/theme/index.tsx b/explorer/src/theme/index.tsx
deleted file mode 100644
index 3542bd9c9a..0000000000
--- a/explorer/src/theme/index.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import * as React from 'react';
-import { NymNetworkExplorerThemeProvider } from '@nymproject/mui-theme';
-import { useMainContext } from '../context/main';
-
-export const NetworkExplorerThemeProvider: FCWithChildren = ({ children }) => {
- const { mode } = useMainContext();
- return {children};
-};
diff --git a/explorer/src/theme/mui-theme.d.ts b/explorer/src/theme/mui-theme.d.ts
deleted file mode 100644
index fc1f856f91..0000000000
--- a/explorer/src/theme/mui-theme.d.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/* eslint-disable no-shadow,@typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-interface,import/no-extraneous-dependencies */
-import { Theme, ThemeOptions, Palette, PaletteOptions } from '@mui/material/styles';
-import { NymTheme, NymPaletteWithExtensions, NymPaletteWithExtensionsOptions } from '@nymproject/mui-theme';
-
-/**
- * If you are unfamiliar with Material UI theming, please read the following first:
- * - https://mui.com/customization/theming/
- * - https://mui.com/customization/palette/
- * - https://mui.com/customization/dark-mode/#dark-mode-with-custom-palette
- *
- * This file adds typings to the theme using Typescript's module augmentation.
- *
- * Read the following if you are unfamiliar with module augmentation and declaration merging. Then
- * look at the recommendations from Material UI docs for implementation:
- * - https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
- * - https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces
- * - https://mui.com/customization/palette/#adding-new-colors
- *
- *
- * IMPORTANT:
- *
- * The type augmentation must match MUI's definitions. So, notice the use of `interface` rather than
- * `type Foo = { ... }` - this is necessary to merge the definitions.
- */
-
-declare module '@mui/material/styles' {
- /**
- * This augments the definitions of the MUI Theme with the Nym theme, as well as
- * a partial `ThemeOptions` type used by `createTheme`
- *
- * IMPORTANT: only add extensions to the interfaces above, do not modify the lines below
- */
- interface Theme extends NymTheme {}
- interface ThemeOptions extends Partial {}
- interface Palette extends NymPaletteWithExtensions {}
- interface PaletteOptions extends NymPaletteWithExtensionsOptions {}
-}
diff --git a/explorer/src/typeDefs/explorer-api.ts b/explorer/src/typeDefs/explorer-api.ts
deleted file mode 100644
index 9319c33952..0000000000
--- a/explorer/src/typeDefs/explorer-api.ts
+++ /dev/null
@@ -1,277 +0,0 @@
-/* eslint-disable camelcase */
-
-export interface ClientConfig {
- url: string;
- version: string;
-}
-
-export interface SummaryOverviewResponse {
- mixnodes: {
- count: number;
- activeset: {
- active: number;
- standby: number;
- inactive: number;
- };
- };
- gateways: {
- count: number;
- };
- validators: {
- count: number;
- };
-}
-
-export interface MixNode {
- host: string;
- mix_port: number;
- http_api_port: number;
- verloc_port: number;
- sphinx_key: string;
- identity_key: string;
- version: string;
- location: string;
-}
-
-export interface Gateway {
- host: string;
- mix_port: number;
- clients_port: number;
- location: string;
- sphinx_key: string;
- identity_key: string;
- version: string;
-}
-
-export interface Amount {
- denom: string;
- amount: number;
-}
-
-export enum MixnodeStatus {
- active = 'active', // in both the active set and the rewarded set
- standby = 'standby', // only in the rewarded set
- inactive = 'inactive', // in neither the rewarded set nor the active set
-}
-
-export enum MixnodeStatusWithAll {
- active = 'active', // in both the active set and the rewarded set
- standby = 'standby', // only in the rewarded set
- inactive = 'inactive', // in neither the rewarded set nor the active set
- all = 'all', // any status
-}
-
-export const toMixnodeStatus = (status?: MixnodeStatusWithAll): MixnodeStatus | undefined => {
- if (!status || status === MixnodeStatusWithAll.all) {
- return undefined;
- }
- return status as unknown as MixnodeStatus;
-};
-
-export interface MixNodeResponseItem {
- mix_id: number;
- pledge_amount: Amount;
- total_delegation: Amount;
- owner: string;
- layer: string;
- status: MixnodeStatus;
- location: {
- country_name: string;
- latitude?: number;
- longitude?: number;
- three_letter_iso_country_code: string;
- two_letter_iso_country_code: string;
- };
- mix_node: MixNode;
- avg_uptime: number;
- node_performance: NodePerformance;
- stake_saturation: number;
- uncapped_saturation: number;
- operating_cost: Amount;
- profit_margin_percent: string;
- blacklisted: boolean;
-}
-
-export type MixNodeResponse = MixNodeResponseItem[];
-
-export interface MixNodeReportResponse {
- identity: string;
- owner: string;
- most_recent_ipv4: boolean;
- most_recent_ipv6: boolean;
- last_hour_ipv4: number;
- last_hour_ipv6: number;
- last_day_ipv4: number;
- last_day_ipv6: number;
-}
-
-export interface StatsResponse {
- update_time: Date;
- previous_update_time: Date;
- packets_received_since_startup: number;
- packets_sent_since_startup: number;
- packets_explicitly_dropped_since_startup: number;
- packets_received_since_last_update: number;
- packets_sent_since_last_update: number;
- packets_explicitly_dropped_since_last_update: number;
-}
-
-export interface NodePerformance {
- most_recent: string;
- last_hour: string;
- last_24h: string;
-}
-
-export type MixNodeHistoryResponse = StatsResponse;
-
-export interface GatewayBond {
- block_height: number;
- pledge_amount: Amount;
- total_delegation: Amount;
- owner: string;
- gateway: Gateway;
- node_performance: NodePerformance;
- location?: Location;
-}
-
-export interface GatewayBondAnnotated {
- gateway_bond: GatewayBond;
- node_performance: NodePerformance;
-}
-
-export interface Location {
- two_letter_iso_country_code: string;
- three_letter_iso_country_code: string;
- country_name: string;
- latitude?: number;
- longitude?: number;
-}
-
-export interface LocatedGateway {
- pledge_amount: Amount;
- owner: string;
- block_height: number;
- gateway: Gateway;
- proxy?: string;
- location?: Location;
-}
-
-export type GatewayResponse = GatewayBond[];
-
-export interface GatewayReportResponse {
- identity: string;
- owner: string;
- most_recent: number;
- last_hour: number;
- last_day: number;
-}
-
-export type GatewayHistoryResponse = StatsResponse;
-
-export interface MixNodeDescriptionResponse {
- name: string;
- description: string;
- link: string;
- location: string;
-}
-
-export type MixNodeStatsResponse = StatsResponse;
-
-export interface Validator {
- address: string;
- proposer_priority: string;
- pub_key: {
- type: string;
- value: string;
- };
-}
-export interface ValidatorsResponse {
- block_height: number;
- count: string;
- total: string;
- validators: Validator[];
-}
-
-export type CountryData = {
- ISO3: string;
- nodes: number;
-};
-
-export type Delegation = {
- owner: string;
- amount: Amount;
- block_height: number;
-};
-
-export type DelegationUniq = {
- owner: string;
- amount: Amount;
-};
-
-export type DelegationsResponse = Delegation[];
-
-export type UniqDelegationsResponse = DelegationUniq[];
-
-export interface CountryDataResponse {
- [threeLetterCountryCode: string]: CountryData;
-}
-
-export type BlockType = number;
-export type BlockResponse = BlockType;
-
-export interface ApiState {
- isLoading: boolean;
- data?: RESPONSE;
- error?: Error;
-}
-
-export type StatusResponse = {
- pending: boolean;
- ports: {
- 1789: boolean;
- 1790: boolean;
- 8000: boolean;
- };
-};
-
-export type UptimeTime = {
- date: string;
- uptime: number;
-};
-
-export type UptimeStoryResponse = {
- history: UptimeTime[];
- identity: string;
- owner: string;
-};
-
-export type MixNodeEconomicDynamicsStatsResponse = {
- stake_saturation: number;
- uncapped_saturation: number;
- // TODO: when v2 will be deployed, remove cases: VeryHigh, Moderate and VeryLow
- active_set_inclusion_probability: 'High' | 'Good' | 'Low';
- reserve_set_inclusion_probability: 'High' | 'Good' | 'Low';
- estimated_total_node_reward: number;
- estimated_operator_reward: number;
- estimated_delegators_reward: number;
- current_interval_uptime: number;
-};
-
-export type Environment = 'mainnet' | 'sandbox' | 'qa';
-
-export type ServiceProviderType = 'Network Requester';
-
-export type DirectoryServiceProvider = {
- id: string;
- description: string;
- address: string;
- gateway: string;
- routing_score: string | null;
- service_type: ServiceProviderType;
-};
-
-export type DirectoryService = {
- id: string;
- description: string;
- items: DirectoryServiceProvider[];
-};
diff --git a/explorer/src/typeDefs/filters.ts b/explorer/src/typeDefs/filters.ts
deleted file mode 100644
index 53de60cb87..0000000000
--- a/explorer/src/typeDefs/filters.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { Mark } from '@mui/base';
-
-export enum EnumFilterKey {
- profitMargin = 'profitMargin',
- stakeSaturation = 'stakeSaturation',
- routingScore = 'routingScore',
-}
-
-export type TFilterItem = {
- label: string;
- id: EnumFilterKey;
- value: number[];
- isSmooth?: boolean;
- marks: Mark[];
- min?: number;
- max?: number;
- scale?: (value: number) => number;
- tooltipInfo?: string;
-};
-
-export type TFilters = { [key in EnumFilterKey]: TFilterItem };
diff --git a/explorer/src/typeDefs/network.ts b/explorer/src/typeDefs/network.ts
deleted file mode 100644
index f8615cd992..0000000000
--- a/explorer/src/typeDefs/network.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type Network = 'QA' | 'SANDBOX' | 'MAINNET';
diff --git a/explorer/src/typeDefs/tables.ts b/explorer/src/typeDefs/tables.ts
deleted file mode 100644
index 1ab2ffead4..0000000000
--- a/explorer/src/typeDefs/tables.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export type TableHeading = {
- id: string;
- numeric: boolean;
- disablePadding: boolean;
- label: string;
-};
-
-export type TableHeadingsType = TableHeading[];
diff --git a/explorer/src/typings/FC.d.ts b/explorer/src/typings/FC.d.ts
deleted file mode 100644
index 08ebdfa298..0000000000
--- a/explorer/src/typings/FC.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare type FCWithChildren = React.FC>;
diff --git a/explorer/src/typings/jpeg.d.ts b/explorer/src/typings/jpeg.d.ts
deleted file mode 100644
index af2ed72913..0000000000
--- a/explorer/src/typings/jpeg.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-declare module '*.jpeg' {
- const value: any;
- export default value;
-}
-
-declare module '*.jpg' {
- const value: any;
- export default value;
-}
diff --git a/explorer/src/typings/json.d.ts b/explorer/src/typings/json.d.ts
deleted file mode 100644
index b72dd46ee5..0000000000
--- a/explorer/src/typings/json.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '*.json' {
- const content: any;
- export default content;
-}
diff --git a/explorer/src/typings/png.d.ts b/explorer/src/typings/png.d.ts
deleted file mode 100644
index dd84df40a4..0000000000
--- a/explorer/src/typings/png.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '*.png' {
- const content: any;
- export default content;
-}
diff --git a/explorer/src/typings/react-identicons.d.ts b/explorer/src/typings/react-identicons.d.ts
deleted file mode 100644
index 6c460eff99..0000000000
--- a/explorer/src/typings/react-identicons.d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-declare module 'react-identicons' {
- import * as React from 'react';
-
- interface IdenticonProps {
- string: string;
- size?: number;
- padding?: number;
- bg?: string;
- fg?: string;
- palette?: string[];
- count?: number;
- // getColor: Function;
- }
-
- declare function Identicon(props: IdenticonProps): React.ReactElement;
-
- export default Identicon;
-}
diff --git a/explorer/src/typings/react-tooltip.d.ts b/explorer/src/typings/react-tooltip.d.ts
deleted file mode 100644
index 98cb6d592d..0000000000
--- a/explorer/src/typings/react-tooltip.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module 'react-tooltip';
diff --git a/explorer/src/typings/svg.d.ts b/explorer/src/typings/svg.d.ts
deleted file mode 100644
index 091d25e210..0000000000
--- a/explorer/src/typings/svg.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '*.svg' {
- const content: any;
- export default content;
-}
diff --git a/explorer/src/utils/currency.ts b/explorer/src/utils/currency.ts
deleted file mode 100644
index ad6ed1f165..0000000000
--- a/explorer/src/utils/currency.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { printableCoin } from '@nymproject/nym-validator-client';
-import Big from 'big.js';
-import { DecCoin, isValidRawCoin } from '@nymproject/types';
-
-const DENOM = process.env.CURRENCY_DENOM || 'unym';
-const DENOM_STAKING = process.env.CURRENCY_STAKING_DENOM || 'unyx';
-
-export const toDisplay = (val: string | number | Big, dp = 4) => {
- let displayValue;
- try {
- displayValue = Big(val).toFixed(dp);
- } catch (e: any) {
- console.warn(`${displayValue} not a valid decimal number: ${e}`);
- }
- return displayValue;
-};
-
-export const currencyToString = ({ amount, dp, denom = DENOM }: { amount: string; dp?: number; denom?: string }) => {
- if (!dp) {
- printableCoin({
- amount,
- denom,
- });
- }
-
- const [printableAmount, printableDenom] = printableCoin({
- amount,
- denom,
- }).split(/\s+/);
-
- return `${toDisplay(printableAmount, dp)} ${printableDenom}`;
-};
-
-export const stakingCurrencyToString = (amount: string, denom: string = DENOM_STAKING) =>
- printableCoin({
- amount,
- denom,
- });
-
-/**
- * Converts a decimal number to a pretty representation
- * with fixed decimal places.
- *
- * @param val - a decimal number of string form
- * @param dp - number of decimal places (4 by default ie. 0.0000)
- * @returns A prettyfied decimal number
- */
-
-/**
- * Converts a decimal number of μNYM (micro NYM) to NYM.
- *
- * @param unym - a decimal number of μNYM
- * @param dp - number of decimal places (4 by default ie. 0.0000)
- * @returns The corresponding decimal number in NYM
- */
-export const unymToNym = (unym: string | number | Big, dp = 4) => {
- let nym;
- try {
- nym = Big(unym).div(1_000_000).toFixed(dp);
- } catch (e: any) {
- console.warn(`${unym} not a valid decimal number: ${e}`);
- }
- return nym;
-};
-
-export const validateAmount = async (
- majorAmountAsString: DecCoin['amount'],
- minimumAmountAsString: DecCoin['amount'],
-): Promise => {
- // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc
- if (!Number(majorAmountAsString)) {
- return false;
- }
-
- if (!isValidRawCoin(majorAmountAsString)) {
- return false;
- }
-
- const majorValueFloat = parseInt(majorAmountAsString, Number(10));
-
- return majorValueFloat >= parseInt(minimumAmountAsString, Number(10));
-};
-
-/**
- * Takes a DecCoin and prettify its amount to a representation
- * with fixed decimal places.
- *
- * @param coin - a DecCoin
- * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000)
- * @returns A DecCoin with prettified amount
- */
-export const decCoinToDisplay = (coin: DecCoin, dp = 4) => {
- const displayCoin = { ...coin };
- try {
- displayCoin.amount = Big(coin.amount).toFixed(dp);
- } catch (e: any) {
- console.warn(`${coin.amount} not a valid decimal number: ${e}`);
- }
- return displayCoin;
-};
diff --git a/explorer/src/utils/index.ts b/explorer/src/utils/index.ts
deleted file mode 100644
index 91b082c5ca..0000000000
--- a/explorer/src/utils/index.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-/* eslint-disable camelcase */
-import { MutableRefObject } from 'react';
-import { Theme } from '@mui/material/styles';
-import { registerLocale, getName } from 'i18n-iso-countries';
-import Big from 'big.js';
-import { CountryData } from '../typeDefs/explorer-api';
-import { EconomicsRowsType } from '../components/MixNodes/Economics/types';
-import { Network } from '../typeDefs/network';
-
-registerLocale(require('i18n-iso-countries/langs/en.json'));
-
-export function formatNumber(num: number): string {
- return new Intl.NumberFormat().format(num);
-}
-
-export function scrollToRef(ref: MutableRefObject): void {
- if (ref?.current) ref.current.scrollIntoView();
-}
-
-export type CountryDataRowType = {
- id: number;
- ISO3: string;
- nodes: number;
- countryName: string;
- percentage: string;
-};
-
-export function countryDataToGridRow(countriesData: CountryData[]): CountryDataRowType[] {
- const totalNodes = countriesData.reduce((acc, obj) => acc + obj.nodes, 0);
- const formatted = countriesData.map((each: CountryData, index: number) => {
- const updatedCountryRecord: CountryDataRowType = {
- ...each,
- id: index,
- countryName: getName(each.ISO3, 'en', { select: 'alias' }),
- percentage: ((each.nodes * 100) / totalNodes).toFixed(1),
- };
- return updatedCountryRecord;
- });
-
- const sorted = formatted.sort((a, b) => (a.nodes < b.nodes ? 1 : -1));
- return sorted;
-}
-
-export const splice = (start: number, deleteCount: number, address?: string): string => {
- if (address) {
- const array = address.split('');
- array.splice(start, deleteCount, '...');
- return array.join('');
- }
- return '';
-};
-
-export const trimAddress = (address = '', trimBy = 6) => `${address.slice(0, trimBy)}...${address.slice(-trimBy)}`;
-
-/**
- * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100).
- *
- * @param value - the percentage to convert
- * @returns A stringified integer
- */
-export const toPercentIntegerString = (value: string) => Math.round(Number(value) * 100).toString();
-export const toPercentInteger = (value: string) => Math.round(Number(value) * 100);
-
-export const textColour = (value: EconomicsRowsType, field: string, theme: Theme) => {
- const progressBarValue = value?.progressBarValue || 0;
- const fieldValue = value.value;
-
- if (progressBarValue > 100) {
- return theme.palette.warning.main;
- }
- if (field === 'selectionChance') {
- // TODO: when v2 will be deployed, remove cases: VeryHigh, Moderate and VeryLow
- switch (fieldValue) {
- case 'High':
- case 'VeryHigh':
- return theme.palette.nym.networkExplorer.selectionChance.overModerate;
- case 'Good':
- case 'Moderate':
- return theme.palette.nym.networkExplorer.selectionChance.moderate;
- case 'Low':
- case 'VeryLow':
- return theme.palette.nym.networkExplorer.selectionChance.underModerate;
- default:
- return theme.palette.nym.wallet.fee;
- }
- }
- return theme.palette.nym.wallet.fee;
-};
-
-export const isGreaterThan = (a: number, b: number) => a > b;
-
-export const isLessThan = (a: number, b: number) => a < b;
-
-/**
- *
- * Checks if the user's balance is enough to pay the fee
- * @param balance - The user's current balance
- * @param fee - The fee for the tx
- * @param tx - The amount of the tx
- * @returns boolean
- *
- */
-
-export const isBalanceEnough = (fee: string, tx: string = '0', balance: string = '0') => {
- try {
- return Big(balance).gte(Big(fee).plus(Big(tx)));
- } catch (e) {
- console.log(e);
- return false;
- }
-};
-
-export const urls = (networkName?: Network) =>
- networkName === 'MAINNET'
- ? {
- mixnetExplorer: 'https://mixnet.explorers.guru/',
- blockExplorer: 'https://blocks.nymtech.net',
- networkExplorer: 'https://explorer.nymtech.net',
- }
- : {
- blockExplorer: `https://${networkName}-blocks.nymtech.net`,
- networkExplorer: `https://${networkName}-explorer.nymtech.net`,
- };
diff --git a/explorer/src/x-data-grid/LICENSE b/explorer/src/x-data-grid/LICENSE
deleted file mode 100644
index 126bc57eaa..0000000000
--- a/explorer/src/x-data-grid/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 Material-UI SAS
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/explorer/src/x-data-grid/README.md b/explorer/src/x-data-grid/README.md
deleted file mode 100644
index c163d7ceeb..0000000000
--- a/explorer/src/x-data-grid/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# @mui/x-data-grid
-
-This package is the community edition of the data grid component.
-It's part of Material-UI X, an open core extension of Material-UI, with advanced components.
-
-## Installation
-
-Install the package in your project directory with:
-
-```sh
-// with npm
-npm install @mui/x-data-grid
-
-// with yarn
-yarn add @mui/x-data-grid
-```
-
-This component has two peer dependencies that you will need to install as well.
-
-```json
-"peerDependencies": {
- "@material-ui/core": "^4.12.0 || ^5.0.0-beta.0",
- "react": "^17.0.0"
-},
-```
-
-## Documentation
-
-[The documentation](https://material-ui.com/components/data-grid/)
diff --git a/explorer/src/x-data-grid/package.json b/explorer/src/x-data-grid/package.json
deleted file mode 100644
index 46225fa760..0000000000
--- a/explorer/src/x-data-grid/package.json
+++ /dev/null
@@ -1,89 +0,0 @@
-{
- "_from": "@mui/x-data-grid",
- "_id": "@mui/x-data-grid@4.0.0",
- "_inBundle": false,
- "_integrity": "sha512-BYn7uLx5tJbMarcWltjjVArWNBdC22/2xOpq3Azhltbb3TRx3h2RLUeKwZI685xmGHmzvtu6QqaoYqQgFe/h+g==",
- "_location": "/@mui/x-data-grid",
- "_phantomChildren": {},
- "_requested": {
- "type": "tag",
- "registry": true,
- "raw": "@mui/x-data-grid",
- "name": "@mui/x-data-grid",
- "escapedName": "@mui%2fx-data-grid",
- "scope": "@mui",
- "rawSpec": "",
- "saveSpec": null,
- "fetchSpec": "latest"
- },
- "_requiredBy": [
- "#USER",
- "/"
- ],
- "_resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-4.0.0.tgz",
- "_shasum": "e9e9c33a8b86e85872c48f30f4a8de72ee819153",
- "_spec": "@mui/x-data-grid",
- "_where": "/Users/adrianthompson/Documents/nym/explorer",
- "author": {
- "name": "MUI Team"
- },
- "bugs": {
- "url": "https://github.com/mui-org/material-ui-x/issues"
- },
- "bundleDependencies": false,
- "dependencies": {
- "@material-ui/utils": "^5.0.0-beta.4",
- "clsx": "^1.1.1",
- "prop-types": "^15.7.2",
- "reselect": "^4.0.0"
- },
- "deprecated": false,
- "description": "The community edition of the data grid component (Material-UI X).",
- "engines": {
- "node": ">=12.0.0"
- },
- "files": [
- "dist/*"
- ],
- "gitHead": "940d6238fe499f027ee27e818d714f79ca40e9a5",
- "homepage": "https://material-ui.com/components/data-grid/",
- "keywords": [
- "react",
- "react-component",
- "material-ui",
- "mui",
- "react-table",
- "table",
- "datatable",
- "data-table",
- "datagrid",
- "data-grid"
- ],
- "license": "MIT",
- "main": "dist/index-cjs.js",
- "module": "dist/index-esm.js",
- "name": "@mui/x-data-grid",
- "peerDependencies": {
- "@material-ui/core": "^4.12.0 || ^5.0.0-beta.0",
- "@mui/styles": "^4.11.4 || ^5.0.0-beta.0",
- "react": "^17.0.0"
- },
- "publishConfig": {
- "access": "public"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/mui-org/material-ui-x.git",
- "directory": "packages/grid/data-grid"
- },
- "scripts": {
- "build": "cd ../ && rollup --config rollup.data-grid.config.js",
- "typescript": "tsc -p tsconfig.json"
- },
- "setupFiles": [
- "/src/setupTests.js"
- ],
- "sideEffects": false,
- "types": "dist/data-grid.d.ts",
- "version": "4.0.0"
-}
\ No newline at end of file
diff --git a/explorer/tsconfig.json b/explorer/tsconfig.json
deleted file mode 100644
index 093340052d..0000000000
--- a/explorer/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "../ts-packages/tsconfig.json",
- "compilerOptions": {
- "jsx": "react-jsx",
- "outDir": "./dist",
- "module": "CommonJS",
- "baseUrl": ".",
- "paths": {
- "@src/*": ["./src/*"],
- "@assets/*": ["../assets/*"]
- }
- },
- "include": ["./src/**/*.ts", "./src/**/*.tsx"],
- "exclude": ["node_modules", "build", "dist"]
-}
diff --git a/explorer/webpack.common.js b/explorer/webpack.common.js
deleted file mode 100644
index 7bb9cb9032..0000000000
--- a/explorer/webpack.common.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const path = require('path');
-const { mergeWithRules } = require('webpack-merge');
-const { webpackCommon } = require('@nymproject/webpack');
-
-module.exports = mergeWithRules({
- module: {
- rules: {
- test: 'match',
- use: 'replace',
- },
- },
-})(webpackCommon(__dirname), {
- entry: path.resolve(__dirname, 'src/index.tsx'),
- output: {
- path: path.resolve(__dirname, 'dist'),
- publicPath: '/',
- },
- resolve: {
- fallback: {
- fs: false,
- tls: false,
- path: false,
- http: false,
- https: false,
- stream: false,
- crypto: false,
- net: false,
- zlib: false,
- buffer: require.resolve('buffer'),
- },
- },
-});
diff --git a/explorer/webpack.config.js b/explorer/webpack.config.js
deleted file mode 100644
index 550951cb52..0000000000
--- a/explorer/webpack.config.js
+++ /dev/null
@@ -1,76 +0,0 @@
-const { mergeWithRules } = require('webpack-merge');
-const webpack = require('webpack');
-const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
-const ReactRefreshTypeScript = require('react-refresh-typescript');
-const commonConfig = require('./webpack.common');
-
-module.exports = mergeWithRules({
- module: {
- rules: {
- test: 'match',
- use: 'replace',
- },
- },
-})(commonConfig, {
- mode: 'development',
- devtool: 'inline-source-map',
- module: {
- rules: [
- {
- test: /\.m?js/,
- resolve: {
- fullySpecified: false,
- },
- },
- {
- test: /\.tsx?$/,
- use: 'ts-loader',
- exclude: /node_modules/,
- options: {
- getCustomTransformers: () => ({
- before: [ReactRefreshTypeScript()],
- }),
- // `ts-loader` does not work with HMR unless `transpileOnly` is used.
- // If you need type checking, `ForkTsCheckerWebpackPlugin` is an alternative.
- transpileOnly: true,
- },
- },
- ],
- },
- plugins: [
- new ReactRefreshWebpackPlugin(),
-
- // this can be included automatically by the dev server, however build mode fails if missing
- new webpack.HotModuleReplacementPlugin(),
- new webpack.ProvidePlugin({
- Buffer: ['buffer', 'Buffer'],
- }),
- ],
-
- target: 'web',
-
- devServer: {
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
- },
- historyApiFallback: true,
- },
-
- // recommended for faster rebuild
- optimization: {
- runtimeChunk: true,
- removeAvailableModules: false,
- removeEmptyChunks: false,
- splitChunks: false,
- },
-
- cache: {
- type: 'filesystem',
- buildDependencies: {
- // restart on config change
- config: ['./webpack.config.js'],
- },
- },
-});
diff --git a/explorer/webpack.prod.js b/explorer/webpack.prod.js
deleted file mode 100644
index 259c32a4af..0000000000
--- a/explorer/webpack.prod.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const webpack = require('webpack');
-const { mergeWithRules } = require('webpack-merge');
-const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
-const MiniCssExtractPlugin = require('mini-css-extract-plugin');
-const commonConfig = require('./webpack.common');
-
-module.exports = mergeWithRules({
- module: {
- rules: {
- test: 'match',
- use: 'replace',
- },
- },
-})(commonConfig, {
- mode: 'production',
-
- // TODO: no source maps, add back
- devtool: false,
-
- module: {
- rules: [
- {
- test: /\.m?js/,
- resolve: {
- fullySpecified: false,
- },
- },
- {
- test: /\.css$/,
- use: [MiniCssExtractPlugin.loader, 'css-loader'],
- },
- ],
- },
- optimization: {
- minimizer: [`...`, new CssMinimizerPlugin()],
- splitChunks: {
- chunks: 'all',
- },
- },
- plugins: [
- new MiniCssExtractPlugin({
- filename: '[name].[contenthash].css',
- }),
- new webpack.ProvidePlugin({
- Buffer: ['buffer', 'Buffer'],
- }),
- ],
- output: {
- pathinfo: false,
- filename: '[name].[contenthash].js',
- },
-});
diff --git a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs
index e9d76a1f75..0a487afe86 100644
--- a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs
+++ b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs
@@ -16,10 +16,6 @@ pub(crate) struct Cli {
#[clap(long, env = "NETWORK_NAME")]
pub(crate) network_name: String,
- /// Explorer api url.
- #[clap(short, long, env = "EXPLORER_API")]
- pub(crate) explorer_api: String,
-
/// Nym api url.
#[clap(short, long, env = "NYM_API")]
pub(crate) nym_api: String,
diff --git a/nym-wallet/nym-wallet-types/src/network/qa.rs b/nym-wallet/nym-wallet-types/src/network/qa.rs
index 761d08f614..8f1fe1277a 100644
--- a/nym-wallet/nym-wallet-types/src/network/qa.rs
+++ b/nym-wallet/nym-wallet-types/src/network/qa.rs
@@ -34,8 +34,6 @@ pub(crate) fn validators() -> Vec {
)]
}
-pub(crate) const EXPLORER_API: &str = "https://qa-network-explorer.qa.nymte.ch/api/";
-
pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
nym_network_defaults::NymNetworkDetails {
network_name: NETWORK_NAME.into(),
@@ -53,7 +51,6 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
},
- explorer_api: parse_optional_str(EXPLORER_API),
nym_vpn_api_url: None,
}
}
diff --git a/nym-wallet/nym-wallet-types/src/network/sandbox.rs b/nym-wallet/nym-wallet-types/src/network/sandbox.rs
index c436c9f09e..cae0140cf8 100644
--- a/nym-wallet/nym-wallet-types/src/network/sandbox.rs
+++ b/nym-wallet/nym-wallet-types/src/network/sandbox.rs
@@ -34,8 +34,6 @@ pub(crate) fn validators() -> Vec {
)]
}
-pub(crate) const EXPLORER_API: &str = "https://sandbox-explorer.nymtech.net/api/";
-
pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
nym_network_defaults::NymNetworkDetails {
network_name: NETWORK_NAME.into(),
@@ -53,7 +51,6 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
},
- explorer_api: parse_optional_str(EXPLORER_API),
nym_vpn_api_url: None,
}
}
diff --git a/tools/internal/testnet-manager/src/manager/network.rs b/tools/internal/testnet-manager/src/manager/network.rs
index 6c65eda06c..4615be274c 100644
--- a/tools/internal/testnet-manager/src/manager/network.rs
+++ b/tools/internal/testnet-manager/src/manager/network.rs
@@ -81,7 +81,6 @@ impl<'a> From<&'a LoadedNetwork> for nym_config::defaults::NymNetworkDetails {
api_url: None,
}],
contracts,
- explorer_api: None,
nym_vpn_api_url: None,
}
}
diff --git a/tools/internal/testnet-manager/src/manager/network_init.rs b/tools/internal/testnet-manager/src/manager/network_init.rs
index 8e978e4fc6..ec7bf8992a 100644
--- a/tools/internal/testnet-manager/src/manager/network_init.rs
+++ b/tools/internal/testnet-manager/src/manager/network_init.rs
@@ -38,7 +38,6 @@ impl InitCtx {
network_name: "foomp".to_string(), // does this matter?
endpoints: vec![],
contracts: Default::default(),
- explorer_api: None,
nym_vpn_api_url: None,
};
Ok(Config::try_from_nym_network_details(&network_details)?)
From ac273480f83895b7ed417bf49d14c4cfaa628f0a Mon Sep 17 00:00:00 2001
From: dynco-nym <173912580+dynco-nym@users.noreply.github.com>
Date: Thu, 12 Jun 2025 11:17:56 +0200
Subject: [PATCH 22/47] Fix CI version check (#5851)
* Fix version
* Test .rc version
* Undo cargo.toml version
* Remove comment
* Apply to statistics service
---
.github/workflows/ci-check-ns-api-version.yml | 6 ++++--
.github/workflows/ci-check-nym-stats-api-version.yml | 6 ++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/ci-check-ns-api-version.yml b/.github/workflows/ci-check-ns-api-version.yml
index 92acb50395..00ef062fc3 100644
--- a/.github/workflows/ci-check-ns-api-version.yml
+++ b/.github/workflows/ci-check-ns-api-version.yml
@@ -44,8 +44,10 @@ jobs:
echo "Tag is empty"
exit 1
fi
+ # first, list all tags for logging purposes
curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq
- exists=$(curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq --arg tag $TAG '.tags | contains([$tag])' )
+ # check if there's a matching tag
+ exists=$(curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq -r --arg tag "$TAG" 'any(.tags[]; . == $tag)' )
if [[ $exists = "true" ]]; then
echo "Version '$TAG' defined in Cargo.toml ALREADY EXISTS as tag in harbor repo"
exit 1
@@ -53,5 +55,5 @@ jobs:
echo "Version '$TAG' doesn't exist on the remote"
else
echo "Unknown output '$exists'"
- exit 1
+ exit 2
fi
diff --git a/.github/workflows/ci-check-nym-stats-api-version.yml b/.github/workflows/ci-check-nym-stats-api-version.yml
index 2bcb0bc87e..6f3eb75770 100644
--- a/.github/workflows/ci-check-nym-stats-api-version.yml
+++ b/.github/workflows/ci-check-nym-stats-api-version.yml
@@ -44,8 +44,10 @@ jobs:
echo "Tag is empty"
exit 1
fi
+ # first, list all tags for logging purposes
curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq
- exists=$(curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq --arg tag $TAG '.tags | contains([$tag])' )
+ # check if there's a matching tag
+ exists=$(curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq -r --arg tag "$TAG" 'any(.tags[]; . == $tag)' )
if [[ $exists = "true" ]]; then
echo "Version '$TAG' defined in Cargo.toml ALREADY EXISTS as tag in harbor repo"
exit 1
@@ -53,5 +55,5 @@ jobs:
echo "Version '$TAG' doesn't exist on the remote"
else
echo "Unknown output '$exists'"
- exit 1
+ exit 2
fi
From d6b3d7fc0aa558f8f8eb374c312861011baae19d Mon Sep 17 00:00:00 2001
From: import this <97586125+serinko@users.noreply.github.com>
Date: Thu, 12 Jun 2025 11:19:00 +0000
Subject: [PATCH 23/47] [DOCs/operators]: Release notes for v2025.11 cheddar
(#5852)
* bump up version
* add dev features
* add operator updates
* add updated stats
* update prebuild
---
.../outputs/api-scraping-outputs/time-now.md | 2 +-
.../docs/pages/operators/changelog.mdx | 47 +++++++++++++++++++
.../pages/operators/nodes/nym-node/setup.mdx | 10 ++--
3 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md
index ac97e28533..3ddd5e309f 100644
--- a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md
+++ b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md
@@ -1 +1 @@
-Friday, June 6th 2025, 09:33:10 UTC
+Thursday, June 12th 2025, 11:03:30 UTC
diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx
index d2a2454361..4ff68694f9 100644
--- a/documentation/docs/pages/operators/changelog.mdx
+++ b/documentation/docs/pages/operators/changelog.mdx
@@ -47,6 +47,53 @@ This page displays a full list of all the changes during our release cycle from
+## `v2025.11-cheddar`
+
+- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.11-cheddar)
+- [`nym-node`](nodes/nym-node.mdx) version `1.13.0`
+
+```sh
+nym-node
+Binary Name: nym-node
+Build Timestamp: 2025-06-10T09:41:31.291089877Z
+Build Version: 1.13.0
+Commit SHA: ef220882d4bcf0a8a703ea62f9273e017c9ebb51
+Commit Date: 2025-06-10T11:39:20.000000000+02:00
+Commit Branch: HEAD
+rustc Version: 1.86.0
+rustc Channel: stable
+cargo Profile: release
+```
+### Operators Updates & Tools
+
+- **Nym Improvement Proposals**: NIPs are being introduced, allowing us to propose changes to the Nym network and ecosystem, and decentralise governance
+- **NIP1** will outline the governance process: Its draft will be published soon for discussion
+- **NIP2** will be about reducing the stake saturation point variable, which would make reward distribution across the network more equitable
+- **Join the Operator AMA next Tuesday** for an in-depth overview of what this all means (feat Nym Chief Scientist Claudia Diaz)
+- Keep an eye on our channels for information about how to participate in the upcoming voting (no need for forum registration, we are building something new!)
+
+### Features
+
+- [Track wireguard credential retries](https://github.com/nymtech/nym/pull/5783)
+
+- [Swap a decode into a `fromrow` to please future `postgres` feature](https://github.com/nymtech/nym/pull/5785): This PR change a sqlx derive from `Decode` to `FromRow` because a future PR will bring the `postgres` feature and it doesn't like that `Decode` there
+
+- [Fix contains ticketbook function that always returned true](https://github.com/nymtech/nym/pull/5787)
+
+- [QoL: `RequestPath` trait for `http-api-client`](https://github.com/nymtech/nym/pull/5788): Those `PathSegments` in `ApiClient` weren't very user-friendly. Instead we've defined a `RequestPath` trait that allows you to also pass a good old `&str` or `String` and internally it does exactly the same sanitization as before. `PathSegments` are also fully supported to not break any existing compatibility.
+
+- [Nym Statistics API](https://github.com/nymtech/nym/pull/5800):
+ - Types for `nym-vpn-client`: It introduces `VpnClientStatsReport` which will be used by nym vpn clients to report statistics. Those types are in the monorepo because they're used by the `num-statistics-API`
+ - Nym Statistics API: Basically a `REST API` with a `postgres` backend. In this first iteration, it only accepts `VpnClientStatsReport` and stores them in its database. It optionally connects to the Nym API to confirm reports are coming from the network and attach country code to them if it's the case (exit node country code).
+
+- [Resolve 1.87 clippy warnings](https://github.com/nymtech/nym/pull/5802)
+
+- [Adjusted wallet storybook mocks to fix the build](https://github.com/nymtech/nym/pull/5804)
+
+- [Set cached storage counters to 0](https://github.com/nymtech/nym/pull/5812)
+
+- [No autoremoval of peers](https://github.com/nymtech/nym/pull/5831)
+
## `v2025.10-brie`
- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.10-brie)
diff --git a/documentation/docs/pages/operators/nodes/nym-node/setup.mdx b/documentation/docs/pages/operators/nodes/nym-node/setup.mdx
index 8c2e00052d..f46a126498 100644
--- a/documentation/docs/pages/operators/nodes/nym-node/setup.mdx
+++ b/documentation/docs/pages/operators/nodes/nym-node/setup.mdx
@@ -18,12 +18,12 @@ This documentation page provides a guide on how to set up and run a [NYM NODE](.
## Current version
```sh
-nym-node
+ym-node
Binary Name: nym-node
-Build Timestamp: 2025-05-27T10:13:18.511075453Z
-Build Version: 1.12.0
-Commit SHA: 1c6db86259d08d80e8bcfbc4fcc71ccb147fcfd0
-Commit Date: 2025-05-27T12:11:13.000000000+02:00
+Build Timestamp: 2025-06-10T09:41:31.291089877Z
+Build Version: 1.13.0
+Commit SHA: ef220882d4bcf0a8a703ea62f9273e017c9ebb51
+Commit Date: 2025-06-10T11:39:20.000000000+02:00
Commit Branch: HEAD
rustc Version: 1.86.0
rustc Channel: stable
From 0caa62796017e6f03d96fde499def7677867a4fa Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 12 Jun 2025 15:12:29 +0200
Subject: [PATCH 24/47] Fix missing await on self.close_pool_inner()
---
sqlx-pool-guard/src/lib.rs | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index d9d89eaae7..96f28f2861 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -56,18 +56,16 @@ impl SqlitePoolGuard {
// Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database.
if !self.connection_pool.is_closed() {
tracing::info!("Closing sqlite pool: {}", self.database_path.display());
- _ = self.close_pool_inner();
+ self.close_pool_inner().await.ok();
}
}
async fn close_pool_inner(&self) -> std::io::Result<()> {
self.connection_pool.close().await;
- if let Err(e) = self.wait_for_db_files_close().await {
+ self.wait_for_db_files_close().await.inspect_err(|e| {
tracing::error!("Failed to wait for file to close: {e}");
- }
-
- Ok(())
+ })
}
/// Returns all database files, including shm and wal files.
From 1d7ffc1bb62b6c294de870e55fea48fcd9b9fc08 Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 12 Jun 2025 15:39:26 +0200
Subject: [PATCH 25/47] test: remove file after closing for a test
---
sqlx-pool-guard/src/lib.rs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sqlx-pool-guard/src/lib.rs b/sqlx-pool-guard/src/lib.rs
index 96f28f2861..3dd15ee6c7 100644
--- a/sqlx-pool-guard/src/lib.rs
+++ b/sqlx-pool-guard/src/lib.rs
@@ -160,7 +160,7 @@ mod tests {
.await
.unwrap();
- let guard = SqlitePoolGuard::new(database_path, connection_pool);
+ let guard = SqlitePoolGuard::new(database_path.clone(), connection_pool);
assert!(
guard
.wait_for_db_files_close()
@@ -170,5 +170,6 @@ mod tests {
);
assert!(guard.close_pool_inner().await.is_ok());
+ tokio::fs::remove_file(database_path).await.unwrap();
}
}
From fec196c09737bb64b2a185269e444a7db1097bbd Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Thu, 12 Jun 2025 17:16:02 +0200
Subject: [PATCH 26/47] Use display when printing paths
---
common/credential-storage/src/persistent_storage/mod.rs | 4 ++--
common/gateway-stats-storage/src/lib.rs | 4 ++--
common/gateway-storage/src/lib.rs | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/common/credential-storage/src/persistent_storage/mod.rs b/common/credential-storage/src/persistent_storage/mod.rs
index 565ab94513..16a1ae9d5a 100644
--- a/common/credential-storage/src/persistent_storage/mod.rs
+++ b/common/credential-storage/src/persistent_storage/mod.rs
@@ -54,8 +54,8 @@ impl PersistentStorage {
/// * `database_path`: path to the database.
pub async fn init>(database_path: P) -> Result {
debug!(
- "Attempting to connect to database {:?}",
- database_path.as_ref().as_os_str()
+ "Attempting to connect to database {}",
+ database_path.as_ref().display()
);
let opts = sqlx::sqlite::SqliteConnectOptions::new()
diff --git a/common/gateway-stats-storage/src/lib.rs b/common/gateway-stats-storage/src/lib.rs
index 8ad34bbca4..d29de3a1b0 100644
--- a/common/gateway-stats-storage/src/lib.rs
+++ b/common/gateway-stats-storage/src/lib.rs
@@ -33,8 +33,8 @@ impl PersistentStatsStorage {
/// * `database_path`: path to the database.
pub async fn init + Send>(database_path: P) -> Result {
debug!(
- "Attempting to connect to database {:?}",
- database_path.as_ref().as_os_str()
+ "Attempting to connect to database {}",
+ database_path.as_ref().display()
);
// TODO: we can inject here more stuff based on our gateway global config
diff --git a/common/gateway-storage/src/lib.rs b/common/gateway-storage/src/lib.rs
index 2d05d43fe7..ea534b8c1b 100644
--- a/common/gateway-storage/src/lib.rs
+++ b/common/gateway-storage/src/lib.rs
@@ -82,8 +82,8 @@ impl GatewayStorage {
message_retrieval_limit: i64,
) -> Result {
debug!(
- "Attempting to connect to database {:?}",
- database_path.as_ref().as_os_str()
+ "Attempting to connect to database {}",
+ database_path.as_ref().display()
);
// TODO: we can inject here more stuff based on our gateway global config
From 378229b04e941a2bb98896dfe665654ce5ee9b88 Mon Sep 17 00:00:00 2001
From: Jack Wampler
Date: Thu, 12 Jun 2025 11:15:36 -0600
Subject: [PATCH 27/47] HTTP Discovery objects & network defaults (#5814)
add extended (optional) fields to the NetworkDiscovery and configure fallback hosts
---
common/network-defaults/src/mainnet.rs | 30 ++++++++++++++--
common/network-defaults/src/network.rs | 35 +++++++++++++++++++
.../nym-wallet-types/src/network/sandbox.rs | 2 ++
.../testnet-manager/src/manager/network.rs | 2 ++
.../src/manager/network_init.rs | 2 ++
5 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs
index 2b54d17406..2698162197 100644
--- a/common/network-defaults/src/mainnet.rs
+++ b/common/network-defaults/src/mainnet.rs
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
#[cfg(feature = "network")]
-use crate::{DenomDetails, ValidatorDetails};
+use crate::{ApiUrlConst, DenomDetails, ValidatorDetails};
pub const NETWORK_NAME: &str = "mainnet";
@@ -29,10 +29,36 @@ pub const COCONUT_DKG_CONTRACT_ADDRESS: &str =
pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
pub const NYXD_URL: &str = "https://rpc.nymtech.net";
-pub const NYM_API: &str = "https://validator.nymtech.net/api/";
pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket";
pub const EXPLORER_API: &str = "https://explorer.nymtech.net/api/";
+pub const NYM_API: &str = "https://validator.nymtech.net/api/";
+#[cfg(feature = "network")]
+pub const NYM_APIS: &[ApiUrlConst] = &[
+ ApiUrlConst {
+ url: NYM_API,
+ front_hosts: None,
+ },
+ ApiUrlConst {
+ url: "https://nym-fronntdoor.vercel.app/api/",
+ front_hosts: Some(&["vercel.app", "vercel.com"]),
+ },
+ ApiUrlConst {
+ url: "https://nym-frontdoor.global.ssl.fastly.net/api/",
+ front_hosts: Some(&["yelp.global.ssl.fastly.net"]),
+ },
+];
pub const NYM_VPN_API: &str = "https://nymvpn.com/api/";
+#[cfg(feature = "network")]
+pub const NYM_VPN_APIS: &[ApiUrlConst] = &[
+ ApiUrlConst {
+ url: NYM_VPN_API,
+ front_hosts: Some(&["vercel.app", "vercel.com"]),
+ },
+ ApiUrlConst {
+ url: "https://nymvpn-frontdoor.global.ssl.fastly.net/api/",
+ front_hosts: Some(&["yelp.global.ssl.fastly.net"]),
+ },
+];
// I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging
pub const EXIT_POLICY_URL: &str =
diff --git a/common/network-defaults/src/network.rs b/common/network-defaults/src/network.rs
index 8cebe53340..e2b7ceb822 100644
--- a/common/network-defaults/src/network.rs
+++ b/common/network-defaults/src/network.rs
@@ -37,6 +37,37 @@ pub struct NymNetworkDetails {
pub contracts: NymContracts,
pub explorer_api: Option,
pub nym_vpn_api_url: Option,
+ pub nym_api_urls: Option>,
+ pub nym_vpn_api_urls: Option>,
+}
+
+#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)]
+#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
+pub struct ApiUrl {
+ /// Expects a string formatted Url
+ ///
+ /// see https://docs.rs/url/latest/url/struct.Url.html
+ pub url: String,
+ /// Optional alternative equivalent hostnames. Each entry must parse as valid Host
+ ///
+ /// see https://docs.rs/url/latest/url/enum.Host.html
+ pub front_hosts: Option>,
+}
+
+pub struct ApiUrlConst<'a> {
+ pub url: &'a str,
+ pub front_hosts: Option<&'a [&'a str]>,
+}
+
+impl From> for ApiUrl {
+ fn from(value: ApiUrlConst) -> Self {
+ ApiUrl {
+ url: value.url.to_string(),
+ front_hosts: value
+ .front_hosts
+ .map(|slice| slice.iter().map(|s| s.to_string()).collect()),
+ }
+ }
}
// by default we assume the same defaults as mainnet, i.e. same prefixes and denoms
@@ -67,6 +98,8 @@ impl NymNetworkDetails {
contracts: Default::default(),
explorer_api: Default::default(),
nym_vpn_api_url: Default::default(),
+ nym_api_urls: Default::default(),
+ nym_vpn_api_urls: Default::default(),
}
}
@@ -154,6 +187,8 @@ impl NymNetworkDetails {
},
explorer_api: parse_optional_str(mainnet::EXPLORER_API),
nym_vpn_api_url: parse_optional_str(mainnet::NYM_VPN_API),
+ nym_api_urls: None,
+ nym_vpn_api_urls: None,
}
}
diff --git a/nym-wallet/nym-wallet-types/src/network/sandbox.rs b/nym-wallet/nym-wallet-types/src/network/sandbox.rs
index c436c9f09e..68d389ebfb 100644
--- a/nym-wallet/nym-wallet-types/src/network/sandbox.rs
+++ b/nym-wallet/nym-wallet-types/src/network/sandbox.rs
@@ -55,5 +55,7 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
},
explorer_api: parse_optional_str(EXPLORER_API),
nym_vpn_api_url: None,
+ nym_vpn_api_urls: None,
+ nym_api_urls: None,
}
}
diff --git a/tools/internal/testnet-manager/src/manager/network.rs b/tools/internal/testnet-manager/src/manager/network.rs
index 6c65eda06c..623a3d0a8e 100644
--- a/tools/internal/testnet-manager/src/manager/network.rs
+++ b/tools/internal/testnet-manager/src/manager/network.rs
@@ -83,6 +83,8 @@ impl<'a> From<&'a LoadedNetwork> for nym_config::defaults::NymNetworkDetails {
contracts,
explorer_api: None,
nym_vpn_api_url: None,
+ nym_vpn_api_urls: None,
+ nym_api_urls: None,
}
}
}
diff --git a/tools/internal/testnet-manager/src/manager/network_init.rs b/tools/internal/testnet-manager/src/manager/network_init.rs
index 8e978e4fc6..6deb16046b 100644
--- a/tools/internal/testnet-manager/src/manager/network_init.rs
+++ b/tools/internal/testnet-manager/src/manager/network_init.rs
@@ -40,6 +40,8 @@ impl InitCtx {
contracts: Default::default(),
explorer_api: None,
nym_vpn_api_url: None,
+ nym_vpn_api_urls: None,
+ nym_api_urls: None,
};
Ok(Config::try_from_nym_network_details(&network_details)?)
}
From a31597aca9248559559928fca3286959248d4be4 Mon Sep 17 00:00:00 2001
From: Simon Wicky
Date: Fri, 13 Jun 2025 09:30:00 +0200
Subject: [PATCH 28/47] fix removal of qa env
---
nym-wallet/src-tauri/src/config/mod.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nym-wallet/src-tauri/src/config/mod.rs b/nym-wallet/src-tauri/src/config/mod.rs
index 78c214d1d1..548f135173 100644
--- a/nym-wallet/src-tauri/src/config/mod.rs
+++ b/nym-wallet/src-tauri/src/config/mod.rs
@@ -459,7 +459,7 @@ impl fmt::Display for OptionalValidators {
.as_ref()
.map(|validators| format!(",\nsandbox: [\n{}\n]", validators.iter().format("\n")))
.unwrap_or_default();
- write!(f, "{s1}{s2}{s3}")
+ write!(f, "{s1}{s2}")
}
}
From 5f9f7f0facf74572d2d606d4307c75d14df4ca7a Mon Sep 17 00:00:00 2001
From: Andrej Mihajlov
Date: Fri, 13 Jun 2025 11:00:48 +0200
Subject: [PATCH 29/47] Clear out screaming logs
---
common/client-core/surb-storage/src/lib.rs | 2 --
1 file changed, 2 deletions(-)
diff --git a/common/client-core/surb-storage/src/lib.rs b/common/client-core/surb-storage/src/lib.rs
index 9e0ba14b34..b1c0f3088b 100644
--- a/common/client-core/surb-storage/src/lib.rs
+++ b/common/client-core/surb-storage/src/lib.rs
@@ -33,7 +33,6 @@ where
self.backend.load_surb_storage().await
}
- // this will have to get enabled after merging develop
pub async fn flush_on_shutdown(
mut self,
mem_state: CombinedReplyStorage,
@@ -50,7 +49,6 @@ where
shutdown.recv().await;
info!("PersistentReplyStorage is flushing all reply-related data to underlying storage");
- info!("you MUST NOT forcefully shutdown now or you risk data corruption!");
if let Err(err) = self.backend.flush_surb_storage(&mem_state).await {
error!("failed to flush our reply-related data to the persistent storage: {err}")
} else {
From b9339b8f0c54d3ed202b8704c8a0ef9dc0f3e341 Mon Sep 17 00:00:00 2001
From: dynco-nym <173912580+dynco-nym@users.noreply.github.com>
Date: Mon, 16 Jun 2025 13:19:35 +0200
Subject: [PATCH 30/47] Add /status endpoints (#5857)
* Add /status endpoints
* Bump package version
* pub use instead of import
---
Cargo.lock | 2 +-
.../nym-node-status-api/Cargo.toml | 4 +-
.../nym-node-status-api/src/http/api/mod.rs | 4 +-
.../src/http/api/status.rs | 46 +++++++++++++++++++
.../nym-node-status-api/src/http/state.rs | 38 ++++++++++++++-
5 files changed, 89 insertions(+), 5 deletions(-)
create mode 100644 nym-node-status-api/nym-node-status-api/src/http/api/status.rs
diff --git a/Cargo.lock b/Cargo.lock
index 0aed14970b..53ee2debe5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6649,7 +6649,7 @@ dependencies = [
[[package]]
name = "nym-node-status-api"
-version = "3.0.0"
+version = "3.1.0"
dependencies = [
"ammonia",
"anyhow",
diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml
index 104e4c9863..7e63db3672 100644
--- a/nym-node-status-api/nym-node-status-api/Cargo.toml
+++ b/nym-node-status-api/nym-node-status-api/Cargo.toml
@@ -3,7 +3,7 @@
[package]
name = "nym-node-status-api"
-version = "3.0.0"
+version = "3.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -28,7 +28,7 @@ moka = { workspace = true, features = ["future"] }
# Nym API: revert after Cheddar is out
nym-contracts-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
nym-mixnet-contract-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
-nym-bin-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
+nym-bin-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar", features = ["openapi"]}
nym-node-status-client = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
nym-crypto = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
nym-http-api-client = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/api/mod.rs
index 5bc06be2b2..bd4300275b 100644
--- a/nym-node-status-api/nym-node-status-api/src/http/api/mod.rs
+++ b/nym-node-status-api/nym-node-status-api/src/http/api/mod.rs
@@ -14,6 +14,7 @@ pub(crate) mod metrics;
pub(crate) mod mixnodes;
pub(crate) mod nym_nodes;
pub(crate) mod services;
+pub(crate) mod status;
pub(crate) mod summary;
pub(crate) mod testruns;
@@ -39,7 +40,8 @@ impl RouterBuilder {
.nest("/mixnodes", mixnodes::routes())
.nest("/services", services::routes())
.nest("/summary", summary::routes())
- .nest("/metrics", metrics::routes()),
+ .nest("/metrics", metrics::routes())
+ .nest("/status", status::routes()),
)
.nest(
"/explorer/v3",
diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/status.rs b/nym-node-status-api/nym-node-status-api/src/http/api/status.rs
new file mode 100644
index 0000000000..306a7f9c2b
--- /dev/null
+++ b/nym-node-status-api/nym-node-status-api/src/http/api/status.rs
@@ -0,0 +1,46 @@
+use axum::{extract::State, Json, Router};
+use nym_validator_client::models::BinaryBuildInformationOwned;
+use tracing::instrument;
+
+use crate::http::{
+ error::HttpResult,
+ state::{AppState, HealthInfo},
+};
+
+pub(crate) fn routes() -> Router {
+ Router::new()
+ .route("/build_information", axum::routing::get(build_information))
+ .route("/health", axum::routing::get(health))
+}
+
+#[utoipa::path(
+ tag = "Status",
+ get,
+ path = "/build_information",
+ context_path = "/v2/status",
+ responses(
+ (status = 200, body = BinaryBuildInformationOwned)
+ )
+)]
+#[instrument(level = tracing::Level::INFO, skip_all)]
+async fn build_information(
+ State(state): State,
+) -> HttpResult> {
+ let build_info = state.build_information().to_owned();
+
+ Ok(Json(build_info))
+}
+
+#[utoipa::path(
+ tag = "Status",
+ get,
+ path = "/health",
+ context_path = "/v2/status",
+ responses(
+ (status = 200, body = HealthInfo)
+ )
+)]
+#[instrument(level = tracing::Level::INFO, skip_all)]
+async fn health(State(state): State) -> HttpResult> {
+ Ok(Json(state.health()))
+}
diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs
index 0a5ef4fca9..8d197f9a07 100644
--- a/nym-node-status-api/nym-node-status-api/src/http/state.rs
+++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs
@@ -1,15 +1,20 @@
use cosmwasm_std::Decimal;
use itertools::Itertools;
use moka::{future::Cache, Entry};
+use nym_bin_common::bin_info_owned;
use nym_contracts_common::NaiveFloat;
use nym_crypto::asymmetric::ed25519::PublicKey;
use nym_mixnet_contract_common::NodeId;
use nym_validator_client::nym_api::SkimmedNode;
use semver::Version;
+use serde::Serialize;
use std::{collections::HashMap, sync::Arc, time::Duration};
+use time::UtcDateTime;
use tokio::sync::RwLock;
use tracing::{error, instrument, warn};
+use utoipa::ToSchema;
+use super::models::SessionStats;
use crate::{
db::{queries, DbPool},
http::models::{
@@ -18,7 +23,7 @@ use crate::{
monitor::{DelegationsCache, NodeGeoCache},
};
-use super::models::SessionStats;
+pub(crate) use nym_validator_client::models::BinaryBuildInformationOwned;
#[derive(Debug, Clone)]
pub(crate) struct AppState {
@@ -28,6 +33,7 @@ pub(crate) struct AppState {
agent_max_count: i64,
node_geocache: NodeGeoCache,
node_delegations: Arc>,
+ bin_info: BinaryInfo,
}
impl AppState {
@@ -46,6 +52,7 @@ impl AppState {
agent_max_count,
node_geocache,
node_delegations,
+ bin_info: BinaryInfo::new(),
}
}
@@ -78,6 +85,15 @@ impl AppState {
.await
.delegations_owned(node_id)
}
+
+ pub(crate) fn health(&self) -> HealthInfo {
+ let uptime = (UtcDateTime::now() - self.bin_info.startup_time).whole_seconds();
+ HealthInfo { uptime }
+ }
+
+ pub(crate) fn build_information(&self) -> &BinaryBuildInformationOwned {
+ &self.bin_info.build_info
+ }
}
static GATEWAYS_LIST_KEY: &str = "gateways";
@@ -631,3 +647,23 @@ async fn aggregate_node_info_from_db(
Ok(parsed_nym_nodes)
}
+
+#[derive(Debug, Clone)]
+pub(crate) struct BinaryInfo {
+ startup_time: UtcDateTime,
+ build_info: BinaryBuildInformationOwned,
+}
+
+impl BinaryInfo {
+ fn new() -> Self {
+ Self {
+ startup_time: UtcDateTime::now(),
+ build_info: bin_info_owned!(),
+ }
+ }
+}
+
+#[derive(Serialize, ToSchema)]
+pub(crate) struct HealthInfo {
+ uptime: i64,
+}
From 4d09b6f2e58f08c3f9989c2990cd96e6b428d953 Mon Sep 17 00:00:00 2001
From: Georgio Nicolas
Date: Wed, 4 Jun 2025 23:21:49 +0200
Subject: [PATCH 31/47] bte/proof_chunking.rs: Check for potential arithmentic
overflows
---
common/dkg/src/bte/proof_chunking.rs | 103 ++++++++++++++++++++++-----
common/dkg/src/error.rs | 6 ++
2 files changed, 92 insertions(+), 17 deletions(-)
diff --git a/common/dkg/src/bte/proof_chunking.rs b/common/dkg/src/bte/proof_chunking.rs
index 1365aecbd7..d756f08733 100644
--- a/common/dkg/src/bte/proof_chunking.rs
+++ b/common/dkg/src/bte/proof_chunking.rs
@@ -28,6 +28,7 @@ const SECURITY_PARAMETER: usize = 256;
/// ceil(SECURITY_PARAMETER / PARALLEL_RUNS) in the paper
const NUM_CHALLENGE_BITS: usize = SECURITY_PARAMETER.div_ceil(PARALLEL_RUNS);
+const EE: usize = 1 << NUM_CHALLENGE_BITS;
// type alias for ease of use
type FirstChallenge = Vec>>;
@@ -110,21 +111,20 @@ impl ProofOfChunking {
// define bounds for the blinding factors
let n = instance.public_keys.len();
let m = NUM_CHUNKS;
- let ee = 1 << NUM_CHALLENGE_BITS;
- // CHUNK_MAX corresponds to paper's B
- let ss = (n * m * (CHUNK_SIZE - 1) * (ee - 1)) as u64;
- let zz = (2 * (PARALLEL_RUNS as u64))
- .checked_mul(ss)
- .expect("overflow in Z = 2 * l * S");
+ // ss = (n * m * (CHUNK_SIZE - 1) * (ee - 1))
+ // Z = 2 * l * S
+ let (ss, zz): (u64, u64) = compute_ss_zz(n, m)?;
let ss_scalar = Scalar::from(ss);
// rather than generating blinding factors in [-S, Z-1] directly,
// do it via [0, Z - 1 + S + 1] and deal with the shift later.
- let combined_upper_range = (zz - 1)
- .checked_add(ss + 1)
- .expect("overflow in Z - 1 + S + 1");
+ // combined_upper_range = Z - 1 + S + 1
+
+ let combined_upper_range = zz.checked_add(ss).ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::construct | Z - 1 + S + 1",
+ })?;
let mut betas = Vec::with_capacity(PARALLEL_RUNS);
let mut bs = Vec::with_capacity(PARALLEL_RUNS);
@@ -178,12 +178,23 @@ impl ProofOfChunking {
// I think this part is more readable with a range loop
#[allow(clippy::needless_range_loop)]
for l in 0..PARALLEL_RUNS {
- let mut sum = 0;
+ let mut sum: u64 = 0;
for (i, witness_i) in witnesses_s.iter().enumerate() {
for (j, witness_ij) in witness_i.to_chunks().chunks.iter().enumerate() {
debug_assert!(std::mem::size_of::() <= std::mem::size_of::());
- sum += first_challenge[i][j][l] * (*witness_ij as u64)
+ // sum += first_challenge[i][j][l] * (*witness_ij as u64)
+ sum = sum
+ .checked_add(
+ first_challenge[i][j][l]
+ .checked_mul(*witness_ij as u64)
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::construct | first_challenge[i][j][l] * witness_ij",
+ })?,
+ )
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::construct | sum + (first_challenge[i][j][l] * witness_ij)",
+ })?;
}
}
@@ -191,7 +202,18 @@ impl ProofOfChunking {
continue 'retry_loop;
}
// shifted_blinding_factors[l] - ss restores it to "proper" [-S, Z - 1] range
- let response = sum + shifted_blinding_factors[l] - ss;
+ // let response = sum + shifted_blinding_factors[l] - ss;
+ let response = sum
+ .checked_add(shifted_blinding_factors[l])
+ .ok_or(DkgError::ArithmeticOverflow {
+ info:
+ "ProofOfChunking::construct | sum + (shifted_blinding_factors[l] - ss)",
+ })?
+ .checked_sub(ss)
+ .ok_or(DkgError::ArithmeticUnderflow {
+ info: "ProofOfChunking::construct | shifted_blinding_factors[l] - ss",
+ })?;
+
if response < zz {
responses_chunks.push(response)
} else {
@@ -276,11 +298,14 @@ impl ProofOfChunking {
ensure_len!(&self.responses_r, n);
ensure_len!(&self.responses_chunks, PARALLEL_RUNS);
- let ee = 1 << NUM_CHALLENGE_BITS;
+ // ss = (n * m * (CHUNK_SIZE - 1) * (ee - 1))
+ // Z = 2 * l * S
- // CHUNK_MAX corresponds to paper's B
- let ss = (n * m * (CHUNK_SIZE - 1) * (ee - 1)) as u64;
- let zz = 2 * (PARALLEL_RUNS as u64) * ss;
+ let zz: u64;
+ match compute_ss_zz(n, m) {
+ Ok((_, zz_res)) => zz = zz_res,
+ _ => return false,
+ };
for response_chunk in &self.responses_chunks {
if response_chunk >= &zz {
@@ -411,7 +436,7 @@ impl ProofOfChunking {
random_oracle_builder.update(lambda_e.to_be_bytes());
let mut oracle = rand_chacha::ChaCha20Rng::from_seed(random_oracle_builder.finalize());
- let range_max_excl = 1 << NUM_CHALLENGE_BITS;
+ let range_max_excl = EE as u64;
(0..n)
.map(|_| {
@@ -637,6 +662,50 @@ impl ProofOfChunking {
}
}
+fn compute_ss_zz(n: usize, m: usize) -> Result<(u64, u64), DkgError> {
+ // let ss = (n * m * (CHUNK_SIZE - 1) * (ee - 1)) as u64;
+ // CHUNK_MAX corresponds to paper's B
+
+ let ee = EE;
+
+ let ss = n
+ .checked_mul(m)
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::compute_ss_zz | n * m",
+ })?
+ .checked_mul(
+ CHUNK_SIZE
+ .checked_sub(1)
+ .ok_or(DkgError::ArithmeticUnderflow {
+ info: "ProofOfChunking::compute_ss_zz | (CHUNK_SIZE - 1)",
+ })?
+ .checked_mul(ee.checked_sub(1).ok_or(DkgError::ArithmeticUnderflow {
+ info: "ProofOfChunking::compute_ss_zz | (ee - 1)",
+ })?)
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::compute_ss_zz | (CHUNK_SIZE - 1) * (ee - 1)",
+ })?,
+ )
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::compute_ss_zz | ss_lhs * ss_rhs",
+ })? as u64;
+
+ // let zz = 2 * PARALLEL_RUNS as u64 * ss;
+ // Z = 2 * l * S
+
+ let zz = 2u64
+ .checked_mul(PARALLEL_RUNS as u64)
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::compute_ss_zz | 2 * l",
+ })?
+ .checked_mul(ss)
+ .ok_or(DkgError::ArithmeticOverflow {
+ info: "ProofOfChunking::compute_ss_zz | (2 * l) * S",
+ })?;
+
+ Ok((ss, zz))
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/common/dkg/src/error.rs b/common/dkg/src/error.rs
index 9329f32794..5bea0fe3a3 100644
--- a/common/dkg/src/error.rs
+++ b/common/dkg/src/error.rs
@@ -99,6 +99,12 @@ pub enum DkgError {
"The reshared dealing has different public constant coefficient than its prior variant"
)]
InvalidResharing,
+
+ #[error("Arithmetic Overflow: {info}")]
+ ArithmeticOverflow { info: &'static str },
+
+ #[error("Arithmetic Underflow: {info}")]
+ ArithmeticUnderflow { info: &'static str },
}
impl DkgError {
From e2f2ab89ecc1bb4e496fbf171415de8b36c686de Mon Sep 17 00:00:00 2001
From: Georgio Nicolas
Date: Wed, 4 Jun 2025 23:33:45 +0200
Subject: [PATCH 32/47] dkg: add CryptoRng trait requirement
---
common/dkg/benches/benchmarks.rs | 5 +++--
common/dkg/src/bte/encryption.rs | 8 ++++++--
common/dkg/src/bte/keys.rs | 8 ++++++--
common/dkg/src/bte/proof_chunking.rs | 8 +++++---
common/dkg/src/bte/proof_discrete_log.rs | 7 ++++++-
common/dkg/src/bte/proof_sharing.rs | 6 ++++--
common/dkg/src/dealing.rs | 3 ++-
common/dkg/src/interpolation/polynomial.rs | 3 ++-
8 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/common/dkg/benches/benchmarks.rs b/common/dkg/benches/benchmarks.rs
index 2951a57a7c..37217bf45d 100644
--- a/common/dkg/benches/benchmarks.rs
+++ b/common/dkg/benches/benchmarks.rs
@@ -14,6 +14,7 @@ use nym_dkg::bte::{
};
use nym_dkg::interpolation::polynomial::Polynomial;
use nym_dkg::{combine_shares, Dealing, NodeIndex, Share, Threshold};
+use rand::CryptoRng;
use rand_core::{RngCore, SeedableRng};
use std::collections::BTreeMap;
@@ -31,7 +32,7 @@ pub fn precomputing_g2_generator_for_miller_loop(c: &mut Criterion) {
}
fn prepare_keys(
- mut rng: impl RngCore,
+ mut rng: impl RngCore + CryptoRng,
nodes: usize,
) -> (BTreeMap, Vec) {
let params = setup();
@@ -50,7 +51,7 @@ fn prepare_keys(
}
fn prepare_resharing(
- mut rng: impl RngCore,
+ mut rng: impl RngCore + CryptoRng,
params: &Params,
nodes: usize,
threshold: Threshold,
diff --git a/common/dkg/src/bte/encryption.rs b/common/dkg/src/bte/encryption.rs
index 8cd6a3e774..56fdd148cd 100644
--- a/common/dkg/src/bte/encryption.rs
+++ b/common/dkg/src/bte/encryption.rs
@@ -9,6 +9,7 @@ use crate::{Chunk, ChunkedShare, Share};
use bls12_381::{G1Affine, G1Projective, G2Prepared, G2Projective, Gt, Scalar};
use ff::Field;
use group::{Curve, Group, GroupEncoding};
+use rand::CryptoRng;
use rand_core::RngCore;
use std::collections::HashMap;
use std::ops::Neg;
@@ -191,7 +192,7 @@ impl HazmatRandomness {
pub fn encrypt_shares(
shares: &[(&Share, &PublicKey)],
params: &Params,
- mut rng: impl RngCore,
+ mut rng: impl RngCore + CryptoRng,
) -> (Ciphertexts, HazmatRandomness) {
let g1 = G1Projective::generator();
@@ -574,7 +575,10 @@ mod tests {
#[test]
fn ciphertexts_roundtrip() {
- fn random_ciphertexts(mut rng: impl RngCore, num_receivers: usize) -> Ciphertexts {
+ fn random_ciphertexts(
+ mut rng: impl RngCore + CryptoRng,
+ num_receivers: usize,
+ ) -> Ciphertexts {
Ciphertexts {
rr: (0..NUM_CHUNKS)
.map(|_| G1Projective::random(&mut rng))
diff --git a/common/dkg/src/bte/keys.rs b/common/dkg/src/bte/keys.rs
index 132f161f5e..20d896a547 100644
--- a/common/dkg/src/bte/keys.rs
+++ b/common/dkg/src/bte/keys.rs
@@ -9,11 +9,15 @@ use bls12_381::{G1Projective, G2Projective, Scalar};
use ff::Field;
use group::GroupEncoding;
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
+use rand::CryptoRng;
use rand_core::RngCore;
use zeroize::Zeroize;
// produces public key and a decryption key for the root of the tree
-pub fn keygen(params: &Params, mut rng: impl RngCore) -> (DecryptionKey, PublicKeyWithProof) {
+pub fn keygen(
+ params: &Params,
+ mut rng: impl RngCore + CryptoRng,
+) -> (DecryptionKey, PublicKeyWithProof) {
let g1 = G1Projective::generator();
let g2 = G2Projective::generator();
@@ -244,7 +248,7 @@ pub struct KeyPair {
}
impl KeyPair {
- pub fn new(params: &Params, rng: impl RngCore) -> Self {
+ pub fn new(params: &Params, rng: impl RngCore + CryptoRng) -> Self {
let (dk, pk) = keygen(params, rng);
Self {
private_key: dk,
diff --git a/common/dkg/src/bte/proof_chunking.rs b/common/dkg/src/bte/proof_chunking.rs
index d756f08733..1021ac9fb4 100644
--- a/common/dkg/src/bte/proof_chunking.rs
+++ b/common/dkg/src/bte/proof_chunking.rs
@@ -10,7 +10,7 @@ use crate::utils::{deserialize_scalar, RandomOracleBuilder};
use bls12_381::{G1Projective, Scalar};
use ff::Field;
use group::{Group, GroupEncoding};
-use rand::Rng;
+use rand::{CryptoRng, Rng};
use rand_core::{RngCore, SeedableRng};
const CHUNKING_ORACLE_DOMAIN: &[u8] =
@@ -95,7 +95,7 @@ impl ProofOfChunking {
// Scalar(-1) would in reality be Scalar(q - 1), which is greater than Scalar(1) and opposite to
// what we wanted.
pub fn construct(
- mut rng: impl RngCore,
+ mut rng: impl RngCore + CryptoRng,
instance: Instance,
witness_r: &[Scalar; NUM_CHUNKS],
witnesses_s: &[Share],
@@ -721,7 +721,9 @@ mod tests {
ciphertext_chunks: Vec<[G1Projective; NUM_CHUNKS]>,
}
- fn setup(mut rng: impl RngCore) -> (OwnedInstance, [Scalar; NUM_CHUNKS], Vec) {
+ fn setup(
+ mut rng: impl RngCore + CryptoRng,
+ ) -> (OwnedInstance, [Scalar; NUM_CHUNKS], Vec