--
-- Author: Ab- 47 ; State: INCOMPLETE.
-- Additional Notes; N/ A; Rights: All Rights Reserved by Developers and Ab- 47 .
-- Project: DAWabus/ client.lua consisting of 2 file( s) .
-- Side Notes: N/ A
--
local screenWidth, screenHeight = guiGetScreenSize( )
local license = { }
local skin_selected = { }
local declined = { }
local rank = { }
skins = {
{ 217 , "Rookie" } ,
{ 211 , "Semi-Pro" } ,
}
bus = {
button = { } ,
window = { } ,
gridlist = { } ,
label = { } ,
column = { }
}
function create_bus_window( )
windowWidth, windowHeight = 316 , 479
windowX, windowY = ( screenWidth / 1.15 ) - ( windowWidth / 2 ) , ( screenHeight / 1.6 ) - ( windowHeight / 2 )
bus.window [ 1 ] = guiCreateWindow( windowX, windowY, windowWidth, windowHeight, "Dawn - Bus Driver Application" , false )
guiWindowSetSizable( bus.window [ 1 ] , false )
guiSetAlpha( bus.window [ 1 ] , 1.00 )
guiSetVisible( bus.window [ 1 ] , false )
bus.button [ 1 ] = guiCreateButton( 273 , 25 , 34 , 34 , "X" , false , bus.window [ 1 ] )
bus.button [ 3 ] = guiCreateButton( 233 , 25 , 34 , 34 , ":)" , false , bus.window [ 1 ] )
bus.button [ 4 ] = guiCreateButton( 10 , 280 , 97 , 33 , "Choose" , false , bus.window [ 1 ] )
bus.button [ 5 ] = guiCreateButton( 116 , 280 , 97 , 33 , "Proceed" , false , bus.window [ 1 ] )
bus.label [ 1 ] = guiCreateLabel( 30 , 26 , 193 , 33 , "Dawn - Bus Driver Job" , false , bus.window [ 1 ] )
bus.label [ 2 ] = guiCreateLabel( 11 , 76 , 296 , 31 , "Do you have a license? If yes then proceed." , false , bus.window [ 1 ] )
bus.label [ 3 ] = guiCreateLabel( 10 , 107 , 193 , 33 , "Step 1 - Skin Selection" , false , bus.window [ 1 ] )
bus.label [ 5 ] = guiCreateLabel( 10 , 346 , 296 , 31 , "Status: Unconfirmed" , false , bus.window [ 1 ] )
bus.label [ 6 ] = guiCreateLabel( 10 , 313 , 148 , 38 , "Step 2 - Confirmation" , false , bus.window [ 1 ] )
bus.label [ 8 ] = guiCreateLabel( 15 , 411 , 281 , 42 , "Click the smiley at the top right to take the job\n select the X to cancel your application." , false , bus.window [ 1 ] )
bus.label [ 9 ] = guiCreateLabel( 10 , 373 , 148 , 38 , "Step 3 - Decision" , false , bus.window [ 1 ] )
bus.gridlist [ 1 ] = guiCreateGridList( 9 , 142 , 298 , 130 , false , bus.window [ 1 ] )
bus.column [ 1 ] = guiGridListAddColumn( bus.gridlist [ 1 ] , "ID" , 0.3 )
bus.column [ 2 ] = guiGridListAddColumn( bus.gridlist [ 1 ] , "Name" , 0.3 )
bus.column [ 3 ] = guiGridListAddColumn( bus.gridlist [ 1 ] , "Rank" , 0.3 )
guiSetProperty( bus.button [ 1 ] , "NormalTextColour" , "FFAAAAAA" )
guiSetProperty( bus.button [ 3 ] , "NormalTextColour" , "FFAAAAAA" )
guiSetProperty( bus.button [ 4 ] , "NormalTextColour" , "FFAAAAAA" )
guiSetProperty( bus.button [ 5 ] , "NormalTextColour" , "FFAAAAAA" )
guiSetFont( bus.label [ 1 ] , "clear-normal" )
guiSetFont( bus.label [ 3 ] , "default-bold-small" )
guiSetFont( bus.label [ 6 ] , "default-bold-small" )
guiSetFont( bus.label [ 9 ] , "default-bold-small" )
guiLabelSetColor( bus.label [ 1 ] , 245 , 232 , 9 )
guiLabelSetColor( bus.label [ 3 ] , 245 , 232 , 9 )
guiLabelSetColor( bus.label [ 6 ] , 245 , 232 , 9 )
guiLabelSetColor( bus.label [ 9 ] , 245 , 232 , 9 )
guiLabelSetVerticalAlign( bus.label [ 1 ] , "center" )
guiLabelSetVerticalAlign( bus.label [ 3 ] , "center" )
guiLabelSetVerticalAlign( bus.label [ 5 ] , "center" )
guiLabelSetVerticalAlign( bus.label [ 6 ] , "center" )
guiLabelSetVerticalAlign( bus.label [ 8 ] , "center" )
guiLabelSetVerticalAlign( bus.label [ 9 ] , "center" )
guiLabelSetHorizontalAlign( bus.label [ 8 ] , "center" , false )
guiLabelSetHorizontalAlign( bus.label [ 2 ] , "center" , false )
guiLabelSetHorizontalAlign( bus.label [ 5 ] , "center" , false )
addEventHandler( "onClientGUIClick" , bus.button [ 1 ] , function( ) if ( source== bus.button [ 1 ] ) then guiSetVisible( bus.window [ 1 ] , false ) outputChatBox( "You have cancelled your application, better luck next time!" , 255 , 0 , 0 ) declined[ localPlayer] = false setElementModel( localPlayer, model) reset_gui_data( ) showCursor( false ) end end)
addEventHandler( "onClientGUIClick" , bus.button [ 3 ] , function( ) if ( source== bus.button [ 3 ] ) then proceed_to_app( ) end end)
addEventHandler( "onClientGUIClick" , bus.button [ 4 ] , function( ) if ( source== bus.button [ 4 ] ) then proceed_to_skin_selection( ) end end)
addEventHandler( "onClientGUIClick" , bus.button [ 5 ] , function( ) if ( source== bus.button [ 5 ] ) then proceed_to_confirmation( ) end end)
addEventHandler( "onClientGUIClick" , bus.gridlist [ 1 ] , viewTheSkin, false )
end
addEventHandler( "onClientResourceStart" , root, create_bus_window)
function proceed_to_skin_selection( )
local skin = getElementModel( localPlayer)
if ( declined[ localPlayer] ) then outputChatBox( "You've already been declined, come back later please!" , 255 , 0 , 0 ) return end
for index, s in pairs( skins) do
if ( skin ~= s) then
if ( skin == 0 or skin == model and not noSkin) then
setElementModel( localPlayer, model)
outputChatBox( "You must select a skin from the list!" , 255 , 0 , 0 )
return
end
end
end
outputChatBox( "Skin successfully chosen, please select 'Proceed' to continue your application." , 0 , 255 , 0 )
skin_selected[ localPlayer] = true
end
function proceed_to_confirmation( )
if ( not skin_selected[ localPlayer] ) then
outputChatBox( "You must choose a skin to proceed to confirmation!" , 255 , 0 , 0 )
elseif ( license[ localPlayer] ) then
outputChatBox( "You do not have an eligible license at the moment, come back when you've got one!" , 255 , 0 , 0 )
guiSetText( bus.label [ 5 ] , "Status: License unidentified, application rejected." )
guiLabelSetColor( bus.label [ 5 ] , 255 , 0 , 0 )
setTimer( function( ) guiLabelSetColor( bus.label [ 8 ] , 255 , 0 , 0 ) end, 1000 , 1 )
declined[ localPlayer] = true
else
outputChatBox( "Step 2 success, continue to step 3 to finish your application." , 0 , 255 , 0 )
guiSetText( bus.label [ 5 ] , "Status: License approved, okay to proceed." )
guiLabelSetColor( bus.label [ 5 ] , 0 , 255 , 0 )
setTimer( function( ) guiLabelSetColor( bus.label [ 8 ] , 0 , 255 , 0 ) end, 1000 , 1 )
end
end
function reset_gui_data( )
guiSetText( bus.label [ 5 ] , "Status: Unidentified" )
guiLabelSetColor( bus.label [ 5 ] , 255 , 255 , 255 )
guiLabelSetColor( bus.label [ 8 ] , 255 , 255 , 255 )
end
function busApplicationHandle( string)
if ( string == "open" ) then
guiSetVisible( bus.window [ 1 ] , true )
showCursor( not isCursorShowing( ) , true )
model = getElementModel( localPlayer)
guiGridListClear( bus.gridlist [ 1 ] )
if ( not skins) then
guiSetVisible( bus.gridlist [ 1 ] , false )
noSkin = true
return
else
guiSetVisible( bus.gridlist [ 1 ] , true )
noSkin = nil
end
for index, skin in pairs( skins) do
local row = guiGridListAddRow( bus.gridlist [ 1 ] )
guiGridListSetItemText( bus.gridlist [ 1 ] , row, bus.column [ 1 ] , skin[ 1 ] , false , true )
guiGridListSetItemText( bus.gridlist [ 1 ] , row, bus.column [ 2 ] , "Bus Driver" , false , true )
guiGridListSetItemText( bus.gridlist [ 1 ] , row, bus.column [ 3 ] , skin[ 2 ] , false , true )
end
elseif ( string == "close" ) then
if ( not guiGetVisible( bus.window [ 1 ] ) ) then return end
rank[ localPlayer] = nil
guiSetVisible( bus.window [ 1 ] , false )
showCursor( false )
end
end
addEvent( "DAWabus.bring_up_application" , true )
addEventHandler( "DAWabus.bring_up_application" , root, busApplicationHandle)
function proceed_to_app( )
if ( declined[ localPlayer] ) then return end
local skin = getElementModel( localPlayer)
for index, s in pairs( skins) do
if ( skin ~= s) then
if ( skin == 0 or skin == model and not noSkin) then
setElementModel( localPlayer, model)
outputChatBox( "An error has occurred, please re-enter the application centre." , 255 , 0 , 0 )
return
end
end
end
if ( getElementModel( localPlayer) == 217 ) then
rank[ localPlayer] = "Rookie"
elseif ( getElementModel( localPlayer) == 211 ) then
rank[ localPlayer] = "Semi-Pro"
end
guiSetVisible( bus.window [ 1 ] , false )
reset_gui_data( )
showCursor( false )
setElementModel( localPlayer, model)
if ( noSkin) then
skin = false
end
outputChatBox( "We've accepted you to the team, you are now employed as a bus driver " ..tostring ( rank[ localPlayer] ) , 0 , 255 , 0 )
triggerServerEvent( "DAWabus.acceptedJob" , root, localPlayer, skin)
rank[ localPlayer] = nil
end
function viewTheSkin( )
if ( guiGridListGetSelectedItem( bus.gridlist [ 1 ] ) == - 1 ) then return end
local row = guiGridListGetSelectedItem( source)
local skin = guiGridListGetItemText( bus.gridlist [ 1 ] , row, bus.column [ 1 ] )
setElementModel( localPlayer, skin or 0 )
end
-- Job Application Finished
-- Beneath will be the actual bus driving code.
LS0KLS0gQXV0aG9yOiBBYi00NzsgU3RhdGU6IElOQ09NUExFVEUuCi0tIEFkZGl0aW9uYWwgTm90ZXM7IE4vQTsgUmlnaHRzOiBBbGwgUmlnaHRzIFJlc2VydmVkIGJ5IERldmVsb3BlcnMgYW5kIEFiLTQ3LgotLSBQcm9qZWN0OiBEQVdhYnVzL2NsaWVudC5sdWEgY29uc2lzdGluZyBvZiAyIGZpbGUocykuCi0tIFNpZGUgTm90ZXM6IE4vQQotLQoKbG9jYWwgc2NyZWVuV2lkdGgsIHNjcmVlbkhlaWdodCA9IGd1aUdldFNjcmVlblNpemUoKQpsb2NhbCBsaWNlbnNlID0ge30KbG9jYWwgc2tpbl9zZWxlY3RlZCA9IHt9CmxvY2FsIGRlY2xpbmVkID0ge30KbG9jYWwgcmFuayA9IHt9Cgpza2lucyA9IHsKCXsyMTcsICJSb29raWUifSwKCXsyMTEsICJTZW1pLVBybyJ9LAp9CgpidXMgPSB7CiAgICBidXR0b24gPSB7fSwKICAgIHdpbmRvdyA9IHt9LAogICAgZ3JpZGxpc3QgPSB7fSwKICAgIGxhYmVsID0ge30sCgljb2x1bW4gPSB7fQp9CgpmdW5jdGlvbiBjcmVhdGVfYnVzX3dpbmRvdygpCgl3aW5kb3dXaWR0aCwgd2luZG93SGVpZ2h0ID0gMzE2LCA0NzkKCXdpbmRvd1gsIHdpbmRvd1kgPSAoc2NyZWVuV2lkdGggLyAxLjE1KSAtICh3aW5kb3dXaWR0aCAvIDIpLCAoc2NyZWVuSGVpZ2h0IC8gMS42KSAtICh3aW5kb3dIZWlnaHQgLyAyKQoJYnVzLndpbmRvd1sxXSA9IGd1aUNyZWF0ZVdpbmRvdyh3aW5kb3dYLCB3aW5kb3dZLCB3aW5kb3dXaWR0aCwgd2luZG93SGVpZ2h0LCAiRGF3biAtIEJ1cyBEcml2ZXIgQXBwbGljYXRpb24iLCBmYWxzZSkKCWd1aVdpbmRvd1NldFNpemFibGUoYnVzLndpbmRvd1sxXSwgZmFsc2UpCglndWlTZXRBbHBoYShidXMud2luZG93WzFdLCAxLjAwKQoJZ3VpU2V0VmlzaWJsZShidXMud2luZG93WzFdLCBmYWxzZSkKCglidXMuYnV0dG9uWzFdID0gZ3VpQ3JlYXRlQnV0dG9uKDI3MywgMjUsIDM0LCAzNCwgIlgiLCBmYWxzZSwgYnVzLndpbmRvd1sxXSkKCWJ1cy5idXR0b25bM10gPSBndWlDcmVhdGVCdXR0b24oMjMzLCAyNSwgMzQsIDM0LCAiOikiLCBmYWxzZSwgYnVzLndpbmRvd1sxXSkKCWJ1cy5idXR0b25bNF0gPSBndWlDcmVhdGVCdXR0b24oMTAsIDI4MCwgOTcsIDMzLCAiQ2hvb3NlIiwgZmFsc2UsIGJ1cy53aW5kb3dbMV0pCglidXMuYnV0dG9uWzVdID0gZ3VpQ3JlYXRlQnV0dG9uKDExNiwgMjgwLCA5NywgMzMsICJQcm9jZWVkIiwgZmFsc2UsIGJ1cy53aW5kb3dbMV0pCgkKCWJ1cy5sYWJlbFsxXSA9IGd1aUNyZWF0ZUxhYmVsKDMwLCAyNiwgMTkzLCAzMywgIkRhd24gLSBCdXMgRHJpdmVyIEpvYiIsIGZhbHNlLCBidXMud2luZG93WzFdKQoJYnVzLmxhYmVsWzJdID0gZ3VpQ3JlYXRlTGFiZWwoMTEsIDc2LCAyOTYsIDMxLCAiRG8geW91IGhhdmUgYSBsaWNlbnNlPyBJZiB5ZXMgdGhlbiBwcm9jZWVkLiIsIGZhbHNlLCBidXMud2luZG93WzFdKQoJYnVzLmxhYmVsWzNdID0gZ3VpQ3JlYXRlTGFiZWwoMTAsIDEwNywgMTkzLCAzMywgIlN0ZXAgMSAtIFNraW4gU2VsZWN0aW9uIiwgZmFsc2UsIGJ1cy53aW5kb3dbMV0pCglidXMubGFiZWxbNV0gPSBndWlDcmVhdGVMYWJlbCgxMCwgMzQ2LCAyOTYsIDMxLCAiU3RhdHVzOiBVbmNvbmZpcm1lZCIsIGZhbHNlLCBidXMud2luZG93WzFdKQoJYnVzLmxhYmVsWzZdID0gZ3VpQ3JlYXRlTGFiZWwoMTAsIDMxMywgMTQ4LCAzOCwgIlN0ZXAgMiAtIENvbmZpcm1hdGlvbiIsIGZhbHNlLCBidXMud2luZG93WzFdKQoJYnVzLmxhYmVsWzhdID0gZ3VpQ3JlYXRlTGFiZWwoMTUsIDQxMSwgMjgxLCA0MiwgIkNsaWNrIHRoZSBzbWlsZXkgYXQgdGhlIHRvcCByaWdodCB0byB0YWtlIHRoZSBqb2JcbnNlbGVjdCB0aGUgWCB0byBjYW5jZWwgeW91ciBhcHBsaWNhdGlvbi4iLCBmYWxzZSwgYnVzLndpbmRvd1sxXSkKCWJ1cy5sYWJlbFs5XSA9IGd1aUNyZWF0ZUxhYmVsKDEwLCAzNzMsIDE0OCwgMzgsICJTdGVwIDMgLSBEZWNpc2lvbiIsIGZhbHNlLCBidXMud2luZG93WzFdKQoJCglidXMuZ3JpZGxpc3RbMV0gPSBndWlDcmVhdGVHcmlkTGlzdCg5LCAxNDIsIDI5OCwgMTMwLCBmYWxzZSwgYnVzLndpbmRvd1sxXSkKCQoJYnVzLmNvbHVtblsxXSA9IGd1aUdyaWRMaXN0QWRkQ29sdW1uKGJ1cy5ncmlkbGlzdFsxXSwgIklEIiwgMC4zKQoJYnVzLmNvbHVtblsyXSA9IGd1aUdyaWRMaXN0QWRkQ29sdW1uKGJ1cy5ncmlkbGlzdFsxXSwgIk5hbWUiLCAwLjMpCglidXMuY29sdW1uWzNdID0gZ3VpR3JpZExpc3RBZGRDb2x1bW4oYnVzLmdyaWRsaXN0WzFdLCAiUmFuayIsIDAuMykKCQoJZ3VpU2V0UHJvcGVydHkoYnVzLmJ1dHRvblsxXSwgIk5vcm1hbFRleHRDb2xvdXIiLCAiRkZBQUFBQUEiKQoJZ3VpU2V0UHJvcGVydHkoYnVzLmJ1dHRvblszXSwgIk5vcm1hbFRleHRDb2xvdXIiLCAiRkZBQUFBQUEiKQoJZ3VpU2V0UHJvcGVydHkoYnVzLmJ1dHRvbls0XSwgIk5vcm1hbFRleHRDb2xvdXIiLCAiRkZBQUFBQUEiKQoJZ3VpU2V0UHJvcGVydHkoYnVzLmJ1dHRvbls1XSwgIk5vcm1hbFRleHRDb2xvdXIiLCAiRkZBQUFBQUEiKQoKCWd1aVNldEZvbnQoYnVzLmxhYmVsWzFdLCAiY2xlYXItbm9ybWFsIikKCWd1aVNldEZvbnQoYnVzLmxhYmVsWzNdLCAiZGVmYXVsdC1ib2xkLXNtYWxsIikKCWd1aVNldEZvbnQoYnVzLmxhYmVsWzZdLCAiZGVmYXVsdC1ib2xkLXNtYWxsIikKCWd1aVNldEZvbnQoYnVzLmxhYmVsWzldLCAiZGVmYXVsdC1ib2xkLXNtYWxsIikKCQoJZ3VpTGFiZWxTZXRDb2xvcihidXMubGFiZWxbMV0sIDI0NSwgMjMyLCA5KQoJZ3VpTGFiZWxTZXRDb2xvcihidXMubGFiZWxbM10sIDI0NSwgMjMyLCA5KQoJZ3VpTGFiZWxTZXRDb2xvcihidXMubGFiZWxbNl0sIDI0NSwgMjMyLCA5KQoJZ3VpTGFiZWxTZXRDb2xvcihidXMubGFiZWxbOV0sIDI0NSwgMjMyLCA5KQoJCglndWlMYWJlbFNldFZlcnRpY2FsQWxpZ24oYnVzLmxhYmVsWzFdLCAiY2VudGVyIikKCWd1aUxhYmVsU2V0VmVydGljYWxBbGlnbihidXMubGFiZWxbM10sICJjZW50ZXIiKQoJZ3VpTGFiZWxTZXRWZXJ0aWNhbEFsaWduKGJ1cy5sYWJlbFs1XSwgImNlbnRlciIpCglndWlMYWJlbFNldFZlcnRpY2FsQWxpZ24oYnVzLmxhYmVsWzZdLCAiY2VudGVyIikKCWd1aUxhYmVsU2V0VmVydGljYWxBbGlnbihidXMubGFiZWxbOF0sICJjZW50ZXIiKQoJZ3VpTGFiZWxTZXRWZXJ0aWNhbEFsaWduKGJ1cy5sYWJlbFs5XSwgImNlbnRlciIpICAKCglndWlMYWJlbFNldEhvcml6b250YWxBbGlnbihidXMubGFiZWxbOF0sICJjZW50ZXIiLCBmYWxzZSkKCWd1aUxhYmVsU2V0SG9yaXpvbnRhbEFsaWduKGJ1cy5sYWJlbFsyXSwgImNlbnRlciIsIGZhbHNlKQoJZ3VpTGFiZWxTZXRIb3Jpem9udGFsQWxpZ24oYnVzLmxhYmVsWzVdLCAiY2VudGVyIiwgZmFsc2UpCgkKCWFkZEV2ZW50SGFuZGxlcigib25DbGllbnRHVUlDbGljayIsIGJ1cy5idXR0b25bMV0sIGZ1bmN0aW9uKCkgaWYoc291cmNlPT1idXMuYnV0dG9uWzFdKXRoZW4gZ3VpU2V0VmlzaWJsZShidXMud2luZG93WzFdLCBmYWxzZSkgb3V0cHV0Q2hhdEJveCgiWW91IGhhdmUgY2FuY2VsbGVkIHlvdXIgYXBwbGljYXRpb24sIGJldHRlciBsdWNrIG5leHQgdGltZSEiLCAyNTUsIDAsIDApIGRlY2xpbmVkW2xvY2FsUGxheWVyXSA9IGZhbHNlIHNldEVsZW1lbnRNb2RlbChsb2NhbFBsYXllciwgbW9kZWwpIHJlc2V0X2d1aV9kYXRhKCkgc2hvd0N1cnNvcihmYWxzZSllbmQgZW5kKQoJYWRkRXZlbnRIYW5kbGVyKCJvbkNsaWVudEdVSUNsaWNrIiwgYnVzLmJ1dHRvblszXSwgZnVuY3Rpb24oKSBpZihzb3VyY2U9PWJ1cy5idXR0b25bM10pdGhlbiBwcm9jZWVkX3RvX2FwcCgpIGVuZCBlbmQpCglhZGRFdmVudEhhbmRsZXIoIm9uQ2xpZW50R1VJQ2xpY2siLCBidXMuYnV0dG9uWzRdLCBmdW5jdGlvbigpIGlmKHNvdXJjZT09YnVzLmJ1dHRvbls0XSl0aGVuIHByb2NlZWRfdG9fc2tpbl9zZWxlY3Rpb24oKSBlbmQgZW5kKQoJYWRkRXZlbnRIYW5kbGVyKCJvbkNsaWVudEdVSUNsaWNrIiwgYnVzLmJ1dHRvbls1XSwgZnVuY3Rpb24oKSBpZihzb3VyY2U9PWJ1cy5idXR0b25bNV0pdGhlbiBwcm9jZWVkX3RvX2NvbmZpcm1hdGlvbigpIGVuZCBlbmQpCglhZGRFdmVudEhhbmRsZXIoIm9uQ2xpZW50R1VJQ2xpY2siLCBidXMuZ3JpZGxpc3RbMV0sIHZpZXdUaGVTa2luLCBmYWxzZSkKZW5kCmFkZEV2ZW50SGFuZGxlcigib25DbGllbnRSZXNvdXJjZVN0YXJ0Iiwgcm9vdCwgY3JlYXRlX2J1c193aW5kb3cpCgpmdW5jdGlvbiBwcm9jZWVkX3RvX3NraW5fc2VsZWN0aW9uKCkKCWxvY2FsIHNraW4gPSBnZXRFbGVtZW50TW9kZWwobG9jYWxQbGF5ZXIpCglpZiAoZGVjbGluZWRbbG9jYWxQbGF5ZXJdKSB0aGVuIG91dHB1dENoYXRCb3goIllvdSd2ZSBhbHJlYWR5IGJlZW4gZGVjbGluZWQsIGNvbWUgYmFjayBsYXRlciBwbGVhc2UhIiwgMjU1LCAwLCAwKSByZXR1cm4gZW5kCglmb3IgaW5kZXgsIHMgaW4gcGFpcnMoc2tpbnMpIGRvCgkJaWYgKHNraW4gfj0gcykgdGhlbgoJCQlpZiAoc2tpbiA9PSAwIG9yIHNraW4gPT0gbW9kZWwgYW5kIG5vdCBub1NraW4pIHRoZW4KCQkJCXNldEVsZW1lbnRNb2RlbChsb2NhbFBsYXllciwgbW9kZWwpCgkJCQlvdXRwdXRDaGF0Qm94KCJZb3UgbXVzdCBzZWxlY3QgYSBza2luIGZyb20gdGhlIGxpc3QhIiwgMjU1LCAwLCAwKQoJCQkJcmV0dXJuCgkJCWVuZAoJCWVuZAoJZW5kCglvdXRwdXRDaGF0Qm94KCJTa2luIHN1Y2Nlc3NmdWxseSBjaG9zZW4sIHBsZWFzZSBzZWxlY3QgJ1Byb2NlZWQnIHRvIGNvbnRpbnVlIHlvdXIgYXBwbGljYXRpb24uIiwgMCwgMjU1LCAwKQoJc2tpbl9zZWxlY3RlZFtsb2NhbFBsYXllcl0gPSB0cnVlCmVuZAoKZnVuY3Rpb24gcHJvY2VlZF90b19jb25maXJtYXRpb24oKQoJaWYgKG5vdCBza2luX3NlbGVjdGVkW2xvY2FsUGxheWVyXSkgdGhlbgoJCW91dHB1dENoYXRCb3goIllvdSBtdXN0IGNob29zZSBhIHNraW4gdG8gcHJvY2VlZCB0byBjb25maXJtYXRpb24hIiwgMjU1LCAwLCAwKQoJZWxzZWlmICggbGljZW5zZVtsb2NhbFBsYXllcl0pIHRoZW4KCQlvdXRwdXRDaGF0Qm94KCJZb3UgZG8gbm90IGhhdmUgYW4gZWxpZ2libGUgbGljZW5zZSBhdCB0aGUgbW9tZW50LCBjb21lIGJhY2sgd2hlbiB5b3UndmUgZ290IG9uZSEiLCAyNTUsIDAsIDApCgkJZ3VpU2V0VGV4dChidXMubGFiZWxbNV0sICJTdGF0dXM6IExpY2Vuc2UgdW5pZGVudGlmaWVkLCBhcHBsaWNhdGlvbiByZWplY3RlZC4iKQoJCWd1aUxhYmVsU2V0Q29sb3IoYnVzLmxhYmVsWzVdLCAyNTUsIDAsIDApCgkJc2V0VGltZXIoZnVuY3Rpb24oKSBndWlMYWJlbFNldENvbG9yKGJ1cy5sYWJlbFs4XSwgMjU1LCAwLCAwKSBlbmQsIDEwMDAsIDEpCgkJZGVjbGluZWRbbG9jYWxQbGF5ZXJdID0gdHJ1ZQoJZWxzZQoJCW91dHB1dENoYXRCb3goIlN0ZXAgMiBzdWNjZXNzLCBjb250aW51ZSB0byBzdGVwIDMgdG8gZmluaXNoIHlvdXIgYXBwbGljYXRpb24uIiwgMCwgMjU1LCAwKQoJCWd1aVNldFRleHQoYnVzLmxhYmVsWzVdLCAiU3RhdHVzOiBMaWNlbnNlIGFwcHJvdmVkLCBva2F5IHRvIHByb2NlZWQuIikKCQlndWlMYWJlbFNldENvbG9yKGJ1cy5sYWJlbFs1XSwgMCwgMjU1LCAwKQoJCXNldFRpbWVyKGZ1bmN0aW9uKCkgZ3VpTGFiZWxTZXRDb2xvcihidXMubGFiZWxbOF0sIDAsIDI1NSwgMCkgZW5kLCAxMDAwLCAxKQoJZW5kCmVuZAoKZnVuY3Rpb24gcmVzZXRfZ3VpX2RhdGEoKQoJZ3VpU2V0VGV4dChidXMubGFiZWxbNV0sICJTdGF0dXM6IFVuaWRlbnRpZmllZCIpCglndWlMYWJlbFNldENvbG9yKGJ1cy5sYWJlbFs1XSwgMjU1LCAyNTUsIDI1NSkKCWd1aUxhYmVsU2V0Q29sb3IoYnVzLmxhYmVsWzhdLCAyNTUsIDI1NSwgMjU1KQplbmQKCmZ1bmN0aW9uIGJ1c0FwcGxpY2F0aW9uSGFuZGxlKHN0cmluZykKCWlmIChzdHJpbmcgPT0gIm9wZW4iKSB0aGVuCgkJZ3VpU2V0VmlzaWJsZShidXMud2luZG93WzFdLCB0cnVlKQoJCXNob3dDdXJzb3Iobm90IGlzQ3Vyc29yU2hvd2luZygpLCB0cnVlKQoJCW1vZGVsID0gZ2V0RWxlbWVudE1vZGVsKGxvY2FsUGxheWVyKQoJCWd1aUdyaWRMaXN0Q2xlYXIoYnVzLmdyaWRsaXN0WzFdKQoJCWlmIChub3Qgc2tpbnMpIHRoZW4KCQkJZ3VpU2V0VmlzaWJsZShidXMuZ3JpZGxpc3RbMV0sIGZhbHNlKQoJCQlub1NraW4gPSB0cnVlCgkJCXJldHVybgoJCWVsc2UKCQkJZ3VpU2V0VmlzaWJsZShidXMuZ3JpZGxpc3RbMV0sIHRydWUpCgkJCW5vU2tpbiA9IG5pbAoJCWVuZAoJCWZvciBpbmRleCwgc2tpbiBpbiBwYWlycyhza2lucykgZG8KCQkJbG9jYWwgcm93ID0gZ3VpR3JpZExpc3RBZGRSb3coYnVzLmdyaWRsaXN0WzFdKQoJCQlndWlHcmlkTGlzdFNldEl0ZW1UZXh0KGJ1cy5ncmlkbGlzdFsxXSwgcm93LCBidXMuY29sdW1uWzFdLCBza2luWzFdLCBmYWxzZSwgdHJ1ZSkKCQkJZ3VpR3JpZExpc3RTZXRJdGVtVGV4dChidXMuZ3JpZGxpc3RbMV0sIHJvdywgYnVzLmNvbHVtblsyXSwgIkJ1cyBEcml2ZXIiLCBmYWxzZSwgdHJ1ZSkKCQkJZ3VpR3JpZExpc3RTZXRJdGVtVGV4dChidXMuZ3JpZGxpc3RbMV0sIHJvdywgYnVzLmNvbHVtblszXSwgc2tpblsyXSwgZmFsc2UsIHRydWUpCgkJZW5kCgllbHNlaWYgKHN0cmluZyA9PSAiY2xvc2UiKSB0aGVuCgkJaWYgKG5vdCBndWlHZXRWaXNpYmxlKGJ1cy53aW5kb3dbMV0pKSB0aGVuIHJldHVybiBlbmQKCQlyYW5rW2xvY2FsUGxheWVyXSA9IG5pbAoJCWd1aVNldFZpc2libGUoYnVzLndpbmRvd1sxXSwgZmFsc2UpCgkJc2hvd0N1cnNvcihmYWxzZSkKCWVuZAplbmQKYWRkRXZlbnQoIkRBV2FidXMuYnJpbmdfdXBfYXBwbGljYXRpb24iLCB0cnVlKQphZGRFdmVudEhhbmRsZXIoIkRBV2FidXMuYnJpbmdfdXBfYXBwbGljYXRpb24iLCByb290LCBidXNBcHBsaWNhdGlvbkhhbmRsZSkKCmZ1bmN0aW9uIHByb2NlZWRfdG9fYXBwKCkKCWlmIChkZWNsaW5lZFtsb2NhbFBsYXllcl0pIHRoZW4gcmV0dXJuIGVuZAoJbG9jYWwgc2tpbiA9IGdldEVsZW1lbnRNb2RlbChsb2NhbFBsYXllcikKCWZvciBpbmRleCwgcyBpbiBwYWlycyhza2lucykgZG8KCQlpZiAoc2tpbiB+PSBzKSB0aGVuCgkJCWlmIChza2luID09IDAgb3Igc2tpbiA9PSBtb2RlbCBhbmQgbm90IG5vU2tpbikgdGhlbgoJCQkJc2V0RWxlbWVudE1vZGVsKGxvY2FsUGxheWVyLCBtb2RlbCkKCQkJCW91dHB1dENoYXRCb3goIkFuIGVycm9yIGhhcyBvY2N1cnJlZCwgcGxlYXNlIHJlLWVudGVyIHRoZSBhcHBsaWNhdGlvbiBjZW50cmUuIiwgMjU1LCAwLCAwKQoJCQkJcmV0dXJuCgkJCWVuZAoJCWVuZAoJZW5kCglpZiAoZ2V0RWxlbWVudE1vZGVsKGxvY2FsUGxheWVyKSA9PSAyMTcpIHRoZW4KCQlyYW5rW2xvY2FsUGxheWVyXSA9ICJSb29raWUiCgllbHNlaWYgKGdldEVsZW1lbnRNb2RlbChsb2NhbFBsYXllcikgPT0gMjExKSB0aGVuCgkJcmFua1tsb2NhbFBsYXllcl0gPSAiU2VtaS1Qcm8iCgllbmQKCWd1aVNldFZpc2libGUoYnVzLndpbmRvd1sxXSwgZmFsc2UpCglyZXNldF9ndWlfZGF0YSgpCglzaG93Q3Vyc29yKGZhbHNlKQoJc2V0RWxlbWVudE1vZGVsKGxvY2FsUGxheWVyLCBtb2RlbCkKCWlmIChub1NraW4pIHRoZW4KCQlza2luID0gZmFsc2UKCWVuZAoJb3V0cHV0Q2hhdEJveCgiV2UndmUgYWNjZXB0ZWQgeW91IHRvIHRoZSB0ZWFtLCB5b3UgYXJlIG5vdyBlbXBsb3llZCBhcyBhIGJ1cyBkcml2ZXIgIi4udG9zdHJpbmcocmFua1tsb2NhbFBsYXllcl0pLCAwLCAyNTUsIDApCgl0cmlnZ2VyU2VydmVyRXZlbnQoIkRBV2FidXMuYWNjZXB0ZWRKb2IiLCByb290LCBsb2NhbFBsYXllciwgc2tpbikKCXJhbmtbbG9jYWxQbGF5ZXJdID0gbmlsCmVuZAoKZnVuY3Rpb24gdmlld1RoZVNraW4oKQoJaWYgKGd1aUdyaWRMaXN0R2V0U2VsZWN0ZWRJdGVtKGJ1cy5ncmlkbGlzdFsxXSkgPT0gLTEpIHRoZW4gcmV0dXJuIGVuZAoJbG9jYWwgcm93ID0gZ3VpR3JpZExpc3RHZXRTZWxlY3RlZEl0ZW0oc291cmNlKQoJbG9jYWwgc2tpbiA9IGd1aUdyaWRMaXN0R2V0SXRlbVRleHQoYnVzLmdyaWRsaXN0WzFdLCByb3csIGJ1cy5jb2x1bW5bMV0pCglzZXRFbGVtZW50TW9kZWwobG9jYWxQbGF5ZXIsIHNraW4gb3IgMCkKZW5kCgotLSBKb2IgQXBwbGljYXRpb24gRmluaXNoZWQKLS0gQmVuZWF0aCB3aWxsIGJlIHRoZSBhY3R1YWwgYnVzIGRyaXZpbmcgY29kZS4=