Commit feae79dd authored by xinzhedeai's avatar xinzhedeai

add:同步 from liqilin 1219

parent 47dfce11
......@@ -68,5 +68,7 @@ VITE_SERVICE_URL=http://192.168.2.53:9995
# 模型地址环境
VITE_MODEL_URL=http://192.168.2.53:9995/model
# 开发环境 - WebSocket 全局地址
# VITE_WEBSOCKET_URL=ws://192.168.3.248:9996
\ No newline at end of file
......@@ -6,17 +6,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<!-- 外部 - 依赖库 -->
<!-- <script src="./public/js/proj4.js"></script>
<script src="./public/js/turf.min.js"></script>
<script src="./public/js/echarts.min.js"></script> -->
<!-- 外部 - 依赖库 -->
<script src="./public/js/proj4.js"></script>
<script src="./public/js/turf.min.js"></script>
<link rel="stylesheet" type="text/css" href="./Cesium/Widgets/widgets.css" />
<script type="text/javascript" src="/public/webrtcstreamer.js"></script>
<script type="text/javascript" src="./Cesium/Cesium.js"></script>
<script src="./public/codebase/webVideoCtrl.js"></script>
<script src="./public/jquery-1.7.1.min.js"></script>
<script src="/public/jquery-1.7.1.min.js"></script>
<title>%VITE_APP_TITLE%</title>
</head>
......
......@@ -29,9 +29,15 @@ importers:
'@sa/utils':
specifier: workspace:*
version: link:packages/utils
'@vicons/fa':
specifier: ^0.13.0
version: 0.13.0
'@vicons/fluent':
specifier: ^0.13.0
version: 0.13.0
'@vicons/ionicons4':
specifier: ^0.13.0
version: 0.13.0
'@vueuse/core':
specifier: 14.0.0
version: 14.0.0(vue@3.5.22(typescript@5.9.3))
......@@ -1455,9 +1461,15 @@ packages:
cpu: [x64]
os: [win32]
'@vicons/fa@0.13.0':
resolution: {integrity: sha512-BFcDewcT78fSn4Y/fOgqlswbLUEW3+qJK2iJiNtgmkMzadBVpDXhNyVKsYM3V2uKPvDUrZT0JCWDWVRCiBXJZA==}
'@vicons/fluent@0.13.0':
resolution: {integrity: sha512-bYGZsOE3qzvm3Cm43e7tybgGlr5ZUpYqtRZq0g0Tfupe8jIzLolpvQLNUt1zS8Mgt6goTbUk5YH7Fkv16jkykg==}
'@vicons/ionicons4@0.13.0':
resolution: {integrity: sha512-5WHIl/4R5a4i9GONa+hIQWxg/WczrbsCdqxawHZvdd3drsEr+Q3yzlfS+NNRO4WS3uDW2uWLCwoW+yp5TgcKeQ==}
'@vicons/ionicons5@0.13.0':
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
......@@ -5441,8 +5453,12 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
optional: true
'@vicons/fa@0.13.0': {}
'@vicons/fluent@0.13.0': {}
'@vicons/ionicons4@0.13.0': {}
'@vicons/ionicons5@0.13.0': {}
'@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(sass@1.93.3)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))':
......
(function() {
var Nr = 10;
// convert two-dimensional indicies to one-dim array indices
var I00 = 0;
var I01 = 1;
var I02 = 2;
var I03 = 3;
var I10 = 4;
var I11 = 5;
var I12 = 6;
var I13 = 7;
var I20 = 8;
var I21 = 9;
var I22 = 10;
var I23 = 11;
var I30 = 12;
var I31 = 13;
var I32 = 14;
var I33 = 15;
// S-Box substitution table
var S_enc = new Array(
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
// inverse S-Box for decryptions
var S_dec = new Array(
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
function cvt_hex8 (val) {
var vh = (val>>>4)&0x0f;
return vh.toString(16) + (val&0x0f).toString(16);
}
function cvt_byte (str) {
// get the first hex digit
var val1 = str.charCodeAt(0);
// do some error checking
if (val1 >= 48 && val1 <= 57) {
// have a valid digit 0-9
val1 -= 48;
} else if (val1 >= 65 && val1 <= 70) {
// have a valid digit A-F
val1 -= 55;
} else if (val1 >= 97 && val1 <= 102) {
// have a valid digit A-F
val1 -= 87;
} else {
// not 0-9 or A-F, complain
console.log( str.charAt(1)+" is not a valid hex digit" );
return -1;
}
// get the second hex digit
var val2 = str.charCodeAt(1);
// do some error checking
if ( val2 >= 48 && val2 <= 57 ) {
// have a valid digit 0-9
val2 -= 48;
} else if ( val2 >= 65 && val2 <= 70 ) {
// have a valid digit A-F
val2 -= 55;
} else if ( val2 >= 97 && val2 <= 102 ) {
// have a valid digit A-F
val2 -= 87;
} else {
// not 0-9 or A-F, complain
console.log( str.charAt(2)+" is not a valid hex digit" );
return -1;
}
// all is ok, return the value
return val1*16 + val2;
}
// conversion function for non-constant subscripts
// assume subscript range 0..3
function I(x,y) {
return (x*4) + y;
}
// remove spaces from input
function remove_spaces(instr) {
var i;
var outstr = "";
for(i=0; i<instr.length; i++) {
if ( instr.charAt(i) != " " )
// not a space, include it
outstr += instr.charAt(i);
}
return outstr;
}
// get the message to encrypt/decrypt or the key
// return as a 16-byte array
function get_value(str, isASCII) {
var dbyte = new Array(16);
var i;
var val; // one hex digit
if (isASCII) {
// check length of data
if (str.length > 16) {
console.log("is too long, using the first 16 ASCII characters" );
}
// have ASCII data
// 16 characters?
if (str.length >= 16) {
// 16 or more characters
for(i=0; i<16; i++) {
dbyte[i] = str.charCodeAt(i);
}
} else {
// less than 16 characters - fill with NULLs
for(i=0; i<str.length; i++) {
dbyte[i] = str.charCodeAt(i);
}
for( i=str.length; i<16; i++) {
dbyte[i] = 0;
}
}
} else {
// have hex data - remove any spaces they used, then convert
//str = remove_spaces(str);
// check length of data
if ( str.length != 32 ) {
//console.log("\tget_value:\tstr = " + str + "\tisASCII = " + isASCII); //isASCII = false
console.log("length wrong: Is " + str.length + " hex digits, but must be 128 bits (32 hex digits)");
dbyte[0] = -1;
return dbyte;
}
for( i=0; i<16; i++ ) {
// isolate and convert this substring
dbyte[i] = cvt_byte( str.substr(i*2,2) );
if( dbyte[i] < 0 ) {
// have an error
dbyte[0] = -1;
return dbyte;
}
}
}
// return successful conversion
return dbyte;
}
//do the AES GF(2**8) multiplication
// do this by the shift-and-"add" approach
function aes_mul(a, b) {
var res = 0;
while(a > 0) {
if((a&1) != 0)
res = res ^ b; // "add" to the result
a >>>= 1; // shift a to get next higher-order bit
b <<= 1; // shift multiplier also
}
// now reduce it modulo x**8 + x**4 + x**3 + x + 1
var hbit = 0x10000; // bit to test if we need to take action
var modulus = 0x11b00; // modulus - XOR by this to change value
while(hbit >= 0x100) {
if ((res & hbit) != 0) {
res ^= modulus; // XOR with the modulus
}
// prepare for the next loop
hbit >>= 1;
modulus >>= 1;
}
return res;
}
// apply the S-box substitution to the key expansion
function SubWord(word_ary) {
var i;
for(i=0; i<16; i++) {
word_ary[i] = S_enc[word_ary[i]];
}
return word_ary;
}
// rotate the bytes in a word
function RotWord(word_ary) {
return new Array(word_ary[1], word_ary[2], word_ary[3], word_ary[0]);
}
// calculate the first item Rcon[i] = { x^(i-1), 0, 0, 0 }
// note we only return the first item
function Rcon(exp) {
var val = 2;
var result = 1;
// remember to calculate x^(exp-1)
exp--;
// process the exponent using normal shift and multiply
while ( exp > 0 )
{
if ( (exp & 1) != 0 )
result = aes_mul( result, val );
// square the value
val = aes_mul( val, val );
// move to the next bit
exp >>= 1;
}
return result;
}
// round key generation
// return a byte array with the expanded key information
function key_expand( key )
{
var temp = new Array(4);
var i, j;
var w = new Array(4*(Nr+1));
// copy initial key stuff
for( i=0; i<16; i++ )
{
w[i] = key[i];
}
// generate rest of key schedule using 32-bit words
i = 4;
while ( i < 4*(Nr+1)) // blocksize * ( rounds + 1 )
{
// copy word W[i-1] to temp
for( j=0; j<4; j++ )
temp[j] = w[(i-1)*4+j];
if ( i % 4 == 0)
{
// temp = SubWord(RotWord(temp)) ^ Rcon[i/4];
temp = RotWord( temp );
temp = SubWord( temp );
temp[0] ^= Rcon( i>>>2 );
}
// word = word ^ temp
for( j=0; j<4; j++ )
w[i*4+j] = w[(i-4)*4+j] ^ temp[j];
i++;
}
return w;
}
// do S-Box substitution
function SubBytes(state, Sbox)
{
var i;
for( i=0; i<16; i++ )
state[i] = Sbox[ state[i] ];
return state;
}
// shift each row as appropriate
function ShiftRows(state)
{
var t0, t1, t2, t3;
// top row (row 0) isn't shifted
// next row (row 1) rotated left 1 place
t0 = state[I10];
t1 = state[I11];
t2 = state[I12];
t3 = state[I13];
state[I10] = t1;
state[I11] = t2;
state[I12] = t3;
state[I13] = t0;
// next row (row 2) rotated left 2 places
t0 = state[I20];
t1 = state[I21];
t2 = state[I22];
t3 = state[I23];
state[I20] = t2;
state[I21] = t3;
state[I22] = t0;
state[I23] = t1;
// bottom row (row 3) rotated left 3 places
t0 = state[I30];
t1 = state[I31];
t2 = state[I32];
t3 = state[I33];
state[I30] = t3;
state[I31] = t0;
state[I32] = t1;
state[I33] = t2;
return state;
}
// inverset shift each row as appropriate
function InvShiftRows(state)
{
var t0, t1, t2, t3;
// top row (row 0) isn't shifted
// next row (row 1) rotated left 1 place
t0 = state[I10];
t1 = state[I11];
t2 = state[I12];
t3 = state[I13];
state[I10] = t3;
state[I11] = t0;
state[I12] = t1;
state[I13] = t2;
// next row (row 2) rotated left 2 places
t0 = state[I20];
t1 = state[I21];
t2 = state[I22];
t3 = state[I23];
state[I20] = t2;
state[I21] = t3;
state[I22] = t0;
state[I23] = t1;
// bottom row (row 3) rotated left 3 places
t0 = state[I30];
t1 = state[I31];
t2 = state[I32];
t3 = state[I33];
state[I30] = t1;
state[I31] = t2;
state[I32] = t3;
state[I33] = t0;
return state;
}
// process column info
function MixColumns(state)
{
var col;
var c0, c1, c2, c3;
for( col=0; col<4; col++ )
{
c0 = state[I(0,col)];
c1 = state[I(1,col)];
c2 = state[I(2,col)];
c3 = state[I(3,col)];
// do mixing, and put back into array
state[I(0,col)] = aes_mul(2,c0) ^ aes_mul(3,c1) ^ c2 ^ c3;
state[I(1,col)] = c0 ^ aes_mul(2,c1) ^ aes_mul(3,c2) ^ c3;
state[I(2,col)] = c0 ^ c1 ^ aes_mul(2,c2) ^ aes_mul(3,c3);
state[I(3,col)] = aes_mul(3,c0) ^ c1 ^ c2 ^ aes_mul(2,c3);
}
return state;
}
// inverse process column info
function InvMixColumns(state)
{
var col;
var c0, c1, c2, c3;
for( col=0; col<4; col++ )
{
c0 = state[I(0,col)];
c1 = state[I(1,col)];
c2 = state[I(2,col)];
c3 = state[I(3,col)];
// do inverse mixing, and put back into array
state[I(0,col)] = aes_mul(0x0e,c0) ^ aes_mul(0x0b,c1)
^ aes_mul(0x0d,c2) ^ aes_mul(0x09,c3);
state[I(1,col)] = aes_mul(0x09,c0) ^ aes_mul(0x0e,c1)
^ aes_mul(0x0b,c2) ^ aes_mul(0x0d,c3);
state[I(2,col)] = aes_mul(0x0d,c0) ^ aes_mul(0x09,c1)
^ aes_mul(0x0e,c2) ^ aes_mul(0x0b,c3);
state[I(3,col)] = aes_mul(0x0b,c0) ^ aes_mul(0x0d,c1)
^ aes_mul(0x09,c2) ^ aes_mul(0x0e,c3);
}
return state;
}
// insert subkey information
function AddRoundKey( state, w, base )
{
var col;
for( col=0; col<4; col++ )
{
state[I(0,col)] ^= w[base+col*4];
state[I(1,col)] ^= w[base+col*4+1];
state[I(2,col)] ^= w[base+col*4+2];
state[I(3,col)] ^= w[base+col*4+3];
}
return state;
}
// return a transposed array
function transpose( msg )
{
var row, col;
var state = new Array( 16 );
for( row=0; row<4; row++ )
for( col=0; col<4; col++ )
state[I(row,col)] = msg[I(col,row)];
return state;
}
// final AES state
var AES_output = new Array(16);
// format AES output
// -- uses the global array DES_output
function format_AES_output(bASCII)
{
var i;
var bits;
var str="";
// what type of data do we have to work with?
if (bASCII)
{
// convert each set of bits back to ASCII
for( i=0; i<16; i++ )
str += String.fromCharCode( AES_output[i] );
}
else
{
// output hexdecimal data (insert spaces)
str = cvt_hex8( AES_output[0] );
for( i=1; i<16; i++ )
{
str += "" + cvt_hex8( AES_output[i] );
}
}
return str;
}
// do encrytion
function aes_encrypt(str, key, bASCII)
{
//console.log(" aes_encrypt:\tstr = " + str + "\tkey = " + key + "\t bASCII = " + bASCII);
var w = new Array( 4*(Nr+1) ); // subkey information
var state = new Array( 16 ); // working state
var round;
//accumulated_output_info = "";
// get the message from the user
// also check if it is ASCII or hex
var msg = get_value(str, bASCII);
// problems??
if ( msg[0] < 0 )
{
return;
}
// get the key from the user
var key = get_value(key, false);
// problems??
if ( key[0] < 0 )
{
return;
}
// expand the key
w = key_expand( key );
// initial state = message in columns (transposed from what we input)
state = transpose( msg );
// display the round key - Transpose due to the way it is stored/used
state = AddRoundKey(state, w, 0);
for( round=1; round<Nr; round++ )
{
state = SubBytes(state, S_enc);
state = ShiftRows(state);
state = MixColumns(state);
// display the round key - Transpose due to the way it is stored/used
// note here the spec uses 32-bit words, we are using bytes, so an extra *4
state = AddRoundKey(state, w, round*4*4);
}
SubBytes(state, S_enc);
ShiftRows(state);
AddRoundKey(state, w, Nr*4*4);
// process output
AES_output = transpose( state );
var szOutput = format_AES_output(!bASCII);
return szOutput;
}
// do decryption
function aes_decrypt(str, key, bASCII)
{
//console.log(" aes_decrypt:\tstr = " + str + "\tkey = " + key + "\tbASCII = " + bASCII);
var w = new Array( 4*(Nr+1) ); // subkey information
var state = new Array( 16 ); // working state
var round;
//accumulated_output_info = "";
// get the message from the user
// also check if it is ASCII or hex
var msg = get_value(str, bASCII);
// problems??
if ( msg[0] < 0 )
{
return;
}
// get the key from the user
var key = get_value(key, false);
// problems??
if ( key[0] < 0 )
{
return;
}
// expand the key
w = key_expand( key );
// initial state = message
state = transpose( msg );
// display the round key - Transpose due to the way it is stored/used
state = AddRoundKey(state, w, Nr*4*4);
for( round=Nr-1; round>=1; round-- )
{
state = InvShiftRows(state);
state = SubBytes(state, S_dec);
// display the round key - Transpose due to the way it is stored/used
// note here the spec uses 32-bit words, we are using bytes, so an extra *4
state = AddRoundKey(state, w, round*4*4);
state = InvMixColumns(state);
}
InvShiftRows(state);
SubBytes(state, S_dec);
AddRoundKey(state, w, 0);
// process output
AES_output = transpose( state );
var szOutput = format_AES_output(!bASCII);
return szOutput;
}
window.aes_encrypt = aes_encrypt;
window.aes_decrypt = aes_decrypt;
window.console = window.console || {
log: function() {}
};
}());
\ No newline at end of file
var dbits,canary=244837814094590,j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){a!=null&&("number"==typeof a?this.fromNumber(a,b,c):b==null&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}function am1(a,b,c,d,e,g){for(;--g>=0;){var h=b*this[a++]+c[d]+e,e=Math.floor(h/67108864);c[d++]=h&67108863}return e}
function am2(a,b,c,d,e,g){var h=b&32767;for(b>>=15;--g>=0;){var f=this[a]&32767,o=this[a++]>>15,p=b*f+o*h,f=h*f+((p&32767)<<15)+c[d]+(e&1073741823),e=(f>>>30)+(p>>>15)+b*o+(e>>>30);c[d++]=f&1073741823}return e}function am3(a,b,c,d,e,g){var h=b&16383;for(b>>=14;--g>=0;){var f=this[a]&16383,o=this[a++]>>14,p=b*f+o*h,f=h*f+((p&16383)<<14)+c[d]+e,e=(f>>28)+(p>>14)+b*o;c[d++]=f&268435455}return e}
j_lm&&navigator.appName=="Microsoft Internet Explorer"?(BigInteger.prototype.am=am2,dbits=30):j_lm&&navigator.appName!="Netscape"?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz",BI_RC=[],rr,vv;
rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv)BI_RC[rr++]=vv;rr="a".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;rr="A".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;function int2char(a){return BI_RM.charAt(a)}function intAt(a,b){var c=BI_RC[a.charCodeAt(b)];return c==null?-1:c}function bnpCopyTo(a){for(var b=this.t-1;b>=0;--b)a[b]=this[b];a.t=this.t;a.s=this.s}function bnpFromInt(a){this.t=1;this.s=a<0?-1:0;a>0?this[0]=a:a<-1?this[0]=a+DV:this.t=0}
function nbv(a){var b=nbi();b.fromInt(a);return b}
function bnpFromString(a,b){var c;if(b==16)c=4;else if(b==8)c=3;else if(b==256)c=8;else if(b==2)c=1;else if(b==32)c=5;else if(b==4)c=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var d=a.length,e=!1,g=0;--d>=0;){var h=c==8?a[d]&255:intAt(a,d);h<0?a.charAt(d)=="-"&&(e=!0):(e=!1,g==0?this[this.t++]=h:g+c>this.DB?(this[this.t-1]|=(h&(1<<this.DB-g)-1)<<g,this[this.t++]=h>>this.DB-g):this[this.t-1]|=h<<g,g+=c,g>=this.DB&&(g-=this.DB))}if(c==8&&(a[0]&128)!=0)this.s=-1,g>0&&(this[this.t-1]|=(1<<
this.DB-g)-1<<g);this.clamp();e&&BigInteger.ZERO.subTo(this,this)}function bnpClamp(){for(var a=this.s&this.DM;this.t>0&&this[this.t-1]==a;)--this.t}
function bnToString(a){if(this.s<0)return"-"+this.negate().toString(a);if(a==16)a=4;else if(a==8)a=3;else if(a==2)a=1;else if(a==32)a=5;else if(a==64)a=6;else if(a==4)a=2;else return this.toRadix(a);var b=(1<<a)-1,c,d=!1,e="",g=this.t,h=this.DB-g*this.DB%a;if(g-- >0){if(h<this.DB&&(c=this[g]>>h)>0)d=!0,e=int2char(c);for(;g>=0;)h<a?(c=(this[g]&(1<<h)-1)<<a-h,c|=this[--g]>>(h+=this.DB-a)):(c=this[g]>>(h-=a)&b,h<=0&&(h+=this.DB,--g)),c>0&&(d=!0),d&&(e+=int2char(c))}return d?e:"0"}
function bnNegate(){var a=nbi();BigInteger.ZERO.subTo(this,a);return a}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var b=this.s-a.s;if(b!=0)return b;var c=this.t,b=c-a.t;if(b!=0)return b;for(;--c>=0;)if((b=this[c]-a[c])!=0)return b;return 0}function nbits(a){var b=1,c;if((c=a>>>16)!=0)a=c,b+=16;if((c=a>>8)!=0)a=c,b+=8;if((c=a>>4)!=0)a=c,b+=4;if((c=a>>2)!=0)a=c,b+=2;a>>1!=0&&(b+=1);return b}
function bnBitLength(){return this.t<=0?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(a,b){var c;for(c=this.t-1;c>=0;--c)b[c+a]=this[c];for(c=a-1;c>=0;--c)b[c]=0;b.t=this.t+a;b.s=this.s}function bnpDRShiftTo(a,b){for(var c=a;c<this.t;++c)b[c-a]=this[c];b.t=Math.max(this.t-a,0);b.s=this.s}
function bnpLShiftTo(a,b){var c=a%this.DB,d=this.DB-c,e=(1<<d)-1,g=Math.floor(a/this.DB),h=this.s<<c&this.DM,f;for(f=this.t-1;f>=0;--f)b[f+g+1]=this[f]>>d|h,h=(this[f]&e)<<c;for(f=g-1;f>=0;--f)b[f]=0;b[g]=h;b.t=this.t+g+1;b.s=this.s;b.clamp()}
function bnpRShiftTo(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,g=(1<<d)-1;b[0]=this[c]>>d;for(var h=c+1;h<this.t;++h)b[h-c-1]|=(this[h]&g)<<e,b[h-c]=this[h]>>d;d>0&&(b[this.t-c-1]|=(this.s&g)<<e);b.t=this.t-c;b.clamp()}}
function bnpSubTo(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d-=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d-=a[c],b[c++]=d&this.DM,d>>=this.DB;d-=a.s}b.s=d<0?-1:0;d<-1?b[c++]=this.DV+d:d>0&&(b[c++]=d);b.t=c;b.clamp()}
function bnpMultiplyTo(a,b){var c=this.abs(),d=a.abs(),e=c.t;for(b.t=e+d.t;--e>=0;)b[e]=0;for(e=0;e<d.t;++e)b[e+c.t]=c.am(0,d[e],b,e,0,c.t);b.s=0;b.clamp();this.s!=a.s&&BigInteger.ZERO.subTo(b,b)}function bnpSquareTo(a){for(var b=this.abs(),c=a.t=2*b.t;--c>=0;)a[c]=0;for(c=0;c<b.t-1;++c){var d=b.am(c,b[c],a,2*c,0,1);if((a[c+b.t]+=b.am(c+1,2*b[c],a,2*c+1,d,b.t-c-1))>=b.DV)a[c+b.t]-=b.DV,a[c+b.t+1]=1}a.t>0&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1));a.s=0;a.clamp()}
function bnpDivRemTo(a,b,c){var d=a.abs();if(!(d.t<=0)){var e=this.abs();if(e.t<d.t)b!=null&&b.fromInt(0),c!=null&&this.copyTo(c);else{c==null&&(c=nbi());var g=nbi(),h=this.s,a=a.s,f=this.DB-nbits(d[d.t-1]);f>0?(d.lShiftTo(f,g),e.lShiftTo(f,c)):(d.copyTo(g),e.copyTo(c));d=g.t;e=g[d-1];if(e!=0){var o=e*(1<<this.F1)+(d>1?g[d-2]>>this.F2:0),p=this.FV/o,o=(1<<this.F1)/o,q=1<<this.F2,n=c.t,k=n-d,j=b==null?nbi():b;g.dlShiftTo(k,j);c.compareTo(j)>=0&&(c[c.t++]=1,c.subTo(j,c));BigInteger.ONE.dlShiftTo(d,
j);for(j.subTo(g,g);g.t<d;)g[g.t++]=0;for(;--k>=0;){var l=c[--n]==e?this.DM:Math.floor(c[n]*p+(c[n-1]+q)*o);if((c[n]+=g.am(0,l,c,k,0,d))<l){g.dlShiftTo(k,j);for(c.subTo(j,c);c[n]<--l;)c.subTo(j,c)}}b!=null&&(c.drShiftTo(d,b),h!=a&&BigInteger.ZERO.subTo(b,b));c.t=d;c.clamp();f>0&&c.rShiftTo(f,c);h<0&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(a){var b=nbi();this.abs().divRemTo(a,null,b);this.s<0&&b.compareTo(BigInteger.ZERO)>0&&a.subTo(b,b);return b}function Classic(a){this.m=a}
function cConvert(a){return a.s<0||a.compareTo(this.m)>=0?a.mod(this.m):a}function cRevert(a){return a}function cReduce(a){a.divRemTo(this.m,null,a)}function cMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}function cSqrTo(a,b){a.squareTo(b);this.reduce(b)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;
function bnpInvDigit(){if(this.t<1)return 0;var a=this[0];if((a&1)==0)return 0;var b=a&3,b=b*(2-(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return b>0?this.DV-b:-b}function Montgomery(a){this.m=a;this.mp=a.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<a.DB-15)-1;this.mt2=2*a.t}
function montConvert(a){var b=nbi();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);a.s<0&&b.compareTo(BigInteger.ZERO)>0&&this.m.subTo(b,b);return b}function montRevert(a){var b=nbi();a.copyTo(b);this.reduce(b);return b}
function montReduce(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b<this.m.t;++b){var c=a[b]&32767,d=c*this.mpl+((c*this.mph+(a[b]>>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp();a.drShiftTo(this.m.t,a);a.compareTo(this.m)>=0&&a.subTo(this.m,a)}function montSqrTo(a,b){a.squareTo(b);this.reduce(b)}function montMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Montgomery.prototype.convert=montConvert;
Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(a,b){if(a>4294967295||a<1)return BigInteger.ONE;var c=nbi(),d=nbi(),e=b.convert(this),g=nbits(a)-1;for(e.copyTo(c);--g>=0;)if(b.sqrTo(c,d),(a&1<<g)>0)b.mulTo(d,e,c);else var h=c,c=d,d=h;return b.revert(c)}
function bnModPowInt(a,b){var c;c=a<256||b.isEven()?new Classic(b):new Montgomery(b);return this.exp(a,c)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;
BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;
BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnClone(){var a=nbi();this.copyTo(a);return a}function bnIntValue(){if(this.s<0)if(this.t==1)return this[0]-this.DV;else{if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnByteValue(){return this.t==0?this.s:this[0]<<24>>24}function bnShortValue(){return this.t==0?this.s:this[0]<<16>>16}
function bnpChunkSize(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}function bnSigNum(){return this.s<0?-1:this.t<=0||this.t==1&&this[0]<=0?0:1}function bnpToRadix(a){a==null&&(a=10);if(this.signum()==0||a<2||a>36)return"0";var b=this.chunkSize(a),b=Math.pow(a,b),c=nbv(b),d=nbi(),e=nbi(),g="";for(this.divRemTo(c,d,e);d.signum()>0;)g=(b+e.intValue()).toString(a).substr(1)+g,d.divRemTo(c,d,e);return e.intValue().toString(a)+g}
function bnpFromRadix(a,b){this.fromInt(0);b==null&&(b=10);for(var c=this.chunkSize(b),d=Math.pow(b,c),e=!1,g=0,h=0,f=0;f<a.length;++f){var o=intAt(a,f);o<0?a.charAt(f)=="-"&&this.signum()==0&&(e=!0):(h=b*h+o,++g>=c&&(this.dMultiply(d),this.dAddOffset(h,0),h=g=0))}g>0&&(this.dMultiply(Math.pow(b,g)),this.dAddOffset(h,0));e&&BigInteger.ZERO.subTo(this,this)}
function bnpFromNumber(a,b,c){if("number"==typeof b)if(a<2)this.fromInt(1);else{this.fromNumber(a,c);this.testBit(a-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);for(this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(BigInteger.ONE.shiftLeft(a-1),this)}else{var c=[],d=a&7;c.length=(a>>3)+1;b.nextBytes(c);d>0?c[0]&=(1<<d)-1:c[0]=0;this.fromString(c,256)}}
function bnToByteArray(){var a=this.t,b=[];b[0]=this.s;var c=this.DB-a*this.DB%8,d,e=0;if(a-- >0){if(c<this.DB&&(d=this[a]>>c)!=(this.s&this.DM)>>c)b[e++]=d|this.s<<this.DB-c;for(;a>=0;)if(c<8?(d=(this[a]&(1<<c)-1)<<8-c,d|=this[--a]>>(c+=this.DB-8)):(d=this[a]>>(c-=8)&255,c<=0&&(c+=this.DB,--a)),(d&128)!=0&&(d|=-256),e==0&&(this.s&128)!=(d&128)&&++e,e>0||d!=this.s)b[e++]=d}return b}function bnEquals(a){return this.compareTo(a)==0}function bnMin(a){return this.compareTo(a)<0?this:a}
function bnMax(a){return this.compareTo(a)>0?this:a}function bnpBitwiseTo(a,b,c){var d,e,g=Math.min(a.t,this.t);for(d=0;d<g;++d)c[d]=b(this[d],a[d]);if(a.t<this.t){e=a.s&this.DM;for(d=g;d<this.t;++d)c[d]=b(this[d],e);c.t=this.t}else{e=this.s&this.DM;for(d=g;d<a.t;++d)c[d]=b(e,a[d]);c.t=a.t}c.s=b(this.s,a.s);c.clamp()}function op_and(a,b){return a&b}function bnAnd(a){var b=nbi();this.bitwiseTo(a,op_and,b);return b}function op_or(a,b){return a|b}
function bnOr(a){var b=nbi();this.bitwiseTo(a,op_or,b);return b}function op_xor(a,b){return a^b}function bnXor(a){var b=nbi();this.bitwiseTo(a,op_xor,b);return b}function op_andnot(a,b){return a&~b}function bnAndNot(a){var b=nbi();this.bitwiseTo(a,op_andnot,b);return b}function bnNot(){for(var a=nbi(),b=0;b<this.t;++b)a[b]=this.DM&~this[b];a.t=this.t;a.s=~this.s;return a}function bnShiftLeft(a){var b=nbi();a<0?this.rShiftTo(-a,b):this.lShiftTo(a,b);return b}
function bnShiftRight(a){var b=nbi();a<0?this.lShiftTo(-a,b):this.rShiftTo(a,b);return b}function lbit(a){if(a==0)return-1;var b=0;(a&65535)==0&&(a>>=16,b+=16);(a&255)==0&&(a>>=8,b+=8);(a&15)==0&&(a>>=4,b+=4);(a&3)==0&&(a>>=2,b+=2);(a&1)==0&&++b;return b}function bnGetLowestSetBit(){for(var a=0;a<this.t;++a)if(this[a]!=0)return a*this.DB+lbit(this[a]);return this.s<0?this.t*this.DB:-1}function cbit(a){for(var b=0;a!=0;)a&=a-1,++b;return b}
function bnBitCount(){for(var a=0,b=this.s&this.DM,c=0;c<this.t;++c)a+=cbit(this[c]^b);return a}function bnTestBit(a){var b=Math.floor(a/this.DB);return b>=this.t?this.s!=0:(this[b]&1<<a%this.DB)!=0}function bnpChangeBit(a,b){var c=BigInteger.ONE.shiftLeft(a);this.bitwiseTo(c,b,c);return c}function bnSetBit(a){return this.changeBit(a,op_or)}function bnClearBit(a){return this.changeBit(a,op_andnot)}function bnFlipBit(a){return this.changeBit(a,op_xor)}
function bnpAddTo(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]+a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d+=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d+=a[c],b[c++]=d&this.DM,d>>=this.DB;d+=a.s}b.s=d<0?-1:0;d>0?b[c++]=d:d<-1&&(b[c++]=this.DV+d);b.t=c;b.clamp()}function bnAdd(a){var b=nbi();this.addTo(a,b);return b}function bnSubtract(a){var b=nbi();this.subTo(a,b);return b}
function bnMultiply(a){var b=nbi();this.multiplyTo(a,b);return b}function bnSquare(){var a=nbi();this.squareTo(a);return a}function bnDivide(a){var b=nbi();this.divRemTo(a,b,null);return b}function bnRemainder(a){var b=nbi();this.divRemTo(a,null,b);return b}function bnDivideAndRemainder(a){var b=nbi(),c=nbi();this.divRemTo(a,b,c);return[b,c]}function bnpDMultiply(a){this[this.t]=this.am(0,a-1,this,0,0,this.t);++this.t;this.clamp()}
function bnpDAddOffset(a,b){if(a!=0){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function NullExp(){}function nNop(a){return a}function nMulTo(a,b,c){a.multiplyTo(b,c)}function nSqrTo(a,b){a.squareTo(b)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(a){return this.exp(a,new NullExp)}
function bnpMultiplyLowerTo(a,b,c){var d=Math.min(this.t+a.t,b);c.s=0;for(c.t=d;d>0;)c[--d]=0;var e;for(e=c.t-this.t;d<e;++d)c[d+this.t]=this.am(0,a[d],c,d,0,this.t);for(e=Math.min(a.t,b);d<e;++d)this.am(0,a[d],c,d,0,b-d);c.clamp()}function bnpMultiplyUpperTo(a,b,c){--b;var d=c.t=this.t+a.t-b;for(c.s=0;--d>=0;)c[d]=0;for(d=Math.max(b-this.t,0);d<a.t;++d)c[this.t+d-b]=this.am(b-d,a[d],c,0,0,this.t+d-b);c.clamp();c.drShiftTo(1,c)}
function Barrett(a){this.r2=nbi();this.q3=nbi();BigInteger.ONE.dlShiftTo(2*a.t,this.r2);this.mu=this.r2.divide(a);this.m=a}function barrettConvert(a){if(a.s<0||a.t>2*this.m.t)return a.mod(this.m);else if(a.compareTo(this.m)<0)return a;else{var b=nbi();a.copyTo(b);this.reduce(b);return b}}function barrettRevert(a){return a}
function barrettReduce(a){a.drShiftTo(this.m.t-1,this.r2);if(a.t>this.m.t+1)a.t=this.m.t+1,a.clamp();this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);a.compareTo(this.r2)<0;)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);a.compareTo(this.m)>=0;)a.subTo(this.m,a)}function barrettSqrTo(a,b){a.squareTo(b);this.reduce(b)}function barrettMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Barrett.prototype.convert=barrettConvert;
Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;
function bnModPow(a,b){var c=a.bitLength(),d,e=nbv(1),g;if(c<=0)return e;else d=c<18?1:c<48?3:c<144?4:c<768?5:6;g=c<8?new Classic(b):b.isEven()?new Barrett(b):new Montgomery(b);var h=[],f=3,o=d-1,p=(1<<d)-1;h[1]=g.convert(this);if(d>1){c=nbi();for(g.sqrTo(h[1],c);f<=p;)h[f]=nbi(),g.mulTo(c,h[f-2],h[f]),f+=2}for(var q=a.t-1,n,k=!0,j=nbi(),c=nbits(a[q])-1;q>=0;){c>=o?n=a[q]>>c-o&p:(n=(a[q]&(1<<c+1)-1)<<o-c,q>0&&(n|=a[q-1]>>this.DB+c-o));for(f=d;(n&1)==0;)n>>=1,--f;if((c-=f)<0)c+=this.DB,--q;if(k)h[n].copyTo(e),
k=!1;else{for(;f>1;)g.sqrTo(e,j),g.sqrTo(j,e),f-=2;f>0?g.sqrTo(e,j):(f=e,e=j,j=f);g.mulTo(j,h[n],e)}for(;q>=0&&(a[q]&1<<c)==0;)g.sqrTo(e,j),f=e,e=j,j=f,--c<0&&(c=this.DB-1,--q)}return g.revert(e)}
function bnGCD(a){var b=this.s<0?this.negate():this.clone(),a=a.s<0?a.negate():a.clone();if(b.compareTo(a)<0)var c=b,b=a,a=c;var c=b.getLowestSetBit(),d=a.getLowestSetBit();if(d<0)return b;c<d&&(d=c);d>0&&(b.rShiftTo(d,b),a.rShiftTo(d,a));for(;b.signum()>0;)(c=b.getLowestSetBit())>0&&b.rShiftTo(c,b),(c=a.getLowestSetBit())>0&&a.rShiftTo(c,a),b.compareTo(a)>=0?(b.subTo(a,b),b.rShiftTo(1,b)):(a.subTo(b,a),a.rShiftTo(1,a));d>0&&a.lShiftTo(d,a);return a}
function bnpModInt(a){if(a<=0)return 0;var b=this.DV%a,c=this.s<0?a-1:0;if(this.t>0)if(b==0)c=this[0]%a;else for(var d=this.t-1;d>=0;--d)c=(b*c+this[d])%a;return c}
function bnModInverse(a){var b=a.isEven();if(this.isEven()&&b||a.signum()==0)return BigInteger.ZERO;for(var c=a.clone(),d=this.clone(),e=nbv(1),g=nbv(0),h=nbv(0),f=nbv(1);c.signum()!=0;){for(;c.isEven();){c.rShiftTo(1,c);if(b){if(!e.isEven()||!g.isEven())e.addTo(this,e),g.subTo(a,g);e.rShiftTo(1,e)}else g.isEven()||g.subTo(a,g);g.rShiftTo(1,g)}for(;d.isEven();){d.rShiftTo(1,d);if(b){if(!h.isEven()||!f.isEven())h.addTo(this,h),f.subTo(a,f);h.rShiftTo(1,h)}else f.isEven()||f.subTo(a,f);f.rShiftTo(1,
f)}c.compareTo(d)>=0?(c.subTo(d,c),b&&e.subTo(h,e),g.subTo(f,g)):(d.subTo(c,d),b&&h.subTo(e,h),f.subTo(g,f))}if(d.compareTo(BigInteger.ONE)!=0)return BigInteger.ZERO;if(f.compareTo(a)>=0)return f.subtract(a);if(f.signum()<0)f.addTo(a,f);else return f;return f.signum()<0?f.add(a):f}
var lowprimes=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,
733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],lplim=67108864/lowprimes[lowprimes.length-1];
function bnIsProbablePrime(a){var b,c=this.abs();if(c.t==1&&c[0]<=lowprimes[lowprimes.length-1]){for(b=0;b<lowprimes.length;++b)if(c[0]==lowprimes[b])return!0;return!1}if(c.isEven())return!1;for(b=1;b<lowprimes.length;){for(var d=lowprimes[b],e=b+1;e<lowprimes.length&&d<lplim;)d*=lowprimes[e++];for(d=c.modInt(d);b<e;)if(d%lowprimes[b++]==0)return!1}return c.millerRabin(a)}
function bnpMillerRabin(a){var b=this.subtract(BigInteger.ONE),c=b.getLowestSetBit();if(c<=0)return!1;var d=b.shiftRight(c),a=a+1>>1;if(a>lowprimes.length)a=lowprimes.length;for(var e=nbi(),g=0;g<a;++g){e.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);var h=e.modPow(d,this);if(h.compareTo(BigInteger.ONE)!=0&&h.compareTo(b)!=0){for(var f=1;f++<c&&h.compareTo(b)!=0;)if(h=h.modPowInt(2,this),h.compareTo(BigInteger.ONE)==0)return!1;if(h.compareTo(b)!=0)return!1}}return!0}
BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.fromNumber=bnpFromNumber;BigInteger.prototype.bitwiseTo=bnpBitwiseTo;BigInteger.prototype.changeBit=bnpChangeBit;BigInteger.prototype.addTo=bnpAddTo;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.multiplyLowerTo=bnpMultiplyLowerTo;BigInteger.prototype.multiplyUpperTo=bnpMultiplyUpperTo;
BigInteger.prototype.modInt=bnpModInt;BigInteger.prototype.millerRabin=bnpMillerRabin;BigInteger.prototype.clone=bnClone;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.byteValue=bnByteValue;BigInteger.prototype.shortValue=bnShortValue;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.toByteArray=bnToByteArray;BigInteger.prototype.equals=bnEquals;BigInteger.prototype.min=bnMin;BigInteger.prototype.max=bnMax;BigInteger.prototype.and=bnAnd;BigInteger.prototype.or=bnOr;
BigInteger.prototype.xor=bnXor;BigInteger.prototype.andNot=bnAndNot;BigInteger.prototype.not=bnNot;BigInteger.prototype.shiftLeft=bnShiftLeft;BigInteger.prototype.shiftRight=bnShiftRight;BigInteger.prototype.getLowestSetBit=bnGetLowestSetBit;BigInteger.prototype.bitCount=bnBitCount;BigInteger.prototype.testBit=bnTestBit;BigInteger.prototype.setBit=bnSetBit;BigInteger.prototype.clearBit=bnClearBit;BigInteger.prototype.flipBit=bnFlipBit;BigInteger.prototype.add=bnAdd;BigInteger.prototype.subtract=bnSubtract;
BigInteger.prototype.multiply=bnMultiply;BigInteger.prototype.divide=bnDivide;BigInteger.prototype.remainder=bnRemainder;BigInteger.prototype.divideAndRemainder=bnDivideAndRemainder;BigInteger.prototype.modPow=bnModPow;BigInteger.prototype.modInverse=bnModInverse;BigInteger.prototype.pow=bnPow;BigInteger.prototype.gcd=bnGCD;BigInteger.prototype.isProbablePrime=bnIsProbablePrime;BigInteger.prototype.square=bnSquare;
(function(a,b,c,d,e,g,h){function f(a){var b,d,e=this,g=a.length,f=0,h=e.i=e.j=e.m=0;e.S=[];e.c=[];for(g||(a=[g++]);f<c;)e.S[f]=f++;for(f=0;f<c;f++)b=e.S[f],h=h+b+a[f%g]&c-1,d=e.S[h],e.S[f]=d,e.S[h]=b;e.g=function(a){var b=e.S,d=e.i+1&c-1,g=b[d],f=e.j+g&c-1,h=b[f];b[d]=h;b[f]=g;for(var k=b[g+h&c-1];--a;)d=d+1&c-1,g=b[d],f=f+g&c-1,h=b[f],b[d]=h,b[f]=g,k=k*c+b[g+h&c-1];e.i=d;e.j=f;return k};e.g(c)}function o(a,b,c,d,e){c=[];e=typeof a;if(b&&e=="object")for(d in a)if(d.indexOf("S")<5)try{c.push(o(a[d],
b-1))}catch(g){}return c.length?c:a+(e!="string"?"\x00":"")}function p(a,b,d,e){a+="";for(e=d=0;e<a.length;e++){var g=b,f=e&c-1,h=(d^=b[e&c-1]*19)+a.charCodeAt(e);g[f]=h&c-1}a="";for(e in b)a+=String.fromCharCode(b[e]);return a}b.seedrandom=function(q,n){var k=[],j,q=p(o(n?[q,a]:arguments.length?q:[(new Date).getTime(),a,window],3),k);j=new f(k);p(j.S,a);b.random=function(){for(var a=j.g(d),b=h,f=0;a<e;)a=(a+f)*c,b*=c,f=j.g(1);for(;a>=g;)a/=2,b/=2,f>>>=1;return(a+f)/b};return q};h=b.pow(c,d);e=b.pow(2,
e);g=e*2;p(b.random(),a)})([],Math,256,6,52);function SeededRandom(){}function SRnextBytes(a){var b;for(b=0;b<a.length;b++)a[b]=Math.floor(Math.random()*256)}SeededRandom.prototype.nextBytes=SRnextBytes;function Arcfour(){this.j=this.i=0;this.S=[]}function ARC4init(a){var b,c,d;for(b=0;b<256;++b)this.S[b]=b;for(b=c=0;b<256;++b)c=c+this.S[b]+a[b%a.length]&255,d=this.S[b],this.S[b]=this.S[c],this.S[c]=d;this.j=this.i=0}
function ARC4next(){var a;this.i=this.i+1&255;this.j=this.j+this.S[this.i]&255;a=this.S[this.i];this.S[this.i]=this.S[this.j];this.S[this.j]=a;return this.S[a+this.S[this.i]&255]}Arcfour.prototype.init=ARC4init;Arcfour.prototype.next=ARC4next;function prng_newstate(){return new Arcfour}var rng_psize=256,rng_state,rng_pool,rng_pptr;
function rng_seed_int(a){rng_pool[rng_pptr++]^=a&255;rng_pool[rng_pptr++]^=a>>8&255;rng_pool[rng_pptr++]^=a>>16&255;rng_pool[rng_pptr++]^=a>>24&255;rng_pptr>=rng_psize&&(rng_pptr-=rng_psize)}function rng_seed_time(){rng_seed_int((new Date).getTime())}
if(rng_pool==null){rng_pool=[];rng_pptr=0;var t;if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t<z.length;++t)rng_pool[rng_pptr++]=z.charCodeAt(t)&255}for(;rng_pptr<rng_psize;)t=Math.floor(65536*Math.random()),rng_pool[rng_pptr++]=t>>>8,rng_pool[rng_pptr++]=t&255;rng_pptr=0;rng_seed_time()}
function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr<rng_pool.length;++rng_pptr)rng_pool[rng_pptr]=0;rng_pptr=0}return rng_state.next()}function rng_get_bytes(a){var b;for(b=0;b<a.length;++b)a[b]=rng_get_byte()}function SecureRandom(){}SecureRandom.prototype.nextBytes=rng_get_bytes;
function SHA256(a){function b(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}function c(a,b){return a>>>b|a<<32-b}a=function(a){for(var a=a.replace(/\r\n/g,"\n"),b="",c=0;c<a.length;c++){var h=a.charCodeAt(c);h<128?b+=String.fromCharCode(h):(h>127&&h<2048?b+=String.fromCharCode(h>>6|192):(b+=String.fromCharCode(h>>12|224),b+=String.fromCharCode(h>>6&63|128)),b+=String.fromCharCode(h&63|128))}return b}(a);return function(a){for(var b="",c=0;c<a.length*4;c++)b+="0123456789abcdef".charAt(a[c>>
2]>>(3-c%4)*8+4&15)+"0123456789abcdef".charAt(a[c>>2]>>(3-c%4)*8&15);return b}(function(a,e){var g=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,
2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],h=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],f=Array(64),o,p,q,n,k,j,l,m,s,r,u,w;a[e>>5]|=128<<24-e%32;a[(e+64>>9<<4)+15]=e;for(s=0;s<a.length;s+=16){o=h[0];p=h[1];q=h[2];n=h[3];
k=h[4];j=h[5];l=h[6];m=h[7];for(r=0;r<64;r++)f[r]=r<16?a[r+s]:b(b(b(c(f[r-2],17)^c(f[r-2],19)^f[r-2]>>>10,f[r-7]),c(f[r-15],7)^c(f[r-15],18)^f[r-15]>>>3),f[r-16]),u=b(b(b(b(m,c(k,6)^c(k,11)^c(k,25)),k&j^~k&l),g[r]),f[r]),w=b(c(o,2)^c(o,13)^c(o,22),o&p^o&q^p&q),m=l,l=j,j=k,k=b(n,u),n=q,q=p,p=o,o=b(u,w);h[0]=b(o,h[0]);h[1]=b(p,h[1]);h[2]=b(q,h[2]);h[3]=b(n,h[3]);h[4]=b(k,h[4]);h[5]=b(j,h[5]);h[6]=b(l,h[6]);h[7]=b(m,h[7])}return h}(function(a){for(var b=[],c=0;c<a.length*8;c+=8)b[c>>5]|=(a.charCodeAt(c/
8)&255)<<24-c%32;return b}(a),a.length*8))}var sha256={hex:function(a){return SHA256(a)}};
function SHA1(a){function b(a,b){return a<<b|a>>>32-b}function c(a){var b="",c,d;for(c=7;c>=0;c--)d=a>>>c*4&15,b+=d.toString(16);return b}var d,e,g=Array(80),h=1732584193,f=4023233417,o=2562383102,p=271733878,q=3285377520,n,k,j,l,m,a=function(a){for(var a=a.replace(/\r\n/g,"\n"),b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);d<128?b+=String.fromCharCode(d):(d>127&&d<2048?b+=String.fromCharCode(d>>6|192):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128)),b+=String.fromCharCode(d&
63|128))}return b}(a);n=a.length;var s=[];for(d=0;d<n-3;d+=4)e=a.charCodeAt(d)<<24|a.charCodeAt(d+1)<<16|a.charCodeAt(d+2)<<8|a.charCodeAt(d+3),s.push(e);switch(n%4){case 0:d=2147483648;break;case 1:d=a.charCodeAt(n-1)<<24|8388608;break;case 2:d=a.charCodeAt(n-2)<<24|a.charCodeAt(n-1)<<16|32768;break;case 3:d=a.charCodeAt(n-3)<<24|a.charCodeAt(n-2)<<16|a.charCodeAt(n-1)<<8|128}for(s.push(d);s.length%16!=14;)s.push(0);s.push(n>>>29);s.push(n<<3&4294967295);for(a=0;a<s.length;a+=16){for(d=0;d<16;d++)g[d]=
s[a+d];for(d=16;d<=79;d++)g[d]=b(g[d-3]^g[d-8]^g[d-14]^g[d-16],1);e=h;n=f;k=o;j=p;l=q;for(d=0;d<=19;d++)m=b(e,5)+(n&k|~n&j)+l+g[d]+1518500249&4294967295,l=j,j=k,k=b(n,30),n=e,e=m;for(d=20;d<=39;d++)m=b(e,5)+(n^k^j)+l+g[d]+1859775393&4294967295,l=j,j=k,k=b(n,30),n=e,e=m;for(d=40;d<=59;d++)m=b(e,5)+(n&k|n&j|k&j)+l+g[d]+2400959708&4294967295,l=j,j=k,k=b(n,30),n=e,e=m;for(d=60;d<=79;d++)m=b(e,5)+(n^k^j)+l+g[d]+3395469782&4294967295,l=j,j=k,k=b(n,30),n=e,e=m;h=h+e&4294967295;f=f+n&4294967295;o=o+k&4294967295;
p=p+j&4294967295;q=q+l&4294967295}m=c(h)+c(f)+c(o)+c(p)+c(q);return m.toLowerCase()}
var sha1={hex:function(a){return SHA1(a)}},MD5=function(a){function b(a,b){var c,d,e,f,g;e=a&2147483648;f=b&2147483648;c=a&1073741824;d=b&1073741824;g=(a&1073741823)+(b&1073741823);return c&d?g^2147483648^e^f:c|d?g&1073741824?g^3221225472^e^f:g^1073741824^e^f:g^e^f}function c(a,c,d,e,f,g,h){a=b(a,b(b(c&d|~c&e,f),h));return b(a<<g|a>>>32-g,c)}function d(a,c,d,e,f,g,h){a=b(a,b(b(c&e|d&~e,f),h));return b(a<<g|a>>>32-g,c)}function e(a,c,d,e,f,g,h){a=b(a,b(b(c^d^e,f),h));return b(a<<g|a>>>32-g,c)}function g(a,
c,d,e,f,g,h){a=b(a,b(b(d^(c|~e),f),h));return b(a<<g|a>>>32-g,c)}function h(a){var b="",c="",d;for(d=0;d<=3;d++)c=a>>>d*8&255,c="0"+c.toString(16),b+=c.substr(c.length-2,2);return b}var f=[],o,p,q,n,k,j,l,m,a=function(a){for(var a=a.replace(/\r\n/g,"\n"),b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);d<128?b+=String.fromCharCode(d):(d>127&&d<2048?b+=String.fromCharCode(d>>6|192):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128)),b+=String.fromCharCode(d&63|128))}return b}(a),
f=function(a){var b,c=a.length;b=c+8;for(var d=((b-b%64)/64+1)*16,e=Array(d-1),f=0,g=0;g<c;)b=(g-g%4)/4,f=g%4*8,e[b]|=a.charCodeAt(g)<<f,g++;e[(g-g%4)/4]|=128<<g%4*8;e[d-2]=c<<3;e[d-1]=c>>>29;return e}(a);k=1732584193;j=4023233417;l=2562383102;m=271733878;for(a=0;a<f.length;a+=16)o=k,p=j,q=l,n=m,k=c(k,j,l,m,f[a+0],7,3614090360),m=c(m,k,j,l,f[a+1],12,3905402710),l=c(l,m,k,j,f[a+2],17,606105819),j=c(j,l,m,k,f[a+3],22,3250441966),k=c(k,j,l,m,f[a+4],7,4118548399),m=c(m,k,j,l,f[a+5],12,1200080426),l=c(l,
m,k,j,f[a+6],17,2821735955),j=c(j,l,m,k,f[a+7],22,4249261313),k=c(k,j,l,m,f[a+8],7,1770035416),m=c(m,k,j,l,f[a+9],12,2336552879),l=c(l,m,k,j,f[a+10],17,4294925233),j=c(j,l,m,k,f[a+11],22,2304563134),k=c(k,j,l,m,f[a+12],7,1804603682),m=c(m,k,j,l,f[a+13],12,4254626195),l=c(l,m,k,j,f[a+14],17,2792965006),j=c(j,l,m,k,f[a+15],22,1236535329),k=d(k,j,l,m,f[a+1],5,4129170786),m=d(m,k,j,l,f[a+6],9,3225465664),l=d(l,m,k,j,f[a+11],14,643717713),j=d(j,l,m,k,f[a+0],20,3921069994),k=d(k,j,l,m,f[a+5],5,3593408605),
m=d(m,k,j,l,f[a+10],9,38016083),l=d(l,m,k,j,f[a+15],14,3634488961),j=d(j,l,m,k,f[a+4],20,3889429448),k=d(k,j,l,m,f[a+9],5,568446438),m=d(m,k,j,l,f[a+14],9,3275163606),l=d(l,m,k,j,f[a+3],14,4107603335),j=d(j,l,m,k,f[a+8],20,1163531501),k=d(k,j,l,m,f[a+13],5,2850285829),m=d(m,k,j,l,f[a+2],9,4243563512),l=d(l,m,k,j,f[a+7],14,1735328473),j=d(j,l,m,k,f[a+12],20,2368359562),k=e(k,j,l,m,f[a+5],4,4294588738),m=e(m,k,j,l,f[a+8],11,2272392833),l=e(l,m,k,j,f[a+11],16,1839030562),j=e(j,l,m,k,f[a+14],23,4259657740),
k=e(k,j,l,m,f[a+1],4,2763975236),m=e(m,k,j,l,f[a+4],11,1272893353),l=e(l,m,k,j,f[a+7],16,4139469664),j=e(j,l,m,k,f[a+10],23,3200236656),k=e(k,j,l,m,f[a+13],4,681279174),m=e(m,k,j,l,f[a+0],11,3936430074),l=e(l,m,k,j,f[a+3],16,3572445317),j=e(j,l,m,k,f[a+6],23,76029189),k=e(k,j,l,m,f[a+9],4,3654602809),m=e(m,k,j,l,f[a+12],11,3873151461),l=e(l,m,k,j,f[a+15],16,530742520),j=e(j,l,m,k,f[a+2],23,3299628645),k=g(k,j,l,m,f[a+0],6,4096336452),m=g(m,k,j,l,f[a+7],10,1126891415),l=g(l,m,k,j,f[a+14],15,2878612391),
j=g(j,l,m,k,f[a+5],21,4237533241),k=g(k,j,l,m,f[a+12],6,1700485571),m=g(m,k,j,l,f[a+3],10,2399980690),l=g(l,m,k,j,f[a+10],15,4293915773),j=g(j,l,m,k,f[a+1],21,2240044497),k=g(k,j,l,m,f[a+8],6,1873313359),m=g(m,k,j,l,f[a+15],10,4264355552),l=g(l,m,k,j,f[a+6],15,2734768916),j=g(j,l,m,k,f[a+13],21,1309151649),k=g(k,j,l,m,f[a+4],6,4149444226),m=g(m,k,j,l,f[a+11],10,3174756917),l=g(l,m,k,j,f[a+2],15,718787259),j=g(j,l,m,k,f[a+9],21,3951481745),k=b(k,o),j=b(j,p),l=b(l,q),m=b(m,n);return(h(k)+h(j)+h(l)+
h(m)).toLowerCase()};function parseBigInt(a,b){return new BigInteger(a,b)}function linebrk(a,b){for(var c="",d=0;d+b<a.length;)c+=a.substring(d,d+b)+"\n",d+=b;return c+a.substring(d,a.length)}function byte2Hex(a){return a<16?"0"+a.toString(16):a.toString(16)}
function pkcs1pad2(a,b){if(b<a.length+11)throw"Message too long for RSA (n="+b+", l="+a.length+")";for(var c=[],d=a.length-1;d>=0&&b>0;){var e=a.charCodeAt(d--);e<128?c[--b]=e:e>127&&e<2048?(c[--b]=e&63|128,c[--b]=e>>6|192):(c[--b]=e&63|128,c[--b]=e>>6&63|128,c[--b]=e>>12|224)}c[--b]=0;d=new SecureRandom;for(e=[];b>2;){for(e[0]=0;e[0]==0;)d.nextBytes(e);c[--b]=e[0]}c[--b]=2;c[--b]=0;return new BigInteger(c)}
function RSAKey(){this.n=null;this.e=0;this.coeff=this.dmq1=this.dmp1=this.q=this.p=this.d=null}function RSASetPublic(a,b){a!=null&&b!=null&&a.length>0&&b.length>0?(this.n=parseBigInt(a,16),this.e=parseInt(b,16)):alert("Invalid RSA public key")}function RSADoPublic(a){return a.modPowInt(this.e,this.n)}function RSAEncrypt(a){a=pkcs1pad2(a,this.n.bitLength()+7>>3);if(a==null)return null;a=this.doPublic(a);if(a==null)return null;a=a.toString(16);return(a.length&1)==0?a:"0"+a}
RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;function pkcs1unpad2(a,b){for(var c=a.toByteArray(),d=0;d<c.length&&c[d]==0;)++d;if(c.length-d!=b-1||c[d]!=2)return null;for(++d;c[d]!=0;)if(++d>=c.length)return null;for(var e="";++d<c.length;){var g=c[d]&255;g<128?e+=String.fromCharCode(g):g>191&&g<224?(e+=String.fromCharCode((g&31)<<6|c[d+1]&63),++d):(e+=String.fromCharCode((g&15)<<12|(c[d+1]&63)<<6|c[d+2]&63),d+=2)}return e}
function RSASetPrivate(a,b,c){a!=null&&b!=null&&a.length>0&&b.length>0?(this.n=parseBigInt(a,16),this.e=parseInt(b,16),this.d=parseBigInt(c,16)):alert("Invalid RSA private key")}
function RSASetPrivateEx(a,b,c,d,e,g,h,f){a!=null&&b!=null&&a.length>0&&b.length>0?(this.n=parseBigInt(a,16),this.e=parseInt(b,16),this.d=parseBigInt(c,16),this.p=parseBigInt(d,16),this.q=parseBigInt(e,16),this.dmp1=parseBigInt(g,16),this.dmq1=parseBigInt(h,16),this.coeff=parseBigInt(f,16)):alert("Invalid RSA private key")}
function RSAGenerate(a,b){var c=new SeededRandom,d=a>>1;this.e=parseInt(b,16);for(var e=new BigInteger(b,16);;){for(;;)if(this.p=new BigInteger(a-d,1,c),this.p.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)==0&&this.p.isProbablePrime(10))break;for(;;)if(this.q=new BigInteger(d,1,c),this.q.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)==0&&this.q.isProbablePrime(10))break;if(this.p.compareTo(this.q)<=0){var g=this.p;this.p=this.q;this.q=g}var g=this.p.subtract(BigInteger.ONE),
h=this.q.subtract(BigInteger.ONE),f=g.multiply(h);if(f.gcd(e).compareTo(BigInteger.ONE)==0){this.n=this.p.multiply(this.q);this.d=e.modInverse(f);this.dmp1=this.d.mod(g);this.dmq1=this.d.mod(h);this.coeff=this.q.modInverse(this.p);break}}}
function RSADoPrivate(a){if(this.p==null||this.q==null)return a.modPow(this.d,this.n);for(var b=a.mod(this.p).modPow(this.dmp1,this.p),a=a.mod(this.q).modPow(this.dmq1,this.q);b.compareTo(a)<0;)b=b.add(this.p);return b.subtract(a).multiply(this.coeff).mod(this.p).multiply(this.q).add(a)}function RSADecrypt(a){a=this.doPrivate(parseBigInt(a,16));return a==null?null:pkcs1unpad2(a,this.n.bitLength()+7>>3)}RSAKey.prototype.doPrivate=RSADoPrivate;RSAKey.prototype.setPrivate=RSASetPrivate;
RSAKey.prototype.setPrivateEx=RSASetPrivateEx;RSAKey.prototype.generate=RSAGenerate;RSAKey.prototype.decrypt=RSADecrypt;var _RSASIGN_DIHEAD=[];_RSASIGN_DIHEAD.sha1="3021300906052b0e03021a05000414";_RSASIGN_DIHEAD.sha256="3031300d060960864801650304020105000420";var _RSASIGN_HASHHEXFUNC=[];_RSASIGN_HASHHEXFUNC.sha1=sha1.hex;_RSASIGN_HASHHEXFUNC.sha256=sha256.hex;
function _rsasign_getHexPaddedDigestInfoForString(a,b,c){b/=4;for(var a=(0,_RSASIGN_HASHHEXFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}function _rsasign_signString(a,b){var c=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),b);return this.doPrivate(parseBigInt(c,16)).toString(16)}
function _rsasign_signStringWithSHA1(a){a=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),"sha1");return this.doPrivate(parseBigInt(a,16)).toString(16)}function _rsasign_signStringWithSHA256(a){a=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),"sha256");return this.doPrivate(parseBigInt(a,16)).toString(16)}function _rsasign_getDecryptSignatureBI(a,b,c){var d=new RSAKey;d.setPublic(b,c);return d.doPublic(a)}
function _rsasign_getHexDigestInfoFromSig(a,b,c){return _rsasign_getDecryptSignatureBI(a,b,c).toString(16).replace(/^1f+00/,"")}function _rsasign_getAlgNameAndHashFromHexDisgestInfo(a){for(var b in _RSASIGN_DIHEAD){var c=_RSASIGN_DIHEAD[b],d=c.length;if(a.substring(0,d)==c)return[b,a.substring(d)]}return[]}
function _rsasign_verifySignatureWithArgs(a,b,c,d){b=_rsasign_getHexDigestInfoFromSig(b,c,d);c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(b);if(c.length==0)return!1;b=c[1];a=(0,_RSASIGN_HASHHEXFUNC[c[0]])(a);return b==a}function _rsasign_verifyHexSignatureForMessage(a,b){var c=parseBigInt(a,16);return _rsasign_verifySignatureWithArgs(b,c,this.n.toString(16),this.e.toString(16))}
function _rsasign_verifyString(a,b){var b=b.replace(/[ \n]+/g,""),c=this.doPublic(parseBigInt(b,16)).toString(16).replace(/^1f+00/,""),d=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(d.length==0)return!1;c=d[1];d=(0,_RSASIGN_HASHHEXFUNC[d[0]])(a);return c==d}RSAKey.prototype.signString=_rsasign_signString;RSAKey.prototype.signStringWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signStringWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.verifyString=_rsasign_verifyString;
RSAKey.prototype.verifyHexSignatureForMessage=_rsasign_verifyHexSignatureForMessage;
var aes=function(){var a={Sbox:[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,
95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22],ShiftRowTab:[0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11]};a.Init=
function(){a.Sbox_Inv=Array(256);for(var b=0;b<256;b++)a.Sbox_Inv[a.Sbox[b]]=b;a.ShiftRowTab_Inv=Array(16);for(b=0;b<16;b++)a.ShiftRowTab_Inv[a.ShiftRowTab[b]]=b;a.xtime=Array(256);for(b=0;b<128;b++)a.xtime[b]=b<<1,a.xtime[128+b]=b<<1^27};a.Done=function(){delete a.Sbox_Inv;delete a.ShiftRowTab_Inv;delete a.xtime};a.ExpandKey=function(b){var c=b.length,d,e=1;switch(c){case 16:d=176;break;case 24:d=208;break;case 32:d=240;break;default:alert("my.ExpandKey: Only key lengths of 16, 24 or 32 bytes allowed!")}for(var g=
c;g<d;g+=4){var h=b.slice(g-4,g);if(g%c==0){if(h=[a.Sbox[h[1]]^e,a.Sbox[h[2]],a.Sbox[h[3]],a.Sbox[h[0]]],(e<<=1)>=256)e^=283}else c>24&&g%c==16&&(h=[a.Sbox[h[0]],a.Sbox[h[1]],a.Sbox[h[2]],a.Sbox[h[3]]]);for(var f=0;f<4;f++)b[g+f]=b[g+f-c]^h[f]}};a.Encrypt=function(b,c){var d=c.length;a.AddRoundKey(b,c.slice(0,16));for(var e=16;e<d-16;e+=16)a.SubBytes(b,a.Sbox),a.ShiftRows(b,a.ShiftRowTab),a.MixColumns(b),a.AddRoundKey(b,c.slice(e,e+16));a.SubBytes(b,a.Sbox);a.ShiftRows(b,a.ShiftRowTab);a.AddRoundKey(b,
c.slice(e,d))};a.Decrypt=function(b,c){var d=c.length;a.AddRoundKey(b,c.slice(d-16,d));a.ShiftRows(b,a.ShiftRowTab_Inv);a.SubBytes(b,a.Sbox_Inv);for(d-=32;d>=16;d-=16)a.AddRoundKey(b,c.slice(d,d+16)),a.MixColumns_Inv(b),a.ShiftRows(b,a.ShiftRowTab_Inv),a.SubBytes(b,a.Sbox_Inv);a.AddRoundKey(b,c.slice(0,16))};a.SubBytes=function(a,c){for(var d=0;d<16;d++)a[d]=c[a[d]]};a.AddRoundKey=function(a,c){for(var d=0;d<16;d++)a[d]^=c[d]};a.ShiftRows=function(a,c){for(var d=[].concat(a),e=0;e<16;e++)a[e]=d[c[e]]};
a.MixColumns=function(b){for(var c=0;c<16;c+=4){var d=b[c+0],e=b[c+1],g=b[c+2],h=b[c+3],f=d^e^g^h;b[c+0]^=f^a.xtime[d^e];b[c+1]^=f^a.xtime[e^g];b[c+2]^=f^a.xtime[g^h];b[c+3]^=f^a.xtime[h^d]}};a.MixColumns_Inv=function(b){for(var c=0;c<16;c+=4){var d=b[c+0],e=b[c+1],g=b[c+2],h=b[c+3],f=d^e^g^h,o=a.xtime[f],p=a.xtime[a.xtime[o^d^g]]^f;f^=a.xtime[a.xtime[o^e^h]];b[c+0]^=p^a.xtime[d^e];b[c+1]^=f^a.xtime[e^g];b[c+2]^=p^a.xtime[g^h];b[c+3]^=f^a.xtime[h^d]}};return a}(),cryptico=function(){var a={};aes.Init();
a.b256to64=function(a){var c,d,e,g="",h=0,f=0,o=a.length;for(e=0;e<o;e++)d=a.charCodeAt(e),f==0?(g+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>2&63),c=(d&3)<<4):f==1?(g+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c|d>>4&15),c=(d&15)<<2):f==2&&(g+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c|d>>6&3),h+=1,g+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d&63)),h+=1,f+=1,f==3&&
(f=0);f>0&&(g+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c),g+="=");f==1&&(g+="=");return g};a.b64to256=function(a){var c,d,e="",g=0,h=0,f=a.length;for(d=0;d<f;d++)c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(a.charAt(d)),c>=0&&(g&&(e+=String.fromCharCode(h|c>>6-g&255)),g=g+2&7,h=c<<g&255);return e};a.b16to64=function(a){var c,d,e="";a.length%2==1&&(a="0"+a);for(c=0;c+3<=a.length;c+=3)d=parseInt(a.substring(c,c+3),16),e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>
6)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d&63);c+1==a.length?(d=parseInt(a.substring(c,c+1),16),e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d<<2)):c+2==a.length&&(d=parseInt(a.substring(c,c+2),16),e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>2)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((d&3)<<4));for(;(e.length&3)>0;)e+="=";return e};a.b64to16=function(a){var c="",
d,e=0,g;for(d=0;d<a.length;++d){if(a.charAt(d)=="=")break;v="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(a.charAt(d));v<0||(e==0?(c+=int2char(v>>2),g=v&3,e=1):e==1?(c+=int2char(g<<2|v>>4),g=v&15,e=2):e==2?(c+=int2char(g),c+=int2char(v>>2),g=v&3,e=3):(c+=int2char(g<<2|v>>4),c+=int2char(v&15),e=0))}e==1&&(c+=int2char(g<<2));return c};a.string2bytes=function(a){for(var c=[],d=0;d<a.length;d++)c.push(a.charCodeAt(d));return c};a.bytes2string=function(a){for(var c="",d=0;d<
a.length;d++)c+=String.fromCharCode(a[d]);return c};a.blockXOR=function(a,c){for(var d=Array(16),e=0;e<16;e++)d[e]=a[e]^c[e];return d};a.blockIV=function(){var a=new SecureRandom,c=Array(16);a.nextBytes(c);return c};a.pad16=function(a){var c=a.slice(0),d=(16-a.length%16)%16;for(i=a.length;i<a.length+d;i++)c.push(0);return c};a.depad=function(a){for(a=a.slice(0);a[a.length-1]==0;)a=a.slice(0,a.length-1);return a};a.encryptAESCBC=function(b,c){var d=c.slice(0);aes.ExpandKey(d);for(var e=a.string2bytes(b),
e=a.pad16(e),g=a.blockIV(),h=0;h<e.length/16;h++){var f=e.slice(h*16,h*16+16),o=g.slice(h*16,h*16+16),f=a.blockXOR(o,f);aes.Encrypt(f,d);g=g.concat(f)}d=a.bytes2string(g);return a.b256to64(d)};a.decryptAESCBC=function(b,c){var d=c.slice(0);aes.ExpandKey(d);for(var b=a.b64to256(b),e=a.string2bytes(b),g=[],h=1;h<e.length/16;h++){var f=e.slice(h*16,h*16+16),o=e.slice((h-1)*16,(h-1)*16+16);aes.Decrypt(f,d);f=a.blockXOR(o,f);g=g.concat(f)}g=a.depad(g);return a.bytes2string(g)};a.wrap60=function(a){for(var c=
"",d=0;d<a.length;d++)d%60==0&&d!=0&&(c+="\n"),c+=a[d];return c};a.generateAESKey=function(){var a=Array(16);(new SecureRandom).nextBytes(a);return a};a.generateRSAKey=function(a,c){Math.seedrandom(sha256.hex(a));var d=new RSAKey;d.generate(c,"10001");return d};a.publicKeyString=function(b){return pubkey=b.n.toString(16)};a.publicKeyID=function(a){return MD5(a)};a.publicKeyFromString=function(b){var b=b.split("|")[0],c=new RSAKey;c.setPublic(b,"10001");return c};a.encrypt=function(b,
c,d){var e="";try{var h=a.publicKeyFromString(c);e+=h.encrypt(b)+"?"}catch(f){return{status:"Invalid public key"}};return{status:"success",cipher:e}};a.decrypt=function(b,c){var d=b.split("?"),e=c.decrypt(d[0]);return{status:"success",plaintext:e,signature:"unsigned"}};return a}();
\ No newline at end of file
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j,
2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},
q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a,
e)).finalize(b)}}});var n=d.algo={};return d}(Math);
(function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v<p;v++)d.push(t.charAt(w>>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w<
l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])},
_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]),
f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f,
m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m,
E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/
4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math);
(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4*q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d,
l)}})();
CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()},
finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^=
c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this,
e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4*b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a,
this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684,
1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},
decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d,
b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();
(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8,
16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t=
d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();
define(function(require, exports, module) {
var _oCommon, _oUtils, _oBase64;
require("websdk");
_oCommon = require("common");
_oUtils = require("utils");
_oBase64 = require("base64");
function EncryptionFac () {}
EncryptionFac.prototype.encrypt = function (oStr, iRSABits, bBase64Encrypted, cbFun) {
//var that = this;
var iBits = 1024;
if (iRSABits) {
iBits = iRSABits;
}
var szPassPhrase = new Date() + "",
szMattsRSAkey = cryptico.generateRSAKey(szPassPhrase, iBits),
szPublicKeyString = cryptico.publicKeyString(szMattsRSAkey),
szXml = "<?xml version='1.0' encoding='UTF-8'?><PublicKey><key>" + _oBase64.encode(szPublicKeyString) + "</key></PublicKey>",
oXmlDoc = _oUtils.parseXmlFromStr(szXml);
WebSDK.WSDK_Request(_oCommon.m_szHostName, _oCommon.m_iHttpProtocal, _oCommon.m_iHttpPort, {
cmd: "challenge",
type: "POST",
data: oXmlDoc,
success: function (status, xmlDoc) {
var szDecryptionResult = cryptico.decrypt(_oBase64.decode(_oUtils.nodeValue(xmlDoc, "key")), szMattsRSAkey);
if(szDecryptionResult.plaintext != null) {
var szKey,szEncryptPassword;
var aResult = [];
if (iBits === 256) {
szKey = _oUtils.toHex(szDecryptionResult.plaintext);
} else {
szKey = szDecryptionResult.plaintext;
}
szEncryptPassword = aes_encrypt(szDecryptionResult.plaintext.substring(0, 16), szKey, true);
if("function" === typeof cbFun) {
if("string" === typeof oStr) {
bBase64Encrypted && ( oStr = _oBase64.encode(oStr) );
cbFun( _oBase64.encode( szEncryptPassword + _oUtils.encodeAES(oStr, szKey, "", "ecb") ) );
} else if("[object Array]" === Object.prototype.toString.call(oStr)) {
for(var i = 0, iArrayLen = oStr.length; i < iArrayLen; i++) {
bBase64Encrypted && ( oStr[i] = _oBase64.encode(oStr[i]) );
var szTemp = szEncryptPassword + _oUtils.encodeAES(oStr[i], szKey, "", "ecb");
aResult.push( _oBase64.encode(szTemp) );
}
cbFun(aResult);
}
}
}
}
});
};
EncryptionFac.prototype.encryptSync = function (oStr, iRSABits, bBase64Encrypted) {
//var that = this;
var iBits = 1024;
var aResult = [];
if (iRSABits) {
iBits = iRSABits;
}
var szPassPhrase = new Date() + "",
szMattsRSAkey = cryptico.generateRSAKey(szPassPhrase, iBits),
szPublicKeyString = cryptico.publicKeyString(szMattsRSAkey),
szXml = "<?xml version='1.0' encoding='UTF-8'?><PublicKey><key>" + _oBase64.encode(szPublicKeyString) + "</key></PublicKey>",
oXmlDoc = _oUtils.parseXmlFromStr(szXml);
WebSDK.WSDK_Request(_oCommon.m_szHostName, _oCommon.m_iHttpProtocal, _oCommon.m_iHttpPort, {
cmd: "challenge",
type: "POST",
async: false,
data: oXmlDoc,
success: function (status, xmlDoc) {
var szDecryptionResult = cryptico.decrypt(_oBase64.decode(_oUtils.nodeValue(xmlDoc, "key")), szMattsRSAkey);
if(szDecryptionResult.plaintext != null) {
var szKey, szEncryptPassword;
if (iBits === 256) {
szKey = _oUtils.toHex(szDecryptionResult.plaintext);
} else {
szKey = szDecryptionResult.plaintext;
}
szEncryptPassword = aes_encrypt(szDecryptionResult.plaintext.substring(0, 16), szKey, true);
if("string" === typeof oStr) {
bBase64Encrypted && ( oStr = _oBase64.encode(oStr) );
aResult.push( _oBase64.encode( szEncryptPassword + _oUtils.encodeAES(oStr, szKey, "", "ecb") ) );
} else {
for(var i = 0, iArrayLen = oStr.length; i < iArrayLen; i++) {
bBase64Encrypted && ( oStr[i] = _oBase64.encode(oStr[i]) );
var szTemp = szEncryptPassword + _oUtils.encodeAES(oStr[i], szKey, "", "ecb");
aResult.push( _oBase64.encode(szTemp) );
}
}
}
}
});
if("string" === typeof oStr) {
return aResult[0];
} else {
return aResult;
}
};
module.exports = new EncryptionFac();
});
\ No newline at end of file
/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",I="\\["+M+"*("+R+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+R+"))|)"+M+"*\\]",W=":("+R+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+I+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),F=new RegExp("^"+M+"*,"+M+"*"),_=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="<a id='"+b+"'></a><select id='"+b+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:he(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:he(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=r.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})r.pseudos[t]=fe(t);for(t in{submit:!0,reset:!0})r.pseudos[t]=pe(t);function ye(){}ye.prototype=r.filters=r.pseudos,r.setFilters=new ye,a=oe.tokenize=function(e,t){var n,i,o,a,s,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=r.preFilter;while(s){n&&!(i=F.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),n=!1,(i=_.exec(s))&&(n=i.shift(),o.push({value:n,type:i[0].replace(B," ")}),s=s.slice(n.length));for(a in r.filter)!(i=V[a].exec(s))||l[a]&&!(i=l[a](i))||(n=i.shift(),o.push({value:n,type:a,matches:i}),s=s.slice(n.length));if(!n)break}return t?s.length:s?oe.error(e):k(e,u).slice(0)};function ve(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function me(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[T,s];if(u){while(t=t[r])if((1===t.nodeType||a)&&e(t,n,u))return!0}else while(t=t[r])if(1===t.nodeType||a)if(f=t[b]||(t[b]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===T&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function xe(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}function we(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(e,t,n,r,i,o){return r&&!r[b]&&(r=Te(r)),i&&!i[b]&&(i=Te(i,o)),se(function(o,a,s,u){var l,c,f,p=[],d=[],h=a.length,g=o||be(t||"*",s.nodeType?[s]:s,[]),y=!e||!o&&t?g:we(g,p,e,s,u),v=n?i||(o?e:h||r)?[]:a:y;if(n&&n(y,v,s,u),r){l=we(v,d),r(l,[],s,u),c=l.length;while(c--)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f))}if(o){if(i||e){if(i){l=[],c=v.length;while(c--)(f=v[c])&&l.push(y[c]=f);i(null,v=[],l,u)}c=v.length;while(c--)(f=v[c])&&(l=i?O(o,f):p[c])>-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u<o;u++)if(n=r.relative[e[u].type])p=[me(xe(p),n)];else{if((n=r.filter[e[u].type].apply(null,e[u].matches))[b]){for(i=++u;i<o;i++)if(r.relative[e[i].type])break;return Te(u>1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u<i&&Ce(e.slice(u,i)),i<o&&Ce(e=e.slice(i)),i<o&&ve(e))}p.push(n)}return xe(p)}function Ee(e,t){var n=t.length>0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t<r;t++)if(w.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)w.find(e,i[t],n);return r>1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(w.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&w(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s<o.length)!1===o[s].apply(n[0],n[1])&&e.stopOnFalse&&(s=o.length,n=!1)}e.memory||(n=!1),t=!1,i&&(o=n?[]:"")},l={add:function(){return o&&(n&&!t&&(s=o.length-1,a.push(n)),function t(n){w.each(n,function(n,r){g(r)?e.unique&&l.has(r)||o.push(r):r&&r.length&&"string"!==x(r)&&t(r)})}(arguments),n&&!t&&u()),this},remove:function(){return w.each(arguments,function(e,t){var n;while((n=w.inArray(t,o,n))>-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t<o)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");l=e&&("object"==typeof e||"function"==typeof e)&&e.then,g(l)?i?l.call(e,a(o,n,I,i),a(o,n,W,i)):(o++,l.call(e,a(o,n,I,i),a(o,n,W,i),a(o,n,I,n.notifyWith))):(r!==I&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},c=i?l:function(){try{l()}catch(e){w.Deferred.exceptionHook&&w.Deferred.exceptionHook(e,c.stackTrace),t+1>=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},X=/^-ms-/,U=/-([a-z])/g;function V(e,t){return t.toUpperCase()}function G(e){return e.replace(X,"ms-").replace(U,V)}var Y=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=w.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Y(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[G(t)]=n;else for(r in t)i[G(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][G(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(G):(t=G(t))in r?[t]:t.match(M)||[]).length;while(n--)delete r[t[n]]}(void 0===t||w.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!w.isEmptyObject(t)}};var J=new Q,K=new Q,Z=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,ee=/[A-Z]/g;function te(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Z.test(e)?JSON.parse(e):e)}function ne(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(ee,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=te(n)}catch(e){}K.set(e,t,n)}else n=void 0;return n}w.extend({hasData:function(e){return K.hasData(e)||J.hasData(e)},data:function(e,t,n){return K.access(e,t,n)},removeData:function(e,t){K.remove(e,t)},_data:function(e,t,n){return J.access(e,t,n)},_removeData:function(e,t){J.remove(e,t)}}),w.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=K.get(o),1===o.nodeType&&!J.get(o,"hasDataAttrs"))){n=a.length;while(n--)a[n]&&0===(r=a[n].name).indexOf("data-")&&(r=G(r.slice(5)),ne(o,r,i[r]));J.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){K.set(this,e)}):z(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=K.get(o,e)))return n;if(void 0!==(n=ne(o,e)))return n}else this.each(function(){K.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?w.queue(this[0],e):void 0===t?this:this.each(function(){var n=w.queue(this,e,t);w._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&w.dequeue(this,e)})},dequeue:function(e){return this.each(function(){w.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=w.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=J.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var re=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ie=new RegExp("^(?:([+-])=|)("+re+")([a-z%]*)$","i"),oe=["Top","Right","Bottom","Left"],ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&w.contains(e.ownerDocument,e)&&"none"===w.css(e,"display")},se=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i};function ue(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return w.css(e,t,"")},u=s(),l=n&&n[3]||(w.cssNumber[t]?"":"px"),c=(w.cssNumber[t]||"px"!==l&&+u)&&ie.exec(w.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)w.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,w.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var le={};function ce(e){var t,n=e.ownerDocument,r=e.nodeName,i=le[r];return i||(t=n.body.appendChild(n.createElement(r)),i=w.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),le[r]=i,i)}function fe(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)(r=e[o]).style&&(n=r.style.display,t?("none"===n&&(i[o]=J.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&ae(r)&&(i[o]=ce(r))):"none"!==n&&(i[o]="none",J.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}w.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?w(this).show():w(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)J.set(e[n],"globalEval",!t||J.get(t[n],"globalEval"))}var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===x(o))w.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+w.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;w.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&w.inArray(o,r)>-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="<textarea>x</textarea>",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n<arguments.length;n++)u[n]=arguments[n];if(t.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,t)){s=w.event.handlers.call(this,t,l),n=0;while((o=s[n++])&&!t.isPropagationStopped()){t.currentTarget=o.elem,r=0;while((a=o.handlers[r++])&&!t.isImmediatePropagationStopped())t.rnamespace&&!t.rnamespace.test(a.namespace)||(t.handleObj=a,t.data=a.data,void 0!==(i=((w.event.special[a.origType]||{}).handle||a.handler).apply(o.elem,u))&&!1===(t.result=i)&&(t.preventDefault(),t.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,t),t.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?w(i,this).index(l)>-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(w.Event.prototype,e,{enumerable:!0,configurable:!0,get:g(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[w.expando]?e:new w.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==Se()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===Se()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},w.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},w.Event=function(e,t){if(!(this instanceof w.Event))return new w.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ee:ke,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&w.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[w.expando]=!0},w.Event.prototype={constructor:w.Event,isDefaultPrevented:ke,isPropagationStopped:ke,isImmediatePropagationStopped:ke,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ee,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ee,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ee,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},w.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&we.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Te.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},w.event.addProp),w.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){w.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||w.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),w.fn.extend({on:function(e,t,n,r){return De(this,e,t,n,r)},one:function(e,t,n,r){return De(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,w(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=ke),this.each(function(){w.event.remove(this,e,n,t)})}});var Ne=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/<script|<style|<link/i,je=/checked\s*(?:[^=]|=\s*.checked.)/i,qe=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)w.event.add(t,i,l[i][n])}K.hasData(e)&&(s=K.access(e),u=w.extend({},s),K.set(t,u))}}function Me(e,t){var n=t.nodeName.toLowerCase();"input"===n&&pe.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function Re(e,t,n,r){t=a.apply([],t);var i,o,s,u,l,c,f=0,p=e.length,d=p-1,y=t[0],v=g(y);if(v||p>1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f<p;f++)l=i,f!==d&&(l=w.clone(l,!0,!0),u&&w.merge(s,ye(l,"script"))),n.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,w.map(s,Oe),f=0;f<u;f++)l=s[f],he.test(l.type||"")&&!J.access(l,"globalEval")&&w.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?w._evalUrl&&w._evalUrl(l.src):m(l.textContent.replace(qe,""),c,l))}return e}function Ie(e,t,n){for(var r,i=t?w.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||w.cleanData(ye(r)),r.parentNode&&(n&&w.contains(r.ownerDocument,r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}w.extend({htmlPrefilter:function(e){return e.replace(Ne,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r<i;r++)Me(o[r],a[r]);if(t)if(n)for(o=o||ye(e),a=a||ye(s),r=0,i=o.length;r<i;r++)Pe(o[r],a[r]);else Pe(e,s);return(a=ye(s,"script")).length>0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(w.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return Re(this,arguments,function(t){var n=this.parentNode;w.inArray(this,e)<0&&(w.cleanData(ye(this)),n&&n.replaceChild(t,this))},e)}}),w.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){w.fn[e]=function(e){for(var n,r=[],i=w(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),w(i[a])[t](n),s.apply(r,n.get());return this.pushStack(r)}});var We=new RegExp("^("+re+")(?!px)[a-z%]+$","i"),$e=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},Be=new RegExp(oe.join("|"),"i");!function(){function t(){if(c){l.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",c.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",be.appendChild(l).appendChild(c);var t=e.getComputedStyle(c);i="1%"!==t.top,u=12===n(t.marginLeft),c.style.right="60%",s=36===n(t.right),o=36===n(t.width),c.style.position="absolute",a=36===c.offsetWidth||"absolute",be.removeChild(l),c=null}}function n(e){return Math.round(parseFloat(e))}var i,o,a,s,u,l=r.createElement("div"),c=r.createElement("div");c.style&&(c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",h.clearCloneStyle="content-box"===c.style.backgroundClip,w.extend(h,{boxSizingReliable:function(){return t(),o},pixelBoxStyles:function(){return t(),s},pixelPosition:function(){return t(),i},reliableMarginLeft:function(){return t(),u},scrollboxSize:function(){return t(),a}}))}();function Fe(e,t,n){var r,i,o,a,s=e.style;return(n=n||$e(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||w.contains(e.ownerDocument,e)||(a=w.style(e,t)),!h.pixelBoxStyles()&&We.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}var ze=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ue={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","Moz","ms"],Ye=r.createElement("div").style;function Qe(e){if(e in Ye)return e;var t=e[0].toUpperCase()+e.slice(1),n=Ge.length;while(n--)if((e=Ge[n]+t)in Ye)return e}function Je(e){var t=w.cssProps[e];return t||(t=w.cssProps[e]=Qe(e)||e),t}function Ke(e,t,n){var r=ie.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ze(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=w.css(e,n+oe[a],!0,i)),r?("content"===n&&(u-=w.css(e,"padding"+oe[a],!0,i)),"margin"!==n&&(u-=w.css(e,"border"+oe[a]+"Width",!0,i))):(u+=w.css(e,"padding"+oe[a],!0,i),"padding"!==n?u+=w.css(e,"border"+oe[a]+"Width",!0,i):s+=w.css(e,"border"+oe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a<i;a++)o[t[a]]=w.css(e,t[a],!1,r);return o}return void 0!==n?w.style(e,t,n):w.css(e,t)},e,t,arguments.length>1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ct(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=J.get(e,"fxshow");n.queue||(null==(a=w._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,w.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],it.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||w.style(e,r)}if((u=!w.isEmptyObject(t))||!w.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=J.get(e,"display")),"none"===(c=w.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=w.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===w.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(y?"hidden"in y&&(g=y.hidden):y=J.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&fe([e],!0),p.done(function(){g||fe([e]),J.remove(e,"fxshow");for(r in d)w.style(e,r,d[r])})),u=lt(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}}function ft(e,t){var n,r,i,o,a;for(n in e)if(r=G(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=w.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function pt(e,t,n){var r,i,o=0,a=pt.prefilters.length,s=w.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=nt||st(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),o=0,a=l.tweens.length;o<a;o++)l.tweens[o].run(r);return s.notifyWith(e,[l,r,n]),r<1&&a?n:(a||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:w.extend({},t),opts:w.extend(!0,{specialEasing:{},easing:w.easing._default},n),originalProperties:t,originalOptions:n,startTime:nt||st(),duration:n.duration,tweens:[],createTween:function(t,n){var r=w.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(ft(c,l.opts.specialEasing);o<a;o++)if(r=pt.prefilters[o].call(l,e,c,l.opts))return g(r.stop)&&(w._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return w.map(c,lt,l),g(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),w.fx.timer(w.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}w.Animation=w.extend(pt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ue(n.elem,e,ie.exec(t),n),n}]},tweener:function(e,t){g(e)?(t=e,e=["*"]):e=e.match(M);for(var n,r=0,i=e.length;r<i;r++)n=e[r],pt.tweeners[n]=pt.tweeners[n]||[],pt.tweeners[n].unshift(t)},prefilters:[ct],prefilter:function(e,t){t?pt.prefilters.unshift(e):pt.prefilters.push(e)}}),w.speed=function(e,t,n){var r=e&&"object"==typeof e?w.extend({},e):{complete:n||!n&&t||g(e)&&e,duration:e,easing:n&&t||t&&!g(t)&&t};return w.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in w.fx.speeds?r.duration=w.fx.speeds[r.duration]:r.duration=w.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){g(r.old)&&r.old.call(this),r.queue&&w.dequeue(this,r.queue)},r},w.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=w.isEmptyObject(e),o=w.speed(t,n,r),a=function(){var t=pt(this,w.extend({},e),o);(i||J.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=w.timers,a=J.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&ot.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||w.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),this.each(function(){var t,n=J.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=w.timers,a=r?r.length:0;for(n.finish=!0,w.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),w.each(["toggle","show","hide"],function(e,t){var n=w.fn[t];w.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ut(t,!0),e,r,i)}}),w.each({slideDown:ut("show"),slideUp:ut("hide"),slideToggle:ut("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){w.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),w.timers=[],w.fx.tick=function(){var e,t=0,n=w.timers;for(nt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||w.fx.stop(),nt=void 0},w.fx.timer=function(e){w.timers.push(e),w.fx.start()},w.fx.interval=13,w.fx.start=function(){rt||(rt=!0,at())},w.fx.stop=function(){rt=null},w.fx.speeds={slow:600,fast:200,_default:400},w.fn.delay=function(t,n){return t=w.fx?w.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=r.createElement("input"),t=r.createElement("select").appendChild(r.createElement("option"));e.type="checkbox",h.checkOn=""!==e.value,h.optSelected=t.selected,(e=r.createElement("input")).value="t",e.type="radio",h.radioValue="t"===e.value}();var dt,ht=w.expr.attrHandle;w.fn.extend({attr:function(e,t){return z(this,w.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=w(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=w.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=w.inArray(w.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&o("error"===e.type?404:200,e.type)}),r.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Yt=[],Qt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||w.expando+"_"+Et++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Qt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=g(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Qt,"$1"+i):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Yt.push(i)),a&&g(o)&&o(a[0]),a=o=void 0}),"script"}),h.createHTMLDocument=function(){var e=r.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),w.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var i,o,a;return t||(h.createHTMLDocument?((i=(t=r.implementation.createHTMLDocument("")).createElement("base")).href=r.location.href,t.head.appendChild(i)):t=r),o=A.exec(e),a=!n&&[],o?[t.createElement(o[1])]:(o=xe([e],t,a),a&&a.length&&w(a).remove(),w.merge([],o.childNodes))},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=vt(e.slice(s)),e=e.slice(0,s)),g(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&w.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?w("<div>").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=w.css(e,"position"),f=w(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=w.css(e,"top"),u=w.css(e,"left"),(l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1)?(a=(r=f.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),g(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===w.css(e,"position"))e=e.offsetParent;return e||be})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return z(this,function(e,r,i){var o;if(y(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=_e(h.pixelPosition,function(e,n){if(n)return n=Fe(e,t),We.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return z(this,function(t,n,i){var o;return y(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
This source diff could not be displayed because it is too large. You can view the blob instead.
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
importScripts('libSystemTransform.js');
const RECORDRTP = 0; //录制一份未经过转封装的码流原始数据,用于定位问题
let dataType = 1;
// 字母字符串转byte数组
function stringToBytes (str) {
var ch;
var st;
var re = [];
for (var i = 0; i < str.length; i++) {
ch = str.charCodeAt(i); // get char
st = []; // set up "stack"
do {
st.push(ch & 0xFF); // push byte to stack
ch = ch >> 8; // shift value down by 1 byte
}
while (ch);
// add stack contents to result
// done because chars have "wrong" endianness
re = re.concat(st.reverse());
}
// return an array of bytes
return re;
}
// 转封装库回调函数
self.STCallBack = function (fileIndex, indexLen, data, dataLen) {
//stFrameInfo的类型见DETAIL_FRAME_INFO
let stFrameInfo = Module._GetDetialFrameInfo();
let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " , stFrameInfo);
//console.log("nIsMp4Index is " + nIsMp4Index);
//debugger
var pData = null;
pData = new Uint8Array(dataLen);
pData.set(Module.HEAPU8.subarray(data, data + dataLen));
if (dataType === 1) {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 1,
frameInfo: stFrameInfo }, [pData.buffer]);
dataType = 2;
} else {
if (nIsMp4Index) {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 6,
frameInfo: stFrameInfo }, [pData.buffer]); //6:索引类型
} else {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 2,
frameInfo: stFrameInfo }, [pData.buffer]); //2:码流
}
}
//stFrameInfo的类型见DETAIL_FRAME_INFO
//let stFrameInfo = Module._GetDetialFrameInfo();
//let stFrameType = stFrameInfo.nFrameType;
//let nFrameNum = stFrameInfo.nFrameNum;
//let nTimeStamp = stFrameInfo.nTimeStamp;
//let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " + stFrameType);
//console.log("nIsMp4Index is " + nIsMp4Index);
};
// self.Module = { memoryInitializerRequest: loadMemInitFile(), TOTAL_MEMORY: 128*1024*1024 };
// importScripts('SystemTransform.js');
self.Module['onRuntimeInitialized'] = function () {
postMessage({type: "loaded"});
};
onmessage = function (e) {
var data = e.data;
if ("create" === data.type) {
if (RECORDRTP) {
postMessage({ type: "created" });
postMessage({ type: "outputData",
buf: data.buf,
dType: 1 }, [data.buf]);
} else {
var iHeadLen = data.len;
var pHead = Module._malloc(iHeadLen);
if (pHead === null) {
console.log("inputdata malloc failed!!!");
return -1;
}
var iTransType = data.packType;//目标格式
var iRet = 0;
var buf = new Uint8Array(data.buf);
//PS流(只有ps支持探测),并且编码格式异常(正常是265和264,11位和10位 不可能全是0,全0 并且是ps就探测策略)的情况下,使用探测策略
if (buf[9] === 0 && buf[8] === 2 && buf[11] === 0 && buf[10] === 0) {
iRet = Module._CreatHandle(0, iTransType, iHeadLen); //用探测的策略
} else {
self.writeArrayToMemory(buf, pHead);
iRet = Module._CreatHandle(pHead, iTransType, iHeadLen);
//-2147483645代表的是参数错误,此种情况,大概率发生在头信息错误,例如大华设备的情况,此时用 无头探测的策略
//其他情况 按海康标准处理流程,不要做任何特殊处理
if (iRet == -2147483645) {
iRet = Module._CreatHandle(0, iTransType, iHeadLen); //失败了,用探测的策略再试一次
}
}
if (iRet != 0) {
if (iRet == -2147483647) {
postMessage({ type: "outputData",
dType: 1501 }); //标记为格式不支持
} else {
postMessage({ type: "outputData",
dType: 1501 }); //转封装创建失败,也同样提示码流格式不支持,如果后续要细化再区分
}
console.log("_CreatHandle failed!" + iRet);
} else {
if (data.options && typeof data.options.pKeyData !== "undefined" && data.options.pKeyData !== null) {
if ((2 === iTransType && "" === data.options.pKeyData)) {
//转ps的时候,如果密码是空是允许的,即使码流加密了,导出加密后的码流就行
//此时不要设置密码否则反而会提示密码错误
} else {
var secretInfo = data.options;
var keyLen = secretInfo.nKeyLen;
var pKeyData = Module._malloc(keyLen);
if (pKeyData === null) {
console.log("setEncryptKey malloc failed!!!");
return -1;
}
var nKeySize = secretInfo.pKeyData.length;
var bufData = stringToBytes(secretInfo.pKeyData);
let inputData = new Uint8Array(bufData);
Module.writeArrayToMemory(inputData, pKeyData);
inputData = null;
iRet = Module._SysTransSetEncryptKey(secretInfo.nKeyType, pKeyData, keyLen, nKeySize);
if (iRet != 0) {
console.log("_SysTransSetEncryptKey failed!");
}
if (pKeyData != null) {
Module._free(pKeyData);
pKeyData = null;
}
}
}
//带samplingParam参数,代表需要 用到 音频替换功能
if (data.options && typeof data.options.samplingParam !== "undefined") {
var oParam = data.options.samplingParam;
var nCapacityType = 1; //写死1 代表 剔除音频
var nType = 3; //写死3 代表 修改输出目标的海康头配置,内部包含视频参数、音频参数
var nAudioEnable = 1; //音频参数修改使能开关,0=不启用,1=启用
var nAudioFormat = oParam.iAudioType; //音频编码类型 对应关系参考海康媒体头规范,PCM 0x7001 G711_U 0x7110 G711_A 0x7111 AAC 0x2001
var nAudioChannels = oParam.iChannel; //音频通道数直接设置为
var nAudioBitsPerSample = oParam.iAudioBitWidth; //音频位样率
var nAudioSamplesrate = oParam.iAudioSamplingRate; //音频采样率
var nAudioBitrate = oParam.iAudioBitRate; //音频比特率
iRet = Module._SysTransConfig(nCapacityType, nType, nAudioEnable, nAudioFormat,
nAudioChannels, nAudioBitsPerSample, nAudioSamplesrate, nAudioBitrate);
if (iRet != 0) {
console.log("_SysTransConfig Failed:" + iRet);
}
} else {
iRet = Module._SysTransConfig(128, 0, 0, 0, 0, 0, 0, 0); //nCapacityType = 0x00000080 代表开启私有信息回调 解决转mp4后,私有信息丢失问题
if (iRet != 0) {
console.log("_SysTransConfig Failed:" + iRet);
}
}
iRet = Module._SysTransRegisterDataCallBack();
if (iRet != 0) {
console.log("_SysTransRegisterDataCallBack Failed:" + iRet);
}
iRet = Module._SysTransStart(null, null);
if (iRet != 0) {
console.log("_SysTransStart Failed:" + iRet);
}
postMessage({type: "created"});
}
if (pHead != null) {
Module._free(pHead);
pHead = null;
}
}
} else if ("inputData" === data.type) {
if (RECORDRTP) {
var aFileData = new Uint8Array(data.buf); // 拷贝一份
var iBufferLen = aFileData.length;
var szBufferLen = iBufferLen.toString(16);
if (szBufferLen.length === 1) {
szBufferLen = "000" + szBufferLen;
} else if (szBufferLen.length === 2) {
szBufferLen = "00" + szBufferLen;
} else if (szBufferLen.length === 3) {
szBufferLen = "0" + szBufferLen;
}
var aData = [0, 0, parseInt(szBufferLen.substring(0, 2), 16), parseInt(szBufferLen.substring(2, 4), 16)];
for (var iIndex = 0, iDataLength = aFileData.length; iIndex < iDataLength; iIndex++) {
aData[iIndex + 4] = aFileData[iIndex];
}
var dataUint8 = new Uint8Array(aData);
postMessage({type: "outputData",
buf: dataUint8.buffer,
dType: 2});
} else {
let inputMode = 0; //代表输入原始数据
if (data.samplingParam) {
iRet = Module._SysTransInputAudioPara(5, data.samplingParam.iChannel, data.samplingParam.iAudioBitWidth,
data.samplingParam.iAudioSamplingRate, data.samplingParam.iTimeStamp, data.samplingParam.iAudioBitRate); //参数含义和_SysTransConfig类似
if (iRet != 0) {
console.log("_SysTransInputAudioPara Failed:" + iRet);
}
inputMode = 2; //输入替换的音频
}
var pInputDataBuf = Module._malloc(data.len);
var idataLen = data.len;
self.writeArrayToMemory(new Uint8Array(data.buf), pInputDataBuf);
// 输入数据,每次最多2m
let pp = Module._SysTransInputData(inputMode, pInputDataBuf, idataLen);
if (pp == -2147483627) {
//-2147483627 对应十六进制的80000015
postMessage({ type: "outputData",
dType: 1500 }); //标记为密码错误
} else if (pp == -2147483647) {
postMessage({ type: "outputData",
dType: 1501 }); //标记为格式不支持
} else if (pp != 0) {
console.log("InputData Failed:" + pp);
}
Module._free(pInputDataBuf);
}
} else if ("release" === data.type) {
var iRet = Module._SysTransStop();
if (iRet != 0) {
console.log("_SysTransStop failed!");
}
Module._SysTransRelease();
if (iRet != 0) {
console.log("_SysTransRelease failed!");
}
close();
}
};
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.3.3 Copyright jQuery Foundation and other contributors.
* Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE
*/
var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i<e.length&&(!e[i]||!t(e[i],i,e));i+=1);}}function eachReverse(e,t){if(e){var i;for(i=e.length-1;i>-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t<e.length;t++)if(i=e[t],"."===i)e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;t>0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.3",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout);
\ No newline at end of file
/*! Sea.js 3.0.1 | seajs.org/LICENSE.md */
!function(a,b){function c(a){return function(b){return{}.toString.call(b)=="[object "+a+"]"}}function d(){return B++}function e(a){return a.match(E)[0]}function f(a){for(a=a.replace(F,"/"),a=a.replace(H,"$1/");a.match(G);)a=a.replace(G,"/");return a}function g(a){var b=a.length-1,c=a.charCodeAt(b);return 35===c?a.substring(0,b):".js"===a.substring(b-2)||a.indexOf("?")>0||47===c?a:a+".js"}function h(a){var b=v.alias;return b&&x(b[a])?b[a]:a}function i(a){var b=v.paths,c;return b&&(c=a.match(I))&&x(b[c[1]])&&(a=b[c[1]]+c[2]),a}function j(a){var b=v.vars;return b&&a.indexOf("{")>-1&&(a=a.replace(J,function(a,c){return x(b[c])?b[c]:a})),a}function k(a){var b=v.map,c=a;if(b)for(var d=0,e=b.length;e>d;d++){var f=b[d];if(c=z(f)?f(a)||a:a.replace(f[0],f[1]),c!==a)break}return c}function l(a,b){var c,d=a.charCodeAt(0);if(K.test(a))c=a;else if(46===d)c=(b?e(b):v.cwd)+a;else if(47===d){var g=v.cwd.match(L);c=g?g[0]+a.substring(1):a}else c=v.base+a;return 0===c.indexOf("//")&&(c=location.protocol+c),f(c)}function m(a,b){if(!a)return"";a=h(a),a=i(a),a=h(a),a=j(a),a=h(a),a=g(a),a=h(a);var c=l(a,b);return c=h(c),c=k(c)}function n(a){return a.hasAttribute?a.src:a.getAttribute("src",4)}function o(a,b,c,d){var e;try{importScripts(a)}catch(f){e=f}b(e)}function p(a,b,c,d){var e=Z.createElement("script");c&&(e.charset=c),A(d)||e.setAttribute("crossorigin",d),q(e,b,a),e.async=!0,e.src=a,ca=e,ba?aa.insertBefore(e,ba):aa.appendChild(e),ca=null}function q(a,b,c){function d(c){a.onload=a.onerror=a.onreadystatechange=null,v.debug||aa.removeChild(a),a=null,b(c)}var e="onload"in a;e?(a.onload=d,a.onerror=function(){D("error",{uri:c,node:a}),d(!0)}):a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&d()}}function r(){if(ca)return ca;if(da&&"interactive"===da.readyState)return da;for(var a=aa.getElementsByTagName("script"),b=a.length-1;b>=0;b--){var c=a[b];if("interactive"===c.readyState)return da=c}}function s(a){function b(){l=a.charAt(k++)}function c(){return/\s/.test(l)}function d(){return'"'==l||"'"==l}function e(){var c=k,d=l,e=a.indexOf(d,c);if(-1==e)k=m;else if("\\"!=a.charAt(e-1))k=e+1;else for(;m>k;)if(b(),"\\"==l)k++;else if(l==d)break;o&&(p.push(a.substring(c,k-1)),o=0)}function f(){for(k--;m>k;)if(b(),"\\"==l)k++;else{if("/"==l)break;if("["==l)for(;m>k;)if(b(),"\\"==l)k++;else if("]"==l)break}}function g(){return/[a-z_$]/i.test(l)}function h(){var b=a.slice(k-1),c=/^[\w$]+/.exec(b)[0];q={"if":1,"for":1,"while":1,"with":1}[c],n={"break":1,"case":1,"continue":1,"debugger":1,"delete":1,"do":1,"else":1,"false":1,"if":1,"in":1,"instanceof":1,"return":1,"typeof":1,"void":1}[c],u="return"==c,s={"instanceof":1,"delete":1,"void":1,"typeof":1,"return":1}.hasOwnProperty(c),o=/^require\s*(?:\/\*[\s\S]*?\*\/\s*)?\(\s*(['"]).+?\1\s*[),]/.test(b),o?(c=/^require\s*(?:\/\*[\s\S]*?\*\/\s*)?\(\s*['"]/.exec(b)[0],k+=c.length-2):k+=/^[\w$]+(?:\s*\.\s*[\w$]+)*/.exec(b)[0].length-1}function i(){return/\d/.test(l)||"."==l&&/\d/.test(a.charAt(k))}function j(){var b=a.slice(k-1),c;c="."==l?/^\.\d+(?:E[+-]?\d*)?\s*/i.exec(b)[0]:/^0x[\da-f]*/i.test(b)?/^0x[\da-f]*\s*/i.exec(b)[0]:/^\d+\.?\d*(?:E[+-]?\d*)?\s*/i.exec(b)[0],k+=c.length-1,n=0}if(-1==a.indexOf("require"))return[];for(var k=0,l,m=a.length,n=1,o=0,p=[],q=0,r=[],s,t=[],u;m>k;)if(b(),c())!u||"\n"!=l&&"\r"!=l||(s=0,u=0);else if(d())e(),n=1,u=0,s=0;else if("/"==l)if(b(),"/"==l)k=a.indexOf("\n",k),-1==k&&(k=a.length);else if("*"==l){var v=a.indexOf("\n",k);k=a.indexOf("*/",k),-1==k?k=m:k+=2,u&&-1!=v&&k>v&&(s=0,u=0)}else n?(f(),n=0,u=0,s=0):(k--,n=1,u=0,s=1);else if(g())h();else if(i())j(),u=0,s=0;else if("("==l)r.push(q),n=1,u=0,s=1;else if(")"==l)n=r.pop(),u=0,s=0;else if("{"==l)u&&(s=1),t.push(s),u=0,n=1;else if("}"==l)s=t.pop(),n=!s,u=0;else{var w=a.charAt(k);";"==l?s=0:"-"==l&&"-"==w||"+"==l&&"+"==w||"="==l&&">"==w?(s=0,k++):s=1,n="]"!=l,u=0}return p}function t(a,b){this.uri=a,this.dependencies=b||[],this.deps={},this.status=0,this._entry=[]}if(!a.seajs){var u=a.seajs={version:"3.0.1"},v=u.data={},w=c("Object"),x=c("String"),y=Array.isArray||c("Array"),z=c("Function"),A=c("Undefined"),B=0,C=v.events={};u.on=function(a,b){var c=C[a]||(C[a]=[]);return c.push(b),u},u.off=function(a,b){if(!a&&!b)return C=v.events={},u;var c=C[a];if(c)if(b)for(var d=c.length-1;d>=0;d--)c[d]===b&&c.splice(d,1);else delete C[a];return u};var D=u.emit=function(a,b){var c=C[a];if(c){c=c.slice();for(var d=0,e=c.length;e>d;d++)c[d](b)}return u},E=/[^?#]*\//,F=/\/\.\//g,G=/\/[^\/]+\/\.\.\//,H=/([^:\/])\/+\//g,I=/^([^\/:]+)(\/.+)$/,J=/{([^{]+)}/g,K=/^\/\/.|:\//,L=/^.*?\/\/.*?\//;u.resolve=m;var M="undefined"==typeof window&&"undefined"!=typeof importScripts&&z(importScripts),N=/^(about|blob):/,O,P,Q=!location.href||N.test(location.href)?"":e(location.href);if(M){var R;try{var S=Error();throw S}catch(T){R=T.stack.split("\n")}R.shift();for(var U,V=/.*?((?:http|https|file)(?::\/{2}[\w]+)(?:[\/|\.]?)(?:[^\s"]*)).*?/i,W=/(.*?):\d+:\d+\)?$/;R.length>0;){var X=R.shift();if(U=V.exec(X),null!=U)break}var Y;if(null!=U)var Y=W.exec(U[1])[1];P=Y,O=e(Y||Q),""===Q&&(Q=O)}else{var Z=document,$=Z.scripts,_=Z.getElementById("seajsnode")||$[$.length-1];P=n(_),O=e(P||Q)}if(M)u.request=o;else{var Z=document,aa=Z.head||Z.getElementsByTagName("head")[0]||Z.documentElement,ba=aa.getElementsByTagName("base")[0],ca;u.request=p}var da,ea=u.cache={},fa,ga={},ha={},ia={},ja=t.STATUS={FETCHING:1,SAVED:2,LOADING:3,LOADED:4,EXECUTING:5,EXECUTED:6,ERROR:7};t.prototype.resolve=function(){for(var a=this,b=a.dependencies,c=[],d=0,e=b.length;e>d;d++)c[d]=t.resolve(b[d],a.uri);return c},t.prototype.pass=function(){for(var a=this,b=a.dependencies.length,c=0;c<a._entry.length;c++){for(var d=a._entry[c],e=0,f=0;b>f;f++){var g=a.deps[a.dependencies[f]];g.status<ja.LOADED&&!d.history.hasOwnProperty(g.uri)&&(d.history[g.uri]=!0,e++,g._entry.push(d),g.status===ja.LOADING&&g.pass())}e>0&&(d.remain+=e-1,a._entry.shift(),c--)}},t.prototype.load=function(){var a=this;if(!(a.status>=ja.LOADING)){a.status=ja.LOADING;var c=a.resolve();D("load",c);for(var d=0,e=c.length;e>d;d++)a.deps[a.dependencies[d]]=t.get(c[d]);if(a.pass(),a._entry.length)return a.onload(),b;var f={},g;for(d=0;e>d;d++)g=ea[c[d]],g.status<ja.FETCHING?g.fetch(f):g.status===ja.SAVED&&g.load();for(var h in f)f.hasOwnProperty(h)&&f[h]()}},t.prototype.onload=function(){var a=this;a.status=ja.LOADED;for(var b=0,c=(a._entry||[]).length;c>b;b++){var d=a._entry[b];0===--d.remain&&d.callback()}delete a._entry},t.prototype.error=function(){var a=this;a.onload(),a.status=ja.ERROR},t.prototype.exec=function(){function a(b){var d=c.deps[b]||t.get(a.resolve(b));if(d.status==ja.ERROR)throw Error("module was broken: "+d.uri);return d.exec()}var c=this;if(c.status>=ja.EXECUTING)return c.exports;if(c.status=ja.EXECUTING,c._entry&&!c._entry.length&&delete c._entry,!c.hasOwnProperty("factory"))return c.non=!0,b;var e=c.uri;a.resolve=function(a){return t.resolve(a,e)},a.async=function(b,c){return t.use(b,c,e+"_async_"+d()),a};var f=c.factory,g=z(f)?f.call(c.exports={},a,c.exports,c):f;return g===b&&(g=c.exports),delete c.factory,c.exports=g,c.status=ja.EXECUTED,D("exec",c),c.exports},t.prototype.fetch=function(a){function c(){u.request(g.requestUri,g.onRequest,g.charset,g.crossorigin)}function d(a){delete ga[h],ha[h]=!0,fa&&(t.save(f,fa),fa=null);var b,c=ia[h];for(delete ia[h];b=c.shift();)a===!0?b.error():b.load()}var e=this,f=e.uri;e.status=ja.FETCHING;var g={uri:f};D("fetch",g);var h=g.requestUri||f;return!h||ha.hasOwnProperty(h)?(e.load(),b):ga.hasOwnProperty(h)?(ia[h].push(e),b):(ga[h]=!0,ia[h]=[e],D("request",g={uri:f,requestUri:h,onRequest:d,charset:z(v.charset)?v.charset(h):v.charset,crossorigin:z(v.crossorigin)?v.crossorigin(h):v.crossorigin}),g.requested||(a?a[g.requestUri]=c:c()),b)},t.resolve=function(a,b){var c={id:a,refUri:b};return D("resolve",c),c.uri||u.resolve(c.id,b)},t.define=function(a,c,d){var e=arguments.length;1===e?(d=a,a=b):2===e&&(d=c,y(a)?(c=a,a=b):c=b),!y(c)&&z(d)&&(c=b===s?[]:s(""+d));var f={id:a,uri:t.resolve(a),deps:c,factory:d};if(!M&&!f.uri&&Z.attachEvent&&b!==r){var g=r();g&&(f.uri=g.src)}D("define",f),f.uri?t.save(f.uri,f):fa=f},t.save=function(a,b){var c=t.get(a);c.status<ja.SAVED&&(c.id=b.id||a,c.dependencies=b.deps||[],c.factory=b.factory,c.status=ja.SAVED,D("save",c))},t.get=function(a,b){return ea[a]||(ea[a]=new t(a,b))},t.use=function(b,c,d){var e=t.get(d,y(b)?b:[b]);e._entry.push(e),e.history={},e.remain=1,e.callback=function(){for(var b=[],d=e.resolve(),f=0,g=d.length;g>f;f++)b[f]=ea[d[f]].exec();c&&c.apply(a,b),delete e.callback,delete e.history,delete e.remain,delete e._entry},e.load()},u.use=function(a,b){return t.use(a,b,v.cwd+"_use_"+d()),u},t.define.cmd={},a.define=t.define,u.Module=t,v.fetchedList=ha,v.cid=d,u.require=function(a){var b=t.get(t.resolve(a));return b.status<ja.EXECUTING&&(b.onload(),b.exec()),b.exports},v.base=O,v.dir=O,v.loader=P,v.cwd=Q,v.charset="utf-8",u.config=function(a){for(var b in a){var c=a[b],d=v[b];if(d&&w(d))for(var e in c)d[e]=c[e];else y(d)?c=d.concat(c):"base"===b&&("/"!==c.slice(-1)&&(c+="/"),c=l(c)),v[b]=c}return D("config",a),u}}}(this);
\ No newline at end of file
var WebRtcStreamer = (function() {
/**
* Interface with WebRTC-streamer API
* @constructor
* @param {string} videoElement - id of the video element tag
* @param {string} srvurl - url of webrtc-streamer (default is current location)
*/
var WebRtcStreamer = function WebRtcStreamer (videoElement, srvurl) {
if (typeof videoElement === "string") {
this.videoElement = document.getElementById(videoElement);
} else {
this.videoElement = videoElement;
}
this.srvurl = srvurl || location.protocol+"//"+window.location.hostname+":"+window.location.port;
this.pc = null;
this.mediaConstraints = { offerToReceiveAudio: true, offerToReceiveVideo: true };
this.iceServers = null;
this.earlyCandidates = [];
}
WebRtcStreamer.prototype._handleHttpErrors = function (response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
/**
* Connect a WebRTC Stream to videoElement
* @param {string} videourl - id of WebRTC video stream
* @param {string} audiourl - id of WebRTC audio stream
* @param {string} options - options of WebRTC call
* @param {string} stream - local stream to send
* @param {string} prefmime - prefered mime
*/
WebRtcStreamer.prototype.connect = function(videourl, audiourl, options, localstream, prefmime) {
this.disconnect();
// getIceServers is not already received
if (!this.iceServers) {
console.log("Get IceServers");
fetch(this.srvurl + "/api/getIceServers")
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.then( (response) => this.onReceiveGetIceServers(response, videourl, audiourl, options, localstream, prefmime))
.catch( (error) => this.onError("getIceServers " + error ))
} else {
this.onReceiveGetIceServers(this.iceServers, videourl, audiourl, options, localstream, prefmime);
}
}
/**
* Disconnect a WebRTC Stream and clear videoElement source
*/
WebRtcStreamer.prototype.disconnect = function() {
if (this.videoElement?.srcObject) {
this.videoElement.srcObject.getTracks().forEach(track => {
track.stop()
this.videoElement.srcObject.removeTrack(track);
});
}
if (this.pc) {
fetch(this.srvurl + "/api/hangup?peerid=" + this.pc.peerid)
.then(this._handleHttpErrors)
.catch( (error) => this.onError("hangup " + error ))
try {
this.pc.close();
}
catch (e) {
console.log ("Failure close peer connection:" + e);
}
this.pc = null;
}
}
WebRtcStreamer.prototype.filterPreferredCodec = function(sdp, prefmime) {
const lines = sdp.split('\n');
const [prefkind, prefcodec] = prefmime.toLowerCase().split('/');
let currentMediaType = null;
let sdpSections = [];
let currentSection = [];
// Group lines into sections
lines.forEach(line => {
if (line.startsWith('m=')) {
if (currentSection.length) {
sdpSections.push(currentSection);
}
currentSection = [line];
} else {
currentSection.push(line);
}
});
sdpSections.push(currentSection);
// Process each section
const processedSections = sdpSections.map(section => {
const firstLine = section[0];
if (!firstLine.startsWith('m=' + prefkind)) {
return section.join('\n');
}
// Get payload types for preferred codec
const rtpLines = section.filter(line => line.startsWith('a=rtpmap:'));
const preferredPayloads = rtpLines
.filter(line => line.toLowerCase().includes(prefcodec))
.map(line => line.split(':')[1].split(' ')[0]);
if (preferredPayloads.length === 0) {
return section.join('\n');
}
// Modify m= line to only include preferred payloads
const mLine = firstLine.split(' ');
const newMLine = [...mLine.slice(0,3), ...preferredPayloads].join(' ');
// Filter related attributes
const filteredLines = section.filter(line => {
if (line === firstLine) return false;
if (line.startsWith('a=rtpmap:')) {
return preferredPayloads.some(payload => line.startsWith(`a=rtpmap:${payload}`));
}
if (line.startsWith('a=fmtp:') || line.startsWith('a=rtcp-fb:')) {
return preferredPayloads.some(payload => line.startsWith(`a=${line.split(':')[0].split('a=')[1]}:${payload}`));
}
return true;
});
return [newMLine, ...filteredLines].join('\n');
});
return processedSections.join('\n');
}
/*
* GetIceServers callback
*/
WebRtcStreamer.prototype.onReceiveGetIceServers = function(iceServers, videourl, audiourl, options, stream, prefmime) {
this.iceServers = iceServers;
this.pcConfig = iceServers || {"iceServers": [] };
try {
this.createPeerConnection();
let callurl = this.srvurl + "/api/call?peerid=" + this.pc.peerid + "&url=" + encodeURIComponent(videourl);
if (audiourl) {
callurl += "&audiourl="+encodeURIComponent(audiourl);
}
if (options) {
callurl += "&options="+encodeURIComponent(options);
}
if (stream) {
this.pc.addStream(stream);
}
// clear early candidates
this.earlyCandidates.length = 0;
// create Offer
this.pc.createOffer(this.mediaConstraints).then((sessionDescription) => {
console.log("Create offer:" + JSON.stringify(sessionDescription));
console.log(`video codecs:${Array.from(new Set(RTCRtpReceiver.getCapabilities("video")?.codecs?.map(codec => codec.mimeType)))}`)
console.log(`audio codecs:${Array.from(new Set(RTCRtpReceiver.getCapabilities("audio")?.codecs?.map(codec => codec.mimeType)))}`)
if (prefmime != undefined) {
//set prefered codec
let [prefkind] = prefmime.split('/');
if (prefkind != "video" && prefkind != "audio") {
prefkind = "video";
prefmime = prefkind + "/" + prefmime;
}
console.log("sdp:" + sessionDescription.sdp);
sessionDescription.sdp = this.filterPreferredCodec(sessionDescription.sdp, prefmime);
console.log("sdp:" + sessionDescription.sdp);
}
this.pc.setLocalDescription(sessionDescription)
.then(() => {
fetch(callurl, { method: "POST", body: JSON.stringify(sessionDescription) })
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.catch( (error) => this.onError("call " + error ))
.then( (response) => this.onReceiveCall(response) )
.catch( (error) => this.onError("call " + error ))
}, (error) => {
console.log ("setLocalDescription error:" + JSON.stringify(error));
});
}, (error) => {
alert("Create offer error:" + JSON.stringify(error));
});
} catch (e) {
this.disconnect();
alert("connect error: " + e);
}
}
WebRtcStreamer.prototype.getIceCandidate = function() {
fetch(this.srvurl + "/api/getIceCandidate?peerid=" + this.pc.peerid)
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.then( (response) => this.onReceiveCandidate(response))
.catch( (error) => this.onError("getIceCandidate " + error ))
}
/*
* create RTCPeerConnection
*/
WebRtcStreamer.prototype.createPeerConnection = function() {
console.log("createPeerConnection config: " + JSON.stringify(this.pcConfig));
this.pc = new RTCPeerConnection(this.pcConfig);
let pc = this.pc;
pc.peerid = Math.random();
pc.onicecandidate = (evt) => this.onIceCandidate(evt);
pc.onaddstream = (evt) => this.onAddStream(evt);
pc.oniceconnectionstatechange = (evt) => {
console.log("oniceconnectionstatechange state: " + pc.iceConnectionState);
if (this.videoElement) {
if (pc.iceConnectionState === "connected") {
this.videoElement.style.opacity = "1.0";
}
else if (pc.iceConnectionState === "disconnected") {
this.videoElement.style.opacity = "0.25";
}
else if ( (pc.iceConnectionState === "failed") || (pc.iceConnectionState === "closed") ) {
this.videoElement.style.opacity = "0.5";
} else if (pc.iceConnectionState === "new") {
this.getIceCandidate();
}
}
}
pc.ondatachannel = function(evt) {
console.log("remote datachannel created:"+JSON.stringify(evt));
evt.channel.onopen = function () {
console.log("remote datachannel open");
this.send("remote channel openned");
}
evt.channel.onmessage = function (event) {
console.log("remote datachannel recv:"+JSON.stringify(event.data));
}
}
try {
let dataChannel = pc.createDataChannel("ClientDataChannel");
dataChannel.onopen = function() {
console.log("local datachannel open");
this.send("local channel openned");
}
dataChannel.onmessage = function(evt) {
console.log("local datachannel recv:"+JSON.stringify(evt.data));
}
} catch (e) {
console.log("Cannor create datachannel error: " + e);
}
console.log("Created RTCPeerConnnection with config: " + JSON.stringify(this.pcConfig) );
return pc;
}
/*
* RTCPeerConnection IceCandidate callback
*/
WebRtcStreamer.prototype.onIceCandidate = function (event) {
if (event.candidate) {
if (this.pc.currentRemoteDescription) {
this.addIceCandidate(this.pc.peerid, event.candidate);
} else {
this.earlyCandidates.push(event.candidate);
}
}
else {
console.log("End of candidates.");
}
}
WebRtcStreamer.prototype.addIceCandidate = function(peerid, candidate) {
fetch(this.srvurl + "/api/addIceCandidate?peerid="+peerid, { method: "POST", body: JSON.stringify(candidate) })
.then(this._handleHttpErrors)
.then( (response) => (response.json()) )
.then( (response) => {console.log("addIceCandidate ok:" + response)})
.catch( (error) => this.onError("addIceCandidate " + error ))
}
/*
* RTCPeerConnection AddTrack callback
*/
WebRtcStreamer.prototype.onAddStream = function(event) {
console.log("Remote track added:" + JSON.stringify(event));
this.videoElement.srcObject = event.stream;
let promise = this.videoElement.play();
if (promise !== undefined) {
promise.catch((error) => {
console.warn("error:"+error);
this.videoElement.setAttribute("controls", true);
});
}
}
/*
* AJAX /call callback
*/
WebRtcStreamer.prototype.onReceiveCall = function(dataJson) {
console.log("offer: " + JSON.stringify(dataJson));
let descr = new RTCSessionDescription(dataJson);
this.pc.setRemoteDescription(descr).then(() => {
console.log ("setRemoteDescription ok");
while (this.earlyCandidates.length) {
let candidate = this.earlyCandidates.shift();
this.addIceCandidate(this.pc.peerid, candidate);
}
this.getIceCandidate()
}
, (error) => {
console.log ("setRemoteDescription error:" + JSON.stringify(error));
});
}
/*
* AJAX /getIceCandidate callback
*/
WebRtcStreamer.prototype.onReceiveCandidate = function(dataJson) {
console.log("candidate: " + JSON.stringify(dataJson));
if (dataJson) {
for (let i=0; i<dataJson.length; i++) {
let candidate = new RTCIceCandidate(dataJson[i]);
console.log("Adding ICE candidate :" + JSON.stringify(candidate) );
this.pc.addIceCandidate(candidate).then( () => { console.log ("addIceCandidate OK"); }
, (error) => { console.log ("addIceCandidate error:" + JSON.stringify(error)); } );
}
this.pc.addIceCandidate();
}
}
/*
* AJAX callback for Error
*/
WebRtcStreamer.prototype.onError = function(status) {
console.log("onError:" + status);
}
return WebRtcStreamer;
})();
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
window.WebRtcStreamer = WebRtcStreamer;
}
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = WebRtcStreamer;
}
......@@ -46,9 +46,6 @@ export const getEnvironmentData = async (): Promise<any> => await axios.get('/ho
// 获取在线数据接口
export const getOnlineData = async (): Promise<any> => await axios.get('/home/online/data');
// 获取车辆日志列表接口
export const getCarLogList = async (): Promise<any> => await axios.get('home/car/log');
// export const getOnlineAlarmList = async (): Promise<any> => await axios.get('/home/online/alarm/list');
// export const getOnlineAlarmList = async (): Promise<any> => await axios.get('/home/online/alarm/list');
// export const getOnlineAlarmList = async (): Promise<any> => await axios.get('/home/online/alarm/list');
......
......@@ -165,8 +165,7 @@ export const getPointAllPersonApi = async (): Promise<any> => await axios.get(`/
// 查询人员轨迹
export const getPersonPointApi = async (data:any): Promise<any> => await axios.post(`/person/point/trajectory`,data);
// 查询车辆轨迹
export const getCarPointApi = async (data:any): Promise<any> => await axios.post(`/car/point/trajectory`,data);
// ------------------- 越界开采报警接口 ------------------
export const getFencePageApi = async (data:any): Promise<any> => await axios.get(`/fence/log/page?pageNum=${data.pageNum}&pageSize=${data.pageSize}&username=${data.username}&carNumber=${data.carNumber}&startTime=${data.startTime}&endTime=${data.endTime}`);
......@@ -177,8 +176,23 @@ export const putFenceeLogApi = async (data:any): Promise<any> => await axios.put
export const delFenceLogApi = async (ids:any): Promise<any> => await axios.delete(`/fence/log/${ids}`,);
// 大屏卡车位置信息
export const getCarPointAllCarApi = async (): Promise<any> => await axios.get(`/car/point/all/car/location`,);
//
// 大屏信息
export const getCarPointAllCarApi = async (): Promise<any> => await axios.get(`/car/point/all/car/location`);
export const getHomeCarApi = async (carNumber:any): Promise<any> => await axios.get(`/home/car/${carNumber}`);
export const getCemeraPointApi = async (): Promise<any> => await axios.get(`/home/camera/point`);
export const getCameraIdApi = async (id:any): Promise<any> => await axios.get(`/home/camera/${id}`);
export const getMonitorPointApi = async (): Promise<any> => await axios.get(`/home/monitor/point`);
export const getMonitorIdApi = async (id:any): Promise<any> => await axios.get(`/home/monitor/${id}`);
// 卡调
export const getCarPointCarNumberApi = async (): Promise<any> => await axios.get(`/car/point/carNumber`,);
// 查询车辆轨迹
export const getCarPointApi = async (data:any): Promise<any> => await axios.post(`/car/point/trajectory`,data);
// 摄像头
export const getPointListApi = async (): Promise<any> => await axios.get(`/cameras/point/list`,);
export function carSpeed(data:any) {
// 路程
let totalDistance = 0;
// 时间
let totalTimeMs = 0;
for (let i = 0; i < data.points.length - 1; i++) {
const point1 = Cesium.Cartesian3.fromDegrees(data.points[i].lon, data.points[i].lat);
const point2 = Cesium.Cartesian3.fromDegrees(data.points[i + 1].lon, data.points[i + 1].lat);
totalDistance += Cesium.Cartesian3.distance(point1, point2);
const time1 = new Date(data.points[i].createTime).getTime();
const time2 = new Date(data.points[i + 1].createTime).getTime();
const timeDiff = Math.abs(time2 - time1); // 使用绝对值确保时间为正
totalTimeMs += timeDiff;
}
const totalTimeHours = totalTimeMs / (1000 * 60 * 60); // 转换为小时
const totalDistanceKm = totalDistance / 1000;
// 平均时速 (公里/小时)
const averageSpeed = totalTimeHours > 0 ? totalDistanceKm / totalTimeHours : 0;
return averageSpeed;
}
\ No newline at end of file
import { AnymatchFn } from 'vite';
import { ref } from 'vue';
import { useMessage } from 'naive-ui';
import { log } from 'echarts/types/src/util/log.js';
import { cesiumToLongitudeAndLatitude } from './coordinateUtil';
const message = useMessage();
const line = ref<any>(null);
let modelExtiti: any = null;
const isOver = false;
// 创建自定义圆形大头针的函数(使用 Canvas 动态生成)
export function createCustomPinImage() {
const canvas = document.createElement('canvas');
const size = 48; // 图标大小
canvas.width = size;
canvas.height = size * 2; // 包括杆子部分
const context = canvas.getContext('2d');
// 绘制红色圆圈(带白边)
context.beginPath();
context.arc(size / 2, size / 2, size / 2 - 4, 0, 2 * Math.PI); // 圆圈
context.fillStyle = 'white'; // 白色边框
context.fill();
context.beginPath();
context.arc(size / 2, size / 2, size / 2 - 8, 0, 2 * Math.PI); // 红色填充
context.fillStyle = 'red';
context.fill();
// 绘制杆子(白色)
context.fillStyle = 'white';
context.fillRect(size / 2 - 2, size, 4, size); // 杆子从圆圈底部向下延伸
return canvas.toDataURL('image/png'); // 返回 Base64 编码的图片
}
export function deletePin(viewer: any, data: any) {
viewer.entities.remove(data.pin);
}
export function deletePins(viewer: any, data: any) {
for (let i = 0; i < data.length; i++) {
viewer.entities.remove(data[i].pin);
}
}
export async function getElevationFromRays(cartographic: any, viewer: any) {
let ellipsoid;
let startPoint;
let surfaceNormal;
let direction;
let ray;
return new Promise(resolve => {
ellipsoid = viewer.scene.globe.ellipsoid;
startPoint = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 200);
surfaceNormal = viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
direction = Cesium.Cartesian3.negate(surfaceNormal, new Cesium.Cartesian3());
ray = new Cesium.Ray(startPoint, direction);
const intersection = viewer.scene.pickFromRay(ray);
if (intersection) {
const cartographicPosition = Cesium.Cartographic.fromCartesian(intersection.position);
resolve(cartographicPosition.height); // 返回检测到的高程
} else {
// 如果没有检测到交点,返回椭球面高度(0)或其他默认值
resolve(0);
}
});
}
export async function getElevationFromRay(cartographic: any, viewer: any) {
let ellipsoid;
let startPoint;
let surfaceNormal;
let direction;
let ray;
return new Promise((resolve, reject) => {
ellipsoid = viewer.scene.globe.ellipsoid;
startPoint = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 200);
surfaceNormal = viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
direction = Cesium.Cartesian3.negate(surfaceNormal, new Cesium.Cartesian3());
ray = new Cesium.Ray(startPoint, direction);
const intersection = viewer.scene.pickFromRay(ray);
if (intersection) {
const cartographicPosition = Cesium.Cartographic.fromCartesian(intersection.position);
resolve(cartographicPosition.height); // 返回高程
} else {
reject('未检测到交点');
}
});
}
// 创建红色线
export function createPolyLine(positions: any, viewer: any) {
line.value = viewer.entities.add({
name: 'polyline',
polyline: {
show: true, // 显示折线
positions, // 折线顶点的位置数组
material: Cesium.Color.fromCssColorString(`rgb(212, 16, 16)`), // 折线颜色
width: 3, // 折线宽度
clampToGround: true, // 将折线贴地
zIndex: 92, // 折线层级索引
classificationType: Cesium.ClassificationType.BOTH, // 折线分类类型
heightReference: Cesium.HeightReference.NONE
}
});
return line.value;
}
export function cleanLine(viewer: any, positions: any) {
viewer.entities.remove(line.value);
viewer.entities.remove(positions);
}
export function createModel(positions: any, viewer: any) {
if (positions.length == 0) {
message.error('没有数据');
return;
}
const url = '/src/assets/imgs/car.glb';
const startPoint = positions[0];
if (modelExtiti) {
viewer.entities.remove(modelExtiti);
}
const entityOptions = {
position: startPoint,
orientation: Cesium.Transforms.headingPitchRollQuaternion(startPoint, new Cesium.HeadingPitchRoll(0, 0, 0)),
model: {
uri: url,
scale: 1.0,
minimumPixelSize: 100,
disableDepthTestDistance: 'infinite',
runAnimations: true
}
};
// 创建并添加实体
modelExtiti = viewer.entities.add(entityOptions);
return modelExtiti;
}
// 辅助函数:开始车辆移动动画
function densifyPoints(positions: any[], stepSize: number = 2.0) {
if (positions.length < 2) return positions;
const densified: any[] = [];
for (let i = 0; i < positions.length - 1; i++) {
const start = positions[i];
const end = positions[i + 1];
// 计算两点间距离
const distance = Cesium.Cartesian3.distance(start, end);
// 放入起始点
densified.push(start);
// 如果距离过大,计算需要插入多少个点
if (distance > stepSize) {
const count = Math.ceil(distance / stepSize);
for (let j = 1; j < count; j++) {
// 线性插值计算中间点
const t = j / count;
const newPoint = Cesium.Cartesian3.lerp(start, end, t, new Cesium.Cartesian3());
densified.push(newPoint);
}
}
}
// 别忘了把最后一个点放进去
densified.push(positions[positions.length - 1]);
return densified;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// ✅ 核心改进 1:路径加密
// 先把只有几个顶点的折线,变成几百个密集的点
// 这样每个点都能去探测模型高度,车子就能贴合起伏了
// =========================================================
const denseCoordinates = densifyPoints(rawCoordinates, 2.0); // 每隔2米插入一个点
let clampedPositions: any[] = [];
try {
// =========================================================
// ✅ 核心改进 2:批量计算高度
// 现在计算的是加密后那几百个点的高度
// =========================================================
// 提示:clampToHeightMostDetailed 支持的点的数量有限,
// 如果路线非常非常长(几十公里),可能需要分段计算,但一般几千个点没问题。
const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);
clampedPositions = updatedPositions.map((pos: any) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos);
// 💡 稍微抬高 0.5 - 1.0 米,防止车轮半截入土
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 0.8);
});
} catch (error) {
console.warn('高度贴合计算失败或部分失败:', error);
clampedPositions = denseCoordinates;
}
// =========================================================
// 下面的逻辑和之前一样,构建 SampledProperty
// =========================================================
const positionProperty = new Cesium.SampledPositionProperty();
let totalDistance = 0;
for (let i = 0; i < clampedPositions.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(clampedPositions[i], clampedPositions[i + 1]);
}
let accumulatedTime = 0;
positionProperty.addSample(viewer.clock.currentTime, clampedPositions[0]);
for (let i = 1; i < clampedPositions.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(clampedPositions[i - 1], clampedPositions[i]);
const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
accumulatedTime += segmentDuration;
const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
positionProperty.addSample(time, clampedPositions[i]);
}
// 因为点很密集,线性插值(LinearApproximation)其实比 Hermite 更稳,不容易出现“过冲”导致的抖动
// 当然 Hermite 也可以,看效果决定
positionProperty.setInterpolationOptions({
interpolationDegree: 1,
interpolationAlgorithm: Cesium.LinearApproximation
});
if (!modelExtiti) return;
modelExtiti.position = positionProperty;
// 姿态计算
const velocityOrientation = new Cesium.VelocityOrientationProperty(positionProperty);
const headingOffset = Cesium.Math.toRadians(90); // 按需调整
modelExtiti.orientation = new Cesium.CallbackProperty((time: any) => {
const velocityQuaternion = velocityOrientation.getValue(time);
if (!velocityQuaternion) return undefined;
const rotation = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, headingOffset);
return Cesium.Quaternion.multiply(velocityQuaternion, rotation, new Cesium.Quaternion());
}, false);
viewer.clock.shouldAnimate = true;
// 结束清理逻辑
const stopTime = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, totalDuration, new Cesium.JulianDate());
const removeListener = viewer.clock.onTick.addEventListener((clock: any) => {
if (Cesium.JulianDate.compare(clock.currentTime, stopTime) >= 0) {
viewer.clock.shouldAnimate = false;
viewer.clock.currentTime = Cesium.JulianDate.now();
// 可以在这重置位置
// modelExtiti.position = clampedPositions[0];
removeListener();
}
});
}
......@@ -94,7 +94,6 @@ export async function getElevationFromRay(cartographic: any, viewer: any) {
// 创建红色线
export function createPolyLine(positions: any, viewer: any) {
console.log(positions);
line.value = viewer.entities.add({
name: 'polyline',
polyline: {
......@@ -182,39 +181,16 @@ function densifyPoints(positions: any[], stepSize: number = 2.0) {
return densified;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// ✅ 核心改进 1:路径加密
// 先把只有几个顶点的折线,变成几百个密集的点
// 这样每个点都能去探测模型高度,车子就能贴合起伏了
// =========================================================
const denseCoordinates = densifyPoints(rawCoordinates, 2.0); // 每隔2米插入一个点
export async function createNewPositionHeight(position: any, viewer: any) {
const denseCoordinates = densifyPoints(position, 10.0); // 每隔2米插入一个点
let clampedPositions: any[] = [];
try {
// =========================================================
// ✅ 核心改进 2:批量计算高度
// 现在计算的是加密后那几百个点的高度
// =========================================================
// 提示:clampToHeightMostDetailed 支持的点的数量有限,
// 如果路线非常非常长(几十公里),可能需要分段计算,但一般几千个点没问题。
const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);
clampedPositions = updatedPositions.map((pos: any) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos);
// 💡 稍微抬高 0.5 - 1.0 米,防止车轮半截入土
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 0.8);
});
} catch (error) {
......@@ -222,6 +198,22 @@ export async function startVehicleMovement(viewer: any, totalDuration: number) {
clampedPositions = denseCoordinates;
}
return clampedPositions;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// 下面的逻辑和之前一样,构建 SampledProperty
// =========================================================
......@@ -229,20 +221,21 @@ export async function startVehicleMovement(viewer: any, totalDuration: number) {
const positionProperty = new Cesium.SampledPositionProperty();
let totalDistance = 0;
for (let i = 0; i < clampedPositions.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(clampedPositions[i], clampedPositions[i + 1]);
for (let i = 0; i < rawCoordinates.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(rawCoordinates[i], rawCoordinates[i + 1]);
}
let accumulatedTime = 0;
positionProperty.addSample(viewer.clock.currentTime, clampedPositions[0]);
positionProperty.addSample(viewer.clock.currentTime, rawCoordinates[0]);
for (let i = 1; i < clampedPositions.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(clampedPositions[i - 1], clampedPositions[i]);
for (let i = 1; i < rawCoordinates.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(rawCoordinates[i - 1], rawCoordinates[i]);
const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
accumulatedTime += segmentDuration;
const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
positionProperty.addSample(time, clampedPositions[i]);
positionProperty.addSample(time, rawCoordinates[i]);
}
// 因为点很密集,线性插值(LinearApproximation)其实比 Hermite 更稳,不容易出现“过冲”导致的抖动
......
import { AnymatchFn } from 'vite';
import { ref } from 'vue';
import { useMessage } from 'naive-ui';
import { log } from 'echarts/types/src/util/log.js';
import { cesiumToLongitudeAndLatitude } from './coordinateUtil';
const message = useMessage();
const line = ref<any>(null);
let modelExtiti: any = null;
const isOver = false;
// 创建自定义圆形大头针的函数(使用 Canvas 动态生成)
export function createCustomPinImage() {
const canvas = document.createElement('canvas');
const size = 48; // 图标大小
canvas.width = size;
canvas.height = size * 2; // 包括杆子部分
const context = canvas.getContext('2d');
// 绘制红色圆圈(带白边)
context.beginPath();
context.arc(size / 2, size / 2, size / 2 - 4, 0, 2 * Math.PI); // 圆圈
context.fillStyle = 'white'; // 白色边框
context.fill();
context.beginPath();
context.arc(size / 2, size / 2, size / 2 - 8, 0, 2 * Math.PI); // 红色填充
context.fillStyle = 'red';
context.fill();
// 绘制杆子(白色)
context.fillStyle = 'white';
context.fillRect(size / 2 - 2, size, 4, size); // 杆子从圆圈底部向下延伸
return canvas.toDataURL('image/png'); // 返回 Base64 编码的图片
}
export function deletePin(viewer: any, data: any) {
viewer.entities.remove(data.pin);
}
export function deletePins(viewer: any, data: any) {
for (let i = 0; i < data.length; i++) {
viewer.entities.remove(data[i].pin);
}
}
export async function getElevationFromRays(cartographic: any, viewer: any) {
let ellipsoid;
let startPoint;
let surfaceNormal;
let direction;
let ray;
return new Promise(resolve => {
ellipsoid = viewer.scene.globe.ellipsoid;
startPoint = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 200);
surfaceNormal = viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
direction = Cesium.Cartesian3.negate(surfaceNormal, new Cesium.Cartesian3());
ray = new Cesium.Ray(startPoint, direction);
const intersection = viewer.scene.pickFromRay(ray);
if (intersection) {
const cartographicPosition = Cesium.Cartographic.fromCartesian(intersection.position);
resolve(cartographicPosition.height); // 返回检测到的高程
} else {
// 如果没有检测到交点,返回椭球面高度(0)或其他默认值
resolve(0);
}
});
}
export async function getElevationFromRay(cartographic: any, viewer: any) {
let ellipsoid;
let startPoint;
let surfaceNormal;
let direction;
let ray;
return new Promise((resolve, reject) => {
ellipsoid = viewer.scene.globe.ellipsoid;
startPoint = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 200);
surfaceNormal = viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
direction = Cesium.Cartesian3.negate(surfaceNormal, new Cesium.Cartesian3());
ray = new Cesium.Ray(startPoint, direction);
const intersection = viewer.scene.pickFromRay(ray);
if (intersection) {
const cartographicPosition = Cesium.Cartographic.fromCartesian(intersection.position);
resolve(cartographicPosition.height); // 返回高程
} else {
reject('未检测到交点');
}
});
}
// 创建红色线
export function createPolyLine(positions: any, viewer: any) {
console.log(positions);
line.value = viewer.entities.add({
name: 'polyline',
polyline: {
show: true, // 显示折线
positions, // 折线顶点的位置数组
material: Cesium.Color.fromCssColorString(`rgb(212, 16, 16)`), // 折线颜色
width: 3, // 折线宽度
clampToGround: true, // 将折线贴地
zIndex: 92, // 折线层级索引
classificationType: Cesium.ClassificationType.BOTH, // 折线分类类型
heightReference: Cesium.HeightReference.NONE
}
});
return line.value;
}
export function cleanLine(viewer: any, positions: any) {
viewer.entities.remove(line.value);
viewer.entities.remove(positions);
}
export function createModel(positions: any, viewer: any) {
if (positions.length == 0) {
message.error('没有数据');
return;
}
const url = '/src/assets/imgs/person1.glb';
const startPoint = positions[0];
if (modelExtiti) {
viewer.entities.remove(modelExtiti);
}
const entityOptions = {
position: startPoint,
orientation: Cesium.Transforms.headingPitchRollQuaternion(startPoint, new Cesium.HeadingPitchRoll(0, 0, 0)),
model: {
uri: url,
scale: 1.0,
minimumPixelSize: 100,
disableDepthTestDistance: 'infinite',
runAnimations: true
}
};
// 创建并添加实体
modelExtiti = viewer.entities.add(entityOptions);
return modelExtiti;
}
// 辅助函数:开始车辆移动动画
function densifyPoints(positions: any[], stepSize: number = 2.0) {
if (positions.length < 2) return positions;
const densified: any[] = [];
for (let i = 0; i < positions.length - 1; i++) {
const start = positions[i];
const end = positions[i + 1];
// 计算两点间距离
const distance = Cesium.Cartesian3.distance(start, end);
// 放入起始点
densified.push(start);
// 如果距离过大,计算需要插入多少个点
if (distance > stepSize) {
const count = Math.ceil(distance / stepSize);
for (let j = 1; j < count; j++) {
// 线性插值计算中间点
const t = j / count;
const newPoint = Cesium.Cartesian3.lerp(start, end, t, new Cesium.Cartesian3());
densified.push(newPoint);
}
}
}
// 别忘了把最后一个点放进去
densified.push(positions[positions.length - 1]);
return densified;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// ✅ 核心改进 1:路径加密
// 先把只有几个顶点的折线,变成几百个密集的点
// 这样每个点都能去探测模型高度,车子就能贴合起伏了
// =========================================================
const denseCoordinates = densifyPoints(rawCoordinates, 2.0); // 每隔2米插入一个点
let clampedPositions: any[] = [];
try {
// =========================================================
// ✅ 核心改进 2:批量计算高度
// 现在计算的是加密后那几百个点的高度
// =========================================================
// 提示:clampToHeightMostDetailed 支持的点的数量有限,
// 如果路线非常非常长(几十公里),可能需要分段计算,但一般几千个点没问题。
const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);
clampedPositions = updatedPositions.map((pos: any) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos);
// 💡 稍微抬高 0.5 - 1.0 米,防止车轮半截入土
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 0.8);
});
} catch (error) {
console.warn('高度贴合计算失败或部分失败:', error);
clampedPositions = denseCoordinates;
}
// =========================================================
// 下面的逻辑和之前一样,构建 SampledProperty
// =========================================================
const positionProperty = new Cesium.SampledPositionProperty();
let totalDistance = 0;
for (let i = 0; i < clampedPositions.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(clampedPositions[i], clampedPositions[i + 1]);
}
let accumulatedTime = 0;
positionProperty.addSample(viewer.clock.currentTime, clampedPositions[0]);
for (let i = 1; i < clampedPositions.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(clampedPositions[i - 1], clampedPositions[i]);
const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
accumulatedTime += segmentDuration;
const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
positionProperty.addSample(time, clampedPositions[i]);
}
// 因为点很密集,线性插值(LinearApproximation)其实比 Hermite 更稳,不容易出现“过冲”导致的抖动
// 当然 Hermite 也可以,看效果决定
positionProperty.setInterpolationOptions({
interpolationDegree: 1,
interpolationAlgorithm: Cesium.LinearApproximation
});
if (!modelExtiti) return;
modelExtiti.position = positionProperty;
// 姿态计算
const velocityOrientation = new Cesium.VelocityOrientationProperty(positionProperty);
const headingOffset = Cesium.Math.toRadians(0); // 按需调整
modelExtiti.orientation = new Cesium.CallbackProperty((time: any) => {
const velocityQuaternion = velocityOrientation.getValue(time);
if (!velocityQuaternion) return undefined;
const rotation = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, headingOffset);
return Cesium.Quaternion.multiply(velocityQuaternion, rotation, new Cesium.Quaternion());
}, false);
viewer.clock.shouldAnimate = true;
// 结束清理逻辑
const stopTime = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, totalDuration, new Cesium.JulianDate());
const removeListener = viewer.clock.onTick.addEventListener((clock: any) => {
if (Cesium.JulianDate.compare(clock.currentTime, stopTime) >= 0) {
viewer.clock.shouldAnimate = false;
viewer.clock.currentTime = Cesium.JulianDate.now();
// 可以在这重置位置
// modelExtiti.position = clampedPositions[0];
removeListener();
}
});
}
......@@ -94,7 +94,6 @@ export async function getElevationFromRay(cartographic: any, viewer: any) {
// 创建红色线
export function createPolyLine(positions: any, viewer: any) {
console.log(positions);
line.value = viewer.entities.add({
name: 'polyline',
polyline: {
......@@ -119,11 +118,11 @@ export function cleanLine(viewer: any, positions: any) {
export function createModel(positions: any, viewer: any) {
if (positions.length == 0) {
message.error('没有数据');
message.error('这个时间点没有数据');
return;
}
const url = '/src/assets/imgs/person1.glb';
const url = '/src/assets/imgs/person2.glb';
const startPoint = positions[0];
if (modelExtiti) {
......@@ -182,46 +181,39 @@ function densifyPoints(positions: any[], stepSize: number = 2.0) {
return densified;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// ✅ 核心改进 1:路径加密
// 先把只有几个顶点的折线,变成几百个密集的点
// 这样每个点都能去探测模型高度,车子就能贴合起伏了
// =========================================================
const denseCoordinates = densifyPoints(rawCoordinates, 2.0); // 每隔2米插入一个点
export async function createNewPositionHeight(position: any, viewer: any) {
const denseCoordinates = densifyPoints(position, 20.0); // 每隔2米插入一个点
let clampedPositions: any[] = [];
try {
// =========================================================
// ✅ 核心改进 2:批量计算高度
// 现在计算的是加密后那几百个点的高度
// =========================================================
// 提示:clampToHeightMostDetailed 支持的点的数量有限,
// 如果路线非常非常长(几十公里),可能需要分段计算,但一般几千个点没问题。
const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);
clampedPositions = updatedPositions.map((pos: any) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos);
// 💡 稍微抬高 0.5 - 1.0 米,防止车轮半截入土
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 0.8);
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 6);
});
} catch (error) {
console.warn('高度贴合计算失败或部分失败:', error);
clampedPositions = denseCoordinates;
}
return clampedPositions;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// 下面的逻辑和之前一样,构建 SampledProperty
// =========================================================
......@@ -229,20 +221,21 @@ export async function startVehicleMovement(viewer: any, totalDuration: number) {
const positionProperty = new Cesium.SampledPositionProperty();
let totalDistance = 0;
for (let i = 0; i < clampedPositions.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(clampedPositions[i], clampedPositions[i + 1]);
for (let i = 0; i < rawCoordinates.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(rawCoordinates[i], rawCoordinates[i + 1]);
}
let accumulatedTime = 0;
positionProperty.addSample(viewer.clock.currentTime, clampedPositions[0]);
positionProperty.addSample(viewer.clock.currentTime, rawCoordinates[0]);
for (let i = 1; i < clampedPositions.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(clampedPositions[i - 1], clampedPositions[i]);
for (let i = 1; i < rawCoordinates.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(rawCoordinates[i - 1], rawCoordinates[i]);
const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
accumulatedTime += segmentDuration;
const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
positionProperty.addSample(time, clampedPositions[i]);
positionProperty.addSample(time, rawCoordinates[i]);
}
// 因为点很密集,线性插值(LinearApproximation)其实比 Hermite 更稳,不容易出现“过冲”导致的抖动
......
import { ref } from 'vue';
import { getPointAllPersonApi } from '@/api';
import bluePersonIcon from '@/assets/blueperson.png';
import { getElevationFromRays } from '../cesiumUtil';
let personEntity: any;
const iconEntities = ref<any[]>([]);
const pins: any = [];
// 点位图标
export async function iconPoint(viewer: any, pins: any) {
// // 批量移除实体
iconEntities.value.forEach(item => {
viewer.entities.remove(item.labelExtity);
viewer.entities.remove(item.entity);
});
for (const item of pins) {
if (item.entity) {
viewer.entities.remove(item.entity);
}
const cartographic = Cesium.Cartographic.fromDegrees(item.position.lon, item.position.lat);
const height = await getElevationFromRays(cartographic, viewer);
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height);
item.entity = viewer.entities.add({
position: cartesian,
billboard: {
image: item.image,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: item.type
}
});
allEntities.push(item.entity);
const entity = viewer.entities.add({
position: cartesian,
billboard: {
image: new URL('../../../assets/titlePerson.png', import.meta.url).href,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -30), // 位置在图标上方
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: item.type
}
});
entity.billboard.width = 220; // 直接设置宽度
entity.billboard.height = 50; // 直接设置高度
allEntities.push(entity);
// 创建名字标签实体
const labelEntit = viewer.entities.add({
position: cartesian,
label: {
text: item.name,
font: 'bold 14px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(0, -36), // 位置在标签框上方
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
scaleByDistance: new Cesium.NearFarScalar(1000, 1, 5000, 0.5),
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000)
},
properties: {
type: item.type
}
});
allEntities.push(labelEntit);
iconEntities.value.push({
labelExtity: labelEntit,
entity
});
}
return { pins, allEntities };
}
......@@ -7,66 +7,37 @@ let personEntity: any;
const iconEntities = ref<any[]>([]);
const pins: any = [];
// 点位图标
export async function iconPoint(viewer: any, data: any, type: any) {
console.log('--1--', data);
const typeIcons = {
person_: new URL('@/assets/blueperson.png', import.meta.url).href,
car_: new URL('@/assets/icon15.png', import.meta.url).href,
slope_: new URL('@/assets/icon17.png', import.meta.url).href,
default: new URL('@/assets/blueperson.png', import.meta.url).href
};
// 清除所有以当前type前缀开头的实体,确保每次调用都是全新的
const entitiesToRemove: any[] = [];
viewer.entities.values.forEach((entity: any) => {
if (typeof entity.id === 'string' && entity.id.startsWith(type)) {
entitiesToRemove.push(entity);
}
export async function iconPoint(viewer: any, pins: any) {
// // 批量移除实体
iconEntities.value.forEach(item => {
viewer.entities.remove(item.labelExtity);
viewer.entities.remove(item.entity);
});
// 批量移除实体
entitiesToRemove.forEach(entity => viewer.entities.remove(entity));
for (const item of pins) {
if (item.entity) {
viewer.entities.remove(item.entity);
}
const cartographic = Cesium.Cartographic.fromDegrees(item.position.lon, item.position.lat);
for (let i = 0; i < data.value.length; i++) {
const cartographic = Cesium.Cartographic.fromDegrees(data.value[i].lon, data.value[i].lat);
const height = await getElevationFromRays(cartographic, viewer);
// 将高度增加一些,确保标签和图标在地形上方
const adjustedHeight = height + 1;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
const iconPath = typeIcons[type as keyof typeof typeIcons] || typeIcons.default;
// 创建实体ID使用传入的type前缀
const entityId = `${type}${i}`;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height);
// 检查是否已存在相同ID的实体,如果存在则移除
const existingEntity = viewer.entities.getById(entityId);
if (existingEntity) {
viewer.entities.remove(existingEntity);
}
// 创建人员/车辆图标实体
personEntity = viewer.entities.add({
id: entityId, // 使用传入的type前缀确保唯一性
item.entity = viewer.entities.add({
position: cartesian,
billboard: {
image: iconPath,
image: item.image,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: data.value[i].type
},
// 存储人员数据
personData: {
index: i,
info: data.value[i]
type: item.type
}
});
// 创建标签框背景实体
const entity = viewer.entities.add({
position: cartesian,
billboard: {
......@@ -76,9 +47,6 @@ export async function iconPoint(viewer: any, data: any, type: any) {
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -30), // 位置在图标上方
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: data.value[i].type
}
});
entity.billboard.width = 220; // 直接设置宽度
......@@ -88,7 +56,7 @@ export async function iconPoint(viewer: any, data: any, type: any) {
const labelEntit = viewer.entities.add({
position: cartesian,
label: {
text: data.value[i].carNumber || data.value[i].realName,
text: item.name,
font: 'bold 14px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
......@@ -100,23 +68,17 @@ export async function iconPoint(viewer: any, data: any, type: any) {
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
scaleByDistance: new Cesium.NearFarScalar(1000, 1, 5000, 0.5),
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000)
},
properties: {
type: data.value[i].type
}
});
iconEntities.value.push(personEntity, entity, labelEntit);
// 存储标签实体到pins数组中,以便主组件控制显示隐藏
item.labelEntity = labelEntit;
item.backgroundEntity = entity;
pins.push({
entity: personEntity,
cardId: data.value[i].cardId,
type: personEntity.id,
position: cartesian,
label: null,
data: data.value[i]
iconEntities.value.push({
labelExtity: labelEntit,
entity
});
}
return pins;
}
src/assets/blueperson.png

1.69 KB | W: | H:

src/assets/blueperson.png

1.76 KB | W: | H:

src/assets/blueperson.png
src/assets/blueperson.png
src/assets/blueperson.png
src/assets/blueperson.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jinrun/bg-left.png

219 KB | W: | H:

src/assets/jinrun/bg-left.png

233 KB | W: | H:

src/assets/jinrun/bg-left.png
src/assets/jinrun/bg-left.png
src/assets/jinrun/bg-left.png
src/assets/jinrun/bg-left.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jinrun/bg-right.png

219 KB | W: | H:

src/assets/jinrun/bg-right.png

233 KB | W: | H:

src/assets/jinrun/bg-right.png
src/assets/jinrun/bg-right.png
src/assets/jinrun/bg-right.png
src/assets/jinrun/bg-right.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jinrun/module-bg.png

51.5 KB | W: | H:

src/assets/jinrun/module-bg.png

51.5 KB | W: | H:

src/assets/jinrun/module-bg.png
src/assets/jinrun/module-bg.png
src/assets/jinrun/module-bg.png
src/assets/jinrun/module-bg.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jinrun/top.png

194 KB | W: | H:

src/assets/jinrun/top.png

199 KB | W: | H:

src/assets/jinrun/top.png
src/assets/jinrun/top.png
src/assets/jinrun/top.png
src/assets/jinrun/top.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -11,7 +11,7 @@
></canvas>
<div class="legend-container">
<div v-for="(item, index) in chartData" :key="index" class="legend-item">
<div class="color-block" :style="{ backgroundColor: item.color || 'fff' }"></div>
<div class="color-block" :style="{ backgroundColor: item.color }"></div>
<div class="legend-text">
<span class="legend-name">{{ item.name }}</span>
<span class="legend-value" :style="`color: ${item.color}`">{{ item.value }}</span>
......@@ -23,11 +23,7 @@
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick, reactive } from 'vue'
import { getCarLogList } from '@/api/index-dp';
import { useMessage } from 'naive-ui';
const message = useMessage();
import { ref, onMounted, watch } from 'vue';
// 1. 定义 TS 类型接口
interface ChartDataItem {
......@@ -42,8 +38,13 @@ interface RingLayer {
}
// 2. 核心配置与数据(5个类别)
// 使用 ref 创建响应式数据
const chartData = ref<ChartDataItem[]>([]);
const chartData: ChartDataItem[] = [
{ name: '疲劳驾驶', value: 10, color: '#409EFF' },
{ name: '违规打电话', value: 15, color: '#52C41A' },
{ name: '违规抽烟', value: 0, color: '#FAAD14' },
{ name: '左顾右盼', value: 2, color: '#FA8C16' },
{ name: '人脸丢失', value: 0, color: '#F5222D' },
];
// 调整环形图层尺寸以适应新的 canvas 尺寸,增大环间距离
const ringLayers: RingLayer[] = [
......@@ -93,7 +94,7 @@ const drawChart = () => {
// 步骤2:按比例绘制数值扇区
const drawSectors = () => {
const validData = chartData.value.filter((item) => item.value > 0);
const validData = chartData.filter((item) => item.value > 0);
const total = validData.reduce((sum, item) => sum + item.value, 0);
if (total === 0) {
console.warn('No valid data to draw');
......@@ -105,7 +106,7 @@ const drawChart = () => {
// 先绘制背景
drawBackground();
chartData.value.forEach((item, index) => {
chartData.forEach((item, index) => {
if (item.value <= 0) return;
const layer = ringLayers[index];
if (!layer) return;
......@@ -136,36 +137,22 @@ const drawChart = () => {
// 5. 挂载后初始化图表(DOM 渲染完成后执行)
onMounted(() => {
getCarLogList().then((response) => {
if (response.data.code == 200) {
// 使用 ref 的 value 属性更新数据,确保是响应式的
chartData.value = response.data.data.map((item: any) => ({
name: item.name,
value: item.count * 1,
color: item.color
}));
console.log('*****************************', chartData.value);
console.log('Component mounted, attempting to draw chart');
// 使用 nextTick 确保 DOM 已完全渲染
nextTick(() => {
setTimeout(() => {
drawChart();
});
} else {
message.error(response.data.msg);
}
}).catch((error) => {
console.error('获取数据失败:', error);
message.error('获取数据失败');
});
}, 0);
});
// // 可选:监听数据变化重新绘制(如需动态更新数据可启用)
// import { watch } from 'vue';
// watch(chartData, () => {
// drawChart();
// }, { deep: true });
// 可选:监听数据变化重新绘制(如需动态更新数据可启用)
watch([() => chartData], () => {
drawChart();
}, { deep: true });
// 导出绘制函数以便外部调用
defineExpose({
drawChart
});
</script>
<style scoped lang="scss">
......@@ -173,7 +160,7 @@ onMounted(() => {
width: 100%;
overflow: auto;
background-image: url("@/assets/jinrun/module-bg.png");
background-size: cover;
background-size: cover;
background-repeat: no-repeat;
}
......@@ -202,10 +189,10 @@ onMounted(() => {
align-items: center;
margin-bottom: 15px;
width: 2.3rem;
height: 0.28rem;
background: #144f8025;
border-radius: 0.14rem;
padding-left: 0.3rem;
height: 0.28rem;
background: #144f8025;
border-radius: 0.14rem;
padding-left: 0.3rem;
}
.color-block {
......@@ -222,15 +209,19 @@ onMounted(() => {
width: 1.3rem;
padding-left: .12rem;
}
// .legend-text:first-child{
// display: inline-block;
// text-align: left;
// }
.legend-name {
font-size: .16rem;
font-size: 12px;
color: #fff;
margin-bottom: 2px;
}
.legend-value {
font-size: .16rem;
font-size: 12px;
color: #666;
}
......
......@@ -276,8 +276,8 @@ const local: App.I18n.Schema = {
orientation_monitor_rainfall: '降雨量历史',
orientation_video: '摄像头管理',
orientation: '全方位监测监控系统',
monitoring_data_detection: '排土场-表面位移',
monitoring_data_rainfall: '排土场-降雨量',
monitoring_data_detection: '边坡-表面位移',
monitoring_data_rainfall: '边坡-降雨量',
monitoring_home: '主页',
monitoring_monitor_entering: '监测值录入',
monitoring_monitor_manage: '监测点管理',
......
......@@ -186,3 +186,16 @@ export const modelsRules: FormRules = {
}
]
};
// 登录
export const loginRules: FormRules = {
username: [
{ type: 'string', required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ type: 'string', required: true, message: '请输入密码', trigger: 'blur' }
],
yzmcode: [
{ type: 'string', required: true, message: '请输入验证码', trigger: 'blur' }
]
}
\ No newline at end of file
......@@ -15,7 +15,6 @@ declare module 'vue' {
AppProvider: typeof import('./../components/common/app-provider.vue')['default']
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
copy: typeof import('./../components/MineMonitor/RightTodayAlarm copy.vue')['default']
CountTo: typeof import('./../components/custom/count-to.vue')['default']
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
......@@ -126,7 +125,6 @@ declare global {
const AppProvider: typeof import('./../components/common/app-provider.vue')['default']
const BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
const ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
const copy: typeof import('./../components/MineMonitor/RightTodayAlarm copy.vue')['default']
const CountTo: typeof import('./../components/custom/count-to.vue')['default']
const DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
const ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
......
import { ref } from "vue";
let webRtcServrce = ref();
export function webVideo(rtsp: any) {
console.log('111',rtsp);
webRtcServrce.value = new WebRtcStreamer('video', location.protocol + '//' + "192.168.2.53:8000")
webRtcServrce.value.connect('rtsp://admin:Gemho120611@192.168.0.17:554/h264/ch1/main/av_stream');
};
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { nextTick, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue';
import '../../../../Cesium/Widgets/widgets.css';
import { useMessage } from 'naive-ui';
import { getFenceListsApi } from '@/api';
import {
getCameraIdApi,
getCarPointAllCarApi,
getCemeraPointApi,
getFenceListsApi,
getHomeCarApi,
getMonitorIdApi,
getMonitorPointApi,
getPointAllPersonApi,
getPointListApi
} from '@/api';
import { create3D } from '@/api/utils/cesium';
import { getElevationFromRay, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { cesiumToLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { iconPoint } from '@/api/utils/home/cesiumPositions';
import { carSpeed } from '@/api/utils/carSpeed';
import fullScreen from '@/utils/full';
import { webVideo } from '@/utils/ai';
import bluePersonIcon from '@/assets/blueperson.png';
import arrowLeftImg from '@/assets/jinrun/arrow-left.png';
import arrowRightImg from '@/assets/jinrun/arrow-right.png';
import redCarIcon from '@/assets/icon15Red.png';
import redVideoIcon from '@/assets/icon16Red.png';
import redBianIcon from '@/assets/icon17Red.png';
import blueCarIcon from '@/assets/icon15.png';
import blueVideoIcon from '@/assets/icon16.png';
import blueBianIcon from '@/assets/icon17.png';
import redPersonIcon from '../../../assets/redperson.png';
import MultiSelect from './appselect.vue';
let viewer: any = null;
......@@ -16,12 +38,17 @@ const message = useMessage();
let personEntity: any;
const pins: any = [];
const full = ref(false);
let entityId: any;
let link: any;
let speed = 0;
let text = '';
const personList = ref([]);
const modelData = ref([
[121.70966961471791, 36.86008449826527],
[121.70852773459532, 36.85709047622009],
[121.71154596109507, 36.8570398369999],
[121.7121957019953, 36.860359083384175],
[121.70966961471791, 36.86008449826527]
[122.04736846370741, 37.48958083145254],
[122.04760069379522, 37.489226301608184],
[122.04823299200363, 37.489451482540346],
[122.04802271634016, 37.48983410372907],
[122.04748237248322, 37.49016152294277]
]);
const options = [
......@@ -31,11 +58,11 @@ const options = [
},
{
label: '在线监测设备',
value: '2'
value: '3'
},
{
label: '视频监控',
value: '3'
value: '2'
},
{
label: '人员定位',
......@@ -51,95 +78,8 @@ const options = [
}
];
const value = ref(options.map(opt => opt.value));
// 监听选中值的变化
watch(
value,
(newVal, oldVal) => {
// 防止无限递归
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;
// 获取除全选外的所有选项值
const otherValues = options.slice(1).map(opt => opt.value);
// 检查是否选中了所有其他选项
const allOtherSelected = otherValues.every(val => newVal.includes(val));
// 检查是否点击了全选
const allSelectedNow = newVal.includes('1');
const allSelectedBefore = oldVal.includes('1');
// 点击了全选选项
if (allSelectedNow && !allSelectedBefore) {
value.value = options.map(opt => opt.value);
return;
}
// 取消了全选选项
if (!allSelectedNow && allSelectedBefore) {
// 检查是否所有其他选项都被选中
const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
if (allOtherOptionsSelected) {
// 如果所有其他选项都被选中,取消所有选中状态
value.value = [];
} else {
// 如果不是所有其他选项都被选中,只取消全选选项
value.value = newVal.filter(val => val !== '1');
}
return;
}
const someOptionUnselected = oldVal.length > newVal.length;
if (someOptionUnselected && allSelectedNow) {
// 如果取消了某个选项且当前处于全选状态,取消全选,但保留其他选项
value.value = newVal.filter(val => val !== '1');
}
// 选中了所有其他选项,自动选中全选
if (allOtherSelected && !allSelectedNow) {
value.value = options.map(opt => opt.value);
}
// 如果取消了所有选项,清空value
if (newVal.length === 0) {
value.value = [];
}
},
{ deep: true }
);
const data = ref([
{
type: 1,
name: '仓房摄像头2',
x: 121.71061401132522,
y: 36.85887225892583
},
{
type: 2,
name: '边坡表面位移1',
x: 121.71008898290809,
y: 36.858159326215
},
{
type: 3,
name: '车辆1',
x: 121.71068916419333,
y: 36.8580421871238
},
{
type: 4,
name: '人工1',
x: 121.71115918429389,
y: 36.858735234993766
},
{
type: 5,
name: '人工2',
x: 121.71068034080756,
y: 36.85840370795711
}
]);
// let datasouce = ref<any>()
const position = ref([]);
const heightData = ref([]);
const data = ref([]);
const datasouce = ref();
const fence = ref<any>();
const personShow = ref(false);
......@@ -154,9 +94,56 @@ const fenceData = ref({
imagePath: '',
imageColor: ''
});
const labelData = ref<any>();
const formData = ref([]);
// zhaojunbao 开始
// REM自适应配置
const active = ref(false);
const REM_CONFIG = {
// 设计稿宽度
designWidth: 1920,
designHeight: 1080,
// 基准值:1rem = 100px
baseSize: 100
};
// 跳转首页
const navTo = () => {
window.location.href = '/home';
};
/**
* 设置REM单位
* 根据窗口宽度动态计算根元素font-size
*/
const setRemUnit = () => {
const { designWidth, designHeight, baseSize } = REM_CONFIG;
// 获取当前窗口尺寸
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
// 计算宽高缩放比例
const scaleX = windowWidth / designWidth;
const scaleY = windowHeight / designHeight;
// 取较小的缩放比例以适应屏幕,确保内容不会被裁剪
const scale = Math.min(scaleX, scaleY);
// 设置根元素font-size,确保最小为50px(可选)
const fontSize = Math.max(baseSize * scale, 50);
document.documentElement.style.fontSize = `${fontSize}px`;
};
// 控制左右模块显示状态的响应式变量
const isLeftModulesVisible = ref(true);
const isRightModulesVisible = ref(true);
const toggleBothModules = () => {
isLeftModulesVisible.value = !isLeftModulesVisible.value;
isRightModulesVisible.value = !isRightModulesVisible.value;
};
// zhaojunbao 结束
// 模型
function add3dtiles() {
const CesiumConfig = {
......@@ -191,7 +178,57 @@ function add3dtiles() {
});
}
// 监听
// 监听选中值的变化
watch(
value,
(newVal, oldVal) => {
// 防止无限递归
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;
// 获取除全选外的所有选项值
const otherValues = options.slice(1).map(opt => opt.value);
// 检查是否选中了所有其他选项
const allOtherSelected = otherValues.every(val => newVal.includes(val));
// 检查是否点击了全选
const allSelectedNow = newVal.includes('1');
const allSelectedBefore = oldVal.includes('1');
// 点击了全选选项
if (allSelectedNow && !allSelectedBefore) {
value.value = options.map(opt => opt.value);
return;
}
// 取消了全选选项
if (!allSelectedNow && allSelectedBefore) {
// 检查是否所有其他选项都被选中
const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
if (allOtherOptionsSelected) {
// 如果所有其他选项都被选中,取消所有选中状态
value.value = [];
} else {
// 如果不是所有其他选项都被选中,只取消全选选项
value.value = newVal.filter(val => val !== '1');
}
return;
}
const someOptionUnselected = oldVal.length > newVal.length;
if (someOptionUnselected && allSelectedNow) {
// 如果取消了某个选项且当前处于全选状态,取消全选,但保留其他选项
value.value = newVal.filter(val => val !== '1');
}
// 选中了所有其他选项,自动选中全选
if (allOtherSelected && !allSelectedNow) {
value.value = options.map(opt => opt.value);
}
// 如果取消了所有选项,清空value
if (newVal.length === 0) {
value.value = [];
}
},
{ deep: true }
);
// 监听选择框的变化
watch(
value,
......@@ -429,150 +466,291 @@ function electronic(position: any, heightData: any, rangeType: any) {
loadWall();
}
// 点位图标
async function iconPoint() {
const typeIcons = {
1: new URL('@/assets/icon16.png', import.meta.url).href,
2: new URL('@/assets/icon17.png', import.meta.url).href,
3: new URL('@/assets/icon15.png', import.meta.url).href,
4: new URL('@/assets/redperson.png', import.meta.url).href,
5: new URL('@/assets/blueperson.png', import.meta.url).href
};
for (let i = 0; i < data.value.length; i++) {
const cartographic = Cesium.Cartographic.fromDegrees(data.value[i].x, data.value[i].y);
const height = await getElevationFromRays(cartographic, viewer);
// 将高度增加一些,确保标签和图标在地形上方
const adjustedHeight = height + 1;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
const iconPath = typeIcons[data.value[i].type as keyof typeof typeIcons] || bluePersonIcon;
// 创建人员图标实体
personEntity = viewer.entities.add({
id: `person_${i}`, // 为人员图标实体设置特定前缀的ID
position: cartesian,
billboard: {
image: iconPath,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: data.value[i].type
// 点击弹框隐藏
function videosShow() {
if (videoShow.value == true) {
videoShow.value = false;
iconShow();
}
});
}
function equipmentsShow() {
if (equipmentShow.value == true) {
equipmentShow.value = false;
iconShow();
}
}
function carsShow() {
if (carShow.value == true) {
carShow.value = false;
iconShow();
}
}
function personsShow() {
if (personShow.value == true) {
personShow.value = false;
iconShow();
}
}
// 创建标签框背景实体
const entity = viewer.entities.add({
position: cartesian,
billboard: {
image: new URL('../../../assets/titlePerson.png', import.meta.url).href,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -30), // 位置在图标上方
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: data.value[i].type
function iconShow() {
for (const item of pins) {
if (item.type == 1) {
item.image = bluePersonIcon;
} else if (item.type == 2) {
item.image = blueCarIcon;
} else if (item.type == 3) {
item.image = blueBianIcon;
} else {
item.image = blueVideoIcon;
}
});
entity.billboard.width = 220; // 直接设置宽度
entity.billboard.height = 50; // 直接设置高度
// 创建名字标签实体
const labelEntit = viewer.entities.add({
position: cartesian,
label: {
text: data.value[i].name,
font: 'bold 14px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(0, -36), // 位置在标签框上方
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
scaleByDistance: new Cesium.NearFarScalar(1000, 1, 5000, 0.5),
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000)
},
properties: {
type: data.value[i].type
}
});
iconPoint(viewer, pins);
}
iconEntities.value.push(personEntity, entity, labelEntit);
// 设置员工类型
function getPersonTypeName(type: number): string {
switch (type) {
case 1:
return '员工';
case 2:
return '访客';
default:
return '没有该类型';
}
}
pins.push({
entity: personEntity,
position: cartesian,
label: null,
type: data.value[i].type
// text: ` 在线监测设备信息 \n 设备名称: ${} \n 设备状态:${} \n 设备类型:${} \n 监测值${} 监测时间: ${} \n 数据状态: ${}`\
});
async function setTimePerson() {
const res = await getPointAllPersonApi();
for (let item of pins) {
const pin = res.data.data.find((personData: any) => personData.cardId == item.id);
if (pin) {
item = pin;
}
}
const carRes = await getCarPointAllCarApi();
for (let item of pins) {
const pin = carRes.data.data.find((carData: any) => carData.carNumber == item.id);
if (pin) {
item = pin;
}
}
iconPoint(viewer, pins);
}
setInterval(setTimePerson, 10 * 1000);
onMounted(() => {
onMounted(async () => {
add3dtiles();
setTimeout(() => {
// electronic();
setTimeout(async () => {
fenceListGet();
iconPoint();
const res = await getPointAllPersonApi();
const personData = res.data.data;
personData.map(item => {
pins.push({
id: item.cardId,
name: item.realName,
type: 1,
image: bluePersonIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
// 获取并显示车辆数据,使用不同的前缀
const resCar = await getCarPointAllCarApi();
const carData = resCar.data.data;
carData.map(item => {
pins.push({
id: item.carNumber,
name: item.carNumber,
type: 2,
image: blueCarIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
// 获取在线监测
const resPoint = await getMonitorPointApi();
const pointData = resPoint.data.data;
pointData.map(item => {
pins.push({
id: item.id,
type: 3,
name: item.equipname,
image: blueBianIcon,
position: {
lon: item.longitude,
lat: item.latitude
},
data: item,
entity: null,
label: null
});
});
// 获取视频监控信息
const resVideo = await getCemeraPointApi();
const videoData = resVideo.data.data;
videoData.map(item => {
pins.push({
id: item.id,
name: item.cameraName,
type: 4,
image: blueVideoIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
iconPoint(viewer, pins).then(result => {
console.log(result);
});
}, 2000);
// setTimePerson();
setRemUnit();
// 监听窗口大小变化
window.addEventListener('resize', setRemUnit);
// zhaojunbao 结束
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 鼠标点击事件
handler.setInputAction(function (click: any) {
handler.setInputAction(async function (click: any) {
const pickedObject = viewer.scene.pick(click.position);
if (!pickedObject.collection) {
videoShow.value = false;
for (const item of pins) {
if (item.type == 1) {
item.image = bluePersonIcon;
} else if (item.type == 2) {
item.image = blueCarIcon;
} else if (item.type == 3) {
item.image = blueBianIcon;
} else {
item.image = blueVideoIcon;
}
}
if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
const pin = pins.find(item => item.entity === pickedObject.id);
if (pin.type == 1) {
equipmentShow.value = false;
videoShow.value = false;
carShow.value = false;
personShow.value = true;
labelData.value = pin.data;
pin.image = redPersonIcon;
} else if (pin.type == 2) {
// 车
equipmentShow.value = false;
videoShow.value = false;
personShow.value = false;
return;
carShow.value = true;
const res = await getHomeCarApi(pin.id);
console.log(res);
if (res.data.code == 200) {
speed = res.data.data.point ? carSpeed(res.data.data) : 0;
labelData.value = res.data.data;
}
if (Cesium.defined(pickedObject) && pickedObject.id) {
const pin = pins.find(p => p.entity === pickedObject.id);
if (pin.type == 1) {
videoShow.value = true;
} else if (pin.type == 2) {
equipmentShow.value = true;
pin.image = redCarIcon;
} else if (pin.type == 3) {
carShow.value = true;
// 监测设备
videoShow.value = false;
carShow.value = false;
personShow.value = false;
equipmentShow.value = true;
const res = await getMonitorIdApi(pin.id);
if (res.data.code == 200) {
if (res.data.data.devicetype == 3) {
text = '表面位移';
} else if (res.data.data.devicetype == 6) {
text = '降雨量';
}
labelData.value = res.data.data;
}
pin.image = redBianIcon;
} else {
personShow.value = true;
// 摄像头
equipmentShow.value = false;
videoShow.value = true;
carShow.value = false;
personShow.value = false;
videoShow.value = true;
const res = await getCameraIdApi(pin.id);
if (res.data.code == 200) {
labelData.value = res.data.data;
console.log(labelData.value);
const webRtcServrce = ref();
nextTick(() => {
webRtcServrce.value = new WebRtcStreamer('video', `${location.protocol}//` + `192.168.2.53:8000`);
webRtcServrce.value.connect(res.data.data.videoStream);
});
}
pin.image = redVideoIcon;
}
// pinsModel(pin,viewer);
iconPoint(viewer, pins);
} else {
videoShow.value = false;
equipmentShow.value = false;
videoShow.value = false;
carShow.value = false;
personShow.value = false;
iconPoint(viewer, pins);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});
onUnmounted(() => {
// 清理Cesium资源
if (viewer) {
viewer.destroy();
viewer = null;
}
// 移除窗口大小变化监听
window.removeEventListener('resize', setRemUnit);
// 移除html元素style属性中的font-size
document.documentElement.style.fontSize = '';
});
</script>
<template>
<div class="wrapper">
<div class="top-toolbar">
<div class="baojing">
声光报警
<NSwitch v-model:value="active" />
</div>
<!-- <i class="split-line"></i> -->
<div class="split-line"></div>
<div class="houtaiguanli" @click="navTo">后台管理</div>
</div>
<!-- cesium 容器 -->
<div class="cesium-container">
<div id="cesiumContainer">
<!-- 选择框 -->
<!--
<NSpace vertical style="width: 220px; height: 36px; position: fixed; z-index: 999; top: 80px; left: 70%">
<NSelect
v-model:value="value"
class="select"
multiple
:options="options"
default-value="all"
:max-tag-count="1"
popup-class="cesium-select-popup"
/>
</NSpace>
-->
<MultiSelect v-model="value" :options="options" style="position: fixed; z-index: 999; top: 80px; left: 70%" />
<MultiSelect v-model="value" :options="options" style="position: fixed; z-index: 999; top: 100px; left: 63%" />
<!-- 人员信息弹框 -->
<div v-if="personShow == true" class="personMessage">
<div style="display: flex; justify-content: flex-start; align-items: center; margin-bottom: 10px">
......@@ -584,6 +762,7 @@ onMounted(() => {
<button
id="close-info"
style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
@click="personsShow()"
>
&times;
</button>
......@@ -591,23 +770,23 @@ onMounted(() => {
<div style="line-height: 1.8">
<p class="title1">
<strong class="title2">姓名:</strong>
赵薇
{{ labelData.realName }}
</p>
<p class="title1">
<strong class="title2">定位卡号:</strong>
ED001
{{ labelData.cardId }}
</p>
<p class="title1">
<strong class="title2">人员类型:</strong>
员工/访客
{{ getPersonTypeName(labelData.personType) }}
</p>
<p class="title1">
<strong class="title2">电话:</strong>
1817456556
{{ labelData.phone }}
</p>
<p class="title1">
<strong class="title2">部门:</strong>
生产部
{{ labelData.deptName }}
</p>
</div>
</div>
......@@ -621,87 +800,64 @@ onMounted(() => {
<button
id="close-info"
style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
@click="carsShow()"
>
&times;
</button>
</div>
<div style="line-height: 1.8; display: flex; justify-content: space-between">
<div class="left">
<div class="car-left">
<div class="left-top">
<p class="title1">
<strong class="title2">车牌号:</strong>
鲁K:534435
{{ labelData.carNumber || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">车队名称:</strong>
KC001
{{ labelData.teamName || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">当前车速:</strong>
25km/h
{{ speed }} km/h
</p>
<p class="title1">
<strong class="title2">车辆类型:</strong>
卡车
{{ labelData.carType || '暂无数据' }}
</p>
</div>
<div class="left-center"></div>
<div class="left-bottom">
<p class="title1">
<strong class="title2">司机姓名:</strong>
张喂
{{ labelData.driverName || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">工作开始时间:</strong>
8:30
{{ labelData.workStartTime || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">工作时长:</strong>
3H
{{ labelData.workTime || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">终端设备编号:</strong>
ZD000001
{{ labelData.terminalNumber || '暂无数据' }}
</p>
</div>
</div>
<div class="right">
<!--
<video id="video" controls autoplay muted playsinline width="100%" height="100%"
style="object-fit: fill; z-index: 1;"></video>
-->
<div
:style="
full
? {
border: '1px solid #ccc',
padding: '2px',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100px',
zIndex: '99'
}
: {
padding: '2px',
height: '250px !important',
border: ' 1px solid #ccc',
position: 'relative'
}
"
>
<div style="position: absolute; bottom: 5px; right: 5px; width: 40px; height: 40px; cursor: pointer">
<icon-gridicons-fullscreen-exit
v-if="full"
color="#11e0ff"
font-size="30"
@click="full = fullScreen(full)"
/>
<icon-gridicons-fullscreen v-else font-size="30" color="#11e0ff" @click="full = fullScreen(full)" />
</div>
<canvas id="canvas-4" style="width: 100%; height: 100%" width="800" height="600"></canvas>
</div>
<div class="car-right">
<iframe
allowfullscreen="true"
allowtransparency="true"
allow="autoplay"
scrolling="no"
:src="link"
width="100%"
height="100%"
frameborder="0"
style="padding-right: 20px"
></iframe>
<!-- '${res.ipAddress}?lang=zh&devIdno=${res.cameraNo}&account=${res.username}&password=${res.password}&channel=1' -->
</div>
</div>
</div>
......@@ -715,6 +871,7 @@ onMounted(() => {
<button
id="close-info"
style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
@click="equipmentsShow()"
>
&times;
</button>
......@@ -722,27 +879,27 @@ onMounted(() => {
<div style="line-height: 1.8">
<p class="title1">
<strong class="title2">设备名称:</strong>
设备表面位移01
{{ labelData.equipname }}
</p>
<p class="title1">
<strong class="title2">设备状态:</strong>
在线/离线
{{ labelData.dataStatus === 0 ? '在线' : '离线' }}
</p>
<p class="title1">
<strong class="title2">设备类型:</strong>
表面位移/降雨量/环境监测
{{ text }}
</p>
<p class="title1">
<strong class="title2">监测值:</strong>
0.004mm
{{ labelData.value }}
</p>
<p class="title1">
<strong class="title2">监测时间:</strong>
2025-10 10:10:10
{{ labelData.time }}
</p>
<p class="title1">
<strong class="title2">数据状态:</strong>
正常
{{ labelData.onlineStatus === 0 ? '正常' : '蓝色报警' }}
</p>
</div>
</div>
......@@ -756,6 +913,7 @@ onMounted(() => {
<button
id="close-info"
style="background: none; border: none; color: white; cursor: pointer; font-size: 18px; margin-left: 10px"
@click="videosShow()"
>
&times;
</button>
......@@ -764,63 +922,111 @@ onMounted(() => {
<div class="video-top">
<div class="title3">
<strong class="title2">● 摄像头名称:</strong>
排土场入口
{{ labelData.areaName }}
</div>
<div class="title3">
<strong class="title4">● 区域名称:</strong>
排土场背部
{{ labelData.cameraName }}
</div>
<div class="title3">
<strong class="title4">● 设备状态:</strong>
在线/离线
{{ labelData.status === 0 ? '在线' : '离线' }}
</div>
</div>
<div class="video-bottom">
<div
:style="
full
? {
border: '1px solid #ccc',
padding: '2px',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100px',
zIndex: '99'
}
: {
padding: '2px',
height: '250px !important',
border: ' 1px solid #ccc',
position: 'relative'
}
"
>
<div style="position: absolute; bottom: 5px; right: 5px; width: 40px; height: 40px; cursor: pointer">
<icon-gridicons-fullscreen-exit
v-if="full"
color="#11e0ff"
font-size="30"
@click="full = fullScreen(full)"
/>
<icon-gridicons-fullscreen v-else font-size="30" color="#11e0ff" @click="full = fullScreen(full)" />
<video
id="video"
controls
autoplay
muted
playsinline
width="100%"
height="100%"
style="object-fit: fill; z-index: 1"
></video>
</div>
<canvas id="canvas-4" style="width: 100%; height: 100%" width="800" height="600"></canvas>
</div>
</div>
<!-- </div> -->
</div>
</div>
</div>
<div class="top">
<div class="first-image">
<img src="@/assets/jinrun/top.png" alt="" srcset="" />
<div class="second-icon">
<img src="@/assets/jinrun/title.png" alt="" />
</div>
</div>
</div>
<div class="bottom"></div>
<div v-show="isLeftModulesVisible" class="left"></div>
<div v-show="isRightModulesVisible" class="right"></div>
<!-- 非cesium相关 开始 -->
<!-- 左侧收起按钮 -->
<div class="toggle-btn left-toggle" :class="{ collapsed: !isLeftModulesVisible }" @click="toggleBothModules">
<div class="btn-arrow1">
<div>
<img :src="isLeftModulesVisible ? arrowLeftImg : arrowRightImg" alt="" srcset="" />
<br />
<div class="arrow-font">
{{ isLeftModulesVisible ? '收起' : '展开' }}
</div>
</div>
</div>
</div>
<!-- 右侧收起按钮 -->
<div class="toggle-btn right-toggle" :class="{ collapsed: !isRightModulesVisible }" @click="toggleBothModules">
<!-- <div class="btn-arrow1"><img src="@/assets/jinrun/arrow-right.png" alt="" srcset=""><br><br></div> -->
<div class="btn-arrow1">
<div>
<img :src="isLeftModulesVisible ? arrowRightImg : arrowLeftImg" alt="" srcset="" />
<br />
<div class="arrow-font">
{{ isLeftModulesVisible ? '收起' : '展开' }}
</div>
</div>
</div>
<!-- </div> -->
</div>
<!-- 左侧模块容器 -->
<Transition name="slide-left">
<div v-show="isLeftModulesVisible" class="left-modules">
<LeftDeviceStatus />
<LeftRainfallTrend />
<LeftOnlineMonitor />
</div>
</Transition>
<!-- 右侧模块容器 -->
<Transition name="slide-right">
<div v-show="isRightModulesVisible" class="right-modules">
<RightAiWarning />
<RightEnvMonitor />
<RightTodayAlarm />
</div>
</Transition>
<!-- 非cesium相关 结束 -->
</template>
<style scoped>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
.cesium-container {
width: 100%;
height: 100vh;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
}
#cesiumContainer {
......@@ -839,7 +1045,7 @@ onMounted(() => {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -856,7 +1062,7 @@ onMounted(() => {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -873,7 +1079,7 @@ onMounted(() => {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -890,7 +1096,7 @@ onMounted(() => {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -908,7 +1114,7 @@ onMounted(() => {
.title3 {
display: flex;
align-items: center;
margin: 0px 0px 8px 10px;
margin: 0px 0px 8px 0px;
}
.title4 {
......@@ -943,8 +1149,12 @@ span {
.right {
width: 60%;
height: 50%;
margin-right: 20px;
margin-top: 20px;
/* margin-right: 20px; */
/* margin-top: 20px; */
}
#video {
height: 250px;
}
.video-top {
......@@ -967,7 +1177,6 @@ span {
.n-select {
background-image: url('@/assets/multiple-pop.png');
/* background-size: cover; */
background-position: center;
}
......@@ -1000,37 +1209,320 @@ span {
:deep(.n-tag .n-tag__border) {
border: none;
}
:deep(.n-base-selection-tag-wrapper) {
background: #10273e00;
}
:global(.cesium-select-popup .n-base-select-menu) {
width: 227px;
height: 230px;
color: white !important;
border: none !important;
background-image: url('@/assets/multiple-pop.png') !important;
background-size: 100% 100% !important;
background-color: transparent !important;
/* zhaojunbao */
.top-toolbar {
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 240px;
height: 0.4rem;
color: #11e0ff;
z-index: 99999;
display: flex;
align-items: center;
justify-content: space-between;
.split-line {
width: 0.03rem;
height: 100%;
background: #11e0ff;
}
.baojing {
position: relative;
padding-left: 25px;
display: block;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
background-image: url('@/assets/jinrun/baojing.png');
background-size: contain;
background-repeat: no-repeat;
}
}
.houtaiguanli {
position: relative;
padding-left: 25px;
display: block;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
background-image: url('@/assets/jinrun/houtai.png');
background-size: contain;
background-repeat: no-repeat;
}
}
}
:global(.cesium-select-popup .n-base-select-menu .n-base-select-option.n-base-select-option--show-checkmark) {
margin-right: 5px;
color: white !important;
.top,
.bottom,
.left,
.right {
position: absolute;
background-repeat: no-repeat;
}
:global(.cesium-select-popup .n-base-select-menu .n-base-select-option.n-base-select-option--selected) {
color: #11e0ff !important;
.top {
top: 0;
width: 100%;
height: 1.25rem;
position: absolute;
.first-image {
width: 100%;
height: 100%;
position: relative;
& > img {
width: 100%;
}
.second-icon {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
width: 5.04rem;
/* 可根据实际需要调整大小 */
height: 0.54rem;
/* 可根据实际需要调整大小 */
}
}
}
:global(.cesium-select-popup.n-base-select-menu) {
background-image: url('@/assets/multiple-pop.png') !important;
color: white !important;
border: none !important;
.bottom {
bottom: 0;
left: 0;
width: 100%;
height: 0.4rem;
background-image: url('@/assets/jinrun/bottom.png');
background-size: cover;
}
.left {
top: 0rem;
left: 0;
width: 5.76rem;
height: calc(100vh);
background-size: contain;
background-position-x: left;
background-image: url('@/assets/jinrun/bg-left.png');
}
.right {
top: 0rem;
right: 0;
width: 5.76rem;
height: calc(100vh);
background-image: url('@/assets/jinrun/bg-right.png');
background-size: contain;
background-position-x: right;
}
:global(.cesium-select-popup .n-base-select-menu .n-base-select-option.n-base-select-option--show-checkmark:hover) {
color: #001f3f !important;
margin-right: 5px;
.toggle-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 0.71rem;
height: 1.87rem;
background-image: url('@/assets/jinrun/toggle-left.png');
background-size: cover;
background-repeat: no-repeat;
border-radius: 0 10px 10px 0;
cursor: pointer;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&.left-toggle {
left: 5rem;
/* 与左侧模块宽度一致 */
background-image: url('@/assets/jinrun/toggle-left.png');
}
&.left-toggle:hover {
background-image: url('@/assets/jinrun/toggle-left_click.png');
}
&.right-toggle {
right: 5rem;
/* 与左侧模块宽度一致 */
background-image: url('@/assets/jinrun/toggle-right.png');
}
&.right-toggle:hover {
background-image: url('@/assets/jinrun/toggle-right_click.png');
}
&.collapsed {
&.left-toggle {
left: 0.55rem;
border-radius: 0 10px 10px 0;
}
&.right-toggle {
right: 0.55rem;
border-radius: 10px 0 0 10px;
}
}
.btn-arrow1 {
img {
width: 0.18rem;
}
}
.btn-arrow {
width: 10px;
height: 10px;
border-top: 2px solid #fff;
border-right: 2px solid #fff;
transition: transform 0.3s ease;
&::before {
content: '';
position: absolute;
width: 2px;
height: 10px;
background: #fff;
top: -4px;
right: 4px;
}
}
&.left-toggle .btn-arrow {
transform: rotate(135deg);
}
&.right-toggle .btn-arrow {
transform: rotate(-45deg);
}
&.collapsed {
&.left-toggle .btn-arrow {
transform: rotate(-45deg);
}
&.right-toggle .btn-arrow {
transform: rotate(135deg);
}
}
&:hover {
}
}
.slide-left-enter-active,
.slide-left-leave-active {
transition:
transform 0.5s ease,
opacity 0.5s ease;
}
.slide-left-enter-from {
transform: translateX(-100%);
opacity: 0;
}
.slide-left-leave-to {
transform: translateX(-100%);
opacity: 0;
}
.slide-right-enter-active,
.slide-right-leave-active {
transition:
transform 0.5s ease,
opacity 0.5s ease;
}
.slide-right-enter-from {
transform: translateX(100%);
opacity: 0;
}
.slide-right-leave-to {
transform: translateX(100%);
opacity: 0;
}
.left-modules:not(.v-enter-active):not(.v-leave-active).left-toggle:not(.collapsed) {
left: 0;
border-radius: 0 10px 10px 0;
}
.right-modules:not(.v-enter-active):not(.v-leave-active).right-toggle:not(.collapsed) {
right: 0;
border-radius: 10px 0 0 10px;
background: pink;
}
.left-modules,
.right-modules {
width: 4.6rem;
padding-top: 0.95rem;
position: absolute;
}
.left-modules {
left: 0;
margin-left: 0.4rem;
}
.right-modules {
right: 0;
margin-right: 0.4rem;
}
.arrow-font {
width: 20px;
color: #fff;
font-size: 0.18rem;
display: flex;
flex-direction: column;
}
.video-container {
width: 100%;
height: 250px;
border: 1px solid #ccc;
background: #f5f5f5;
position: relative;
}
#divPlugin {
width: 100%;
height: 100%;
}
.status-info {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
}
</style>
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue';
import '../../../../Cesium/Widgets/widgets.css';
import { useMessage } from 'naive-ui';
import { getFenceListsApi, getPointAllPersonApi } from '@/api';
import { create3D } from '@/api/utils/cesium';
import { getElevationFromRay, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { cesiumToLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import fullScreen from '@/utils/full';
import bluePersonIcon from '@/assets/blueperson.png';
import redPersonIcon from '../../../assets/redperson.png';
import arrowLeftImg from '@/assets/jinrun/arrow-left.png';
import arrowRightImg from '@/assets/jinrun/arrow-right.png';
import MultiSelect from './appselect.vue';
import { iconPoint } from '@/api/utils/home/cesiumPositions';
let viewer: any = null;
const message = useMessage();
let personEntity: any;
let pins: any = [];
const full = ref(false);
let entityId: any;
const personList = ref([]);
const modelData = ref([
import { nextTick, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue';
import '../../../../Cesium/Widgets/widgets.css';
import { useMessage } from 'naive-ui';
import {
getCameraIdApi,
getCarPointAllCarApi,
getCemeraPointApi,
getFenceListsApi,
getHomeCarApi,
getMonitorIdApi,
getMonitorPointApi,
getPointAllPersonApi,
getPointListApi
} from '@/api';
import { create3D } from '@/api/utils/cesium';
import { getElevationFromRay, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { cesiumToLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { iconPoint } from '@/api/utils/home/cesiumPositions';
import { carSpeed } from '@/api/utils/carSpeed';
import fullScreen from '@/utils/full';
import { webVideo } from '@/utils/ai';
import bluePersonIcon from '@/assets/blueperson.png';
import arrowLeftImg from '@/assets/jinrun/arrow-left.png';
import arrowRightImg from '@/assets/jinrun/arrow-right.png';
import redCarIcon from '@/assets/icon15Red.png';
import redVideoIcon from '@/assets/icon16Red.png';
import redBianIcon from '@/assets/icon17Red.png';
import redPersonIcon from '../../../assets/redperson.png';
import blueCarIcon from '@/assets/icon15.png';
import blueVideoIcon from '@/assets/icon16.png';
import blueBianIcon from '@/assets/icon17.png';
import MultiSelect from './appselect.vue';
let viewer: any = null;
const message = useMessage();
let personEntity: any;
const pins: any = [];
const full = ref(false);
let entityId: any;
let link: any;
let speed = 0;
let text = '';
const personList = ref([]);
const modelData = ref([
[122.04736846370741, 37.48958083145254],
[122.04760069379522, 37.489226301608184],
[122.04823299200363, 37.489451482540346],
[122.04802271634016, 37.48983410372907],
[122.04748237248322, 37.49016152294277]
]);
]);
const options = [
const options = [
{
label: '全选',
value: '1'
},
{
label: '在线监测设备',
value: '2'
value: '3'
},
{
label: '视频监控',
value: '3'
value: '2'
},
{
label: '人员定位',
......@@ -55,133 +76,48 @@ const options = [
label: '越界开采',
value: '6'
}
];
const value = ref(options.map(opt => opt.value));
// 监听选中值的变化
watch(
value,
(newVal, oldVal) => {
// 防止无限递归
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;
// 获取除全选外的所有选项值
const otherValues = options.slice(1).map(opt => opt.value);
// 检查是否选中了所有其他选项
const allOtherSelected = otherValues.every(val => newVal.includes(val));
// 检查是否点击了全选
const allSelectedNow = newVal.includes('1');
const allSelectedBefore = oldVal.includes('1');
// 点击了全选选项
if (allSelectedNow && !allSelectedBefore) {
value.value = options.map(opt => opt.value);
return;
}
// 取消了全选选项
if (!allSelectedNow && allSelectedBefore) {
// 检查是否所有其他选项都被选中
const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
if (allOtherOptionsSelected) {
// 如果所有其他选项都被选中,取消所有选中状态
value.value = [];
} else {
// 如果不是所有其他选项都被选中,只取消全选选项
value.value = newVal.filter(val => val !== '1');
}
return;
}
const someOptionUnselected = oldVal.length > newVal.length;
if (someOptionUnselected && allSelectedNow) {
// 如果取消了某个选项且当前处于全选状态,取消全选,但保留其他选项
value.value = newVal.filter(val => val !== '1');
}
// 选中了所有其他选项,自动选中全选
if (allOtherSelected && !allSelectedNow) {
value.value = options.map(opt => opt.value);
}
// 如果取消了所有选项,清空value
if (newVal.length === 0) {
value.value = [];
}
},
{ deep: true }
);
// const data = ref([
// {
// type: 1,
// name: '仓房摄像头2',
// x: 122.04736846370741,
// y: 37.48958083145254
// },
// {
// type: 2,
// name: '边坡表面位移1',
// x: 122.04760069379522,
// y: 37.489226301608184
// },
// {
// type: 3,
// name: '车辆1',
// x: 122.04823299200363,
// y: 37.489451482540346
// },
// {
// type: 4,
// name: '人工1',
// x: 122.04802271634016,
// y: 37.48983410372907
// },
// {
// type: 5,
// name: '人工2',
// x: 122.04748237248322,
// y: 37.49016152294277
// }
// ]);
const data = ref([]);
const position = ref([]);
const heightData = ref([]);
const datasouce = ref();
const fence = ref<any>();
const personShow = ref(false);
const carShow = ref(false);
const equipmentShow = ref(false);
const videoShow = ref(false);
const treeFence = ref<any>([]);
const wallEntities = ref<any[]>([]);
const iconEntities = ref<any[]>([]);
const fenceData = ref({
];
const value = ref(options.map(opt => opt.value));
const data = ref([]);
const datasouce = ref();
const fence = ref<any>();
const personShow = ref(false);
const carShow = ref(false);
const equipmentShow = ref(false);
const videoShow = ref(false);
const treeFence = ref<any>([]);
const wallEntities = ref<any[]>([]);
const iconEntities = ref<any[]>([]);
const fenceData = ref({
imagePath: '',
imageColor: ''
});
});
const labelData = ref<any>();
const formData = ref([]);
// zhaojunbao 开始
// REM自适应配置
const active = ref(false);
const REM_CONFIG = {
const formData = ref([]);
// zhaojunbao 开始
// REM自适应配置
const active = ref(false);
const REM_CONFIG = {
// 设计稿宽度
designWidth: 1920,
designHeight: 1080,
// 基准值:1rem = 100px
baseSize: 100
};
// 跳转首页
const navTo = () => {
};
// 跳转首页
const navTo = () => {
window.location.href = '/home';
};
};
/**
/**
* 设置REM单位
* 根据窗口宽度动态计算根元素font-size
*/
const setRemUnit = () => {
const setRemUnit = () => {
const { designWidth, designHeight, baseSize } = REM_CONFIG;
// 获取当前窗口尺寸
const windowWidth = window.innerWidth;
......@@ -197,19 +133,19 @@ const setRemUnit = () => {
// 设置根元素font-size,确保最小为50px(可选)
const fontSize = Math.max(baseSize * scale, 50);
document.documentElement.style.fontSize = `${fontSize}px`;
};
};
// 控制左右模块显示状态的响应式变量
const isLeftModulesVisible = ref(true);
const isRightModulesVisible = ref(true);
// 控制左右模块显示状态的响应式变量
const isLeftModulesVisible = ref(true);
const isRightModulesVisible = ref(true);
const toggleBothModules = () => {
const toggleBothModules = () => {
isLeftModulesVisible.value = !isLeftModulesVisible.value;
isRightModulesVisible.value = !isRightModulesVisible.value;
};
// zhaojunbao 结束
// 模型
function add3dtiles() {
};
// zhaojunbao 结束
// 模型
function add3dtiles() {
const CesiumConfig = {
defaultAccessToken:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NTE1OTUxOS1jNTc5LTQwNmMtOWU5My1jNTI3NTIyYzAxNTUiLCJpZCI6MjUwODM5LCJpYXQiOjE3Mjk5MjE1MzV9.xromwPD3oA1e0YsWV035DE5KmYvivkC6fxt344vwObA'
......@@ -240,163 +176,61 @@ function add3dtiles() {
getModel().then(item => {
create3D(viewer, item, 0);
});
}
// 摄像头
// 全局保存当前选中窗口
var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
var g_oLocalConfig = null; //本地配置
//错误码
//通用错误
var ERROR_CODE_UNKNOWN = 1000; //未知错误
var ERROR_CODE_NETWORKERROR = 1001; //网络错误
var ERROR_CODE_PARAMERROR = 1002; //缺少插件元素
//登录模块
var ERROR_CODE_LOGIN_NOLOGIN = 2000; // 未登录
var ERROR_CODE_LOGIN_REPEATLOGIN = 2001; //设备已登录,重复登录
var ERROR_CODE_LOGIN_NOSUPPORT = 2002; //当前设备不支持Digest登录
//预览播放
var ERROR_CODE_PLAY_PLUGININITFAIL = 3000; //插件初始化失败
var ERROR_CODE_PLAY_NOREPEATPLAY = 3001; //当前窗口已经在预览
var ERROR_CODE_PLAY_PLAYBACKABNORMAL = 3002; //回放异常
var ERROR_CODE_PLAY_PLAYBACKSTOP = 3003; //回放停止
var ERROR_CODE_PLAY_NOFREESPACE = 3004; //录像过程中,硬盘容量不足
//对讲
var ERROR_CODE_TALK_FAIL = 5000; //语音对讲失败
let rtsp = {
ip: "192.168.0.17",
user: "admin",
password: "Gemho120611",
port: "80",
channel: "1",
stream: "0.sdp"
};
let arr = ["192.168.0.17", "192.168.0.18", "192.168.0.15"]
function switchVideo() {
let szDeviceIdentify = rtsp.ip + "_" + rtsp.port
WebVideoCtrl.I_Stop({
szDeviceIdentify: szDeviceIdentify, // 例:192.168.1.64_80
iWndIndex: g_iWndIndex, // 0~35
success: function () {
console.log("停播成功");
// 停完再播
startPreview();
},
error: function () {
console.log("停播失败,直接销毁插件");
WebVideoCtrl.I_DestroyPlugin();
startPreview()
}
});
// 含 0 且含 2(闭区间)
const rClosed = Math.random() * 3; // 0 ≤ r < 3
const rClosed2 = Math.floor(rClosed);
rtsp.ip = arr[rClosed2]
login()
}
function login() {
// 初始化插件
WebVideoCtrl.I_InitPlugin({
szContainerID: "videoLayout",
iWndowType: 1, // 改为1表示单个窗口
cbSelWnd: function (xmlDoc) {
console.log("选择了窗口:");
},
cbInitPluginComplete: function () {
WebVideoCtrl.I_InsertOBJECTPlugin("videoLayout").then(() => {
console.log("插件初始化成功!");
clickLogin(1)
}, (err) => {
console.log("插件初始化失败");
});
}
});
clickLogout()
}
// 监听选中值的变化
watch(
value,
(newVal, oldVal) => {
// 防止无限递归
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;
// 登录
function clickLogin(szProtoType) {
let szIP = rtsp.ip
let szPort = rtsp.port
let szUsername = rtsp.user
let szPassword = rtsp.password
// 获取除全选外的所有选项值
const otherValues = options.slice(1).map(opt => opt.value);
// 检查是否选中了所有其他选项
const allOtherSelected = otherValues.every(val => newVal.includes(val));
// 检查是否点击了全选
const allSelectedNow = newVal.includes('1');
const allSelectedBefore = oldVal.includes('1');
if ("" == szIP || "" == szPort) {
// 点击了全选选项
if (allSelectedNow && !allSelectedBefore) {
value.value = options.map(opt => opt.value);
return;
}
var szDeviceIdentify = szIP + "_" + szPort;
WebVideoCtrl.I_Login(szIP, szProtoType, szPort, szUsername, szPassword, {
timeout: 3000,
success: function (xmlDoc) {
console.log("登陆成功");
startPreview();
},
error: function (oError) {
if (ERROR_CODE_LOGIN_REPEATLOGIN === status) {
console.log(" 已登录过!");
} else {
if (oError.errorCode === 401) {
console.log(" 登录失败,已自动切换认证方式!");
// 取消了全选选项
if (!allSelectedNow && allSelectedBefore) {
// 检查是否所有其他选项都被选中
const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
if (allOtherOptionsSelected) {
// 如果所有其他选项都被选中,取消所有选中状态
value.value = [];
} else {
console.log(" 登录失败");
}
}
}
});
// 如果不是所有其他选项都被选中,只取消全选选项
value.value = newVal.filter(val => val !== '1');
}
// 退出
function clickLogout() {
var szDeviceIdentify = rtsp.ip;
if (null == szDeviceIdentify) {
return;
}
WebVideoCtrl.I_Logout(szDeviceIdentify).then(() => {
console.log("退出成功");
}, () => {
console.log("退出失败");
});
const someOptionUnselected = oldVal.length > newVal.length;
if (someOptionUnselected && allSelectedNow) {
// 如果取消了某个选项且当前处于全选状态,取消全选,但保留其他选项
value.value = newVal.filter(val => val !== '1');
}
// 开始预览
function startPreview() {
deviceIdentify = rtsp.ip + "_" + rtsp.port
WebVideoCtrl.I_StartRealPlay(deviceIdentify, {
iWndIndex: g_iWndIndex,
iStreamType: 1, // 主码流
iChannelID: 1,
bZeroChannel: false,
success: function () {
showOPInfo(`摄像头 ${cameraIndex} (${deviceIdentify}) 在窗口 ${windowIndex} 预览成功!`);
},
error: function (err) {
showOPInfo(`摄像头 ${cameraIndex} (${deviceIdentify}) 在窗口 ${windowIndex} 预览失败:${err ? (err.errorCode + " - " + err.errorMsg) : "未知错误"}`);
// 选中了所有其他选项,自动选中全选
if (allOtherSelected && !allSelectedNow) {
value.value = options.map(opt => opt.value);
}
});
// 如果取消了所有选项,清空value
if (newVal.length === 0) {
value.value = [];
}
// 摄像头
},
{ deep: true }
);
// 监听
// 监听选择框的变化
watch(
// 监听选择框的变化
watch(
value,
newValue => {
// 如果选中了"全选",显示所有实体
......@@ -416,14 +250,14 @@ watch(
entity.show = newValue.includes('3');
break;
case 2: // 视频监控
entity.show = newValue.includes('2');
entity.show = newValue.includes('4');
break;
case 3: // 车辆定位
entity.show = newValue.includes('5');
entity.show = newValue.includes('2');
break;
case 4: // 人员定位
case 5: // 人员定位
entity.show = newValue.includes('4');
entity.show = newValue.includes('1');
break;
default:
entity.show = false;
......@@ -432,9 +266,9 @@ watch(
}
},
{ immediate: true }
);
);
async function fenceListGet() {
async function fenceListGet() {
const res = await getFenceListsApi();
formData.value = res.data.data;
......@@ -452,10 +286,10 @@ async function fenceListGet() {
}
electronic(positions, heights, item.rangeType);
}
}
}
// 电子围栏
function electronic(position: any, heightData: any, rangeType: any) {
// 电子围栏
function electronic(position: any, heightData: any, rangeType: any) {
function map_common_addDatasouce(datasouceName: string) {
let datasouce = viewer.dataSources._dataSources.find(t => {
return t && t.name == datasouceName;
......@@ -630,33 +464,52 @@ function electronic(position: any, heightData: any, rangeType: any) {
window.fenceData = position;
}
loadWall();
}
}
// 点击弹框隐藏
function videosShow() {
// 点击弹框隐藏
function videosShow() {
if (videoShow.value == true) {
videoShow.value = false;
iconShow();
}
}
}
function equipmentsShow() {
function equipmentsShow() {
if (equipmentShow.value == true) {
equipmentShow.value = false;
iconShow();
}
}
function carsShow() {
}
function carsShow() {
if (carShow.value == true) {
carShow.value = false;
iconShow();
}
}
}
function personsShow() {
function personsShow() {
if (personShow.value == true) {
personShow.value = false;
iconShow();
}
}
function iconShow() {
for (const item of pins) {
if (item.type == 1) {
item.image = bluePersonIcon;
} else if (item.type == 2) {
item.image = blueCarIcon;
} else if (item.type == 3) {
item.image = blueBianIcon;
} else {
item.image = blueVideoIcon;
}
}
iconPoint(viewer, pins);
}
}
// 设置员工类型
function getPersonTypeName(type: number): string {
switch(type) {
// 设置员工类型
function getPersonTypeName(type: number): string {
switch (type) {
case 1:
return '员工';
case 2:
......@@ -664,100 +517,220 @@ function getPersonTypeName(type: number): string {
default:
return '没有该类型';
}
}
}
onMounted(() => {
async function setTimePerson() {
const res = await getPointAllPersonApi();
for (const item of pins) {
const pin = res.data.data.find((personData: any) => personData.cardId == item.id);
if (pin) {
personShow.value = false;
item.image = bluePersonIcon;
item.position = {
lon: pin.lon,
lat: pin.lat
};
}
}
const carRes = await getCarPointAllCarApi();
for (const item of pins) {
const pin = carRes.data.data.find((carData: any) => carData.carNumber == item.id);
if (pin) {
carShow.value = false;
item.image = blueCarIcon;
item.position = {
lon: pin.lon,
lat: pin.lat
};
}
}
iconPoint(viewer, pins);
}
setInterval(setTimePerson, 10 * 1000);
onMounted(async () => {
add3dtiles();
setTimeout(async () => {
// electronic();
fenceListGet();
let res = await getPointAllPersonApi();
data.value = res.data.data;
iconPoint(viewer,data,'person_').then(result => {
pins = result;
console.log('111',pins);
const res = await getPointAllPersonApi();
const personData = res.data.data;
personData.map(item => {
pins.push({
id: item.cardId,
name: item.realName,
type: 1,
image: bluePersonIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
// 获取并显示车辆数据,使用不同的前缀
const resCar = await getCarPointAllCarApi();
const carData = resCar.data.data;
carData.map(item => {
pins.push({
id: item.carNumber,
name: item.carNumber,
type: 2,
image: blueCarIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
// 获取在线监测
const resPoint = await getMonitorPointApi();
const pointData = resPoint.data.data;
pointData.map(item => {
pins.push({
id: item.id,
type: 3,
name: item.equipname,
image: blueBianIcon,
position: {
lon: item.longitude,
lat: item.latitude
},
data: item,
entity: null,
label: null
});
});
// 获取视频监控信息
const resVideo = await getCemeraPointApi();
const videoData = resVideo.data.data;
videoData.map(item => {
pins.push({
id: item.id,
name: item.cameraName,
type: 4,
image: blueVideoIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
iconPoint(viewer, pins).then(result => {
console.log(result);
});
}, 2000);
// setTimePerson();
// zhaojunbao 开始
// 初始化REM自适应
setRemUnit();
// 监听窗口大小变化
window.addEventListener('resize', setRemUnit);
// zhaojunbao 结束
let currentSelectedPerson = null;
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 鼠标点击事件
handler.setInputAction(function (click: any) {
console.log('222',pins);
handler.setInputAction(async function (click: any) {
const pickedObject = viewer.scene.pick(click.position);
entityId = pickedObject.id.id;
if (!pickedObject.collection) {
videoShow.value = false;
equipmentShow.value = false;
carShow.value = false;
personShow.value = false;
return;
}
if (Cesium.defined(pickedObject) && pickedObject.id) {
const pin = pins.find(p => p.entity === pickedObject.id);
console.log('333',pin);
if (pin.type == 1) {
videoShow.value = true;
} else if (pin.type == 2) {
equipmentShow.value = true;
} else if (pin.type == 3) {
carShow.value = true;
for (const item of pins) {
if (item.type == 1) {
item.image = bluePersonIcon;
} else if (item.type == 2) {
item.image = blueCarIcon;
} else if (item.type == 3) {
item.image = blueBianIcon;
} else {
personList.value = [];
if(typeof entityId == 'string' && entityId.startsWith('person_')) {
viewer.entities.values.forEach((entity:any) => {
if(typeof entity.id === 'string' && entity.id.startsWith('person_')) {
entity.billboard.image = bluePersonIcon;
item.image = blueVideoIcon;
}
});
const clickedEntity = viewer.entities.getById(entityId);
if(clickedEntity) {
clickedEntity.billboard.image = redPersonIcon;
currentSelectedPerson = clickedEntity;
}
if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
const pin = pins.find(item => item.entity === pickedObject.id);
if (pin.type == 1) {
equipmentShow.value = false;
videoShow.value = false;
carShow.value = false;
personShow.value = true;
console.log(pickedObject.id.personData);
if (pickedObject.id.personData) {
labelData.value = pin.data;
pin.image = redPersonIcon;
} else if (pin.type == 2) {
// 车
equipmentShow.value = false;
videoShow.value = false;
personShow.value = false;
carShow.value = true;
const res = await getHomeCarApi(pin.id);
console.log(res);
personList.value.push({
personId: pickedObject.id.personData.info.personId,
realName: pickedObject.id.personData.info.realName,
remark: pickedObject.id.personData.info.remark,
phone: pickedObject.id.personData.info.phone,
deptName: pickedObject.id.personData.info.deptName,
personType: pickedObject.id.personData.info.personType,
})
if (res.data.code == 200) {
speed = res.data.data.point ? carSpeed(res.data.data) : 0;
labelData.value = res.data.data;
link = `${labelData.value.ipAddress}?lang=zh&devIdno=${labelData.value.cameraNo}&account=${labelData.value.username}&password=${labelData.value.password}&channel=1`;
}
} else {
personList.value = [];
personShow.value = false;
if (personShow.value == false) {
const clickedEntity = viewer.entities.getById(entityId);
clickedEntity.billboard.image = bluePersonIcon;
pin.image = redCarIcon;
} else if (pin.type == 3) {
// 监测设备
videoShow.value = false;
carShow.value = false;
personShow.value = false;
equipmentShow.value = true;
const res = await getMonitorIdApi(pin.id);
if (res.data.code == 200) {
if (res.data.data.devicetype == 3) {
text = '表面位移';
} else if (res.data.data.devicetype == 6) {
text = '降雨量';
}
labelData.value = res.data.data;
}
pin.image = redBianIcon;
} else {
// 摄像头
equipmentShow.value = false;
videoShow.value = true;
carShow.value = false;
personShow.value = false;
videoShow.value = true;
const res = await getCameraIdApi(pin.id);
if (res.data.code == 200) {
labelData.value = res.data.data;
console.log(labelData.value);
const webRtcServrce = ref();
nextTick(() => {
webRtcServrce.value = new WebRtcStreamer('video', `${location.protocol}//` + `192.168.2.53:8000`);
webRtcServrce.value.connect(res.data.data.videoStream);
});
}
pin.image = redVideoIcon;
}
iconPoint(viewer, pins);
} else {
videoShow.value = false;
equipmentShow.value = false;
videoShow.value = false;
carShow.value = false;
personShow.value = false;
iconPoint(viewer, pins);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});
});
onUnmounted(() => {
onUnmounted(() => {
// 清理Cesium资源
if (viewer) {
viewer.destroy();
......@@ -765,14 +738,14 @@ onUnmounted(() => {
}
// 移除窗口大小变化监听
window.removeEventListener("resize", setRemUnit);
window.removeEventListener('resize', setRemUnit);
// 移除html元素style属性中的font-size
document.documentElement.style.fontSize = '';
});
</script>
});
</script>
<template>
<template>
<div class="wrapper">
<div class="top-toolbar">
<div class="baojing">
......@@ -805,26 +778,26 @@ onUnmounted(() => {
&times;
</button>
</div>
<div style="line-height: 1.8" v-for="item in personList">
<div style="line-height: 1.8">
<p class="title1">
<strong class="title2">姓名:</strong>
{{item.realName}}
{{ labelData.realName }}
</p>
<p class="title1">
<strong class="title2">定位卡号:</strong>
{{item.remark}}
{{ labelData.cardId }}
</p>
<p class="title1">
<strong class="title2">人员类型:</strong>
{{ getPersonTypeName(item.personType) }}
{{ getPersonTypeName(labelData.personType) }}
</p>
<p class="title1">
<strong class="title2">电话:</strong>
{{ item.phone}}
{{ labelData.phone }}
</p>
<p class="title1">
<strong class="title2">部门:</strong>
{{ item.deptName}}
{{ labelData.deptName }}
</p>
</div>
</div>
......@@ -848,79 +821,54 @@ onUnmounted(() => {
<div class="left-top">
<p class="title1">
<strong class="title2">车牌号:</strong>
鲁K:534435
{{ labelData.carNumber || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">车队名称:</strong>
KC001
{{ labelData.teamName || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">当前车速:</strong>
25km/h
{{ speed }} km/h
</p>
<p class="title1">
<strong class="title2">车辆类型:</strong>
卡车
{{ labelData.carType || '暂无数据' }}
</p>
</div>
<div class="left-center"></div>
<div class="left-bottom">
<p class="title1">
<strong class="title2">司机姓名:</strong>
张喂
{{ labelData.driverName || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">工作开始时间:</strong>
8:30
{{ labelData.workStartTime || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">工作时长:</strong>
3H
{{ labelData.workTime || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">终端设备编号:</strong>
ZD000001
{{ labelData.terminalNumber || '暂无数据' }}
</p>
</div>
</div>
<div class="car-right">
<!--
<video id="video" controls autoplay muted playsinline width="100%" height="100%"
style="object-fit: fill; z-index: 1;"></video>
-->
<div
:style="
full
? {
border: '1px solid #ccc',
padding: '2px',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100px',
zIndex: '99'
}
: {
padding: '2px',
height: '250px !important',
border: ' 1px solid #ccc',
position: 'relative',
margin: '0px 10px 0px 0px'
}
"
>
<div style="position: absolute; bottom: 5px; right: 5px; width: 40px; height: 40px; cursor: pointer">
<icon-gridicons-fullscreen-exit
v-if="full"
color="#11e0ff"
font-size="30"
@click="full = fullScreen(full)"
/>
<icon-gridicons-fullscreen v-else font-size="30" color="#11e0ff" @click="full = fullScreen(full)" />
</div>
<canvas id="canvas-4" style="width: 100%; height: 100%" width="800" height="600"></canvas>
</div>
<iframe
allowfullscreen="true"
allowtransparency="true"
allow="autoplay"
scrolling="no"
:src="link"
width="100%"
height="100%"
frameborder="0"
style="padding-right: 20px"
></iframe>
<!-- '${res.ipAddress}?lang=zh&devIdno=${res.cameraNo}&account=${res.username}&password=${res.password}&channel=1' -->
</div>
</div>
</div>
......@@ -942,27 +890,27 @@ onUnmounted(() => {
<div style="line-height: 1.8">
<p class="title1">
<strong class="title2">设备名称:</strong>
设备表面位移01
{{ labelData.equipname }}
</p>
<p class="title1">
<strong class="title2">设备状态:</strong>
在线/离线
{{ labelData.dataStatus === 0 ? '在线' : '离线' }}
</p>
<p class="title1">
<strong class="title2">设备类型:</strong>
表面位移/降雨量/环境监测
{{ text }}
</p>
<p class="title1">
<strong class="title2">监测值:</strong>
0.004mm
{{ labelData.value }}
</p>
<p class="title1">
<strong class="title2">监测时间:</strong>
2025-10 10:10:10
{{ labelData.time }}
</p>
<p class="title1">
<strong class="title2">数据状态:</strong>
正常
{{ labelData.onlineStatus === 0 ? '正常' : '蓝色报警' }}
</p>
</div>
</div>
......@@ -985,53 +933,28 @@ onUnmounted(() => {
<div class="video-top">
<div class="title3">
<strong class="title2">● 摄像头名称:</strong>
排土场入口
{{ labelData.areaName }}
</div>
<div class="title3">
<strong class="title4">● 区域名称:</strong>
排土场背部
{{ labelData.cameraName }}
</div>
<div class="title3">
<strong class="title4">● 设备状态:</strong>
在线/离线
{{ labelData.status === 0 ? '在线' : '离线' }}
</div>
</div>
<div class="video-bottom">
<!-- <NButton @click="login()">登陆</NButton>
<NButton @click="switchVideo()">切换视频流</NButton>
<div id="videoLayout" style="width: 500px; height: 250px; border: 1px solid red;"></div> -->
<div
:style="
full
? {
border: '1px solid #ccc',
padding: '2px',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100px',
zIndex: '99'
}
: {
padding: '2px',
height: '250px !important',
border: ' 1px solid #ccc',
position: 'relative'
}
"
>
<div style="position: absolute; bottom: 5px; right: 5px; width: 40px; height: 40px; cursor: pointer">
<icon-gridicons-fullscreen-exit
v-if="full"
color="#11e0ff"
font-size="30"
@click="full = fullScreen(full)"
/>
<icon-gridicons-fullscreen v-else font-size="30" color="#11e0ff" @click="full = fullScreen(full)" />
</div>
<canvas id="canvas-4" style="width: 100%; height: 100%" width="800" height="600"></canvas>
</div>
<video
id="video"
controls
autoplay
muted
playsinline
width="100%"
height="100%"
style="object-fit: fill; z-index: 1"
></video>
</div>
</div>
</div>
......@@ -1049,8 +972,8 @@ onUnmounted(() => {
</div>
</div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
<div v-show="isLeftModulesVisible" class="left"></div>
<div v-show="isRightModulesVisible" class="right"></div>
<!-- 非cesium相关 开始 -->
......@@ -1060,11 +983,6 @@ onUnmounted(() => {
<div>
<img :src="isLeftModulesVisible ? arrowLeftImg : arrowRightImg" alt="" srcset="" />
<br />
<!--
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
<br />
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
-->
<div class="arrow-font">
{{ isLeftModulesVisible ? '收起' : '展开' }}
</div>
......@@ -1079,11 +997,6 @@ onUnmounted(() => {
<div>
<img :src="isLeftModulesVisible ? arrowRightImg : arrowLeftImg" alt="" srcset="" />
<br />
<!--
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
<br />
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
-->
<div class="arrow-font">
{{ isLeftModulesVisible ? '收起' : '展开' }}
</div>
......@@ -1092,45 +1005,47 @@ onUnmounted(() => {
</div>
<!-- 左侧模块容器 -->
<transition name="slide-left">
<div class="left-modules" v-show="isLeftModulesVisible">
<Transition name="slide-left">
<div v-show="isLeftModulesVisible" class="left-modules">
<LeftDeviceStatus />
<LeftRainfallTrend />
<LeftOnlineMonitor />
</div>
</transition>
</Transition>
<!-- 右侧模块容器 -->
<transition name="slide-right">
<div class="right-modules" v-show="isRightModulesVisible">
<Transition name="slide-right">
<div v-show="isRightModulesVisible" class="right-modules">
<RightAiWarning />
<RightEnvMonitor />
<RightTodayAlarm />
</div>
</transition>
</Transition>
<!-- 非cesium相关 结束 -->
</template>
</template>
<style scoped>
html, body {
<style scoped>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
.cesium-container {
}
.cesium-container {
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
}
#cesiumContainer {
#cesiumContainer {
width: 100%;
height: 100%;
}
}
.personMessage {
.personMessage {
width: 450px;
height: 250px;
position: absolute;
......@@ -1141,13 +1056,13 @@ html, body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
}
}
.carMessage {
.carMessage {
width: 600px;
height: 380px;
position: absolute;
......@@ -1158,13 +1073,13 @@ html, body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
}
}
.equipmentMessage {
.equipmentMessage {
width: 450px;
height: 290px;
position: absolute;
......@@ -1175,13 +1090,13 @@ html, body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
}
}
.videoMessage {
.videoMessage {
width: 680px;
height: 380px;
position: absolute;
......@@ -1192,41 +1107,41 @@ html, body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
}
}
.title1 {
.title1 {
margin-top: 5px;
}
}
.title2 {
.title2 {
color: #29d7fb;
margin-right: 10px;
}
}
.title3 {
.title3 {
display: flex;
align-items: center;
margin: 0px 0px 8px 10px;
}
margin: 0px 0px 8px 0px;
}
.title4 {
.title4 {
color: #29d7fb;
margin-right: 10px;
margin-left: 20px;
}
}
span {
span {
position: absolute;
z-index: 4;
left: 30px;
top: 10px;
}
}
.person1 {
.person1 {
width: 85%;
height: 40px;
background-image: url('@/assets/person1.png');
......@@ -1234,81 +1149,86 @@ span {
position: absolute;
left: 6px;
top: 20px;
}
}
.left-center {
.left-center {
width: 100%;
height: 10px;
border-bottom: 1px solid #147f9c;
}
}
.right {
.right {
width: 60%;
height: 50%;
margin-right: 20px;
/* margin-right: 20px; */
/* margin-top: 20px; */
}
}
#video {
height: 250px;
}
.video-top {
.video-top {
width: 100%;
height: 50%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
}
.video-bottom {
.video-bottom {
margin-right: 20px;
}
}
.select {
.select {
width: 100%;
border: none;
background-image: url('@/assets/multiple-pop.png');
}
}
.n-select {
.n-select {
background-image: url('@/assets/multiple-pop.png');
background-position: center;
}
}
.n-select .n-select-trigger {
.n-select .n-select-trigger {
background-color: transparent;
}
}
.n-select .n-select-menu {
.n-select .n-select-menu {
background-color: transparent;
}
}
:deep(.n-base-selection .n-base-selection-tags) {
:deep(.n-base-selection .n-base-selection-tags) {
background-color: transparent !important;
}
}
:deep(.n-base-selection .n-base-selection-label .n-base-selection-input .n-base-selection-input__content) {
:deep(.n-base-selection .n-base-selection-label .n-base-selection-input .n-base-selection-input__content) {
color: white !important;
}
}
:deep(.n-base-selection .n-base-selection__border, .n-base-selection .n-base-selection__state-border) {
:deep(.n-base-selection .n-base-selection__border, .n-base-selection .n-base-selection__state-border) {
border: 1px solid #4ab9fd;
}
}
:deep(.n-tag) {
:deep(.n-tag) {
color: #fff;
background: #10273e00;
/* display:none; */
}
}
:deep(.n-tag .n-tag__border) {
:deep(.n-tag .n-tag__border) {
border: none;
}
:deep(.n-base-selection-tag-wrapper) {
}
:deep(.n-base-selection-tag-wrapper) {
background: #10273e00;
}
}
/* zhaojunbao */
.top-toolbar {
/* zhaojunbao */
.top-toolbar {
position: absolute;
top: .5rem;
top: 0.5rem;
right: 0.5rem;
width: 240px;
height: 0.4rem;
......@@ -1317,55 +1237,61 @@ span {
display: flex;
align-items: center;
justify-content: space-between;
.split-line {
width: 0.03rem;
height: 100%;
background: #11e0ff;
}
.baojing {
position: relative;
padding-left: 25px;
display: block;
&::before {
content: "";
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
background-image: url("@/assets/jinrun/baojing.png");
background-image: url('@/assets/jinrun/baojing.png');
background-size: contain;
background-repeat: no-repeat;
}
}
.houtaiguanli {
position: relative;
padding-left: 25px;
display: block;
&::before {
content: "";
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
background-image: url("@/assets/jinrun/houtai.png");
background-image: url('@/assets/jinrun/houtai.png');
background-size: contain;
background-repeat: no-repeat;
}
}
}
}
.top,
.bottom,
.left,
.right {
.top,
.bottom,
.left,
.right {
position: absolute;
background-repeat: no-repeat;
}
.top {
}
.top {
top: 0;
width: 100%;
height: 1.25rem;
......@@ -1376,51 +1302,59 @@ span {
height: 100%;
position: relative;
& > img {
width: 100%;
}
.second-icon {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
width: 5.04rem; /* 可根据实际需要调整大小 */
height: 0.54rem; /* 可根据实际需要调整大小 */
width: 5.04rem;
/* 可根据实际需要调整大小 */
height: 0.54rem;
/* 可根据实际需要调整大小 */
}
}
}
}
.bottom {
.bottom {
bottom: 0;
left: 0;
width: 100%;
height: 0.4rem;
background-image: url("@/assets/jinrun/bottom.png");
background-image: url('@/assets/jinrun/bottom.png');
background-size: cover;
}
.left {
}
.left {
top: 0rem;
left: 0;
width: 264px;
width: 5.76rem;
height: calc(100vh);
background-size: contain;
background-position-x: left;
background-image: url('@/assets/jinrun/bg-left.png');
}
background-image: url("@/assets/jinrun/left.png");
}
.right {
.right {
top: 0rem;
right: 0;
width: 264px;
width: 5.76rem;
height: calc(100vh);
background-image: url("@/assets/jinrun/right.png");
background-image: url('@/assets/jinrun/bg-right.png');
background-size: contain;
background-position-x: right;
}
}
.toggle-btn {
.toggle-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 0.71rem;
height: 1.87rem;
background-image: url("@/assets/jinrun/toggle-left.png");
background-image: url('@/assets/jinrun/toggle-left.png');
background-size: cover;
background-repeat: no-repeat;
border-radius: 0 10px 10px 0;
......@@ -1432,19 +1366,23 @@ span {
transition: all 0.3s ease;
&.left-toggle {
left: 5rem; /* 与左侧模块宽度一致 */
background-image: url("@/assets/jinrun/toggle-left.png");
left: 5rem;
/* 与左侧模块宽度一致 */
background-image: url('@/assets/jinrun/toggle-left.png');
}
&.left-toggle:hover {
background-image: url("@/assets/jinrun/toggle-left_click.png");
background-image: url('@/assets/jinrun/toggle-left_click.png');
}
&.right-toggle {
right: 5rem; /* 与左侧模块宽度一致 */
background-image: url("@/assets/jinrun/toggle-right.png");
right: 5rem;
/* 与左侧模块宽度一致 */
background-image: url('@/assets/jinrun/toggle-right.png');
}
&.right-toggle:hover {
background-image: url("@/assets/jinrun/toggle-right_click.png");
background-image: url('@/assets/jinrun/toggle-right_click.png');
}
&.collapsed {
......@@ -1473,7 +1411,7 @@ span {
transition: transform 0.3s ease;
&::before {
content: "";
content: '';
position: absolute;
width: 2px;
height: 10px;
......@@ -1503,72 +1441,100 @@ span {
&:hover {
}
}
}
.slide-left-enter-active,
.slide-left-leave-active {
transition: transform 0.5s ease, opacity 0.5s ease;
}
.slide-left-enter-active,
.slide-left-leave-active {
transition:
transform 0.5s ease,
opacity 0.5s ease;
}
.slide-left-enter-from {
.slide-left-enter-from {
transform: translateX(-100%);
opacity: 0;
}
}
.slide-left-leave-to {
.slide-left-leave-to {
transform: translateX(-100%);
opacity: 0;
}
}
.slide-right-enter-active,
.slide-right-leave-active {
transition: transform 0.5s ease, opacity 0.5s ease;
}
.slide-right-enter-active,
.slide-right-leave-active {
transition:
transform 0.5s ease,
opacity 0.5s ease;
}
.slide-right-enter-from {
.slide-right-enter-from {
transform: translateX(100%);
opacity: 0;
}
}
.slide-right-leave-to {
.slide-right-leave-to {
transform: translateX(100%);
opacity: 0;
}
}
.left-modules:not(.v-enter-active):not(.v-leave-active).left-toggle:not(.collapsed) {
.left-modules:not(.v-enter-active):not(.v-leave-active).left-toggle:not(.collapsed) {
left: 0;
border-radius: 0 10px 10px 0;
}
}
.right-modules:not(.v-enter-active):not(.v-leave-active).right-toggle:not(.collapsed) {
.right-modules:not(.v-enter-active):not(.v-leave-active).right-toggle:not(.collapsed) {
right: 0;
border-radius: 10px 0 0 10px;
background: pink;
}
}
.left-modules,
.right-modules {
.left-modules,
.right-modules {
width: 4.6rem;
padding-top: .95rem;
padding-top: 0.95rem;
position: absolute;
}
}
.left-modules {
.left-modules {
left: 0;
margin-left: 0.4rem;
}
}
.right-modules {
.right-modules {
right: 0;
margin-right: 0.4rem;
}
}
.arrow-font {
.arrow-font {
width: 20px;
color: #fff;
font-size: 0.18rem;
display: flex;
flex-direction: column;
}
</style>
}
.video-container {
width: 100%;
height: 250px;
border: 1px solid #ccc;
background: #f5f5f5;
position: relative;
}
#divPlugin {
width: 100%;
height: 100%;
}
.status-info {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue';
import { nextTick, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue';
import '../../../../Cesium/Widgets/widgets.css';
import { useMessage } from 'naive-ui';
import { getCarPointAllCarApi, getFenceListsApi, getPointAllPersonApi } from '@/api';
import {
getCameraIdApi,
getCarPointAllCarApi,
getCemeraPointApi,
getFenceListsApi,
getHomeCarApi,
getMonitorIdApi,
getMonitorPointApi,
getPointAllPersonApi,
getPointListApi
} from '@/api';
import { create3D } from '@/api/utils/cesium';
import { getElevationFromRay, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { cesiumToLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { iconPoint } from '@/api/utils/home/cesiumPositions';
import { carSpeed } from '@/api/utils/carSpeed';
import fullScreen from '@/utils/full';
import { webVideo } from '@/utils/ai';
import bluePersonIcon from '@/assets/blueperson.png';
import arrowLeftImg from '@/assets/jinrun/arrow-left.png';
import arrowRightImg from '@/assets/jinrun/arrow-right.png';
import redCarIcon from '@/assets/icon15Red.png';
import redVideoIcon from '@/assets/icon16Red.png';
import redBianIcon from '@/assets/icon17Red.png';
import blueCarIcon from '@/assets/icon15.png';
import blueVideoIcon from '@/assets/icon16.png';
import blueBianIcon from '@/assets/icon17.png';
import redPersonIcon from '../../../assets/redperson.png';
import MultiSelect from './appselect.vue';
let viewer: any = null;
const message = useMessage();
let personEntity: any;
let pins: any = [];
const pins: any = [];
const full = ref(false);
let entityId: any;
let link: any;
let speed = 0;
let text = '';
const personList = ref([]);
const modelData = ref([
[122.04736846370741, 37.48958083145254],
......@@ -37,11 +58,11 @@ const options = [
},
{
label: '在线监测设备',
value: '2'
value: '3'
},
{
label: '视频监控',
value: '3'
value: '2'
},
{
label: '人员定位',
......@@ -57,95 +78,8 @@ const options = [
}
];
const value = ref(options.map(opt => opt.value));
// 监听选中值的变化
watch(
value,
(newVal, oldVal) => {
// 防止无限递归
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;
// 获取除全选外的所有选项值
const otherValues = options.slice(1).map(opt => opt.value);
// 检查是否选中了所有其他选项
const allOtherSelected = otherValues.every(val => newVal.includes(val));
// 检查是否点击了全选
const allSelectedNow = newVal.includes('1');
const allSelectedBefore = oldVal.includes('1');
// 点击了全选选项
if (allSelectedNow && !allSelectedBefore) {
value.value = options.map(opt => opt.value);
return;
}
// 取消了全选选项
if (!allSelectedNow && allSelectedBefore) {
// 检查是否所有其他选项都被选中
const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
if (allOtherOptionsSelected) {
// 如果所有其他选项都被选中,取消所有选中状态
value.value = [];
} else {
// 如果不是所有其他选项都被选中,只取消全选选项
value.value = newVal.filter(val => val !== '1');
}
return;
}
const someOptionUnselected = oldVal.length > newVal.length;
if (someOptionUnselected && allSelectedNow) {
// 如果取消了某个选项且当前处于全选状态,取消全选,但保留其他选项
value.value = newVal.filter(val => val !== '1');
}
// 选中了所有其他选项,自动选中全选
if (allOtherSelected && !allSelectedNow) {
value.value = options.map(opt => opt.value);
}
// 如果取消了所有选项,清空value
if (newVal.length === 0) {
value.value = [];
}
},
{ deep: true }
);
// const data = ref([
// {
// type: 1,
// name: '仓房摄像头2',
// x: 122.04736846370741,
// y: 37.48958083145254
// },
// {
// type: 2,
// name: '边坡表面位移1',
// x: 122.04760069379522,
// y: 37.489226301608184
// },
// {
// type: 3,
// name: '车辆1',
// x: 122.04823299200363,
// y: 37.489451482540346
// },
// {
// type: 4,
// name: '人工1',
// x: 122.04802271634016,
// y: 37.48983410372907
// },
// {
// type: 5,
// name: '人工2',
// x: 122.04748237248322,
// y: 37.49016152294277
// }
// ]);
const data = ref([]);
const position = ref([]);
const heightData = ref([]);
const datasouce = ref();
const fence = ref<any>();
const personShow = ref(false);
......@@ -160,8 +94,10 @@ const fenceData = ref({
imagePath: '',
imageColor: ''
});
const labelData = ref<any>();
const formData = ref([]);
// zhaojunbao 开始
// REM自适应配置
const active = ref(false);
......@@ -242,6 +178,57 @@ function add3dtiles() {
});
}
// 监听选中值的变化
watch(
value,
(newVal, oldVal) => {
// 防止无限递归
if (JSON.stringify(newVal) === JSON.stringify(oldVal)) return;
// 获取除全选外的所有选项值
const otherValues = options.slice(1).map(opt => opt.value);
// 检查是否选中了所有其他选项
const allOtherSelected = otherValues.every(val => newVal.includes(val));
// 检查是否点击了全选
const allSelectedNow = newVal.includes('1');
const allSelectedBefore = oldVal.includes('1');
// 点击了全选选项
if (allSelectedNow && !allSelectedBefore) {
value.value = options.map(opt => opt.value);
return;
}
// 取消了全选选项
if (!allSelectedNow && allSelectedBefore) {
// 检查是否所有其他选项都被选中
const allOtherOptionsSelected = otherValues.every(val => newVal.includes(val));
if (allOtherOptionsSelected) {
// 如果所有其他选项都被选中,取消所有选中状态
value.value = [];
} else {
// 如果不是所有其他选项都被选中,只取消全选选项
value.value = newVal.filter(val => val !== '1');
}
return;
}
const someOptionUnselected = oldVal.length > newVal.length;
if (someOptionUnselected && allSelectedNow) {
// 如果取消了某个选项且当前处于全选状态,取消全选,但保留其他选项
value.value = newVal.filter(val => val !== '1');
}
// 选中了所有其他选项,自动选中全选
if (allOtherSelected && !allSelectedNow) {
value.value = options.map(opt => opt.value);
}
// 如果取消了所有选项,清空value
if (newVal.length === 0) {
value.value = [];
}
},
{ deep: true }
);
// 监听选择框的变化
watch(
value,
......@@ -249,32 +236,45 @@ watch(
// 如果选中了"全选",显示所有实体
if (newValue.includes('1')) {
wallEntities.value.forEach(entity => (entity.show = true));
iconEntities.value.forEach(entity => (entity.show = true));
// 显示所有图标和标签
pins.forEach(pin => {
if (pin.entity) pin.entity.show = true;
if (pin.labelEntity) pin.labelEntity.show = true;
if (pin.backgroundEntity) pin.backgroundEntity.show = true;
});
} else {
// 根据选中的选项显示对应实体
wallEntities.value.forEach(entity => {
entity.show = newValue.includes('6'); // 越界开采对应电子围栏
});
iconEntities.value.forEach(entity => {
const type = entity.properties?.type?.getValue();
// 根据选中的选项显示对应图标和标签
pins.forEach(pin => {
const type = pin.type;
let shouldShow = false;
switch (type) {
case 1: // 在线监测设备
entity.show = newValue.includes('3');
case 1: // 人员定位
shouldShow = newValue.includes('4');
break;
case 2: // 视频监控
entity.show = newValue.includes('2');
case 2: // 车辆定位
shouldShow = newValue.includes('5');
break;
case 3: // 车辆定位
entity.show = newValue.includes('5');
case 3: // 在线监测设备
shouldShow = newValue.includes('3');
break;
case 4: // 人员定位
case 5: // 人员定位
entity.show = newValue.includes('4');
case 4: // 视频监控
shouldShow = newValue.includes('2');
break;
default:
entity.show = false;
shouldShow = false;
}
// 设置图标和标签的显示状态
if (pin.entity) pin.entity.show = shouldShow;
if (pin.labelEntity) pin.labelEntity.show = shouldShow;
if (pin.backgroundEntity) pin.backgroundEntity.show = shouldShow;
});
}
},
......@@ -483,24 +483,43 @@ function electronic(position: any, heightData: any, rangeType: any) {
function videosShow() {
if (videoShow.value == true) {
videoShow.value = false;
iconShow();
}
}
function equipmentsShow() {
if (equipmentShow.value == true) {
equipmentShow.value = false;
iconShow();
}
}
function carsShow() {
if (carShow.value == true) {
carShow.value = false;
iconShow();
}
}
function personsShow() {
if (personShow.value == true) {
personShow.value = false;
iconShow();
}
}
function iconShow() {
for (const item of pins) {
if (item.type == 1) {
item.image = bluePersonIcon;
} else if (item.type == 2) {
item.image = blueCarIcon;
} else if (item.type == 3) {
item.image = blueBianIcon;
} else {
item.image = blueVideoIcon;
}
}
iconPoint(viewer, pins);
}
// 设置员工类型
function getPersonTypeName(type: number): string {
switch (type) {
......@@ -513,103 +532,213 @@ function getPersonTypeName(type: number): string {
}
}
onMounted(() => {
async function setTimePerson() {
const res = await getPointAllPersonApi();
for (const item of pins) {
const pin = res.data.data.find((personData: any) => personData.cardId == item.id);
if (pin) {
personShow.value = false;
item.image = bluePersonIcon;
item.position = {
lon: pin.lon,
lat: pin.lat
};
}
}
const carRes = await getCarPointAllCarApi();
for (const item of pins) {
const pin = carRes.data.data.find((carData: any) => carData.carNumber == item.id);
if (pin) {
carShow.value = false;
item.image = blueCarIcon;
item.position = {
lon: pin.lon,
lat: pin.lat
};
}
}
iconPoint(viewer, pins);
}
setInterval(setTimePerson, 2 * 60 * 1000);
onMounted(async () => {
add3dtiles();
setTimeout(async () => {
// electronic();
fenceListGet();
// 获取并显示人员数据
const res = await getPointAllPersonApi();
const personData = ref(res.data.data);
await iconPoint(viewer, personData, 'person_').then(result => {
pins = result;
console.log('111', pins);
const personData = res.data.data;
personData.map(item => {
pins.push({
id: item.cardId,
name: item.realName,
type: 1,
image: bluePersonIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
// 获取并显示车辆数据,使用不同的前缀
const resCar = await getCarPointAllCarApi();
const carData = ref(resCar.data.data);
await iconPoint(viewer, carData, 'car_').then(result => {
pins = [...pins, ...result];
console.log('222', pins);
const carData = resCar.data.data;
carData.map(item => {
pins.push({
id: item.carNumber,
name: item.carNumber,
type: 2,
image: blueCarIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
// 获取在线监测
const resPoint = await getMonitorPointApi();
const pointData = resPoint.data.data;
pointData.map(item => {
pins.push({
id: item.id,
type: 3,
name: item.equipname,
image: blueBianIcon,
position: {
lon: item.longitude,
lat: item.latitude
},
data: item,
entity: null,
label: null
});
});
// 保留原始数据引用用于其他操作
data.value = [...res.data.data, ...resCar.data.data];
// 获取视频监控信息
const resVideo = await getCemeraPointApi();
const videoData = resVideo.data.data;
videoData.map(item => {
pins.push({
id: item.id,
name: item.cameraName,
type: 4,
image: blueVideoIcon,
position: {
lon: item.lon,
lat: item.lat
},
data: item,
entity: null
});
});
iconPoint(viewer, pins).then(result => {
console.log(result);
});
}, 2000);
// setTimePerson();
// zhaojunbao 开始
// 初始化REM自适应
setRemUnit();
// 监听窗口大小变化
window.addEventListener('resize', setRemUnit);
// zhaojunbao 结束
let currentSelectedPerson = null;
const currentCar = ref<any>(null);
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 鼠标点击事件
handler.setInputAction(function (click: any) {
handler.setInputAction(async function (click: any) {
const pickedObject = viewer.scene.pick(click.position);
entityId = pickedObject.id.id;
if (!pickedObject.collection) {
videoShow.value = false;
equipmentShow.value = false;
carShow.value = false;
personShow.value = false;
return;
for (const item of pins) {
if (item.type == 1) {
item.image = bluePersonIcon;
} else if (item.type == 2) {
item.image = blueCarIcon;
} else if (item.type == 3) {
item.image = blueBianIcon;
} else {
item.image = blueVideoIcon;
}
if (Cesium.defined(pickedObject) && pickedObject.id) {
const pin = pins.find(p => p.entity === pickedObject.id);
}
if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
const pin = pins.find(item => item.entity === pickedObject.id);
if (pin.type == 1) {
videoShow.value = true;
equipmentShow.value = false;
videoShow.value = false;
carShow.value = false;
personShow.value = true;
labelData.value = pin.data;
pin.image = redPersonIcon;
} else if (pin.type == 2) {
equipmentShow.value = true;
} else if (pin.type == 3) {
// 车
equipmentShow.value = false;
videoShow.value = false;
personShow.value = false;
carShow.value = true;
currentCar.value = pin.data;
} else {
personList.value = [];
if (typeof entityId === 'string' && entityId.startsWith('person_')) {
viewer.entities.values.forEach((entity: any) => {
if (typeof entity.id === 'string' && entity.id.startsWith('person_')) {
entity.billboard.image = bluePersonIcon;
}
});
const res = await getHomeCarApi(pin.id);
console.log(res);
const clickedEntity = viewer.entities.getById(entityId);
if (clickedEntity) {
clickedEntity.billboard.image = redPersonIcon;
currentSelectedPerson = clickedEntity;
if (res.data.code == 200) {
speed = res.data.data.point ? carSpeed(res.data.data) : 0;
labelData.value = res.data.data;
link = `${labelData.value.ipAddress}?lang=zh&devIdno=${labelData.value.cameraNo}&account=${labelData.value.username}&password=${labelData.value.password}&channel=1`;
}
personShow.value = true;
if (pickedObject.id.personData) {
personList.value.push({
personId: pickedObject.id.personData.info.personId,
realName: pickedObject.id.personData.info.realName,
remark: pickedObject.id.personData.info.remark,
phone: pickedObject.id.personData.info.phone,
deptName: pickedObject.id.personData.info.deptName,
personType: pickedObject.id.personData.info.personType
});
pin.image = redCarIcon;
} else if (pin.type == 3) {
// 监测设备
videoShow.value = false;
carShow.value = false;
personShow.value = false;
equipmentShow.value = true;
const res = await getMonitorIdApi(pin.id);
if (res.data.code == 200) {
if (res.data.data.devicetype == 3) {
text = '表面位移';
} else if (res.data.data.devicetype == 6) {
text = '降雨量';
}
labelData.value = res.data.data;
}
pin.image = redBianIcon;
} else {
personList.value = [];
// 摄像头
equipmentShow.value = false;
videoShow.value = true;
carShow.value = false;
personShow.value = false;
if (personShow.value == false) {
const clickedEntity = viewer.entities.getById(entityId);
clickedEntity.billboard.image = bluePersonIcon;
}
videoShow.value = true;
const res = await getCameraIdApi(pin.id);
if (res.data.code == 200) {
labelData.value = res.data.data;
console.log(labelData.value);
const webRtcServrce = ref();
nextTick(() => {
webRtcServrce.value = new WebRtcStreamer('video', `${location.protocol}//` + `192.168.2.53:8000`);
webRtcServrce.value.connect(res.data.data.videoStream);
});
}
pin.image = redVideoIcon;
}
iconPoint(viewer, pins);
} else {
videoShow.value = false;
equipmentShow.value = false;
videoShow.value = false;
carShow.value = false;
personShow.value = false;
iconPoint(viewer, pins);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});
......@@ -662,26 +791,26 @@ onUnmounted(() => {
&times;
</button>
</div>
<div v-for="item in personList" style="line-height: 1.8">
<div style="line-height: 1.8">
<p class="title1">
<strong class="title2">姓名:</strong>
{{ item.realName }}
{{ labelData.realName }}
</p>
<p class="title1">
<strong class="title2">定位卡号:</strong>
{{ item.remark }}
{{ labelData.cardId }}
</p>
<p class="title1">
<strong class="title2">人员类型:</strong>
{{ getPersonTypeName(item.personType) }}
{{ getPersonTypeName(labelData.personType) }}
</p>
<p class="title1">
<strong class="title2">电话:</strong>
{{ item.phone }}
{{ labelData.phone }}
</p>
<p class="title1">
<strong class="title2">部门:</strong>
{{ item.deptName }}
{{ labelData.deptName }}
</p>
</div>
</div>
......@@ -705,79 +834,54 @@ onUnmounted(() => {
<div class="left-top">
<p class="title1">
<strong class="title2">车牌号:</strong>
{{ currentCar?.carNumber || '暂无数据' }}
{{ labelData.carNumber || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">车队名称:</strong>
{{ currentCar?.teamName || currentCar?.carName || '暂无数据' }}
{{ labelData.teamName || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">当前车速:</strong>
{{ currentCar?.speed || 0 }}km/h
{{ speed }} km/h
</p>
<p class="title1">
<strong class="title2">车辆类型:</strong>
{{ currentCar?.carType || '暂无数据' }}
{{ labelData.carType || '暂无数据' }}
</p>
</div>
<div class="left-center"></div>
<div class="left-bottom">
<p class="title1">
<strong class="title2">司机姓名:</strong>
{{ currentCar?.driverName || '暂无数据' }}
{{ labelData.driverName || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">工作开始时间:</strong>
{{ currentCar?.workStartTime || '暂无数据' }}
{{ labelData.workStartTime || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">工作时长:</strong>
{{ currentCar?.workDuration || '暂无数据' }}
{{ labelData.workTime || '暂无数据' }}
</p>
<p class="title1">
<strong class="title2">终端设备编号:</strong>
{{ currentCar?.deviceNo || '暂无数据' }}
{{ labelData.terminalNumber || '暂无数据' }}
</p>
</div>
</div>
<div class="car-right">
<!--
<video id="video" controls autoplay muted playsinline width="100%" height="100%"
style="object-fit: fill; z-index: 1;"></video>
-->
<div
:style="
full
? {
border: '1px solid #ccc',
padding: '2px',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100px',
zIndex: '99'
}
: {
padding: '2px',
height: '250px !important',
border: ' 1px solid #ccc',
position: 'relative',
margin: '0px 10px 0px 0px'
}
"
>
<div style="position: absolute; bottom: 5px; right: 5px; width: 40px; height: 40px; cursor: pointer">
<icon-gridicons-fullscreen-exit
v-if="full"
color="#11e0ff"
font-size="30"
@click="full = fullScreen(full)"
/>
<icon-gridicons-fullscreen v-else font-size="30" color="#11e0ff" @click="full = fullScreen(full)" />
</div>
<canvas id="canvas-4" style="width: 100%; height: 100%" width="800" height="600"></canvas>
</div>
<iframe
allowfullscreen="true"
allowtransparency="true"
allow="autoplay"
scrolling="no"
:src="link"
width="100%"
height="100%"
frameborder="0"
style="padding-right: 20px"
></iframe>
<!-- '${res.ipAddress}?lang=zh&devIdno=${res.cameraNo}&account=${res.username}&password=${res.password}&channel=1' -->
</div>
</div>
</div>
......@@ -799,27 +903,27 @@ onUnmounted(() => {
<div style="line-height: 1.8">
<p class="title1">
<strong class="title2">设备名称:</strong>
设备表面位移01
{{ labelData.equipname }}
</p>
<p class="title1">
<strong class="title2">设备状态:</strong>
在线/离线
{{ labelData.dataStatus === 0 ? '在线' : '离线' }}
</p>
<p class="title1">
<strong class="title2">设备类型:</strong>
表面位移/降雨量/环境监测
{{ text }}
</p>
<p class="title1">
<strong class="title2">监测值:</strong>
0.004mm
{{ labelData.value }}
</p>
<p class="title1">
<strong class="title2">监测时间:</strong>
2025-10 10:10:10
{{ labelData.time }}
</p>
<p class="title1">
<strong class="title2">数据状态:</strong>
正常
{{ labelData.onlineStatus === 0 ? '正常' : '蓝色报警' }}
</p>
</div>
</div>
......@@ -842,55 +946,28 @@ onUnmounted(() => {
<div class="video-top">
<div class="title3">
<strong class="title2">● 摄像头名称:</strong>
排土场入口
{{ labelData.areaName }}
</div>
<div class="title3">
<strong class="title4">● 区域名称:</strong>
排土场背部
{{ labelData.cameraName }}
</div>
<div class="title3">
<strong class="title4">● 设备状态:</strong>
在线/离线
{{ labelData.status === 0 ? '在线' : '离线' }}
</div>
</div>
<div class="video-bottom">
<!--
<NButton @click="login()">登陆</NButton>
<NButton @click="switchVideo()">切换视频流</NButton>
<div id="videoLayout" style="width: 500px; height: 250px; border: 1px solid red;"></div>
-->
<div
:style="
full
? {
border: '1px solid #ccc',
padding: '2px',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100px',
zIndex: '99'
}
: {
padding: '2px',
height: '250px !important',
border: ' 1px solid #ccc',
position: 'relative'
}
"
>
<div style="position: absolute; bottom: 5px; right: 5px; width: 40px; height: 40px; cursor: pointer">
<icon-gridicons-fullscreen-exit
v-if="full"
color="#11e0ff"
font-size="30"
@click="full = fullScreen(full)"
/>
<icon-gridicons-fullscreen v-else font-size="30" color="#11e0ff" @click="full = fullScreen(full)" />
</div>
<canvas id="canvas-4" style="width: 100%; height: 100%" width="800" height="600"></canvas>
</div>
<video
id="video"
controls
autoplay
muted
playsinline
width="100%"
height="100%"
style="object-fit: fill; z-index: 1"
></video>
</div>
</div>
</div>
......@@ -908,8 +985,8 @@ onUnmounted(() => {
</div>
</div>
<div class="bottom"></div>
<div class="left" v-show="isLeftModulesVisible"></div>
<div class="right" v-show="isRightModulesVisible"></div>
<div v-show="isLeftModulesVisible" class="left"></div>
<div v-show="isRightModulesVisible" class="right"></div>
<!-- 非cesium相关 开始 -->
......@@ -919,11 +996,6 @@ onUnmounted(() => {
<div>
<img :src="isLeftModulesVisible ? arrowLeftImg : arrowRightImg" alt="" srcset="" />
<br />
<!--
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
<br />
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
-->
<div class="arrow-font">
{{ isLeftModulesVisible ? '收起' : '展开' }}
</div>
......@@ -938,11 +1010,6 @@ onUnmounted(() => {
<div>
<img :src="isLeftModulesVisible ? arrowRightImg : arrowLeftImg" alt="" srcset="" />
<br />
<!--
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
<br />
<span class="arrow-font">{{ isLeftModulesVisible ? "" : "" }}</span>
-->
<div class="arrow-font">
{{ isLeftModulesVisible ? '收起' : '展开' }}
</div>
......@@ -952,7 +1019,7 @@ onUnmounted(() => {
<!-- 左侧模块容器 -->
<Transition name="slide-left">
<div class="left-modules" v-show="isLeftModulesVisible">
<div v-show="isLeftModulesVisible" class="left-modules">
<LeftDeviceStatus />
<LeftRainfallTrend />
<LeftOnlineMonitor />
......@@ -961,7 +1028,7 @@ onUnmounted(() => {
<!-- 右侧模块容器 -->
<Transition name="slide-right">
<div class="right-modules" v-show="isRightModulesVisible">
<div v-show="isRightModulesVisible" class="right-modules">
<RightAiWarning />
<RightEnvMonitor />
<RightTodayAlarm />
......@@ -977,6 +1044,7 @@ body {
height: 100%;
overflow: hidden;
}
.cesium-container {
width: 100%;
height: 100vh;
......@@ -1001,7 +1069,7 @@ body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -1018,7 +1086,7 @@ body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -1035,7 +1103,7 @@ body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -1052,7 +1120,7 @@ body {
pointer-events: auto;
z-index: 9999;
top: 100px;
left: 30%;
left: 20%;
background-image: url('@/assets/person2.png');
background-size: 100% 100%;
transform: translate(50%, 50%);
......@@ -1070,7 +1138,7 @@ body {
.title3 {
display: flex;
align-items: center;
margin: 0px 0px 8px 10px;
margin: 0px 0px 8px 0px;
}
.title4 {
......@@ -1109,6 +1177,10 @@ span {
/* margin-top: 20px; */
}
#video {
height: 250px;
}
.video-top {
width: 100%;
height: 50%;
......@@ -1161,6 +1233,7 @@ span {
:deep(.n-tag .n-tag__border) {
border: none;
}
:deep(.n-base-selection-tag-wrapper) {
background: #10273e00;
}
......@@ -1177,15 +1250,18 @@ span {
display: flex;
align-items: center;
justify-content: space-between;
.split-line {
width: 0.03rem;
height: 100%;
background: #11e0ff;
}
.baojing {
position: relative;
padding-left: 25px;
display: block;
&::before {
content: '';
position: absolute;
......@@ -1199,10 +1275,12 @@ span {
background-repeat: no-repeat;
}
}
.houtaiguanli {
position: relative;
padding-left: 25px;
display: block;
&::before {
content: '';
position: absolute;
......@@ -1225,6 +1303,7 @@ span {
position: absolute;
background-repeat: no-repeat;
}
.top {
top: 0;
width: 100%;
......@@ -1235,7 +1314,8 @@ span {
width: 100%;
height: 100%;
position: relative;
&>img{
& > img {
width: 100%;
}
......@@ -1244,11 +1324,14 @@ span {
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
width: 5.04rem; /* 可根据实际需要调整大小 */
height: 0.54rem; /* 可根据实际需要调整大小 */
width: 5.04rem;
/* 可根据实际需要调整大小 */
height: 0.54rem;
/* 可根据实际需要调整大小 */
}
}
}
.bottom {
bottom: 0;
left: 0;
......@@ -1257,6 +1340,7 @@ span {
background-image: url('@/assets/jinrun/bottom.png');
background-size: cover;
}
.left {
top: 0rem;
left: 0;
......@@ -1266,6 +1350,7 @@ span {
background-position-x: left;
background-image: url('@/assets/jinrun/bg-left.png');
}
.right {
top: 0rem;
right: 0;
......@@ -1294,17 +1379,21 @@ span {
transition: all 0.3s ease;
&.left-toggle {
left: 5rem; /* 与左侧模块宽度一致 */
left: 5rem;
/* 与左侧模块宽度一致 */
background-image: url('@/assets/jinrun/toggle-left.png');
}
&.left-toggle:hover {
background-image: url('@/assets/jinrun/toggle-left_click.png');
}
&.right-toggle {
right: 5rem; /* 与左侧模块宽度一致 */
right: 5rem;
/* 与左侧模块宽度一致 */
background-image: url('@/assets/jinrun/toggle-right.png');
}
&.right-toggle:hover {
background-image: url('@/assets/jinrun/toggle-right_click.png');
}
......@@ -1423,6 +1512,7 @@ span {
left: 0;
margin-left: 0.4rem;
}
.right-modules {
right: 0;
margin-right: 0.4rem;
......@@ -1435,4 +1525,28 @@ span {
display: flex;
flex-direction: column;
}
.video-container {
width: 100%;
height: 250px;
border: 1px solid #ccc;
background: #f5f5f5;
position: relative;
}
#divPlugin {
width: 100%;
height: 100%;
}
.status-info {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
}
</style>
......@@ -55,9 +55,9 @@ const bgColor = computed(() => {
<!-- <WaveBg class="box" /> -->
<NCard :bordered="false" class="relative z-4 w-auto rd-12px">
<div class="w-400px lt-sm:w-300px">
<header class="flex-y-center justify-between">
<header class="flex-x-center justify-between" style="display: flex;justify-content: center;">
<!-- <SystemLogo class="text-64px text-primary lt-sm:text-48px" /> -->
<h3 class="text-28px text-primary font-600 lt-sm:text-22px">{{ $t('system.title') }}</h3>
<h3 class="text-28px text-primary font-600 lt-sm:text-22px form-t">{{ $t('system.title') }}</h3>
<div class="i-flex-col">
<!-- <ThemeSchemaSwitch
:theme-schema="themeStore.themeScheme"
......@@ -65,17 +65,17 @@ const bgColor = computed(() => {
class="text-20px lt-sm:text-18px"
@switch="themeStore.toggleThemeScheme"
/> -->
<LangSwitch
<!-- <LangSwitch
v-if="themeStore.header.multilingual.visible"
:lang="appStore.locale"
:lang-options="appStore.localeOptions"
:show-tooltip="false"
@change-lang="appStore.changeLocale"
/>
/> -->
</div>
</header>
<main class="pt-24px">
<h3 class="text-18px text-primary font-medium">{{ $t(activeModule.label) }}</h3>
<h3 class="text-18px text-primary font-medium">账号登录</h3>
<div class="pt-24px">
<Transition :name="themeStore.page.animateMode" mode="out-in" appear>
<component :is="activeModule.component" />
......
<template>
<div class="captcha-container">
<canvas ref="canvasRef" @click="refreshCaptcha" width="120" height="39"></canvas>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
const canvasRef = ref(null);
const captchaText = ref('');
// 生成随机数字(默认4位)
const generateRandomDigits = (length = 4) => {
return Array.from({ length }, () => Math.floor(Math.random() * 10)).join('');
};
// 绘制验证码
const drawCaptcha = () => {
const canvas = canvasRef.value;
if (!canvas) return;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 生成新验证码
captchaText.value = generateRandomDigits();
// 背景色
ctx.fillStyle = '#f5f5f5';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制文字(随机位置、颜色、旋转)
for (let i = 0; i < captchaText.value.length; i++) {
ctx.font = 'bold 24px Arial';
ctx.fillStyle = getRandomColor();
ctx.save();
ctx.translate(10 + i * 30, 28);
ctx.rotate((Math.random() - 0.5) * 0.4);
ctx.fillText(captchaText.value[i], 0, 0);
ctx.restore();
}
// 绘制干扰线
for (let i = 0; i < 15; i++) {
ctx.strokeStyle = getRandomColor(300);
ctx.beginPath();
ctx.moveTo(
Math.random() * canvas.width,
Math.random() * canvas.height
);
ctx.lineTo(
Math.random() * canvas.width,
Math.random() * canvas.height
);
ctx.stroke();
}
};
// 随机颜色
const getRandomColor = (min = 50) => {
const r = min + Math.floor(Math.random() * (100 - min));
const g = min + Math.floor(Math.random() * (100 - min));
const b = min + Math.floor(Math.random() * (100 - min));
return `rgb(${r}, ${g}, ${b})`;
};
// 点击刷新
const refreshCaptcha = () => {
drawCaptcha();
};
// 初始化
onMounted(() => {
drawCaptcha();
});
// 暴露验证码文本(供父组件校验)
defineExpose({
captchaText,
});
</script>
<style scoped>
.captcha-container {
display: inline-block;
cursor: pointer;
}
canvas {
border: 1px solid #ddd;
border-radius: 4px;
}
.hint {
font-size: 12px;
color: #999;
text-align: center;
}
</style>
\ No newline at end of file
......@@ -6,9 +6,14 @@ import { api_loginPost } from '@/api';
import { useAuthStore } from '@/store/modules/auth';
import { useRouterPush } from '@/hooks/common/router';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import Captcha from '../modules/Captcha.vue';
import { localStg } from '@/utils/storage';
import { $t } from '@/locales';
import { useMessage } from 'naive-ui';
import { loginRules } from '@/rules/rules';
import { User } from '@vicons/fa';
import { IosLock } from '@vicons/ionicons4';
import { ShieldTask16Filled } from '@vicons/fluent'
defineOptions({
name: 'PwdLogin'
......@@ -21,21 +26,13 @@ const { formRef, validate } = useNaiveForm();
interface FormModel {
username: string;
password: string;
yzmcode: string;
}
const model: FormModel = reactive({
username: 'admin',
password: 'admin123'
});
const rules = computed<Record<keyof FormModel, App.Global.FormRule[]>>(() => {
const { formRules } = useFormRules();
return {
username: formRules.username,
password: formRules.pwd
};
username: '',
password: '',
yzmcode:''
});
async function handleSubmit() {
......@@ -61,12 +58,10 @@ async function handleSubmit() {
}
</script>
<template>
<NForm ref="formRef" :model="model" :rules="rules" size="large" :show-label="false" @keyup.enter="handleSubmit">
<NForm ref="formRef" :model="model" :rules="loginRules" size="large" :show-label="false" @keyup.enter="handleSubmit">
<NFormItem path="username">
<NInput v-model:value="model.username" :placeholder="$t('page.login.common.userNamePlaceholder')" />
</NFormItem>
......@@ -78,6 +73,22 @@ async function handleSubmit() {
:placeholder="$t('page.login.common.passwordPlaceholder')"
/>
</NFormItem>
<NFormItem path="yzmcode">
<n-row>
<n-col :span = "16">
<NInput class="itemCode" v-model:value="model.yzmcode" show-password-on="click"
:placeholder="'请输入验证码'">
</NInput>
</n-col>
<n-col :span = "6">
<div style="margin-left: 10px;">
<Captcha ref="captchaRef" />
</div>
</n-col>
</n-row>
</NFormItem>
<NSpace vertical :size="24">
<NButton type="primary" size="large" round block :loading="authStore.loginLoading" @click="handleSubmit">
{{ $t('common.confirm') }}
......
......@@ -13,7 +13,7 @@ onMounted(async () => {
</script>
<template>
<iframe src="http://192.168.2.54:9528/large" frameborder="0"></iframe>
<iframe allowfullscreen="true" allowtransparency="true" allow="autoplay" scrolling="no" src="http://192.168.2.54:9528/large" frameborder="0"></iframe>
</template>
<style scoped></style>
\ No newline at end of file
......@@ -13,7 +13,7 @@ onMounted(async () => {
</script>
<template>
<iframe src="http://192.168.2.54:9528/camera" frameborder="0"></iframe>
<iframe allowfullscreen="true" allowtransparency="true" allow="autoplay" scrolling="no" src="http://192.168.2.54:9528/camera" frameborder="0"></iframe>
</template>
<style scoped></style>
......@@ -197,9 +197,11 @@ const treeData = ref<any>([])
watch(posArr.value, async (val, old) => {
if (!formData.value.rangeType) {
if(!showModal) {
message.info('请先选取围栏类型后在进行操作')
return
}
}
if (pins.length > 0) {
handlerClean();
pins = [];
......
<template>
<div>表面位移</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/dataMonitor/bmwy/history" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>降雨量</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/dataMonitor/jyl/history" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>可视化大屏</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/index" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>监测值录入</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/personMonitor/valueInput" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>监测点管理</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/personMonitor/monitorPoints" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>报警列表</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/alarmManage/history" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>预警值设置</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/alarmManage/warning" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>检查项管理</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/personInspection/checkItem" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>检查结果录入</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/personInspection/checkResult" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>检查项类型管理</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/personInspection/checkMode" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>设备管理</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/system/deviceManage" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>首页模块管理</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/system/monitorItems" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>模块化数据配置</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/system/moduleConfig" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
<template>
<div>监测点配置</div>
<iframe style="width: 100%; height: 100%;" src="http://192.168.2.15:84/system/monitorPointConfig" frameborder="0"></iframe>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { api_tokenGet } from '@/api';
import { useMessage } from 'naive-ui';
import { onMounted } from 'vue';
<style scoped>
</style>
\ No newline at end of file
onMounted(async () => {
const message = useMessage();
let res = await api_tokenGet()
if (res.data.code == 401) {
message.error('登录过期');
}
})
</script>
<style scoped></style>
\ No newline at end of file
......@@ -145,7 +145,6 @@ function selectChange(item:any) {
}
function handleSearch() {
console.log(personValue.value);
if(personValue.value == '') {
message.info('请选择您要查询的人员');
return;
......@@ -162,6 +161,7 @@ function handleReset() {
entity.billboard.image = bluePersonIcon;
}
});
value.value = null;
personList.value = [];
personShow.value = false;
message.success('重置成功');
......@@ -240,6 +240,7 @@ onMounted(() => {
phone: pickedObject.id.personData.info.phone,
deptName: pickedObject.id.personData.info.deptName,
personType: pickedObject.id.personData.info.personType,
cardId: pickedObject.id.personData.info.cardId,
})
}
......@@ -292,7 +293,7 @@ onMounted(() => {
</div>
<div style="line-height: 1.8;" v-for="item in personList">
<p class="title1"><strong class="title2">姓名:</strong> {{ item.realName }}</p>
<p class="title1"><strong class="title2">定位卡号:</strong> {{ item.remark }}</p>
<p class="title1"><strong class="title2">定位卡号:</strong> {{ item.cardId }}</p>
<p class="title1"><strong class="title2">人员类型:</strong> {{ getPersonTypeName(item.personType) }}</p>
<p class="title1"><strong class="title2">电话:</strong> {{item.phone}}</p>
<p class="title1"><strong class="title2">部门:</strong> {{item.deptName}}</p>
......
<template>
<div>人员分布统计</div>
<iframe src="http://192.168.2.11/tongji/fenbu" frameborder="0"></iframe>
</template>
<script lang="ts" setup>
......
<script lang="ts" setup>
import { h, onMounted, ref, watch } from 'vue';
import { NButton, NSelect, NSpace, useMessage } from 'naive-ui';
import { Pause } from '@vicons/ionicons5';
import { PlayCircle48Regular } from '@vicons/fluent';
import { create3D } from '@/api/utils/cesium';
import { createModel, createPolyLine, getElevationFromRay, startVehicleMovement, cleanLine, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { remove } from 'nprogress';
import { toConvertLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { getModelAllApi, getPersonPointApi } from '@/api';
let viewer: any = null;
const range = ref<any>(null);
const personValue = ref('');
const serarchData = ref({
username: '',
startTime: '',
endTime: ''
});
const isShow = ref(false);
const value = ref(null);
const options = ref();
const message = useMessage();
// 进度条相关状态
const speed = ref('1x');
const speedOptions = [
{ label: '1x', value: '50' },
{ label: '10x', value: '100' },
{ label: '20x', value: '200' },
{ label: '30x', value: '300' },
];
const elapsedSeconds = ref(0);
const position = ref([])
// zhangyang
const positions = ref<any[]>([]);
const lineValue = ref<any>();
const model = ref<any>();
const progressFill = ref<HTMLDListElement | null>(null);
let totalSeconds = 3600;
let stepPercent = 100 / totalSeconds;
let currentProgress: any = 0;
let elapsed = 0;
let intervalId: any = null;
// 修改为响应式变量,用于记录暂停状态
const pausedPosition = ref(null);
const remainingSeconds = ref(0);
const isPaused = ref(false);
// 禁用超出一小时范围的日期选择
function disabledDate(current: number, type: string) {
// 如果是日期范围选择器的结束日期,并且已经选择了开始日期
if (type === 'end' && range.value && range.value[0]) {
const startDate = new Date(range.value[0]);
const minEndDate = new Date(startDate);
const maxEndDate = new Date(startDate);
// 设置最大结束时间为开始时间加1小时
maxEndDate.setHours(maxEndDate.getHours() + 1);
// 禁用超出一小时范围的日期
return current > maxEndDate.getTime();
}
return false;
}
// 更新进度
function updateProgress() {
if (elapsed >= totalSeconds) return;
elapsed++;
if (elapsed === totalSeconds) currentProgress = 100;
progressFill.value.style.width = `${currentProgress}%`;
stepPercent = 100 / totalSeconds;
currentProgress += stepPercent;
if (currentProgress > 99) {
isShow.value = false;
}
if (elapsed >= totalSeconds) {
pauseProgress();
resetProgress();
}
}
// 开始进度
function startProgress() {
if(!model.value && !lineValue.value){
message.warning("请选择指定车辆和时间")
}
if (viewer.clock.shouldAnimate) {
// 暂停状态
isShow.value = false;
viewer.clock.shouldAnimate = false;
pauseProgress();
isPaused.value = true;
pausedPosition.value = viewer.clock.currentTime; // 保存当前时间位置
} else if (model.value && lineValue.value) {
isShow.value = true;
// 开始或恢复播放
if (isPaused.value) {
// 从暂停状态恢复,不重置任何进度
viewer.clock.shouldAnimate = true;
if (intervalId) return;
intervalId = setInterval(updateProgress, 1000);
isPaused.value = false;
} else {
// 全新开始
totalSeconds = totalSeconds / speed.value;
startVehicleMovement(viewer, totalSeconds);
if (intervalId) return;
if (elapsed >= totalSeconds) return;
intervalId = setInterval(updateProgress, 1000);
}
}
}
function resetProgress() {
pauseProgress();
stepPercent = 100 / totalSeconds;
currentProgress = 0;
elapsed = 0;
// UI 归零
setTimeout(() => {
progressFill.value.style.width = '0%';
}, 500)
}
// 暂停进度
function pauseProgress() {
if (!intervalId) return;
clearInterval(intervalId);
intervalId = null;
}
// 监听选取的人员
function selectChange(item:any) {
personValue.value = item;
}
// 监听时间范围变化
function watchTimeData(newRange: any) {
if (newRange && newRange.length === 2) {
const startDate = new Date(newRange[0]);
const endDate = new Date(newRange[1]);
// 计算时间差(毫秒)
const durationMs = endDate.getTime() - startDate.getTime();
const durationHours = durationMs / (1000 * 60 * 60);
// 如果超出一小时,给出提示
if (durationHours > 1) {
message.warning('时间范围不能超过一小时,请重新选择');
range.value = null;
serarchData.value.startTime = '';
serarchData.value.endTime = '';
return;
}
serarchData.value.startTime = newRange[0];
serarchData.value.endTime = newRange[1];
// 计算总时长(毫秒转秒)
const durationMs1 = endDate.getTime() - startDate.getTime();
totalSeconds = Math.floor(durationMs1 / 1000);
elapsedSeconds.value = 0;
updateProgress();
}
}
function add3dtiles() {
const CesiumConfig = {
defaultAccessToken:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NTE1OTUxOS1jNTc5LTQwNmMtOWU5My1jNTI3NTIyYzAxNTUiLCJpZCI6MjUwODM5LCJpYXQiOjE3Mjk5MjE1MzV9.xromwPD3oA1e0YsWV035DE5KmYvivkC6fxt344vwObA'
};
Cesium.Ion.defaultAccessToken = CesiumConfig.defaultAccessToken;
viewer = new Cesium.Viewer('cesiumcontainer', {
geocoder: false,
homeButton: false,
infoBox: false,
animation: false,
fullscreenButton: false,
enableCompass: true, // 启用指南针
enableCompassOuterRing: true, // 启用指南针外环
sceneModePicker: false,
timeline: false,
navigationHelpButton: false,
baseLayerPicker: false,
enableZoomControls: false, // 禁用缩放控件
enableDistanceLegend: false // 禁用比例尺
});
viewer.scene.globe.depthTestAgainstTerrain = true;
viewer.scene.globe.depthTestAgainstTerrain = true;
viewer.cesiumWidget.creditContainer.style.display = 'none';
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
getModel().then(item => {
create3D(viewer, item, 0);
});
}
function handleclear() {
serarchData.value.startTime = '';
serarchData.value.endTime = '';
}
function handleReset() {
isShow.value = false;
//删除模型
if (model.value) {
viewer.entities.remove(model.value);
}
viewer.entities.remove(positions.value);
serarchData.value.startTime = '';
serarchData.value.endTime = '';
//进度条清空
resetProgress();
value.value = null;
range.value = null;
//删除线
cleanLine(viewer, positions.value);
personValue.value = '';
positions.value = [];
lineValue.value = [];
}
function handlerClean() {
isShow.value = false;
//删除模型
if (model.value) {
viewer.entities.remove(model.value);
}
//进度条清空
resetProgress();
//删除线
cleanLine(viewer, positions.value);
viewer.entities.remove(positions.value);
positions.value = [];
lineValue.value = [];
}
function selectSpeed(e) {
speed.value = e;
totalSeconds = 3600 / Number(e);
isShow.value = false;
// 重置所有进度相关变量
resetProgress();
// 确保viewer.clock处于正确状态
if (viewer) {
viewer.clock.shouldAnimate = false;
viewer.clock.currentTime = Cesium.JulianDate.now();
}
// 移除并重新创建模型
if (model.value) {
viewer.entities.remove(model.value);
model.value = null;
}
// 确保positions数组有数据才创建模型
if (positions.value && positions.value.length > 0) {
model.value = createModel(positions.value, viewer);
// 确保路线也存在
if (!lineValue.value && positions.value.length >= 2) {
lineValue.value = createPolyLine(positions.value, viewer);
}
// 手动触发开始进度,确保车辆开始移动
// setTimeout(() => {
if (model.value && lineValue.value) {
// 重置isPaused状态,确保是全新开始
isPaused.value = false;
// 直接调用startVehicleMovement开始车辆移动
startVehicleMovement(viewer, totalSeconds);
// 启动进度条更新
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(updateProgress, 1000);
// 更新UI状态
isShow.value = true;
}
// }, 100);
}
}
async function handleSearch() {
handlerClean()
if (serarchData.value.startTime && serarchData.value.endTime) {
let data = {
cardId: personValue.value,
startTime: serarchData.value.startTime,
endTime: serarchData.value.endTime
}
let res = await getPersonPointApi(data);
if(res.data.code == 200) {
for(let item of res.data.data){
const cartographic = Cesium.Cartographic.fromDegrees(item.lon, item.lat);
const height = await getElevationFromRays(cartographic, viewer);
const adjustedHeight = height;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
positions.value.push(cartesian)
}
model.value = createModel(positions.value, viewer);
undataLine();
} else {
message.error(res.data.msg);
}
} else {
message.info('请先选择您要看的时间点');
}
}
// 添加开始和结束时间显示
function formatDateTime(date: any) {
if (!date) return '';
const d = new Date(date);
return d.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
}
async function undataLine() {
lineValue.value = createPolyLine(positions.value, viewer);
}
async function search() {
let res = await getModelAllApi();
options.value = res.data.data;
}
onMounted(() => {
add3dtiles();
updateProgress();
search();
});
</script>
<template>
<div class="track-page">
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center">
<NSpace>
<div style="display: flex; align-items: center">
人员姓名
<NSpace vertical style="width: 200px; margin-left: 10px">
<NSelect v-model:value="value" :options="options" label-field="realName" value-field="cardId" @update:value="selectChange" />
</NSpace>
</div>
<div style="display: flex; align-items: center; margin-left: 30px">
<NDatePicker v-model:value="range" type="datetimerange" clearable style="margin-left: 10px"
:disabled-date="disabledDate" @update:value="watchTimeData" @clear="handleclear" />
</div>
<NButton color="#2198f2" style="padding: 0px 17px; border-radius: 5px; margin-left: 40px" @click="handleSearch">
查询
</NButton>
<NButton style="padding: 0px 17px; border-radius: 5px" @click="handleReset">重置</NButton>
</NSpace>
</div>
<!-- cesium -->
<div id="cesiumcontainer">
<div class="progress-container">
<!-- 添加开始和结束时间显示 -->
<div class="time-range-display">
<div class="start-time">{{ formatDateTime(serarchData.startTime) }}</div>
<div class="end-time">{{ formatDateTime(serarchData.endTime) }}</div>
</div>
<div class="left-controls">
<NIcon v-if="!isShow" class="control-btn" size="35px" @click="startProgress()">
<PlayCircle48Regular />
</NIcon>
<NIcon v-if="isShow" class="control-btn" size="35px" @click="startProgress()">
<Pause />
</NIcon>
</div>
<!-- 进度条 -->
<div class="progress-bar">
<div ref="progressFill" class="progress-fill"></div>
<div class="progress-dots">
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
<div class="progress-dot"></div>
</div>
<div id="progressText" class="progress-text"></div>
</div>
<div class="progress-time">60分</div>
<div class="right-controls">
<NSelect v-model:value="speed" :options="speedOptions" style="width: 80px; margin-left: 10px"
@update:value="selectSpeed" />
</div>
</div>
</div>
</div>
</template>
<style scoped>
#home {
width: 100%;
height: 100%;
}
#cesiumcontainer {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
box-sizing: border-box;
contain: strict;
isolation: isolate;
}
.progress-container {
position: absolute;
width: 100%;
height: 100px;
background-color: rgba(0, 0, 0, 0.85);
top: 90%;
z-index: 3;
}
.progress-bar {
width: 85%;
height: 15px;
background: rgba(46, 46, 46);
border-radius: 15px;
overflow: hidden;
margin-bottom: 10px;
position: relative;
margin-left: 80px;
margin-top: 40px;
display: flex;
align-items: center;
}
.progress-dots {
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: space-around;
align-items: center;
padding: 0 5%;
box-sizing: border-box;
pointer-events: none;
}
.progress-dot {
width: 12px;
height: 12px;
background-image: url('@/assets/dian.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #00c6ff, #0072ff);
transition: width 0.3s ease;
border-radius: 15px;
box-shadow: 0 0 15px rgba(0, 114, 255, 0.5);
}
.progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-weight: bold;
font-size: 14px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
.left-controls {
position: absolute;
color: white;
margin: 30px 0 0 30px;
}
.right-controls {
position: absolute;
top: 30px;
left: 94%;
}
.progress-time {
position: absolute;
top: 35px;
left: 90%;
color: white;
}
.time-range-display {
height: 0px;
display: flex;
justify-content: space-between;
padding: 0px 205px 0px 80px;
color: #e8e8e7;
font-size: 14px;
}
.start-time {
text-align: left;
margin-top: 10px;
}
.end-time {
text-align: right;
margin-top: 10px;
}
.control-btn {
border: none;
color: white;
font-size: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
</style>
......@@ -4,7 +4,7 @@ import { NButton, NSelect, NSpace, useMessage } from 'naive-ui';
import { Pause } from '@vicons/ionicons5';
import { PlayCircle48Regular } from '@vicons/fluent';
import { create3D } from '@/api/utils/cesium';
import { createModel, createPolyLine, getElevationFromRay, startVehicleMovement, cleanLine, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { createModel, createPolyLine, getElevationFromRay, startVehicleMovement, cleanLine, getElevationFromRays, createNewPositionHeight } from '@/api/utils/cesiumUtil';
import { remove } from 'nprogress';
import { toConvertLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
......@@ -18,19 +18,18 @@ const serarchData = ref({
startTime: '',
endTime: ''
});
const cesiumShow = ref(false)
const isShow = ref(false);
const value = ref(null);
const options = ref();
const message = useMessage();
// 进度条相关状态
const speed = ref('1x');
const speed = ref('50');
const speedOptions = [
{ label: '1x', value: '50' },
{ label: '10x', value: '100' },
{ label: '20x', value: '180' },
{ label: '30x', value: '280' },
{ label: '40x', value: '380' },
{ label: '50x', value: '450' },
{ label: '20x', value: '200' },
{ label: '30x', value: '300' }
];
const elapsedSeconds = ref(0);
const position = ref([])
......@@ -77,6 +76,7 @@ function updateProgress() {
if (elapsed === totalSeconds) currentProgress = 100;
progressFill.value.style.width = `${currentProgress}%`;
stepPercent = 100 / totalSeconds;
currentProgress += stepPercent;
if (currentProgress > 99) {
......@@ -91,6 +91,9 @@ function updateProgress() {
// 开始进度
function startProgress() {
if (!model.value && !lineValue.value) {
message.warning("请选择指定车辆和时间")
}
if (viewer.clock.shouldAnimate) {
// 暂停状态
isShow.value = false;
......@@ -109,7 +112,9 @@ function startProgress() {
isPaused.value = false;
} else {
// 全新开始
totalSeconds = 3600 / Number(speed.value);
startVehicleMovement(viewer, totalSeconds);
if (intervalId) return;
if (elapsed >= totalSeconds) return;
intervalId = setInterval(updateProgress, 1000);
......@@ -125,7 +130,7 @@ function resetProgress() {
// UI 归零
setTimeout(() => {
progressFill.value.style.width = '0%';
}, 500)
}, 100)
}
// 暂停进度
......@@ -136,7 +141,7 @@ function pauseProgress() {
}
// 监听选取的人员
function selectChange(item:any) {
function selectChange(item: any) {
personValue.value = item;
}
// 监听时间范围变化
......@@ -229,6 +234,21 @@ function handleReset() {
lineValue.value = [];
}
function handlerClean() {
isShow.value = false;
//删除模型
if (model.value) {
viewer.entities.remove(model.value);
}
//进度条清空
resetProgress();
//删除线
cleanLine(viewer, positions.value);
viewer.entities.remove(positions.value);
positions.value = [];
lineValue.value = [];
}
function selectSpeed(e) {
speed.value = e;
totalSeconds = 3600 / Number(e);
......@@ -258,7 +278,6 @@ function selectSpeed(e) {
}
// 手动触发开始进度,确保车辆开始移动
// setTimeout(() => {
if (model.value && lineValue.value) {
// 重置isPaused状态,确保是全新开始
isPaused.value = false;
......@@ -272,24 +291,57 @@ function selectSpeed(e) {
// 更新UI状态
isShow.value = true;
}
// }, 100);
}
}
async function handleSearch() {
handlerClean()
if (serarchData.value.startTime && serarchData.value.endTime) {
cesiumShow.value = true;
let data = {
cardId: personValue.value,
startTime: serarchData.value.startTime,
endTime: serarchData.value.endTime
}
let resHeight = null;
let res = await getPersonPointApi(data);
position.value = res.data.data;
undataLine();
model.value = createModel(positions.value, viewer);
if (res.data.code == 200) {
for (let item of res.data.data) {
const cartographic = Cesium.Cartographic.fromDegrees(item.lon, item.lat);
const height = await getElevationFromRays(cartographic, viewer);
const adjustedHeight = height;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
if (resHeight != null) {
let dataHeight = Number(height) - Number(resHeight);
if (dataHeight < 0.5) {
positions.value.push(cartesian);
}
} else {
positions.value.push(cartesian);
}
resHeight = height;
}
let newPositions = await createNewPositionHeight(positions.value, viewer)
model.value = createModel(newPositions, viewer);
undataLine(newPositions);
cesiumShow.value = false;
} else {
message.error(res.data.msg)
cesiumShow.value = false;
}
} else {
message.info('请先选择您要看的时间点');
}
}
// watch([model, lineValue], ([newModel, newLineValue], [oldModel, oldLineValue]) => {
// if (newModel && newLineValue) {
// cesiumShow.value = false;
// } else {
// cesiumShow.value = true;
// }
// });
// 添加开始和结束时间显示
function formatDateTime(date: any) {
if (!date) return '';
......@@ -303,17 +355,8 @@ function formatDateTime(date: any) {
});
}
async function undataLine() {
for (let i = 0; i < position.value.length; i++) {
const cartographic = Cesium.Cartographic.fromDegrees(position.value[i].lon, position.value[i].lat);
const height = await getElevationFromRays(cartographic, viewer);
const adjustedHeight = height;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
positions.value.push(cartesian);
}
lineValue.value = createPolyLine(positions.value, viewer);
function undataLine(newPositions: any) {
lineValue.value = createPolyLine(newPositions, viewer);
}
async function search() {
......@@ -323,7 +366,9 @@ async function search() {
onMounted(() => {
add3dtiles();
setTimeout(() => {
updateProgress();
}, 2000);
search();
});
</script>
......@@ -335,7 +380,8 @@ onMounted(() => {
<div style="display: flex; align-items: center">
人员姓名
<NSpace vertical style="width: 200px; margin-left: 10px">
<NSelect v-model:value="value" :options="options" label-field="realName" value-field="cardId" @update:value="selectChange" />
<NSelect v-model:value="value" :options="options" label-field="realName" value-field="cardId"
@update:value="selectChange" />
</NSpace>
</div>
<div style="display: flex; align-items: center; margin-left: 30px">
......@@ -350,6 +396,12 @@ onMounted(() => {
</NSpace>
</div>
<n-spin class="spinDiv" v-show="cesiumShow">
<template #description>
<span style="color: #2198f2;">加载中...</span>
</template>
</n-spin>
<!-- cesium -->
<div id="cesiumcontainer">
<div class="progress-container">
......@@ -522,4 +574,12 @@ onMounted(() => {
justify-content: center;
transition: all 0.3s ease;
}
.spinDiv{
width: 87%;
height: 80%;
position: absolute;
top: 169px;
z-index: 999;
background-color: #2e2e2e67;
}
</style>
\ No newline at end of file
<script lang="ts" setup>
import { h, onMounted, ref, watch } from 'vue';
import { NButton, NSelect, NSpace, useMessage } from 'naive-ui';
import { Pause } from '@vicons/ionicons5';
import { PlayCircle48Regular } from '@vicons/fluent';
import { create3D } from '@/api/utils/cesium';
import { createModel, createPolyLine, getElevationFromRay, startVehicleMovement, cleanLine, getElevationFromRays } from '@/api/utils/cesiumCarsUtil';
import { remove } from 'nprogress';
import { toConvertLongitudeAndLatitude } from '@/api/utils/cesiumCarUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { getModelAllApi, getPersonPointApi } from '@/api';
let viewer: any = null;
const range = ref<any>(null);
const personValue = ref('');
const serarchData = ref({
import { h, onMounted, ref, watch } from 'vue';
import { NButton, NSelect, NSpace, useMessage } from 'naive-ui';
import { Pause } from '@vicons/ionicons5';
import { PlayCircle48Regular } from '@vicons/fluent';
import { create3D } from '@/api/utils/cesium';
import { createModel, createPolyLine, getElevationFromRay, startVehicleMovement, cleanLine, getElevationFromRays, createNewPositionHeight } from '@/api/utils/cesiumCarsUtil';
import { remove } from 'nprogress';
import { toConvertLongitudeAndLatitude } from '@/api/utils/cesiumCarUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { getCarPointApi, getCarPointCarNumberApi, getModelAllApi, getPersonPointApi } from '@/api';
import { toProjectionCoordinates } from '@/api/utils/coordinateUtil';
let viewer: any = null;
const range = ref<any>(null);
const personValue = ref('');
const cesiumShow = ref(false)
const serarchData = ref({
username: '',
startTime: '',
endTime: ''
});
const isShow = ref(false);
const value = ref(null);
const options = ref();
const message = useMessage();
// 进度条相关状态
const speed = ref('1x');
const speedOptions = [
});
const isShow = ref(false);
const value = ref(null);
const options = ref();
const message = useMessage();
// 进度条相关状态
const speed = ref('50');
const speedOptions = [
{ label: '1x', value: '50' },
{ label: '10x', value: '100' },
{ label: '20x', value: '200' },
{ label: '30x', value: '300' },
{ label: '40x', value: '400' },
{ label: '50x', value: '500' },
];
const elapsedSeconds = ref(0);
const position = ref([])
// zhangyang
const positions = ref<any[]>([]);
const lineValue = ref<any>();
const model = ref<any>();
const progressFill = ref<HTMLDListElement | null>(null);
let totalSeconds = 3600;
let stepPercent = 100 / totalSeconds;
let currentProgress: any = 0;
let elapsed = 0;
let intervalId: any = null;
// 修改为响应式变量,用于记录暂停状态
const pausedPosition = ref(null);
const remainingSeconds = ref(0);
const isPaused = ref(false);
// 禁用超出一小时范围的日期选择
function disabledDate(current: number, type: string) {
];
const elapsedSeconds = ref(0);
const position = ref([])
// zhangyang
const positions = ref<any[]>([]);
const lineValue = ref<any>();
const model = ref<any>();
const progressFill = ref<HTMLDListElement | null>(null);
let totalSeconds = 3600;
let stepPercent = 100 / totalSeconds;
let currentProgress: any = 0;
let elapsed = 0;
let intervalId: any = null;
// 修改为响应式变量,用于记录暂停状态
const pausedPosition = ref(null);
const remainingSeconds = ref(0);
const isPaused = ref(false);
// 禁用超出一小时范围的日期选择
function disabledDate(current: number, type: string) {
// 如果是日期范围选择器的结束日期,并且已经选择了开始日期
if (type === 'end' && range.value && range.value[0]) {
const startDate = new Date(range.value[0]);
......@@ -67,16 +67,18 @@
return current > maxEndDate.getTime();
}
return false;
}
}
// 更新进度
function updateProgress() {
// 更新进度
function updateProgress() {
if (elapsed >= totalSeconds) return;
elapsed++;
if (elapsed === totalSeconds) currentProgress = 100;
progressFill.value.style.width = `${currentProgress}%`;
stepPercent = 100 / totalSeconds;
currentProgress += stepPercent;
......@@ -88,10 +90,14 @@
pauseProgress();
resetProgress();
}
}
// 开始进度
function startProgress() {
if (!model.value && !lineValue.value) {
message.warning("请选择指定车辆和时间")
}
// 开始进度
function startProgress() {
if (viewer.clock.shouldAnimate) {
// 暂停状态
isShow.value = false;
......@@ -109,6 +115,7 @@
intervalId = setInterval(updateProgress, 1000);
isPaused.value = false;
} else {
totalSeconds = 3600 / Number(speed.value)
// 全新开始
startVehicleMovement(viewer, totalSeconds);
if (intervalId) return;
......@@ -116,9 +123,9 @@
intervalId = setInterval(updateProgress, 1000);
}
}
}
}
function resetProgress() {
function resetProgress() {
pauseProgress();
stepPercent = 100 / totalSeconds;
currentProgress = 0;
......@@ -126,22 +133,24 @@
// UI 归零
setTimeout(() => {
progressFill.value.style.width = '0%';
}, 500)
}
}, 100)
}
// 暂停进度
function pauseProgress() {
// 暂停进度
function pauseProgress() {
if (!intervalId) return;
clearInterval(intervalId);
intervalId = null;
}
}
// 监听选取的人员
function selectChange(item: any) {
console.log(item);
// 监听选取的人员
function selectChange(item:any) {
personValue.value = item;
}
// 监听时间范围变化
function watchTimeData(newRange: any) {
}
// 监听时间范围变化
function watchTimeData(newRange: any) {
if (newRange && newRange.length === 2) {
const startDate = new Date(newRange[0]);
const endDate = new Date(newRange[1]);
......@@ -168,9 +177,9 @@
elapsedSeconds.value = 0;
updateProgress();
}
}
}
function add3dtiles() {
function add3dtiles() {
const CesiumConfig = {
defaultAccessToken:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NTE1OTUxOS1jNTc5LTQwNmMtOWU5My1jNTI3NTIyYzAxNTUiLCJpZCI6MjUwODM5LCJpYXQiOjE3Mjk5MjE1MzV9.xromwPD3oA1e0YsWV035DE5KmYvivkC6fxt344vwObA'
......@@ -202,19 +211,18 @@
getModel().then(item => {
create3D(viewer, item, 0);
});
}
}
function handleclear() {
function handleclear() {
serarchData.value.startTime = '';
serarchData.value.endTime = '';
}
}
function handleReset() {
function handleReset() {
isShow.value = false;
//删除模型
if (model.value) {
viewer.entities.remove(model.value);
}
//进度条清空
resetProgress();
......@@ -225,10 +233,25 @@
viewer.entities.remove(positions.value);
positions.value = [];
lineValue.value = [];
}
function handlerClean() {
isShow.value = false;
//删除模型
if (model.value) {
viewer.entities.remove(model.value);
}
//进度条清空
resetProgress();
//删除线
cleanLine(viewer, positions.value);
viewer.entities.remove(positions.value);
positions.value = [];
lineValue.value = [];
}
function selectSpeed(e) {
function selectSpeed(e) {
speed.value = e;
totalSeconds = 3600 / Number(e);
isShow.value = false;
......@@ -273,24 +296,59 @@
}
// }, 100);
}
}
async function handleSearch() {
}
async function handleSearch() {
handlerClean()
if (serarchData.value.startTime && serarchData.value.endTime) {
cesiumShow.value = true;
let data = {
cardId: personValue.value,
carNumber: personValue.value,
startTime: serarchData.value.startTime,
endTime: serarchData.value.endTime
}
let res = await getPersonPointApi(data);
position.value = res.data.data;
undataLine();
model.value = createModel(positions.value, viewer);
let resHeight = null;
let res = await getCarPointApi(data);
if (res.data.code == 200) {
for (let item of res.data.data) {
const cartographic = Cesium.Cartographic.fromDegrees(item.lon, item.lat);
const height = await getElevationFromRays(cartographic, viewer);
const adjustedHeight = height;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
if (resHeight != null) {
let dataHeight = Number(height) - Number(resHeight);
if (dataHeight < 0.5) {
positions.value.push(cartesian);
}
} else {
message.info('请先选择您要看的时间点');
positions.value.push(cartesian);
}
resHeight = height;
}
// 添加开始和结束时间显示
function formatDateTime(date: any) {
let newPositions = await createNewPositionHeight(positions.value, viewer)
model.value = createModel(newPositions, viewer);
undataLine(newPositions);
cesiumShow.value = false;
} else {
message.error(res.data.msg);
cesiumShow.value = false;
}
} else {
message.info('请先选择您要看的时间点');
}
}
// watch([model.value, lineValue.value], ([newModel, newLineValue], [oldModel, oldLineValue]) => {
// if (newModel && newLineValue) {
// cesiumShow.value = false;
// } else {
// cesiumShow.value = true;
// }
// },{ deep: true });
// 添加开始和结束时间显示
function formatDateTime(date: any) {
if (!date) return '';
const d = new Date(date);
return d.toLocaleString('zh-CN', {
......@@ -300,39 +358,33 @@
hour: '2-digit',
minute: '2-digit'
});
}
}
async function undataLine() {
for (let i = 0; i < position.value.length; i++) {
const cartographic = Cesium.Cartographic.fromDegrees(position.value[i].lon, position.value[i].lat);
const height = await getElevationFromRays(cartographic, viewer);
const adjustedHeight = height;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
positions.value.push(cartesian);
}
lineValue.value = createPolyLine(positions.value, viewer);
}
async function undataLine(newPositions: any) {
lineValue.value = createPolyLine(newPositions, viewer);
}
async function search() {
let res = await getModelAllApi();
async function search() {
let res = await getCarPointCarNumberApi();
options.value = res.data.data;
}
}
onMounted(() => {
onMounted(() => {
add3dtiles();
updateProgress();
search();
});
</script>
});
</script>
<template>
<template>
<div class="track-page">
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center">
<NSpace>
<div style="display: flex; align-items: center">
车牌号
<NSpace vertical style="width: 200px; margin-left: 10px">
<NSelect v-model:value="value" :options="options" label-field="realName" value-field="cardId" @update:value="selectChange" />
<NSelect v-model:value="value" :options="options" label-field="carNumber" value-field="carNumber"
@update:value="selectChange" />
</NSpace>
</div>
<div style="display: flex; align-items: center; margin-left: 30px">
......@@ -346,7 +398,12 @@
<NButton style="padding: 0px 17px; border-radius: 5px" @click="handleReset">重置</NButton>
</NSpace>
</div>
<!-- 加载中 -->
<n-spin class="spinDiv" v-show="cesiumShow">
<template #description>
<span style="color: #2198f2;">加载中...</span>
</template>
</n-spin>
<!-- cesium -->
<div id="cesiumcontainer">
<div class="progress-container">
......@@ -390,15 +447,15 @@
</div>
</div>
</div>
</template>
</template>
<style scoped>
#home {
<style scoped>
#home {
width: 100%;
height: 100%;
}
}
#cesiumcontainer {
#cesiumcontainer {
width: 100%;
height: 100%;
position: relative;
......@@ -406,18 +463,18 @@
box-sizing: border-box;
contain: strict;
isolation: isolate;
}
}
.progress-container {
.progress-container {
position: absolute;
width: 100%;
height: 100px;
background-color: rgba(0, 0, 0, 0.85);
top: 90%;
z-index: 3;
}
}
.progress-bar {
.progress-bar {
width: 85%;
height: 15px;
background: rgba(46, 46, 46);
......@@ -429,9 +486,9 @@
margin-top: 40px;
display: flex;
align-items: center;
}
}
.progress-dots {
.progress-dots {
position: absolute;
width: 100%;
height: 100%;
......@@ -441,26 +498,26 @@
padding: 0 5%;
box-sizing: border-box;
pointer-events: none;
}
}
.progress-dot {
.progress-dot {
width: 12px;
height: 12px;
background-image: url('@/assets/dian.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
}
.progress-fill {
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #00c6ff, #0072ff);
transition: width 0.3s ease;
border-radius: 15px;
box-shadow: 0 0 15px rgba(0, 114, 255, 0.5);
}
}
.progress-text {
.progress-text {
position: absolute;
top: 50%;
left: 50%;
......@@ -469,47 +526,47 @@
font-weight: bold;
font-size: 14px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
}
.left-controls {
.left-controls {
position: absolute;
color: white;
margin: 30px 0 0 30px;
}
}
.right-controls {
.right-controls {
position: absolute;
top: 30px;
left: 94%;
}
}
.progress-time {
.progress-time {
position: absolute;
top: 35px;
left: 90%;
color: white;
}
}
.time-range-display {
.time-range-display {
height: 0px;
display: flex;
justify-content: space-between;
padding: 0px 205px 0px 80px;
color: #e8e8e7;
font-size: 14px;
}
}
.start-time {
.start-time {
text-align: left;
margin-top: 10px;
}
}
.end-time {
.end-time {
text-align: right;
margin-top: 10px;
}
}
.control-btn {
.control-btn {
border: none;
color: white;
font-size: 16px;
......@@ -518,6 +575,14 @@
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
</style>
}
.spinDiv {
width: 87%;
height: 80%;
position: absolute;
top: 169px;
z-index: 999;
background-color: #2e2e2e67;
}
</style>
\ No newline at end of file
......@@ -262,6 +262,8 @@ function posSubmit() {
message.success('修改成功')
search()
passwordModal.value = false;
localStorage.removeItem('token');
window.location.href = '/login';
}else{
message.error(res.data.msg)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment