#define MAX_MODESS 1
#include < a_samp>
#include < a_http> /// <- Add this include, it's needed to HTTP() function.
#include < YSI\y_ini>
#include < timerfix>
#include zcmd
#include sscanf2
#include streamer
#include admsys
#pragma tabsize 0
#define COLOR_GREY 0xAFAFAFAA
#define COLOR_GREEN 0x33AA33AA
#define COLOR_RED 0xAA3333AA
#define COLOR_YELLOW 0xFFFF00AA
#define COLOR_WHITE 0xFFFFFFAA
#define COLOR_BLUE 0x0000BBAA
#define COLOR_LIGHTBLUE 0x33CCFFAA
#define COLOR_ORANGE 0xFF9900AA
#define COLOR_RED 0xAA3333AA
#define COLOR_LIME 0x10F441AA
#define COLOR_MAGENTA 0xFF00FFFF
#define COLOR_NAVY 0x000080AA
#define COLOR_AQUA 0xF0F8FFAA
#define COLOR_CRIMSON 0xDC143CAA
#define COLOR_FLBLUE 0x6495EDAA
#define COLOR_BISQUE 0xFFE4C4AA
#define COLOR_BLACK 0x000000AA
#define COLOR_CHARTREUSE 0x7FFF00AA
#define COLOR_BROWN 0XA52A2AAA
#define COLOR_CORAL 0xFF7F50AA
#define COLOR_GOLD 0xB8860BAA
#define COLOR_GREENYELLOW 0xADFF2FAA
#define COLOR_INDIGO 0x4B00B0AA
#define COLOR_IVORY 0xFFFF82AA
#define COLOR_LAWNGREEN 0x7CFC00AA
#define COLOR_LIMEGREEN 0x32CD32AA //<--- Dark lime
#define COLOR_MIDNIGHTBLUE 0X191970AA
#define COLOR_MAROON 0x800000AA
#define COLOR_OLIVE 0x808000AA
#define COLOR_ORANGERED 0xFF4500AA
#define COLOR_PINK 0xFFC0CBAA // - Light light pink
#define COLOR_SEAGREEN 0x2E8B57AA
#define COLOR_SPRINGGREEN 0x00FF7FAA
#define COLOR_TOMATO 0xFF6347AA // - Tomato >:/ sounds wrong lol... well... :P
#define COLOR_YELLOWGREEN 0x9ACD32AA //- like military green
#define COLOR_MEDIUMAQUA 0x83BFBFAA
#define COLOR_MEDIUMMAGENTA 0x8B008BAA // dark magenta ^^
#define rosso 0x660000FF
#define verde 0x006600FF
#define giallo 0xCC9900FF
#define DIALOG_REGISTER 1
#define DIALOG_LOGIN 2
#define DIALOG_SUCCESS_1 3
#define DIALOG_SUCCESS_2 4
#define PATH "/Users/%s.ini"
#define COL_WHITE "{FFFFFF}"
#define COL_RED "{F81414}"
#define COL_GREEN "{00FF22}"
#define COL_LIGHTBLUE "{00CED1}"
new timerbarra;
enum pInfo
{
pPass,
pCash,
pAdmin,
pKills,
pDeaths,
pLingua,
pPremium,
pScore
}
new PlayerInfo[ MAX_PLAYERS] [ pInfo] ;
forward LoadUser_data( playerid,name[ ] ,value[ ] ) ;
public LoadUser_data( playerid,name[ ] ,value[ ] )
{
INI_Int( "Password" ,PlayerInfo[ playerid] [ pPass] ) ;
INI_Int( "Cash" ,PlayerInfo[ playerid] [ pCash] ) ;
INI_Int( "Admin" ,PlayerInfo[ playerid] [ pAdmin] ) ;
INI_Int( "Kills" ,PlayerInfo[ playerid] [ pKills] ) ;
INI_Int( "Deaths" ,PlayerInfo[ playerid] [ pDeaths] ) ;
INI_Int( "Lingua" ,PlayerInfo[ playerid] [ pLingua] ) ;
INI_Int( "Premium" ,PlayerInfo[ playerid] [ pPremium] ) ;
INI_Int( "Score" ,PlayerInfo[ playerid] [ pScore] ) ;
return 1 ;
}
stock UserPath( playerid)
{
new string[ 128 ] ,playername[ MAX_PLAYER_NAME] ;
GetPlayerName( playerid,playername,sizeof( playername) ) ;
format( string,sizeof( string) ,PATH,playername) ;
return string;
}
/*Credits to Dracoblue*/
stock udb_hash( buf[ ] ) {
new length= strlen( buf) ;
new s1 = 1 ;
new s2 = 0 ;
new n;
for ( n= 0 ; n< length; n++ )
{
s1 = ( s1 + buf[ n] ) % 65521 ;
s2 = ( s2 + s1) % 65521 ;
}
return ( s2 << 16 ) + s1;
}
forward GEOIP_HTTPREQUEST( playerid, response_code, location[ ] ) ;
public GEOIP_HTTPREQUEST( playerid, response_code, location[ ] ) // The GEO-IP Callback.
{
new string[ 128 ] ;
if ( response_code == 200 ) {
new Pname[ 64 ] ;
GetPlayerName( playerid,Pname,sizeof( Pname) ) ;
format( string, sizeof( string) , "[+] %s [%s] [+]" ,Pname,location) ;
SendClientMessage( playerid, COLOR_GREEN, string) ;
return 1 ;
}
else {
new Pname[ 64 ] ;
GetPlayerName( playerid,Pname,sizeof( Pname) ) ;
format( string, sizeof( string) , "[+] %s [+]" ,Pname) ;
SendClientMessage( playerid, COLOR_GREEN, string) ;
return 0 ;
}
}
new Text: choosen;
// Forward (make public) the function so the server can 'see' it
forward NuovaMode( modeid) ;
// The timer function - the code to be executed when the timer is called goes here
public NuovaMode( modeid)
{
if ( modeid == 69 ) // a cazzo
{
modeid = random( MAX_MODESS) ;
}
if ( modeid == 0 )
{
SendRconCommand( "changemode GM0" ) ;
SendClientMessageToAll( giallo,"[MODALITA'] Toronto Drift" ) ;
}
if ( modeid == 1 )
{
SendRconCommand( "changemode GM1" ) ;
SendClientMessageToAll( giallo,"[MODALITA'] Los Santos Stunts" ) ;
}
// e così via
return 1 ;
}
new Text: ProgressBar;
new ProgressBarAll = 1 ;
forward Inizializza( modeid) ;
public Inizializza( modeid)
{
TextDrawSetString( ProgressBar, "~l~.........." ) ;
timerbarra = SetTimerEx( "UpdateBars" ,1000 ,1 ,"i" ,modeid) ;
for ( new i = 0 ; i < MAX_PLAYERS; i++ )
{
MostraStatBox( i) ;
TextDrawShowForPlayer( i,ProgressBar) ;
new texter = random( 13 ) ;
if ( texter == 0 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc1" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 1 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc10" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 2 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc11" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 3 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc12" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 4 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc13" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 5 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc14" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 6 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc2" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 7 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc3" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 8 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc4" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 9 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc5" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 10 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc6" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 11 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc7" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 12 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc8" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
if ( texter == 13 )
{
choosen = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadsc9" ) ;
TextDrawFont( choosen, 4 ) ;
TextDrawTextSize( choosen, 641.500 , 451.000 ) ;
TextDrawColor( choosen, - 1 ) ;
TextDrawShowForAll( choosen) ;
}
}
forward UpdateBars( modeid) ;
public UpdateBars( modeid)
{
if ( ProgressBarAll == 12 ) ProgressBarAll = 1 ;
new str[ 30 ] ;
if ( ProgressBarAll == 0 ) format( str,sizeof( str) ,"~l~.........." ) ;
else if ( ProgressBarAll == 1 ) format( str,sizeof( str) ,"~w~.~l~........." ) ;
else if ( ProgressBarAll == 2 ) format( str,sizeof( str) ,"~w~..~l~........" ) ;
else if ( ProgressBarAll == 3 ) format( str,sizeof( str) ,"~w~...~l~......." ) ;
else if ( ProgressBarAll == 4 ) format( str,sizeof( str) ,"~w~....~l~......" ) ;
else if ( ProgressBarAll == 5 ) format( str,sizeof( str) ,"~w~.....~l~....." ) ;
else if ( ProgressBarAll == 6 ) format( str,sizeof( str) ,"~w~......~l~...." ) ;
else if ( ProgressBarAll == 7 ) format( str,sizeof( str) ,"~w~.......~l~..." ) ;
else if ( ProgressBarAll == 8 ) format( str,sizeof( str) ,"~w~........~l~.." ) ;
else if ( ProgressBarAll == 9 ) format( str,sizeof( str) ,"~w~.........~l~." ) ;
else if ( ProgressBarAll == 10 ) format( str,sizeof( str) ,"~w~.........~l~." ) ;
else if ( ProgressBarAll == 11 )
{
for ( new i = 0 ; i < MAX_PLAYERS; i++ )
{
TextDrawHideForPlayer( i,ProgressBar) ;
TextDrawHideForPlayer( i,choosen) ;
}
format( str,sizeof( str) ,"~w~.........." ) ;
KillTimer( timerbarra) ;
NuovaMode( modeid) ;
ProgressBarAll++;
return 1 ;
}
TextDrawSetString( ProgressBar, str) ;
ProgressBarAll++;
return 1 ;
}
public OnFilterScriptInit( )
{
print( "\n --------------------------------------" ) ;
print( " Atlantide Everystuff RELOADED" ) ;
print( "--------------------------------------\n " ) ;
SendRconCommand( "language ENG/ITA" ) ;
SendRconCommand( "hostname Atlantis EveryStuff" ) ;
SendRconCommand( "gamemodetext Minimodes" ) ;
SendRconCommand( "mapname San Andreas" ) ;
SendRconCommand( "weburl scambioetico.org" ) ;
SetTimerEx( "Inizializza" , 360 , true ,"i" ,69 ) ;
ProgressBar = TextDrawCreate( 520.000000 ,298.000000 ,".........." ) ;
TextDrawAlignment( ProgressBar,0 ) ;
TextDrawBackgroundColor( ProgressBar,0x000000ff) ;
TextDrawFont( ProgressBar,3 ) ;
TextDrawLetterSize( ProgressBar,0.799999 ,12.899990 ) ;
TextDrawColor( ProgressBar,0xffffffff) ;
TextDrawSetOutline( ProgressBar,1 ) ;
TextDrawSetProportional( ProgressBar,1 ) ;
TextDrawSetShadow( ProgressBar,1 ) ;
return 1 ;
}
public OnFilterScriptExit( )
{
return 1 ;
}
new Text: Textboxdraw0;
new Text: Textboxdraw1;
new Text: Textboxdraw2;
new Text: Textboxdraw3[ MAX_PLAYERS] ;
new Text: Textboxdraw4[ MAX_PLAYERS] ;
new Text: Textboxdraw5[ MAX_PLAYERS] ;
new Text: Textboxdraw6[ MAX_PLAYERS] ;
new Text: Textboxdraw8[ MAX_PLAYERS] ;
new Text: TextWHITECross1;
new Text: TextWHITECross2;
new Text: TextWHITECross3;
new Text: TextWHITECross4;
new Text: TextWHITECross5;
stock MostraCrossBianco( playerid)
{
TextDrawShowForPlayer( playerid,TextWHITECross1) ;
TextDrawShowForPlayer( playerid,TextWHITECross2) ;
TextDrawShowForPlayer( playerid,TextWHITECross3) ;
TextDrawShowForPlayer( playerid,TextWHITECross4) ;
TextDrawShowForPlayer( playerid,TextWHITECross5) ;
return 1 ;
}
stock NascondiCrossBianco( playerid)
{
TextDrawHideForPlayer( playerid,TextWHITECross1) ;
TextDrawHideForPlayer( playerid,TextWHITECross2) ;
TextDrawHideForPlayer( playerid,TextWHITECross3) ;
TextDrawHideForPlayer( playerid,TextWHITECross4) ;
TextDrawHideForPlayer( playerid,TextWHITECross5) ;
return 1 ;
}
stock NascondiStatBox( playerid)
{
TextDrawHideForPlayer( playerid,Textboxdraw0) ;
TextDrawHideForPlayer( playerid,Textboxdraw1) ;
TextDrawHideForPlayer( playerid,Textboxdraw2) ;
TextDrawHideForPlayer( playerid,Textboxdraw3[ playerid] ) ;
TextDrawHideForPlayer( playerid,Textboxdraw4[ playerid] ) ;
TextDrawHideForPlayer( playerid,Textboxdraw5[ playerid] ) ;
TextDrawHideForPlayer( playerid,Textboxdraw6[ playerid] ) ;
TextDrawHideForPlayer( playerid,Textboxdraw8[ playerid] ) ;
return 1 ;
}
stock MostraStatBox( playerid)
{
new textstring[ 90 ] ;
format( textstring,90 ,"YOU HAVE: %i POINTS" ,GetPlayerScore( playerid) ) ;
TextDrawSetString( Textboxdraw3[ playerid] ,textstring) ;
format( textstring,90 ,"MONEY: $%i" ,GetPlayerMoney( playerid) ) ;
TextDrawSetString( Textboxdraw4[ playerid] ,textstring) ;
TextDrawSetString( Textboxdraw5[ playerid] ,"YOU CAN EARN POINTS BY SIMPLY PLAYING" ) ;
new morti = PlayerInfo[ playerid] [ pDeaths] ;
if ( ! morti) morti = 1 ;
new Float : kd
= floatdiv
( PlayerInfo
[ playerid
] [ pKills
] , morti
) ; format( textstring,90 ,"KILLS: %d DEATHS: %d - K/D: %.2f" ,PlayerInfo[ playerid] [ pKills] ,PlayerInfo[ playerid] [ pDeaths] ,kd) ;
TextDrawSetString( Textboxdraw6[ playerid] ,textstring) ;
TextDrawSetString( Textboxdraw8[ playerid] ,"YOU CAN UNLOCK REWARDS WITH THOSE POINTS YOU EARN!" ) ;
// TextDrawShowForPlayer(playerid,textscreen);
TextDrawShowForPlayer( playerid,Textboxdraw1) ;
TextDrawShowForPlayer( playerid,Textboxdraw2) ;
TextDrawShowForPlayer( playerid,Textboxdraw3[ playerid] ) ;
TextDrawShowForPlayer( playerid,Textboxdraw4[ playerid] ) ;
TextDrawShowForPlayer( playerid,Textboxdraw5[ playerid] ) ;
TextDrawShowForPlayer( playerid,Textboxdraw6[ playerid] ) ;
TextDrawShowForPlayer( playerid,Textboxdraw8[ playerid] ) ;
// TextDrawShowForPlayer(playerid,ProgressBar);
return 1 ;
}
new Text: PlayerTextdraw1;
public OnPlayerConnect( playerid)
{
if ( IsPlayerNPC( playerid) ) return 1 ;
new req[ 256 ] ;
new IP[ 16 ] ;
GetPlayerIp( playerid,IP,sizeof( IP) ) ;
// format(IP,sizeof(IP),"117.56.0.98"); //Un-comment this line if you want to put some random Dummy IP to test the script
if ( strlen( IP) < 1 ) return 1 ;
format( req, sizeof( req) ,"geoip.cybernieve.com/?IP=%s" ,IP) ; //// Replace the address (geoip.cybernieve.com) if you've setup your own GEO-IP Server
HTTP( playerid, HTTP_GET, req,"" ,"GEOIP_HTTPREQUEST" ) ;
SendClientMessage( playerid,COLOR_BLACK,"____________________________________________________________________" ) ;
SendClientMessage( playerid,COLOR_GREY,"Benvenuto su Atlantis Everystuff® 2010/2011 V 1.12" ) ;
SendClientMessage( playerid,COLOR_GREY,"per continuare loggati o registrati" ) ;
SendClientMessage( playerid,COLOR_GREY,"Linee: nonsocontare - www.atlantisgaming.it" ) ;
SendClientMessage( playerid,COLOR_BLACK,"____________________________________________________________________" ) ;
PlayerTextdraw1 = TextDrawCreate( - 0.500 , - 2.000 , "LOADSUK:loadscuk" ) ;
TextDrawFont( PlayerTextdraw1, 4 ) ;
TextDrawTextSize( PlayerTextdraw1, 641.500 , 451.000 ) ;
TextDrawColor( PlayerTextdraw1, - 1 ) ;
TextDrawShowForPlayer( playerid, PlayerTextdraw1) ;
SetPlayerAdminLevel( playerid,5 ) ;
if ( fexist( UserPath( playerid) ) )
{
INI_ParseFile( UserPath( playerid) , "LoadUser_%s" , .bExtra = true , .extra = playerid) ;
if ( PlayerInfo[ playerid] [ pLingua] == 0 )
{
ShowPlayerDialog( playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,"" COL_WHITE"Login" ,"" COL_WHITE"Enter your password to login" ,"Login" ,"Exit" ) ;
}
if ( PlayerInfo[ playerid] [ pLingua] == 1 )
{
ShowPlayerDialog( playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,"" COL_WHITE"Login" ,"" COL_WHITE"Inserisci la tua password per effettuare il login" ,"Login" ,"Esci" ) ;
}
}
else
{
ShowPlayerDialog( playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT,"" COL_WHITE"Registration" ,"" COL_WHITE"Create a new account to start having fun!" ,"Next" ,"Exit" ) ;
}
return 1 ;
}
public OnPlayerDisconnect( playerid, reason)
{
new name[ MAX_PLAYER_NAME] , string[ 24 + MAX_PLAYER_NAME] ;
GetPlayerName( playerid, name, sizeof( name) ) ;
if ( reason == 1 ) format( string, sizeof( string) , "[-] %s [/q]" , name) ;
if ( reason == 0 ) format( string, sizeof( string) , "[-] %s [CRASH]" , name) ;
if ( reason == 2 ) format( string, sizeof( string) , "[-] %s [ADMIN]" , name) ;
SendClientMessageToAll( COLOR_RED,string) ;
print( string) ;
new INI
: File = INI_Open
( UserPath
( playerid
) ) ; INI_WriteInt
( File ,
"Cash" ,GetPlayerMoney
( playerid
) ) ; INI_WriteInt
( File ,
"Admin" ,PlayerInfo
[ playerid
] [ pAdmin
] ) ; INI_WriteInt
( File ,
"Kills" ,PlayerInfo
[ playerid
] [ pKills
] ) ; INI_WriteInt
( File ,
"Deaths" ,PlayerInfo
[ playerid
] [ pDeaths
] ) ; INI_WriteInt
( File ,
"Lingua" ,PlayerInfo
[ playerid
] [ pLingua
] ) ; INI_WriteInt
( File ,
"Premium" ,PlayerInfo
[ playerid
] [ pPremium
] ) ; INI_WriteInt
( File ,
"Score" ,GetPlayerScore
( playerid
) ) ; return 1 ;
}
public OnPlayerSpawn( playerid)
{
return 1 ;
}
public OnPlayerDeath( playerid, killerid, reason)
{
return 1 ;
}
public OnVehicleSpawn( vehicleid)
{
return 1 ;
}
public OnVehicleDeath( vehicleid, killerid)
{
return 1 ;
}
public OnPlayerText( playerid, text[ ] )
{
return 1 ;
}
public OnPlayerCommandText( playerid, cmdtext[ ] )
{
if ( strcmp( "/mycommand" , cmdtext, true , 10 ) == 0 )
{
// Do something here
return 1 ;
}
return 0 ;
}
public OnPlayerEnterVehicle( playerid, vehicleid, ispassenger)
{
return 1 ;
}
public OnPlayerExitVehicle( playerid, vehicleid)
{
return 1 ;
}
public OnPlayerStateChange( playerid, newstate, oldstate)
{
return 1 ;
}
public OnPlayerEnterCheckpoint( playerid)
{
return 1 ;
}
public OnPlayerLeaveCheckpoint( playerid)
{
return 1 ;
}
public OnPlayerEnterRaceCheckpoint( playerid)
{
return 1 ;
}
public OnPlayerLeaveRaceCheckpoint( playerid)
{
return 1 ;
}
public OnRconCommand( cmd[ ] )
{
return 1 ;
}
public OnPlayerRequestSpawn( playerid)
{
return 1 ;
}
public OnObjectMoved( objectid)
{
return 1 ;
}
public OnPlayerObjectMoved( playerid, objectid)
{
return 1 ;
}
public OnPlayerPickUpPickup( playerid, pickupid)
{
return 1 ;
}
public OnVehicleMod( playerid, vehicleid, componentid)
{
return 1 ;
}
public OnVehiclePaintjob( playerid, vehicleid, paintjobid)
{
return 1 ;
}
public OnVehicleRespray( playerid, vehicleid, color1, color2)
{
return 1 ;
}
public OnPlayerSelectedMenuRow( playerid, row)
{
return 1 ;
}
public OnPlayerExitedMenu( playerid)
{
return 1 ;
}
public OnPlayerInteriorChange( playerid, newinteriorid, oldinteriorid)
{
return 1 ;
}
public OnPlayerKeyStateChange( playerid, newkeys, oldkeys)
{
return 1 ;
}
public OnRconLoginAttempt( ip[ ] , password[ ] , success)
{
return 1 ;
}
public OnPlayerUpdate( playerid) //The player changed something
{
new pName[ MAX_PLAYER_NAME] , string[ 128 ] ; //I already explained it. Too much explaination for one line
if ( GetPlayerMoney( playerid) > Soldazzi[ playerid] ) //The player has more money then the string says (more 'bout that later)
{
GetPlayerName( playerid, pName, MAX_PLAYER_NAME) ; //Will get the player's name
format( string, sizeof( string) , "[AUTOBAN] %s è stato bannato: MONEY CHEAT." , pName) ; //Format's a script: "* 'pName' has been banned: MONEY CHEAT"
SendClientMessageToAll( - 1 , string) ; //Send an message to ALL the active players with the formatted string: "* 'pName' has been banned: MONEY CHEAT" in an RED COLOR
BanEx( playerid, "Money Cheat" ) ; //Bans the player with the reason "Money Cheat"
}
return 1 ;
}
public OnPlayerStreamIn( playerid, forplayerid)
{
return 1 ;
}
public OnPlayerStreamOut( playerid, forplayerid)
{
return 1 ;
}
stock CLS( playerid) {
for ( new i= 0 ; i< 100 ; i++ ) { SendClientMessage( playerid, - 1 , " " ) ; }
return 1 ; }
stock a_GivePlayerMoney( playerid, money)
{
Soldazzi[ playerid] += money; //Will increase the string: "+="
GivePlayerMoney( playerid, money) ; //Give's the player money... DUH :P Don't use "a_GivePlayerMoney" here.
}
stock a_SetPlayerMoney( playerid, money)
{
Soldazzi[ playerid] = money; //Will set the string to the money ammount
ResetPlayerMoney( playerid) ; //Reset's player money
GivePlayerMoney( playerid, money) ; //Will give the player money. no a_GivePlayerMoney needed!
}
public OnVehicleStreamIn( vehicleid, forplayerid)
{
return 1 ;
}
public OnVehicleStreamOut( vehicleid, forplayerid)
{
return 1 ;
}
public OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] )
{
switch ( dialogid )
{
case DIALOG_SUCCESS_1:
{
TextDrawHideForPlayer( playerid, PlayerTextdraw1) ;
if ( ! response)
{
new INI
: File = INI_Open
( UserPath
( playerid
) ) ; PlayerInfo[ playerid] [ pLingua] = 1 ;
INI_WriteInt
( File ,
"Lingua" ,PlayerInfo
[ playerid
] [ pLingua
] ) ; }
if ( response)
{
new INI
: File = INI_Open
( UserPath
( playerid
) ) ; PlayerInfo[ playerid] [ pLingua] = 0 ;
INI_WriteInt
( File ,
"Lingua" ,PlayerInfo
[ playerid
] [ pLingua
] ) ;
}
}
case DIALOG_REGISTER:
{
if ( ! response) return Kick( playerid) ;
if ( response)
{
if ( ! strlen( inputtext) ) return ShowPlayerDialog( playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "" COL_WHITE"Registration" ,"" COL_RED"Invalid password.\n " COL_WHITE"Enter a password to register" ,"Next" ,"Esci" ) ;
new INI
: File = INI_Open
( UserPath
( playerid
) ) ; INI_WriteInt
( File ,
"Password" ,udb_hash
( inputtext
) ) ; INI_WriteInt
( File ,
"Cash" ,
0 ) ; INI_WriteInt
( File ,
"Admin" ,
0 ) ; INI_WriteInt
( File ,
"Kills" ,
0 ) ; INI_WriteInt
( File ,
"Deaths" ,
0 ) ; INI_WriteInt
( File ,
"Premium" ,
0 ) ; INI_WriteInt
( File ,
"Score" ,
0 ) ;
ShowPlayerDialog( playerid, DIALOG_SUCCESS_1, DIALOG_STYLE_MSGBOX,"" COL_WHITE"Last step" ,"" COL_WHITE"Choose server language" ,"ENG" ,"ITA" ) ;
}
}
case DIALOG_LOGIN:
{
if ( ! response ) return Kick ( playerid ) ;
if ( response )
{
if ( udb_hash( inputtext) == PlayerInfo[ playerid] [ pPass] )
{
INI_ParseFile( UserPath( playerid) , "LoadUser_%s" , .bExtra = true , .extra = playerid) ;
a_GivePlayerMoney( playerid, PlayerInfo[ playerid] [ pCash] ) ;
SetPlayerAdminLevel( playerid,PlayerInfo[ playerid] [ pAdmin] ) ;
TextDrawHideForPlayer( playerid,PlayerTextdraw1 ) ;
if ( PlayerInfo[ playerid] [ pLingua] == 0 )
{
SendClientMessage( playerid,- 1 ,"Welcome back to the server. Have a good time in here!" ) ;
}
if ( PlayerInfo[ playerid] [ pLingua] == 1 )
{
SendClientMessage( playerid,- 1 ,"Bentornato in server. Divertiti!" ) ;
}
}
else
{
if ( PlayerInfo[ playerid] [ pLingua] == 0 )
{
ShowPlayerDialog( playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,"" COL_WHITE"Login" ,"" COL_RED"Invalid password.\n " COL_WHITE"Enter your password" ,"Login" ,"Exit" ) ;
}
if ( PlayerInfo[ playerid] [ pLingua] == 1 )
{
ShowPlayerDialog( playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,"" COL_WHITE"Login" ,"" COL_RED"Password errata.\n " COL_WHITE"Inserisci la password per entrare nel server" ,"Login" ,"Esci" ) ;
}
}
return 1 ;
}
}
}
return 1 ;
}
public OnPlayerClickPlayer( playerid, clickedplayerid, source)
{
return 1 ;
}
// comandi
COMMAND: switchlanguage( playerid, params[ ] )
{
if ( PlayerInfo[ playerid] [ pLingua] == 0 )
{
PlayerInfo[ playerid] [ pLingua] = 1 ;
SendClientMessage( playerid,verde,"Ora la lingua principale è italiano." ) ;
return 1 ;
}
if ( PlayerInfo[ playerid] [ pLingua] == 1 )
{
PlayerInfo[ playerid] [ pLingua] = 0 ;
SendClientMessage( playerid,verde,"Now your main language is english." ) ;
return 1 ;
}
return 1 ;
}
COMMAND: changemode( playerid, params[ ] )
{
if ( ! IsPlayerAdminEx( playerid) ) return 1 ;
if ( isnull( params) ) return SendClientMessage( playerid, ADMSYS_DEFAULT_COLOR1, "Usa: /changemode [id mode] - per una lista completa usa /modes" ) ;
if ( ! isnumeric( params) ) return SendClientMessage( playerid, ADMSYS_DEFAULT_COLOR1, "Usa: /changemode [id mode]" ) ;
new vittima = strval( params) ; // iValue is now vittima
if ( vittima == 0 )
{
SendRconCommand( "changemode GM1" ) ;
}
return 1 ;
}
COMMAND: stats( playerid, params[ ] )
{
if ( PlayerInfo[ playerid] [ pLingua] == 0 )
{
new Hour, Minute, Second;
gettime( Hour, Minute, Second) ;
new Year, Month, Day, string[ 128 ] , string1[ 128 ] , string2[ 128 ] ;
getdate( Year, Month, Day) ;
format( string, sizeof( string) ,"Atlantis Everystuff ================ %02d:%02d:%02d %02d/%02d/%d ================ Stats" , Hour, Minute, Second, Day, Month, Year) ;
new playername[ MAX_PLAYER_NAME] ;
GetPlayerName( playerid,playername,sizeof( playername) ) ;
new morti = PlayerInfo[ playerid] [ pDeaths] ;
if ( ! morti) morti = 1 ;
new Float : kd
= floatdiv
( PlayerInfo
[ playerid
] [ pKills
] , morti
) ; new premiuml[ 128 ] ;
if ( PlayerInfo[ playerid] [ pPremium] == 0 ) { format( premiuml,sizeof( premiuml) ,"None (/gopremium to see all advantages!)" ) ; }
if ( PlayerInfo[ playerid] [ pPremium] == 1 ) { format( premiuml,sizeof( premiuml) ,"Silver" ) ; }
if ( PlayerInfo[ playerid] [ pPremium] == 2 ) { format( premiuml,sizeof( premiuml) ,"Gold" ) ; }
format( string1, sizeof( string1) ,"Name: %s | Money: %i | Kills: %i | Deaths: %i | Ratio: %.2f | Score: %i" , playername, GetPlayerMoney( playerid) , PlayerInfo[ playerid] [ pKills] , PlayerInfo[ playerid] [ pDeaths] , kd, GetPlayerScore( playerid) ) ;
format( string2, sizeof( string2) ,"Lifetime Premium Level: %s" , premiuml) ;
SendClientMessage( playerid,giallo,string) ;
SendClientMessage( playerid,giallo,string1) ;
SendClientMessage( playerid,giallo,string2) ;
return 1 ;
}
if ( PlayerInfo[ playerid] [ pLingua] == 1 )
{
new Hour, Minute, Second;
gettime( Hour, Minute, Second) ;
new Year, Month, Day, string[ 128 ] , string1[ 128 ] , string2[ 128 ] ;
getdate( Year, Month, Day) ;
format( string, sizeof( string) ,"Street Gang Wars ================ %02d:%02d:%02d %02d/%02d/%d ================ Info" , Hour, Minute, Second, Day, Month, Year) ;
new playername[ MAX_PLAYER_NAME] ;
GetPlayerName( playerid,playername,sizeof( playername) ) ;
new morti = PlayerInfo[ playerid] [ pDeaths] ;
if ( ! morti) morti = 1 ;
new Float : kd
= floatdiv
( PlayerInfo
[ playerid
] [ pKills
] , morti
) ; new premiuml[ 128 ] ;
if ( PlayerInfo[ playerid] [ pPremium] == 0 ) { format( premiuml,sizeof( premiuml) ,"Nessuno (/gopremium per vedere tutti i vantaggi!)" ) ; }
if ( PlayerInfo[ playerid] [ pPremium] == 1 ) { format( premiuml,sizeof( premiuml) ,"Silver" ) ; }
if ( PlayerInfo[ playerid] [ pPremium] == 2 ) { format( premiuml,sizeof( premiuml) ,"Gold" ) ; }
format( string1, sizeof( string1) ,"Nome: %s | Soldi: %i | Kills: %i | Deaths: %i | Ratio: %.2f | Punti: %i" , playername, GetPlayerMoney( playerid) , PlayerInfo[ playerid] [ pKills] , PlayerInfo[ playerid] [ pDeaths] , kd, GetPlayerScore( playerid) ) ;
format( string2, sizeof( string2) ,"Livello Premium Permanente: %s" , premiuml) ;
SendClientMessage( playerid,giallo,string) ;
SendClientMessage( playerid,giallo,string1) ;
SendClientMessage( playerid,giallo,string2) ;
return 1 ;
}
return 1 ;
}
COMMAND: showstats( playerid, params[ ] )
{
if ( ! IsPlayerAdminEx( playerid) ) return 1 ;
if ( isnull( params) ) return SendClientMessage( playerid, ADMSYS_DEFAULT_COLOR1, "Usa: /showstats [id]" ) ;
if ( ! isnumeric( params) ) return SendClientMessage( playerid, ADMSYS_DEFAULT_COLOR1, "Usa: /showstats [id]" ) ;
new vittima = strval( params) ; // iValue is now vittima
if ( ! IsPlayerConnected( vittima) ) return SendClientMessage( playerid, ADMSYS_DEFAULT_COLOR1, "Giocatore non connesso." ) ;
new Hour, Minute, Second;
gettime( Hour, Minute, Second) ;
new Year, Month, Day, string[ 128 ] , string1[ 128 ] , string2[ 128 ] , string3[ 128 ] ;
getdate( Year, Month, Day) ;
format( string, sizeof( string) ,"Street Gang Wars ===ADMIN=== %02d:%02d:%02d %02d/%02d/%d ===ADMIN=== Stats" , Hour, Minute, Second, Day, Month, Year) ;
new playername[ MAX_PLAYER_NAME] ;
GetPlayerName( vittima,playername,sizeof( playername) ) ;
new morti = PlayerInfo[ vittima] [ pDeaths] ;
if ( ! morti) morti = 1 ;
new Float : kd
= floatdiv
( PlayerInfo
[ vittima
] [ pKills
] , morti
) ; new premiuml[ 128 ] ;
if ( PlayerInfo[ vittima] [ pPremium] == 0 ) { format( premiuml,sizeof( premiuml) ,"Nessuno" ) ; }
if ( PlayerInfo[ vittima] [ pPremium] == 1 ) { format( premiuml,sizeof( premiuml) ,"Silver" ) ; }
if ( PlayerInfo[ vittima] [ pPremium] == 2 ) { format( premiuml,sizeof( premiuml) ,"Gold" ) ; }
format( string1, sizeof( string1) ,"Nome: %s | Soldi: %i | Kills: %i | Deaths: %i | Ratio: %.2f | Punti: %i" , playername, GetPlayerMoney( vittima) , PlayerInfo[ vittima] [ pKills] , PlayerInfo[ vittima] [ pDeaths] , kd, GetPlayerScore( playerid) ) ;
format( string2, sizeof( string2) ,"Livello Premium Permanente: %s" , premiuml) ;
new Float : allasalute,
Float : allasalute2, ippo
[ 16 ] ; GetPlayerHealth( vittima, allasalute) ;
GetPlayerArmour( vittima, allasalute2) ;
GetPlayerIp( vittima,ippo,sizeof( ippo) ) ;
format( string3, sizeof( string3) ,"HP: %.1f | AP: %.1f | Indirizzo IP: %s | Ping attuale: %i | Interior: %i | Virtual World: %i" , allasalute, allasalute2, ippo, GetPlayerPing( vittima) , GetPlayerInterior( vittima) , GetPlayerVirtualWorld( vittima) ) ;
SendClientMessage( playerid,giallo,string) ;
SendClientMessage( playerid,giallo,string1) ;
SendClientMessage( playerid,giallo,string2) ;
SendClientMessage( playerid,giallo,string3) ;
return 1 ;
}
COMMAND: help( playerid, params[ ] )
{
if ( PlayerInfo[ playerid] [ pLingua] == 0 )
{
SendClientMessage( playerid,giallo,"Street Gang Wars =============================================== Avaible Commands" ) ;
SendClientMessage( playerid,giallo,"[SETTINGS] /switchlanguage" ) ;
SendClientMessage( playerid,giallo,"[GENERAL] /help /admins /report" ) ;
}
if ( PlayerInfo[ playerid] [ pLingua] == 1 )
{
SendClientMessage( playerid,giallo,"Street Gang Wars ============================================= Comandi Disponibili" ) ;
SendClientMessage( playerid,giallo,"[IMPOSTAZIONI] /switchlanguage" ) ;
SendClientMessage( playerid,giallo,"[GENERALE] /aiuto /admins /report" ) ;
}
return 1 ;
}
COMMAND: aiuto( playerid, params[ ] )
{
return cmd_help( playerid, params) ;
}
COMMAND: info( playerid, params[ ] )
{
return cmd_stats( playerid, params) ;
}
CgoKI2RlZmluZSBNQVhfTU9ERVNTIDEKCgoKCgojaW5jbHVkZSA8YV9zYW1wPgojaW5jbHVkZSA8YV9odHRwPiAvLy8gPC0gQWRkIHRoaXMgaW5jbHVkZSwgaXQncyBuZWVkZWQgdG8gSFRUUCgpIGZ1bmN0aW9uLgojaW5jbHVkZSA8WVNJXHlfaW5pPgojaW5jbHVkZSA8dGltZXJmaXg+CiNpbmNsdWRlIHpjbWQKI2luY2x1ZGUgc3NjYW5mMgoKI2luY2x1ZGUgc3RyZWFtZXIKI2luY2x1ZGUgYWRtc3lzCiNwcmFnbWEgdGFic2l6ZSAwCgojZGVmaW5lIENPTE9SX0dSRVkgMHhBRkFGQUZBQQojZGVmaW5lIENPTE9SX0dSRUVOIDB4MzNBQTMzQUEKI2RlZmluZSBDT0xPUl9SRUQgMHhBQTMzMzNBQQojZGVmaW5lIENPTE9SX1lFTExPVyAweEZGRkYwMEFBCiNkZWZpbmUgQ09MT1JfV0hJVEUgMHhGRkZGRkZBQQojZGVmaW5lIENPTE9SX0JMVUUgMHgwMDAwQkJBQQojZGVmaW5lIENPTE9SX0xJR0hUQkxVRSAweDMzQ0NGRkFBCiNkZWZpbmUgQ09MT1JfT1JBTkdFIDB4RkY5OTAwQUEKI2RlZmluZSBDT0xPUl9SRUQgMHhBQTMzMzNBQQojZGVmaW5lIENPTE9SX0xJTUUgMHgxMEY0NDFBQQojZGVmaW5lIENPTE9SX01BR0VOVEEgMHhGRjAwRkZGRgojZGVmaW5lIENPTE9SX05BVlkgMHgwMDAwODBBQQojZGVmaW5lIENPTE9SX0FRVUEgMHhGMEY4RkZBQQojZGVmaW5lIENPTE9SX0NSSU1TT04gMHhEQzE0M0NBQQojZGVmaW5lIENPTE9SX0ZMQkxVRSAweDY0OTVFREFBCiNkZWZpbmUgQ09MT1JfQklTUVVFIDB4RkZFNEM0QUEKI2RlZmluZSBDT0xPUl9CTEFDSyAweDAwMDAwMEFBCiNkZWZpbmUgQ09MT1JfQ0hBUlRSRVVTRSAweDdGRkYwMEFBCiNkZWZpbmUgQ09MT1JfQlJPV04gMFhBNTJBMkFBQQojZGVmaW5lIENPTE9SX0NPUkFMIDB4RkY3RjUwQUEKI2RlZmluZSBDT0xPUl9HT0xEIDB4Qjg4NjBCQUEKI2RlZmluZSBDT0xPUl9HUkVFTllFTExPVyAweEFERkYyRkFBCiNkZWZpbmUgQ09MT1JfSU5ESUdPIDB4NEIwMEIwQUEKI2RlZmluZSBDT0xPUl9JVk9SWSAweEZGRkY4MkFBCiNkZWZpbmUgQ09MT1JfTEFXTkdSRUVOIDB4N0NGQzAwQUEKI2RlZmluZSBDT0xPUl9MSU1FR1JFRU4gMHgzMkNEMzJBQSAvLzwtLS0gRGFyayBsaW1lCiNkZWZpbmUgQ09MT1JfTUlETklHSFRCTFVFIDBYMTkxOTcwQUEKI2RlZmluZSBDT0xPUl9NQVJPT04gMHg4MDAwMDBBQQojZGVmaW5lIENPTE9SX09MSVZFIDB4ODA4MDAwQUEKI2RlZmluZSBDT0xPUl9PUkFOR0VSRUQgMHhGRjQ1MDBBQQojZGVmaW5lIENPTE9SX1BJTksgMHhGRkMwQ0JBQSAvLyAtIExpZ2h0IGxpZ2h0IHBpbmsKI2RlZmluZSBDT0xPUl9TRUFHUkVFTiAweDJFOEI1N0FBCiNkZWZpbmUgQ09MT1JfU1BSSU5HR1JFRU4gMHgwMEZGN0ZBQQojZGVmaW5lIENPTE9SX1RPTUFUTyAweEZGNjM0N0FBIC8vIC0gVG9tYXRvID46LyBzb3VuZHMgd3JvbmcgbG9sLi4uIHdlbGwuLi4gOlAKI2RlZmluZSBDT0xPUl9ZRUxMT1dHUkVFTiAweDlBQ0QzMkFBIC8vLSBsaWtlIG1pbGl0YXJ5IGdyZWVuCiNkZWZpbmUgQ09MT1JfTUVESVVNQVFVQSAweDgzQkZCRkFBCiNkZWZpbmUgQ09MT1JfTUVESVVNTUFHRU5UQSAweDhCMDA4QkFBIC8vIGRhcmsgbWFnZW50YSBeXgoKI2RlZmluZSByb3NzbyAweDY2MDAwMEZGCiNkZWZpbmUgdmVyZGUgMHgwMDY2MDBGRgojZGVmaW5lIGdpYWxsbyAweENDOTkwMEZGCgoKCiNkZWZpbmUgRElBTE9HX1JFR0lTVEVSIDEKI2RlZmluZSBESUFMT0dfTE9HSU4gMgojZGVmaW5lIERJQUxPR19TVUNDRVNTXzEgMwojZGVmaW5lIERJQUxPR19TVUNDRVNTXzIgNAojZGVmaW5lIFBBVEggIi9Vc2Vycy8lcy5pbmkiCiNkZWZpbmUgQ09MX1dISVRFICJ7RkZGRkZGfSIKI2RlZmluZSBDT0xfUkVEICJ7RjgxNDE0fSIKI2RlZmluZSBDT0xfR1JFRU4gInswMEZGMjJ9IgojZGVmaW5lIENPTF9MSUdIVEJMVUUgInswMENFRDF9IgpuZXcgdGltZXJiYXJyYTsKZW51bSBwSW5mbwp7CiAgICBwUGFzcywKICAgIHBDYXNoLAogICAgcEFkbWluLAogICAgcEtpbGxzLAogICAgcERlYXRocywKICAgIHBMaW5ndWEsCglwUHJlbWl1bSwKCXBTY29yZQp9Cm5ldyBQbGF5ZXJJbmZvW01BWF9QTEFZRVJTXVtwSW5mb107CgoKCmZvcndhcmQgTG9hZFVzZXJfZGF0YShwbGF5ZXJpZCxuYW1lW10sdmFsdWVbXSk7CnB1YmxpYyBMb2FkVXNlcl9kYXRhKHBsYXllcmlkLG5hbWVbXSx2YWx1ZVtdKQp7CglJTklfSW50KCJQYXNzd29yZCIsUGxheWVySW5mb1twbGF5ZXJpZF1bcFBhc3NdKTsKCUlOSV9JbnQoIkNhc2giLFBsYXllckluZm9bcGxheWVyaWRdW3BDYXNoXSk7CglJTklfSW50KCJBZG1pbiIsUGxheWVySW5mb1twbGF5ZXJpZF1bcEFkbWluXSk7CglJTklfSW50KCJLaWxscyIsUGxheWVySW5mb1twbGF5ZXJpZF1bcEtpbGxzXSk7CiAgICBJTklfSW50KCJEZWF0aHMiLFBsYXllckluZm9bcGxheWVyaWRdW3BEZWF0aHNdKTsKICAgIElOSV9JbnQoIkxpbmd1YSIsUGxheWVySW5mb1twbGF5ZXJpZF1bcExpbmd1YV0pOwogICAgSU5JX0ludCgiUHJlbWl1bSIsUGxheWVySW5mb1twbGF5ZXJpZF1bcFByZW1pdW1dKTsKICAgIElOSV9JbnQoIlNjb3JlIixQbGF5ZXJJbmZvW3BsYXllcmlkXVtwU2NvcmVdKTsKIAlyZXR1cm4gMTsKfQpzdG9jayBVc2VyUGF0aChwbGF5ZXJpZCkKewoJbmV3IHN0cmluZ1sxMjhdLHBsYXllcm5hbWVbTUFYX1BMQVlFUl9OQU1FXTsKCUdldFBsYXllck5hbWUocGxheWVyaWQscGxheWVybmFtZSxzaXplb2YocGxheWVybmFtZSkpOwoJZm9ybWF0KHN0cmluZyxzaXplb2Yoc3RyaW5nKSxQQVRILHBsYXllcm5hbWUpOwoJcmV0dXJuIHN0cmluZzsKfQovKkNyZWRpdHMgdG8gRHJhY29ibHVlKi8Kc3RvY2sgdWRiX2hhc2goYnVmW10pIHsKCW5ldyBsZW5ndGg9c3RybGVuKGJ1Zik7CiAgICBuZXcgczEgPSAxOwogICAgbmV3IHMyID0gMDsKICAgIG5ldyBuOwogICAgZm9yIChuPTA7IG48bGVuZ3RoOyBuKyspCiAgICB7CiAgICAgICBzMSA9IChzMSArIGJ1ZltuXSkgJSA2NTUyMTsKICAgICAgIHMyID0gKHMyICsgczEpICAgICAlIDY1NTIxOwogICAgfQogICAgcmV0dXJuIChzMiA8PCAxNikgKyBzMTsKfQoKZm9yd2FyZCBHRU9JUF9IVFRQUkVRVUVTVChwbGF5ZXJpZCwgcmVzcG9uc2VfY29kZSwgbG9jYXRpb25bXSk7CnB1YmxpYyBHRU9JUF9IVFRQUkVRVUVTVChwbGF5ZXJpZCwgcmVzcG9uc2VfY29kZSwgbG9jYXRpb25bXSkgLy8gVGhlIEdFTy1JUCBDYWxsYmFjay4KewogICAgbmV3IHN0cmluZ1sxMjhdOwogICAgaWYocmVzcG9uc2VfY29kZSA9PSAyMDApIHsKICAgICAgICBuZXcgUG5hbWVbNjRdOwogICAgICAgIEdldFBsYXllck5hbWUocGxheWVyaWQsUG5hbWUsc2l6ZW9mKFBuYW1lKSk7CiAgICAgICAgZm9ybWF0KHN0cmluZywgc2l6ZW9mKHN0cmluZyksICJbK10gJXMgWyVzXSBbK10iLFBuYW1lLGxvY2F0aW9uKTsKICAgICAgICBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCwgQ09MT1JfR1JFRU4sIHN0cmluZyk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBuZXcgUG5hbWVbNjRdOwogICAgICAgIEdldFBsYXllck5hbWUocGxheWVyaWQsUG5hbWUsc2l6ZW9mKFBuYW1lKSk7CiAgICAgICAgZm9ybWF0KHN0cmluZywgc2l6ZW9mKHN0cmluZyksICJbK10gJXMgWytdIixQbmFtZSk7CiAgICAgICAgU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsIENPTE9SX0dSRUVOLCBzdHJpbmcpOwogICAgICAgIHJldHVybiAwOwogICAgfQp9CgpuZXcgVGV4dDpjaG9vc2VuOwoKCi8vIEZvcndhcmQgKG1ha2UgcHVibGljKSB0aGUgZnVuY3Rpb24gc28gdGhlIHNlcnZlciBjYW4gJ3NlZScgaXQKZm9yd2FyZCBOdW92YU1vZGUobW9kZWlkKTsKCi8vIFRoZSB0aW1lciBmdW5jdGlvbiAtIHRoZSBjb2RlIHRvIGJlIGV4ZWN1dGVkIHdoZW4gdGhlIHRpbWVyIGlzIGNhbGxlZCBnb2VzIGhlcmUKcHVibGljIE51b3ZhTW9kZShtb2RlaWQpCnsKCgogICAgaWYobW9kZWlkID09IDY5KSAvLyBhIGNhenpvCiAgICB7CiAgICAgbW9kZWlkID0gcmFuZG9tKE1BWF9NT0RFU1MpOwogICAgIH0KICAgICBpZihtb2RlaWQgPT0gMCkKICAgICB7CiAgICAgU2VuZFJjb25Db21tYW5kKCJjaGFuZ2Vtb2RlIEdNMCIpOwogICAgIFNlbmRDbGllbnRNZXNzYWdlVG9BbGwoZ2lhbGxvLCJbTU9EQUxJVEEnXSBUb3JvbnRvIERyaWZ0Iik7CiAgICAgfQogICAgICBpZihtb2RlaWQgPT0gMSkKICAgICB7CiAgICAgU2VuZFJjb25Db21tYW5kKCJjaGFuZ2Vtb2RlIEdNMSIpOwogICAgIFNlbmRDbGllbnRNZXNzYWdlVG9BbGwoZ2lhbGxvLCJbTU9EQUxJVEEnXSBMb3MgU2FudG9zIFN0dW50cyIpOwogICAgIH0KICAgICAvLyBlIGNvc8OsIHZpYQoKCgogICAgcmV0dXJuIDE7Cn0KCgpuZXcgVGV4dDpQcm9ncmVzc0JhcjsKbmV3IFByb2dyZXNzQmFyQWxsID0gMTsKCmZvcndhcmQgSW5pemlhbGl6emEobW9kZWlkKTsKcHVibGljIEluaXppYWxpenphKG1vZGVpZCkKewoKVGV4dERyYXdTZXRTdHJpbmcoUHJvZ3Jlc3NCYXIsICJ+bH4uLi4uLi4uLi4uIik7CnRpbWVyYmFycmEgPSBTZXRUaW1lckV4KCJVcGRhdGVCYXJzIiwxMDAwLDEsImkiLG1vZGVpZCk7CgoJZm9yKG5ldyBpID0gMDsgaSA8IE1BWF9QTEFZRVJTOyBpKyspCgkJewogICAgTW9zdHJhU3RhdEJveChpKTsKVGV4dERyYXdTaG93Rm9yUGxheWVyKGksUHJvZ3Jlc3NCYXIpOwogICAgbmV3IHRleHRlciA9IHJhbmRvbSgxMyk7CiAgICBpZih0ZXh0ZXIgPT0gMCkKICAgIHsKICAgIGNob29zZW4gPSBUZXh0RHJhd0NyZWF0ZSgtMC41MDAsIC0yLjAwMCwgIkxPQURTVUs6bG9hZHNjMSIpOwpUZXh0RHJhd0ZvbnQoY2hvb3NlbiwgNCk7ClRleHREcmF3VGV4dFNpemUoY2hvb3NlbiwgNjQxLjUwMCwgNDUxLjAwMCk7ClRleHREcmF3Q29sb3IoY2hvb3NlbiwgLTEpOwpUZXh0RHJhd1Nob3dGb3JBbGwoY2hvb3Nlbik7CiAgICB9CiAgICBpZih0ZXh0ZXIgPT0gMSkKICAgIHsKICAgIGNob29zZW4gPSBUZXh0RHJhd0NyZWF0ZSgtMC41MDAsIC0yLjAwMCwgIkxPQURTVUs6bG9hZHNjMTAiKTsKVGV4dERyYXdGb250KGNob29zZW4sIDQpOwpUZXh0RHJhd1RleHRTaXplKGNob29zZW4sIDY0MS41MDAsIDQ1MS4wMDApOwpUZXh0RHJhd0NvbG9yKGNob29zZW4sIC0xKTsKVGV4dERyYXdTaG93Rm9yQWxsKGNob29zZW4pOwogICAgfQogICAgaWYodGV4dGVyID09IDIpCiAgICB7CiAgICBjaG9vc2VuID0gVGV4dERyYXdDcmVhdGUoLTAuNTAwLCAtMi4wMDAsICJMT0FEU1VLOmxvYWRzYzExIik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSAzKQogICAgewogICAgY2hvb3NlbiA9IFRleHREcmF3Q3JlYXRlKC0wLjUwMCwgLTIuMDAwLCAiTE9BRFNVSzpsb2Fkc2MxMiIpOwpUZXh0RHJhd0ZvbnQoY2hvb3NlbiwgNCk7ClRleHREcmF3VGV4dFNpemUoY2hvb3NlbiwgNjQxLjUwMCwgNDUxLjAwMCk7ClRleHREcmF3Q29sb3IoY2hvb3NlbiwgLTEpOwpUZXh0RHJhd1Nob3dGb3JBbGwoY2hvb3Nlbik7CiAgICB9CiAgICBpZih0ZXh0ZXIgPT0gNCkKICAgIHsKICAgIGNob29zZW4gPSBUZXh0RHJhd0NyZWF0ZSgtMC41MDAsIC0yLjAwMCwgIkxPQURTVUs6bG9hZHNjMTMiKTsKVGV4dERyYXdGb250KGNob29zZW4sIDQpOwpUZXh0RHJhd1RleHRTaXplKGNob29zZW4sIDY0MS41MDAsIDQ1MS4wMDApOwpUZXh0RHJhd0NvbG9yKGNob29zZW4sIC0xKTsKVGV4dERyYXdTaG93Rm9yQWxsKGNob29zZW4pOwogICAgfQogICAgaWYodGV4dGVyID09IDUpCiAgICB7CiAgICBjaG9vc2VuID0gVGV4dERyYXdDcmVhdGUoLTAuNTAwLCAtMi4wMDAsICJMT0FEU1VLOmxvYWRzYzE0Iik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSA2KQogICAgewogICAgY2hvb3NlbiA9IFRleHREcmF3Q3JlYXRlKC0wLjUwMCwgLTIuMDAwLCAiTE9BRFNVSzpsb2Fkc2MyIik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSA3KQogICAgewogICAgY2hvb3NlbiA9IFRleHREcmF3Q3JlYXRlKC0wLjUwMCwgLTIuMDAwLCAiTE9BRFNVSzpsb2Fkc2MzIik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSA4KQogICAgewogICAgY2hvb3NlbiA9IFRleHREcmF3Q3JlYXRlKC0wLjUwMCwgLTIuMDAwLCAiTE9BRFNVSzpsb2Fkc2M0Iik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSA5KQogICAgewogICAgY2hvb3NlbiA9IFRleHREcmF3Q3JlYXRlKC0wLjUwMCwgLTIuMDAwLCAiTE9BRFNVSzpsb2Fkc2M1Iik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSAxMCkKICAgIHsKICAgIGNob29zZW4gPSBUZXh0RHJhd0NyZWF0ZSgtMC41MDAsIC0yLjAwMCwgIkxPQURTVUs6bG9hZHNjNiIpOwpUZXh0RHJhd0ZvbnQoY2hvb3NlbiwgNCk7ClRleHREcmF3VGV4dFNpemUoY2hvb3NlbiwgNjQxLjUwMCwgNDUxLjAwMCk7ClRleHREcmF3Q29sb3IoY2hvb3NlbiwgLTEpOwpUZXh0RHJhd1Nob3dGb3JBbGwoY2hvb3Nlbik7CiAgICB9CiAgICBpZih0ZXh0ZXIgPT0gMTEpCiAgICB7CiAgICBjaG9vc2VuID0gVGV4dERyYXdDcmVhdGUoLTAuNTAwLCAtMi4wMDAsICJMT0FEU1VLOmxvYWRzYzciKTsKVGV4dERyYXdGb250KGNob29zZW4sIDQpOwpUZXh0RHJhd1RleHRTaXplKGNob29zZW4sIDY0MS41MDAsIDQ1MS4wMDApOwpUZXh0RHJhd0NvbG9yKGNob29zZW4sIC0xKTsKVGV4dERyYXdTaG93Rm9yQWxsKGNob29zZW4pOwogICAgfQogICAgaWYodGV4dGVyID09IDEyKQogICAgewogICAgY2hvb3NlbiA9IFRleHREcmF3Q3JlYXRlKC0wLjUwMCwgLTIuMDAwLCAiTE9BRFNVSzpsb2Fkc2M4Iik7ClRleHREcmF3Rm9udChjaG9vc2VuLCA0KTsKVGV4dERyYXdUZXh0U2l6ZShjaG9vc2VuLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihjaG9vc2VuLCAtMSk7ClRleHREcmF3U2hvd0ZvckFsbChjaG9vc2VuKTsKICAgIH0KICAgIGlmKHRleHRlciA9PSAxMykKICAgIHsKICAgIGNob29zZW4gPSBUZXh0RHJhd0NyZWF0ZSgtMC41MDAsIC0yLjAwMCwgIkxPQURTVUs6bG9hZHNjOSIpOwpUZXh0RHJhd0ZvbnQoY2hvb3NlbiwgNCk7ClRleHREcmF3VGV4dFNpemUoY2hvb3NlbiwgNjQxLjUwMCwgNDUxLjAwMCk7ClRleHREcmF3Q29sb3IoY2hvb3NlbiwgLTEpOwpUZXh0RHJhd1Nob3dGb3JBbGwoY2hvb3Nlbik7CiAgICB9Cn0KCgoKZm9yd2FyZCBVcGRhdGVCYXJzKG1vZGVpZCk7CnB1YmxpYyBVcGRhdGVCYXJzKG1vZGVpZCkKewoKCQlpZihQcm9ncmVzc0JhckFsbCA9PSAxMikgUHJvZ3Jlc3NCYXJBbGwgPSAxOwogICAgICAgIG5ldyBzdHJbMzBdOwogICAgICAgIGlmKFByb2dyZXNzQmFyQWxsID09IDApICAgICAgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifmx+Li4uLi4uLi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gMSkgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Ln5sfi4uLi4uLi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gMikgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li5+bH4uLi4uLi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gMykgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4ufmx+Li4uLi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gNCkgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4uLn5sfi4uLi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gNSkgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4uLi5+bH4uLi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gNikgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4uLi4ufmx+Li4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gNykgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4uLi4uLn5sfi4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gOCkgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4uLi4uLi5+bH4uLiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gOSkgZm9ybWF0KHN0cixzaXplb2Yoc3RyKSwifnd+Li4uLi4uLi4ufmx+LiIpOwogICAgICAgIGVsc2UgaWYoUHJvZ3Jlc3NCYXJBbGwgPT0gMTApIGZvcm1hdChzdHIsc2l6ZW9mKHN0ciksIn53fi4uLi4uLi4uLn5sfi4iKTsKICAgICAgICBlbHNlIGlmKFByb2dyZXNzQmFyQWxsID09IDExKQoJCXsKCgkJCWZvcihuZXcgaSA9IDA7IGkgPCBNQVhfUExBWUVSUzsgaSsrKQoJCXsKCgkJCVRleHREcmF3SGlkZUZvclBsYXllcihpLFByb2dyZXNzQmFyKTsKCQkJVGV4dERyYXdIaWRlRm9yUGxheWVyKGksY2hvb3Nlbik7CgkJCX0KCSAJCWZvcm1hdChzdHIsc2l6ZW9mKHN0ciksIn53fi4uLi4uLi4uLi4iKTsKCQkgICAgS2lsbFRpbWVyKHRpbWVyYmFycmEpOwoJCSAgICBOdW92YU1vZGUobW9kZWlkKTsKCQkJUHJvZ3Jlc3NCYXJBbGwrKzsKCQkJcmV0dXJuIDE7CgkJfQogICAgICAgIFRleHREcmF3U2V0U3RyaW5nKFByb2dyZXNzQmFyLCBzdHIpOwoJCVByb2dyZXNzQmFyQWxsKys7CiAgICAgICAgcmV0dXJuIDE7Cn0KCnB1YmxpYyBPbkZpbHRlclNjcmlwdEluaXQoKQp7CglwcmludCgiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwoJcHJpbnQoIiBBdGxhbnRpZGUgRXZlcnlzdHVmZiBSRUxPQURFRCIpOwoJcHJpbnQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKCVNlbmRSY29uQ29tbWFuZCgibGFuZ3VhZ2UgRU5HL0lUQSIpOwogICAgU2VuZFJjb25Db21tYW5kKCJob3N0bmFtZSBBdGxhbnRpcyBFdmVyeVN0dWZmIik7CiAgICBTZW5kUmNvbkNvbW1hbmQoImdhbWVtb2RldGV4dCBNaW5pbW9kZXMiKTsKICAgIFNlbmRSY29uQ29tbWFuZCgibWFwbmFtZSBTYW4gQW5kcmVhcyIpOwogICAgU2VuZFJjb25Db21tYW5kKCJ3ZWJ1cmwgc2NhbWJpb2V0aWNvLm9yZyIpOwogICAgIFNldFRpbWVyRXgoIkluaXppYWxpenphIiwgMzYwLCB0cnVlLCJpIiw2OSk7CiAgICAgCVByb2dyZXNzQmFyID0gVGV4dERyYXdDcmVhdGUoNTIwLjAwMDAwMCwyOTguMDAwMDAwLCIuLi4uLi4uLi4uIik7CiAJVGV4dERyYXdBbGlnbm1lbnQoUHJvZ3Jlc3NCYXIsMCk7CiAgCVRleHREcmF3QmFja2dyb3VuZENvbG9yKFByb2dyZXNzQmFyLDB4MDAwMDAwZmYpOwogICAJVGV4dERyYXdGb250KFByb2dyZXNzQmFyLDMpOwogICAgVGV4dERyYXdMZXR0ZXJTaXplKFByb2dyZXNzQmFyLDAuNzk5OTk5LDEyLjg5OTk5MCk7CiAgICBUZXh0RHJhd0NvbG9yKFByb2dyZXNzQmFyLDB4ZmZmZmZmZmYpOwogICAgVGV4dERyYXdTZXRPdXRsaW5lKFByb2dyZXNzQmFyLDEpOwogICAgVGV4dERyYXdTZXRQcm9wb3J0aW9uYWwoUHJvZ3Jlc3NCYXIsMSk7CiAgICBUZXh0RHJhd1NldFNoYWRvdyhQcm9ncmVzc0JhciwxKTsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25GaWx0ZXJTY3JpcHRFeGl0KCkKewoJcmV0dXJuIDE7Cn0KCgpuZXcgVGV4dDpUZXh0Ym94ZHJhdzA7Cm5ldyBUZXh0OlRleHRib3hkcmF3MTsKbmV3IFRleHQ6VGV4dGJveGRyYXcyOwpuZXcgVGV4dDpUZXh0Ym94ZHJhdzNbTUFYX1BMQVlFUlNdOwpuZXcgVGV4dDpUZXh0Ym94ZHJhdzRbTUFYX1BMQVlFUlNdOwpuZXcgVGV4dDpUZXh0Ym94ZHJhdzVbTUFYX1BMQVlFUlNdOwpuZXcgVGV4dDpUZXh0Ym94ZHJhdzZbTUFYX1BMQVlFUlNdOwpuZXcgVGV4dDpUZXh0Ym94ZHJhdzhbTUFYX1BMQVlFUlNdOwpuZXcgVGV4dDpUZXh0V0hJVEVDcm9zczE7Cm5ldyBUZXh0OlRleHRXSElURUNyb3NzMjsKbmV3IFRleHQ6VGV4dFdISVRFQ3Jvc3MzOwpuZXcgVGV4dDpUZXh0V0hJVEVDcm9zczQ7Cm5ldyBUZXh0OlRleHRXSElURUNyb3NzNTsKCgpzdG9jayBNb3N0cmFDcm9zc0JpYW5jbyhwbGF5ZXJpZCkKewoJVGV4dERyYXdTaG93Rm9yUGxheWVyKHBsYXllcmlkLFRleHRXSElURUNyb3NzMSk7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dFdISVRFQ3Jvc3MyKTsKCVRleHREcmF3U2hvd0ZvclBsYXllcihwbGF5ZXJpZCxUZXh0V0hJVEVDcm9zczMpOwoJVGV4dERyYXdTaG93Rm9yUGxheWVyKHBsYXllcmlkLFRleHRXSElURUNyb3NzNCk7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dFdISVRFQ3Jvc3M1KTsKCglyZXR1cm4gMTsKfQoKCnN0b2NrIE5hc2NvbmRpQ3Jvc3NCaWFuY28ocGxheWVyaWQpCnsKCVRleHREcmF3SGlkZUZvclBsYXllcihwbGF5ZXJpZCxUZXh0V0hJVEVDcm9zczEpOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRXSElURUNyb3NzMik7CglUZXh0RHJhd0hpZGVGb3JQbGF5ZXIocGxheWVyaWQsVGV4dFdISVRFQ3Jvc3MzKTsKCVRleHREcmF3SGlkZUZvclBsYXllcihwbGF5ZXJpZCxUZXh0V0hJVEVDcm9zczQpOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRXSElURUNyb3NzNSk7CglyZXR1cm4gMTsKfQoKCnN0b2NrIE5hc2NvbmRpU3RhdEJveChwbGF5ZXJpZCkKewoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3MCk7CglUZXh0RHJhd0hpZGVGb3JQbGF5ZXIocGxheWVyaWQsVGV4dGJveGRyYXcxKTsKCVRleHREcmF3SGlkZUZvclBsYXllcihwbGF5ZXJpZCxUZXh0Ym94ZHJhdzIpOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3M1twbGF5ZXJpZF0pOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3NFtwbGF5ZXJpZF0pOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3NVtwbGF5ZXJpZF0pOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3NltwbGF5ZXJpZF0pOwoJVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3OFtwbGF5ZXJpZF0pOwoJcmV0dXJuIDE7Cn0KCnN0b2NrIE1vc3RyYVN0YXRCb3gocGxheWVyaWQpCnsKCW5ldyB0ZXh0c3RyaW5nWzkwXTsKCWZvcm1hdCh0ZXh0c3RyaW5nLDkwLCJZT1UgSEFWRTogJWkgUE9JTlRTIixHZXRQbGF5ZXJTY29yZShwbGF5ZXJpZCkpOwoJVGV4dERyYXdTZXRTdHJpbmcoVGV4dGJveGRyYXczW3BsYXllcmlkXSx0ZXh0c3RyaW5nKTsKCWZvcm1hdCh0ZXh0c3RyaW5nLDkwLCJNT05FWTogJCVpIixHZXRQbGF5ZXJNb25leShwbGF5ZXJpZCkpOwoJVGV4dERyYXdTZXRTdHJpbmcoVGV4dGJveGRyYXc0W3BsYXllcmlkXSx0ZXh0c3RyaW5nKTsKCVRleHREcmF3U2V0U3RyaW5nKFRleHRib3hkcmF3NVtwbGF5ZXJpZF0sIllPVSBDQU4gRUFSTiBQT0lOVFMgQlkgU0lNUExZIFBMQVlJTkciKTsKCW5ldyBtb3J0aSA9IFBsYXllckluZm9bcGxheWVyaWRdW3BEZWF0aHNdOwppZighbW9ydGkpIG1vcnRpID0gMTsKCW5ldyBGbG9hdDprZCA9ICBmbG9hdGRpdihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwS2lsbHNdLCBtb3J0aSk7Cglmb3JtYXQodGV4dHN0cmluZyw5MCwiS0lMTFM6ICVkIERFQVRIUzogJWQgLSBLL0Q6ICUuMmYiLFBsYXllckluZm9bcGxheWVyaWRdW3BLaWxsc10sUGxheWVySW5mb1twbGF5ZXJpZF1bcERlYXRoc10sa2QpOwoJVGV4dERyYXdTZXRTdHJpbmcoVGV4dGJveGRyYXc2W3BsYXllcmlkXSx0ZXh0c3RyaW5nKTsKCVRleHREcmF3U2V0U3RyaW5nKFRleHRib3hkcmF3OFtwbGF5ZXJpZF0sIllPVSBDQU4gVU5MT0NLIFJFV0FSRFMgV0lUSCBUSE9TRSBQT0lOVFMgWU9VIEVBUk4hIik7Ci8vCVRleHREcmF3U2hvd0ZvclBsYXllcihwbGF5ZXJpZCx0ZXh0c2NyZWVuKTsKCVRleHREcmF3U2hvd0ZvclBsYXllcihwbGF5ZXJpZCxUZXh0Ym94ZHJhdzEpOwoJVGV4dERyYXdTaG93Rm9yUGxheWVyKHBsYXllcmlkLFRleHRib3hkcmF3Mik7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dGJveGRyYXczW3BsYXllcmlkXSk7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dGJveGRyYXc0W3BsYXllcmlkXSk7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dGJveGRyYXc1W3BsYXllcmlkXSk7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dGJveGRyYXc2W3BsYXllcmlkXSk7CglUZXh0RHJhd1Nob3dGb3JQbGF5ZXIocGxheWVyaWQsVGV4dGJveGRyYXc4W3BsYXllcmlkXSk7Ci8vCVRleHREcmF3U2hvd0ZvclBsYXllcihwbGF5ZXJpZCxQcm9ncmVzc0Jhcik7CgoJcmV0dXJuIDE7Cn0KbmV3IFRleHQ6UGxheWVyVGV4dGRyYXcxOwoKcHVibGljIE9uUGxheWVyQ29ubmVjdChwbGF5ZXJpZCkKewppZihJc1BsYXllck5QQyhwbGF5ZXJpZCkpIHJldHVybiAxOwogbmV3IHJlcVsyNTZdOwogICAgbmV3IElQWzE2XTsKICAgICAgICBHZXRQbGF5ZXJJcChwbGF5ZXJpZCxJUCxzaXplb2YoSVApKTsKICAgIC8vIGZvcm1hdChJUCxzaXplb2YoSVApLCIxMTcuNTYuMC45OCIpOyAvL1VuLWNvbW1lbnQgdGhpcyBsaW5lIGlmIHlvdSB3YW50IHRvIHB1dCBzb21lIHJhbmRvbSBEdW1teSBJUCB0byB0ZXN0IHRoZSBzY3JpcHQKCiAgICBpZihzdHJsZW4oSVApPDEpIHJldHVybiAxOwogICAgZm9ybWF0KHJlcSwgc2l6ZW9mKHJlcSksImdlb2lwLmN5YmVybmlldmUuY29tLz9JUD0lcyIsSVApOyAvLy8vIFJlcGxhY2UgdGhlIGFkZHJlc3MgKGdlb2lwLmN5YmVybmlldmUuY29tKSBpZiB5b3UndmUgc2V0dXAgeW91ciBvd24gR0VPLUlQIFNlcnZlcgogICAgSFRUUChwbGF5ZXJpZCwgSFRUUF9HRVQsIHJlcSwiIiwiR0VPSVBfSFRUUFJFUVVFU1QiKTsKU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsQ09MT1JfQkxBQ0ssIl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fIik7ClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLENPTE9SX0dSRVksIkJlbnZlbnV0byBzdSBBdGxhbnRpcyBFdmVyeXN0dWZmwq4gMjAxMC8yMDExIFYgMS4xMiIpOwpTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCxDT0xPUl9HUkVZLCJwZXIgY29udGludWFyZSBsb2dnYXRpIG8gcmVnaXN0cmF0aSIpOwpTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCxDT0xPUl9HUkVZLCJMaW5lZTogbm9uc29jb250YXJlIC0gd3d3LmF0bGFudGlzZ2FtaW5nLml0Iik7ClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLENPTE9SX0JMQUNLLCJfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyIpOwpQbGF5ZXJUZXh0ZHJhdzEgPSBUZXh0RHJhd0NyZWF0ZSgtMC41MDAsIC0yLjAwMCwgIkxPQURTVUs6bG9hZHNjdWsiKTsKVGV4dERyYXdGb250KFBsYXllclRleHRkcmF3MSwgNCk7ClRleHREcmF3VGV4dFNpemUoUGxheWVyVGV4dGRyYXcxLCA2NDEuNTAwLCA0NTEuMDAwKTsKVGV4dERyYXdDb2xvcihQbGF5ZXJUZXh0ZHJhdzEsIC0xKTsKVGV4dERyYXdTaG93Rm9yUGxheWVyKHBsYXllcmlkLCBQbGF5ZXJUZXh0ZHJhdzEpOwoKU2V0UGxheWVyQWRtaW5MZXZlbChwbGF5ZXJpZCw1KTsKCmlmKGZleGlzdChVc2VyUGF0aChwbGF5ZXJpZCkpKQoJewoKCQlJTklfUGFyc2VGaWxlKFVzZXJQYXRoKHBsYXllcmlkKSwgIkxvYWRVc2VyXyVzIiwgLmJFeHRyYSA9IHRydWUsIC5leHRyYSA9IHBsYXllcmlkKTsKCQlpZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9PSAwKQoJCXsKICAJCVNob3dQbGF5ZXJEaWFsb2cocGxheWVyaWQsIERJQUxPR19MT0dJTiwgRElBTE9HX1NUWUxFX0lOUFVULCIiQ09MX1dISVRFIkxvZ2luIiwiIkNPTF9XSElURSJFbnRlciB5b3VyIHBhc3N3b3JkIHRvIGxvZ2luIiwiTG9naW4iLCJFeGl0Iik7CiAgCQl9CiAgCQlpZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9PSAxKQoJCXsKICAJCVNob3dQbGF5ZXJEaWFsb2cocGxheWVyaWQsIERJQUxPR19MT0dJTiwgRElBTE9HX1NUWUxFX0lOUFVULCIiQ09MX1dISVRFIkxvZ2luIiwiIkNPTF9XSElURSJJbnNlcmlzY2kgbGEgdHVhIHBhc3N3b3JkIHBlciBlZmZldHR1YXJlIGlsIGxvZ2luIiwiTG9naW4iLCJFc2NpIik7CiAgCQl9Cgl9CgllbHNlCgl7CglTaG93UGxheWVyRGlhbG9nKHBsYXllcmlkLCBESUFMT0dfUkVHSVNURVIsIERJQUxPR19TVFlMRV9JTlBVVCwiIkNPTF9XSElURSJSZWdpc3RyYXRpb24iLCIiQ09MX1dISVRFIkNyZWF0ZSBhIG5ldyBhY2NvdW50IHRvIHN0YXJ0IGhhdmluZyBmdW4hIiwiTmV4dCIsIkV4aXQiKTsKCQoKCX0KCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJEaXNjb25uZWN0KHBsYXllcmlkLCByZWFzb24pCnsKbmV3IG5hbWVbTUFYX1BMQVlFUl9OQU1FXSwgc3RyaW5nWzI0K01BWF9QTEFZRVJfTkFNRV07CkdldFBsYXllck5hbWUocGxheWVyaWQsIG5hbWUsIHNpemVvZihuYW1lKSk7CmlmKHJlYXNvbiA9PSAxKQlmb3JtYXQoc3RyaW5nLCBzaXplb2Yoc3RyaW5nKSwgIlstXSAlcyBbL3FdIiwgbmFtZSk7CmlmKHJlYXNvbiA9PSAwKQlmb3JtYXQoc3RyaW5nLCBzaXplb2Yoc3RyaW5nKSwgIlstXSAlcyBbQ1JBU0hdIiwgbmFtZSk7CmlmKHJlYXNvbiA9PSAyKQlmb3JtYXQoc3RyaW5nLCBzaXplb2Yoc3RyaW5nKSwgIlstXSAlcyBbQURNSU5dIiwgbmFtZSk7ClNlbmRDbGllbnRNZXNzYWdlVG9BbGwoQ09MT1JfUkVELHN0cmluZyk7CnByaW50KHN0cmluZyk7CgluZXcgSU5JOkZpbGUgPSBJTklfT3BlbihVc2VyUGF0aChwbGF5ZXJpZCkpOwoJSU5JX1NldFRhZyhGaWxlLCJkYXRhIik7CglJTklfV3JpdGVJbnQoRmlsZSwiQ2FzaCIsR2V0UGxheWVyTW9uZXkocGxheWVyaWQpKTsKCUlOSV9Xcml0ZUludChGaWxlLCJBZG1pbiIsUGxheWVySW5mb1twbGF5ZXJpZF1bcEFkbWluXSk7CglJTklfV3JpdGVJbnQoRmlsZSwiS2lsbHMiLFBsYXllckluZm9bcGxheWVyaWRdW3BLaWxsc10pOwoJSU5JX1dyaXRlSW50KEZpbGUsIkRlYXRocyIsUGxheWVySW5mb1twbGF5ZXJpZF1bcERlYXRoc10pOwoJSU5JX1dyaXRlSW50KEZpbGUsIkxpbmd1YSIsUGxheWVySW5mb1twbGF5ZXJpZF1bcExpbmd1YV0pOwoJSU5JX1dyaXRlSW50KEZpbGUsIlByZW1pdW0iLFBsYXllckluZm9bcGxheWVyaWRdW3BQcmVtaXVtXSk7CglJTklfV3JpdGVJbnQoRmlsZSwiU2NvcmUiLEdldFBsYXllclNjb3JlKHBsYXllcmlkKSk7CglJTklfQ2xvc2UoRmlsZSk7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyU3Bhd24ocGxheWVyaWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJEZWF0aChwbGF5ZXJpZCwga2lsbGVyaWQsIHJlYXNvbikKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblZlaGljbGVTcGF3bih2ZWhpY2xlaWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25WZWhpY2xlRGVhdGgodmVoaWNsZWlkLCBraWxsZXJpZCkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblBsYXllclRleHQocGxheWVyaWQsIHRleHRbXSkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblBsYXllckNvbW1hbmRUZXh0KHBsYXllcmlkLCBjbWR0ZXh0W10pCnsKCWlmIChzdHJjbXAoIi9teWNvbW1hbmQiLCBjbWR0ZXh0LCB0cnVlLCAxMCkgPT0gMCkKCXsKCQkvLyBEbyBzb21ldGhpbmcgaGVyZQoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCnB1YmxpYyBPblBsYXllckVudGVyVmVoaWNsZShwbGF5ZXJpZCwgdmVoaWNsZWlkLCBpc3Bhc3NlbmdlcikKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblBsYXllckV4aXRWZWhpY2xlKHBsYXllcmlkLCB2ZWhpY2xlaWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJTdGF0ZUNoYW5nZShwbGF5ZXJpZCwgbmV3c3RhdGUsIG9sZHN0YXRlKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyRW50ZXJDaGVja3BvaW50KHBsYXllcmlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyTGVhdmVDaGVja3BvaW50KHBsYXllcmlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyRW50ZXJSYWNlQ2hlY2twb2ludChwbGF5ZXJpZCkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblBsYXllckxlYXZlUmFjZUNoZWNrcG9pbnQocGxheWVyaWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25SY29uQ29tbWFuZChjbWRbXSkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblBsYXllclJlcXVlc3RTcGF3bihwbGF5ZXJpZCkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPbk9iamVjdE1vdmVkKG9iamVjdGlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyT2JqZWN0TW92ZWQocGxheWVyaWQsIG9iamVjdGlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyUGlja1VwUGlja3VwKHBsYXllcmlkLCBwaWNrdXBpZCkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblZlaGljbGVNb2QocGxheWVyaWQsIHZlaGljbGVpZCwgY29tcG9uZW50aWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25WZWhpY2xlUGFpbnRqb2IocGxheWVyaWQsIHZlaGljbGVpZCwgcGFpbnRqb2JpZCkKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblZlaGljbGVSZXNwcmF5KHBsYXllcmlkLCB2ZWhpY2xlaWQsIGNvbG9yMSwgY29sb3IyKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyU2VsZWN0ZWRNZW51Um93KHBsYXllcmlkLCByb3cpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJFeGl0ZWRNZW51KHBsYXllcmlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVySW50ZXJpb3JDaGFuZ2UocGxheWVyaWQsIG5ld2ludGVyaW9yaWQsIG9sZGludGVyaW9yaWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJLZXlTdGF0ZUNoYW5nZShwbGF5ZXJpZCwgbmV3a2V5cywgb2xka2V5cykKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblJjb25Mb2dpbkF0dGVtcHQoaXBbXSwgcGFzc3dvcmRbXSwgc3VjY2VzcykKewoJcmV0dXJuIDE7Cn0KCnB1YmxpYyBPblBsYXllclVwZGF0ZShwbGF5ZXJpZCkgLy9UaGUgcGxheWVyIGNoYW5nZWQgc29tZXRoaW5nCnsKCW5ldyBwTmFtZVtNQVhfUExBWUVSX05BTUVdLCBzdHJpbmdbMTI4XTsgLy9JIGFscmVhZHkgZXhwbGFpbmVkIGl0LiBUb28gbXVjaCBleHBsYWluYXRpb24gZm9yIG9uZSBsaW5lCglpZihHZXRQbGF5ZXJNb25leShwbGF5ZXJpZCkgPiBTb2xkYXp6aVtwbGF5ZXJpZF0pIC8vVGhlIHBsYXllciBoYXMgbW9yZSBtb25leSB0aGVuIHRoZSBzdHJpbmcgc2F5cyAobW9yZSAnYm91dCB0aGF0IGxhdGVyKQoJewoJCUdldFBsYXllck5hbWUocGxheWVyaWQsIHBOYW1lLCBNQVhfUExBWUVSX05BTUUpOyAvL1dpbGwgZ2V0IHRoZSBwbGF5ZXIncyBuYW1lCgkJZm9ybWF0KHN0cmluZywgc2l6ZW9mKHN0cmluZyksICJbQVVUT0JBTl0gJXMgw6ggc3RhdG8gYmFubmF0bzogTU9ORVkgQ0hFQVQuIiwgcE5hbWUpOyAvL0Zvcm1hdCdzIGEgc2NyaXB0OiAiKiAncE5hbWUnIGhhcyBiZWVuIGJhbm5lZDogTU9ORVkgQ0hFQVQiCgkJU2VuZENsaWVudE1lc3NhZ2VUb0FsbCgtMSwgc3RyaW5nKTsgLy9TZW5kIGFuIG1lc3NhZ2UgdG8gQUxMIHRoZSBhY3RpdmUgcGxheWVycyB3aXRoIHRoZSBmb3JtYXR0ZWQgc3RyaW5nOiAiKiAncE5hbWUnIGhhcyBiZWVuIGJhbm5lZDogTU9ORVkgQ0hFQVQiIGluIGFuIFJFRCBDT0xPUgoJCUJhbkV4KHBsYXllcmlkLCAiTW9uZXkgQ2hlYXQiKTsgLy9CYW5zIHRoZSBwbGF5ZXIgd2l0aCB0aGUgcmVhc29uICJNb25leSBDaGVhdCIKCX0KCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJTdHJlYW1JbihwbGF5ZXJpZCwgZm9ycGxheWVyaWQpCnsKCXJldHVybiAxOwp9CgpwdWJsaWMgT25QbGF5ZXJTdHJlYW1PdXQocGxheWVyaWQsIGZvcnBsYXllcmlkKQp7CglyZXR1cm4gMTsKfQoKc3RvY2sgQ0xTKHBsYXllcmlkKSB7Cglmb3IobmV3IGk9MDtpPDEwMDtpKyspIHsgU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsIC0xLCAiICIpOyB9CglyZXR1cm4gMTsgfQoKCglzdG9jayBhX0dpdmVQbGF5ZXJNb25leShwbGF5ZXJpZCwgbW9uZXkpCnsKCVNvbGRhenppW3BsYXllcmlkXSArPSBtb25leTsgLy9XaWxsIGluY3JlYXNlIHRoZSBzdHJpbmc6ICIrPSIKCUdpdmVQbGF5ZXJNb25leShwbGF5ZXJpZCwgbW9uZXkpOyAvL0dpdmUncyB0aGUgcGxheWVyIG1vbmV5Li4uIERVSCA6UCBEb24ndCB1c2UgImFfR2l2ZVBsYXllck1vbmV5IiBoZXJlLgp9CgpzdG9jayBhX1NldFBsYXllck1vbmV5KHBsYXllcmlkLCBtb25leSkKewoJU29sZGF6emlbcGxheWVyaWRdID0gbW9uZXk7IC8vV2lsbCBzZXQgdGhlIHN0cmluZyB0byB0aGUgbW9uZXkgYW1tb3VudAoJUmVzZXRQbGF5ZXJNb25leShwbGF5ZXJpZCk7IC8vUmVzZXQncyBwbGF5ZXIgbW9uZXkKCUdpdmVQbGF5ZXJNb25leShwbGF5ZXJpZCwgbW9uZXkpOyAvL1dpbGwgZ2l2ZSB0aGUgcGxheWVyIG1vbmV5LiBubyBhX0dpdmVQbGF5ZXJNb25leSBuZWVkZWQhCn0KCnB1YmxpYyBPblZlaGljbGVTdHJlYW1Jbih2ZWhpY2xlaWQsIGZvcnBsYXllcmlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uVmVoaWNsZVN0cmVhbU91dCh2ZWhpY2xlaWQsIGZvcnBsYXllcmlkKQp7CglyZXR1cm4gMTsKfQoKcHVibGljIE9uRGlhbG9nUmVzcG9uc2UocGxheWVyaWQsIGRpYWxvZ2lkLCByZXNwb25zZSwgbGlzdGl0ZW0sIGlucHV0dGV4dFtdKQp7CiAgICBzd2l0Y2goIGRpYWxvZ2lkICkKICAgIHsKICAgIGNhc2UgRElBTE9HX1NVQ0NFU1NfMToKICAgICAgICB7CiAgICAgICAgVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLCBQbGF5ZXJUZXh0ZHJhdzEpOwogICAgICAgIGlmICghcmVzcG9uc2UpCiAgICAgICAgewogICAgICAgIAluZXcgSU5JOkZpbGUgPSBJTklfT3BlbihVc2VyUGF0aChwbGF5ZXJpZCkpOwoJSU5JX1NldFRhZyhGaWxlLCJkYXRhIik7CglQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9IDE7CglJTklfV3JpdGVJbnQoRmlsZSwiTGluZ3VhIixQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSk7CglJTklfQ2xvc2UoRmlsZSk7CiAgICAgICAgfQogICAgICAgIGlmKHJlc3BvbnNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICBuZXcgSU5JOkZpbGUgPSBJTklfT3BlbihVc2VyUGF0aChwbGF5ZXJpZCkpOwoJSU5JX1NldFRhZyhGaWxlLCJkYXRhIik7CglQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9IDA7CglJTklfV3JpdGVJbnQoRmlsZSwiTGluZ3VhIixQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSk7CglJTklfQ2xvc2UoRmlsZSk7CgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhc2UgRElBTE9HX1JFR0lTVEVSOgogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIEtpY2socGxheWVyaWQpOwogICAgICAgICAgICBpZihyZXNwb25zZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIXN0cmxlbihpbnB1dHRleHQpKSByZXR1cm4gU2hvd1BsYXllckRpYWxvZyhwbGF5ZXJpZCwgRElBTE9HX1JFR0lTVEVSLCBESUFMT0dfU1RZTEVfSU5QVVQsICIiQ09MX1dISVRFIlJlZ2lzdHJhdGlvbiIsIiJDT0xfUkVEIkludmFsaWQgcGFzc3dvcmQuXG4iQ09MX1dISVRFIkVudGVyIGEgcGFzc3dvcmQgdG8gcmVnaXN0ZXIiLCJOZXh0IiwiRXNjaSIpOwogICAgICAgICAgICAgICAgbmV3IElOSTpGaWxlID0gSU5JX09wZW4oVXNlclBhdGgocGxheWVyaWQpKTsKICAgICAgICAgICAgICAgIElOSV9TZXRUYWcoRmlsZSwiZGF0YSIpOwogICAgICAgICAgICAgICAgSU5JX1dyaXRlSW50KEZpbGUsIlBhc3N3b3JkIix1ZGJfaGFzaChpbnB1dHRleHQpKTsKICAgICAgICAgICAgICAgIElOSV9Xcml0ZUludChGaWxlLCJDYXNoIiwwKTsKICAgICAgICAgICAgICAgIElOSV9Xcml0ZUludChGaWxlLCJBZG1pbiIsMCk7CiAgICAgICAgICAgICAgICBJTklfV3JpdGVJbnQoRmlsZSwiS2lsbHMiLDApOwogICAgICAgICAgICAgICAgSU5JX1dyaXRlSW50KEZpbGUsIkRlYXRocyIsMCk7CiAgICAgICAgICAgICAgICBJTklfV3JpdGVJbnQoRmlsZSwiUHJlbWl1bSIsMCk7CiAgICAgICAgICAgICAgICBJTklfV3JpdGVJbnQoRmlsZSwiU2NvcmUiLDApOwogICAgICAgICAgICAgICAgSU5JX0Nsb3NlKEZpbGUpOwoKICAgICAgICAgICAgICAgIFNob3dQbGF5ZXJEaWFsb2cocGxheWVyaWQsIERJQUxPR19TVUNDRVNTXzEsIERJQUxPR19TVFlMRV9NU0dCT1gsIiJDT0xfV0hJVEUiTGFzdCBzdGVwIiwiIkNPTF9XSElURSJDaG9vc2Ugc2VydmVyIGxhbmd1YWdlIiwiRU5HIiwiSVRBIik7CgkJCX0KICAgICAgICB9CgogICAgICAgIGNhc2UgRElBTE9HX0xPR0lOOgogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAhcmVzcG9uc2UgKSByZXR1cm4gS2ljayAoIHBsYXllcmlkICk7CiAgICAgICAgICAgIGlmKCByZXNwb25zZSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKHVkYl9oYXNoKGlucHV0dGV4dCkgPT0gUGxheWVySW5mb1twbGF5ZXJpZF1bcFBhc3NdKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIElOSV9QYXJzZUZpbGUoVXNlclBhdGgocGxheWVyaWQpLCAiTG9hZFVzZXJfJXMiLCAuYkV4dHJhID0gdHJ1ZSwgLmV4dHJhID0gcGxheWVyaWQpOwogICAgICAgICAgICAgICAgICAgIGFfR2l2ZVBsYXllck1vbmV5KHBsYXllcmlkLCBQbGF5ZXJJbmZvW3BsYXllcmlkXVtwQ2FzaF0pOwogICAgICAgICAgICAgICAgICAgIFNldFBsYXllckFkbWluTGV2ZWwocGxheWVyaWQsUGxheWVySW5mb1twbGF5ZXJpZF1bcEFkbWluXSk7CiAgICAgICAgICAgICAgICAgICAgVGV4dERyYXdIaWRlRm9yUGxheWVyKHBsYXllcmlkLFBsYXllclRleHRkcmF3MSApOwogICAgICAgICAgICAgICAgICAgIGlmKFBsYXllckluZm9bcGxheWVyaWRdW3BMaW5ndWFdID09IDApCgkJewoKCQkJCQlTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCwtMSwiV2VsY29tZSBiYWNrIHRvIHRoZSBzZXJ2ZXIuIEhhdmUgYSBnb29kIHRpbWUgaW4gaGVyZSEiKTsKCQkJCQl9CgkJCQkJIGlmKFBsYXllckluZm9bcGxheWVyaWRdW3BMaW5ndWFdID09IDEpCgkJewoKCQkJCQlTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCwtMSwiQmVudG9ybmF0byBpbiBzZXJ2ZXIuIERpdmVydGl0aSEiKTsKCQkJCQl9CgkJCQkJCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiBpZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9PSAwKQoJCXsKICAgICAgICAgICAgICAgICAgICBTaG93UGxheWVyRGlhbG9nKHBsYXllcmlkLCBESUFMT0dfTE9HSU4sIERJQUxPR19TVFlMRV9JTlBVVCwiIkNPTF9XSElURSJMb2dpbiIsIiJDT0xfUkVEIkludmFsaWQgcGFzc3dvcmQuXG4iQ09MX1dISVRFIkVudGVyIHlvdXIgcGFzc3dvcmQiLCJMb2dpbiIsIkV4aXQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoUGxheWVySW5mb1twbGF5ZXJpZF1bcExpbmd1YV0gPT0gMSkKCQl7CiAgICAgICAgICAgICAgICAgICAgU2hvd1BsYXllckRpYWxvZyhwbGF5ZXJpZCwgRElBTE9HX0xPR0lOLCBESUFMT0dfU1RZTEVfSU5QVVQsIiJDT0xfV0hJVEUiTG9naW4iLCIiQ09MX1JFRCJQYXNzd29yZCBlcnJhdGEuXG4iQ09MX1dISVRFIkluc2VyaXNjaSBsYSBwYXNzd29yZCBwZXIgZW50cmFyZSBuZWwgc2VydmVyIiwiTG9naW4iLCJFc2NpIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKcHVibGljIE9uUGxheWVyQ2xpY2tQbGF5ZXIocGxheWVyaWQsIGNsaWNrZWRwbGF5ZXJpZCwgc291cmNlKQp7CglyZXR1cm4gMTsKfQoKCgoKCgoKLy8gY29tYW5kaQoKQ09NTUFORDpzd2l0Y2hsYW5ndWFnZShwbGF5ZXJpZCwgcGFyYW1zW10pCnsKICBpZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9PSAwKQogIHsKICBQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9IDE7CiAgU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsdmVyZGUsIk9yYSBsYSBsaW5ndWEgcHJpbmNpcGFsZSDDqCBpdGFsaWFuby4iKTsKICByZXR1cm4gMTsKICB9CiAgIGlmKFBsYXllckluZm9bcGxheWVyaWRdW3BMaW5ndWFdID09IDEpCiAgewogIFBsYXllckluZm9bcGxheWVyaWRdW3BMaW5ndWFdID0gMDsKICBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCx2ZXJkZSwiTm93IHlvdXIgbWFpbiBsYW5ndWFnZSBpcyBlbmdsaXNoLiIpOwogIHJldHVybiAxOwogIH0KICByZXR1cm4gMTsKfQoKQ09NTUFORDpjaGFuZ2Vtb2RlKHBsYXllcmlkLCBwYXJhbXNbXSkKewppZighSXNQbGF5ZXJBZG1pbkV4KHBsYXllcmlkKSkgcmV0dXJuIDE7CmlmKGlzbnVsbChwYXJhbXMpKSByZXR1cm4gU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsIEFETVNZU19ERUZBVUxUX0NPTE9SMSwgIlVzYTogL2NoYW5nZW1vZGUgW2lkIG1vZGVdIC0gcGVyIHVuYSBsaXN0YSBjb21wbGV0YSB1c2EgL21vZGVzIik7CmlmKCFpc251bWVyaWMocGFyYW1zKSkgcmV0dXJuIFNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLCBBRE1TWVNfREVGQVVMVF9DT0xPUjEsICJVc2E6IC9jaGFuZ2Vtb2RlIFtpZCBtb2RlXSIpOwpuZXcgdml0dGltYSA9IHN0cnZhbChwYXJhbXMpOyAvLyBpVmFsdWUgaXMgbm93IHZpdHRpbWEKaWYodml0dGltYSA9PSAwKQp7ClNlbmRSY29uQ29tbWFuZCgiY2hhbmdlbW9kZSBHTTEiKTsKCn0KICByZXR1cm4gMTsKfQoKQ09NTUFORDpzdGF0cyhwbGF5ZXJpZCwgcGFyYW1zW10pCnsKICBpZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9PSAwKQogIHsKICBuZXcgSG91ciwgTWludXRlLCBTZWNvbmQ7CmdldHRpbWUoSG91ciwgTWludXRlLCBTZWNvbmQpOwpuZXcgWWVhciwgTW9udGgsIERheSwgc3RyaW5nWzEyOF0sIHN0cmluZzFbMTI4XSwgc3RyaW5nMlsxMjhdOwpnZXRkYXRlKFllYXIsIE1vbnRoLCBEYXkpOwpmb3JtYXQoc3RyaW5nLCBzaXplb2Yoc3RyaW5nKSwiQXRsYW50aXMgRXZlcnlzdHVmZiA9PT09PT09PT09PT09PT09ICUwMmQ6JTAyZDolMDJkICUwMmQvJTAyZC8lZCA9PT09PT09PT09PT09PT09IFN0YXRzIiwgSG91ciwgTWludXRlLCBTZWNvbmQsIERheSwgTW9udGgsIFllYXIpOwpuZXcgcGxheWVybmFtZVtNQVhfUExBWUVSX05BTUVdOwpHZXRQbGF5ZXJOYW1lKHBsYXllcmlkLHBsYXllcm5hbWUsc2l6ZW9mKHBsYXllcm5hbWUpKTsKbmV3IG1vcnRpID0gUGxheWVySW5mb1twbGF5ZXJpZF1bcERlYXRoc107CmlmKCFtb3J0aSkgbW9ydGkgPSAxOwpuZXcgRmxvYXQ6a2QgPSAgZmxvYXRkaXYoUGxheWVySW5mb1twbGF5ZXJpZF1bcEtpbGxzXSwgbW9ydGkpOwpuZXcgcHJlbWl1bWxbMTI4XTsKaWYoUGxheWVySW5mb1twbGF5ZXJpZF1bcFByZW1pdW1dID09IDApeyBmb3JtYXQocHJlbWl1bWwsc2l6ZW9mKHByZW1pdW1sKSwiTm9uZSAoL2dvcHJlbWl1bSB0byBzZWUgYWxsIGFkdmFudGFnZXMhKSIpO30KaWYoUGxheWVySW5mb1twbGF5ZXJpZF1bcFByZW1pdW1dID09IDEpeyBmb3JtYXQocHJlbWl1bWwsc2l6ZW9mKHByZW1pdW1sKSwiU2lsdmVyIik7fQppZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwUHJlbWl1bV0gPT0gMil7IGZvcm1hdChwcmVtaXVtbCxzaXplb2YocHJlbWl1bWwpLCJHb2xkIik7fQpmb3JtYXQoc3RyaW5nMSwgc2l6ZW9mKHN0cmluZzEpLCJOYW1lOiAlcyB8IE1vbmV5OiAlaSB8IEtpbGxzOiAlaSB8IERlYXRoczogJWkgfCBSYXRpbzogJS4yZiB8IFNjb3JlOiAlaSIsIHBsYXllcm5hbWUsIEdldFBsYXllck1vbmV5KHBsYXllcmlkKSwgUGxheWVySW5mb1twbGF5ZXJpZF1bcEtpbGxzXSwgUGxheWVySW5mb1twbGF5ZXJpZF1bcERlYXRoc10sIGtkLCBHZXRQbGF5ZXJTY29yZShwbGF5ZXJpZCkpOwpmb3JtYXQoc3RyaW5nMiwgc2l6ZW9mKHN0cmluZzIpLCJMaWZldGltZSBQcmVtaXVtIExldmVsOiAlcyIsIHByZW1pdW1sKTsKU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsZ2lhbGxvLHN0cmluZyk7ClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbyxzdHJpbmcxKTsKClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbyxzdHJpbmcyKTsKICByZXR1cm4gMTsKICB9CiAgICBpZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwTGluZ3VhXSA9PSAxKQogIHsKICBuZXcgSG91ciwgTWludXRlLCBTZWNvbmQ7CmdldHRpbWUoSG91ciwgTWludXRlLCBTZWNvbmQpOwpuZXcgWWVhciwgTW9udGgsIERheSwgc3RyaW5nWzEyOF0sIHN0cmluZzFbMTI4XSwgc3RyaW5nMlsxMjhdOwpnZXRkYXRlKFllYXIsIE1vbnRoLCBEYXkpOwpmb3JtYXQoc3RyaW5nLCBzaXplb2Yoc3RyaW5nKSwiU3RyZWV0IEdhbmcgV2FycyA9PT09PT09PT09PT09PT09ICUwMmQ6JTAyZDolMDJkICUwMmQvJTAyZC8lZCA9PT09PT09PT09PT09PT09IEluZm8iLCBIb3VyLCBNaW51dGUsIFNlY29uZCwgRGF5LCBNb250aCwgWWVhcik7Cm5ldyBwbGF5ZXJuYW1lW01BWF9QTEFZRVJfTkFNRV07CkdldFBsYXllck5hbWUocGxheWVyaWQscGxheWVybmFtZSxzaXplb2YocGxheWVybmFtZSkpOwpuZXcgbW9ydGkgPSBQbGF5ZXJJbmZvW3BsYXllcmlkXVtwRGVhdGhzXTsKaWYoIW1vcnRpKSBtb3J0aSA9IDE7Cm5ldyBGbG9hdDprZCA9ICBmbG9hdGRpdihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwS2lsbHNdLCBtb3J0aSk7Cm5ldyBwcmVtaXVtbFsxMjhdOwppZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwUHJlbWl1bV0gPT0gMCl7IGZvcm1hdChwcmVtaXVtbCxzaXplb2YocHJlbWl1bWwpLCJOZXNzdW5vICgvZ29wcmVtaXVtIHBlciB2ZWRlcmUgdHV0dGkgaSB2YW50YWdnaSEpIik7fQppZihQbGF5ZXJJbmZvW3BsYXllcmlkXVtwUHJlbWl1bV0gPT0gMSl7IGZvcm1hdChwcmVtaXVtbCxzaXplb2YocHJlbWl1bWwpLCJTaWx2ZXIiKTt9CmlmKFBsYXllckluZm9bcGxheWVyaWRdW3BQcmVtaXVtXSA9PSAyKXsgZm9ybWF0KHByZW1pdW1sLHNpemVvZihwcmVtaXVtbCksIkdvbGQiKTt9CmZvcm1hdChzdHJpbmcxLCBzaXplb2Yoc3RyaW5nMSksIk5vbWU6ICVzIHwgU29sZGk6ICVpIHwgS2lsbHM6ICVpIHwgRGVhdGhzOiAlaSB8IFJhdGlvOiAlLjJmIHwgUHVudGk6ICVpIiwgcGxheWVybmFtZSwgR2V0UGxheWVyTW9uZXkocGxheWVyaWQpLCBQbGF5ZXJJbmZvW3BsYXllcmlkXVtwS2lsbHNdLCBQbGF5ZXJJbmZvW3BsYXllcmlkXVtwRGVhdGhzXSwga2QsIEdldFBsYXllclNjb3JlKHBsYXllcmlkKSk7CmZvcm1hdChzdHJpbmcyLCBzaXplb2Yoc3RyaW5nMiksIkxpdmVsbG8gUHJlbWl1bSBQZXJtYW5lbnRlOiAlcyIsIHByZW1pdW1sKTsKU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsZ2lhbGxvLHN0cmluZyk7ClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbyxzdHJpbmcxKTsKU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsZ2lhbGxvLHN0cmluZzIpOwogIHJldHVybiAxOwogIH0KICByZXR1cm4gMTsKfQoKQ09NTUFORDpzaG93c3RhdHMocGxheWVyaWQsIHBhcmFtc1tdKQp7CmlmKCFJc1BsYXllckFkbWluRXgocGxheWVyaWQpKSByZXR1cm4gMTsKaWYoaXNudWxsKHBhcmFtcykpIHJldHVybiBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCwgQURNU1lTX0RFRkFVTFRfQ09MT1IxLCAiVXNhOiAvc2hvd3N0YXRzIFtpZF0iKTsKaWYoIWlzbnVtZXJpYyhwYXJhbXMpKSByZXR1cm4gU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsIEFETVNZU19ERUZBVUxUX0NPTE9SMSwgIlVzYTogL3Nob3dzdGF0cyBbaWRdIik7Cm5ldyB2aXR0aW1hID0gc3RydmFsKHBhcmFtcyk7IC8vIGlWYWx1ZSBpcyBub3cgdml0dGltYQppZighSXNQbGF5ZXJDb25uZWN0ZWQodml0dGltYSkpIHJldHVybiBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCwgQURNU1lTX0RFRkFVTFRfQ09MT1IxLCAiR2lvY2F0b3JlIG5vbiBjb25uZXNzby4iKTsKCiBuZXcgSG91ciwgTWludXRlLCBTZWNvbmQ7CmdldHRpbWUoSG91ciwgTWludXRlLCBTZWNvbmQpOwpuZXcgWWVhciwgTW9udGgsIERheSwgc3RyaW5nWzEyOF0sIHN0cmluZzFbMTI4XSwgc3RyaW5nMlsxMjhdLCBzdHJpbmczWzEyOF07CmdldGRhdGUoWWVhciwgTW9udGgsIERheSk7CmZvcm1hdChzdHJpbmcsIHNpemVvZihzdHJpbmcpLCJTdHJlZXQgR2FuZyBXYXJzID09PUFETUlOPT09ICUwMmQ6JTAyZDolMDJkICUwMmQvJTAyZC8lZCA9PT1BRE1JTj09PSBTdGF0cyIsIEhvdXIsIE1pbnV0ZSwgU2Vjb25kLCBEYXksIE1vbnRoLCBZZWFyKTsKbmV3IHBsYXllcm5hbWVbTUFYX1BMQVlFUl9OQU1FXTsKR2V0UGxheWVyTmFtZSh2aXR0aW1hLHBsYXllcm5hbWUsc2l6ZW9mKHBsYXllcm5hbWUpKTsKbmV3IG1vcnRpID0gUGxheWVySW5mb1t2aXR0aW1hXVtwRGVhdGhzXTsKaWYoIW1vcnRpKSBtb3J0aSA9IDE7Cm5ldyBGbG9hdDprZCA9ICBmbG9hdGRpdihQbGF5ZXJJbmZvW3ZpdHRpbWFdW3BLaWxsc10sIG1vcnRpKTsKbmV3IHByZW1pdW1sWzEyOF07CmlmKFBsYXllckluZm9bdml0dGltYV1bcFByZW1pdW1dID09IDApeyBmb3JtYXQocHJlbWl1bWwsc2l6ZW9mKHByZW1pdW1sKSwiTmVzc3VubyIpO30KaWYoUGxheWVySW5mb1t2aXR0aW1hXVtwUHJlbWl1bV0gPT0gMSl7IGZvcm1hdChwcmVtaXVtbCxzaXplb2YocHJlbWl1bWwpLCJTaWx2ZXIiKTt9CmlmKFBsYXllckluZm9bdml0dGltYV1bcFByZW1pdW1dID09IDIpeyBmb3JtYXQocHJlbWl1bWwsc2l6ZW9mKHByZW1pdW1sKSwiR29sZCIpO30KZm9ybWF0KHN0cmluZzEsIHNpemVvZihzdHJpbmcxKSwiTm9tZTogJXMgfCBTb2xkaTogJWkgfCBLaWxsczogJWkgfCBEZWF0aHM6ICVpIHwgUmF0aW86ICUuMmYgfCBQdW50aTogJWkiLCBwbGF5ZXJuYW1lLCBHZXRQbGF5ZXJNb25leSh2aXR0aW1hKSwgUGxheWVySW5mb1t2aXR0aW1hXVtwS2lsbHNdLCBQbGF5ZXJJbmZvW3ZpdHRpbWFdW3BEZWF0aHNdLCBrZCwgR2V0UGxheWVyU2NvcmUocGxheWVyaWQpKTsKZm9ybWF0KHN0cmluZzIsIHNpemVvZihzdHJpbmcyKSwiTGl2ZWxsbyBQcmVtaXVtIFBlcm1hbmVudGU6ICVzIiwgcHJlbWl1bWwpOwpuZXcgRmxvYXQ6YWxsYXNhbHV0ZSwgRmxvYXQ6YWxsYXNhbHV0ZTIsIGlwcG9bMTZdOwpHZXRQbGF5ZXJIZWFsdGgodml0dGltYSwgYWxsYXNhbHV0ZSk7CkdldFBsYXllckFybW91cih2aXR0aW1hLCBhbGxhc2FsdXRlMik7CkdldFBsYXllcklwKHZpdHRpbWEsaXBwbyxzaXplb2YoaXBwbykpOwpmb3JtYXQoc3RyaW5nMywgc2l6ZW9mKHN0cmluZzMpLCJIUDogJS4xZiB8IEFQOiAlLjFmIHwgSW5kaXJpenpvIElQOiAlcyB8IFBpbmcgYXR0dWFsZTogJWkgfCBJbnRlcmlvcjogJWkgfCBWaXJ0dWFsIFdvcmxkOiAlaSIsIGFsbGFzYWx1dGUsIGFsbGFzYWx1dGUyLCBpcHBvLCBHZXRQbGF5ZXJQaW5nKHZpdHRpbWEpLCBHZXRQbGF5ZXJJbnRlcmlvcih2aXR0aW1hKSwgR2V0UGxheWVyVmlydHVhbFdvcmxkKHZpdHRpbWEpKTsKU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsZ2lhbGxvLHN0cmluZyk7ClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbyxzdHJpbmcxKTsKClNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbyxzdHJpbmcyKTsKU2VuZENsaWVudE1lc3NhZ2UocGxheWVyaWQsZ2lhbGxvLHN0cmluZzMpOwpyZXR1cm4gMTsKfQoKQ09NTUFORDpoZWxwKHBsYXllcmlkLCBwYXJhbXNbXSkKewogIGlmKFBsYXllckluZm9bcGxheWVyaWRdW3BMaW5ndWFdID09IDApCiAgewoKICBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCxnaWFsbG8sIlN0cmVldCBHYW5nIFdhcnMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gQXZhaWJsZSBDb21tYW5kcyIpOwogIFNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbywiW1NFVFRJTkdTXSAvc3dpdGNobGFuZ3VhZ2UiKTsKICBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCxnaWFsbG8sIltHRU5FUkFMXSAvaGVscCAvYWRtaW5zIC9yZXBvcnQiKTsKICB9CiAgIGlmKFBsYXllckluZm9bcGxheWVyaWRdW3BMaW5ndWFdID09IDEpCiAgewoKICBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCxnaWFsbG8sIlN0cmVldCBHYW5nIFdhcnMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IENvbWFuZGkgRGlzcG9uaWJpbGkiKTsKICBTZW5kQ2xpZW50TWVzc2FnZShwbGF5ZXJpZCxnaWFsbG8sIltJTVBPU1RBWklPTkldIC9zd2l0Y2hsYW5ndWFnZSIpOwogIFNlbmRDbGllbnRNZXNzYWdlKHBsYXllcmlkLGdpYWxsbywiW0dFTkVSQUxFXSAvYWl1dG8gL2FkbWlucyAvcmVwb3J0Iik7CiAgfQogIHJldHVybiAxOwp9CgpDT01NQU5EOmFpdXRvKHBsYXllcmlkLCBwYXJhbXNbXSkKewogIHJldHVybiBjbWRfaGVscChwbGF5ZXJpZCwgcGFyYW1zKTsKfQoKQ09NTUFORDppbmZvKHBsYXllcmlkLCBwYXJhbXNbXSkKewogIHJldHVybiBjbWRfc3RhdHMocGxheWVyaWQsIHBhcmFtcyk7Cn0=