added card stuff to convert to konami id
This commit is contained in:
parent
651d18ca80
commit
27f5da4847
@ -5,7 +5,10 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1.82"
|
async-trait = "0.1.82"
|
||||||
|
byteorder = "1.5.0"
|
||||||
|
cbc = "0.1.2"
|
||||||
chrono = "0.4.38"
|
chrono = "0.4.38"
|
||||||
|
des = "0.8.1"
|
||||||
kbinxml = { git = "https://github.com/mbilker/kbinxml-rs.git", version = "3.1.1" }
|
kbinxml = { git = "https://github.com/mbilker/kbinxml-rs.git", version = "3.1.1" }
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
lz77 = "0.1.0"
|
lz77 = "0.1.0"
|
||||||
|
@ -176,6 +176,69 @@ impl GetServicesHandler {
|
|||||||
}
|
}
|
||||||
services
|
services
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_pan_services<'a>(
|
||||||
|
mut services: Vec<XmlEvent<'a>>,
|
||||||
|
common_url: &'a str,
|
||||||
|
) -> Vec<XmlEvent<'a>> {
|
||||||
|
let m39_services = vec![
|
||||||
|
"local", "local2", "lobby", "slocal", "slocal2", "sglocal", "sglocal2", "lab",
|
||||||
|
"globby", "slobby", "sglobby",
|
||||||
|
];
|
||||||
|
|
||||||
|
for service in m39_services {
|
||||||
|
services.push(
|
||||||
|
XmlEvent::start_element("item")
|
||||||
|
.attr("name", service)
|
||||||
|
.attr("url", &common_url)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
services.push(XmlEvent::end_element().into());
|
||||||
|
}
|
||||||
|
services
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_ujk_services<'a>(
|
||||||
|
mut services: Vec<XmlEvent<'a>>,
|
||||||
|
common_url: &'a str,
|
||||||
|
) -> Vec<XmlEvent<'a>> {
|
||||||
|
let m39_services = vec![
|
||||||
|
"local", "local2", "lobby", "slocal", "slocal2", "sglocal", "sglocal2", "lab",
|
||||||
|
"globby", "slobby", "sglobby",
|
||||||
|
];
|
||||||
|
|
||||||
|
for service in m39_services {
|
||||||
|
services.push(
|
||||||
|
XmlEvent::start_element("item")
|
||||||
|
.attr("name", service)
|
||||||
|
.attr("url", &common_url)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
services.push(XmlEvent::end_element().into());
|
||||||
|
}
|
||||||
|
services
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_l44_services<'a>(
|
||||||
|
mut services: Vec<XmlEvent<'a>>,
|
||||||
|
common_url: &'a str,
|
||||||
|
) -> Vec<XmlEvent<'a>> {
|
||||||
|
let m39_services = vec![
|
||||||
|
"local", "local2", "lobby", "slocal", "slocal2", "sglocal", "sglocal2", "lab",
|
||||||
|
"globby", "slobby", "sglobby",
|
||||||
|
];
|
||||||
|
|
||||||
|
for service in m39_services {
|
||||||
|
services.push(
|
||||||
|
XmlEvent::start_element("item")
|
||||||
|
.attr("name", service)
|
||||||
|
.attr("url", &common_url)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
services.push(XmlEvent::end_element().into());
|
||||||
|
}
|
||||||
|
services
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@ -201,6 +264,9 @@ impl Handler for GetServicesHandler {
|
|||||||
Some("MDX") => GetServicesHandler::add_mdx_services(services, &common_url),
|
Some("MDX") => GetServicesHandler::add_mdx_services(services, &common_url),
|
||||||
Some("M39") => GetServicesHandler::add_m39_services(services, &common_url),
|
Some("M39") => GetServicesHandler::add_m39_services(services, &common_url),
|
||||||
Some("M32") => GetServicesHandler::add_m32_services(services, &common_url),
|
Some("M32") => GetServicesHandler::add_m32_services(services, &common_url),
|
||||||
|
Some("PAN") => GetServicesHandler::add_pan_services(services, &common_url),
|
||||||
|
Some("UJK") => GetServicesHandler::add_ujk_services(services, &common_url),
|
||||||
|
Some("L44") => GetServicesHandler::add_l44_services(services, &common_url),
|
||||||
_ => services,
|
_ => services,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
98
src/handlers/common/card/inquire_card_managment_handler.rs
Normal file
98
src/handlers/common/card/inquire_card_managment_handler.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
use crate::{handlers::handler::Handler, utils::card_convert::CardConvert};
|
||||||
|
use std::io::{BufReader, Cursor};
|
||||||
|
use xml::{
|
||||||
|
reader::{EventReader, XmlEvent},
|
||||||
|
EmitterConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct InquireCardManagment {
|
||||||
|
card_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InquireCardManagmentHandler {
|
||||||
|
module: String,
|
||||||
|
method: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InquireCardManagmentHandler {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
InquireCardManagmentHandler {
|
||||||
|
module: "cardmng".to_string(),
|
||||||
|
method: "inquire".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_inquire_card_managment(xml_data: &str) -> Option<InquireCardManagment> {
|
||||||
|
let reader = EventReader::new(BufReader::new(xml_data.as_bytes()));
|
||||||
|
let mut inquire_card_managment = InquireCardManagment {
|
||||||
|
card_id: String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for event in reader {
|
||||||
|
match event {
|
||||||
|
Ok(XmlEvent::StartElement {
|
||||||
|
name, attributes, ..
|
||||||
|
}) => {
|
||||||
|
if name.local_name == "cardmng" {
|
||||||
|
for attr in attributes {
|
||||||
|
match attr.name.local_name.as_str() {
|
||||||
|
"cardid" => inquire_card_managment.card_id = attr.value.clone(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
print!("Error: {}", e);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(inquire_card_managment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Handler for InquireCardManagmentHandler {
|
||||||
|
fn module(&self) -> &str {
|
||||||
|
&self.module
|
||||||
|
}
|
||||||
|
|
||||||
|
fn method(&self) -> &str {
|
||||||
|
&self.method
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle(&self, _model: String, body: String) -> String {
|
||||||
|
let card_managment = Self::parse_inquire_card_managment(body.as_str()).unwrap();
|
||||||
|
|
||||||
|
let mut buffer = Cursor::new(vec![]);
|
||||||
|
let mut writer = EmitterConfig::new()
|
||||||
|
.perform_indent(true)
|
||||||
|
.create_writer(&mut buffer);
|
||||||
|
|
||||||
|
writer
|
||||||
|
.write(xml::writer::XmlEvent::start_element("response"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if card_managment.card_id == "" {
|
||||||
|
writer.write(xml::writer::XmlEvent::start_element("cardmng")
|
||||||
|
.attr("status", "111")).unwrap();
|
||||||
|
|
||||||
|
writer.write(xml::writer::XmlEvent::end_element()).unwrap();
|
||||||
|
writer.write(xml::writer::XmlEvent::end_element()).unwrap();
|
||||||
|
return String::from_utf8(buffer.into_inner()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
let konami_id = CardConvert::to_konami_id(card_managment.card_id);
|
||||||
|
|
||||||
|
if konami_id.is_some() {
|
||||||
|
println!("Konami id: {}", konami_id.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.write(xml::writer::XmlEvent::end_element()).unwrap();
|
||||||
|
|
||||||
|
String::from_utf8(buffer.into_inner()).unwrap()
|
||||||
|
}
|
||||||
|
}
|
1
src/handlers/common/card/mod.rs
Normal file
1
src/handlers/common/card/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod inquire_card_managment_handler;
|
@ -3,4 +3,5 @@ pub mod alive_pcb_tracker_handler;
|
|||||||
pub mod get_messages_handler;
|
pub mod get_messages_handler;
|
||||||
pub mod put_pcb_event_handler;
|
pub mod put_pcb_event_handler;
|
||||||
|
|
||||||
pub mod ota;
|
pub mod ota;
|
||||||
|
pub mod card;
|
@ -4,8 +4,6 @@ use xml::{reader::{EventReader, XmlEvent}, EmitterConfig};
|
|||||||
|
|
||||||
use crate::handlers::handler::Handler;
|
use crate::handlers::handler::Handler;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct PcbEvent {
|
struct PcbEvent {
|
||||||
tag: String,
|
tag: String,
|
||||||
src_id: String,
|
src_id: String,
|
||||||
|
@ -6,9 +6,11 @@ mod parsers;
|
|||||||
mod generators;
|
mod generators;
|
||||||
mod handlers;
|
mod handlers;
|
||||||
mod routes;
|
mod routes;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
use handlers::boot::get_services_handler::GetServicesHandler;
|
use handlers::boot::get_services_handler::GetServicesHandler;
|
||||||
use handlers::common::alive_pcb_tracker_handler::AlivePcbTrackerHandler;
|
use handlers::common::alive_pcb_tracker_handler::AlivePcbTrackerHandler;
|
||||||
|
use handlers::common::card::inquire_card_managment_handler::InquireCardManagmentHandler;
|
||||||
use handlers::common::get_messages_handler::GetMessageHandler;
|
use handlers::common::get_messages_handler::GetMessageHandler;
|
||||||
use handlers::common::ota::list_package_handler::ListPackageHandler;
|
use handlers::common::ota::list_package_handler::ListPackageHandler;
|
||||||
use handlers::common::ota::progress_dl_status_handler::ProgressDLStatusHandler;
|
use handlers::common::ota::progress_dl_status_handler::ProgressDLStatusHandler;
|
||||||
@ -35,6 +37,7 @@ fn register_handlers() -> Vec<Arc<dyn Handler>> {
|
|||||||
let put_pcb_event_handler = Arc::new(PutPcbEventHandler::new());
|
let put_pcb_event_handler = Arc::new(PutPcbEventHandler::new());
|
||||||
let list_package_handler = Arc::new(ListPackageHandler::new());
|
let list_package_handler = Arc::new(ListPackageHandler::new());
|
||||||
let progress_dl_status_handler = Arc::new(ProgressDLStatusHandler::new());
|
let progress_dl_status_handler = Arc::new(ProgressDLStatusHandler::new());
|
||||||
|
let inquire_card_managment_handler = Arc::new(InquireCardManagmentHandler::new());
|
||||||
|
|
||||||
let handlers: Vec<Arc<dyn Handler>> = vec![
|
let handlers: Vec<Arc<dyn Handler>> = vec![
|
||||||
get_services_handler,
|
get_services_handler,
|
||||||
@ -42,7 +45,8 @@ fn register_handlers() -> Vec<Arc<dyn Handler>> {
|
|||||||
get_messages_handler,
|
get_messages_handler,
|
||||||
put_pcb_event_handler,
|
put_pcb_event_handler,
|
||||||
list_package_handler,
|
list_package_handler,
|
||||||
progress_dl_status_handler
|
progress_dl_status_handler,
|
||||||
|
inquire_card_managment_handler
|
||||||
];
|
];
|
||||||
|
|
||||||
handlers
|
handlers
|
||||||
|
128
src/utils/card_convert.rs
Normal file
128
src/utils/card_convert.rs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
|
||||||
|
use super::triple_des;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref ALPHABET: Vec<char> = "0123456789ABCDEFGHJKLMNPRSTUWXYZ".chars().collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref RAWKEY: Vec<u8> = {
|
||||||
|
"?I'llB2c.YouXXXeMeHaYpy!"
|
||||||
|
.chars()
|
||||||
|
.filter_map(|c| if c.is_ascii() { Some(c as u8) } else { None })
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CardConvert {}
|
||||||
|
|
||||||
|
impl CardConvert {
|
||||||
|
pub fn to_konami_id(card_id: String) -> Option<String> {
|
||||||
|
if card_id.len() != 16 {
|
||||||
|
eprintln!("Invalid UID length must be 16 characters");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let card_type: i32 = if card_id.starts_with("E004") {
|
||||||
|
1
|
||||||
|
} else if card_id.starts_with('0') {
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
if card_type == -1 {
|
||||||
|
eprintln!("Invalid UID prefix");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut konami_id: Vec<u8> = (0..card_id.len() / 2)
|
||||||
|
.map(|x| u8::from_str_radix(&card_id[x * 2..x * 2 + 2], 16).unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
konami_id.reverse();
|
||||||
|
|
||||||
|
if konami_id.len() != 8 {
|
||||||
|
eprintln!("Invalid UID length. Must be 8 bytes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let konami_id = triple_des::encrypt(
|
||||||
|
&konami_id,
|
||||||
|
&Self::generate_encryption_key(),
|
||||||
|
konami_id.len(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if konami_id.len() != 8 {
|
||||||
|
eprintln!("Invalid UID length. Must be 8 bytes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let konami_id = Self::unpack_5(&konami_id);
|
||||||
|
|
||||||
|
let mut konami_id = [&konami_id[..13], &[0, 0, 0]].concat();
|
||||||
|
|
||||||
|
if konami_id.len() != 16 {
|
||||||
|
eprintln!("Invalid unpacked ID length. Must be 16 bytes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
konami_id[0] ^= card_type as u8;
|
||||||
|
konami_id[13] = 1;
|
||||||
|
|
||||||
|
for i in 1..14 {
|
||||||
|
konami_id[i] ^= konami_id[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
konami_id[14] = card_type as u8;
|
||||||
|
konami_id[15] = Self::calculate_checksum(konami_id.clone());
|
||||||
|
|
||||||
|
Some(konami_id.iter().map(|&byte| ALPHABET[byte as usize]).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_encryption_key() -> Vec<u8> {
|
||||||
|
RAWKEY.iter().map(|&x| x * 2).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack_5(data: &[u8]) -> Vec<u8> {
|
||||||
|
// Convert each byte to an 8-bit binary string and concatenate them
|
||||||
|
let binary_string: String = data.iter().map(|&b| format!("{:08b}", b)).collect();
|
||||||
|
|
||||||
|
// Ensure the total length is a multiple of 5 by padding with zeroes if necessary
|
||||||
|
let remainder = binary_string.len() % 5;
|
||||||
|
let padded_binary_string = if remainder != 0 {
|
||||||
|
let padding_length = 5 - remainder;
|
||||||
|
format!("{}{}", binary_string, "0".repeat(padding_length))
|
||||||
|
} else {
|
||||||
|
binary_string
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert the 5-bit chunks back into bytes
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for chunk in padded_binary_string.as_bytes().chunks(5) {
|
||||||
|
let chunk_str = std::str::from_utf8(chunk).unwrap();
|
||||||
|
let byte = u8::from_str_radix(chunk_str, 2).unwrap();
|
||||||
|
result.push(byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_checksum(konami_id: Vec<u8>) -> u8 {
|
||||||
|
let mut checksum: u8 = 0;
|
||||||
|
|
||||||
|
for i in 0..15 {
|
||||||
|
if i >= konami_id.len() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum = checksum.wrapping_add(konami_id[i] * ((i % 3) + 1) as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
while checksum > 31 {
|
||||||
|
checksum = (checksum >> 5) + (checksum & 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum as u8
|
||||||
|
}
|
||||||
|
}
|
3
src/utils/mod.rs
Normal file
3
src/utils/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
pub mod card_convert;
|
||||||
|
pub mod triple_des;
|
46
src/utils/triple_des.rs
Normal file
46
src/utils/triple_des.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use des::TdesEde3;
|
||||||
|
use cbc::cipher::{KeyIvInit, BlockEncryptMut, BlockDecryptMut};
|
||||||
|
|
||||||
|
// Alias for Triple DES CBC encryption
|
||||||
|
type TdesCbc = cbc::Encryptor<TdesEde3>;
|
||||||
|
|
||||||
|
// Alias for Triple DES CBC decryption
|
||||||
|
type TdesCbcDecryptor = cbc::Decryptor<TdesEde3>;
|
||||||
|
|
||||||
|
// Function to encrypt the data using Triple DES in CBC mode with no padding
|
||||||
|
pub fn encrypt(data: &[u8], key: &[u8], msg_size: usize) -> Vec<u8> {
|
||||||
|
// All-zero IV (8 bytes)
|
||||||
|
let iv = [0u8; 8];
|
||||||
|
|
||||||
|
// Create the Triple DES CBC encryptor with the key and IV
|
||||||
|
let cipher = TdesCbc::new(key.into(), &iv.into());
|
||||||
|
|
||||||
|
// Since padding is set to None, the input must be a multiple of the block size (8 bytes for DES/3DES)
|
||||||
|
assert!(data.len() % 8 == 0, "Input data must be a multiple of 8 bytes");
|
||||||
|
|
||||||
|
// Create a mutable buffer from the input data
|
||||||
|
let mut buffer = data.to_vec();
|
||||||
|
|
||||||
|
// Encrypt the data in place
|
||||||
|
cipher.encrypt_padded_mut::<cbc::cipher::block_padding::NoPadding>(&mut buffer, msg_size)
|
||||||
|
.expect("Encryption failed").to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to decrypt the data using Triple DES in CBC mode with no padding
|
||||||
|
pub fn decrypt(data: &[u8], key: &[u8]) -> Vec<u8> {
|
||||||
|
// All-zero IV (8 bytes)
|
||||||
|
let iv = [0u8; 8];
|
||||||
|
|
||||||
|
// Create the Triple DES CBC decryptor with the key and IV
|
||||||
|
let mut cipher = TdesCbcDecryptor::new(key.into(), &iv.into());
|
||||||
|
|
||||||
|
// Since padding is set to None, the input must be a multiple of the block size (8 bytes for DES/3DES)
|
||||||
|
assert!(data.len() % 8 == 0, "Input data must be a multiple of 8 bytes");
|
||||||
|
|
||||||
|
// Create a mutable buffer from the input data
|
||||||
|
let mut buffer = data.to_vec();
|
||||||
|
|
||||||
|
// Decrypt the data in place
|
||||||
|
cipher.decrypt_padded_mut::<cbc::cipher::block_padding::NoPadding>(&mut buffer)
|
||||||
|
.expect("Decryption failed").to_vec()
|
||||||
|
}
|
21
web/vite.config.ts.timestamp-1725920055853-df6655ad6213d.mjs
Normal file
21
web/vite.config.ts.timestamp-1725920055853-df6655ad6213d.mjs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// vite.config.ts
|
||||||
|
import { fileURLToPath, URL } from "node:url";
|
||||||
|
import { defineConfig } from "file:///D:/ProjectsOld/Rust/Medusa/web/node_modules/vite/dist/node/index.js";
|
||||||
|
import vue from "file:///D:/ProjectsOld/Rust/Medusa/web/node_modules/@vitejs/plugin-vue/dist/index.mjs";
|
||||||
|
import vueDevTools from "file:///D:/ProjectsOld/Rust/Medusa/web/node_modules/vite-plugin-vue-devtools/dist/vite.mjs";
|
||||||
|
var __vite_injected_original_import_meta_url = "file:///D:/ProjectsOld/Rust/Medusa/web/vite.config.ts";
|
||||||
|
var vite_config_default = defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
vueDevTools()
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": fileURLToPath(new URL("./src", __vite_injected_original_import_meta_url))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
export {
|
||||||
|
vite_config_default as default
|
||||||
|
};
|
||||||
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxQcm9qZWN0c09sZFxcXFxSdXN0XFxcXE1lZHVzYVxcXFx3ZWJcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkQ6XFxcXFByb2plY3RzT2xkXFxcXFJ1c3RcXFxcTWVkdXNhXFxcXHdlYlxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRDovUHJvamVjdHNPbGQvUnVzdC9NZWR1c2Evd2ViL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZmlsZVVSTFRvUGF0aCwgVVJMIH0gZnJvbSAnbm9kZTp1cmwnXHJcblxyXG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJ1xyXG5pbXBvcnQgdnVlIGZyb20gJ0B2aXRlanMvcGx1Z2luLXZ1ZSdcclxuaW1wb3J0IHZ1ZURldlRvb2xzIGZyb20gJ3ZpdGUtcGx1Z2luLXZ1ZS1kZXZ0b29scydcclxuXHJcbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXHJcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XHJcbiAgcGx1Z2luczogW1xyXG4gICAgdnVlKCksXHJcbiAgICB2dWVEZXZUb29scygpLFxyXG4gIF0sXHJcbiAgcmVzb2x2ZToge1xyXG4gICAgYWxpYXM6IHtcclxuICAgICAgJ0AnOiBmaWxlVVJMVG9QYXRoKG5ldyBVUkwoJy4vc3JjJywgaW1wb3J0Lm1ldGEudXJsKSlcclxuICAgIH1cclxuICB9XHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBc1IsU0FBUyxlQUFlLFdBQVc7QUFFelQsU0FBUyxvQkFBb0I7QUFDN0IsT0FBTyxTQUFTO0FBQ2hCLE9BQU8saUJBQWlCO0FBSnFKLElBQU0sMkNBQTJDO0FBTzlOLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVM7QUFBQSxJQUNQLElBQUk7QUFBQSxJQUNKLFlBQVk7QUFBQSxFQUNkO0FBQUEsRUFDQSxTQUFTO0FBQUEsSUFDUCxPQUFPO0FBQUEsTUFDTCxLQUFLLGNBQWMsSUFBSSxJQUFJLFNBQVMsd0NBQWUsQ0FBQztBQUFBLElBQ3REO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
Loading…
Reference in New Issue
Block a user