Skip to content

Commit

Permalink
update cryptio
Browse files Browse the repository at this point in the history
  • Loading branch information
nicarq committed Jan 24, 2025
1 parent 4fbee6c commit 140315d
Show file tree
Hide file tree
Showing 33 changed files with 82 additions and 81 deletions.
4 changes: 2 additions & 2 deletions cloud-node/env.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ NODE_HTTPS_PORT=9553
IDENTITY_SECRET_KEY=
ENCRYPTION_SECRET_KEY=
PING_INTERVAL_SECS=0
GLOBAL_IDENTITY_NAME=@@my_local_ai.arb-sep-shinkai
GLOBAL_IDENTITY_NAME=@@my_local_ai.sep-shinkai
RUST_LOG=debug,error,info
STARTING_NUM_QR_PROFILES=1
STARTING_NUM_QR_DEVICES=1
FIRST_DEVICE_NEEDS_REGISTRATION_CODE=false
LOG_SIMPLE=true
NO_SECRET_FILE=true
EMBEDDINGS_SERVER_URL=
PROXY_IDENTITY=@@relayer_pub_01.arb-sep-shinkai
PROXY_IDENTITY=@@relayer_pub_01.sep-shinkai
SHINKAI_TOOLS_RUNNER_DENO_BINARY_PATH=./shinkai-tools-runner-resources/deno
SHINKAI_TOOLS_RUNNER_UV_BINARY_PATH=./shinkai-tools-runner-resources/uv
SHINKAI_TOOLS_DIRECTORY_URL=https://download.shinkai.com/tools/directory.json
Expand Down
2 changes: 1 addition & 1 deletion scripts/run_agent_provider.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export NODE_WS_PORT="9751"
export IDENTITY_SECRET_KEY="df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
export ENCRYPTION_SECRET_KEY="d83f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81159"
export PING_INTERVAL_SECS="0"
export GLOBAL_IDENTITY_NAME="@@agent_provider.arb-sep-shinkai"
export GLOBAL_IDENTITY_NAME="@@agent_provider.sep-shinkai"
export NODE_STORAGE_PATH="agent_provider"
export RUST_LOG=debug,error,info
export STARTING_NUM_QR_PROFILES="1"
Expand Down
4 changes: 2 additions & 2 deletions scripts/run_all_localhost.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ export NODE_HTTPS_PORT="9553"
export IDENTITY_SECRET_KEY="df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
export ENCRYPTION_SECRET_KEY="d83f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81159"
export PING_INTERVAL_SECS="0"
export GLOBAL_IDENTITY_NAME="@@localhost.arb-sep-shinkai"
export GLOBAL_IDENTITY_NAME="@@localhost.sep-shinkai"
export RUST_LOG=debug,error,info
export STARTING_NUM_QR_PROFILES="1"
export STARTING_NUM_QR_DEVICES="1"
export FIRST_DEVICE_NEEDS_REGISTRATION_CODE="false"
export LOG_SIMPLE="true"
export NO_SECRET_FILE="true"
export EMBEDDINGS_SERVER_URL="http://localhost:11434/"
export PROXY_IDENTITY="@@relayer_pub_01.arb-sep-shinkai"
export PROXY_IDENTITY="@@relayer_pub_01.sep-shinkai"
export SHINKAI_TOOLS_RUNNER_DENO_BINARY_PATH="${workspaceFolder}/shinkai-bin/shinkai-node/shinkai-tools-runner-resources/deno"
export SHINKAI_TOOLS_RUNNER_UV_BINARY_PATH="${workspaceFolder}/shinkai-bin/shinkai-node/shinkai-tools-runner-resources/uv"

Expand Down
4 changes: 2 additions & 2 deletions scripts/run_local_ai_with_proxy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export SUBSCRIPTION_HTTP_UPLOAD_INTERVAL_MINUTES="1"
export SUBSCRIPTION_UPDATE_CACHE_INTERVAL_MINUTES="1"
export LOG_ALL="1"
export DEBUG_VRKAI="1"
# export PROXY_IDENTITY="@@kao_tcp_relayer.arb-sep-shinkai"
export PROXY_IDENTITY="@@relayer_pub_01.arb-sep-shinkai"
# export PROXY_IDENTITY="@@kao_tcp_relayer.sep-shinkai"
export PROXY_IDENTITY="@@relayer_pub_01.sep-shinkai"

cargo run --bin shinkai_node --package shinkai_node
2 changes: 1 addition & 1 deletion scripts/run_node_localhost.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export NODE_PORT="9452"
export NODE_API_IP="0.0.0.0"
export NODE_API_PORT="9450"
export PING_INTERVAL_SECS="0"
export GLOBAL_IDENTITY_NAME="@@localhost.arb-sep-shinkai"
export GLOBAL_IDENTITY_NAME="@@localhost.sep-shinkai"
export RUST_LOG=debug,error,info
export STARTING_NUM_QR_PROFILES="1"
export STARTING_NUM_QR_DEVICES="1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ mod tests {
async fn test_set_column_with_mock_job_manager() {
let db = setup_test_db();
let db = Arc::new(db);
let node_name = "@@test.arb-sep-shinkai".to_string();
let node_name = "@@test.sep-shinkai".to_string();
let node_name = ShinkaiName::new(node_name).unwrap();
let ws_manager: Option<Arc<Mutex<dyn WSUpdateHandler + Send>>> = None;

Expand Down Expand Up @@ -739,7 +739,7 @@ mod tests {
async fn test_update_column_with_values() {
let db = setup_test_db();
let db = Arc::new(db);
let node_name = "@@test.arb-sep-shinkai".to_string();
let node_name = "@@test.sep-shinkai".to_string();
let node_name = ShinkaiName::new(node_name).unwrap();
let ws_manager: Option<Arc<Mutex<dyn WSUpdateHandler + Send>>> = None;

Expand Down Expand Up @@ -804,7 +804,7 @@ mod tests {
async fn test_replace_value_at_position() {
let db = setup_test_db();
let db = Arc::new(db);
let node_name = "@@test.arb-sep-shinkai".to_string();
let node_name = "@@test.sep-shinkai".to_string();
let node_name = ShinkaiName::new(node_name).unwrap();
let ws_manager: Option<Arc<Mutex<dyn WSUpdateHandler + Send>>> = None;

Expand Down Expand Up @@ -869,7 +869,7 @@ mod tests {
async fn test_create_new_columns_with_csv() {
let db = setup_test_db();
let db = Arc::new(db);
let node_name = "@@test.arb-sep-shinkai".to_string();
let node_name = "@@test.sep-shinkai".to_string();
let node_name = ShinkaiName::new(node_name).unwrap();
let ws_manager: Option<Arc<Mutex<dyn WSUpdateHandler + Send>>> = None;

Expand Down Expand Up @@ -932,7 +932,7 @@ mod tests {
async fn test_create_new_columns_with_large_csv() {
let db = setup_test_db();
let db = Arc::new(db);
let node_name = "@@test.arb-sep-shinkai".to_string();
let node_name = "@@test.sep-shinkai".to_string();
let node_name = ShinkaiName::new(node_name).unwrap();
let ws_manager: Option<Arc<Mutex<dyn WSUpdateHandler + Send>>> = None;

Expand Down Expand Up @@ -1185,7 +1185,7 @@ mod tests {
async fn test_create_new_columns_with_semicolon_csv() {
let db = setup_test_db();
let db = Arc::new(db);
let node_name = "@@test.arb-sep-shinkai".to_string();
let node_name = "@@test.sep-shinkai".to_string();
let node_name = ShinkaiName::new(node_name).unwrap();
let ws_manager: Option<Arc<Mutex<dyn WSUpdateHandler + Send>>> = None;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl JobManager {
);

let node_name = user_profile
.unwrap_or_else(|| ShinkaiName::new("@@localhost.arb-sep-shinkai".to_string()).unwrap())
.unwrap_or_else(|| ShinkaiName::new("@@localhost.sep-shinkai".to_string()).unwrap())
.node_name;

let error_json = error.to_error_message();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ mod tests {
"response": null,
"tool_router_key": null
},
"response": "{\"data\":{\"__created_files__\":[\"shinkai://file/@@my_local_ai.arb-sep-shinkai/main/jobid_c93837a6-358b-4648-9617-1d6e93d0bb59/logs/log_jobid_c93837a6-358b-4648-9617-1d6e93d0bb59_localduckduckgo_searchduckduckgo_search.log\"],\"message\":\"[{\\\"title\\\":\\\"Movie Tickets &amp; Movie Times | Fandango\\\",\\\"description\\\":\\\"Honoring the Best <b>movies</b> &amp; TV. Check out the winners from this year&#x27;s 26th annual Rotten Tomatoes Awards. LEARN MORE. Collectors, assemble! image link. Collectors, assemble! Suit up and get the Captain America Collector Pack, featuring an exclusive Collector&#x27;s Coin, Limited-Edition Poster, and one <b>movie</b> ticket!\\\",\\\"url\\\":\\\"https://www.fandango.com/\\\"}]\"}}",
"response": "{\"data\":{\"__created_files__\":[\"shinkai://file/@@my_local_ai.sep-shinkai/main/jobid_c93837a6-358b-4648-9617-1d6e93d0bb59/logs/log_jobid_c93837a6-358b-4648-9617-1d6e93d0bb59_localduckduckgo_searchduckduckgo_search.log\"],\"message\":\"[{\\\"title\\\":\\\"Movie Tickets &amp; Movie Times | Fandango\\\",\\\"description\\\":\\\"Honoring the Best <b>movies</b> &amp; TV. Check out the winners from this year&#x27;s 26th annual Rotten Tomatoes Awards. LEARN MORE. Collectors, assemble! image link. Collectors, assemble! Suit up and get the Captain America Collector Pack, featuring an exclusive Collector&#x27;s Coin, Limited-Edition Poster, and one <b>movie</b> ticket!\\\",\\\"url\\\":\\\"https://www.fandango.com/\\\"}]\"}}",
}),
100,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ mod tests {
"response": null,
"tool_router_key": null
},
"response": "{\"data\":{\"__created_files__\":[\"shinkai://file/@@my_local_ai.arb-sep-shinkai/main/jobid_c93837a6-358b-4648-9617-1d6e93d0bb59/logs/log_jobid_c93837a6-358b-4648-9617-1d6e93d0bb59_localduckduckgo_searchduckduckgo_search.log\"],\"message\":\"[{\\\"title\\\":\\\"Movie Tickets &amp; Movie Times | Fandango\\\",\\\"description\\\":\\\"Honoring the Best <b>movies</b> &amp; TV. Check out the winners from this year&#x27;s 26th annual Rotten Tomatoes Awards. LEARN MORE. Collectors, assemble! image link. Collectors, assemble! Suit up and get the Captain America Collector Pack, featuring an exclusive Collector&#x27;s Coin, Limited-Edition Poster, and one <b>movie</b> ticket!\\\",\\\"url\\\":\\\"https://www.fandango.com/\\\"}]\"}}",
"response": "{\"data\":{\"__created_files__\":[\"shinkai://file/@@my_local_ai.sep-shinkai/main/jobid_c93837a6-358b-4648-9617-1d6e93d0bb59/logs/log_jobid_c93837a6-358b-4648-9617-1d6e93d0bb59_localduckduckgo_searchduckduckgo_search.log\"],\"message\":\"[{\\\"title\\\":\\\"Movie Tickets &amp; Movie Times | Fandango\\\",\\\"description\\\":\\\"Honoring the Best <b>movies</b> &amp; TV. Check out the winners from this year&#x27;s 26th annual Rotten Tomatoes Awards. LEARN MORE. Collectors, assemble! image link. Collectors, assemble! Suit up and get the Captain America Collector Pack, featuring an exclusive Collector&#x27;s Coin, Limited-Edition Poster, and one <b>movie</b> ticket!\\\",\\\"url\\\":\\\"https://www.fandango.com/\\\"}]\"}}",
}),
100,
),
Expand Down Expand Up @@ -572,7 +572,7 @@ mod tests {
{
"role": "user",
"parts": [{
"text": "{\"data\":{\"__created_files__\":[\"shinkai://file/@@my_local_ai.arb-sep-shinkai/main/jobid_c93837a6-358b-4648-9617-1d6e93d0bb59/logs/log_jobid_c93837a6-358b-4648-9617-1d6e93d0bb59_localduckduckgo_searchduckduckgo_search.log\"],\"message\":\"[{\\\"title\\\":\\\"Movie Tickets &amp; Movie Times | Fandango\\\",\\\"description\\\":\\\"Honoring the Best <b>movies</b> &amp; TV. Check out the winners from this year&#x27;s 26th annual Rotten Tomatoes Awards. LEARN MORE. Collectors, assemble! image link. Collectors, assemble! Suit up and get the Captain America Collector Pack, featuring an exclusive Collector&#x27;s Coin, Limited-Edition Poster, and one <b>movie</b> ticket!\\\",\\\"url\\\":\\\"https://www.fandango.com/\\\"}]\"}}",
"text": "{\"data\":{\"__created_files__\":[\"shinkai://file/@@my_local_ai.sep-shinkai/main/jobid_c93837a6-358b-4648-9617-1d6e93d0bb59/logs/log_jobid_c93837a6-358b-4648-9617-1d6e93d0bb59_localduckduckgo_searchduckduckgo_search.log\"],\"message\":\"[{\\\"title\\\":\\\"Movie Tickets &amp; Movie Times | Fandango\\\",\\\"description\\\":\\\"Honoring the Best <b>movies</b> &amp; TV. Check out the winners from this year&#x27;s 26th annual Rotten Tomatoes Awards. LEARN MORE. Collectors, assemble! image link. Collectors, assemble! Suit up and get the Captain America Collector Pack, featuring an exclusive Collector&#x27;s Coin, Limited-Edition Poster, and one <b>movie</b> ticket!\\\",\\\"url\\\":\\\"https://www.fandango.com/\\\"}]\"}}",
}]
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl IdentityNetworkManager {
let node_base = node.split(':').next().unwrap_or(node);
node_base.ends_with(".sepolia-shinkai") ||
node_base.ends_with(".shinkai") ||
node_base.ends_with(".arb-sep-shinkai")
node_base.ends_with(".sep-shinkai")
}) {
// Call the proxy node to get the actual data
let proxy_identity = record.address_or_proxy_nodes.clone();
Expand Down
4 changes: 2 additions & 2 deletions shinkai-bin/shinkai-node/src/managers/tool_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ impl ToolRouter {
name: "network__echo".to_string(),
description: "Echoes the input message".to_string(),
version: "0.1".to_string(),
provider: ShinkaiName::new("@@agent_provider.arb-sep-shinkai".to_string()).unwrap(),
provider: ShinkaiName::new("@@agent_provider.sep-shinkai".to_string()).unwrap(),
author: "@@official.shinkai".to_string(),
usage_type: usage_type.clone(),
activated: true,
Expand Down Expand Up @@ -339,7 +339,7 @@ impl ToolRouter {
name: "youtube_transcript_with_timestamps".to_string(),
description: "Takes a YouTube link and summarizes the content by creating multiple sections with a summary and a timestamp.".to_string(),
version: "0.1".to_string(),
provider: ShinkaiName::new("@@agent_provider.arb-sep-shinkai".to_string()).unwrap(),
provider: ShinkaiName::new("@@agent_provider.sep-shinkai".to_string()).unwrap(),
author: "@@official.shinkai".to_string(),
usage_type: usage_type.clone(),
activated: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -946,11 +946,11 @@ mod tests {
}

fn default_test_profile() -> ShinkaiName {
ShinkaiName::new("@@localhost.arb-sep-shinkai/main".to_string()).unwrap()
ShinkaiName::new("@@localhost.sep-shinkai/main".to_string()).unwrap()
}

fn node_name() -> ShinkaiName {
ShinkaiName::new("@@localhost.arb-sep-shinkai".to_string()).unwrap()
ShinkaiName::new("@@localhost.sep-shinkai".to_string()).unwrap()
}

// async fn setup_default_vector_fs() -> VectorFS {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ mod tests {
let (_, node1_encryption_pk) = unsafe_deterministic_encryption_keypair(0);

let dummy_standard_identity = Identity::Standard(StandardIdentity {
full_identity_name: ShinkaiName::new("@@localhost.arb-sep-shinkai/main".to_string()).unwrap(),
full_identity_name: ShinkaiName::new("@@localhost.sep-shinkai/main".to_string()).unwrap(),
addr: None,
node_encryption_public_key: node1_encryption_pk,
node_signature_public_key: node1_identity_pk,
Expand All @@ -690,15 +690,15 @@ mod tests {
#[async_trait]
impl IdentityManagerTrait for MockIdentityManager {
fn find_by_identity_name(&self, _full_profile_name: ShinkaiName) -> Option<&Identity> {
if _full_profile_name.to_string() == "@@localhost.arb-sep-shinkai/main" {
if _full_profile_name.to_string() == "@@localhost.sep-shinkai/main" {
Some(&self.dummy_standard_identity)
} else {
None
}
}

async fn search_identity(&self, full_identity_name: &str) -> Option<Identity> {
if full_identity_name == "@@localhost.arb-sep-shinkai/main" {
if full_identity_name == "@@localhost.sep-shinkai/main" {
Some(self.dummy_standard_identity.clone())
} else {
None
Expand All @@ -713,7 +713,7 @@ mod tests {
&self,
full_profile_name: &str,
) -> Result<StandardIdentity, String> {
if full_profile_name == "@@localhost.arb-sep-shinkai" {
if full_profile_name == "@@localhost.sep-shinkai" {
if let Identity::Standard(identity) = &self.dummy_standard_identity {
Ok(identity.clone())
} else {
Expand All @@ -734,11 +734,11 @@ mod tests {
}

fn default_test_profile() -> ShinkaiName {
ShinkaiName::new("@@localhost.arb-sep-shinkai/main".to_string()).unwrap()
ShinkaiName::new("@@localhost.sep-shinkai/main".to_string()).unwrap()
}

fn node_name() -> ShinkaiName {
ShinkaiName::new("@@localhost.arb-sep-shinkai".to_string()).unwrap()
ShinkaiName::new("@@localhost.sep-shinkai".to_string()).unwrap()
}

// async fn setup_default_vector_fs() -> VectorFS {
Expand Down Expand Up @@ -777,7 +777,7 @@ mod tests {
// ));

// let tool_router = Arc::new(ToolRouter::new(lance_db.clone()));
// let node_name = ShinkaiName::new("@@localhost.arb-sep-shinkai/main".to_string()).unwrap();
// let node_name = ShinkaiName::new("@@localhost.sep-shinkai/main".to_string()).unwrap();

// let (my_signature_secret_key, _) = unsafe_deterministic_signature_keypair(0);
// let (my_encryption_secret_key, _) = unsafe_deterministic_encryption_keypair(0);
Expand Down Expand Up @@ -808,7 +808,7 @@ mod tests {
// "shinkai_toolkit".to_string(),
// "A tool for testing".to_string(),
// "1.0".to_string(),
// ShinkaiName::new("@@localhost.arb-sep-shinkai".to_string()).unwrap(),
// ShinkaiName::new("@@localhost.sep-shinkai".to_string()).unwrap(),
// UsageType::PerUse(ToolPrice::DirectDelegation("0.01".to_string())),
// true,
// vec![],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use shinkai_message_primitives::{
},
shinkai_utils::{
job_scope::MinimalJobScope, shinkai_message_builder::ShinkaiMessageBuilder,
signatures::clone_signature_secret_key, shinkai_path::ShinkaiPath,
signatures::clone_signature_secret_key,
},
};

Expand Down Expand Up @@ -517,7 +517,8 @@ impl Node {
};

// Retrieve all smart inboxes for the profile with pagination
let paginated_inboxes = match db.get_all_smart_inboxes_for_profile_with_pagination(main_identity, limit, offset) {
let paginated_inboxes = match db.get_all_smart_inboxes_for_profile_with_pagination(main_identity, limit, offset)
{
Ok(inboxes) => inboxes,
Err(err) => {
let api_error = APIError {
Expand All @@ -531,7 +532,8 @@ impl Node {
};

// Convert SmartInbox to V2SmartInbox
let v2_smart_inboxes: Result<Vec<V2SmartInbox>, NodeError> = paginated_inboxes.inboxes
let v2_smart_inboxes: Result<Vec<V2SmartInbox>, NodeError> = paginated_inboxes
.inboxes
.into_iter()
.map(Self::convert_smart_inbox_to_v2_smart_inbox)
.collect();
Expand Down Expand Up @@ -1802,4 +1804,3 @@ impl Node {
Ok(())
}
}

4 changes: 2 additions & 2 deletions shinkai-bin/shinkai-node/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ pub async fn initialize_node() -> Result<
let global_identity_name = secrets
.get("GLOBAL_IDENTITY_NAME")
.cloned()
.unwrap_or_else(|| env::var("GLOBAL_IDENTITY_NAME").unwrap_or("@@localhost.arb-sep-shinkai".to_string()));
.unwrap_or_else(|| env::var("GLOBAL_IDENTITY_NAME").unwrap_or("@@localhost.sep-shinkai".to_string()));

let global_identity_name = if global_identity_name.is_empty() {
"@@localhost.arb-sep-shinkai".to_string()
"@@localhost.sep-shinkai".to_string()
} else {
global_identity_name
};
Expand Down
2 changes: 1 addition & 1 deletion shinkai-bin/shinkai-node/src/utils/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub fn fetch_llm_provider_env(global_identity: String) -> Vec<SerializedLLMProvi
}

pub fn fetch_node_environment() -> NodeEnvironment {
let global_identity_name = env::var("GLOBAL_IDENTITY_NAME").unwrap_or("@@localhost.arb-sep-shinkai".to_string());
let global_identity_name = env::var("GLOBAL_IDENTITY_NAME").unwrap_or("@@localhost.sep-shinkai".to_string());

// Fetch the environment variables for the IP and port, or use default values
let ip: IpAddr = env::var("NODE_IP")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ fn micropayment_flow_test() {
let rt = Runtime::new().unwrap();

rt.block_on(async {
let node1_identity_name = "@@node1_test.arb-sep-shinkai";
let node2_identity_name = "@@node2_test.arb-sep-shinkai";
let node1_identity_name = "@@node1_test.sep-shinkai";
let node2_identity_name = "@@node2_test.sep-shinkai";
let node1_profile_name = "main";
let node1_device_name = "node1_device";
let node2_profile_name = "main_profile_node2";
Expand Down Expand Up @@ -296,7 +296,7 @@ fn micropayment_flow_test() {
// node2 receives the result and stores it
// done

let test_network_tool_name = "@@node1_test.arb-sep-shinkai:::shinkai-tool-echo:::network__echo";
let test_network_tool_name = "@@node1_test.sep-shinkai:::shinkai-tool-echo:::network__echo";
let test_local_tool_key_name = "local:::shinkai-tool-echo:::network__echo";

let shinkai_tool_offering = ShinkaiToolOffering {
Expand Down
Loading

0 comments on commit 140315d

Please sign in to comment.