diff --git a/app/Database/migrations/2021_03_01_044305_add_aircraft_to_simbrief.php b/app/Database/migrations/2021_03_01_044305_add_aircraft_to_simbrief.php new file mode 100644 index 00000000..adbd532e --- /dev/null +++ b/app/Database/migrations/2021_03_01_044305_add_aircraft_to_simbrief.php @@ -0,0 +1,24 @@ +unsignedInteger('aircraft_id') + ->nullable() + ->after('pirep_id'); + + // Temp column to hold the calculated fare data for the API + // Remove this once the prefile to acars feature is completed + $table->mediumText('fare_data')->nullable()->after('ofp_xml'); + }); + } +} diff --git a/app/Database/seeds/dev/sample.yml b/app/Database/seeds/dev/sample.yml index 46a6e817..1a831aa4 100644 --- a/app/Database/seeds/dev/sample.yml +++ b/app/Database/seeds/dev/sample.yml @@ -119,8 +119,8 @@ aircraft: - id: 1 subfleet_id: 1 - icao: null - iata: null + icao: B744 + iata: 744 airport_id: KJFK landing_time: '2020-10-23 07:50:16' name: 'Boeing 747-438' @@ -136,8 +136,8 @@ aircraft: - id: 2 subfleet_id: 2 - icao: null - iata: null + icao: B777 + iata: 777 airport_id: LGRP landing_time: null name: 'Boeing 777-200' @@ -153,8 +153,8 @@ aircraft: - id: 3 subfleet_id: 1 - icao: null - iata: null + icao: B744 + iata: 744 airport_id: KAUS landing_time: '2020-10-24 08:50:13' name: 'Boeing 747-412' @@ -170,8 +170,8 @@ aircraft: - id: 4 subfleet_id: 1 - icao: null - iata: null + icao: B744 + iata: 744 airport_id: KAUS landing_time: null name: 'Boeing 747-436 RETIRED' @@ -187,7 +187,7 @@ aircraft: - id: 5 subfleet_id: 4 - icao: A320 + icao: 'A320' iata: '320' airport_id: EGLL landing_time: null diff --git a/app/Http/Controllers/Frontend/PirepController.php b/app/Http/Controllers/Frontend/PirepController.php index de3d9243..41f22e9c 100644 --- a/app/Http/Controllers/Frontend/PirepController.php +++ b/app/Http/Controllers/Frontend/PirepController.php @@ -8,6 +8,7 @@ use App\Http\Requests\UpdatePirepRequest; use App\Models\Enums\PirepSource; use App\Models\Enums\PirepState; use App\Models\Enums\PirepStatus; +use App\Models\Fare; use App\Models\Pirep; use App\Models\SimBrief; use App\Models\User; @@ -253,23 +254,48 @@ class PirepController extends Controller /** * They have a SimBrief ID, load that up and figure out the flight that it's from */ + $fare_values = []; + $simbrief = null; $simbrief_id = null; + $aircraft = null; if ($request->has('sb_id')) { $simbrief_id = $request->input('sb_id'); - $brief = SimBrief::find($simbrief_id); - $pirep = Pirep::fromSimBrief($brief); + $simbrief = SimBrief::find($simbrief_id); + $pirep = Pirep::fromSimBrief($simbrief); + + $aircraft = $simbrief->aircraft; + $aircraft_list[$aircraft->subfleet->name] = []; + $aircraft_list[$aircraft->subfleet->name][$aircraft->id] = $aircraft->name.' - '.$aircraft->registration; + + // Convert the fare data into the expected output format + if (!empty($simbrief->fare_data)) { + $fare_values = json_decode($simbrief->fare_data, true); + $fares = []; + $fare_data = json_decode($simbrief->fare_data, true); + foreach ($fare_data as $fare) { + $fares[] = new Fare($fare); + } + + $aircraft->subfleet->fares = collect($fares); + } + + // TODO: Set more fields from the Simbrief to the PIREP form + } else { + $aircraft_list = $this->aircraftList(true); } return view('pireps.create', [ - 'aircraft' => null, + 'aircraft' => $aircraft, 'pirep' => $pirep, 'read_only' => false, 'airline_list' => $this->airlineRepo->selectBoxList(true), - 'aircraft_list' => $this->aircraftList(true), + 'aircraft_list' => $aircraft_list, 'airport_list' => $this->airportRepo->selectBoxList(true), 'pirep_fields' => $this->pirepFieldRepo->all(), 'field_values' => [], + 'fare_values' => $fare_values, 'simbrief_id' => $simbrief_id, + 'simbrief' => $simbrief, ]); } diff --git a/app/Http/Controllers/Frontend/SimBriefController.php b/app/Http/Controllers/Frontend/SimBriefController.php index c7e93c4e..8d10d8ab 100644 --- a/app/Http/Controllers/Frontend/SimBriefController.php +++ b/app/Http/Controllers/Frontend/SimBriefController.php @@ -4,8 +4,12 @@ namespace App\Http\Controllers\Frontend; use App\Exceptions\AssetNotFound; use App\Models\Aircraft; +use App\Models\Enums\FareType; use App\Models\Enums\FlightType; +use App\Models\Fare; +use App\Models\Flight; use App\Models\SimBrief; +use App\Models\User; use App\Repositories\FlightRepository; use App\Services\FareService; use App\Services\SimBriefService; @@ -49,8 +53,9 @@ class SimBriefController $flight_id = $request->input('flight_id'); $aircraft_id = $request->input('aircraft_id'); - $flight = $this->flightRepo->with(['subfleets'])->find($flight_id); - // $flight = $this->fareSvc->getReconciledFaresForFlight($flight); + + /** @var Flight $flight */ + $flight = $this->flightRepo->with(['fares', 'subfleets'])->find($flight_id); if (!$flight) { flash()->error('Unknown flight'); @@ -63,15 +68,15 @@ class SimBriefController return redirect(route('frontend.flights.index')); } - // If no subfleets defined for flight get them from user - if ($flight->subfleets->count() > 0) { - $subfleets = $flight->subfleets; - } else { - $subfleets = $this->userSvc->getAllowableSubfleets($user); - } - // No aircraft selected, show selection form if (!$aircraft_id) { + // If no subfleets defined for flight get them from user + if ($flight->subfleets->count() > 0) { + $subfleets = $flight->subfleets; + } else { + $subfleets = $this->userSvc->getAllowableSubfleets($user); + } + return view('flights.simbrief_aircraft', [ 'flight' => $flight, 'subfleets' => $subfleets, @@ -90,8 +95,14 @@ class SimBriefController // SimBrief profile does not exists and everything else is ok // Select aircraft which will be used for calculations and details + /** @var Aircraft $aircraft */ $aircraft = Aircraft::where('id', $aircraft_id)->first(); + // Figure out the proper fares to use for this flight/aircraft + $all_fares = $this->fareSvc->getFareWithOverrides($aircraft->subfleet->fares, $flight->fares); + + // TODO: Reconcile the fares for this aircraft w/ proper for the flight/subfleet + // Get passenger and baggage weights with failsafe defaults if ($flight->flight_type === FlightType::CHARTER_PAX_ONLY) { $pax_weight = setting('simbrief.charter_pax_weight', 168); @@ -115,14 +126,86 @@ class SimBriefController $loadmax = 100; } + // Load fares for passengers + + $loaddist = []; // The load distribution string + + $pax_load_sheet = []; + $tpaxfig = 0; + + /** @var Fare $fare */ + foreach ($all_fares as $fare) { + if ($fare->type !== FareType::PASSENGER || empty($fare->capacity)) { + continue; + } + + $count = floor(($fare->capacity * rand($loadmin, $loadmax)) / 100); + $tpaxfig += $count; + $pax_load_sheet[] = [ + 'id' => $fare->id, + 'code' => $fare->code, + 'name' => $fare->name, + 'type' => $fare->type, + 'capacity' => (int) $fare->capacity, + 'count' => $count, + ]; + + $loaddist[] = $fare->code.' '.$count; + } + + // Calculate total weights + if (setting('units.weight') === 'kg') { + $tpaxload = round(($pax_weight * $tpaxfig) / 2.205); + $tbagload = round(($bag_weight * $tpaxfig) / 2.205); + } else { + $tpaxload = round($pax_weight * $tpaxfig); + $tbagload = round($bag_weight * $tpaxfig); + } + + // Load up fares for cargo + + $tcargoload = 0; + $cargo_load_sheet = []; + foreach ($all_fares as $fare) { + if ($fare->type !== FareType::CARGO || empty($fare->capacity)) { + continue; + } + + $count = ceil((($fare->capacity - $tbagload) * rand($loadmin, $loadmax)) / 100); + $tcargoload += $count; + $cargo_load_sheet[] = [ + 'id' => $fare->id, + 'code' => $fare->code, + 'name' => $fare->name, + 'type' => $fare->type, + 'capacity' => $fare->capacity, + 'count' => $count, + ]; + + $loaddist[] = $fare->code.' '.$count; + } + + $tpayload = $tpaxload + $tbagload + $tcargoload; + + $request->session()->put('simbrief_fares', array_merge($pax_load_sheet, $cargo_load_sheet)); + // Show the main simbrief form return view('flights.simbrief_form', [ - 'flight' => $flight, - 'aircraft' => $aircraft, - 'pax_weight' => $pax_weight, - 'bag_weight' => $bag_weight, - 'loadmin' => $loadmin, - 'loadmax' => $loadmax, + 'user' => Auth::user(), + 'flight' => $flight, + 'aircraft' => $aircraft, + 'pax_weight' => $pax_weight, + 'bag_weight' => $bag_weight, + 'loadmin' => $loadmin, + 'loadmax' => $loadmax, + 'pax_load_sheet' => $pax_load_sheet, + 'cargo_load_sheet' => $cargo_load_sheet, + 'tpaxfig' => $tpaxfig, + 'tpaxload' => $tpaxload, + 'tbagload' => $tbagload, + 'tpayload' => $tpayload, + 'tcargoload' => $tcargoload, + 'loaddist' => implode(' ', $loaddist), ]); } @@ -227,6 +310,7 @@ class SimBriefController /** * Check whether the OFP was generated. Pass in two items, the flight_id and ofp_id + * This does the actual "attachment" of the Simbrief to the flight * * @param \Illuminate\Http\Request $request * @@ -234,10 +318,14 @@ class SimBriefController */ public function check_ofp(Request $request) { + /** @var User $user */ + $user = Auth::user(); $ofp_id = $request->input('ofp_id'); $flight_id = $request->input('flight_id'); + $aircraft_id = $request->input('aircraft_id'); + $fares = $request->session()->get('simbrief_fares', []); - $simbrief = $this->simBriefSvc->downloadOfp(Auth::user()->id, $ofp_id, $flight_id); + $simbrief = $this->simBriefSvc->downloadOfp($user->id, $ofp_id, $flight_id, $aircraft_id, $fares); if ($simbrief === null) { $error = new AssetNotFound(new Exception('Simbrief OFP not found')); return $error->getResponse(); diff --git a/app/Http/Resources/Fare.php b/app/Http/Resources/Fare.php index e89a5ab9..3db2387a 100644 --- a/app/Http/Resources/Fare.php +++ b/app/Http/Resources/Fare.php @@ -17,6 +17,7 @@ class Fare extends Resource 'name' => $this->name, 'capacity' => $this->capacity, 'cost' => $this->cost, + 'count' => $this->count ?? 0, 'price' => $this->price, 'type' => $this->type, 'notes' => $this->notes, diff --git a/app/Http/Resources/SimBrief.php b/app/Http/Resources/SimBrief.php index 340041f7..7ba53d26 100644 --- a/app/Http/Resources/SimBrief.php +++ b/app/Http/Resources/SimBrief.php @@ -11,9 +11,27 @@ class SimBrief extends Resource { public function toArray($request) { - return [ + $data = [ 'id' => $this->id, 'url' => url(route('api.flights.briefing', ['id' => $this->id])), ]; + + try { + if (!empty($this->fare_data)) { + $fares = []; + $fare_data = json_decode($this->fare_data, true); + foreach ($fare_data as $fare) { + $fares[] = new \App\Models\Fare($fare); + } + + $this->aircraft->subfleet->fares = collect($fares); + } + } catch (\Exception $e) { + // Invalid fare data + } + + $data['subfleet'] = new Subfleet($this->aircraft->subfleet); + + return $data; } } diff --git a/app/Http/Resources/User.php b/app/Http/Resources/User.php index 3ef2fb8f..24af27f1 100644 --- a/app/Http/Resources/User.php +++ b/app/Http/Resources/User.php @@ -15,9 +15,8 @@ class User extends Resource 'id' => $this->id, 'pilot_id' => $this->pilot_id, 'ident' => $this->ident, - 'name' => $this->name, + 'name' => $this->name_private, 'name_private' => $this->name_private, - 'email' => $this->email, 'avatar' => $this->resolveAvatarUrl(), 'rank_id' => $this->rank_id, 'home_airport' => $this->home_airport_id, diff --git a/app/Models/Fare.php b/app/Models/Fare.php index aba31ec3..f8800255 100644 --- a/app/Models/Fare.php +++ b/app/Models/Fare.php @@ -20,12 +20,14 @@ class Fare extends Model public $table = 'fares'; protected $fillable = [ + 'id', 'code', 'name', 'type', 'price', 'cost', 'capacity', + 'count', 'notes', 'active', ]; @@ -34,6 +36,7 @@ class Fare extends Model 'price' => 'float', 'cost' => 'float', 'capacity' => 'integer', + 'count' => 'integer', 'type' => 'integer', 'active' => 'boolean', ]; diff --git a/app/Models/Pirep.php b/app/Models/Pirep.php index ac5a6722..aa940ec5 100644 --- a/app/Models/Pirep.php +++ b/app/Models/Pirep.php @@ -305,7 +305,9 @@ class Pirep extends Model public function getFieldsAttribute() { $custom_fields = PirepField::all(); - $field_values = PirepFieldValue::where('pirep_id', $this->id)->get(); + $field_values = PirepFieldValue::where('pirep_id', $this->id) + ->orderBy('created_at', 'asc') + ->get(); // Merge the field values into $fields foreach ($custom_fields as $field) { @@ -321,7 +323,7 @@ class Pirep extends Model } } - return $field_values->sortBy('source'); + return $field_values; } /** diff --git a/app/Models/SimBrief.php b/app/Models/SimBrief.php index 1dcb1b63..56c7b5a5 100644 --- a/app/Models/SimBrief.php +++ b/app/Models/SimBrief.php @@ -13,11 +13,13 @@ use Illuminate\Support\Collection; * @property string $acars_xml * @property string $ofp_xml * @property string $ofp_html + * @property string $fare_data JSON string of the fare data that was generated * @property Collection $images * @property Collection $files * @property Flight $flight * @property User $user * @property SimBriefXML $xml + * @property Aircraft $aircraft * @property string $acars_flightplan_url */ class SimBrief extends Model @@ -29,9 +31,11 @@ class SimBrief extends Model 'id', 'user_id', 'flight_id', + 'aircraft_id', 'pirep_id', 'acars_xml', 'ofp_xml', + 'fare_data', 'created_at', 'updated_at', ]; @@ -80,6 +84,11 @@ class SimBrief extends Model * Relationships */ + public function aircraft() + { + return $this->belongsTo(Aircraft::class, 'aircraft_id'); + } + public function flight() { if (!empty($this->attributes['flight_id'])) { diff --git a/app/Services/BidService.php b/app/Services/BidService.php index acd88e51..738c7b75 100644 --- a/app/Services/BidService.php +++ b/app/Services/BidService.php @@ -51,6 +51,7 @@ class BidService extends Service 'flight', 'flight.fares', 'flight.simbrief', + 'flight.simbrief.aircraft', 'flight.subfleets', 'flight.subfleets.aircraft', 'flight.subfleets.fares', diff --git a/app/Services/FareService.php b/app/Services/FareService.php index 6be9d3ec..6f55e0ff 100644 --- a/app/Services/FareService.php +++ b/app/Services/FareService.php @@ -172,6 +172,24 @@ class FareService extends Service return $fare; } + /** + * Return all the fares for an aircraft. check the pivot + * table to see if the price/cost/capacity has been overridden + * and return the correct amounts. + * + * @param Subfleet $subfleet + * + * @return Collection + */ + public function getForSubfleet(Subfleet $subfleet) + { + $fares = $subfleet->fares->map(function ($fare) { + return $this->getFares($fare); + }); + + return $fares; + } + /** * Attach a fare to an flight * @@ -240,24 +258,6 @@ class FareService extends Service return $subfleet; } - /** - * return all the fares for an aircraft. check the pivot - * table to see if the price/cost/capacity has been overridden - * and return the correct amounts. - * - * @param Subfleet $subfleet - * - * @return Collection - */ - public function getForSubfleet(Subfleet $subfleet) - { - $fares = $subfleet->fares->map(function ($fare) { - return $this->getFares($fare); - }); - - return $fares; - } - /** * Delete the fare from a subfleet * diff --git a/app/Services/SimBriefService.php b/app/Services/SimBriefService.php index 9dc46f06..1d090533 100644 --- a/app/Services/SimBriefService.php +++ b/app/Services/SimBriefService.php @@ -29,11 +29,18 @@ class SimBriefService extends Service * @param string $user_id User who generated this * @param string $ofp_id The SimBrief OFP ID * @param string $flight_id The flight ID + * @param string $ac_id The aircraft ID + * @param array $fares Full list of fares for the flightß * * @return SimBrief|null */ - public function downloadOfp(string $user_id, string $ofp_id, string $flight_id) - { + public function downloadOfp( + string $user_id, + string $ofp_id, + string $flight_id, + string $ac_id, + array $fares = [] + ) { $uri = str_replace('{id}', $ofp_id, config('phpvms.simbrief_url')); $opts = [ @@ -57,11 +64,17 @@ class SimBriefService extends Service $ofp = simplexml_load_string($body, SimBriefXML::class); $attrs = [ - 'user_id' => $user_id, - 'flight_id' => $flight_id, - 'ofp_xml' => $ofp->asXML(), + 'user_id' => $user_id, + 'flight_id' => $flight_id, + 'aircraft_id' => $ac_id, + 'ofp_xml' => $ofp->asXML(), ]; + // encode the fares data to JSONß + if (!empty($fares)) { + $attrs['fare_data'] = json_encode($fares); + } + // Try to download the XML file for ACARS. If it doesn't work, try to modify the main OFP $acars_xml = $this->getAcarsOFP($ofp); if (empty($acars_xml)) { diff --git a/public/assets/global/js/simbrief.apiv1.js b/public/assets/global/js/simbrief.apiv1.js index 5953b750..3c038e37 100755 --- a/public/assets/global/js/simbrief.apiv1.js +++ b/public/assets/global/js/simbrief.apiv1.js @@ -1,622 +1,629 @@ -'use strict'; -/* -* SimBrief APIv1 Javascript Functions -* For use with VA Dispatch systems -* By Derek Mayer - contact@simbrief.com -* -* Any individual wishing to make use of this class must first contact me -* to obtain a unique API key; without which it will be impossible to connect -* to the API. -* -* Any attempt to circumvent the API authorization, steal another -* developer's API key, hack, compromise, or gain unauthorized access to -* the SimBrief website or it's web systems, or bypass or allow others to bypass -* the SimBrief.com login screen will result in immediate revocation of the -* associated API key, and in serious situations, legal action at my discretion. -*/ - -/* -* Settings and initial variables -*/ - -let sbform = "sbapiform"; -let sbworkerurl = "https://www.simbrief.com/ofp/ofp.loader.api.php"; -let sbworkerid = 'SBworker'; -let sbcallerid = 'SBcaller'; -let sbworkerstyle = 'width=600,height=315'; -let sbworker; -let SBloop; - -let ofp_id; -let flight_id; - -let outputpage_save; -let outputpage_calc; -let fe_result; - -let timestamp; -let api_code; - - -function simbriefsubmit(_flight_id, outputpage) { - flight_id = _flight_id; - - if (sbworker) { - sbworker.close(); - } - - if (SBloop) { - window.clearInterval(SBloop); - } - - api_code = null; - ofp_id = null; - fe_result = null; - timestamp = null; - outputpage_save = null; - outputpage_calc = null; - - do_simbriefsubmit(outputpage); -} - - -async function do_simbriefsubmit(outputpage) { - - //CATCH UNDEFINED OUTPUT PAGE, SET IT TO THE CURRENT PAGE - - if (!outputpage) { - outputpage = location.href; - } - - if (!timestamp) { - timestamp = Math.round(+new Date() / 1000); - } - - outputpage_save = outputpage; - outputpage_calc = outputpage.replace("http://", ""); - - if (!api_code) { - const api_req = document.getElementsByName('orig')[0].value + document.getElementsByName('dest')[0].value + document.getElementsByName('type')[0].value + timestamp + outputpage_calc; - - let apiCodeResp; - - try { - apiCodeResp = await phpvms.request({ - method: 'POST', - url: '/simbrief/apicode', - data: { - api_req, - flight_id, - } - }); - } catch (e) { - console.log('request error', e); - return; - } - - api_code = apiCodeResp.data.api_code; - console.log('API code response: ', api_code); - } - - //IF API_CODE IS SET, FINALIZE FORM - - var apiform = document.getElementById(sbform); - apiform.setAttribute("method", "get"); - apiform.setAttribute("action", sbworkerurl); - apiform.setAttribute("target", sbworkerid); - - var input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", "apicode"); - input.setAttribute("value", api_code); - apiform.appendChild(input); - - - var input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", "outputpage"); - input.setAttribute("value", outputpage_calc); - apiform.appendChild(input); - - - var input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", "timestamp"); - input.setAttribute("value", timestamp); - apiform.appendChild(input); - - - //LAUNCH FORM - - window.name = sbcallerid; - LaunchSBworker(); - apiform.submit(); - - //DETERMINE OFP_ID - - ofp_id = timestamp + '_' + md5(document.getElementsByName('orig')[0].value + document.getElementsByName('dest')[0].value + document.getElementsByName('type')[0].value); - - //LOOP TO DETECT WHEN THE WORKER PROCESS IS CLOSED - SBloop = window.setInterval(checkSBworker, 500); -} - -/* -* Other related functions -*/ - -function LaunchSBworker() { - sbworker = window.open('about:blank', sbworkerid, sbworkerstyle) - - //TEST FOR POPUP BLOCKERS - - if (sbworker == null || typeof (sbworker) == 'undefined') { - alert('Please disable your pop-up blocker to generate a flight plan!'); - } else { - if (window.focus) { - sbworker.focus(); - } - } -} - - -function checkSBworker() { - if (sbworker && sbworker.closed) { - window.clearInterval(SBloop); - Redirect_caller(); - } -} - - -async function Redirect_caller() { - - /* - * First check that the file actually exists. - * It might not if the window was closed before completion. - * - * An external PHP file is used so as to avoid any "Same - * Origin" errors. - */ - - let apiCodeResp; - - try { - apiCodeResp = await phpvms.request({ - method: 'GET', - url: '/simbrief/check_ofp', - params: { - flight_id, - ofp_id, - } - }); - } catch (e) { - console.log('request error', e); - setTimeout(function () { - Redirect_caller(); - }, 500); - - return; - } - - api_code = apiCodeResp.data.id; - console.log('API code response: ', api_code); - - /* - * If the file exists, redirect to the specified Output Page. - */ - outputpage_save += '/' + ofp_id; - - let apiform = document.createElement("form"); - apiform.setAttribute("method", "get"); - apiform.setAttribute("action", outputpage_save); - - /* - * Analyse link to see if there are any prior GET params. - * If so, append them to the form - */ - - let urlinfo = urlObject({'url': outputpage_save}); - for (let key in urlinfo['parameters']) { - let input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", key); - input.setAttribute("value", urlinfo['parameters'][key]); - apiform.appendChild(input); - } - - let input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", "ofp_id"); - input.setAttribute("value", ofp_id); - apiform.appendChild(input); - - document.body.appendChild(apiform); - - apiform.submit(); -} - - -function sb_res_load(url) { - var fileref = document.createElement('script'); - fileref.type = "text/javascript"; - fileref.src = url + "&p=" + Math.floor(Math.random() * 10000000); - document.getElementsByTagName("head")[0].appendChild(fileref); -} - - -/* -* URLOBJECT function -* Courtesy Ayman Farhat -*/ - -function urlObject(options) { - "use strict"; - /*global window, document*/ - - var url_search_arr, - option_key, - i, - urlObj, - get_param, - key, - val, - url_query, - url_get_params = {}, - a = document.createElement('a'), - default_options = { - 'url': window.location.href, - 'unescape': true, - 'convert_num': true - }; - - if (typeof options !== "object") { - options = default_options; - } else { - for (option_key in default_options) { - if (default_options.hasOwnProperty(option_key)) { - if (options[option_key] === undefined) { - options[option_key] = default_options[option_key]; - } - } - } - } - - a.href = options.url; - url_query = a.search.substring(1); - url_search_arr = url_query.split('&'); - - if (url_search_arr[0].length > 1) { - for (i = 0; i < url_search_arr.length; i += 1) { - get_param = url_search_arr[i].split("="); - - if (options.unescape) { - key = decodeURI(get_param[0]); - val = decodeURI(get_param[1]); - } else { - key = get_param[0]; - val = get_param[1]; - } - - if (options.convert_num) { - if (val.match(/^\d+$/)) { - val = parseInt(val, 10); - } else if (val.match(/^\d+\.\d+$/)) { - val = parseFloat(val); - } - } - - if (url_get_params[key] === undefined) { - url_get_params[key] = val; - } else if (typeof url_get_params[key] === "string") { - url_get_params[key] = [url_get_params[key], val]; - } else { - url_get_params[key].push(val); - } - - get_param = []; - } - } - - urlObj = { - protocol: a.protocol, - hostname: a.hostname, - host: a.host, - port: a.port, - hash: a.hash.substr(1), - pathname: a.pathname, - search: a.search, - parameters: url_get_params - }; - - return urlObj; -} - - -/* -* MD5 and UTF8_ENCODE functions -* Courtesy of phpjs.org -*/ - -function md5(str) { - // discuss at: http://phpjs.org/functions/md5/ - // original by: Webtoolkit.info (http://www.webtoolkit.info/) - // improved by: Michael White (http://getsprink.com) - // improved by: Jack - // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // input by: Brett Zamir (http://brett-zamir.me) - // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // depends on: utf8_encode - // example 1: md5('Kevin van Zonneveld'); - // returns 1: '6e658d4bfcb59cc13f96c14450ac40b9' - - var xl; - - var rotateLeft = function (lValue, iShiftBits) { - return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); - }; - - var addUnsigned = function (lX, lY) { - var lX4, lY4, lX8, lY8, lResult; - lX8 = (lX & 0x80000000); - lY8 = (lY & 0x80000000); - lX4 = (lX & 0x40000000); - lY4 = (lY & 0x40000000); - lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); - if (lX4 & lY4) { - return (lResult ^ 0x80000000 ^ lX8 ^ lY8); - } - if (lX4 | lY4) { - if (lResult & 0x40000000) { - return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); - } else { - return (lResult ^ 0x40000000 ^ lX8 ^ lY8); - } - } else { - return (lResult ^ lX8 ^ lY8); - } - }; - - var _F = function (x, y, z) { - return (x & y) | ((~x) & z); - }; - var _G = function (x, y, z) { - return (x & z) | (y & (~z)); - }; - var _H = function (x, y, z) { - return (x ^ y ^ z); - }; - var _I = function (x, y, z) { - return (y ^ (x | (~z))); - }; - - var _FF = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var _GG = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var _HH = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var _II = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var convertToWordArray = function (str) { - var lWordCount; - var lMessageLength = str.length; - var lNumberOfWords_temp1 = lMessageLength + 8; - var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; - var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; - var lWordArray = new Array(lNumberOfWords - 1); - var lBytePosition = 0; - var lByteCount = 0; - while (lByteCount < lMessageLength) { - lWordCount = (lByteCount - (lByteCount % 4)) / 4; - lBytePosition = (lByteCount % 4) * 8; - lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition)); - lByteCount++; - } - lWordCount = (lByteCount - (lByteCount % 4)) / 4; - lBytePosition = (lByteCount % 4) * 8; - lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); - lWordArray[lNumberOfWords - 2] = lMessageLength << 3; - lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; - return lWordArray; - }; - - var wordToHex = function (lValue) { - var wordToHexValue = '', - wordToHexValue_temp = '', - lByte, lCount; - for (lCount = 0; lCount <= 3; lCount++) { - lByte = (lValue >>> (lCount * 8)) & 255; - wordToHexValue_temp = '0' + lByte.toString(16); - wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2); - } - return wordToHexValue; - }; - - var x = [], - k, AA, BB, CC, DD, a, b, c, d, S11 = 7, - S12 = 12, - S13 = 17, - S14 = 22, - S21 = 5, - S22 = 9, - S23 = 14, - S24 = 20, - S31 = 4, - S32 = 11, - S33 = 16, - S34 = 23, - S41 = 6, - S42 = 10, - S43 = 15, - S44 = 21; - - str = utf8_encode(str); - x = convertToWordArray(str); - a = 0x67452301; - b = 0xEFCDAB89; - c = 0x98BADCFE; - d = 0x10325476; - - xl = x.length; - for (k = 0; k < xl; k += 16) { - AA = a; - BB = b; - CC = c; - DD = d; - a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); - d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); - c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB); - b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); - a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); - d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); - c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613); - b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501); - a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8); - d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); - c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); - b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); - a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122); - d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193); - c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E); - b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821); - a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); - d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340); - c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); - b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); - a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); - d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453); - c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); - b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); - a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); - d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); - c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); - b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); - a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); - d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); - c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); - b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); - a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); - d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681); - c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); - b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); - a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); - d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); - c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); - b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); - a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); - d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); - c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); - b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05); - a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); - d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); - c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); - b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); - a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244); - d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97); - c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); - b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039); - a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3); - d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); - c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); - b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1); - a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); - d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); - c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314); - b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); - a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82); - d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); - c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); - b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391); - a = addUnsigned(a, AA); - b = addUnsigned(b, BB); - c = addUnsigned(c, CC); - d = addUnsigned(d, DD); - } - - var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); - - return temp.toUpperCase().substr(0, 10); -} - - -function utf8_encode(argString) { - // discuss at: http://phpjs.org/functions/utf8_encode/ - // original by: Webtoolkit.info (http://www.webtoolkit.info/) - // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // improved by: sowberry - // improved by: Jack - // improved by: Yves Sucaet - // improved by: kirilloid - // bugfixed by: Onno Marsman - // bugfixed by: Onno Marsman - // bugfixed by: Ulrich - // bugfixed by: Rafal Kukawski - // bugfixed by: kirilloid - // example 1: utf8_encode('Kevin van Zonneveld'); - // returns 1: 'Kevin van Zonneveld' - - if (argString === null || typeof argString === 'undefined') { - return ''; - } - - // .replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - var string = (argString + ''); - var utftext = '', - start, end, stringl = 0; - - start = end = 0; - stringl = string.length; - for (var n = 0; n < stringl; n++) { - var c1 = string.charCodeAt(n); - var enc = null; - - if (c1 < 128) { - end++; - } else if (c1 > 127 && c1 < 2048) { - enc = String.fromCharCode( - (c1 >> 6) | 192, (c1 & 63) | 128 - ); - } else if ((c1 & 0xF800) != 0xD800) { - enc = String.fromCharCode( - (c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128 - ); - } else { - // surrogate pairs - if ((c1 & 0xFC00) != 0xD800) { - throw new RangeError('Unmatched trail surrogate at ' + n); - } - var c2 = string.charCodeAt(++n); - if ((c2 & 0xFC00) != 0xDC00) { - throw new RangeError('Unmatched lead surrogate at ' + (n - 1)); - } - c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000; - enc = String.fromCharCode( - (c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128 - ); - } - if (enc !== null) { - if (end > start) { - utftext += string.slice(start, end); - } - utftext += enc; - start = end = n + 1; - } - } - - if (end > start) { - utftext += string.slice(start, stringl); - } - - return utftext; -} +'use strict'; +/* +* SimBrief APIv1 Javascript Functions +* For use with VA Dispatch systems +* By Derek Mayer - contact@simbrief.com +* +* Any individual wishing to make use of this class must first contact me +* to obtain a unique API key; without which it will be impossible to connect +* to the API. +* +* Any attempt to circumvent the API authorization, steal another +* developer's API key, hack, compromise, or gain unauthorized access to +* the SimBrief website or it's web systems, or bypass or allow others to bypass +* the SimBrief.com login screen will result in immediate revocation of the +* associated API key, and in serious situations, legal action at my discretion. +*/ + +/* +* Settings and initial variables +*/ + +let sbform = "sbapiform"; +let sbworkerurl = "https://www.simbrief.com/ofp/ofp.loader.api.php"; +let sbworkerid = 'SBworker'; +let sbcallerid = 'SBcaller'; +let sbworkerstyle = 'width=600,height=315'; +let sbworker; +let SBloop; + +let ofp_id; +let flight_id; +let aircraft_id; + +let outputpage_save; +let outputpage_calc; +let fe_result; + +let timestamp; +let api_code; + + +function simbriefsubmit(_flight_id, _aircraft_id, outputpage) { + flight_id = _flight_id; + aircraft_id = _aircraft_id; + + if (sbworker) { + sbworker.close(); + } + + if (SBloop) { + window.clearInterval(SBloop); + } + + api_code = null; + ofp_id = null; + fe_result = null; + timestamp = null; + outputpage_save = null; + outputpage_calc = null; + + console.log('Flight ID', _flight_id); + console.log('Aircraft ID', _aircraft_id); + console.log('Output Page', outputpage); + + do_simbriefsubmit(outputpage); +} + + +async function do_simbriefsubmit(outputpage) { + + //CATCH UNDEFINED OUTPUT PAGE, SET IT TO THE CURRENT PAGE + + if (!outputpage) { + outputpage = location.href; + } + + if (!timestamp) { + timestamp = Math.round(+new Date() / 1000); + } + + outputpage_save = outputpage; + outputpage_calc = outputpage.replace("http://", ""); + + if (!api_code) { + const api_req = document.getElementsByName('orig')[0].value + document.getElementsByName('dest')[0].value + document.getElementsByName('type')[0].value + timestamp + outputpage_calc; + + let apiCodeResp; + + try { + apiCodeResp = await phpvms.request({ + method: 'POST', + url: '/simbrief/apicode', + data: { + api_req, + flight_id, + aircraft_id, + } + }); + } catch (e) { + console.log('request error', e); + return; + } + + api_code = apiCodeResp.data.api_code; + console.log('API code response: ', api_code); + } + + //IF API_CODE IS SET, FINALIZE FORM + + var apiform = document.getElementById(sbform); + apiform.setAttribute("method", "get"); + apiform.setAttribute("action", sbworkerurl); + apiform.setAttribute("target", sbworkerid); + + var input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "apicode"); + input.setAttribute("value", api_code); + apiform.appendChild(input); + + var input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "outputpage"); + input.setAttribute("value", outputpage_calc); + apiform.appendChild(input); + + + var input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "timestamp"); + input.setAttribute("value", timestamp); + apiform.appendChild(input); + + + //LAUNCH FORM + + window.name = sbcallerid; + LaunchSBworker(); + apiform.submit(); + + //DETERMINE OFP_ID + + ofp_id = timestamp + '_' + md5(document.getElementsByName('orig')[0].value + document.getElementsByName('dest')[0].value + document.getElementsByName('type')[0].value); + + //LOOP TO DETECT WHEN THE WORKER PROCESS IS CLOSED + SBloop = window.setInterval(checkSBworker, 500); +} + +/* +* Other related functions +*/ + +function LaunchSBworker() { + sbworker = window.open('about:blank', sbworkerid, sbworkerstyle) + + //TEST FOR POPUP BLOCKERS + + if (sbworker == null || typeof (sbworker) == 'undefined') { + alert('Please disable your pop-up blocker to generate a flight plan!'); + } else { + if (window.focus) { + sbworker.focus(); + } + } +} + + +function checkSBworker() { + if (sbworker && sbworker.closed) { + window.clearInterval(SBloop); + Redirect_caller(); + } +} + + +async function Redirect_caller() { + + /* + * First check that the file actually exists. + * It might not if the window was closed before completion. + * + * An external PHP file is used so as to avoid any "Same + * Origin" errors. + */ + + let apiCodeResp; + + try { + apiCodeResp = await phpvms.request({ + method: 'GET', + url: '/simbrief/check_ofp', + params: { + aircraft_id, + flight_id, + ofp_id, + } + }); + } catch (e) { + console.log('request error', e); + setTimeout(function () { + Redirect_caller(); + }, 500); + + return; + } + + api_code = apiCodeResp.data.id; + console.log('API code response: ', api_code); + + /* + * If the file exists, redirect to the specified Output Page. + */ + outputpage_save += '/' + ofp_id; + + let apiform = document.createElement("form"); + apiform.setAttribute("method", "get"); + apiform.setAttribute("action", outputpage_save); + + /* + * Analyse link to see if there are any prior GET params. + * If so, append them to the form + */ + + let urlinfo = urlObject({'url': outputpage_save}); + for (let key in urlinfo['parameters']) { + let input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", key); + input.setAttribute("value", urlinfo['parameters'][key]); + apiform.appendChild(input); + } + + let input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "ofp_id"); + input.setAttribute("value", ofp_id); + apiform.appendChild(input); + + document.body.appendChild(apiform); + + apiform.submit(); +} + + +function sb_res_load(url) { + var fileref = document.createElement('script'); + fileref.type = "text/javascript"; + fileref.src = url + "&p=" + Math.floor(Math.random() * 10000000); + document.getElementsByTagName("head")[0].appendChild(fileref); +} + + +/* +* URLOBJECT function +* Courtesy Ayman Farhat +*/ + +function urlObject(options) { + "use strict"; + /*global window, document*/ + + var url_search_arr, + option_key, + i, + urlObj, + get_param, + key, + val, + url_query, + url_get_params = {}, + a = document.createElement('a'), + default_options = { + 'url': window.location.href, + 'unescape': true, + 'convert_num': true + }; + + if (typeof options !== "object") { + options = default_options; + } else { + for (option_key in default_options) { + if (default_options.hasOwnProperty(option_key)) { + if (options[option_key] === undefined) { + options[option_key] = default_options[option_key]; + } + } + } + } + + a.href = options.url; + url_query = a.search.substring(1); + url_search_arr = url_query.split('&'); + + if (url_search_arr[0].length > 1) { + for (i = 0; i < url_search_arr.length; i += 1) { + get_param = url_search_arr[i].split("="); + + if (options.unescape) { + key = decodeURI(get_param[0]); + val = decodeURI(get_param[1]); + } else { + key = get_param[0]; + val = get_param[1]; + } + + if (options.convert_num) { + if (val.match(/^\d+$/)) { + val = parseInt(val, 10); + } else if (val.match(/^\d+\.\d+$/)) { + val = parseFloat(val); + } + } + + if (url_get_params[key] === undefined) { + url_get_params[key] = val; + } else if (typeof url_get_params[key] === "string") { + url_get_params[key] = [url_get_params[key], val]; + } else { + url_get_params[key].push(val); + } + + get_param = []; + } + } + + urlObj = { + protocol: a.protocol, + hostname: a.hostname, + host: a.host, + port: a.port, + hash: a.hash.substr(1), + pathname: a.pathname, + search: a.search, + parameters: url_get_params + }; + + return urlObj; +} + + +/* +* MD5 and UTF8_ENCODE functions +* Courtesy of phpjs.org +*/ + +function md5(str) { + // discuss at: http://phpjs.org/functions/md5/ + // original by: Webtoolkit.info (http://www.webtoolkit.info/) + // improved by: Michael White (http://getsprink.com) + // improved by: Jack + // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // input by: Brett Zamir (http://brett-zamir.me) + // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // depends on: utf8_encode + // example 1: md5('Kevin van Zonneveld'); + // returns 1: '6e658d4bfcb59cc13f96c14450ac40b9' + + var xl; + + var rotateLeft = function (lValue, iShiftBits) { + return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); + }; + + var addUnsigned = function (lX, lY) { + var lX4, lY4, lX8, lY8, lResult; + lX8 = (lX & 0x80000000); + lY8 = (lY & 0x80000000); + lX4 = (lX & 0x40000000); + lY4 = (lY & 0x40000000); + lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); + if (lX4 & lY4) { + return (lResult ^ 0x80000000 ^ lX8 ^ lY8); + } + if (lX4 | lY4) { + if (lResult & 0x40000000) { + return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); + } else { + return (lResult ^ 0x40000000 ^ lX8 ^ lY8); + } + } else { + return (lResult ^ lX8 ^ lY8); + } + }; + + var _F = function (x, y, z) { + return (x & y) | ((~x) & z); + }; + var _G = function (x, y, z) { + return (x & z) | (y & (~z)); + }; + var _H = function (x, y, z) { + return (x ^ y ^ z); + }; + var _I = function (x, y, z) { + return (y ^ (x | (~z))); + }; + + var _FF = function (a, b, c, d, x, s, ac) { + a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac)); + return addUnsigned(rotateLeft(a, s), b); + }; + + var _GG = function (a, b, c, d, x, s, ac) { + a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac)); + return addUnsigned(rotateLeft(a, s), b); + }; + + var _HH = function (a, b, c, d, x, s, ac) { + a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac)); + return addUnsigned(rotateLeft(a, s), b); + }; + + var _II = function (a, b, c, d, x, s, ac) { + a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac)); + return addUnsigned(rotateLeft(a, s), b); + }; + + var convertToWordArray = function (str) { + var lWordCount; + var lMessageLength = str.length; + var lNumberOfWords_temp1 = lMessageLength + 8; + var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; + var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; + var lWordArray = new Array(lNumberOfWords - 1); + var lBytePosition = 0; + var lByteCount = 0; + while (lByteCount < lMessageLength) { + lWordCount = (lByteCount - (lByteCount % 4)) / 4; + lBytePosition = (lByteCount % 4) * 8; + lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition)); + lByteCount++; + } + lWordCount = (lByteCount - (lByteCount % 4)) / 4; + lBytePosition = (lByteCount % 4) * 8; + lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); + lWordArray[lNumberOfWords - 2] = lMessageLength << 3; + lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; + return lWordArray; + }; + + var wordToHex = function (lValue) { + var wordToHexValue = '', + wordToHexValue_temp = '', + lByte, lCount; + for (lCount = 0; lCount <= 3; lCount++) { + lByte = (lValue >>> (lCount * 8)) & 255; + wordToHexValue_temp = '0' + lByte.toString(16); + wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2); + } + return wordToHexValue; + }; + + var x = [], + k, AA, BB, CC, DD, a, b, c, d, S11 = 7, + S12 = 12, + S13 = 17, + S14 = 22, + S21 = 5, + S22 = 9, + S23 = 14, + S24 = 20, + S31 = 4, + S32 = 11, + S33 = 16, + S34 = 23, + S41 = 6, + S42 = 10, + S43 = 15, + S44 = 21; + + str = utf8_encode(str); + x = convertToWordArray(str); + a = 0x67452301; + b = 0xEFCDAB89; + c = 0x98BADCFE; + d = 0x10325476; + + xl = x.length; + for (k = 0; k < xl; k += 16) { + AA = a; + BB = b; + CC = c; + DD = d; + a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); + d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); + c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB); + b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); + a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); + d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); + c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613); + b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501); + a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8); + d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); + c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); + b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); + a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122); + d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193); + c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E); + b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821); + a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); + d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340); + c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); + b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); + a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); + d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453); + c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); + b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); + a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); + d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); + c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); + b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); + a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); + d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); + c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); + b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); + a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); + d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681); + c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); + b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); + a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); + d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); + c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); + b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); + a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); + d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); + c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); + b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05); + a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); + d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); + c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); + b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); + a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244); + d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97); + c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); + b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039); + a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3); + d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); + c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); + b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1); + a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); + d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); + c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314); + b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); + a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82); + d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); + c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); + b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391); + a = addUnsigned(a, AA); + b = addUnsigned(b, BB); + c = addUnsigned(c, CC); + d = addUnsigned(d, DD); + } + + var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); + + return temp.toUpperCase().substr(0, 10); +} + + +function utf8_encode(argString) { + // discuss at: http://phpjs.org/functions/utf8_encode/ + // original by: Webtoolkit.info (http://www.webtoolkit.info/) + // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // improved by: sowberry + // improved by: Jack + // improved by: Yves Sucaet + // improved by: kirilloid + // bugfixed by: Onno Marsman + // bugfixed by: Onno Marsman + // bugfixed by: Ulrich + // bugfixed by: Rafal Kukawski + // bugfixed by: kirilloid + // example 1: utf8_encode('Kevin van Zonneveld'); + // returns 1: 'Kevin van Zonneveld' + + if (argString === null || typeof argString === 'undefined') { + return ''; + } + + // .replace(/\r\n/g, "\n").replace(/\r/g, "\n"); + var string = (argString + ''); + var utftext = '', + start, end, stringl = 0; + + start = end = 0; + stringl = string.length; + for (var n = 0; n < stringl; n++) { + var c1 = string.charCodeAt(n); + var enc = null; + + if (c1 < 128) { + end++; + } else if (c1 > 127 && c1 < 2048) { + enc = String.fromCharCode( + (c1 >> 6) | 192, (c1 & 63) | 128 + ); + } else if ((c1 & 0xF800) != 0xD800) { + enc = String.fromCharCode( + (c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128 + ); + } else { + // surrogate pairs + if ((c1 & 0xFC00) != 0xD800) { + throw new RangeError('Unmatched trail surrogate at ' + n); + } + var c2 = string.charCodeAt(++n); + if ((c2 & 0xFC00) != 0xDC00) { + throw new RangeError('Unmatched lead surrogate at ' + (n - 1)); + } + c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000; + enc = String.fromCharCode( + (c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128 + ); + } + if (enc !== null) { + if (end > start) { + utftext += string.slice(start, end); + } + utftext += enc; + start = end = n + 1; + } + } + + if (end > start) { + utftext += string.slice(start, stringl); + } + + return utftext; +} diff --git a/resources/views/layouts/default/flights/simbrief_form.blade.php b/resources/views/layouts/default/flights/simbrief_form.blade.php index 5f7337c4..1987bbce 100644 --- a/resources/views/layouts/default/flights/simbrief_form.blade.php +++ b/resources/views/layouts/default/flights/simbrief_form.blade.php @@ -83,49 +83,19 @@