#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <time.h>
enum { false , true } ;
typedef int bool;
HANDLE hOut;
time_t start, endet;
int width = 55 ;
int height = 36 ;
bool ende = false ;
int mainLoop = 0 ;
int cScore = 0 , yScore = 0 ;
int links = 65 , rechts = 68 , beenden = 81 , modifikator = 0 , siegPunkte = 5 ;
char * st1;
char * st2;
char * st3;
char * st4;
char * st5;
char * st6;
char * st7;
char * st8;
char * st9;
char * st10;
char * ausgabe;
char name[ 40 ] ;
char pfad[ 60 ] = "C:\\ Machbar.txt" ;
char zwischenPfad[ 60 ] = "" ;
char schwierigkeit[ 20 ] = "Machbar" ;
char schwierigkeit1[ 20 ] = "Amateur" ;
char schwierigkeit2[ 20 ] = "Machbar" ;
char schwierigkeit3[ 20 ] = "Veteran" ;
char schwierigkeit4[ 20 ] = "Nervt\224 tend" ;
char spielergebnis[ 20 ] = "" ;
const int delay = 50 ;
double high[ 20 ] , dif = 0.0f ;
float maxSpeed = 3.2f , compv = 8.0f , speed = 0.0f ;
typedef struct
{
float x, y; // Bewegung
int size;
float ox, oy; // Anfangstellung der Pads
float vx; // KI Steuerung
} spieler;
void spieler_( spieler * this, int _x, int _y, int _size)
{
this-> x = ( float ) ( _x) ;
this-> y = ( float ) ( _y) ;
this-> size = _size;
this-> ox = ( float ) ( _x) ;
this-> oy = ( float ) ( _y) ;
}
// Pads zeichnen
void draw( spieler * this)
{
int i;
COORD p;
p.X = ( int ) ( this-> ox) - this-> size ;
p.Y = ( int ) ( this-> oy) ;
SetConsoleCursorPosition( hOut, p) ;
for ( i = - this-> size; i < this-> size + modifikator; ++ i)
{
}
p.X = ( int ) ( this-> x) - this-> size; // Pads zeichnen
p.Y = ( int ) ( this-> y) ;
SetConsoleCursorPosition( hOut, p) ;
SetConsoleTextAttribute( hOut, 10 ) ;
for ( i = - this-> size; i < this-> size + modifikator; i++ )
{
}
SetConsoleTextAttribute( hOut, 15 ) ;
this-> ox = this-> x;
this-> oy = this-> y;
}
typedef struct ball
{
float x, y, ox, oy; // aktuelle und Anfangsstellung des Balls
float vx, vy; // Geschwindigkeit x, y
} ball;
void ball_( ball * this, int _x, int _y) {
this-> x = ( float ) ( _x) ;
this-> y = ( float ) ( _y) ;
this-> ox = ( float ) ( this-> x) ;
this-> oy = ( float ) ( this-> y) ;
this-> vx = this-> vy = 0 ;
}
// Ball zeichnen
void drawball( ball * this)
{
COORD p;
p.X = ( int ) ( this-> ox) ;
p.Y = ( int ) ( this-> oy) ;
SetConsoleCursorPosition( hOut, p) ;
p.X = ( int ) ( this-> x) ;
p.Y = ( int ) ( this-> y) ;
SetConsoleCursorPosition( hOut, p) ;
SetConsoleTextAttribute( hOut, 12 ) ;
SetConsoleTextAttribute( hOut, 15 ) ;
this-> ox = this-> x;
this-> oy = this-> y;
}
// Alles zurücksetzen
void reset( spieler * you, spieler * comp, ball * b, bool gestartet, int you_score, int comp_score)
{
b-> x = ( float ) ( width / 2 - 1 ) ;
b-> y = ( float ) ( height / 2 ) ;
you-> x = comp-> x = ( float ) ( width / 2 ) ;
comp-> vx = 0.0f ;
b
-> vx
= ( float ) ( rand ( ) % 3 ) - 1.5f ; b-> vy = 1 ;
gestartet = false ;
{
COORD p;
p.X = 0 ;
p.Y = height;
SetConsoleCursorPosition( hOut, p) ;
printf ( "\n | Your score: %i | Computer score: %i ||| Speed: 0 |\n " , you_score
, comp_score
) ; }
}
// Größe der Konsole festlegen
void setWindowSize( int x, int y)
{
SMALL_RECT sr_window = { 0 , 0 , x - 1 , y - 1 } ;
COORD extension;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE) , & csbi) ; // Akutelle Fensterpuffer Größe ermitteln
extension.X = max( x, csbi.dwMaximumWindowSize .X ) ;
extension.Y = max( y, csbi.dwMaximumWindowSize .Y ) ;
SetConsoleScreenBufferSize( GetStdHandle( STD_OUTPUT_HANDLE) , extension) ; // Puffer auf max Werte setzen
SetConsoleWindowInfo( GetStdHandle( STD_OUTPUT_HANDLE) , TRUE, & sr_window) ; // Fenster auf max Werte setzen
extension.X = x;
extension.Y = y;
SetConsoleScreenBufferSize( GetStdHandle( STD_OUTPUT_HANDLE) , extension) ; // Puffer auf Fenstergröße setzen
}
// Highscore anzeigen
void highscoreAusgeben( )
{
strcat ( zwischenPfad
, pfad
) ; // Pfad in zwischenPfad zwischenspeichern char einlesen[ 69 ] ; // Array um Inhalt der txt zwischen zu speichern
printf ( "Welche Highscores wollen sie anschauen?\n \n " ) ;
int auswahl = _getch( ) ; // Hihscorelistenauswahl einlesen
system ( "cls" ) ; // Konsole leeren
if ( auswahl == 49 ) // ansonsten Highscore ausgeben
{
FILE* FDatei; // Zeiger auf Highscore txt erstellen
strcpy ( pfad
, "C:\\ Amateur.txt" ) ; // Highscore Datei öffnen, auslesen und in die Konsole schreiben FDatei
= fopen ( pfad
, "r" ) ; // Highscore txt öffnen und lesen int i = 1 ; // Startwert für Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
if ( ! FDatei)
{
FDatei
= fopen ( pfad
, "w" ) ; printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
else if ( fgets ( einlesen
, 50 , FDatei
) == NULL
) // wird ein ":" in der Datei gefunden? Falls nicht, "Keine Highscores" Meldung ausgeben {
printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
fclose ( FDatei
) ; // Datei schliessen }
else
{
FDatei
= fopen ( pfad
, "r" ) ; // noch einmal schließen und öffnen, um wieder am Anfang der Datei zu beginnen while ( fgets ( einlesen
, 50 , FDatei
) ) // ansonsten Highscore ausgeben & lese bis Dateiende {
ausgabe
= strchr ( einlesen
, '.' ) ; // Punkt im eingelesenen String suchen ausgabe += 1 ; // Zeiger um 1 nach rechts verschieben, um den Punkt nicht mit auszugeben
printf ( "%i. %s" , i
, ausgabe
) ; // bearbeiteten String ausgeben i++; // Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
}
fclose ( FDatei
) ; // Datei schliessen printf ( "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
}
else if ( auswahl == 50 ) // ansonsten Highscore ausgeben
{
FILE* FDatei; // Zeiger auf Highscore txt erstellen
strcpy ( pfad
, "C:\\ Machbar.txt" ) ; // Highscore Datei öffnen, auslesen und in die Konsole schreiben FDatei
= fopen ( pfad
, "r" ) ; // Highscore txt öffnen und lesen int i = 1 ; // Startwert für Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
if ( ! FDatei)
{
FDatei
= fopen ( pfad
, "w" ) ; printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
fclose ( FDatei
) ; // Datei schliessen
}
else if ( fgets ( einlesen
, 50 , FDatei
) == NULL
) // wird ein ":" in der Datei gefunden? Falls nicht, "Keine Highscores" Meldung ausgeben {
printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; fclose ( FDatei
) ; // Datei schliessen int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
else
{
FDatei
= fopen ( pfad
, "r" ) ; // noch einmal schließen und öffnen, um wieder am Anfang der Datei zu beginnen while ( fgets ( einlesen
, 50 , FDatei
) ) // ansonsten Highscore ausgeben & lese bis Dateiende {
ausgabe
= strchr ( einlesen
, '.' ) ; // Punkt im eingelesenen String suchen ausgabe += 1 ; // Zeiger um 1 nach rechts verschieben, um den Punkt nicht mit auszugeben
printf ( "%i. %s" , i
, ausgabe
) ; // bearbeiteten String ausgeben i++; // Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
}
fclose ( FDatei
) ; // Datei schliessen printf ( "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
}
else if ( auswahl == 51 ) // ansonsten Highscore ausgeben
{
FILE* FDatei; // Zeiger auf Highscore txt erstellen
strcpy ( pfad
, "C:\\ Veteran.txt" ) ; // Highscore Datei öffnen, auslesen und in die Konsole schreiben FDatei
= fopen ( pfad
, "r" ) ; // Highscore txt öffnen und lesen int i = 1 ; // Startwert für Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
if ( ! FDatei)
{
FDatei
= fopen ( pfad
, "w" ) ; printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
else if ( fgets ( einlesen
, 50 , FDatei
) == NULL
) // wird ein ":" in der Datei gefunden? Falls nicht, "Keine Highscores" Meldung ausgeben {
printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; fclose ( FDatei
) ; // Datei schliessen int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
else
{
FDatei
= fopen ( pfad
, "r" ) ; // noch einmal schließen und öffnen, um wieder am Anfang der Datei zu beginnen while ( fgets ( einlesen
, 50 , FDatei
) ) // ansonsten Highscore ausgeben & lese bis Dateiende {
ausgabe
= strchr ( einlesen
, '.' ) ; // Punkt im eingelesenen String suchen ausgabe += 1 ; // Zeiger um 1 nach rechts verschieben, um den Punkt nicht mit auszugeben
printf ( "%i. %s" , i
, ausgabe
) ; // bearbeiteten String ausgeben i++; // Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
}
fclose ( FDatei
) ; // Datei schliessen
printf ( "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
}
else if ( auswahl == 52 ) // ansonsten Highscore ausgeben
{
FILE* FDatei; // Zeiger auf Highscore txt erstellen
strcpy ( pfad
, "C:\\ Nervt\224 tend.txt" ) ; FDatei
= fopen ( pfad
, "r" ) ; // Highscore txt öffnen und lesen int i = 1 ; // Startwert für Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
if ( ! FDatei)
{
FDatei
= fopen ( pfad
, "w" ) ; printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
else if ( fgets ( einlesen
, 50 , FDatei
) == NULL
) // wird ein ":" in der Datei gefunden? Falls nicht, "Keine Highscores" Meldung ausgeben {
printf ( "\n Leider hat noch niemand einen Highscore aufgestellt!\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; fclose ( FDatei
) ; // Datei schliessen int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
else
{
FDatei
= fopen ( pfad
, "r" ) ; // noch einmal schließen und öffnen, um wieder am Anfang der Datei zu beginnen while ( fgets ( einlesen
, 50 , FDatei
) ) // ansonsten Highscore ausgeben & lese bis Dateiende {
ausgabe
= strchr ( einlesen
, '.' ) ; // Punkt im eingelesenen String suchen ausgabe += 1 ; // Zeiger um 1 nach rechts verschieben, um den Punkt nicht mit auszugeben
printf ( "%i. %s" , i
, ausgabe
) ; // bearbeiteten String ausgeben i++; // Vorzeichen (1. , 2. , 3....) für Ausgabe erhöhen
}
fclose ( FDatei
) ; // Datei schliessen printf ( "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <1> Zur\201 ck zum Hauptmen\201 " ) ; // falls Highscore Datei noch nicht vorhanden, erstelle diese
int auswahl = _getch( ) ; // zurück zum Menü Abfrage (falls 1 gedrückt wird)
if ( auswahl == 49 )
{
return ;
}
}
}
strcpy ( pfad
, zwischenPfad
) ; // ursprünglichen Pfad -> strcpy ( zwischenPfad
, "" ) ; // -> wiederherstellen }
// Highscore in Datei schreiben
void highscoreEinlesen( )
{
FILE* FDatei;
FDatei
= fopen ( pfad
, "r" ) ; //-------------------------------------------------------- Zahlen einlesen --------------------------------------------------------------------------------------
char score[ 60 ] ;
char * sc;
int i = 0 ;
while ( fgets ( score
, 40 , FDatei
) != NULL
) {
sc
= strchr ( score
, ':' ) ; // Highscore aus der Textdatei lesen und in double Array speichern i++;
}
//-------------------------------------------------------- Namen einlesen --------------------------------------------------------------------------------------
FDatei
= fopen ( pfad
, "r" ) ; // Datei öffnen und lesen char * ptr = ":" ;
if ( fgets ( score
, 60 , FDatei
) != NULL
) {
FDatei
= fopen ( pfad
, "r" ) ; // Datei öffnen und lesen
char platz1[ 60 ] = "" ;
if ( fgets ( platz1
, 60 , FDatei
) != NULL
) {
st1 += 1 ;
}
char platz2[ 60 ] = "" ;
if ( fgets ( platz2
, 60 , FDatei
) != NULL
) {
st2 += 1 ;
}
char platz3[ 60 ] = "" ;
if ( fgets ( platz3
, 60 , FDatei
) != NULL
) {
st3 += 1 ;
}
char platz4[ 60 ] = "" ;
if ( fgets ( platz4
, 60 , FDatei
) != NULL
) {
st4 += 1 ;
}
char platz5[ 60 ] = "" ;
if ( fgets ( platz5
, 60 , FDatei
) != NULL
) {
st5 += 1 ;
}
char platz6[ 60 ] = "" ;
if ( fgets ( platz6
, 60 , FDatei
) != NULL
) {
st6 += 1 ;
}
char platz7[ 60 ] = "" ;
if ( fgets ( platz7
, 60 , FDatei
) != NULL
) {
st7 += 1 ;
}
char platz8[ 60 ] = "" ;
if ( fgets ( platz8
, 60 , FDatei
) != NULL
) {
st8 += 1 ;
}
char platz9[ 60 ] = "" ;
if ( fgets ( platz9
, 60 , FDatei
) != NULL
) {
st9 += 1 ;
}
FDatei
= fopen ( pfad
, "w+" ) ; // Datei öffnen und Higscores an Dateiende anhängen
if ( dif <= high[ 0 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = high[ 5 ] ;
high[ 5 ] = high[ 4 ] ;
high[ 4 ] = high[ 3 ] ;
high[ 3 ] = high[ 2 ] ;
high[ 2 ] = high[ 1 ] ;
high[ 1 ] = high[ 0 ] ;
high[ 0 ] = dif;
if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 0 ] ) ; if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 1 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 2 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 3 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 4 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 5 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 0 ] && dif <= high[ 1 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = high[ 5 ] ;
high[ 5 ] = high[ 4 ] ;
high[ 4 ] = high[ 3 ] ;
high[ 3 ] = high[ 2 ] ;
high[ 2 ] = high[ 1 ] ;
high[ 1 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 1 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 2 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 3 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 4 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 5 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 0 ] && dif > high[ 1 ] && dif <= high[ 2 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = high[ 5 ] ;
high[ 5 ] = high[ 4 ] ;
high[ 4 ] = high[ 3 ] ;
high[ 3 ] = high[ 2 ] ;
high[ 2 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 2 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 3 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 4 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 5 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 0 ] && dif >= high[ 1 ] && dif > high[ 2 ] && dif <= high[ 3 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = high[ 5 ] ;
high[ 5 ] = high[ 4 ] ;
high[ 4 ] = high[ 3 ] ;
high[ 3 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 3 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 4 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 5 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 3 ] && dif <= high[ 4 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = high[ 5 ] ;
high[ 5 ] = high[ 4 ] ;
high[ 4 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 3 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 4 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 5 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ;
}
else if ( dif > high[ 4 ] && dif <= high[ 5 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = high[ 5 ] ;
high[ 5 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 3 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 4 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 5 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 5 ] && dif <= high[ 6 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = high[ 6 ] ;
high[ 6 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 3 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 4 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 5 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 6 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 6 ] && dif <= high[ 7 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = high[ 7 ] ;
high[ 7 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 3 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 4 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 5 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 6 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 7 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 7 ] && dif <= high[ 8 ] )
{
high[ 9 ] = high[ 8 ] ;
high[ 8 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 3 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 4 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 5 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 6 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 7 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs\n " , name
, high
[ 8 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs" , st9
, high
[ 9 ] ) ; }
else if ( dif > high[ 8 ] && dif <= high[ 9 ] )
{
high[ 9 ] = dif;
if ( st1
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st1
, high
[ 0 ] ) ; if ( st2
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st2
, high
[ 1 ] ) ; if ( st3
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st3
, high
[ 2 ] ) ; if ( st4
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st4
, high
[ 3 ] ) ; if ( st5
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st5
, high
[ 4 ] ) ; if ( st6
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st6
, high
[ 5 ] ) ; if ( st7
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st7
, high
[ 6 ] ) ; if ( st8
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st8
, high
[ 7 ] ) ; if ( st9
!= NULL
) fprintf ( FDatei
, ".%s: %.2fs\n " , st9
, high
[ 8 ] ) ; if ( name
!= NULL
) fprintf ( FDatei
, ".%s's Zeit: %.2fs" , name
, high
[ 9 ] ) ; }
fclose ( FDatei
) ; // Datei schließen }
// Vorgehen nach Spielende abfragen
void spielende( )
{
int auswahl;
COORD p;
printf ( "------------------------------------\n " ) ; printf ( "| %s \t \t |\n |----------------------------------|" , spielergebnis
) ; // Tabelle mit Spielergebnissen anzeigen printf ( "\n | Endstand: Du <%i> Computer <%i> |\n " , yScore
, cScore
) ; printf ( "------------------------------------\n \n " ) ; printf ( "W\204 hlen sie eine M\224 glichkeit!\n \n " ) ; printf ( "<1> Zur\201 ck zum Hauptmen\201 \n " ) ; printf ( "<2> Highscore anzeigen\n " ) ; p.X = ( int ) ( 20 ) ;
p.Y = ( int ) ( 1 ) ;
SetConsoleCursorPosition( hOut, p) ;
// Menü nach Spielende darstellen
auswahl = _getch( ) ;
if ( auswahl == 49 )
{
mainLoop = 0 ;
return ;
}
else if ( auswahl == 50 )
{
highscoreAusgeben( ) ;
}
else if ( ende == true )
{
ende = false ;
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; Sleep( 2000 ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen
system ( "cls" ) ; // und zurück zum Hautpmenü spielende( ) ;
}
}
// Spiel ausführen
void spielen( )
{
int i, gestartet;
int you_score = 0 , comp_score = 0 ; // Statistik auf Standard setzen
spieler you, comp; ball b;
setWindowSize( 55 , 39 ) ;
// Oberfläche zeichnen
SetConsoleTextAttribute( hOut, 15 ) ;
for ( i = 0 ; i < width - 1 ; ++ i)
for ( i = 0 ; i < height - 1 ; ++ i)
{
for ( i = 0 ; i < width - 3 ; ++ i)
}
for ( i = 0 ; i < width - 1 ; ++ i)
printf ( "\n | Your score: 0 | Computer score: 0 ||| Speed: 0 |\n " ) ; for ( i = 0 ; i < width - 1 ; ++ i)
// Ende Oberfläche zeichnen
gestartet = false ; // Spiel gestartet?
spieler_( & you, width / 2 , height - 2 , 4 ) ; // Spieler erstellen
spieler_( & comp, width / 2 , 2 , 4 ) ; // KI erstellen
ball_( & b, width / 2 - 1 , height / 2 ) ; // Ball erstellen
// Ball in zufällige Richtung zum Spieler
b.
vx = ( float ) ( rand ( ) % 3 ) - 1.5f ; b.vy = 1 ;
comp.vx = 0 ;
time ( & start
) ; // Stoppuhr für Highscore starten
while ( true )
{
if ( gestartet == true ) // Spiel gestartet?
{
if ( GetAsyncKeyState( links) )
{
if ( strcmp ( schwierigkeit
, schwierigkeit1
) == 0 ) {
you.x -= 2.5 ;
}
else if ( strcmp ( schwierigkeit
, schwierigkeit2
) == 0 ) {
you.x -= 2 ;
}
else if ( strcmp ( schwierigkeit
, schwierigkeit3
) == 0 ) {
you.x -= 2 ;
}
else if ( strcmp ( schwierigkeit
, schwierigkeit4
) == 0 ) {
you.x -= 2.5 ;
}
}
else if ( GetAsyncKeyState( rechts) )
{
if ( strcmp ( schwierigkeit
, schwierigkeit1
) == 0 ) {
you.x += 2.5 ;
}
else if ( strcmp ( schwierigkeit
, schwierigkeit2
) == 0 ) {
you.x += 2 ;
}
else if ( strcmp ( schwierigkeit
, schwierigkeit3
) == 0 ) {
you.x += 2 ;
}
else if ( strcmp ( schwierigkeit
, schwierigkeit4
) == 0 ) {
you.x += 2.5 ;
}
}
else if ( GetAsyncKeyState( beenden) )
{
COORD p;
p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.8f ) ;
SetConsoleCursorPosition( hOut, p) ;
printf ( "Spiel wirklich beenden?" ) ; p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.6f ) ;
SetConsoleCursorPosition( hOut, p) ; // Abfrage, ob Spiel fortsetzen oder Beenden
printf ( "<1> Weiterspielen\n " ) ; // wird druch das drücken der q Taste auf p.X = ( int ) ( width / 2 - 16 ) ; // in die Konsole geschrieben und eingelesen
p.Y = ( int ) ( height / 1.55f ) ;
SetConsoleCursorPosition( hOut, p) ;
printf ( "<2> Spiel beenden\n \n " ) ; p.X = ( int ) ( width / 2 - 17 ) ;
p.Y = ( int ) ( height / 1.35f ) ;
SetConsoleCursorPosition( hOut, p) ;
char c;
while ( ( c = _getch( ) ) != EOF && c != 'q' ) ; // Puffer automatisch im Hintergrund leeren
int auswahl = _getch( ) ;
while ( GetAsyncKeyState( VK_RETURN) ) ;
if ( auswahl == 49 )
{
p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.8f ) ;
SetConsoleCursorPosition( hOut, p) ;
p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.6f ) ;
SetConsoleCursorPosition( hOut, p) ; // nach Eingabe, wird der Dialog wieder entfernt
p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.55f ) ;
SetConsoleCursorPosition( hOut, p) ;
p.X = ( int ) ( width / 2 - 17 ) ;
p.Y = ( int ) ( height / 1.35f ) ;
SetConsoleCursorPosition( hOut, p) ;
}
else
{
time ( & endet
) ; // Stoppuhr stoppen break ;
}
}
// Ballgeschwindigkeit für Statistik berechnen
speed = x + y;
COORD p;
p.X = ( int ) ( 47 ) ;
p.Y = ( int ) ( 37 ) ;
SetConsoleCursorPosition( hOut, p) ;
// KI zum Ball führen
comp.vx -= ( float ) ( comp.x - b.x ) / compv;
comp.vx *= 0.83f ;
// KI Geschwindigeit in Abhängigkeit der Ballgeschwindigkeit anpassen
comp.x += comp.vx ;
// Bewegungsgrenzen setzen
if ( you.x < you.size + 1 )
{
you.x = ( float ) ( you.size + 1 ) ;
}
else if ( you.x > width - you.size - 2 - modifikator)
{
you.x = ( float ) ( width - you.size - 2 - modifikator) ;
}
// KI Bewegungsgrenze setzen
if ( comp.x < comp.size + 1 )
{
comp.x = ( float ) ( comp.size + 1 ) ;
}
else if ( comp.x > width - comp.size - 2 - modifikator)
{
comp.x = ( float ) ( width - comp.size - 2 - modifikator) ;
}
// Ball Höchstgeschwindigkeit einhalten
if ( b.vx < - maxSpeed)
{
b.vx = - maxSpeed;
}
else if ( b.vx > maxSpeed)
{
b.vx = maxSpeed;
}
// Dem Ball an der aktuellen Position Geschwindigkeit zuführen
b.x += b.vx ;
b.y += b.vy ;
// Hat der Ball den Spieler getroffen?
if ( b.y >= you.y - 1 && b.y <= you.y + 1 )
{
if ( b.x > you.x - you.size && b.x < you.x + you.size )
{
b.vy *= - 1 ;
b.vx += ( float ) ( b.x - you.x ) / 3 ;
b.y = you.y - 1 ;
}
}
// Hat der Ball die KI getroffen?
if ( b.y <= comp.y + 1 && b.y >= comp.y - 1 )
{
if ( b.x > comp.x - comp.size && b.x < comp.x + comp.size )
{
b.vy *= - 1 ;
b.vx += ( float ) ( b.x - comp.x ) / 3 ;
b.y = comp.y + 1 ;
}
}
// Hat der Ball die Grenzen überschritten?(Punkt bekommen)
if ( b.y >= height)
{
comp_score++;
cScore = comp_score;
reset( & you, & comp, & b, gestartet, you_score, comp_score ) ;
}
else if ( b.y <= 0 )
{
you_score++;
yScore = you_score;
reset( & you, & comp, & b, gestartet, you_score, comp_score ) ;
}
if ( b.x <= 1 )
{
b.vx *= - 1 ;
b.x = 1.0f ;
}
else if ( b.x >= width - 3 )
{
b.vx *= - 1 ;
b.x = ( float ) ( width - 3 ) ;
}
}
else if ( you_score == siegPunkte)
{
dif = 1000 ;
high[ 0 ] = dif, high[ 1 ] = dif, high[ 2 ] = dif, high[ 3 ] = dif; // Standartwerte initialisieren
system ( "cls" ) ; // Konsole leeren time ( & endet
) ; // Stoppuhr stoppen dif
= difftime ( endet
, start
) ; // Highscore Zeit berechnen (ende - anfang) strcpy ( spielergebnis
, "" ) ; // spielergebnis string leeren strcat ( spielergebnis
, "Gewonnen!!!" ) ; // Endergebnis speichern für spätere Ausgabe printf ( "\n \n \n \n \n \n \n \n \t \t Gewonnen!!! :)" ) ; // Siegmeldung ausgeben printf ( "\n \n \n \n ...um fortzufahren bitte Enter dr\201 cken..." ) ; char c;
while ( ( c = _getch( ) ) != EOF && c != 13 ) ; // Puffer automatisch im Hintergrund leeren
//-------------------------------------------------------- Namen einlesen -------------------------------------------------------------------------------------------
printf ( "Bitte geben sie ihren Namen ein: " ) ; // Benutzer zur Namenseingabe aufforden und diesen in "name" abspeichern
//-------------------------------------------------------- Highscores einlesen --------------------------------------------------------------------------------------
FILE * FDatei;
FDatei
= fopen ( pfad
, "r" ) ; if ( ! FDatei)
{
FDatei
= fopen ( pfad
, "w" ) ; // falls öffnen der Datei fehlgeschlagen, eine Datei erstellen fclose ( FDatei
) ; // Datei schließen }
highscoreEinlesen( ) ;
mainLoop = 1 ; // über main Funktion zu spielende() springen
break ;
}
else if ( comp_score == siegPunkte)
{
system ( "cls" ) ; // Konsole leeren time ( & endet
) ; // Stoppuhr stoppen dif
= difftime ( endet
, start
) ; // Highscore Zeit berechnen (ende - anfang) strcpy ( spielergebnis
, "" ) ; // spielergebnis string leeren strcat ( spielergebnis
, "Verloren!!!" ) ; // Endergebnis speichern für spätere Ausgabe printf ( "\n \n \n \n \n \n \n \n \t \t Verloren!!! :(" ) ; // Niederlage Meldung ausgeben printf ( "\n \n \n \n ...um fortzufahren bitte Enter dr\201 cken..." ) ; char c;
while ( ( c = _getch( ) ) != EOF && c != 13 ) ; // Puffer automatisch im Hintergrund leeren
mainLoop = 1 ; // über main Funktion zu spielende() springen
break ;
}
else
{
// Startbedingungüberprüfen (Leertaste gedrückt?)
COORD p;
p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.5f ) ;
SetConsoleCursorPosition( hOut, p) ;
printf ( "Press the space bar to start..." ) ;
if ( GetAsyncKeyState( VK_SPACE) )
{
COORD p;
p.X = ( int ) ( width / 2 - 16 ) ;
p.Y = ( int ) ( height / 1.5f ) ;
SetConsoleCursorPosition( hOut, p) ;
gestartet = true ;
}
}
// Alles zeichnen
draw( & you) ;
draw( & comp) ;
drawball( & b) ;
// Verzögern
Sleep( delay) ;
}
}
// Konfiguration der Tastenbelegung
void steuerung( )
{
printf ( "===========================================================================\n " ) ; printf ( "== Bitte w\204 hlen sie die Taste die sie ver\204 ndern m\224 chten und dr\201 cken sie ==\n " ) ; printf ( "== anschlie\341 end die Taste die sie zuweisen wollen! ==\n " ) ; // Menü darstellen printf ( "===========================================================================\n \n " ) ;
printf ( "<1> Links\t \t \t Aktuelle Taste: %c\n " , links
) ; printf ( "<2> Rechts\t \t \t Aktuelle Taste: %c\n " , rechts
) ; // aktuelle Tastenbelegung anzeigen printf ( "<3> Beenden\t \t \t Aktuelle Taste: %c\n " , beenden
) ; printf ( "<4> Zur\201 ck zum Hauptmen\201 \n \n " ) ; printf ( "Beachte: Kleinbuchstaben m\201 ssen leider im Moment noch als\n " ) ; printf ( "\t Gro\341 buchstaben angegeben werden!" ) ;
int auswahl = _getch( ) ;
if ( auswahl == 49 )
{
links = _getch( ) ; // Auf Benutzereingabe warten und auswerten
steuerung( ) ;
}
else if ( auswahl == 50 )
{
rechts = _getch( ) ;
system ( "cls" ) ; // warten auf Eingabe und neue Taste setzen steuerung( ) ;
}
else if ( auswahl == 51 )
{
beenden = _getch( ) ;
steuerung( ) ;
}
else if ( auswahl == 52 )
{
system ( "cls" ) ; // zurück zum Hauptmenü return ;
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; Sleep( 2000 ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen
system ( "cls" ) ; // und zurück zum Hautpmenü steuerung( ) ;
}
}
// Schwierigkeitsgrad, Ballgeschwindigkeit
// einstellen, alles zurücksetzen
void einstellungen( )
{
printf ( "Bitte w\204 hlen sie eine Einstellung die sie ver\204 ndern m\224 chten!\n \n " ) ; printf ( "<1> Schwieriegkeitsgrad \204 ndern\t \t Aktuelle Schwierigkeit: %s\n " , schwierigkeit
) ; // Menü mit aktuellen Einstellungen anzeigen printf ( "<2> Maximale Ballgeschwindigkeit\t Aktuelle Geschwindigkeit: %.2f\n " , maxSpeed
) ; printf ( "<3> Anzahl der Punkte bis zum Sieg\t Aktuelle Siegpunkte: %i\n " , siegPunkte
) ; printf ( "<4> Alle Einstellungen zur\201 cksetzen\n " ) ; printf ( "<5> Highscore zur\201 cksetzten\n " ) ; printf ( "<6> Zur\201 ck zum Hauptmen\201 \n \n " ) ;
int auswahl = _getch( ) ; // Eingabe in Variable speichern
if ( auswahl == 49 ) // Eingabe auswerten
{
printf ( "W\204 hlen sie ihren bevorzugten Schwierigkeitsgrad!\n \n " ) ; printf ( "<1> Amateur\n " ) ; // Schwierigkeitsgrad Menü öffnen printf ( "<4> Nervt\224 tend\n " ) ;
int auswahl = _getch( ) ;
if ( auswahl == 49 )
{
modifikator = 0 ;
modifikator += 2 ; // Padlänge anpassen
maxSpeed = 1.8f ; // Ballgeschwindigkeit je nach Auswahl anpassen
strcat ( schwierigkeit
, "Amateur" ) ; // Schwierigkeitsgradanzeige im Einstellungsmenü aktualisieren strcpy ( pfad
, "C:\\ Amateur.txt" ) ; // Pfad für Highscoredatei aktualisieren compv = 10.0f ; // Computer Schnelligkeit setzen
return ; // (alter String wird gelöscht und neuer angehängt)
}
else if ( auswahl == 50 )
{
modifikator = 0 ;
strcat ( schwierigkeit
, "Machbar" ) ; strcpy ( pfad
, "C:\\ Machbar.txt" ) ; compv = 8.0f ;
maxSpeed = 3.2f ;
return ;
}
else if ( auswahl == 51 )
{
modifikator = 0 ;
modifikator -= 2 ;
strcat ( schwierigkeit
, "Veteran" ) ; strcpy ( pfad
, "C:\\ Veteran.txt" ) ; compv = 6.0f ;
maxSpeed = 4.5f ;
return ;
}
else if ( auswahl == 52 )
{
modifikator = 0 ;
modifikator -= 4 ;
strcat ( schwierigkeit
, "Nervt\224 tend" ) ; strcpy ( pfad
, "C:\\ Nervt\224 tend.txt" ) ; compv = 3.7f ;
maxSpeed = 6.0f ;
return ;
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen Sleep( 2000 ) ; // und zurück zum Hautpmenü
return ;
}
}
else if ( auswahl == 50 )
{
printf ( "Neue Ballgeschwindigkeit eingeben!\n \n " ) ; // Abfrage nach neuer Ballgeschwindigkeit
if ( maxSpeed != 1.8f && maxSpeed != 2.8f && maxSpeed != 3.5f && maxSpeed != 5 ) // Falls Ballgeschwindigkeit ungleich den Voreinstellungen, so
{
strcpy ( schwierigkeit
, "" ) ; // wird die Schwierigkeitsanzeige auf "Persönlich" gesetzt strcat ( schwierigkeit
, "Pers\224 nlich" ) ; }
einstellungen( ) ; // zurück zum Einstellungsmenü
}
else if ( auswahl == 51 )
{
printf ( "Neue Anzahl der ben\224 tigten Siegpunkte eingeben!\n \n " ) ; // Abfrage nach neuer Ballgeschwindigkeit return ;
}
else if ( auswahl == 52 )
{
printf ( "Sind sie sich sicher, dass sie alle Einstellungen zur\201 cksetzen m\224 chten?\n \n " ) ; // Fragen, ob der Benutzer sicher ist, dass er die Einstellungen zurücksetzen möcht printf ( "<1> Ja, alle l\224 schen\n " ) ; printf ( "<2> Nein, zur\201 ck zu Einstellungen" ) ;
int auswahl = _getch( ) ; // Benutzereingabe einlesen
if ( auswahl == 49 )
{
strcat ( schwierigkeit
, "Machbar" ) ; // Alle Werte auf Standard setzen maxSpeed = 3.2f ;
links = 65 , rechts = 68 , beenden = 81 ;
printf ( "\n Einstellungen erfolgreich zur\201 ckgesetzt!" ) ; Sleep( 2500 ) ;
return ;
}
else if ( auswahl == 50 )
{
einstellungen( ) ; // falls nein, zurück zum Einstellungsmenü
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; Sleep( 2000 ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen
system ( "cls" ) ; // und zurück zum Hautpmenü einstellungen( ) ;
}
}
else if ( auswahl == 53 )
{
printf ( "Sind sie sich sicher, dass sie alle Highscores l\224 schen m\224 chten?\n \n " ) ; // Fragen, ob der Benutzer sicher ist, dass er die Highscores löschen möchte printf ( "<1> Ja, alle l\224 schen\n " ) ; printf ( "<2> Nein, zur\201 ck zu Einstellungen" ) ;
int auswahl = _getch( ) ; // Benutzereingabe einlesen
if ( auswahl == 49 )
{
FILE * FDatei;
FDatei
= fopen ( "C:\\ Amateur" , "w" ) ; // Alte Highscore Textdatei leeren FDatei
= fopen ( "C:\\ Machbar.txt" , "w" ) ; // Alte Highscore Textdatei leeren FDatei
= fopen ( "C:\\ Veteran.txt" , "w" ) ; // Alte Highscore Textdatei leeren FDatei
= fopen ( "C:\\ Nervt\224 tend.txt" , "w" ) ; // Alte Highscore Textdatei leeren printf ( "Highscores erfolgreich zur\201 ckgesetzt!" ) ; Sleep( 2000 ) ;
return ;
}
else if ( auswahl == 50 )
{
einstellungen( ) ;
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; Sleep( 2000 ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen
system ( "cls" ) ; // und zurück zum Hautpmenü einstellungen( ) ;
}
}
else if ( auswahl == 54 )
{
system ( "cls" ) ; // zurück zum Hauptmenü return ;
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; Sleep( 2000 ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen
system ( "cls" ) ; // und zurück zum Hautpmenü einstellungen( ) ;
}
}
// Hauptmenü anzeigen und Auswahl auswerten
void menu( )
{
setWindowSize( 80 , 25 ) ;
printf ( "W\204 hlen sie eine M\224 glichkeit!\n \n " ) ; printf ( "<2> Steuerung\n " ) ; // Menü darstellen printf ( "<4> Einstellungen\n " ) ; printf ( "<5> Spiel beenden\n \n " ) ; int auswahl = _getch( ) ;
// Auf Benutzereingabe warten
if ( auswahl == 49 )
{
spielen( ) ;
}
else if ( auswahl == 50 ) // je nach Auswahl, das enstprechende Untermenü öffnen
{
steuerung( ) ;
}
else if ( auswahl == 51 )
{
highscoreAusgeben( ) ;
}
else if ( auswahl == 52 )
{
einstellungen( ) ;
}
else if ( auswahl == 53 )
{
mainLoop = 2 ; // Main Schleife unterbrechen und Programm beenden
}
else
{
printf ( "\n \n Ung\201 ltige Eingabe!\n \n " ) ; Sleep( 2000 ) ; // falls eine Taste, die nicht zur Auswahl stand gedrückt wurde, Ungültige Eingabe anzeigen
menu( ) ; // und zurück zum Hautpmenü
}
}
// Beginn des Programms direkter Verweis nach Menü
int main( )
{
hOut = GetStdHandle( STD_OUTPUT_HANDLE) ;
// Cursor verstecken
CONSOLE_CURSOR_INFO ConCurInf;
ConCurInf.dwSize = 10 ;
ConCurInf.bVisible = false ;
SetConsoleCursorInfo( hOut, & ConCurInf) ;
while ( mainLoop <= 1 )
{
if ( mainLoop == 0 )
{
menu( ) ; // verhindern, dass das Programm frühzeitig beendet wird
}
else if ( mainLoop == 1 )
{
spielende( ) ;
}
}
return 0 ;
}
I2luY2x1ZGUgPHdpbmRvd3MuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjb25pby5oPgojaW5jbHVkZSA8bWF0aC5oPgojaW5jbHVkZSA8dGltZS5oPgoKZW51bSB7ZmFsc2UsdHJ1ZX07CnR5cGVkZWYgaW50IGJvb2w7CgogICAgSEFORExFIGhPdXQ7Cgl0aW1lX3Qgc3RhcnQsZW5kZXQ7CglpbnQgd2lkdGggPSA1NTsKCWludCBoZWlnaHQgPSAzNjsKCWJvb2wgZW5kZSA9IGZhbHNlOwoJaW50IG1haW5Mb29wID0gMDsKCWludCBjU2NvcmUgPSAwLCB5U2NvcmUgPSAwOwoJaW50IGxpbmtzID0gNjUsIHJlY2h0cyA9IDY4LCBiZWVuZGVuID0gODEsIG1vZGlmaWthdG9yID0gMCwgc2llZ1B1bmt0ZSA9IDU7CgljaGFyKiBzdDE7CgljaGFyKiBzdDI7CgljaGFyKiBzdDM7CgljaGFyKiBzdDQ7CgljaGFyKiBzdDU7CgljaGFyKiBzdDY7CgljaGFyKiBzdDc7CgljaGFyKiBzdDg7CgljaGFyKiBzdDk7CgljaGFyKiBzdDEwOwoJY2hhciogYXVzZ2FiZTsKCWNoYXIgbmFtZVs0MF07CgljaGFyIHBmYWRbNjBdID0gIkM6XFxNYWNoYmFyLnR4dCI7CgljaGFyIHp3aXNjaGVuUGZhZFs2MF0gPSAiIjsKCWNoYXIgc2Nod2llcmlna2VpdFsyMF0gPSAiTWFjaGJhciI7CgljaGFyIHNjaHdpZXJpZ2tlaXQxWzIwXSA9ICJBbWF0ZXVyIjsKCWNoYXIgc2Nod2llcmlna2VpdDJbMjBdID0gIk1hY2hiYXIiOwoJY2hhciBzY2h3aWVyaWdrZWl0M1syMF0gPSAiVmV0ZXJhbiI7CgljaGFyIHNjaHdpZXJpZ2tlaXQ0WzIwXSA9ICJOZXJ2dFwyMjR0ZW5kIjsKCWNoYXIgc3BpZWxlcmdlYm5pc1syMF0gPSAiIjsKCWNvbnN0IGludCBkZWxheSA9IDUwOwoJZG91YmxlIGhpZ2hbMjBdLCBkaWYgPSAwLjBmOwoJZmxvYXQgbWF4U3BlZWQgPSAzLjJmLCBjb21wdiA9IDguMGYsIHNwZWVkID0gMC4wZjsKCgoJdHlwZWRlZiBzdHJ1Y3QKCXsKCQlmbG9hdCB4LCB5OwkJCQkJCS8vIEJld2VndW5nCgkJaW50IHNpemU7CgkJZmxvYXQgb3gsIG95OwkJCQkJCS8vIEFuZmFuZ3N0ZWxsdW5nIGRlciBQYWRzCgkJZmxvYXQgdng7CQkJCQkJLy8gS0kgU3RldWVydW5nCgoKCn0gc3BpZWxlcjsKCgl2b2lkIHNwaWVsZXJfKHNwaWVsZXIgKnRoaXMsaW50IF94LCBpbnQgX3ksIGludCBfc2l6ZSkKCXsKCQl0aGlzLT54ID0gKGZsb2F0KShfeCk7CgkJdGhpcy0+eSA9IChmbG9hdCkoX3kpOwoJCXRoaXMtPnNpemUgPSBfc2l6ZTsKCQl0aGlzLT5veCA9IChmbG9hdCkoX3gpOwoJCXRoaXMtPm95ID0gKGZsb2F0KShfeSk7Cgl9CgoJLy8gUGFkcyB6ZWljaG5lbgoJdm9pZCBkcmF3KHNwaWVsZXIgKnRoaXMpCgl7CgkgIGludCBpOwoJCUNPT1JEIHA7CgkJcC5YID0gKGludCkodGhpcy0+b3gpIC0gdGhpcy0+c2l6ZSA7CgkJcC5ZID0gKGludCkodGhpcy0+b3kpOwoJCVNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihoT3V0LCBwKTsKCgkJZm9yIChpID0gLXRoaXMtPnNpemU7IGkgPCB0aGlzLT5zaXplICsgbW9kaWZpa2F0b3I7ICsraSkKCQl7CgkJCXByaW50ZigiICIpOwoJCX0KCgkJcC5YID0gKGludCkodGhpcy0+eCkgLSB0aGlzLT5zaXplOwkJCQkJLy8gUGFkcyB6ZWljaG5lbgoJCXAuWSA9IChpbnQpKHRoaXMtPnkpOwoJCVNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihoT3V0LCBwKTsKCQlTZXRDb25zb2xlVGV4dEF0dHJpYnV0ZShoT3V0LCAxMCk7CgoJCWZvciAoaSA9IC10aGlzLT5zaXplOyBpIDwgdGhpcy0+c2l6ZSArIG1vZGlmaWthdG9yOyBpKyspCgkJewoJCQlwcmludGYoIj0iKTsKCQl9CgoJCVNldENvbnNvbGVUZXh0QXR0cmlidXRlKGhPdXQsIDE1KTsKCQl0aGlzLT5veCA9IHRoaXMtPng7CgkJdGhpcy0+b3kgPSB0aGlzLT55OwoJfQoKCXR5cGVkZWYgc3RydWN0IGJhbGwKCXsKCQlmbG9hdCB4LCB5LCBveCwgb3k7CQkJCS8vIGFrdHVlbGxlIHVuZCBBbmZhbmdzc3RlbGx1bmcgZGVzIEJhbGxzCgkJZmxvYXQgdngsIHZ5OwkJCQkJLy8gR2VzY2h3aW5kaWdrZWl0IHgsIHkKCgoKCn0gYmFsbDsKCnZvaWQgCQliYWxsXyhiYWxsICp0aGlzLGludCBfeCwgaW50IF95KSB7CgkJdGhpcy0+eCA9IChmbG9hdCkoX3gpOwoJCXRoaXMtPnkgPSAoZmxvYXQpKF95KTsKCQl0aGlzLT5veCA9IChmbG9hdCkodGhpcy0+eCk7CgkJdGhpcy0+b3kgPSAoZmxvYXQpKHRoaXMtPnkpOwoJCXRoaXMtPnZ4ID0gdGhpcy0+dnkgPSAwOwoJfQoKCS8vIEJhbGwgemVpY2huZW4KCXZvaWQgZHJhd2JhbGwoYmFsbCAqdGhpcykKCXsKCQlDT09SRCBwOwogCQlwLlggPSAoaW50KSh0aGlzLT5veCk7CgkJcC5ZID0gKGludCkodGhpcy0+b3kpOwoJCVNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihoT3V0LCBwKTsKCQlwcmludGYoIiAiKTsKCQlwLlggPSAoaW50KSh0aGlzLT54KTsKCQlwLlkgPSAoaW50KSh0aGlzLT55KTsKCQlTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oaE91dCwgcCk7CgkJU2V0Q29uc29sZVRleHRBdHRyaWJ1dGUoaE91dCwgMTIpOwoJCXByaW50ZigiMCIpOwoJCVNldENvbnNvbGVUZXh0QXR0cmlidXRlKGhPdXQsIDE1KTsKCQl0aGlzLT5veCA9IHRoaXMtPng7CgkJdGhpcy0+b3kgPSB0aGlzLT55OwoJfQoKCS8vIEFsbGVzIHp1csODwrxja3NldHplbgoJdm9pZCByZXNldChzcGllbGVyICp5b3UsIHNwaWVsZXIgKmNvbXAsIGJhbGwgKmIsIGJvb2wgZ2VzdGFydGV0LCBpbnQgeW91X3Njb3JlLCBpbnQgY29tcF9zY29yZSkKCXsKCQliLT54ID0gKGZsb2F0KSh3aWR0aCAvIDIgLSAxKTsKCQliLT55ID0gKGZsb2F0KShoZWlnaHQgLyAyKTsKCQl5b3UtPnggPSBjb21wLT54ID0gKGZsb2F0KSh3aWR0aCAvIDIpOwoJCWNvbXAtPnZ4ID0gMC4wZjsKCQliLT52eCA9IChmbG9hdCkocmFuZCgpICUgMykgLSAxLjVmOwoJCWItPnZ5ID0gMTsKCQlnZXN0YXJ0ZXQgPSBmYWxzZTsKCQl7CgkJQ09PUkQgcDsKCQlwLlggPSAwOwogCQlwLlkgPSBoZWlnaHQ7CgkJU2V0Q29uc29sZUN1cnNvclBvc2l0aW9uKGhPdXQsIHApOwoJCXByaW50ZigiXG58IFlvdXIgc2NvcmU6ICVpIHwgQ29tcHV0ZXIgc2NvcmU6ICVpIHx8fCBTcGVlZDogICAwICAgfFxuIiwgeW91X3Njb3JlLCAJCQljb21wX3Njb3JlKTsKICAgIH0KCX0KCgkvLyBHcsODwrbDg8W4ZSBkZXIgS29uc29sZSBmZXN0bGVnZW4KCXZvaWQgc2V0V2luZG93U2l6ZShpbnQgeCwgaW50IHkpCgl7CgkJU01BTExfUkVDVCBzcl93aW5kb3cgPSB7MCwgMCwgeCAtIDEsIHkgLSAxfTsKCQlDT09SRCBleHRlbnNpb247CgkJQ09OU09MRV9TQ1JFRU5fQlVGRkVSX0lORk8gY3NiaTsKCgkJR2V0Q29uc29sZVNjcmVlbkJ1ZmZlckluZm8oR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgJmNzYmkpOwkJCQkJICAgICAgICAgICAgICAgIC8vIEFrdXRlbGxlIEZlbnN0ZXJwdWZmZXIgR3LDg8K2w4PFuGUgZXJtaXR0ZWxuCgoJCWV4dGVuc2lvbi5YID0gbWF4KHgsIGNzYmkuZHdNYXhpbXVtV2luZG93U2l6ZS5YKTsKCQlleHRlbnNpb24uWSA9IG1heCh5LCBjc2JpLmR3TWF4aW11bVdpbmRvd1NpemUuWSk7CgoJCVNldENvbnNvbGVTY3JlZW5CdWZmZXJTaXplKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksIGV4dGVuc2lvbik7CQkJLy8gUHVmZmVyIGF1ZiBtYXggV2VydGUgc2V0emVuCgkJU2V0Q29uc29sZVdpbmRvd0luZm8oR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgVFJVRSwgJnNyX3dpbmRvdyk7CQkvLyBGZW5zdGVyIGF1ZiBtYXggV2VydGUgc2V0emVuCgoJCWV4dGVuc2lvbi5YID0geDsKCQlleHRlbnNpb24uWSA9IHk7CgkJU2V0Q29uc29sZVNjcmVlbkJ1ZmZlclNpemUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgZXh0ZW5zaW9uKTsJCQkgICAgICAgICAgICAgIC8vIFB1ZmZlciBhdWYgRmVuc3Rlcmdyw4PCtsODxbhlIHNldHplbgoJfQoKCS8vIEhpZ2hzY29yZSBhbnplaWdlbgoJdm9pZCBoaWdoc2NvcmVBdXNnZWJlbigpCgl7CgkJCXN0cmNhdCh6d2lzY2hlblBmYWQscGZhZCk7CQkJCQkvLyBQZmFkIGluIHp3aXNjaGVuUGZhZCB6d2lzY2hlbnNwZWljaGVybgoJCQljaGFyIGVpbmxlc2VuWzY5XTsJCQkJCQkJLy8gQXJyYXkgdW0gSW5oYWx0IGRlciB0eHQgendpc2NoZW4genUgc3BlaWNoZXJuCgoJCQlzeXN0ZW0oImNscyIpOwoJCQlwcmludGYoIldlbGNoZSBIaWdoc2NvcmVzIHdvbGxlbiBzaWUgYW5zY2hhdWVuP1xuXG4iKTsKCQkJcHJpbnRmKCI8MT4gQW1hdGV1clxuIik7CgkJCXByaW50ZigiPDI+IE1hY2hiYXJcbiIpOwoJCQlwcmludGYoIjwzPiBWZXRlcmFuXG4iKTsKCQkJcHJpbnRmKCI8ND4gTmVydnRcMjI0dGVuZCIpOwoKCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkvLyBIaWhzY29yZWxpc3RlbmF1c3dhaGwgZWlubGVzZW4KCQkJc3lzdGVtKCJjbHMiKTsJCQkJCQkJCS8vIEtvbnNvbGUgbGVlcmVuCgoJCQlpZihhdXN3YWhsID09IDQ5KQkJCQkJCQkvLyBhbnNvbnN0ZW4gSGlnaHNjb3JlIGF1c2dlYmVuCgkJCXsKCQkJCUZJTEUqIEZEYXRlaTsJCQkJCQkJLy8gWmVpZ2VyIGF1ZiBIaWdoc2NvcmUgdHh0IGVyc3RlbGxlbgoJCQkJc3RyY3B5KHBmYWQsICJDOlxcQW1hdGV1ci50eHQiKTsJCS8vIEhpZ2hzY29yZSBEYXRlaSDDg8K2ZmZuZW4sIGF1c2xlc2VuIHVuZCBpbiBkaWUgS29uc29sZSBzY2hyZWliZW4KCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJCS8vIEhpZ2hzY29yZSB0eHQgw4PCtmZmbmVuIHVuZCBsZXNlbgoJCQkJaW50IGkgPSAxOwkJCQkJCQkJLy8gU3RhcnR3ZXJ0IGbDg8K8ciBWb3J6ZWljaGVuICgxLiAsIDIuICwgMy4uLi4pIGbDg8K8ciBBdXNnYWJlIGVyaMODwrZoZW4KCgkJCQlpZighRkRhdGVpKQoJCQkJewoJCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJ3Iik7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CgkJCQkJcHJpbnRmKCJcbkxlaWRlciBoYXQgbm9jaCBuaWVtYW5kIGVpbmVuIEhpZ2hzY29yZSBhdWZnZXN0ZWxsdCFcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48MT4gWnVyXDIwMWNrIHp1bSBIYXVwdG1lblwyMDEiKTsJLy8gZmFsbHMgSGlnaHNjb3JlIERhdGVpIG5vY2ggbmljaHQgdm9yaGFuZGVuLCBlcnN0ZWxsZSBkaWVzZQoKCQkJCQlpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCS8vIHp1csODwrxjayB6dW0gTWVuw4PCvCBBYmZyYWdlIChmYWxscyAxIGdlZHLDg8K8Y2t0IHdpcmQpCgkJCQkJaWYoYXVzd2FobCA9PSA0OSkKCQkJCQl7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmKGZnZXRzKGVpbmxlc2VuLDUwLEZEYXRlaSkgPT0gTlVMTCkJCS8vIHdpcmQgZWluICI6IiBpbiBkZXIgRGF0ZWkgZ2VmdW5kZW4/IEZhbGxzIG5pY2h0LCAiS2VpbmUgSGlnaHNjb3JlcyIgTWVsZHVuZyBhdXNnZWJlbgoJCQkJewoJCQkJCXByaW50ZigiXG5MZWlkZXIgaGF0IG5vY2ggbmllbWFuZCBlaW5lbiBIaWdoc2NvcmUgYXVmZ2VzdGVsbHQhXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuPDE+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxIik7CgkJCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkvLyB6dXLDg8K8Y2sgenVtIE1lbsODwrwgQWJmcmFnZSAoZmFsbHMgMSBnZWRyw4PCvGNrdCB3aXJkKQoJCQkJCWlmKGF1c3dhaGwgPT0gNDkpCgkJCQkJewoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJCWZjbG9zZShGRGF0ZWkpOwkJCQkJCQkJLy8gRGF0ZWkgc2NobGllc3NlbgoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWZjbG9zZShGRGF0ZWkpOwoJCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJCQkvLyBub2NoIGVpbm1hbCBzY2hsaWXDg8W4ZW4gdW5kIMODwrZmZm5lbiwgdW0gd2llZGVyIGFtIEFuZmFuZyBkZXIgRGF0ZWkgenUgYmVnaW5uZW4KCQkJCQl3aGlsZSAoZmdldHMoZWlubGVzZW4sNTAsRkRhdGVpKSkJCQkvLyBhbnNvbnN0ZW4gSGlnaHNjb3JlIGF1c2dlYmVuICYgbGVzZSBiaXMgRGF0ZWllbmRlCgkJCQkJewoJCQkJCQlhdXNnYWJlID0gc3RyY2hyIChlaW5sZXNlbiwgJy4nKTsJCS8vIFB1bmt0IGltIGVpbmdlbGVzZW5lbiBTdHJpbmcgc3VjaGVuCgkJCQkJCWF1c2dhYmUgKz0gMTsJCQkJCQkJLy8gWmVpZ2VyIHVtIDEgbmFjaCByZWNodHMgdmVyc2NoaWViZW4sIHVtIGRlbiBQdW5rdCBuaWNodCBtaXQgYXVzenVnZWJlbgoJCQkJCQlwcmludGYoIiVpLiAlcyIsIGksIGF1c2dhYmUpOwkJCS8vIGJlYXJiZWl0ZXRlbiBTdHJpbmcgYXVzZ2ViZW4KCQkJCQkJaSsrOwkJCQkJCQkJCS8vIFZvcnplaWNoZW4gKDEuICwgMi4gLCAzLi4uLikgZsODwrxyIEF1c2dhYmUgZXJow4PCtmhlbgoJCQkJCX0KCQkJCQlmY2xvc2UoRkRhdGVpKTsJCQkJCQkJCS8vIERhdGVpIHNjaGxpZXNzZW4KCQkJCQlwcmludGYoIlxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuPDE+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxIik7CS8vIGZhbGxzIEhpZ2hzY29yZSBEYXRlaSBub2NoIG5pY2h0IHZvcmhhbmRlbiwgZXJzdGVsbGUgZGllc2UKCgkJCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkvLyB6dXLDg8K8Y2sgenVtIE1lbsODwrwgQWJmcmFnZSAoZmFsbHMgMSBnZWRyw4PCvGNrdCB3aXJkKQoJCQkJCWlmKGF1c3dhaGwgPT0gNDkpCgkJCQkJewoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgaWYoYXVzd2FobCA9PSA1MCkJCQkJCQkvLyBhbnNvbnN0ZW4gSGlnaHNjb3JlIGF1c2dlYmVuCgkJCXsKCQkJCUZJTEUqIEZEYXRlaTsJCQkJCQkJLy8gWmVpZ2VyIGF1ZiBIaWdoc2NvcmUgdHh0IGVyc3RlbGxlbgoJCQkJc3RyY3B5KHBmYWQsICJDOlxcTWFjaGJhci50eHQiKTsJCS8vIEhpZ2hzY29yZSBEYXRlaSDDg8K2ZmZuZW4sIGF1c2xlc2VuIHVuZCBpbiBkaWUgS29uc29sZSBzY2hyZWliZW4KCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJCS8vIEhpZ2hzY29yZSB0eHQgw4PCtmZmbmVuIHVuZCBsZXNlbgoJCQkJaW50IGkgPSAxOwkJCQkJCQkJLy8gU3RhcnR3ZXJ0IGbDg8K8ciBWb3J6ZWljaGVuICgxLiAsIDIuICwgMy4uLi4pIGbDg8K8ciBBdXNnYWJlIGVyaMODwrZoZW4KCgkJCQlpZighRkRhdGVpKQoJCQkJewoJCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJ3Iik7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CgkJCQkJcHJpbnRmKCJcbkxlaWRlciBoYXQgbm9jaCBuaWVtYW5kIGVpbmVuIEhpZ2hzY29yZSBhdWZnZXN0ZWxsdCFcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48MT4gWnVyXDIwMWNrIHp1bSBIYXVwdG1lblwyMDEiKTsJLy8gZmFsbHMgSGlnaHNjb3JlIERhdGVpIG5vY2ggbmljaHQgdm9yaGFuZGVuLCBlcnN0ZWxsZSBkaWVzZQoKCQkJCQlpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCS8vIHp1csODwrxjayB6dW0gTWVuw4PCvCBBYmZyYWdlIChmYWxscyAxIGdlZHLDg8K8Y2t0IHdpcmQpCgkJCQkJaWYoYXVzd2FobCA9PSA0OSkKCQkJCQl7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQkJZmNsb3NlKEZEYXRlaSk7CQkJCQkJCQkvLyBEYXRlaSBzY2hsaWVzc2VuCgoJCQkJfQoJCQkJZWxzZSBpZihmZ2V0cyhlaW5sZXNlbiw1MCxGRGF0ZWkpID09IE5VTEwpCQkJCQkJCS8vIHdpcmQgZWluICI6IiBpbiBkZXIgRGF0ZWkgZ2VmdW5kZW4/IEZhbGxzIG5pY2h0LCAiS2VpbmUgSGlnaHNjb3JlcyIgTWVsZHVuZyBhdXNnZWJlbgoJCQkJewoJCQkJCXByaW50ZigiXG5MZWlkZXIgaGF0IG5vY2ggbmllbWFuZCBlaW5lbiBIaWdoc2NvcmUgYXVmZ2VzdGVsbHQhXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuPDE+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxIik7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CQkJCQkJCQkvLyBEYXRlaSBzY2hsaWVzc2VuCgkJCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkvLyB6dXLDg8K8Y2sgenVtIE1lbsODwrwgQWJmcmFnZSAoZmFsbHMgMSBnZWRyw4PCvGNrdCB3aXJkKQoJCQkJCWlmKGF1c3dhaGwgPT0gNDkpCgkJCQkJewoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWZjbG9zZShGRGF0ZWkpOwoJCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJCQkvLyBub2NoIGVpbm1hbCBzY2hsaWXDg8W4ZW4gdW5kIMODwrZmZm5lbiwgdW0gd2llZGVyIGFtIEFuZmFuZyBkZXIgRGF0ZWkgenUgYmVnaW5uZW4KCQkJCQl3aGlsZSAoZmdldHMoZWlubGVzZW4sNTAsRkRhdGVpKSkJCQkvLyBhbnNvbnN0ZW4gSGlnaHNjb3JlIGF1c2dlYmVuICYgbGVzZSBiaXMgRGF0ZWllbmRlCgkJCQkJewoJCQkJCQlhdXNnYWJlID0gc3RyY2hyIChlaW5sZXNlbiwgJy4nKTsJCS8vIFB1bmt0IGltIGVpbmdlbGVzZW5lbiBTdHJpbmcgc3VjaGVuCgkJCQkJCWF1c2dhYmUgKz0gMTsJCQkJCQkJLy8gWmVpZ2VyIHVtIDEgbmFjaCByZWNodHMgdmVyc2NoaWViZW4sIHVtIGRlbiBQdW5rdCBuaWNodCBtaXQgYXVzenVnZWJlbgoJCQkJCQlwcmludGYoIiVpLiAlcyIsIGksIGF1c2dhYmUpOwkJCS8vIGJlYXJiZWl0ZXRlbiBTdHJpbmcgYXVzZ2ViZW4KCQkJCQkJaSsrOwkJCQkJCQkJCS8vIFZvcnplaWNoZW4gKDEuICwgMi4gLCAzLi4uLikgZsODwrxyIEF1c2dhYmUgZXJow4PCtmhlbgoJCQkJCX0KCQkJCQlmY2xvc2UoRkRhdGVpKTsJCQkJCQkJCS8vIERhdGVpIHNjaGxpZXNzZW4KCQkJCQlwcmludGYoIlxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuPDE+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxIik7CS8vIGZhbGxzIEhpZ2hzY29yZSBEYXRlaSBub2NoIG5pY2h0IHZvcmhhbmRlbiwgZXJzdGVsbGUgZGllc2UKCgkJCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkvLyB6dXLDg8K8Y2sgenVtIE1lbsODwrwgQWJmcmFnZSAoZmFsbHMgMSBnZWRyw4PCvGNrdCB3aXJkKQoJCQkJCWlmKGF1c3dhaGwgPT0gNDkpCgkJCQkJewoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgaWYoYXVzd2FobCA9PSA1MSkJCQkJCQkvLyBhbnNvbnN0ZW4gSGlnaHNjb3JlIGF1c2dlYmVuCgkJCXsKCQkJCUZJTEUqIEZEYXRlaTsJCQkJCQkJLy8gWmVpZ2VyIGF1ZiBIaWdoc2NvcmUgdHh0IGVyc3RlbGxlbgoJCQkJc3RyY3B5KHBmYWQsICJDOlxcVmV0ZXJhbi50eHQiKTsJCS8vIEhpZ2hzY29yZSBEYXRlaSDDg8K2ZmZuZW4sIGF1c2xlc2VuIHVuZCBpbiBkaWUgS29uc29sZSBzY2hyZWliZW4KCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJCS8vIEhpZ2hzY29yZSB0eHQgw4PCtmZmbmVuIHVuZCBsZXNlbgoJCQkJaW50IGkgPSAxOwkJCQkJCQkJLy8gU3RhcnR3ZXJ0IGbDg8K8ciBWb3J6ZWljaGVuICgxLiAsIDIuICwgMy4uLi4pIGbDg8K8ciBBdXNnYWJlIGVyaMODwrZoZW4KCgkJCQlpZighRkRhdGVpKQoJCQkJewoJCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJ3Iik7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CgkJCQkJcHJpbnRmKCJcbkxlaWRlciBoYXQgbm9jaCBuaWVtYW5kIGVpbmVuIEhpZ2hzY29yZSBhdWZnZXN0ZWxsdCFcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48MT4gWnVyXDIwMWNrIHp1bSBIYXVwdG1lblwyMDEiKTsJLy8gZmFsbHMgSGlnaHNjb3JlIERhdGVpIG5vY2ggbmljaHQgdm9yaGFuZGVuLCBlcnN0ZWxsZSBkaWVzZQoKCQkJCQlpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCS8vIHp1csODwrxjayB6dW0gTWVuw4PCvCBBYmZyYWdlIChmYWxscyAxIGdlZHLDg8K8Y2t0IHdpcmQpCgkJCQkJaWYoYXVzd2FobCA9PSA0OSkKCQkJCQl7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmKGZnZXRzKGVpbmxlc2VuLDUwLEZEYXRlaSkgPT0gTlVMTCkJCQkJCQkJLy8gd2lyZCBlaW4gIjoiIGluIGRlciBEYXRlaSBnZWZ1bmRlbj8gRmFsbHMgbmljaHQsICJLZWluZSBIaWdoc2NvcmVzIiBNZWxkdW5nIGF1c2dlYmVuCgkJCQl7CgkJCQkJcHJpbnRmKCJcbkxlaWRlciBoYXQgbm9jaCBuaWVtYW5kIGVpbmVuIEhpZ2hzY29yZSBhdWZnZXN0ZWxsdCFcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48MT4gWnVyXDIwMWNrIHp1bSBIYXVwdG1lblwyMDEiKTsKCQkJCQlmY2xvc2UoRkRhdGVpKTsJCQkJCQkJCS8vIERhdGVpIHNjaGxpZXNzZW4KCQkJCQlpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCS8vIHp1csODwrxjayB6dW0gTWVuw4PCvCBBYmZyYWdlIChmYWxscyAxIGdlZHLDg8K8Y2t0IHdpcmQpCgkJCQkJaWYoYXVzd2FobCA9PSA0OSkKCQkJCQl7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQl9CgkJCQllbHNlCgkJCQl7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CgkJCQkJRkRhdGVpID0gZm9wZW4ocGZhZCwgInIiKTsJCQkJCS8vIG5vY2ggZWlubWFsIHNjaGxpZcODxbhlbiB1bmQgw4PCtmZmbmVuLCB1bSB3aWVkZXIgYW0gQW5mYW5nIGRlciBEYXRlaSB6dSBiZWdpbm5lbgoJCQkJCXdoaWxlIChmZ2V0cyhlaW5sZXNlbiw1MCxGRGF0ZWkpKQkJCS8vIGFuc29uc3RlbiBIaWdoc2NvcmUgYXVzZ2ViZW4gJiBsZXNlIGJpcyBEYXRlaWVuZGUKCQkJCQl7CgkJCQkJCWF1c2dhYmUgPSBzdHJjaHIgKGVpbmxlc2VuLCAnLicpOwkJLy8gUHVua3QgaW0gZWluZ2VsZXNlbmVuIFN0cmluZyBzdWNoZW4KCQkJCQkJYXVzZ2FiZSArPSAxOwkJCQkJCQkvLyBaZWlnZXIgdW0gMSBuYWNoIHJlY2h0cyB2ZXJzY2hpZWJlbiwgdW0gZGVuIFB1bmt0IG5pY2h0IG1pdCBhdXN6dWdlYmVuCgkJCQkJCXByaW50ZigiJWkuICVzIiwgaSwgYXVzZ2FiZSk7CQkJLy8gYmVhcmJlaXRldGVuIFN0cmluZyBhdXNnZWJlbgoJCQkJCQlpKys7CQkJCQkJCQkJLy8gVm9yemVpY2hlbiAoMS4gLCAyLiAsIDMuLi4uKSBmw4PCvHIgQXVzZ2FiZSBlcmjDg8K2aGVuCgkJCQkJfQoJCQkJCWZjbG9zZShGRGF0ZWkpOwkJCQkJCQkJLy8gRGF0ZWkgc2NobGllc3NlbgoKCQkJCQlwcmludGYoIlxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuPDE+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxIik7CS8vIGZhbGxzIEhpZ2hzY29yZSBEYXRlaSBub2NoIG5pY2h0IHZvcmhhbmRlbiwgZXJzdGVsbGUgZGllc2UKCgkJCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkvLyB6dXLDg8K8Y2sgenVtIE1lbsODwrwgQWJmcmFnZSAoZmFsbHMgMSBnZWRyw4PCvGNrdCB3aXJkKQoJCQkJCWlmKGF1c3dhaGwgPT0gNDkpCgkJCQkJewoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgaWYoYXVzd2FobCA9PSA1MikJCQkJCQkvLyBhbnNvbnN0ZW4gSGlnaHNjb3JlIGF1c2dlYmVuCgkJCXsKCQkJCUZJTEUqIEZEYXRlaTsJCQkJCQkJLy8gWmVpZ2VyIGF1ZiBIaWdoc2NvcmUgdHh0IGVyc3RlbGxlbgoJCQkJc3RyY3B5KHBmYWQsICJDOlxcTmVydnRcMjI0dGVuZC50eHQiKTsKCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJCS8vIEhpZ2hzY29yZSB0eHQgw4PCtmZmbmVuIHVuZCBsZXNlbgoJCQkJaW50IGkgPSAxOwkJCQkJCQkJLy8gU3RhcnR3ZXJ0IGbDg8K8ciBWb3J6ZWljaGVuICgxLiAsIDIuICwgMy4uLi4pIGbDg8K8ciBBdXNnYWJlIGVyaMODwrZoZW4KCgkJCQlpZighRkRhdGVpKQoJCQkJewoJCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJ3Iik7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CgkJCQkJcHJpbnRmKCJcbkxlaWRlciBoYXQgbm9jaCBuaWVtYW5kIGVpbmVuIEhpZ2hzY29yZSBhdWZnZXN0ZWxsdCFcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48MT4gWnVyXDIwMWNrIHp1bSBIYXVwdG1lblwyMDEiKTsJLy8gZmFsbHMgSGlnaHNjb3JlIERhdGVpIG5vY2ggbmljaHQgdm9yaGFuZGVuLCBlcnN0ZWxsZSBkaWVzZQoKCQkJCQlpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCS8vIHp1csODwrxjayB6dW0gTWVuw4PCvCBBYmZyYWdlIChmYWxscyAxIGdlZHLDg8K8Y2t0IHdpcmQpCgkJCQkJaWYoYXVzd2FobCA9PSA0OSkKCQkJCQl7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmKGZnZXRzKGVpbmxlc2VuLDUwLEZEYXRlaSkgPT0gTlVMTCkJCQkJCQkJLy8gd2lyZCBlaW4gIjoiIGluIGRlciBEYXRlaSBnZWZ1bmRlbj8gRmFsbHMgbmljaHQsICJLZWluZSBIaWdoc2NvcmVzIiBNZWxkdW5nIGF1c2dlYmVuCgkJCQl7CgkJCQkJcHJpbnRmKCJcbkxlaWRlciBoYXQgbm9jaCBuaWVtYW5kIGVpbmVuIEhpZ2hzY29yZSBhdWZnZXN0ZWxsdCFcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48MT4gWnVyXDIwMWNrIHp1bSBIYXVwdG1lblwyMDEiKTsKCQkJCQlmY2xvc2UoRkRhdGVpKTsJCQkJCQkJCS8vIERhdGVpIHNjaGxpZXNzZW4KCQkJCQlpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCS8vIHp1csODwrxjayB6dW0gTWVuw4PCvCBBYmZyYWdlIChmYWxscyAxIGdlZHLDg8K8Y2t0IHdpcmQpCgkJCQkJaWYoYXVzd2FobCA9PSA0OSkKCQkJCQl7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQl9CgkJCQllbHNlCgkJCQl7CgkJCQkJZmNsb3NlKEZEYXRlaSk7CgkJCQkJRkRhdGVpID0gZm9wZW4ocGZhZCwgInIiKTsJCQkJLy8gbm9jaCBlaW5tYWwgc2NobGllw4PFuGVuIHVuZCDDg8K2ZmZuZW4sIHVtIHdpZWRlciBhbSBBbmZhbmcgZGVyIERhdGVpIHp1IGJlZ2lubmVuCgkJCQkJd2hpbGUgKGZnZXRzKGVpbmxlc2VuLDUwLEZEYXRlaSkpCQkJLy8gYW5zb25zdGVuIEhpZ2hzY29yZSBhdXNnZWJlbiAmIGxlc2UgYmlzIERhdGVpZW5kZQoJCQkJCXsKCQkJCQkJYXVzZ2FiZSA9IHN0cmNociAoZWlubGVzZW4sICcuJyk7CQkvLyBQdW5rdCBpbSBlaW5nZWxlc2VuZW4gU3RyaW5nIHN1Y2hlbgoJCQkJCQlhdXNnYWJlICs9IDE7CQkJCQkJCS8vIFplaWdlciB1bSAxIG5hY2ggcmVjaHRzIHZlcnNjaGllYmVuLCB1bSBkZW4gUHVua3QgbmljaHQgbWl0IGF1c3p1Z2ViZW4KCQkJCQkJcHJpbnRmKCIlaS4gJXMiLCBpLCBhdXNnYWJlKTsJCQkvLyBiZWFyYmVpdGV0ZW4gU3RyaW5nIGF1c2dlYmVuCgkJCQkJCWkrKzsJCQkJCQkJCQkvLyBWb3J6ZWljaGVuICgxLiAsIDIuICwgMy4uLi4pIGbDg8K8ciBBdXNnYWJlIGVyaMODwrZoZW4KCQkJCQl9CgkJCQkJZmNsb3NlKEZEYXRlaSk7CQkJCQkJCQkvLyBEYXRlaSBzY2hsaWVzc2VuCgkJCQkJcHJpbnRmKCJcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cbjwxPiBadXJcMjAxY2sgenVtIEhhdXB0bWVuXDIwMSIpOwkvLyBmYWxscyBIaWdoc2NvcmUgRGF0ZWkgbm9jaCBuaWNodCB2b3JoYW5kZW4sIGVyc3RlbGxlIGRpZXNlCgoJCQkJCWludCBhdXN3YWhsID0gX2dldGNoKCk7CQkJCQkJLy8genVyw4PCvGNrIHp1bSBNZW7Dg8K8IEFiZnJhZ2UgKGZhbGxzIDEgZ2VkcsODwrxja3Qgd2lyZCkKCQkJCQlpZihhdXN3YWhsID09IDQ5KQoJCQkJCXsKCQkJCQkJcmV0dXJuOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJc3RyY3B5KHBmYWQsIHp3aXNjaGVuUGZhZCk7CQkJCQkvLyB1cnNwcsODwrxuZ2xpY2hlbiBQZmFkIC0+CgkJCXN0cmNweSh6d2lzY2hlblBmYWQsICIiKTsJCQkJCS8vIC0+IHdpZWRlcmhlcnN0ZWxsZW4KCX0KCgkvLyBIaWdoc2NvcmUgaW4gRGF0ZWkgc2NocmVpYmVuCgl2b2lkIGhpZ2hzY29yZUVpbmxlc2VuKCkKCXsKCQkJRklMRSogRkRhdGVpOwoJCQlGRGF0ZWkgPSBmb3BlbihwZmFkLCAiciIpOwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFphaGxlbiBlaW5sZXNlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCQljaGFyIHNjb3JlWzYwXTsKCQkJY2hhciogc2M7CgkJCWludCBpID0gMDsKCQkJd2hpbGUoZmdldHMoc2NvcmUsNDAsRkRhdGVpKSAhPSBOVUxMKQoJCQl7CgkJCQlzYyA9IHN0cmNocihzY29yZSwgJzonKTsJCQkJCQkJLy8gSGlnaHNjb3JlIGF1cyBkZXIgVGV4dGRhdGVpIGxlc2VuIHVuZCBpbiBkb3VibGUgQXJyYXkgc3BlaWNoZXJuCgkJCQloaWdoW2ldID0gc3RydG9kKHNjKzEsTlVMTCk7CgkJCQlpKys7CgkJCX0KCQkJZmNsb3NlKEZEYXRlaSk7CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE5hbWVuIGVpbmxlc2VuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQlGRGF0ZWkgPSBmb3BlbihwZmFkLCAiciIpOwkJCQkvLyBEYXRlaSDDg8K2ZmZuZW4gdW5kIGxlc2VuCgkJCWNoYXIqIHB0ciA9ICI6IjsKCQkJaWYoZmdldHMoc2NvcmUsNjAsRkRhdGVpKSAhPSBOVUxMKQoJCQl7CgkJCQlmY2xvc2UoRkRhdGVpKTsKCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsICJyIik7CQkJLy8gRGF0ZWkgw4PCtmZmbmVuIHVuZCBsZXNlbgoKCQkJCWNoYXIgcGxhdHoxWzYwXSA9ICIiOwoJCQkJaWYoZmdldHMocGxhdHoxLDYwLEZEYXRlaSkgIT0gTlVMTCkKCQkJCXsKCQkJCQlzdDEgPSBzdHJjaHIgKHBsYXR6MSwgJy4nKTsKCQkJCQlzdDEgKz0gMTsKCQkJCQlzdHJ0b2soc3QxLHB0cik7CgkJCQl9CgoJCQkJY2hhciBwbGF0ejJbNjBdID0gIiI7CgkJCQlpZihmZ2V0cyhwbGF0ejIsNjAsRkRhdGVpKSAhPSBOVUxMKQoJCQkJewoJCQkJCXN0MiA9IHN0cmNociAocGxhdHoyLCAnLicpOwoJCQkJCXN0MiArPSAxOwoJCQkJCXN0cnRvayhzdDIscHRyKTsKCQkJCX0KCgkJCQljaGFyIHBsYXR6M1s2MF0gPSAiIjsKCQkJCWlmKGZnZXRzKHBsYXR6Myw2MCxGRGF0ZWkpICE9IE5VTEwpCgkJCQl7CgkJCQkJc3QzID0gc3RyY2hyIChwbGF0ejMsICcuJyk7CgkJCQkJc3QzICs9IDE7CgkJCQkJc3RydG9rKHN0MyxwdHIpO30KCQkJCX0KCgkJCQljaGFyIHBsYXR6NFs2MF0gPSAiIjsKCQkJCWlmKGZnZXRzKHBsYXR6NCw2MCxGRGF0ZWkpICE9IE5VTEwpCgkJCQl7CgkJCQkJc3Q0ID0gc3RyY2hyIChwbGF0ejQsICcuJyk7CgkJCQkJc3Q0ICs9IDE7CgkJCQkJc3RydG9rKHN0NCxwdHIpOwoJCQkJfQoKCQkJCWNoYXIgcGxhdHo1WzYwXSA9ICIiOwoJCQkJaWYoZmdldHMocGxhdHo1LDYwLEZEYXRlaSkgIT0gTlVMTCkKCQkJCXsKCQkJCQlzdDUgPSBzdHJjaHIgKHBsYXR6NSwgJy4nKTsKCQkJCQlzdDUgKz0gMTsKCQkJCQlzdHJ0b2soc3Q1LHB0cik7CgkJCQl9CgoJCQkJY2hhciBwbGF0ejZbNjBdID0gIiI7CgkJCQlpZihmZ2V0cyhwbGF0ejYsNjAsRkRhdGVpKSAhPSBOVUxMKQoJCQkJewoJCQkJCXN0NiA9IHN0cmNociAocGxhdHo2LCAnLicpOwoJCQkJCXN0NiArPSAxOwoJCQkJCXN0cnRvayhzdDYscHRyKTsKCQkJCX0KCgkJCQljaGFyIHBsYXR6N1s2MF0gPSAiIjsKCQkJCWlmKGZnZXRzKHBsYXR6Nyw2MCxGRGF0ZWkpICE9IE5VTEwpCgkJCQl7CgkJCQkJc3Q3ID0gc3RyY2hyIChwbGF0ejcsICcuJyk7CgkJCQkJc3Q3ICs9IDE7CgkJCQkJc3RydG9rKHN0NyxwdHIpOwoJCQkJfQoKCQkJCWNoYXIgcGxhdHo4WzYwXSA9ICIiOwoJCQkJaWYoZmdldHMocGxhdHo4LDYwLEZEYXRlaSkgIT0gTlVMTCkKCQkJCXsKCQkJCQlzdDggPSBzdHJjaHIgKHBsYXR6OCwgJy4nKTsKCQkJCQlzdDggKz0gMTsKCQkJCQlzdHJ0b2soc3Q4LHB0cik7CgkJCQl9CgoJCQkJY2hhciBwbGF0ejlbNjBdID0gIiI7CgkJCQlpZihmZ2V0cyhwbGF0ejksNjAsRkRhdGVpKSAhPSBOVUxMKQoJCQkJewoJCQkJCXN0OSA9IHN0cmNociAocGxhdHo5LCAnLicpOwoJCQkJCXN0OSArPSAxOwoJCQkJCXN0cnRvayhzdDkscHRyKTsKCQkJCX0KCQkJCWZjbG9zZShGRGF0ZWkpOwoKCQkJCUZEYXRlaSA9IGZvcGVuKHBmYWQsIncrIik7CQkJCQkvLyBEYXRlaSDDg8K2ZmZuZW4gdW5kIEhpZ3Njb3JlcyBhbiBEYXRlaWVuZGUgYW5ow4PCpG5nZW4KCgkJaWYoZGlmIDw9IGhpZ2hbMF0pCgkJewoJCQloaWdoWzldID0gaGlnaFs4XTsKCQkJaGlnaFs4XSA9IGhpZ2hbN107CgkJCWhpZ2hbN10gPSBoaWdoWzZdOwoJCQloaWdoWzZdID0gaGlnaFs1XTsKCQkJaGlnaFs1XSA9IGhpZ2hbNF07CgkJCWhpZ2hbNF0gPSBoaWdoWzNdOwoJCQloaWdoWzNdID0gaGlnaFsyXTsKCQkJaGlnaFsyXSA9IGhpZ2hbMV07CgkJCWhpZ2hbMV0gPSBoaWdoWzBdOwoJCQloaWdoWzBdID0gZGlmOwoJCQlpZihuYW1lICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXMncyBaZWl0OiAlLjJmc1xuIixuYW1lLGhpZ2hbMF0pOwoJCQlpZihzdDEgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QxLGhpZ2hbMV0pOwoJCQlpZihzdDIgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QyLGhpZ2hbMl0pOwoJCQlpZihzdDMgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QzLGhpZ2hbM10pOwoJCQlpZihzdDQgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q0LGhpZ2hbNF0pOwoJCQlpZihzdDUgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q1LGhpZ2hbNV0pOwoJCQlpZihzdDYgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q2LGhpZ2hbNl0pOwoJCQlpZihzdDcgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q3LGhpZ2hbN10pOwoJCQlpZihzdDggIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q4LGhpZ2hbOF0pOwoJCQlpZihzdDkgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnMiLHN0OSxoaWdoWzldKTsKCQl9CgkJZWxzZSBpZihkaWYgPiBoaWdoWzBdICYmIGRpZiA8PSBoaWdoWzFdKQoJCXsKCQkJaGlnaFs5XSA9IGhpZ2hbOF07CgkJCWhpZ2hbOF0gPSBoaWdoWzddOwoJCQloaWdoWzddID0gaGlnaFs2XTsKCQkJaGlnaFs2XSA9IGhpZ2hbNV07CgkJCWhpZ2hbNV0gPSBoaWdoWzRdOwoJCQloaWdoWzRdID0gaGlnaFszXTsKCQkJaGlnaFszXSA9IGhpZ2hbMl07CgkJCWhpZ2hbMl0gPSBoaWdoWzFdOwoJCQloaWdoWzFdID0gZGlmOwoJCQlpZihzdDEgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QxLGhpZ2hbMF0pOwoJCQlpZihuYW1lICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXMncyBaZWl0OiAlLjJmc1xuIixuYW1lLGhpZ2hbMV0pOwoJCQlpZihzdDIgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QyLGhpZ2hbMl0pOwoJCQlpZihzdDMgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QzLGhpZ2hbM10pOwoJCQlpZihzdDQgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q0LGhpZ2hbNF0pOwoJCQlpZihzdDUgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q1LGhpZ2hbNV0pOwoJCQlpZihzdDYgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q2LGhpZ2hbNl0pOwoJCQlpZihzdDcgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q3LGhpZ2hbN10pOwoJCQlpZihzdDggIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q4LGhpZ2hbOF0pOwoJCQlpZihzdDkgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnMiLHN0OSxoaWdoWzldKTsKCQl9CgkJZWxzZSBpZihkaWYgPiBoaWdoWzBdICYmIGRpZiA+IGhpZ2hbMV0gJiYgZGlmIDw9IGhpZ2hbMl0pCgkJewoJCQloaWdoWzldID0gaGlnaFs4XTsKCQkJaGlnaFs4XSA9IGhpZ2hbN107CgkJCWhpZ2hbN10gPSBoaWdoWzZdOwoJCQloaWdoWzZdID0gaGlnaFs1XTsKCQkJaGlnaFs1XSA9IGhpZ2hbNF07CgkJCWhpZ2hbNF0gPSBoaWdoWzNdOwoJCQloaWdoWzNdID0gaGlnaFsyXTsKCQkJaGlnaFsyXSA9IGRpZjsKCQkJaWYoc3QxICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MSxoaWdoWzBdKTsKCQkJaWYoc3QyICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MixoaWdoWzFdKTsKCQkJaWYobmFtZSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzJ3MgWmVpdDogJS4yZnNcbiIsbmFtZSxoaWdoWzJdKTsKCQkJaWYoc3QzICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MyxoaWdoWzNdKTsKCQkJaWYoc3Q0ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NCxoaWdoWzRdKTsKCQkJaWYoc3Q1ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NSxoaWdoWzVdKTsKCQkJaWYoc3Q2ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NixoaWdoWzZdKTsKCQkJaWYoc3Q3ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NyxoaWdoWzddKTsKCQkJaWYoc3Q4ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0OCxoaWdoWzhdKTsKCQkJaWYoc3Q5ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzIixzdDksaGlnaFs5XSk7CgkJfQoJCWVsc2UgaWYoZGlmID4gaGlnaFswXSAmJiBkaWYgPj0gaGlnaFsxXSAmJiBkaWYgPiBoaWdoWzJdICYmIGRpZiA8PSBoaWdoWzNdKQoJCXsKCgkJCWhpZ2hbOV0gPSBoaWdoWzhdOwoJCQloaWdoWzhdID0gaGlnaFs3XTsKCQkJaGlnaFs3XSA9IGhpZ2hbNl07CgkJCWhpZ2hbNl0gPSBoaWdoWzVdOwoJCQloaWdoWzVdID0gaGlnaFs0XTsKCQkJaGlnaFs0XSA9IGhpZ2hbM107CgkJCWhpZ2hbM10gPSBkaWY7CgkJCWlmKHN0MSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDEsaGlnaFswXSk7CgkJCWlmKHN0MiAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDIsaGlnaFsxXSk7CgkJCWlmKHN0MyAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDMsaGlnaFsyXSk7CgkJCWlmKG5hbWUgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lcydzIFplaXQ6ICUuMmZzXG4iLG5hbWUsaGlnaFszXSk7CgkJCWlmKHN0NCAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDQsaGlnaFs0XSk7CgkJCWlmKHN0NSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDUsaGlnaFs1XSk7CgkJCWlmKHN0NiAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDYsaGlnaFs2XSk7CgkJCWlmKHN0NyAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDcsaGlnaFs3XSk7CgkJCWlmKHN0OCAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmc1xuIixzdDgsaGlnaFs4XSk7CgkJCWlmKHN0OSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzOiAlLjJmcyIsc3Q5LGhpZ2hbOV0pOwoJCX0KCQllbHNlIGlmKGRpZiA+IGhpZ2hbM10gJiYgZGlmIDw9IGhpZ2hbNF0pCgkJewoKCQkJaGlnaFs5XSA9IGhpZ2hbOF07CgkJCWhpZ2hbOF0gPSBoaWdoWzddOwoJCQloaWdoWzddID0gaGlnaFs2XTsKCQkJaGlnaFs2XSA9IGhpZ2hbNV07CgkJCWhpZ2hbNV0gPSBoaWdoWzRdOwoJCQloaWdoWzRdID0gZGlmOwoJCQlpZihzdDEgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QxLGhpZ2hbMF0pOwoJCQlpZihzdDIgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QyLGhpZ2hbMV0pOwoJCQlpZihzdDMgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QzLGhpZ2hbMl0pOwoJCQlpZihzdDQgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q0LGhpZ2hbM10pOwoJCQlpZihuYW1lICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXMncyBaZWl0OiAlLjJmc1xuIixuYW1lLGhpZ2hbNF0pOwoJCQlpZihzdDUgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q1LGhpZ2hbNV0pOwoJCQlpZihzdDYgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q2LGhpZ2hbNl0pOwoJCQlpZihzdDcgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q3LGhpZ2hbN10pOwoJCQlpZihzdDggIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q4LGhpZ2hbOF0pOwoJCQlpZihzdDkgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnMiLHN0OSxoaWdoWzldKTsKCgkJfQoJCWVsc2UgaWYoZGlmID4gaGlnaFs0XSAmJiBkaWYgPD0gaGlnaFs1XSkKCQl7CgkJCWhpZ2hbOV0gPSBoaWdoWzhdOwoJCQloaWdoWzhdID0gaGlnaFs3XTsKCQkJaGlnaFs3XSA9IGhpZ2hbNl07CgkJCWhpZ2hbNl0gPSBoaWdoWzVdOwoJCQloaWdoWzVdID0gZGlmOwoJCQlpZihzdDEgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QxLGhpZ2hbMF0pOwoJCQlpZihzdDIgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QyLGhpZ2hbMV0pOwoJCQlpZihzdDMgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QzLGhpZ2hbMl0pOwoJCQlpZihzdDQgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q0LGhpZ2hbM10pOwoJCQlpZihzdDUgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q1LGhpZ2hbNF0pOwoJCQlpZihuYW1lICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXMncyBaZWl0OiAlLjJmc1xuIixuYW1lLGhpZ2hbNV0pOwoJCQlpZihzdDYgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q2LGhpZ2hbNl0pOwoJCQlpZihzdDcgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q3LGhpZ2hbN10pOwoJCQlpZihzdDggIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q4LGhpZ2hbOF0pOwoJCQlpZihzdDkgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnMiLHN0OSxoaWdoWzldKTsKCQl9CgkJZWxzZSBpZihkaWYgPiBoaWdoWzVdICYmIGRpZiA8PSBoaWdoWzZdKQoJCXsKCQkJaGlnaFs5XSA9IGhpZ2hbOF07CgkJCWhpZ2hbOF0gPSBoaWdoWzddOwoJCQloaWdoWzddID0gaGlnaFs2XTsKCQkJaGlnaFs2XSA9IGRpZjsKCQkJaWYoc3QxICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MSxoaWdoWzBdKTsKCQkJaWYoc3QyICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MixoaWdoWzFdKTsKCQkJaWYoc3QzICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MyxoaWdoWzJdKTsKCQkJaWYoc3Q0ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NCxoaWdoWzNdKTsKCQkJaWYoc3Q1ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NSxoaWdoWzRdKTsKCQkJaWYoc3Q2ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NixoaWdoWzVdKTsKCQkJaWYobmFtZSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzJ3MgWmVpdDogJS4yZnNcbiIsbmFtZSxoaWdoWzZdKTsKCQkJaWYoc3Q3ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NyxoaWdoWzddKTsKCQkJaWYoc3Q4ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0OCxoaWdoWzhdKTsKCQkJaWYoc3Q5ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzIixzdDksaGlnaFs5XSk7CgkJfQoJCWVsc2UgaWYoZGlmID4gaGlnaFs2XSAmJiBkaWYgPD0gaGlnaFs3XSkKCQl7CgkJCWhpZ2hbOV0gPSBoaWdoWzhdOwoJCQloaWdoWzhdID0gaGlnaFs3XTsKCQkJaGlnaFs3XSA9IGRpZjsKCQkJaWYoc3QxICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MSxoaWdoWzBdKTsKCQkJaWYoc3QyICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MixoaWdoWzFdKTsKCQkJaWYoc3QzICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MyxoaWdoWzJdKTsKCQkJaWYoc3Q0ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NCxoaWdoWzNdKTsKCQkJaWYoc3Q1ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NSxoaWdoWzRdKTsKCQkJaWYoc3Q2ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NixoaWdoWzVdKTsKCQkJaWYoc3Q3ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NyxoaWdoWzZdKTsKCQkJaWYobmFtZSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzJ3MgWmVpdDogJS4yZnNcbiIsbmFtZSxoaWdoWzddKTsKCQkJaWYoc3Q4ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0OCxoaWdoWzhdKTsKCQkJaWYoc3Q5ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzIixzdDksaGlnaFs5XSk7CgkJfQoJCWVsc2UgaWYoZGlmID4gaGlnaFs3XSAmJiBkaWYgPD0gaGlnaFs4XSkKCQl7CgkJCWhpZ2hbOV0gPSBoaWdoWzhdOwoJCQloaWdoWzhdID0gZGlmOwoJCQlpZihzdDEgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QxLGhpZ2hbMF0pOwoJCQlpZihzdDIgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QyLGhpZ2hbMV0pOwoJCQlpZihzdDMgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3QzLGhpZ2hbMl0pOwoJCQlpZihzdDQgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q0LGhpZ2hbM10pOwoJCQlpZihzdDUgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q1LGhpZ2hbNF0pOwoJCQlpZihzdDYgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q2LGhpZ2hbNV0pOwoJCQlpZihzdDcgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q3LGhpZ2hbNl0pOwoJCQlpZihzdDggIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnNcbiIsc3Q4LGhpZ2hbN10pOwoJCQlpZihuYW1lICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXMncyBaZWl0OiAlLjJmc1xuIixuYW1lLGhpZ2hbOF0pOwoJCQlpZihzdDkgIT0gTlVMTClmcHJpbnRmKEZEYXRlaSwgIi4lczogJS4yZnMiLHN0OSxoaWdoWzldKTsKCQl9CgkJZWxzZSBpZihkaWYgPiBoaWdoWzhdICYmIGRpZiA8PSBoaWdoWzldKQoJCXsKCQkJaGlnaFs5XSA9IGRpZjsKCQkJaWYoc3QxICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MSxoaWdoWzBdKTsKCQkJaWYoc3QyICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MixoaWdoWzFdKTsKCQkJaWYoc3QzICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0MyxoaWdoWzJdKTsKCQkJaWYoc3Q0ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NCxoaWdoWzNdKTsKCQkJaWYoc3Q1ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NSxoaWdoWzRdKTsKCQkJaWYoc3Q2ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NixoaWdoWzVdKTsKCQkJaWYoc3Q3ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0NyxoaWdoWzZdKTsKCQkJaWYoc3Q4ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0OCxoaWdoWzddKTsKCQkJaWYoc3Q5ICE9IE5VTEwpZnByaW50ZihGRGF0ZWksICIuJXM6ICUuMmZzXG4iLHN0OSxoaWdoWzhdKTsKCQkJaWYobmFtZSAhPSBOVUxMKWZwcmludGYoRkRhdGVpLCAiLiVzJ3MgWmVpdDogJS4yZnMiLG5hbWUsaGlnaFs5XSk7CgkJfQoJCWZjbG9zZShGRGF0ZWkpOwkJCQkvLyBEYXRlaSBzY2hsaWXDg8W4ZW4KCX0KCgkvLyBWb3JnZWhlbiBuYWNoIFNwaWVsZW5kZSBhYmZyYWdlbgoJdm9pZCBzcGllbGVuZGUoKQoJewoJICBpbnQgYXVzd2FobDsKCSAgQ09PUkQgcDsKCQlzeXN0ZW0oImNscyIpOwoJCXByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKCQlwcmludGYoInwgJXMgXHRcdCAgICAgICAgICAgfFxufC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Iiwgc3BpZWxlcmdlYm5pcyk7CQkJLy8gVGFiZWxsZSBtaXQgU3BpZWxlcmdlYm5pc3NlbiBhbnplaWdlbgoJCXByaW50ZigiXG58IEVuZHN0YW5kOiBEdSA8JWk+ICBDb21wdXRlciA8JWk+ICAgfFxuIix5U2NvcmUsIGNTY29yZSk7CgkJcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuIik7CgkJcHJpbnRmKCJXXDIwNGhsZW4gc2llIGVpbmUgTVwyMjRnbGljaGtlaXQhXG5cbiIpOwoJCXByaW50ZigiPDE+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxXG4iKTsKCQlwcmludGYoIjwyPiBIaWdoc2NvcmUgYW56ZWlnZW5cbiIpOwoJCXAuWCA9IChpbnQpICgyMCk7CgkJcC5ZID0gKGludCkgKDEpOwoJCVNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihoT3V0LCBwKTsKCQlwcmludGYoIlplaXQ6ICUuMmZzIiwgZGlmKTsKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBNZW7Dg8K8IG5hY2ggU3BpZWxlbmRlIGRhcnN0ZWxsZW4KCQlhdXN3YWhsID0gX2dldGNoKCk7CgoJCWlmKGF1c3dhaGwgPT0gNDkpCgkJewoJCQltYWluTG9vcCA9IDA7CgkJCXJldHVybjsKCQl9CgkJZWxzZSBpZihhdXN3YWhsID09IDUwKQoJCXsKCQkJaGlnaHNjb3JlQXVzZ2ViZW4oKTsKCQl9CgkJZWxzZSBpZihlbmRlID09IHRydWUpCgkJewoJCQllbmRlID0gZmFsc2U7CgkJfQoJCWVsc2UKCQl7CgkJIHByaW50ZigiXG5cblVuZ1wyMDFsdGlnZSBFaW5nYWJlIVxuXG4iKTsKCQkgU2xlZXAoMjAwMCk7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBmYWxscyBlaW5lIFRhc3RlLCBkaWUgbmljaHQgenVyIEF1c3dhaGwgc3RhbmQgZ2VkcsODwrxja3Qgd3VyZGUsIFVuZ8ODwrxsdGlnZSBFaW5nYWJlIGFuemVpZ2VuCgkJIHN5c3RlbSgiY2xzIik7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyB1bmQgenVyw4PCvGNrIHp1bSBIYXV0cG1lbsODwrwKCQkgc3BpZWxlbmRlKCk7CgkJfQogfQoKCS8vIFNwaWVsIGF1c2bDg8K8aHJlbgoJdm9pZCBzcGllbGVuKCkKCXsKCSAgaW50IGksZ2VzdGFydGV0OwoJCWludCB5b3Vfc2NvcmUgPSAwLCBjb21wX3Njb3JlID0gMDsJCQkJCQkJLy8gU3RhdGlzdGlrIGF1ZiBTdGFuZGFyZCBzZXR6ZW4KCQlzcGllbGVyIHlvdSxjb21wOyBiYWxsIGI7CgoJCXNldFdpbmRvd1NpemUoNTUsMzkpOwoKCQkvLyBPYmVyZmzDg8KkY2hlIHplaWNobmVuCiAJCVNldENvbnNvbGVUZXh0QXR0cmlidXRlKCBoT3V0LCAxNSApOwoKCQlmb3IgKCBpID0gMDsgaSA8IHdpZHRoIC0gMTsgKytpKQoJCQlwcmludGYoIi0iKTsKCQlmb3IgKCBpID0gMDsgaSA8IGhlaWdodCAtIDE7ICsraSkKCQl7CgkJCXByaW50ZigiXG58Iik7CgoJCWZvciAoIGkgPSAwOyBpIDwgd2lkdGggLSAzOyArK2kpCgkJCXByaW50ZigiICIpOwoJCQlwcmludGYoInwiKTsKCQl9CgkJcHJpbnRmKCJcbiIpOwoJCWZvciAoIGkgPSAwOyBpIDwgd2lkdGggLSAxOyArK2kpCgoJCQlwcmludGYoIi0iKTsKCQkJcHJpbnRmKCJcbnwgWW91ciBzY29yZTogMCB8IENvbXB1dGVyIHNjb3JlOiAwIHx8fCBTcGVlZDogICAwICAgfFxuIik7CgkJZm9yICggaSA9IDA7IGkgPCB3aWR0aCAtIDE7ICsraSkKCQkJcHJpbnRmKCItIik7CgoJCS8vIEVuZGUgT2JlcmZsw4PCpGNoZSB6ZWljaG5lbgoKCQlnZXN0YXJ0ZXQgPSBmYWxzZTsJCQkJCQkJCQkJLy8gU3BpZWwgZ2VzdGFydGV0PwoJCXNwaWVsZXJfKCZ5b3Usd2lkdGggLyAyLCBoZWlnaHQgLSAyLCA0KTsJCQkJCQkvLyBTcGllbGVyIGVyc3RlbGxlbgoJCXNwaWVsZXJfKCZjb21wLHdpZHRoIC8gMiwgMiwgNCk7CQkJCQkJCQkvLyBLSSBlcnN0ZWxsZW4KCQliYWxsXygmYix3aWR0aCAvIDIgLSAxLCBoZWlnaHQgLyAyKTsJCQkJCQkJLy8gQmFsbCBlcnN0ZWxsZW4KCgkJLy8gQmFsbCBpbiB6dWbDg8KkbGxpZ2UgUmljaHR1bmcgenVtIFNwaWVsZXIKCQliLnZ4ID0gKGZsb2F0KShyYW5kKCkgJSAzKSAtIDEuNWY7CgkJYi52eSA9IDE7CgkJY29tcC52eCA9IDA7CgoJCXRpbWUoJnN0YXJ0KTsJCQkJCQkJCQkJCQkvLyBTdG9wcHVociBmw4PCvHIgSGlnaHNjb3JlIHN0YXJ0ZW4KCndoaWxlICh0cnVlKQp7CiAgICBpZiAoZ2VzdGFydGV0ID09IHRydWUpCQkJCQkJCQkJCQkvLyBTcGllbCBnZXN0YXJ0ZXQ/Cgl7CgoJCWlmIChHZXRBc3luY0tleVN0YXRlKGxpbmtzKSkKCQl7CgkJCWlmKHN0cmNtcChzY2h3aWVyaWdrZWl0LHNjaHdpZXJpZ2tlaXQxKSA9PSAwKQoJCQl7CgkJCQl5b3UueCAtPSAyLjU7CgkJCX0KCQkJZWxzZSBpZihzdHJjbXAoc2Nod2llcmlna2VpdCxzY2h3aWVyaWdrZWl0MikgPT0gMCkKCQkJewoJCQkJeW91LnggLT0gMjsKCQkJfQoJCQllbHNlIGlmKHN0cmNtcChzY2h3aWVyaWdrZWl0LHNjaHdpZXJpZ2tlaXQzKSA9PSAwKQoJCQl7CgkJCQl5b3UueCAtPSAyOwoJCQl9CgkJCWVsc2UgaWYoc3RyY21wKHNjaHdpZXJpZ2tlaXQsc2Nod2llcmlna2VpdDQpID09IDApCgkJCXsKCQkJCXlvdS54IC09IDIuNTsKCQkJfQoJCX0KCQllbHNlIGlmIChHZXRBc3luY0tleVN0YXRlKHJlY2h0cykpCgkJewoJCQlpZihzdHJjbXAoc2Nod2llcmlna2VpdCxzY2h3aWVyaWdrZWl0MSkgPT0gMCkKCQkJewoJCQkJeW91LnggKz0gMi41OwoJCQl9CgkJCWVsc2UgaWYoc3RyY21wKHNjaHdpZXJpZ2tlaXQsc2Nod2llcmlna2VpdDIpID09IDApCgkJCXsKCQkJCXlvdS54ICs9IDI7CgkJCX0KCQkJZWxzZSBpZihzdHJjbXAoc2Nod2llcmlna2VpdCxzY2h3aWVyaWdrZWl0MykgPT0gMCkKCQkJewoJCQkJeW91LnggKz0gMjsKCQkJfQoJCQllbHNlIGlmKHN0cmNtcChzY2h3aWVyaWdrZWl0LHNjaHdpZXJpZ2tlaXQ0KSA9PSAwKQoJCQl7CgkJCQl5b3UueCArPSAyLjU7CgkJCX0KCQl9CgkJZWxzZSBpZiAoR2V0QXN5bmNLZXlTdGF0ZShiZWVuZGVuKSkKCQl7CgkJCUNPT1JEIHA7CgkJCXAuWCA9IChpbnQpICh3aWR0aCAvIDIgLSAxNik7CgkJCXAuWSA9IChpbnQpIChoZWlnaHQgLyAxLjhmKTsKCQkJU2V0Q29uc29sZUN1cnNvclBvc2l0aW9uKGhPdXQsIHApOwoJCQlwcmludGYoIlNwaWVsIHdpcmtsaWNoIGJlZW5kZW4/Iik7CgkJCXAuWCA9IChpbnQpICh3aWR0aCAvIDIgLSAxNik7CgkJCXAuWSA9IChpbnQpIChoZWlnaHQgLyAxLjZmKTsKCQkJU2V0Q29uc29sZUN1cnNvclBvc2l0aW9uKGhPdXQsIHApOwkJCQkJCS8vIEFiZnJhZ2UsIG9iIFNwaWVsIGZvcnRzZXR6ZW4gb2RlciBCZWVuZGVuCgkJCXByaW50ZigiPDE+IFdlaXRlcnNwaWVsZW5cbiIpOwkJCQkJCQkvLyB3aXJkIGRydWNoIGRhcyBkcsODwrxja2VuIGRlciBxIFRhc3RlIGF1ZgoJCQlwLlggPSAoaW50KSAod2lkdGggLyAyIC0gMTYpOwkJCQkJCQkJLy8gaW4gZGllIEtvbnNvbGUgZ2VzY2hyaWViZW4gdW5kIGVpbmdlbGVzZW4KCQkJcC5ZID0gKGludCkgKGhlaWdodCAvIDEuNTVmKTsKCQkJU2V0Q29uc29sZUN1cnNvclBvc2l0aW9uKGhPdXQsIHApOwoJCQlwcmludGYoIjwyPiBTcGllbCBiZWVuZGVuXG5cbiIpOwoJCQlwLlggPSAoaW50KSAod2lkdGggLyAyIC0gMTcpOwoJCQlwLlkgPSAoaW50KSAoaGVpZ2h0IC8gMS4zNWYpOwoJCQlTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oaE91dCwgcCk7CgkJCWNoYXIgYzsKCQkJd2hpbGUgKChjID0gX2dldGNoKCkpICE9IEVPRiAmJiBjICE9ICdxJyk7CQkJCS8vIFB1ZmZlciBhdXRvbWF0aXNjaCBpbSBIaW50ZXJncnVuZCBsZWVyZW4KCQkJaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsKCQkJd2hpbGUoR2V0QXN5bmNLZXlTdGF0ZShWS19SRVRVUk4pKTsKCgoJCWlmKGF1c3dhaGwgPT0gNDkpCgkJewoJCQlwLlggPSAoaW50KSAod2lkdGggLyAyIC0gMTYpOwoJCQlwLlkgPSAoaW50KSAoaGVpZ2h0IC8gMS44Zik7CgkJCVNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihoT3V0LCBwKTsKCQkJcHJpbnRmKCIgICAgICAgICAgICAgICAgICAgICAgICAgICIpOwoJCQlwLlggPSAoaW50KSAod2lkdGggLyAyIC0gMTYpOwoJCQlwLlkgPSAoaW50KSAoaGVpZ2h0IC8gMS42Zik7CgkJCVNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihoT3V0LCBwKTsJCQkJCQkvLyBuYWNoIEVpbmdhYmUsIHdpcmQgZGVyIERpYWxvZyB3aWVkZXIgZW50ZmVybnQKCQkJcHJpbnRmKCIgICAgICAgICAgICAgICAgICAgICAgICAgICIpOwoJCQlwLlggPSAoaW50KSAod2lkdGggLyAyIC0gMTYpOwoJCQlwLlkgPSAoaW50KSAoaGVpZ2h0IC8gMS41NWYpOwoJCQlTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oaE91dCwgcCk7CgkJCXByaW50ZigiICAgICAgICAgICAgICAgICAgICAgICAgICAiKTsKCQkJcC5YID0gKGludCkgKHdpZHRoIC8gMiAtIDE3KTsKCQkJcC5ZID0gKGludCkgKGhlaWdodCAvIDEuMzVmKTsKCQkJU2V0Q29uc29sZUN1cnNvclBvc2l0aW9uKGhPdXQsIHApOwoJCQlwcmludGYoIiAgICAgICAgICAgIik7CgkJfQoJCWVsc2UKCQl7CgkJCXRpbWUoJmVuZGV0KTsJLy8gU3RvcHB1aHIgc3RvcHBlbgoJCQlicmVhazsKCQl9CgoJfQoKCSAgLy8gQmFsbGdlc2Nod2luZGlna2VpdCBmw4PCvHIgU3RhdGlzdGlrIGJlcmVjaG5lbgoJICBmbG9hdCB4ID0gcG93KGIudngsIDIpOwoJICBmbG9hdCB5ID0gcG93KGIudnksIDIpOwoJICBzcGVlZCA9IHggKyB5OwoJICBzcGVlZCA9IHNxcnQoc3BlZWQpOwoJICBDT09SRCBwOwogICAgICBwLlggPSAoaW50KSAoNDcpOwogICAgICBwLlkgPSAoaW50KSAoMzcpOwogICAgICBTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oaE91dCwgcCk7CgkgIHByaW50ZigiJS4yZiIsIHNwZWVkKTsKCiAgICAgIC8vIEtJIHp1bSBCYWxsIGbDg8K8aHJlbgogICAgICBjb21wLnZ4IC09IChmbG9hdCkoY29tcC54IC0gYi54KSAvIGNvbXB2OwogICAgICBjb21wLnZ4ICo9IDAuODNmOwoKICAgICAgLy8gS0kgR2VzY2h3aW5kaWdlaXQgaW4gQWJow4PCpG5naWdrZWl0IGRlciBCYWxsZ2VzY2h3aW5kaWdrZWl0IGFucGFzc2VuCiAgICAgIGNvbXAueCArPSBjb21wLnZ4OwoKICAgICAgLy8gQmV3ZWd1bmdzZ3JlbnplbiBzZXR6ZW4KICAgICAgaWYgKHlvdS54IDwgeW91LnNpemUgKyAxKQoJICB7CiAgICAgICAgeW91LnggPSAoZmxvYXQpICh5b3Uuc2l6ZSArIDEpOwogICAgICB9CgkgIGVsc2UgaWYgKHlvdS54ID4gd2lkdGggLSB5b3Uuc2l6ZSAtIDIgLSBtb2RpZmlrYXRvcikKCSAgewogICAgICAgIHlvdS54ID0gKGZsb2F0KSAod2lkdGggLSB5b3Uuc2l6ZSAtIDIgLSBtb2RpZmlrYXRvcik7CiAgICAgIH0KCiAgICAgIC8vIEtJIEJld2VndW5nc2dyZW56ZSBzZXR6ZW4KICAgICAgaWYgKGNvbXAueCA8IGNvbXAuc2l6ZSArIDEpCgkgIHsKICAgICAgICBjb21wLnggPSAoZmxvYXQpIChjb21wLnNpemUgKyAxKTsKICAgICAgfQoJICBlbHNlIGlmIChjb21wLnggPiB3aWR0aCAtIGNvbXAuc2l6ZSAtIDIgLSBtb2RpZmlrYXRvcikKCSAgewogICAgICAgIGNvbXAueCA9IChmbG9hdCkgKHdpZHRoIC0gY29tcC5zaXplIC0gMiAtIG1vZGlmaWthdG9yKTsKICAgICAgfQoKICAgICAgLy8gQmFsbCBIw4PCtmNoc3RnZXNjaHdpbmRpZ2tlaXQgZWluaGFsdGVuCiAgICAgIGlmICAoYi52eCA8IC1tYXhTcGVlZCkKCSAgewogICAgICAgIGIudnggPSAtbWF4U3BlZWQ7CiAgICAgIH0KCSAgZWxzZSBpZiAoYi52eCA+IG1heFNwZWVkKQoJICB7CiAgICAgICAgYi52eCA9IG1heFNwZWVkOwogICAgICB9CgogICAgICAvLyBEZW0gQmFsbCBhbiBkZXIgYWt0dWVsbGVuIFBvc2l0aW9uIEdlc2Nod2luZGlna2VpdCB6dWbDg8K8aHJlbgogICAgICBiLnggKz0gYi52eDsKICAgICAgYi55ICs9IGIudnk7CgogICAgICAvLyBIYXQgZGVyIEJhbGwgZGVuIFNwaWVsZXIgZ2V0cm9mZmVuPwogICAgICBpZiAoYi55ID49IHlvdS55IC0gMSAmJiBiLnkgPD0geW91LnkgKyAxKQoJICB7CiAgICAgICAgaWYgKGIueCA+IHlvdS54IC0geW91LnNpemUgJiYgYi54IDwgeW91LnggKyB5b3Uuc2l6ZSkKCQl7CiAgICAgICAgICBiLnZ5ICo9IC0xOwogICAgICAgICAgYi52eCArPSAoZmxvYXQpKGIueCAtIHlvdS54KSAvIDM7CiAgICAgICAgICBiLnkgPSB5b3UueSAtIDE7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBIYXQgZGVyIEJhbGwgZGllIEtJIGdldHJvZmZlbj8KICAgICAgaWYgKGIueSA8PSBjb21wLnkgKyAxICYmIGIueSA+PSBjb21wLnkgLSAxKQoJICB7CiAgICAgICAgaWYgKGIueCA+IGNvbXAueCAtIGNvbXAuc2l6ZSAmJiBiLnggPCBjb21wLnggKyBjb21wLnNpemUpCgkJewogICAgICAgICAgYi52eSAqPSAtMTsKICAgICAgICAgIGIudnggKz0gKGZsb2F0KShiLnggLSBjb21wLngpIC8gMzsKICAgICAgICAgIGIueSA9IGNvbXAueSArIDE7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBIYXQgZGVyIEJhbGwgZGllIEdyZW56ZW4gw4PCvGJlcnNjaHJpdHRlbj8oUHVua3QgYmVrb21tZW4pCiAgICAgIGlmIChiLnkgPj0gaGVpZ2h0KQoJICB7CiAgICAgICAgY29tcF9zY29yZSsrOwoJCWNTY29yZSA9IGNvbXBfc2NvcmU7CiAgICAgICAgcmVzZXQoICZ5b3UsICZjb21wLCAmYiwgZ2VzdGFydGV0LCB5b3Vfc2NvcmUsIGNvbXBfc2NvcmUgKTsKICAgICAgfQoJICBlbHNlIGlmIChiLnkgPD0gMCkKCSAgewogICAgICAgIHlvdV9zY29yZSsrOwoJCXlTY29yZSA9IHlvdV9zY29yZTsKICAgICAgICByZXNldCggJnlvdSwgJmNvbXAsICZiLCBnZXN0YXJ0ZXQsIHlvdV9zY29yZSwgY29tcF9zY29yZSApOwogICAgICB9CiAgICAgIGlmIChiLnggPD0gMSkKCSAgewogICAgICAgIGIudnggKj0gLTE7CiAgICAgICAgYi54ID0gMS4wZjsKICAgICAgfQoJICBlbHNlIGlmIChiLnggPj0gd2lkdGggLSAzKQoJICB7CiAgICAgICAgYi52eCAqPSAtMTsKICAgICAgICBiLnggPSAoZmxvYXQpKHdpZHRoIC0gMyk7CiAgICAgIH0KCX0KCWVsc2UgaWYoeW91X3Njb3JlID09IHNpZWdQdW5rdGUpCgl7CgkJZGlmID0gMTAwMDsKCQloaWdoWzBdID0gZGlmLCBoaWdoWzFdID0gZGlmLCBoaWdoWzJdID0gZGlmLCBoaWdoWzNdID0gZGlmOwkvLyBTdGFuZGFydHdlcnRlIGluaXRpYWxpc2llcmVuCgkJc3lzdGVtKCJjbHMiKTsJCQkJCQkJCQkJCQkvLyBLb25zb2xlIGxlZXJlbgoJCXRpbWUoJmVuZGV0KTsJCQkJCQkJCQkJCQkvLyBTdG9wcHVociBzdG9wcGVuCgkJZGlmID0gZGlmZnRpbWUoZW5kZXQsc3RhcnQpOwkJCQkJCQkJLy8gSGlnaHNjb3JlIFplaXQgYmVyZWNobmVuIChlbmRlIC0gYW5mYW5nKQoJCXN0cmNweShzcGllbGVyZ2VibmlzLCAiIik7CQkJCQkJCQkJLy8gc3BpZWxlcmdlYm5pcyBzdHJpbmcgbGVlcmVuCgkJc3RyY2F0KHNwaWVsZXJnZWJuaXMsICJHZXdvbm5lbiEhISIpOwkJCQkJCS8vIEVuZGVyZ2VibmlzIHNwZWljaGVybiBmw4PCvHIgc3DDg8KkdGVyZSBBdXNnYWJlCgkJcHJpbnRmKCJcblxuXG5cblxuXG5cblxuXHRcdCAgIEdld29ubmVuISEhIDopIik7CQkJLy8gU2llZ21lbGR1bmcgYXVzZ2ViZW4KCQlwcmludGYoIlxuXG5cblxuICAgICAuLi51bSBmb3J0enVmYWhyZW4gYml0dGUgRW50ZXIgZHJcMjAxY2tlbi4uLiIpOwoJCWNoYXIgYzsKCQl3aGlsZSAoKGMgPSBfZ2V0Y2goKSkgIT0gRU9GICYmIGMgIT0gMTMpOwkJCQkJLy8gUHVmZmVyIGF1dG9tYXRpc2NoIGltIEhpbnRlcmdydW5kIGxlZXJlbgoJCXN5c3RlbSgiY2xzIik7CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE5hbWVuIGVpbmxlc2VuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkJcHJpbnRmKCJCaXR0ZSBnZWJlbiBzaWUgaWhyZW4gTmFtZW4gZWluOiAiKTsJCQkJCS8vIEJlbnV0emVyIHp1ciBOYW1lbnNlaW5nYWJlIGF1ZmZvcmRlbiB1bmQgZGllc2VuIGluICJuYW1lIiBhYnNwZWljaGVybgoJCXNjYW5mKCIlcyIsIG5hbWUpOwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIaWdoc2NvcmVzIGVpbmxlc2VuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCUZJTEUgKkZEYXRlaTsKCgkJRkRhdGVpID0gZm9wZW4ocGZhZCwgInIiKTsKCQlpZighRkRhdGVpKQoJCXsKCQkJRkRhdGVpID0gZm9wZW4ocGZhZCwgInciKTsJCQkJLy8gZmFsbHMgw4PCtmZmbmVuIGRlciBEYXRlaSBmZWhsZ2VzY2hsYWdlbiwgZWluZSBEYXRlaSBlcnN0ZWxsZW4KCQkJZmNsb3NlKEZEYXRlaSk7CQkJCQkJCS8vIERhdGVpIHNjaGxpZcODxbhlbgoJCX0KCQloaWdoc2NvcmVFaW5sZXNlbigpOwoJCW1haW5Mb29wID0gMTsJCQkJCQkJCS8vIMODwrxiZXIgbWFpbiBGdW5rdGlvbiB6dSBzcGllbGVuZGUoKSBzcHJpbmdlbgoJCWJyZWFrOwoJICB9CgllbHNlIGlmKGNvbXBfc2NvcmUgPT0gc2llZ1B1bmt0ZSkKCSAgewoJCXN5c3RlbSgiY2xzIik7CQkJCQkJCQkJCQkJLy8gS29uc29sZSBsZWVyZW4KCQl0aW1lKCZlbmRldCk7CQkJCQkJCQkJCQkJLy8gU3RvcHB1aHIgc3RvcHBlbgoJCWRpZiA9IGRpZmZ0aW1lKGVuZGV0LHN0YXJ0KTsJCQkJCQkJCS8vIEhpZ2hzY29yZSBaZWl0IGJlcmVjaG5lbiAoZW5kZSAtIGFuZmFuZykKCQlzdHJjcHkoc3BpZWxlcmdlYm5pcywgIiIpOwkJCQkJCQkJCS8vIHNwaWVsZXJnZWJuaXMgc3RyaW5nIGxlZXJlbgoJCXN0cmNhdChzcGllbGVyZ2VibmlzLCAiVmVybG9yZW4hISEiKTsJCQkJCQkvLyBFbmRlcmdlYm5pcyBzcGVpY2hlcm4gZsODwrxyIHNww4PCpHRlcmUgQXVzZ2FiZQoJCXByaW50ZigiXG5cblxuXG5cblxuXG5cblx0XHQgICBWZXJsb3JlbiEhISA6KCIpOwkJCS8vIE5pZWRlcmxhZ2UgTWVsZHVuZyBhdXNnZWJlbgoJCXByaW50ZigiXG5cblxuXG4gICAgIC4uLnVtIGZvcnR6dWZhaHJlbiBiaXR0ZSBFbnRlciBkclwyMDFja2VuLi4uIik7CgkJY2hhciBjOwoJCXdoaWxlICgoYyA9IF9nZXRjaCgpKSAhPSBFT0YgJiYgYyAhPSAxMyk7CQkJCQkvLyBQdWZmZXIgYXV0b21hdGlzY2ggaW0gSGludGVyZ3J1bmQgbGVlcmVuCgkJbWFpbkxvb3AgPSAxOwkJCQkJCQkJCQkJCS8vIMODwrxiZXIgbWFpbiBGdW5rdGlvbiB6dSBzcGllbGVuZGUoKSBzcHJpbmdlbgoJCWJyZWFrOwoJICB9CgllbHNlCgl7CiAgICAgIC8vIFN0YXJ0YmVkaW5ndW5nw4PCvGJlcnByw4PCvGZlbiAoTGVlcnRhc3RlIGdlZHLDg8K8Y2t0PykKICAgICAgQ09PUkQgcDsKICAgICAgcC5YID0gKGludCkgKHdpZHRoIC8gMiAtIDE2KTsKICAgICAgcC5ZID0gKGludCkgKGhlaWdodCAvIDEuNWYpOwogICAgICBTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oaE91dCwgcCk7CiAgICAgIHByaW50ZigiUHJlc3MgdGhlIHNwYWNlIGJhciB0byBzdGFydC4uLiIpOwoKICAgICAgaWYgKEdldEFzeW5jS2V5U3RhdGUoVktfU1BBQ0UpKQoJICB7CiAgICAgICAgQ09PUkQgcDsKICAgICAgICBwLlggPSAoaW50KSAod2lkdGggLyAyIC0gMTYpOwogICAgICAgIHAuWSA9IChpbnQpIChoZWlnaHQgLyAxLjVmKTsKICAgICAgICBTZXRDb25zb2xlQ3Vyc29yUG9zaXRpb24oaE91dCwgcCk7CiAgICAgICAgcHJpbnRmKCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIpOwogICAgICAgIGdlc3RhcnRldCA9IHRydWU7CiAgICAgIH0KICAgIH0KCiAgICAvLyBBbGxlcyB6ZWljaG5lbgogICAgZHJhdygmeW91KTsKICAgIGRyYXcoJmNvbXApOwogICAgZHJhd2JhbGwoJmIpOwoKCS8vIFZlcnrDg8K2Z2VybgogICAgU2xlZXAoZGVsYXkpOwogIH0KIH0KCgkvLyBLb25maWd1cmF0aW9uIGRlciBUYXN0ZW5iZWxlZ3VuZwoJdm9pZCBzdGV1ZXJ1bmcoKQoJewoJIHN5c3RlbSgiY2xzIik7CgkgcHJpbnRmKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwoJIHByaW50ZigiPT0gIEJpdHRlIHdcMjA0aGxlbiBzaWUgZGllIFRhc3RlIGRpZSBzaWUgdmVyXDIwNG5kZXJuIG1cMjI0Y2h0ZW4gdW5kIGRyXDIwMWNrZW4gc2llID09XG4iKTsKCSBwcmludGYoIj09ICBhbnNjaGxpZVwzNDFlbmQgZGllIFRhc3RlIGRpZSBzaWUgenV3ZWlzZW4gd29sbGVuISAgICAgICAgICAgICAgICAgICAgICA9PVxuIik7CQkJCS8vIE1lbsODwrwgZGFyc3RlbGxlbgoJIHByaW50ZigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiIpOwoKCSBwcmludGYoIjwxPiBMaW5rc1x0XHRcdEFrdHVlbGxlIFRhc3RlOiAlY1xuIixsaW5rcyk7CgkgcHJpbnRmKCI8Mj4gUmVjaHRzXHRcdFx0QWt0dWVsbGUgVGFzdGU6ICVjXG4iLHJlY2h0cyk7CQkJCQkJCQkJCQkJCQkvLyBha3R1ZWxsZSBUYXN0ZW5iZWxlZ3VuZyBhbnplaWdlbgoJIHByaW50ZiAoIjwzPiBCZWVuZGVuXHRcdFx0QWt0dWVsbGUgVGFzdGU6ICVjXG4iLGJlZW5kZW4pOwoJIHByaW50ZigiPDQ+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxXG5cbiIpOwoJIHByaW50ZigiQmVhY2h0ZTogS2xlaW5idWNoc3RhYmVuIG1cMjAxc3NlbiBsZWlkZXIgaW0gTW9tZW50IG5vY2ggYWxzXG4iKTsKCSBwcmludGYoIlx0IEdyb1wzNDFidWNoc3RhYmVuIGFuZ2VnZWJlbiB3ZXJkZW4hIik7CgoJIGludCBhdXN3YWhsID0gX2dldGNoKCk7CgoJIGlmKGF1c3dhaGwgPT0gNDkpCgkgewoJCSBsaW5rcyA9IF9nZXRjaCgpOwkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBBdWYgQmVudXR6ZXJlaW5nYWJlIHdhcnRlbiB1bmQgYXVzd2VydGVuCgkJIHN5c3RlbSgiY2xzIik7CgkJIHN0ZXVlcnVuZygpOwoJIH0KCSBlbHNlIGlmKGF1c3dhaGwgPT0gNTApCgkgewoJCSByZWNodHMgPSBfZ2V0Y2goKTsKCQkgc3lzdGVtKCJjbHMiKTsJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIHdhcnRlbiBhdWYgRWluZ2FiZSB1bmQgbmV1ZSBUYXN0ZSBzZXR6ZW4KCQkgc3RldWVydW5nKCk7CgkgfQoJIGVsc2UgaWYoYXVzd2FobCA9PSA1MSkKCSB7CgkJIGJlZW5kZW4gPSBfZ2V0Y2goKTsKCQkgc3lzdGVtKCJjbHMiKTsKCQkgc3RldWVydW5nKCk7CgkgfQoJIGVsc2UgaWYoYXVzd2FobCA9PSA1MikKCSB7CgkJIHN5c3RlbSgiY2xzIik7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyB6dXLDg8K8Y2sgenVtIEhhdXB0bWVuw4PCvAoJCSByZXR1cm47CgkgfQoJIGVsc2UKCSB7CgkJIHByaW50ZigiXG5cblVuZ1wyMDFsdGlnZSBFaW5nYWJlIVxuXG4iKTsKCQkgU2xlZXAoMjAwMCk7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBmYWxscyBlaW5lIFRhc3RlLCBkaWUgbmljaHQgenVyIEF1c3dhaGwgc3RhbmQgZ2VkcsODwrxja3Qgd3VyZGUsIFVuZ8ODwrxsdGlnZSBFaW5nYWJlIGFuemVpZ2VuCgkJIHN5c3RlbSgiY2xzIik7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyB1bmQgenVyw4PCvGNrIHp1bSBIYXV0cG1lbsODwrwKCQkgc3RldWVydW5nKCk7CgkgfQogfQoKCS8vIFNjaHdpZXJpZ2tlaXRzZ3JhZCwgQmFsbGdlc2Nod2luZGlna2VpdAoJLy8gZWluc3RlbGxlbiwgYWxsZXMgenVyw4PCvGNrc2V0emVuCgl2b2lkIGVpbnN0ZWxsdW5nZW4oKQogewoJIHN5c3RlbSgiY2xzIik7CgkgcHJpbnRmKCJCaXR0ZSB3XDIwNGhsZW4gc2llIGVpbmUgRWluc3RlbGx1bmcgZGllIHNpZSB2ZXJcMjA0bmRlcm4gbVwyMjRjaHRlbiFcblxuIik7CgkgcHJpbnRmKCI8MT4gU2Nod2llcmllZ2tlaXRzZ3JhZCBcMjA0bmRlcm5cdFx0QWt0dWVsbGUgU2Nod2llcmlna2VpdDogJXNcbiIsc2Nod2llcmlna2VpdCk7CQkJLy8gTWVuw4PCvCBtaXQgYWt0dWVsbGVuIEVpbnN0ZWxsdW5nZW4gYW56ZWlnZW4KCSBwcmludGYoIjwyPiBNYXhpbWFsZSBCYWxsZ2VzY2h3aW5kaWdrZWl0XHRBa3R1ZWxsZSBHZXNjaHdpbmRpZ2tlaXQ6ICUuMmZcbiIsbWF4U3BlZWQpOwoJIHByaW50ZigiPDM+IEFuemFobCBkZXIgUHVua3RlIGJpcyB6dW0gU2llZ1x0QWt0dWVsbGUgU2llZ3B1bmt0ZTogJWlcbiIsc2llZ1B1bmt0ZSk7CgkgcHJpbnRmKCI8ND4gQWxsZSBFaW5zdGVsbHVuZ2VuIHp1clwyMDFja3NldHplblxuIik7CgkgcHJpbnRmKCI8NT4gSGlnaHNjb3JlIHp1clwyMDFja3NldHp0ZW5cbiIpOwoJIHByaW50ZigiPDY+IFp1clwyMDFjayB6dW0gSGF1cHRtZW5cMjAxXG5cbiIpOwoKCSBpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwkJCQkJCQkJCQkJCQkJCQkJCQkvLyBFaW5nYWJlIGluIFZhcmlhYmxlIHNwZWljaGVybgoKCSBpZihhdXN3YWhsID09IDQ5KQkJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIEVpbmdhYmUgYXVzd2VydGVuCgkgewoJCSBzeXN0ZW0oImNscyIpOwoJCSBwcmludGYoIldcMjA0aGxlbiBzaWUgaWhyZW4gYmV2b3J6dWd0ZW4gU2Nod2llcmlna2VpdHNncmFkIVxuXG4iKTsKCQkgcHJpbnRmKCI8MT4gQW1hdGV1clxuIik7CQkJCQkJCQkJCQkJCQkJCQkJLy8gU2Nod2llcmlna2VpdHNncmFkIE1lbsODwrwgw4PCtmZmbmVuCgkJIHByaW50ZigiPDI+IE1hY2hiYXJcbiIpOwoJCSBwcmludGYoIjwzPiBWZXRlcmFuXG4iKTsKCQkgcHJpbnRmKCI8ND4gTmVydnRcMjI0dGVuZFxuIik7CgoJCSBpbnQgYXVzd2FobCA9IF9nZXRjaCgpOwoJCSBzdHJjcHkoc2Nod2llcmlna2VpdCwgIiIpOwoKCQkgaWYoYXVzd2FobCA9PSA0OSkKCQkgewoJCQkgbW9kaWZpa2F0b3IgPSAwOwoJCQkgbW9kaWZpa2F0b3IgKz0gMjsJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBQYWRsw4PCpG5nZSBhbnBhc3NlbgoJCQkgbWF4U3BlZWQgPSAxLjhmOwkJCQkJCQkJCQkJCQkJCQkJCQkvLyBCYWxsZ2VzY2h3aW5kaWdrZWl0IGplIG5hY2ggQXVzd2FobCBhbnBhc3NlbgoJCQkgc3RyY2F0KHNjaHdpZXJpZ2tlaXQsICJBbWF0ZXVyIik7CQkJCQkJCQkJCQkJCQkJLy8gU2Nod2llcmlna2VpdHNncmFkYW56ZWlnZSBpbSBFaW5zdGVsbHVuZ3NtZW7Dg8K8IGFrdHVhbGlzaWVyZW4KCQkJIHN0cmNweShwZmFkLCAiQzpcXEFtYXRldXIudHh0Iik7CQkJCQkJCQkJCQkJCQkJLy8gUGZhZCBmw4PCvHIgSGlnaHNjb3JlZGF0ZWkgYWt0dWFsaXNpZXJlbgoJCQkgY29tcHYgPSAxMC4wZjsJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIENvbXB1dGVyIFNjaG5lbGxpZ2tlaXQgc2V0emVuCgkJCSByZXR1cm47CQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gKGFsdGVyIFN0cmluZyB3aXJkIGdlbMODwrZzY2h0IHVuZCBuZXVlciBhbmdlaMODwqRuZ3QpCgkJIH0KCQkgZWxzZSBpZihhdXN3YWhsID09IDUwKQoJCSB7CgkJCSBtb2RpZmlrYXRvciA9IDA7CgkJCSBzdHJjYXQoc2Nod2llcmlna2VpdCwgIk1hY2hiYXIiKTsKCQkJIHN0cmNweShwZmFkLCAiQzpcXE1hY2hiYXIudHh0Iik7CgkJCSBjb21wdiA9IDguMGY7CgkJCSBtYXhTcGVlZCA9IDMuMmY7CgkJCSByZXR1cm47CgkJIH0KCQkgZWxzZSBpZihhdXN3YWhsID09IDUxKQoJCSB7CgkJCSBtb2RpZmlrYXRvciA9IDA7CgkJCSBtb2RpZmlrYXRvciAtPSAyOwoJCQkgc3RyY2F0KHNjaHdpZXJpZ2tlaXQsICJWZXRlcmFuIik7CgkJCSBzdHJjcHkocGZhZCwgIkM6XFxWZXRlcmFuLnR4dCIpOwoJCQkgY29tcHYgPSA2LjBmOwoJCQkgbWF4U3BlZWQgPSA0LjVmOwoJCQkgcmV0dXJuOwoJCSB9CgkJIGVsc2UgaWYoYXVzd2FobCA9PSA1MikKCQkgewoJCQkgbW9kaWZpa2F0b3IgPSAwOwoJCQkgbW9kaWZpa2F0b3IgLT0gNDsKCQkJIHN0cmNhdChzY2h3aWVyaWdrZWl0LCAiTmVydnRcMjI0dGVuZCIpOwoJCQkgc3RyY3B5KHBmYWQsICJDOlxcTmVydnRcMjI0dGVuZC50eHQiKTsKCQkJIGNvbXB2ID0gMy43ZjsKCQkJIG1heFNwZWVkID0gNi4wZjsKCQkJIHJldHVybjsKCQkgfQoJCSBlbHNlCgkJIHsKCQkJcHJpbnRmKCJcblxuVW5nXDIwMWx0aWdlIEVpbmdhYmUhXG5cbiIpOwkJCQkJCQkJCQkJCQkJLy8gZmFsbHMgZWluZSBUYXN0ZSwgZGllIG5pY2h0IHp1ciBBdXN3YWhsIHN0YW5kIGdlZHLDg8K8Y2t0IHd1cmRlLCBVbmfDg8K8bHRpZ2UgRWluZ2FiZSBhbnplaWdlbgoJCQlTbGVlcCgyMDAwKTsJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyB1bmQgenVyw4PCvGNrIHp1bSBIYXV0cG1lbsODwrwKCQkJcmV0dXJuOwoJCSB9CgkgfQoJIGVsc2UgaWYoYXVzd2FobCA9PSA1MCkKCSB7CgkJIHByaW50ZigiTmV1ZSBCYWxsZ2VzY2h3aW5kaWdrZWl0IGVpbmdlYmVuIVxuXG4iKTsJCQkJCQkJCQkJCQkJLy8gQWJmcmFnZSBuYWNoIG5ldWVyIEJhbGxnZXNjaHdpbmRpZ2tlaXQKCQkgc2NhbmYoIiVmIiwmbWF4U3BlZWQpOwoKCQkgaWYobWF4U3BlZWQgIT0gMS44ZiAmJiBtYXhTcGVlZCAhPSAyLjhmICYmIG1heFNwZWVkICE9IDMuNWYgJiYgbWF4U3BlZWQgIT0gNSkJCQkJCQkvLyBGYWxscyBCYWxsZ2VzY2h3aW5kaWdrZWl0IHVuZ2xlaWNoIGRlbiBWb3JlaW5zdGVsbHVuZ2VuLCBzbwoJCSB7CgkJCXN0cmNweShzY2h3aWVyaWdrZWl0LCIiKTsJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIHdpcmQgZGllIFNjaHdpZXJpZ2tlaXRzYW56ZWlnZSBhdWYgIlBlcnPDg8K2bmxpY2giIGdlc2V0enQKCQkJc3RyY2F0KHNjaHdpZXJpZ2tlaXQsICJQZXJzXDIyNG5saWNoIik7CgkJCXN5c3RlbSgiY2xzIik7CgkJIH0KCQkgZWluc3RlbGx1bmdlbigpOwkJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIHp1csODwrxjayB6dW0gRWluc3RlbGx1bmdzbWVuw4PCvAoJIH0KCSBlbHNlIGlmKGF1c3dhaGwgPT0gNTEpCgkgewoJCSBwcmludGYoIk5ldWUgQW56YWhsIGRlciBiZW5cMjI0dGlndGVuIFNpZWdwdW5rdGUgZWluZ2ViZW4hXG5cbiIpOwkJCQkJCQkJCS8vIEFiZnJhZ2UgbmFjaCBuZXVlciBCYWxsZ2VzY2h3aW5kaWdrZWl0CgkJIHNjYW5mKCIlaSIsJnNpZWdQdW5rdGUpOwoJCSBzeXN0ZW0oImNscyIpOwoJCSByZXR1cm47CgkgfQoJIGVsc2UgaWYoYXVzd2FobCA9PSA1MikKCSB7CgkJIHN5c3RlbSgiY2xzIik7CgkJIHByaW50ZigiU2luZCBzaWUgc2ljaCBzaWNoZXIsIGRhc3Mgc2llIGFsbGUgRWluc3RlbGx1bmdlbiB6dXJcMjAxY2tzZXR6ZW4gbVwyMjRjaHRlbj9cblxuIik7CQkvLyBGcmFnZW4sIG9iIGRlciBCZW51dHplciBzaWNoZXIgaXN0LCBkYXNzIGVyIGRpZSBFaW5zdGVsbHVuZ2VuIHp1csODwrxja3NldHplbiBtw4PCtmNodAoJCSBwcmludGYoIjwxPiBKYSwgYWxsZSBsXDIyNHNjaGVuXG4iKTsKCQkgcHJpbnRmKCI8Mj4gTmVpbiwgenVyXDIwMWNrIHp1IEVpbnN0ZWxsdW5nZW4iKTsKCgkJIGludCBhdXN3YWhsID0gX2dldGNoKCk7CQkJCQkJCQkJCQkJCQkJCQkJCS8vIEJlbnV0emVyZWluZ2FiZSBlaW5sZXNlbgoKCQkgaWYoYXVzd2FobCA9PSA0OSkKCQkgewoJCQlzeXN0ZW0oImNscyIpOwoJCQlzdHJjcHkoc2Nod2llcmlna2VpdCwiIik7CgkJCXN0cmNhdChzY2h3aWVyaWdrZWl0LCAiTWFjaGJhciIpOwkJCQkJCQkJCQkJCQkJCQkvLyBBbGxlIFdlcnRlIGF1ZiBTdGFuZGFyZCBzZXR6ZW4KCQkJbWF4U3BlZWQgPSAzLjJmOwoJCQlsaW5rcyA9IDY1LCByZWNodHMgPSA2OCwgYmVlbmRlbiA9IDgxOwoJCQlwcmludGYoIlxuIEVpbnN0ZWxsdW5nZW4gZXJmb2xncmVpY2ggenVyXDIwMWNrZ2VzZXR6dCEiKTsKCQkJU2xlZXAoMjUwMCk7CgkJCXN5c3RlbSgiY2xzIik7CgkJCXJldHVybjsKCQkgIH0KCQkgIGVsc2UgaWYoYXVzd2FobCA9PSA1MCkKCQkgIHsKCQkJZWluc3RlbGx1bmdlbigpOwkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gZmFsbHMgbmVpbiwgenVyw4PCvGNrIHp1bSBFaW5zdGVsbHVuZ3NtZW7Dg8K8CgkJICB9CgkJICBlbHNlCgkJICB7CgkJCXByaW50ZigiXG5cblVuZ1wyMDFsdGlnZSBFaW5nYWJlIVxuXG4iKTsKCQkJU2xlZXAoMjAwMCk7CQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gZmFsbHMgZWluZSBUYXN0ZSwgZGllIG5pY2h0IHp1ciBBdXN3YWhsIHN0YW5kIGdlZHLDg8K8Y2t0IHd1cmRlLCBVbmfDg8K8bHRpZ2UgRWluZ2FiZSBhbnplaWdlbgoJCQlzeXN0ZW0oImNscyIpOwkJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIHVuZCB6dXLDg8K8Y2sgenVtIEhhdXRwbWVuw4PCvAoJCQllaW5zdGVsbHVuZ2VuKCk7CgkJICB9CgkgfQoJIGVsc2UgaWYoYXVzd2FobCA9PSA1MykKCSB7CgkJIHN5c3RlbSgiY2xzIik7CgkJIHByaW50ZigiU2luZCBzaWUgc2ljaCBzaWNoZXIsIGRhc3Mgc2llIGFsbGUgSGlnaHNjb3JlcyBsXDIyNHNjaGVuIG1cMjI0Y2h0ZW4/XG5cbiIpOwkJCQkvLyBGcmFnZW4sIG9iIGRlciBCZW51dHplciBzaWNoZXIgaXN0LCBkYXNzIGVyIGRpZSBIaWdoc2NvcmVzIGzDg8K2c2NoZW4gbcODwrZjaHRlCgkJIHByaW50ZigiPDE+IEphLCBhbGxlIGxcMjI0c2NoZW5cbiIpOwoJCSBwcmludGYoIjwyPiBOZWluLCB6dXJcMjAxY2sgenUgRWluc3RlbGx1bmdlbiIpOwoKCQkgaW50IGF1c3dhaGwgPSBfZ2V0Y2goKTsJCQkJCQkJCQkJCQkJCQkJCQkJLy8gQmVudXR6ZXJlaW5nYWJlIGVpbmxlc2VuCgoJCSBpZihhdXN3YWhsID09IDQ5KQoJCSB7CgkJCUZJTEUgKkZEYXRlaTsKCQkJRkRhdGVpID0gZm9wZW4oIkM6XFxBbWF0ZXVyIiwidyIpOwkJCQkJCQkJCQkJCQkJLy8gQWx0ZSBIaWdoc2NvcmUgVGV4dGRhdGVpIGxlZXJlbgoJCQlmY2xvc2UoRkRhdGVpKTsKCQkJRkRhdGVpID0gZm9wZW4oIkM6XFxNYWNoYmFyLnR4dCIsInciKTsJCQkJCQkJCQkJCQkJCS8vIEFsdGUgSGlnaHNjb3JlIFRleHRkYXRlaSBsZWVyZW4KCQkJZmNsb3NlKEZEYXRlaSk7CgkJCUZEYXRlaSA9IGZvcGVuKCJDOlxcVmV0ZXJhbi50eHQiLCJ3Iik7CQkJCQkJCQkJCQkJCQkvLyBBbHRlIEhpZ2hzY29yZSBUZXh0ZGF0ZWkgbGVlcmVuCgkJCWZjbG9zZShGRGF0ZWkpOwoJCQlGRGF0ZWkgPSBmb3BlbigiQzpcXE5lcnZ0XDIyNHRlbmQudHh0IiwidyIpOwkJCQkJCQkJCQkJCQkJLy8gQWx0ZSBIaWdoc2NvcmUgVGV4dGRhdGVpIGxlZXJlbgoJCQlmY2xvc2UoRkRhdGVpKTsKCQkJc3lzdGVtKCJjbHMiKTsKCQkJcHJpbnRmKCJIaWdoc2NvcmVzIGVyZm9sZ3JlaWNoIHp1clwyMDFja2dlc2V0enQhIik7CgkJCVNsZWVwKDIwMDApOwoJCQlyZXR1cm47CgkJIH0KCQkgZWxzZSBpZihhdXN3YWhsID09IDUwKQoJCSB7CgkJCWVpbnN0ZWxsdW5nZW4oKTsKCQkgfQoJCSBlbHNlCgkJIHsKCQkJcHJpbnRmKCJcblxuVW5nXDIwMWx0aWdlIEVpbmdhYmUhXG5cbiIpOwoJCQlTbGVlcCgyMDAwKTsJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBmYWxscyBlaW5lIFRhc3RlLCBkaWUgbmljaHQgenVyIEF1c3dhaGwgc3RhbmQgZ2VkcsODwrxja3Qgd3VyZGUsIFVuZ8ODwrxsdGlnZSBFaW5nYWJlIGFuemVpZ2VuCgkJCXN5c3RlbSgiY2xzIik7CQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gdW5kIHp1csODwrxjayB6dW0gSGF1dHBtZW7Dg8K8CgkJCWVpbnN0ZWxsdW5nZW4oKTsKCQkgfQoJIH0KCSBlbHNlIGlmKGF1c3dhaGwgPT0gNTQpCgkgewoJCSBzeXN0ZW0oImNscyIpOwkJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIHp1csODwrxjayB6dW0gSGF1cHRtZW7Dg8K8CgkJIHJldHVybjsKCSB9CgkgZWxzZQoJIHsKCQkgcHJpbnRmKCJcblxuVW5nXDIwMWx0aWdlIEVpbmdhYmUhXG5cbiIpOwoJCSBTbGVlcCgyMDAwKTsJCQkJCQkJCQkJCQkJCQkJCQkJCQkvLyBmYWxscyBlaW5lIFRhc3RlLCBkaWUgbmljaHQgenVyIEF1c3dhaGwgc3RhbmQgZ2VkcsODwrxja3Qgd3VyZGUsIFVuZ8ODwrxsdGlnZSBFaW5nYWJlIGFuemVpZ2VuCgkJIHN5c3RlbSgiY2xzIik7CQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gdW5kIHp1csODwrxjayB6dW0gSGF1dHBtZW7Dg8K8CgkJIGVpbnN0ZWxsdW5nZW4oKTsKCSB9CgoKCiB9CgoJLy8gSGF1cHRtZW7Dg8K8IGFuemVpZ2VuIHVuZCBBdXN3YWhsIGF1c3dlcnRlbgoJdm9pZCBtZW51KCkKIHsKCglzZXRXaW5kb3dTaXplKDgwLDI1KTsKCglzeXN0ZW0oImNscyIpOwoJcHJpbnRmKCJXXDIwNGhsZW4gc2llIGVpbmUgTVwyMjRnbGljaGtlaXQhXG5cbiIpOwoJcHJpbnRmKCI8MT4gUG9uZyBzcGllbGVuXG4iKTsKCXByaW50ZigiPDI+IFN0ZXVlcnVuZ1xuIik7CQkJCQkJCQkJCQkJCQkJCS8vIE1lbsODwrwgZGFyc3RlbGxlbgoJcHJpbnRmKCI8Mz4gSGlnaHNjb3JlXG4iKTsKCXByaW50ZigiPDQ+IEVpbnN0ZWxsdW5nZW5cbiIpOwoJcHJpbnRmKCI8NT4gU3BpZWwgYmVlbmRlblxuXG4iKTsKCWludCBhdXN3YWhsID0gX2dldGNoKCk7CgkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gQXVmIEJlbnV0emVyZWluZ2FiZSB3YXJ0ZW4KCXN5c3RlbSgiY2xzIik7CgoJaWYoYXVzd2FobCA9PSA0OSkKCXsKCQlzcGllbGVuKCk7Cgl9CgllbHNlIGlmKGF1c3dhaGwgPT0gNTApCQkJCQkJCQkJCQkJCQkJCQkvLyBqZSBuYWNoIEF1c3dhaGwsIGRhcyBlbnN0cHJlY2hlbmRlIFVudGVybWVuw4PCvCDDg8K2ZmZuZW4KCXsKCQlzdGV1ZXJ1bmcoKTsKCX0KCWVsc2UgaWYoYXVzd2FobCA9PSA1MSkKCXsKCQloaWdoc2NvcmVBdXNnZWJlbigpOwoJfQoJZWxzZSBpZihhdXN3YWhsID09IDUyKQoJewoJCWVpbnN0ZWxsdW5nZW4oKTsKCX0KCWVsc2UgaWYoYXVzd2FobCA9PSA1MykKCXsKCQltYWluTG9vcCA9IDI7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCS8vIE1haW4gU2NobGVpZmUgdW50ZXJicmVjaGVuIHVuZCBQcm9ncmFtbSBiZWVuZGVuCgl9CgllbHNlCgkgewoJCSBwcmludGYoIlxuXG5VbmdcMjAxbHRpZ2UgRWluZ2FiZSFcblxuIik7CgkJIFNsZWVwKDIwMDApOwkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gZmFsbHMgZWluZSBUYXN0ZSwgZGllIG5pY2h0IHp1ciBBdXN3YWhsIHN0YW5kIGdlZHLDg8K8Y2t0IHd1cmRlLCBVbmfDg8K8bHRpZ2UgRWluZ2FiZSBhbnplaWdlbgoJCSBtZW51KCk7CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJLy8gdW5kIHp1csODwrxjayB6dW0gSGF1dHBtZW7Dg8K8CgkgfQogfQoKCS8vIEJlZ2lubiBkZXMgUHJvZ3JhbW1zIGRpcmVrdGVyIFZlcndlaXMgbmFjaCBNZW7Dg8K8CglpbnQgbWFpbigpCgl7CgkJaE91dCA9IEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSk7CgkJLy8gQ3Vyc29yIHZlcnN0ZWNrZW4KCQlDT05TT0xFX0NVUlNPUl9JTkZPIENvbkN1ckluZjsKCQlDb25DdXJJbmYuZHdTaXplID0gMTA7CgkJQ29uQ3VySW5mLmJWaXNpYmxlID0gZmFsc2U7CgkJU2V0Q29uc29sZUN1cnNvckluZm8oaE91dCwgJkNvbkN1ckluZik7CgoJCXdoaWxlKG1haW5Mb29wIDw9IDEpCgkJewoJCQlpZihtYWluTG9vcCA9PSAwKQoJCQl7CgkJCQltZW51KCk7CQkJCQkJCQkJCS8vIHZlcmhpbmRlcm4sIGRhc3MgZGFzIFByb2dyYW1tIGZyw4PCvGh6ZWl0aWcgYmVlbmRldCB3aXJkCgkJCX0KCQkJZWxzZSBpZihtYWluTG9vcCA9PSAxKQoJCQl7CgkJCQlzcGllbGVuZGUoKTsKCQkJfQoKCQl9CgoJCXJldHVybiAwOwoKCX0K