Move seed data into separate file with importer; fix admin panel js being broken
This commit is contained in:
1
Makefile
1
Makefile
@@ -60,6 +60,7 @@ reset: clean
|
|||||||
reload-db:
|
reload-db:
|
||||||
@php artisan database:create --reset
|
@php artisan database:create --reset
|
||||||
@php artisan migrate:refresh --seed
|
@php artisan migrate:refresh --seed
|
||||||
|
@php artisan phpvms:import app/Database/seeds/sample.yml
|
||||||
@php artisan phpvms:navdata
|
@php artisan phpvms:navdata
|
||||||
|
|
||||||
.PHONY: tests
|
.PHONY: tests
|
||||||
|
|||||||
@@ -11,17 +11,9 @@ use App\Models\Pirep;
|
|||||||
|
|
||||||
class DevCommands extends BaseCommand
|
class DevCommands extends BaseCommand
|
||||||
{
|
{
|
||||||
protected $signature = 'phpvms {cmd} {--file=?}';
|
protected $signature = 'phpvms {cmd}';
|
||||||
protected $description = 'Developer commands';
|
protected $description = 'Developer commands';
|
||||||
|
|
||||||
protected $dbSvc;
|
|
||||||
|
|
||||||
public function __construct(DatabaseService $dbSvc)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->dbSvc = $dbSvc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run dev related commands
|
* Run dev related commands
|
||||||
*/
|
*/
|
||||||
@@ -37,7 +29,6 @@ class DevCommands extends BaseCommand
|
|||||||
$commands = [
|
$commands = [
|
||||||
'clear-acars' => 'clearAcars',
|
'clear-acars' => 'clearAcars',
|
||||||
'compile-assets' => 'compileAssets',
|
'compile-assets' => 'compileAssets',
|
||||||
'import' => 'importYaml',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if(!array_key_exists($command, $commands)) {
|
if(!array_key_exists($command, $commands)) {
|
||||||
@@ -76,12 +67,4 @@ class DevCommands extends BaseCommand
|
|||||||
$this->runCommand('npm update');
|
$this->runCommand('npm update');
|
||||||
$this->runCommand('npm run dev');
|
$this->runCommand('npm run dev');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Import data from a YAML file
|
|
||||||
*/
|
|
||||||
protected function importYaml()
|
|
||||||
{
|
|
||||||
$this->info('importing '. $this->argument('file'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
53
app/Console/Commands/ImportCommand.php
Normal file
53
app/Console/Commands/ImportCommand.php
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use DB;
|
||||||
|
use App\Console\BaseCommand;
|
||||||
|
use App\Services\DatabaseService;
|
||||||
|
|
||||||
|
class ImportCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
protected $signature = 'phpvms:import {files*}';
|
||||||
|
protected $description = 'Developer commands';
|
||||||
|
|
||||||
|
protected $dbSvc;
|
||||||
|
|
||||||
|
public function __construct(DatabaseService $dbSvc)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->dbSvc = $dbSvc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run dev related commands
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$files = $this->argument('files');
|
||||||
|
if(empty($files)) {
|
||||||
|
$this->error('No files to import specified!');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$ignore_errors = true;
|
||||||
|
/*$ignore_errors = $this->option('ignore_errors');
|
||||||
|
if(!$ignore_errors) {
|
||||||
|
$ignore_errors = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
foreach($files as $file) {
|
||||||
|
if(!file_exists($file)) {
|
||||||
|
$this->error('File ' . $file .' doesn\'t exist');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Importing ' . $file);
|
||||||
|
|
||||||
|
$imported = $this->dbSvc->seed_from_yaml_file($file, $ignore_errors);
|
||||||
|
foreach($imported as $table => $count) {
|
||||||
|
$this->info('Imported '.$count.' records from "'.$table.'"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel
|
|||||||
Commands\AcarsReplay::class,
|
Commands\AcarsReplay::class,
|
||||||
Commands\CreateDatabase::class,
|
Commands\CreateDatabase::class,
|
||||||
Commands\DevCommands::class,
|
Commands\DevCommands::class,
|
||||||
|
Commands\ImportCommand::class,
|
||||||
Commands\Install::class,
|
Commands\Install::class,
|
||||||
Commands\NavdataCommand::class,
|
Commands\NavdataCommand::class,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use App\Models\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
class CreateRanksTable extends Migration
|
class CreateRanksTable extends Migration
|
||||||
@@ -24,6 +24,19 @@ class CreateRanksTable extends Migration
|
|||||||
|
|
||||||
$table->unique('name');
|
$table->unique('name');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial required data...
|
||||||
|
*/
|
||||||
|
$ranks = [
|
||||||
|
[
|
||||||
|
'id' => 1,
|
||||||
|
'name' => 'New Pilot',
|
||||||
|
'hours' => 0,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->addData('ranks', $ranks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,92 +1,7 @@
|
|||||||
|
#
|
||||||
airlines:
|
# Initial minimal data required. You probably don't
|
||||||
- id: 1
|
# want to modify or erase any of this here
|
||||||
icao: VMS
|
#
|
||||||
iata: VM
|
|
||||||
name: phpvms airlines
|
|
||||||
active: 1
|
|
||||||
created_at: now
|
|
||||||
updated_at: now
|
|
||||||
|
|
||||||
users:
|
|
||||||
- id: 1
|
|
||||||
name: Admin User
|
|
||||||
email: admin@phpvms.net
|
|
||||||
password: admin
|
|
||||||
api_key: testadminapikey
|
|
||||||
airline_id: 1
|
|
||||||
rank_id: 1
|
|
||||||
home_airport_id: KAUS
|
|
||||||
curr_airport_id: KJFK
|
|
||||||
last_pirep_id: pirepid_3
|
|
||||||
flights: 3
|
|
||||||
flight_time: 43200
|
|
||||||
timezone: America/Chicago
|
|
||||||
state: 1
|
|
||||||
created_at: now
|
|
||||||
updated_at: now
|
|
||||||
- id: 2
|
|
||||||
name: Carla Walters
|
|
||||||
email: carla.walters68@example.com
|
|
||||||
password: admin
|
|
||||||
api_key: testuserapikey1
|
|
||||||
airline_id: 1
|
|
||||||
rank_id: 1
|
|
||||||
home_airport_id: KJFK
|
|
||||||
curr_airport_id: KJFK
|
|
||||||
flights: 1
|
|
||||||
flight_time: 43200
|
|
||||||
created_at: now
|
|
||||||
updated_at: now
|
|
||||||
state: 0
|
|
||||||
- id: 3
|
|
||||||
name: Raymond Pearson
|
|
||||||
email: raymond.pearson56@example.com
|
|
||||||
password: admin
|
|
||||||
api_key: testuserapikey2
|
|
||||||
airline_id: 1
|
|
||||||
rank_id: 1
|
|
||||||
home_airport_id: KJFK
|
|
||||||
curr_airport_id: KAUS
|
|
||||||
flights: 1
|
|
||||||
flight_time: 43200
|
|
||||||
created_at: now
|
|
||||||
updated_at: now
|
|
||||||
state: 1
|
|
||||||
|
|
||||||
role_user:
|
|
||||||
- user_id: 1
|
|
||||||
role_id: 1
|
|
||||||
user_type: App\Models\User
|
|
||||||
- user_id: 1
|
|
||||||
role_id: 2
|
|
||||||
user_type: App\Models\User
|
|
||||||
- user_id: 2
|
|
||||||
role_id: 2
|
|
||||||
user_type: App\Models\User
|
|
||||||
- user_id: 3
|
|
||||||
role_id: 2
|
|
||||||
user_type: App\Models\User
|
|
||||||
|
|
||||||
# ranks
|
|
||||||
ranks:
|
|
||||||
- id: 1
|
|
||||||
name: New Pilot
|
|
||||||
hours: 0
|
|
||||||
- id: 2
|
|
||||||
name: Junior First Officer
|
|
||||||
hours: 10
|
|
||||||
- id: 3
|
|
||||||
name: First Officer
|
|
||||||
hours: 15
|
|
||||||
auto_approve_acars: 1
|
|
||||||
auto_approve_manual: 1
|
|
||||||
- id: 4
|
|
||||||
name: Senior Captain
|
|
||||||
hours: 20
|
|
||||||
auto_approve_acars: 1
|
|
||||||
auto_approve_manual: 1
|
|
||||||
auto_promote: 0
|
|
||||||
|
|
||||||
airports:
|
airports:
|
||||||
- id: KAUS
|
- id: KAUS
|
||||||
@@ -98,233 +13,3 @@ airports:
|
|||||||
lat: 30.1945278
|
lat: 30.1945278
|
||||||
lon: -97.6698889
|
lon: -97.6698889
|
||||||
tz: America/Chicago
|
tz: America/Chicago
|
||||||
- id: KJFK
|
|
||||||
iata: JFK
|
|
||||||
icao: KJFK
|
|
||||||
name: John F Kennedy
|
|
||||||
location: New York, New York, USA
|
|
||||||
country: United States
|
|
||||||
lat: 40.6399257
|
|
||||||
lon: -73.7786950
|
|
||||||
tz: America/New_York
|
|
||||||
- id: KBWI
|
|
||||||
iata: BWI
|
|
||||||
icao: KBWI
|
|
||||||
name: Baltimore/Washington International Thurgood Marshall Airport
|
|
||||||
location: Baltimore, MD
|
|
||||||
country: United States
|
|
||||||
lat: 39.1754
|
|
||||||
lon: -76.6683
|
|
||||||
tz: America/New_York
|
|
||||||
- id: KIAH
|
|
||||||
iata: IAH
|
|
||||||
icao: KIAH
|
|
||||||
name: George Bush Intercontinental Houston Airport
|
|
||||||
location: Houston, TX
|
|
||||||
country: United States
|
|
||||||
lat: 29.9844
|
|
||||||
lon: -95.3414
|
|
||||||
tz: America/Chicago
|
|
||||||
- id: KORD
|
|
||||||
iata: ORD
|
|
||||||
icao: KORD
|
|
||||||
name: Chicago O'Hare International Airport
|
|
||||||
location: Chicago, IL
|
|
||||||
country: United States
|
|
||||||
lat: 41.9786
|
|
||||||
lon: -87.9048
|
|
||||||
tz: America/Chicago
|
|
||||||
- id: KDFW
|
|
||||||
iata: DFW
|
|
||||||
icao: KDFW
|
|
||||||
name: Dallas Fort Worth International Airport
|
|
||||||
location: Dallas, TX
|
|
||||||
country: United States
|
|
||||||
lat: 32.8968
|
|
||||||
lon: -97.038
|
|
||||||
tz: America/Chicago
|
|
||||||
- id: EFHK
|
|
||||||
iata: HEL
|
|
||||||
icao: EFHK
|
|
||||||
name: Helsinki Vantaa Airport
|
|
||||||
location: Helsinki
|
|
||||||
country: Finland
|
|
||||||
lat: 60.3172
|
|
||||||
lon: 24.9633
|
|
||||||
tz: Europe/Helsinki
|
|
||||||
- id: EGLL
|
|
||||||
iata: LHR
|
|
||||||
icao: EGLL
|
|
||||||
name: London Heathrow
|
|
||||||
location: London, England
|
|
||||||
lat: 51.4775
|
|
||||||
lon: -0.4614
|
|
||||||
tz: Europe/London
|
|
||||||
|
|
||||||
#
|
|
||||||
aircraft:
|
|
||||||
- id: 1
|
|
||||||
subfleet_id: 1
|
|
||||||
name: Boeing 747-400
|
|
||||||
registration: NC17
|
|
||||||
tail_number: 17
|
|
||||||
- id: 2
|
|
||||||
subfleet_id: 2
|
|
||||||
name: Boeing 777-200
|
|
||||||
registration: NC20
|
|
||||||
tail_number: 20
|
|
||||||
|
|
||||||
#aircraft_rank:
|
|
||||||
# - aircraft_id: 1
|
|
||||||
# rank_id: 1
|
|
||||||
# - aircraft_id: 1
|
|
||||||
# rank_id: 2
|
|
||||||
# acars_pay: 100
|
|
||||||
# manual_pay: 50
|
|
||||||
|
|
||||||
fares:
|
|
||||||
- id: 1
|
|
||||||
code: Y
|
|
||||||
name: Economy
|
|
||||||
price: 100
|
|
||||||
capacity: 200
|
|
||||||
- id: 2
|
|
||||||
code: B
|
|
||||||
name: Business
|
|
||||||
price: 500
|
|
||||||
capacity: 10
|
|
||||||
- id: 3
|
|
||||||
code: F
|
|
||||||
name: First-Class
|
|
||||||
price: 800
|
|
||||||
capacity: 5
|
|
||||||
|
|
||||||
subfleets:
|
|
||||||
- id: 1
|
|
||||||
airline_id: 1
|
|
||||||
name: 747-400 Winglets
|
|
||||||
type: 744W
|
|
||||||
- id: 2
|
|
||||||
airline_id: 1
|
|
||||||
name: 777-200 LR
|
|
||||||
type: 772-LR
|
|
||||||
|
|
||||||
# add a few mods to aircraft and fares
|
|
||||||
subfleet_fare:
|
|
||||||
|
|
||||||
# Fare classes on the 747
|
|
||||||
- subfleet_id: 1
|
|
||||||
fare_id: 1
|
|
||||||
price: 200
|
|
||||||
capacity: 400
|
|
||||||
- subfleet_id: 1
|
|
||||||
fare_id: 2
|
|
||||||
capacity: 20
|
|
||||||
- subfleet_id: 1
|
|
||||||
fare_id: 3
|
|
||||||
price: 1000
|
|
||||||
capacity: 10
|
|
||||||
|
|
||||||
# Fare classes on the 777
|
|
||||||
- subfleet_id: 2
|
|
||||||
fare_id: 1
|
|
||||||
- subfleet_id: 2
|
|
||||||
fare_id: 3
|
|
||||||
capacity: 10
|
|
||||||
|
|
||||||
subfleet_flight:
|
|
||||||
- subfleet_id: 1
|
|
||||||
flight_id: flightid_1
|
|
||||||
|
|
||||||
flights:
|
|
||||||
- id: flightid_1
|
|
||||||
airline_id: 1
|
|
||||||
flight_number: 100
|
|
||||||
dpt_airport_id: KAUS
|
|
||||||
arr_airport_id: KJFK
|
|
||||||
route: KAUS SID TNV J87 IAH J2 LCH J22 MEI J239 ATL J52 AJFEB J14 BYJAC Q60 JAXSN J14 COLIN J61 HUBBS J55 SIE STAR KJFK
|
|
||||||
dpt_time: 6PM CST
|
|
||||||
arr_time: 11PM EST
|
|
||||||
created_at: NOW
|
|
||||||
updated_at: NOW
|
|
||||||
- id: flightid_2
|
|
||||||
airline_id: 1
|
|
||||||
flight_number: 6028
|
|
||||||
dpt_airport_id: KIAH
|
|
||||||
arr_airport_id: KAUS
|
|
||||||
dpt_time: 9AM CST
|
|
||||||
arr_time: 1030AM CST
|
|
||||||
route: PITZZ4 MNURE WLEEE4
|
|
||||||
created_at: NOW
|
|
||||||
updated_at: NOW
|
|
||||||
|
|
||||||
flight_fields:
|
|
||||||
- id: 1
|
|
||||||
flight_id: flightid_1
|
|
||||||
name: cost index
|
|
||||||
value: 80
|
|
||||||
- id: 2
|
|
||||||
flight_id: flightid_2
|
|
||||||
name: cost index
|
|
||||||
value: 100
|
|
||||||
|
|
||||||
user_bids:
|
|
||||||
- id: 100
|
|
||||||
user_id: 1
|
|
||||||
flight_id: flightid_1
|
|
||||||
- id: 101
|
|
||||||
user_id: 1
|
|
||||||
flight_id: flightid_3
|
|
||||||
|
|
||||||
pireps:
|
|
||||||
- id: pirepid_1
|
|
||||||
user_id: 1
|
|
||||||
airline_id: 1
|
|
||||||
flight_id: flightid_1
|
|
||||||
aircraft_id: 1
|
|
||||||
dpt_airport_id: KAUS
|
|
||||||
arr_airport_id: KJFK
|
|
||||||
flight_time: 180 # 6 hours
|
|
||||||
state: 1
|
|
||||||
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
|
|
||||||
notes: just a pilot report
|
|
||||||
created_at: NOW
|
|
||||||
updated_at: NOW
|
|
||||||
- id: pirepid_2
|
|
||||||
user_id: 1
|
|
||||||
airline_id: 1
|
|
||||||
flight_id: flightid_2
|
|
||||||
aircraft_id: 1
|
|
||||||
dpt_airport_id: KJFK
|
|
||||||
arr_airport_id: KAUS
|
|
||||||
flight_time: 180 # 6 hours
|
|
||||||
state: 1
|
|
||||||
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
|
|
||||||
notes: just a pilot report
|
|
||||||
created_at: NOW
|
|
||||||
updated_at: NOW
|
|
||||||
- id: pirepid_3
|
|
||||||
user_id: 1
|
|
||||||
airline_id: 1
|
|
||||||
flight_id: flightid_2
|
|
||||||
aircraft_id: 1
|
|
||||||
dpt_airport_id: KJFK
|
|
||||||
arr_airport_id: KAUS
|
|
||||||
flight_time: 180 # 6 hours
|
|
||||||
state: 1
|
|
||||||
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
|
|
||||||
notes: just a pilot report
|
|
||||||
created_at: NOW
|
|
||||||
updated_at: NOW
|
|
||||||
|
|
||||||
pirep_fields:
|
|
||||||
- id: 1
|
|
||||||
name: arrival gate
|
|
||||||
required: 0
|
|
||||||
|
|
||||||
pirep_field_values:
|
|
||||||
- id: 1
|
|
||||||
pirep_id: pirepid_1
|
|
||||||
name: arrival gate
|
|
||||||
value: B14
|
|
||||||
source: manual
|
|
||||||
|
|||||||
327
app/Database/seeds/sample.yml
Normal file
327
app/Database/seeds/sample.yml
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
|
||||||
|
airlines:
|
||||||
|
- id: 1
|
||||||
|
icao: VMS
|
||||||
|
iata: VM
|
||||||
|
name: phpvms airlines
|
||||||
|
active: 1
|
||||||
|
created_at: now
|
||||||
|
updated_at: now
|
||||||
|
|
||||||
|
users:
|
||||||
|
- id: 1
|
||||||
|
name: Admin User
|
||||||
|
email: admin@phpvms.net
|
||||||
|
password: admin
|
||||||
|
api_key: testadminapikey
|
||||||
|
airline_id: 1
|
||||||
|
rank_id: 1
|
||||||
|
home_airport_id: KAUS
|
||||||
|
curr_airport_id: KJFK
|
||||||
|
last_pirep_id: pirepid_3
|
||||||
|
flights: 3
|
||||||
|
flight_time: 43200
|
||||||
|
timezone: America/Chicago
|
||||||
|
state: 1
|
||||||
|
created_at: now
|
||||||
|
updated_at: now
|
||||||
|
- id: 2
|
||||||
|
name: Carla Walters
|
||||||
|
email: carla.walters68@example.com
|
||||||
|
password: admin
|
||||||
|
api_key: testuserapikey1
|
||||||
|
airline_id: 1
|
||||||
|
rank_id: 1
|
||||||
|
home_airport_id: KJFK
|
||||||
|
curr_airport_id: KJFK
|
||||||
|
flights: 1
|
||||||
|
flight_time: 43200
|
||||||
|
created_at: now
|
||||||
|
updated_at: now
|
||||||
|
state: 0
|
||||||
|
- id: 3
|
||||||
|
name: Raymond Pearson
|
||||||
|
email: raymond.pearson56@example.com
|
||||||
|
password: admin
|
||||||
|
api_key: testuserapikey2
|
||||||
|
airline_id: 1
|
||||||
|
rank_id: 1
|
||||||
|
home_airport_id: KJFK
|
||||||
|
curr_airport_id: KAUS
|
||||||
|
flights: 1
|
||||||
|
flight_time: 43200
|
||||||
|
created_at: now
|
||||||
|
updated_at: now
|
||||||
|
state: 1
|
||||||
|
|
||||||
|
role_user:
|
||||||
|
- user_id: 1
|
||||||
|
role_id: 1
|
||||||
|
user_type: App\Models\User
|
||||||
|
- user_id: 1
|
||||||
|
role_id: 2
|
||||||
|
user_type: App\Models\User
|
||||||
|
- user_id: 2
|
||||||
|
role_id: 2
|
||||||
|
user_type: App\Models\User
|
||||||
|
- user_id: 3
|
||||||
|
role_id: 2
|
||||||
|
user_type: App\Models\User
|
||||||
|
|
||||||
|
# ranks
|
||||||
|
ranks:
|
||||||
|
- id: 2
|
||||||
|
name: Junior First Officer
|
||||||
|
hours: 10
|
||||||
|
- id: 3
|
||||||
|
name: First Officer
|
||||||
|
hours: 15
|
||||||
|
auto_approve_acars: 1
|
||||||
|
auto_approve_manual: 1
|
||||||
|
- id: 4
|
||||||
|
name: Senior Captain
|
||||||
|
hours: 20
|
||||||
|
auto_approve_acars: 1
|
||||||
|
auto_approve_manual: 1
|
||||||
|
auto_promote: 0
|
||||||
|
|
||||||
|
airports:
|
||||||
|
- id: KAUS
|
||||||
|
iata: AUS
|
||||||
|
icao: KAUS
|
||||||
|
name: Austin-Bergstrom
|
||||||
|
location: Austin, Texas, USA
|
||||||
|
country: United States
|
||||||
|
lat: 30.1945278
|
||||||
|
lon: -97.6698889
|
||||||
|
tz: America/Chicago
|
||||||
|
- id: KJFK
|
||||||
|
iata: JFK
|
||||||
|
icao: KJFK
|
||||||
|
name: John F Kennedy
|
||||||
|
location: New York, New York, USA
|
||||||
|
country: United States
|
||||||
|
lat: 40.6399257
|
||||||
|
lon: -73.7786950
|
||||||
|
tz: America/New_York
|
||||||
|
- id: KBWI
|
||||||
|
iata: BWI
|
||||||
|
icao: KBWI
|
||||||
|
name: Baltimore/Washington International Thurgood Marshall Airport
|
||||||
|
location: Baltimore, MD
|
||||||
|
country: United States
|
||||||
|
lat: 39.1754
|
||||||
|
lon: -76.6683
|
||||||
|
tz: America/New_York
|
||||||
|
- id: KIAH
|
||||||
|
iata: IAH
|
||||||
|
icao: KIAH
|
||||||
|
name: George Bush Intercontinental Houston Airport
|
||||||
|
location: Houston, TX
|
||||||
|
country: United States
|
||||||
|
lat: 29.9844
|
||||||
|
lon: -95.3414
|
||||||
|
tz: America/Chicago
|
||||||
|
- id: KORD
|
||||||
|
iata: ORD
|
||||||
|
icao: KORD
|
||||||
|
name: Chicago O'Hare International Airport
|
||||||
|
location: Chicago, IL
|
||||||
|
country: United States
|
||||||
|
lat: 41.9786
|
||||||
|
lon: -87.9048
|
||||||
|
tz: America/Chicago
|
||||||
|
- id: KDFW
|
||||||
|
iata: DFW
|
||||||
|
icao: KDFW
|
||||||
|
name: Dallas Fort Worth International Airport
|
||||||
|
location: Dallas, TX
|
||||||
|
country: United States
|
||||||
|
lat: 32.8968
|
||||||
|
lon: -97.038
|
||||||
|
tz: America/Chicago
|
||||||
|
- id: EFHK
|
||||||
|
iata: HEL
|
||||||
|
icao: EFHK
|
||||||
|
name: Helsinki Vantaa Airport
|
||||||
|
location: Helsinki
|
||||||
|
country: Finland
|
||||||
|
lat: 60.3172
|
||||||
|
lon: 24.9633
|
||||||
|
tz: Europe/Helsinki
|
||||||
|
- id: EGLL
|
||||||
|
iata: LHR
|
||||||
|
icao: EGLL
|
||||||
|
name: London Heathrow
|
||||||
|
location: London, England
|
||||||
|
lat: 51.4775
|
||||||
|
lon: -0.4614
|
||||||
|
tz: Europe/London
|
||||||
|
|
||||||
|
#
|
||||||
|
aircraft:
|
||||||
|
- id: 1
|
||||||
|
subfleet_id: 1
|
||||||
|
name: Boeing 747-400
|
||||||
|
registration: NC17
|
||||||
|
tail_number: 17
|
||||||
|
- id: 2
|
||||||
|
subfleet_id: 2
|
||||||
|
name: Boeing 777-200
|
||||||
|
registration: NC20
|
||||||
|
tail_number: 20
|
||||||
|
|
||||||
|
#aircraft_rank:
|
||||||
|
# - aircraft_id: 1
|
||||||
|
# rank_id: 1
|
||||||
|
# - aircraft_id: 1
|
||||||
|
# rank_id: 2
|
||||||
|
# acars_pay: 100
|
||||||
|
# manual_pay: 50
|
||||||
|
|
||||||
|
fares:
|
||||||
|
- id: 1
|
||||||
|
code: Y
|
||||||
|
name: Economy
|
||||||
|
price: 100
|
||||||
|
capacity: 200
|
||||||
|
- id: 2
|
||||||
|
code: B
|
||||||
|
name: Business
|
||||||
|
price: 500
|
||||||
|
capacity: 10
|
||||||
|
- id: 3
|
||||||
|
code: F
|
||||||
|
name: First-Class
|
||||||
|
price: 800
|
||||||
|
capacity: 5
|
||||||
|
|
||||||
|
subfleets:
|
||||||
|
- id: 1
|
||||||
|
airline_id: 1
|
||||||
|
name: 747-400 Winglets
|
||||||
|
type: 744W
|
||||||
|
- id: 2
|
||||||
|
airline_id: 1
|
||||||
|
name: 777-200 LR
|
||||||
|
type: 772-LR
|
||||||
|
|
||||||
|
# add a few mods to aircraft and fares
|
||||||
|
subfleet_fare:
|
||||||
|
|
||||||
|
# Fare classes on the 747
|
||||||
|
- subfleet_id: 1
|
||||||
|
fare_id: 1
|
||||||
|
price: 200
|
||||||
|
capacity: 400
|
||||||
|
- subfleet_id: 1
|
||||||
|
fare_id: 2
|
||||||
|
capacity: 20
|
||||||
|
- subfleet_id: 1
|
||||||
|
fare_id: 3
|
||||||
|
price: 1000
|
||||||
|
capacity: 10
|
||||||
|
|
||||||
|
# Fare classes on the 777
|
||||||
|
- subfleet_id: 2
|
||||||
|
fare_id: 1
|
||||||
|
- subfleet_id: 2
|
||||||
|
fare_id: 3
|
||||||
|
capacity: 10
|
||||||
|
|
||||||
|
subfleet_flight:
|
||||||
|
- subfleet_id: 1
|
||||||
|
flight_id: flightid_1
|
||||||
|
|
||||||
|
flights:
|
||||||
|
- id: flightid_1
|
||||||
|
airline_id: 1
|
||||||
|
flight_number: 100
|
||||||
|
dpt_airport_id: KAUS
|
||||||
|
arr_airport_id: KJFK
|
||||||
|
route: KAUS SID TNV J87 IAH J2 LCH J22 MEI J239 ATL J52 AJFEB J14 BYJAC Q60 JAXSN J14 COLIN J61 HUBBS J55 SIE STAR KJFK
|
||||||
|
dpt_time: 6PM CST
|
||||||
|
arr_time: 11PM EST
|
||||||
|
created_at: NOW
|
||||||
|
updated_at: NOW
|
||||||
|
- id: flightid_2
|
||||||
|
airline_id: 1
|
||||||
|
flight_number: 6028
|
||||||
|
dpt_airport_id: KIAH
|
||||||
|
arr_airport_id: KAUS
|
||||||
|
dpt_time: 9AM CST
|
||||||
|
arr_time: 1030AM CST
|
||||||
|
route: PITZZ4 MNURE WLEEE4
|
||||||
|
created_at: NOW
|
||||||
|
updated_at: NOW
|
||||||
|
|
||||||
|
flight_fields:
|
||||||
|
- id: 1
|
||||||
|
flight_id: flightid_1
|
||||||
|
name: cost index
|
||||||
|
value: 80
|
||||||
|
- id: 2
|
||||||
|
flight_id: flightid_2
|
||||||
|
name: cost index
|
||||||
|
value: 100
|
||||||
|
|
||||||
|
user_bids:
|
||||||
|
- id: 100
|
||||||
|
user_id: 1
|
||||||
|
flight_id: flightid_1
|
||||||
|
- id: 101
|
||||||
|
user_id: 1
|
||||||
|
flight_id: flightid_3
|
||||||
|
|
||||||
|
pireps:
|
||||||
|
- id: pirepid_1
|
||||||
|
user_id: 1
|
||||||
|
airline_id: 1
|
||||||
|
flight_id: flightid_1
|
||||||
|
aircraft_id: 1
|
||||||
|
dpt_airport_id: KAUS
|
||||||
|
arr_airport_id: KJFK
|
||||||
|
flight_time: 180 # 6 hours
|
||||||
|
state: 1
|
||||||
|
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
|
||||||
|
notes: just a pilot report
|
||||||
|
created_at: NOW
|
||||||
|
updated_at: NOW
|
||||||
|
- id: pirepid_2
|
||||||
|
user_id: 1
|
||||||
|
airline_id: 1
|
||||||
|
flight_id: flightid_2
|
||||||
|
aircraft_id: 1
|
||||||
|
dpt_airport_id: KJFK
|
||||||
|
arr_airport_id: KAUS
|
||||||
|
flight_time: 180 # 6 hours
|
||||||
|
state: 1
|
||||||
|
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
|
||||||
|
notes: just a pilot report
|
||||||
|
created_at: NOW
|
||||||
|
updated_at: NOW
|
||||||
|
- id: pirepid_3
|
||||||
|
user_id: 1
|
||||||
|
airline_id: 1
|
||||||
|
flight_id: flightid_2
|
||||||
|
aircraft_id: 1
|
||||||
|
dpt_airport_id: KJFK
|
||||||
|
arr_airport_id: KAUS
|
||||||
|
flight_time: 180 # 6 hours
|
||||||
|
state: 1
|
||||||
|
route: PLMMR2 SPA Q22 BEARI FAK PHLBO3
|
||||||
|
notes: just a pilot report
|
||||||
|
created_at: NOW
|
||||||
|
updated_at: NOW
|
||||||
|
|
||||||
|
pirep_fields:
|
||||||
|
- id: 1
|
||||||
|
name: arrival gate
|
||||||
|
required: 0
|
||||||
|
|
||||||
|
pirep_field_values:
|
||||||
|
- id: 1
|
||||||
|
pirep_id: pirepid_1
|
||||||
|
name: arrival gate
|
||||||
|
value: B14
|
||||||
|
source: manual
|
||||||
@@ -30,7 +30,7 @@ class AircraftController extends BaseController
|
|||||||
$aircraft = $this->aircraftRepository->all();
|
$aircraft = $this->aircraftRepository->all();
|
||||||
|
|
||||||
return view('admin.aircraft.index', [
|
return view('admin.aircraft.index', [
|
||||||
'aircraft', $aircraft
|
'aircraft' => $aircraft
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,16 +28,32 @@ class DatabaseService extends BaseService
|
|||||||
return Carbon::now('UTC')->format('Y-m-d H:i:s');
|
return Carbon::now('UTC')->format('Y-m-d H:i:s');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function seed_from_yaml_file($yaml_file)
|
/**
|
||||||
|
* @param $yaml_file
|
||||||
|
* @param bool $ignore_errors
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function seed_from_yaml_file($yaml_file, $ignore_errors=false): array
|
||||||
{
|
{
|
||||||
$yml = file_get_contents($yaml_file);
|
$yml = file_get_contents($yaml_file);
|
||||||
$this->seed_from_yaml($yml);
|
return $this->seed_from_yaml($yml, $ignore_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function seed_from_yaml($yml)
|
/**
|
||||||
|
* @param $yml
|
||||||
|
* @param bool $ignore_errors
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function seed_from_yaml($yml, $ignore_errors=false): array
|
||||||
{
|
{
|
||||||
|
$imported = [];
|
||||||
$yml = Yaml::parse($yml);
|
$yml = Yaml::parse($yml);
|
||||||
foreach ($yml as $table => $rows) {
|
foreach ($yml as $table => $rows) {
|
||||||
|
|
||||||
|
$imported[$table] = 0;
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
|
|
||||||
# see if this table uses a UUID as the PK
|
# see if this table uses a UUID as the PK
|
||||||
@@ -60,12 +76,19 @@ class DatabaseService extends BaseService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#try {
|
try {
|
||||||
DB::table($table)->insert($row);
|
DB::table($table)->insert($row);
|
||||||
#} catch(QueryException $e) {
|
++$imported[$table];
|
||||||
# Log::info($e->getMessage());
|
} catch(QueryException $e) {
|
||||||
#}
|
if($ignore_errors) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $imported;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
package-lock.json
generated
13
package-lock.json
generated
@@ -2,9 +2,6 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Leaflet.Geodesic": {
|
|
||||||
"version": "git+https://git@github.com/henrythasler/Leaflet.Geodesic.git#c5dd6d6a0ee394d0c274d2a3a09d69a11fc11b8b"
|
|
||||||
},
|
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
@@ -1192,6 +1189,11 @@
|
|||||||
"hoek": "2.16.3"
|
"hoek": "2.16.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bootstrap-editable": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap-editable/-/bootstrap-editable-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-RFpnG1q1/td+jH9OX/vHlsYLUCM="
|
||||||
|
},
|
||||||
"bootstrap-sass": {
|
"bootstrap-sass": {
|
||||||
"version": "3.3.7",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz",
|
||||||
@@ -10918,6 +10920,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||||
},
|
},
|
||||||
|
"x-editable": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/x-editable/-/x-editable-1.5.1.tgz",
|
||||||
|
"integrity": "sha1-Ltu4kR7yxdYfY/BrDPAgvg/MWEk="
|
||||||
|
},
|
||||||
"xml-char-classes": {
|
"xml-char-classes": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"pjax": "^0.2.4",
|
"pjax": "^0.2.4",
|
||||||
"popper.js": "^1.13.0",
|
"popper.js": "^1.13.0",
|
||||||
"rivets": "0.9.6",
|
"rivets": "0.9.6",
|
||||||
"select2": "^4.0.5"
|
"select2": "^4.0.5",
|
||||||
|
"x-editable": "1.5.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
664
public/assets/admin/css/vendor.min.css
vendored
664
public/assets/admin/css/vendor.min.css
vendored
@@ -16416,6 +16416,670 @@ a.editable-click.editable-disabled:hover {
|
|||||||
background-size: 176px 22px;
|
background-size: 176px 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*! X-editable - v1.5.1
|
||||||
|
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
||||||
|
* http://github.com/vitalets/x-editable
|
||||||
|
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
|
||||||
|
.editableform {
|
||||||
|
margin-bottom: 0; /* overwrites bootstrap margin */
|
||||||
|
}
|
||||||
|
|
||||||
|
.editableform .control-group {
|
||||||
|
margin-bottom: 0; /* overwrites bootstrap margin */
|
||||||
|
white-space: nowrap; /* prevent wrapping buttons on new line */
|
||||||
|
line-height: 20px; /* overwriting bootstrap line-height. See #133 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
BS3 width:1005 for inputs breaks editable form in popup
|
||||||
|
See: https://github.com/vitalets/x-editable/issues/393
|
||||||
|
*/
|
||||||
|
.editableform .form-control {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-buttons {
|
||||||
|
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
|
||||||
|
vertical-align: top;
|
||||||
|
margin-left: 7px;
|
||||||
|
/* inline-block emulation for IE7*/
|
||||||
|
zoom: 1;
|
||||||
|
*display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-buttons.editable-buttons-bottom {
|
||||||
|
display: block;
|
||||||
|
margin-top: 7px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-input {
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
|
||||||
|
width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
|
||||||
|
white-space: normal; /* reset white-space decalred in parent*/
|
||||||
|
/* display-inline emulation for IE7*/
|
||||||
|
zoom: 1;
|
||||||
|
*display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-buttons .editable-cancel {
|
||||||
|
margin-left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*for jquery-ui buttons need set height to look more pretty*/
|
||||||
|
.editable-buttons button.ui-button-icon-only {
|
||||||
|
height: 24px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editableform-loading {
|
||||||
|
background: url('../img/loading.gif') center center no-repeat;
|
||||||
|
height: 25px;
|
||||||
|
width: auto;
|
||||||
|
min-width: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-inline .editableform-loading {
|
||||||
|
background-position: left 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-error-block {
|
||||||
|
max-width: 300px;
|
||||||
|
margin: 5px 0 0 0;
|
||||||
|
width: auto;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*add padding for jquery ui*/
|
||||||
|
.editable-error-block.ui-state-error {
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- For specific types ---- */
|
||||||
|
|
||||||
|
.editableform .editable-date {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
|
||||||
|
.editable-inline .add-on .icon-th {
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* checklist vertical alignment */
|
||||||
|
.editable-checklist label input[type="checkbox"],
|
||||||
|
.editable-checklist label span {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-checklist label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set exact width of textarea to fit buttons toolbar */
|
||||||
|
.editable-wysihtml5 {
|
||||||
|
width: 566px;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear button shown as link in date inputs */
|
||||||
|
.editable-clear {
|
||||||
|
clear: both;
|
||||||
|
font-size: 0.9em;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IOS-style clear button for text inputs */
|
||||||
|
.editable-clear-x {
|
||||||
|
background: url('../img/clear.png') center center no-repeat;
|
||||||
|
display: block;
|
||||||
|
width: 13px;
|
||||||
|
height: 13px;
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0.6;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
right: 6px;
|
||||||
|
margin-top: -6px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-clear-x:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-pre-wrapped {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
.editable-container.editable-popup {
|
||||||
|
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-container.popover {
|
||||||
|
width: auto; /* without this rule popover does not stretch */
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-container.editable-inline {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: auto;
|
||||||
|
/* inline-block emulation for IE7*/
|
||||||
|
zoom: 1;
|
||||||
|
*display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-container.ui-widget {
|
||||||
|
font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
|
||||||
|
z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
|
||||||
|
}
|
||||||
|
.editable-click,
|
||||||
|
a.editable-click,
|
||||||
|
a.editable-click:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: dashed 1px #0088cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-click.editable-disabled,
|
||||||
|
a.editable-click.editable-disabled,
|
||||||
|
a.editable-click.editable-disabled:hover {
|
||||||
|
color: #585858;
|
||||||
|
cursor: default;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-empty, .editable-empty:hover, .editable-empty:focus{
|
||||||
|
font-style: italic;
|
||||||
|
color: #DD1144;
|
||||||
|
/* border-bottom: none; */
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-unsaved {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-unsaved:after {
|
||||||
|
/* content: '*'*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-bg-transition {
|
||||||
|
-webkit-transition: background-color 1400ms ease-out;
|
||||||
|
-moz-transition: background-color 1400ms ease-out;
|
||||||
|
-o-transition: background-color 1400ms ease-out;
|
||||||
|
-ms-transition: background-color 1400ms ease-out;
|
||||||
|
transition: background-color 1400ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*see https://github.com/vitalets/x-editable/issues/139 */
|
||||||
|
.form-horizontal .editable
|
||||||
|
{
|
||||||
|
padding-top: 5px;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Datepicker for Bootstrap
|
||||||
|
*
|
||||||
|
* Copyright 2012 Stefan Petre
|
||||||
|
* Improvements by Andrew Rowls
|
||||||
|
* Licensed under the Apache License v2.0
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.datepicker {
|
||||||
|
padding: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
direction: ltr;
|
||||||
|
/*.dow {
|
||||||
|
border-top: 1px solid #ddd !important;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
.datepicker-inline {
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
.datepicker.datepicker-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
.datepicker.datepicker-rtl table tr td span {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.datepicker-dropdown {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.datepicker-dropdown:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-bottom: 7px solid #ccc;
|
||||||
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
|
position: absolute;
|
||||||
|
top: -7px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
.datepicker-dropdown:after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid #ffffff;
|
||||||
|
position: absolute;
|
||||||
|
top: -6px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
.datepicker > div {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.datepicker.days div.datepicker-days {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.datepicker.months div.datepicker-months {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.datepicker.years div.datepicker-years {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.datepicker table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.datepicker td,
|
||||||
|
.datepicker th {
|
||||||
|
text-align: center;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.table-striped .datepicker table tr td,
|
||||||
|
.table-striped .datepicker table tr th {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.day:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.old,
|
||||||
|
.datepicker table tr td.new {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.disabled,
|
||||||
|
.datepicker table tr td.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.today,
|
||||||
|
.datepicker table tr td.today:hover,
|
||||||
|
.datepicker table tr td.today.disabled,
|
||||||
|
.datepicker table tr td.today.disabled:hover {
|
||||||
|
background-color: #fde19a;
|
||||||
|
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||||
|
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||||
|
border-color: #fdf59a #fdf59a #fbed50;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.today:hover,
|
||||||
|
.datepicker table tr td.today:hover:hover,
|
||||||
|
.datepicker table tr td.today.disabled:hover,
|
||||||
|
.datepicker table tr td.today.disabled:hover:hover,
|
||||||
|
.datepicker table tr td.today:active,
|
||||||
|
.datepicker table tr td.today:hover:active,
|
||||||
|
.datepicker table tr td.today.disabled:active,
|
||||||
|
.datepicker table tr td.today.disabled:hover:active,
|
||||||
|
.datepicker table tr td.today.active,
|
||||||
|
.datepicker table tr td.today:hover.active,
|
||||||
|
.datepicker table tr td.today.disabled.active,
|
||||||
|
.datepicker table tr td.today.disabled:hover.active,
|
||||||
|
.datepicker table tr td.today.disabled,
|
||||||
|
.datepicker table tr td.today:hover.disabled,
|
||||||
|
.datepicker table tr td.today.disabled.disabled,
|
||||||
|
.datepicker table tr td.today.disabled:hover.disabled,
|
||||||
|
.datepicker table tr td.today[disabled],
|
||||||
|
.datepicker table tr td.today:hover[disabled],
|
||||||
|
.datepicker table tr td.today.disabled[disabled],
|
||||||
|
.datepicker table tr td.today.disabled:hover[disabled] {
|
||||||
|
background-color: #fdf59a;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.today:active,
|
||||||
|
.datepicker table tr td.today:hover:active,
|
||||||
|
.datepicker table tr td.today.disabled:active,
|
||||||
|
.datepicker table tr td.today.disabled:hover:active,
|
||||||
|
.datepicker table tr td.today.active,
|
||||||
|
.datepicker table tr td.today:hover.active,
|
||||||
|
.datepicker table tr td.today.disabled.active,
|
||||||
|
.datepicker table tr td.today.disabled:hover.active {
|
||||||
|
background-color: #fbf069 \9;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.today:hover:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.today.active:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.range,
|
||||||
|
.datepicker table tr td.range:hover,
|
||||||
|
.datepicker table tr td.range.disabled,
|
||||||
|
.datepicker table tr td.range.disabled:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.range.today,
|
||||||
|
.datepicker table tr td.range.today:hover,
|
||||||
|
.datepicker table tr td.range.today.disabled,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover {
|
||||||
|
background-color: #f3d17a;
|
||||||
|
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
|
||||||
|
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
|
||||||
|
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
|
||||||
|
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
|
||||||
|
background-image: linear-gradient(top, #f3c17a, #f3e97a);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
|
||||||
|
border-color: #f3e97a #f3e97a #edde34;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.range.today:hover,
|
||||||
|
.datepicker table tr td.range.today:hover:hover,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover:hover,
|
||||||
|
.datepicker table tr td.range.today:active,
|
||||||
|
.datepicker table tr td.range.today:hover:active,
|
||||||
|
.datepicker table tr td.range.today.disabled:active,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover:active,
|
||||||
|
.datepicker table tr td.range.today.active,
|
||||||
|
.datepicker table tr td.range.today:hover.active,
|
||||||
|
.datepicker table tr td.range.today.disabled.active,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover.active,
|
||||||
|
.datepicker table tr td.range.today.disabled,
|
||||||
|
.datepicker table tr td.range.today:hover.disabled,
|
||||||
|
.datepicker table tr td.range.today.disabled.disabled,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover.disabled,
|
||||||
|
.datepicker table tr td.range.today[disabled],
|
||||||
|
.datepicker table tr td.range.today:hover[disabled],
|
||||||
|
.datepicker table tr td.range.today.disabled[disabled],
|
||||||
|
.datepicker table tr td.range.today.disabled:hover[disabled] {
|
||||||
|
background-color: #f3e97a;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.range.today:active,
|
||||||
|
.datepicker table tr td.range.today:hover:active,
|
||||||
|
.datepicker table tr td.range.today.disabled:active,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover:active,
|
||||||
|
.datepicker table tr td.range.today.active,
|
||||||
|
.datepicker table tr td.range.today:hover.active,
|
||||||
|
.datepicker table tr td.range.today.disabled.active,
|
||||||
|
.datepicker table tr td.range.today.disabled:hover.active {
|
||||||
|
background-color: #efe24b \9;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.selected,
|
||||||
|
.datepicker table tr td.selected:hover,
|
||||||
|
.datepicker table tr td.selected.disabled,
|
||||||
|
.datepicker table tr td.selected.disabled:hover {
|
||||||
|
background-color: #9e9e9e;
|
||||||
|
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
|
||||||
|
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
|
||||||
|
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
|
||||||
|
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
|
||||||
|
background-image: linear-gradient(top, #b3b3b3, #808080);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
|
||||||
|
border-color: #808080 #808080 #595959;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
.datepicker table tr td.selected:hover,
|
||||||
|
.datepicker table tr td.selected:hover:hover,
|
||||||
|
.datepicker table tr td.selected.disabled:hover,
|
||||||
|
.datepicker table tr td.selected.disabled:hover:hover,
|
||||||
|
.datepicker table tr td.selected:active,
|
||||||
|
.datepicker table tr td.selected:hover:active,
|
||||||
|
.datepicker table tr td.selected.disabled:active,
|
||||||
|
.datepicker table tr td.selected.disabled:hover:active,
|
||||||
|
.datepicker table tr td.selected.active,
|
||||||
|
.datepicker table tr td.selected:hover.active,
|
||||||
|
.datepicker table tr td.selected.disabled.active,
|
||||||
|
.datepicker table tr td.selected.disabled:hover.active,
|
||||||
|
.datepicker table tr td.selected.disabled,
|
||||||
|
.datepicker table tr td.selected:hover.disabled,
|
||||||
|
.datepicker table tr td.selected.disabled.disabled,
|
||||||
|
.datepicker table tr td.selected.disabled:hover.disabled,
|
||||||
|
.datepicker table tr td.selected[disabled],
|
||||||
|
.datepicker table tr td.selected:hover[disabled],
|
||||||
|
.datepicker table tr td.selected.disabled[disabled],
|
||||||
|
.datepicker table tr td.selected.disabled:hover[disabled] {
|
||||||
|
background-color: #808080;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.selected:active,
|
||||||
|
.datepicker table tr td.selected:hover:active,
|
||||||
|
.datepicker table tr td.selected.disabled:active,
|
||||||
|
.datepicker table tr td.selected.disabled:hover:active,
|
||||||
|
.datepicker table tr td.selected.active,
|
||||||
|
.datepicker table tr td.selected:hover.active,
|
||||||
|
.datepicker table tr td.selected.disabled.active,
|
||||||
|
.datepicker table tr td.selected.disabled:hover.active {
|
||||||
|
background-color: #666666 \9;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.active,
|
||||||
|
.datepicker table tr td.active:hover,
|
||||||
|
.datepicker table tr td.active.disabled,
|
||||||
|
.datepicker table tr td.active.disabled:hover {
|
||||||
|
background-color: #006dcc;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||||
|
border-color: #0044cc #0044cc #002a80;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
.datepicker table tr td.active:hover,
|
||||||
|
.datepicker table tr td.active:hover:hover,
|
||||||
|
.datepicker table tr td.active.disabled:hover,
|
||||||
|
.datepicker table tr td.active.disabled:hover:hover,
|
||||||
|
.datepicker table tr td.active:active,
|
||||||
|
.datepicker table tr td.active:hover:active,
|
||||||
|
.datepicker table tr td.active.disabled:active,
|
||||||
|
.datepicker table tr td.active.disabled:hover:active,
|
||||||
|
.datepicker table tr td.active.active,
|
||||||
|
.datepicker table tr td.active:hover.active,
|
||||||
|
.datepicker table tr td.active.disabled.active,
|
||||||
|
.datepicker table tr td.active.disabled:hover.active,
|
||||||
|
.datepicker table tr td.active.disabled,
|
||||||
|
.datepicker table tr td.active:hover.disabled,
|
||||||
|
.datepicker table tr td.active.disabled.disabled,
|
||||||
|
.datepicker table tr td.active.disabled:hover.disabled,
|
||||||
|
.datepicker table tr td.active[disabled],
|
||||||
|
.datepicker table tr td.active:hover[disabled],
|
||||||
|
.datepicker table tr td.active.disabled[disabled],
|
||||||
|
.datepicker table tr td.active.disabled:hover[disabled] {
|
||||||
|
background-color: #0044cc;
|
||||||
|
}
|
||||||
|
.datepicker table tr td.active:active,
|
||||||
|
.datepicker table tr td.active:hover:active,
|
||||||
|
.datepicker table tr td.active.disabled:active,
|
||||||
|
.datepicker table tr td.active.disabled:hover:active,
|
||||||
|
.datepicker table tr td.active.active,
|
||||||
|
.datepicker table tr td.active:hover.active,
|
||||||
|
.datepicker table tr td.active.disabled.active,
|
||||||
|
.datepicker table tr td.active.disabled:hover.active {
|
||||||
|
background-color: #003399 \9;
|
||||||
|
}
|
||||||
|
.datepicker table tr td span {
|
||||||
|
display: block;
|
||||||
|
width: 23%;
|
||||||
|
height: 54px;
|
||||||
|
line-height: 54px;
|
||||||
|
float: left;
|
||||||
|
margin: 1%;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.datepicker table tr td span:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
.datepicker table tr td span.disabled,
|
||||||
|
.datepicker table tr td span.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.datepicker table tr td span.active,
|
||||||
|
.datepicker table tr td span.active:hover,
|
||||||
|
.datepicker table tr td span.active.disabled,
|
||||||
|
.datepicker table tr td span.active.disabled:hover {
|
||||||
|
background-color: #006dcc;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||||
|
border-color: #0044cc #0044cc #002a80;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
.datepicker table tr td span.active:hover,
|
||||||
|
.datepicker table tr td span.active:hover:hover,
|
||||||
|
.datepicker table tr td span.active.disabled:hover,
|
||||||
|
.datepicker table tr td span.active.disabled:hover:hover,
|
||||||
|
.datepicker table tr td span.active:active,
|
||||||
|
.datepicker table tr td span.active:hover:active,
|
||||||
|
.datepicker table tr td span.active.disabled:active,
|
||||||
|
.datepicker table tr td span.active.disabled:hover:active,
|
||||||
|
.datepicker table tr td span.active.active,
|
||||||
|
.datepicker table tr td span.active:hover.active,
|
||||||
|
.datepicker table tr td span.active.disabled.active,
|
||||||
|
.datepicker table tr td span.active.disabled:hover.active,
|
||||||
|
.datepicker table tr td span.active.disabled,
|
||||||
|
.datepicker table tr td span.active:hover.disabled,
|
||||||
|
.datepicker table tr td span.active.disabled.disabled,
|
||||||
|
.datepicker table tr td span.active.disabled:hover.disabled,
|
||||||
|
.datepicker table tr td span.active[disabled],
|
||||||
|
.datepicker table tr td span.active:hover[disabled],
|
||||||
|
.datepicker table tr td span.active.disabled[disabled],
|
||||||
|
.datepicker table tr td span.active.disabled:hover[disabled] {
|
||||||
|
background-color: #0044cc;
|
||||||
|
}
|
||||||
|
.datepicker table tr td span.active:active,
|
||||||
|
.datepicker table tr td span.active:hover:active,
|
||||||
|
.datepicker table tr td span.active.disabled:active,
|
||||||
|
.datepicker table tr td span.active.disabled:hover:active,
|
||||||
|
.datepicker table tr td span.active.active,
|
||||||
|
.datepicker table tr td span.active:hover.active,
|
||||||
|
.datepicker table tr td span.active.disabled.active,
|
||||||
|
.datepicker table tr td span.active.disabled:hover.active {
|
||||||
|
background-color: #003399 \9;
|
||||||
|
}
|
||||||
|
.datepicker table tr td span.old,
|
||||||
|
.datepicker table tr td span.new {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.datepicker th.datepicker-switch {
|
||||||
|
width: 145px;
|
||||||
|
}
|
||||||
|
.datepicker thead tr:first-child th,
|
||||||
|
.datepicker tfoot tr th {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.datepicker thead tr:first-child th:hover,
|
||||||
|
.datepicker tfoot tr th:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
.datepicker .cw {
|
||||||
|
font-size: 10px;
|
||||||
|
width: 12px;
|
||||||
|
padding: 0 2px 0 5px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.datepicker thead tr:first-child th.cw {
|
||||||
|
cursor: default;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.input-append.date .add-on i,
|
||||||
|
.input-prepend.date .add-on i {
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
.input-daterange input {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.input-daterange input:first-child {
|
||||||
|
-webkit-border-radius: 3px 0 0 3px;
|
||||||
|
-moz-border-radius: 3px 0 0 3px;
|
||||||
|
border-radius: 3px 0 0 3px;
|
||||||
|
}
|
||||||
|
.input-daterange input:last-child {
|
||||||
|
-webkit-border-radius: 0 3px 3px 0;
|
||||||
|
-moz-border-radius: 0 3px 3px 0;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
}
|
||||||
|
.input-daterange .add-on {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
min-width: 16px;
|
||||||
|
height: 18px;
|
||||||
|
padding: 4px 5px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 0 1px 0 #ffffff;
|
||||||
|
vertical-align: middle;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin-left: -5px;
|
||||||
|
margin-right: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
=========================================================
|
=========================================================
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -39766,555 +39766,6 @@ module.exports = (function() {
|
|||||||
},{}]},{},[1])
|
},{}]},{},[1])
|
||||||
(1)
|
(1)
|
||||||
});
|
});
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// This file is part of Leaflet.Geodesic.
|
|
||||||
// Copyright (C) 2017 Henry Thasler
|
|
||||||
// based on code by Chris Veness Copyright (C) 2014 https://github.com/chrisveness/geodesy
|
|
||||||
//
|
|
||||||
// Leaflet.Geodesic is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Leaflet.Geodesic is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Leaflet.Geodesic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Extend Number object with method to convert numeric degrees to radians */
|
|
||||||
if (typeof Number.prototype.toRadians === "undefined") {
|
|
||||||
Number.prototype.toRadians = function() {
|
|
||||||
return this * Math.PI / 180
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Extend Number object with method to convert radians to numeric (signed) degrees */
|
|
||||||
if (typeof Number.prototype.toDegrees === "undefined") {
|
|
||||||
Number.prototype.toDegrees = function() {
|
|
||||||
return this * 180 / Math.PI
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const INTERSECT_LNG = 179.999 // Lng used for intersection and wrap around on map edges
|
|
||||||
|
|
||||||
L.Geodesic = L.Polyline.extend({
|
|
||||||
options: {
|
|
||||||
color: "blue",
|
|
||||||
steps: 10,
|
|
||||||
dash: 1,
|
|
||||||
wrap: true
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function(latlngs, options) {
|
|
||||||
this.options = this._merge_options(this.options, options)
|
|
||||||
this.datum = {}
|
|
||||||
this.datum.ellipsoid = {
|
|
||||||
a: 6378137,
|
|
||||||
b: 6356752.3142,
|
|
||||||
f: 1 / 298.257223563
|
|
||||||
} // WGS-84
|
|
||||||
this._latlngs = (this.options.dash < 1) ? this._generate_GeodesicDashed(
|
|
||||||
latlngs) : this._generate_Geodesic(latlngs)
|
|
||||||
L.Polyline.prototype.initialize.call(this, this._latlngs, this.options)
|
|
||||||
},
|
|
||||||
|
|
||||||
setLatLngs: function(latlngs) {
|
|
||||||
this._latlngs = (this.options.dash < 1) ? this._generate_GeodesicDashed(
|
|
||||||
latlngs) : this._generate_Geodesic(latlngs)
|
|
||||||
L.Polyline.prototype.setLatLngs.call(this, this._latlngs)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates some statistic values of current geodesic multipolyline
|
|
||||||
* @returns (Object} Object with several properties (e.g. overall distance)
|
|
||||||
*/
|
|
||||||
getStats: function() {
|
|
||||||
let obj = {
|
|
||||||
distance: 0,
|
|
||||||
points: 0,
|
|
||||||
polygons: this._latlngs.length
|
|
||||||
},
|
|
||||||
poly, points
|
|
||||||
|
|
||||||
for (poly = 0; poly < this._latlngs.length; poly++) {
|
|
||||||
obj.points += this._latlngs[poly].length
|
|
||||||
for (points = 0; points < (this._latlngs[poly].length - 1); points++) {
|
|
||||||
obj.distance += this._vincenty_inverse(this._latlngs[poly][points],
|
|
||||||
this._latlngs[poly][points + 1]).distance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates geodesic lines from geoJson. Replaces all current features of this instance.
|
|
||||||
* Supports LineString, MultiLineString and Polygon
|
|
||||||
* @param {Object} geojson - geosjon as object.
|
|
||||||
*/
|
|
||||||
geoJson: function(geojson) {
|
|
||||||
|
|
||||||
let normalized = L.GeoJSON.asFeature(geojson)
|
|
||||||
let features = normalized.type === "FeatureCollection" ? normalized.features : [
|
|
||||||
normalized
|
|
||||||
]
|
|
||||||
this._latlngs = []
|
|
||||||
for (let feature of features) {
|
|
||||||
let geometry = feature.type === "Feature" ? feature.geometry :
|
|
||||||
feature,
|
|
||||||
coords = geometry.coordinates
|
|
||||||
|
|
||||||
switch (geometry.type) {
|
|
||||||
case "LineString":
|
|
||||||
this._latlngs.push(this._generate_Geodesic([L.GeoJSON.coordsToLatLngs(
|
|
||||||
coords, 0)]))
|
|
||||||
break
|
|
||||||
case "MultiLineString":
|
|
||||||
case "Polygon":
|
|
||||||
this._latlngs.push(this._generate_Geodesic(L.GeoJSON.coordsToLatLngs(
|
|
||||||
coords, 1)))
|
|
||||||
break
|
|
||||||
case "Point":
|
|
||||||
case "MultiPoint":
|
|
||||||
console.log("Dude, points can't be drawn as geodesic lines...")
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
console.log("Drawing " + geometry.type +
|
|
||||||
" as a geodesic is not supported. Skipping...")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
L.Polyline.prototype.setLatLngs.call(this, this._latlngs)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a great circle. Replaces all current lines.
|
|
||||||
* @param {Object} center - geographic position
|
|
||||||
* @param {number} radius - radius of the circle in metres
|
|
||||||
*/
|
|
||||||
createCircle: function(center, radius) {
|
|
||||||
let polylineIndex = 0
|
|
||||||
let prev = {
|
|
||||||
lat: 0,
|
|
||||||
lng: 0,
|
|
||||||
brg: 0
|
|
||||||
}
|
|
||||||
let step
|
|
||||||
|
|
||||||
this._latlngs = []
|
|
||||||
this._latlngs[polylineIndex] = []
|
|
||||||
|
|
||||||
let direct = this._vincenty_direct(L.latLng(center), 0, radius, this.options
|
|
||||||
.wrap)
|
|
||||||
prev = L.latLng(direct.lat, direct.lng)
|
|
||||||
this._latlngs[polylineIndex].push(prev)
|
|
||||||
for (step = 1; step <= this.options.steps;) {
|
|
||||||
direct = this._vincenty_direct(L.latLng(center), 360 / this.options
|
|
||||||
.steps * step, radius, this.options.wrap)
|
|
||||||
let gp = L.latLng(direct.lat, direct.lng)
|
|
||||||
if (Math.abs(gp.lng - prev.lng) > 180) {
|
|
||||||
let inverse = this._vincenty_inverse(prev, gp)
|
|
||||||
let sec = this._intersection(prev, inverse.initialBearing, {
|
|
||||||
lat: -89,
|
|
||||||
lng: ((gp.lng - prev.lng) > 0) ? -INTERSECT_LNG : INTERSECT_LNG
|
|
||||||
}, 0)
|
|
||||||
if (sec) {
|
|
||||||
this._latlngs[polylineIndex].push(L.latLng(sec.lat, sec.lng))
|
|
||||||
polylineIndex++
|
|
||||||
this._latlngs[polylineIndex] = []
|
|
||||||
prev = L.latLng(sec.lat, -sec.lng)
|
|
||||||
this._latlngs[polylineIndex].push(prev)
|
|
||||||
} else {
|
|
||||||
polylineIndex++
|
|
||||||
this._latlngs[polylineIndex] = []
|
|
||||||
this._latlngs[polylineIndex].push(gp)
|
|
||||||
prev = gp
|
|
||||||
step++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._latlngs[polylineIndex].push(gp)
|
|
||||||
prev = gp
|
|
||||||
step++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
L.Polyline.prototype.setLatLngs.call(this, this._latlngs)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a geodesic Polyline from given coordinates
|
|
||||||
* @param {Object} latlngs - One or more polylines as an array. See Leaflet doc about Polyline
|
|
||||||
* @returns (Object} An array of arrays of geographical points.
|
|
||||||
*/
|
|
||||||
_generate_Geodesic: function(latlngs) {
|
|
||||||
let _geo = [],
|
|
||||||
_geocnt = 0,
|
|
||||||
s, poly, points, pointA, pointB
|
|
||||||
|
|
||||||
for (poly = 0; poly < latlngs.length; poly++) {
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
for (points = 0; points < (latlngs[poly].length - 1); points++) {
|
|
||||||
pointA = L.latLng(latlngs[poly][points])
|
|
||||||
pointB = L.latLng(latlngs[poly][points + 1])
|
|
||||||
if (pointA.equals(pointB)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let inverse = this._vincenty_inverse(pointA, pointB)
|
|
||||||
let prev = pointA
|
|
||||||
_geo[_geocnt].push(prev)
|
|
||||||
for (s = 1; s <= this.options.steps;) {
|
|
||||||
let direct = this._vincenty_direct(pointA, inverse.initialBearing,
|
|
||||||
inverse.distance / this.options.steps * s, this.options.wrap
|
|
||||||
)
|
|
||||||
let gp = L.latLng(direct.lat, direct.lng)
|
|
||||||
if (Math.abs(gp.lng - prev.lng) > 180) {
|
|
||||||
let sec = this._intersection(pointA, inverse.initialBearing, {
|
|
||||||
lat: -89,
|
|
||||||
lng: ((gp.lng - prev.lng) > 0) ? -INTERSECT_LNG : INTERSECT_LNG
|
|
||||||
}, 0)
|
|
||||||
if (sec) {
|
|
||||||
_geo[_geocnt].push(L.latLng(sec.lat, sec.lng))
|
|
||||||
_geocnt++
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
prev = L.latLng(sec.lat, -sec.lng)
|
|
||||||
_geo[_geocnt].push(prev)
|
|
||||||
} else {
|
|
||||||
_geocnt++
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
_geo[_geocnt].push(gp)
|
|
||||||
prev = gp
|
|
||||||
s++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_geo[_geocnt].push(gp)
|
|
||||||
prev = gp
|
|
||||||
s++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_geocnt++
|
|
||||||
}
|
|
||||||
return _geo
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a dashed geodesic Polyline from given coordinates - under work
|
|
||||||
* @param {Object} latlngs - One or more polylines as an array. See Leaflet doc about Polyline
|
|
||||||
* @returns (Object} An array of arrays of geographical points.
|
|
||||||
*/
|
|
||||||
_generate_GeodesicDashed: function(latlngs) {
|
|
||||||
let _geo = [],
|
|
||||||
_geocnt = 0,
|
|
||||||
s, poly, points
|
|
||||||
// _geo = latlngs; // bypass
|
|
||||||
|
|
||||||
for (poly = 0; poly < latlngs.length; poly++) {
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
for (points = 0; points < (latlngs[poly].length - 1); points++) {
|
|
||||||
let inverse = this._vincenty_inverse(L.latLng(latlngs[poly][
|
|
||||||
points
|
|
||||||
]), L.latLng(latlngs[poly][points + 1]))
|
|
||||||
let prev = L.latLng(latlngs[poly][points])
|
|
||||||
_geo[_geocnt].push(prev)
|
|
||||||
for (s = 1; s <= this.options.steps;) {
|
|
||||||
let direct = this._vincenty_direct(L.latLng(latlngs[poly][
|
|
||||||
points
|
|
||||||
]), inverse.initialBearing, inverse.distance / this.options
|
|
||||||
.steps * s - inverse.distance / this.options.steps * (1 -
|
|
||||||
this.options.dash), this.options.wrap)
|
|
||||||
let gp = L.latLng(direct.lat, direct.lng)
|
|
||||||
if (Math.abs(gp.lng - prev.lng) > 180) {
|
|
||||||
let sec = this._intersection(L.latLng(latlngs[poly][points]),
|
|
||||||
inverse.initialBearing, {
|
|
||||||
lat: -89,
|
|
||||||
lng: ((gp.lng - prev.lng) > 0) ? -INTERSECT_LNG : INTERSECT_LNG
|
|
||||||
}, 0)
|
|
||||||
if (sec) {
|
|
||||||
_geo[_geocnt].push(L.latLng(sec.lat, sec.lng))
|
|
||||||
_geocnt++
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
prev = L.latLng(sec.lat, -sec.lng)
|
|
||||||
_geo[_geocnt].push(prev)
|
|
||||||
} else {
|
|
||||||
_geocnt++
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
_geo[_geocnt].push(gp)
|
|
||||||
prev = gp
|
|
||||||
s++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_geo[_geocnt].push(gp)
|
|
||||||
_geocnt++
|
|
||||||
let direct2 = this._vincenty_direct(L.latLng(latlngs[poly][
|
|
||||||
points
|
|
||||||
]), inverse.initialBearing, inverse.distance / this.options
|
|
||||||
.steps * s, this.options.wrap)
|
|
||||||
_geo[_geocnt] = []
|
|
||||||
_geo[_geocnt].push(L.latLng(direct2.lat, direct2.lng))
|
|
||||||
s++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_geocnt++
|
|
||||||
}
|
|
||||||
return _geo
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vincenty direct calculation.
|
|
||||||
* based on the work of Chris Veness (https://github.com/chrisveness/geodesy)
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {number} initialBearing - Initial bearing in degrees from north.
|
|
||||||
* @param {number} distance - Distance along bearing in metres.
|
|
||||||
* @returns (Object} Object including point (destination point), finalBearing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_vincenty_direct: function(p1, initialBearing, distance, wrap) {
|
|
||||||
var φ1 = p1.lat.toRadians(),
|
|
||||||
λ1 = p1.lng.toRadians();
|
|
||||||
var α1 = initialBearing.toRadians();
|
|
||||||
var s = distance;
|
|
||||||
|
|
||||||
var a = this.datum.ellipsoid.a,
|
|
||||||
b = this.datum.ellipsoid.b,
|
|
||||||
f = this.datum.ellipsoid.f;
|
|
||||||
|
|
||||||
var sinα1 = Math.sin(α1);
|
|
||||||
var cosα1 = Math.cos(α1);
|
|
||||||
|
|
||||||
var tanU1 = (1 - f) * Math.tan(φ1),
|
|
||||||
cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)),
|
|
||||||
sinU1 = tanU1 * cosU1;
|
|
||||||
var σ1 = Math.atan2(tanU1, cosα1);
|
|
||||||
var sinα = cosU1 * sinα1;
|
|
||||||
var cosSqα = 1 - sinα * sinα;
|
|
||||||
var uSq = cosSqα * (a * a - b * b) / (b * b);
|
|
||||||
var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 *
|
|
||||||
uSq)));
|
|
||||||
var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
||||||
|
|
||||||
var σ = s / (b * A),
|
|
||||||
σʹ, iterations = 0;
|
|
||||||
do {
|
|
||||||
var cos2σM = Math.cos(2 * σ1 + σ);
|
|
||||||
var sinσ = Math.sin(σ);
|
|
||||||
var cosσ = Math.cos(σ);
|
|
||||||
var Δσ = B * sinσ * (cos2σM + B / 4 * (cosσ * (-1 + 2 * cos2σM *
|
|
||||||
cos2σM) -
|
|
||||||
B / 6 * cos2σM * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σM *
|
|
||||||
cos2σM)));
|
|
||||||
σʹ = σ;
|
|
||||||
σ = s / (b * A) + Δσ;
|
|
||||||
} while (Math.abs(σ - σʹ) > 1e-12 && ++iterations);
|
|
||||||
|
|
||||||
var x = sinU1 * sinσ - cosU1 * cosσ * cosα1;
|
|
||||||
var φ2 = Math.atan2(sinU1 * cosσ + cosU1 * sinσ * cosα1, (1 - f) *
|
|
||||||
Math.sqrt(sinα * sinα + x * x));
|
|
||||||
var λ = Math.atan2(sinσ * sinα1, cosU1 * cosσ - sinU1 * sinσ * cosα1);
|
|
||||||
var C = f / 16 * cosSqα * (4 + f * (4 - 3 * cosSqα));
|
|
||||||
var L = λ - (1 - C) * f * sinα *
|
|
||||||
(σ + C * sinσ * (cos2σM + C * cosσ * (-1 + 2 * cos2σM * cos2σM)));
|
|
||||||
|
|
||||||
if (wrap)
|
|
||||||
var λ2 = (λ1 + L + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // normalise to -180...+180
|
|
||||||
else
|
|
||||||
var λ2 = (λ1 + L); // do not normalize
|
|
||||||
|
|
||||||
var revAz = Math.atan2(sinα, -x);
|
|
||||||
|
|
||||||
return {
|
|
||||||
lat: φ2.toDegrees(),
|
|
||||||
lng: λ2.toDegrees(),
|
|
||||||
finalBearing: revAz.toDegrees()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vincenty inverse calculation.
|
|
||||||
* based on the work of Chris Veness (https://github.com/chrisveness/geodesy)
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {LatLng} p1 - Latitude/longitude of start point.
|
|
||||||
* @param {LatLng} p2 - Latitude/longitude of destination point.
|
|
||||||
* @returns {Object} Object including distance, initialBearing, finalBearing.
|
|
||||||
* @throws {Error} If formula failed to converge.
|
|
||||||
*/
|
|
||||||
_vincenty_inverse: function(p1, p2) {
|
|
||||||
var φ1 = p1.lat.toRadians(),
|
|
||||||
λ1 = p1.lng.toRadians();
|
|
||||||
var φ2 = p2.lat.toRadians(),
|
|
||||||
λ2 = p2.lng.toRadians();
|
|
||||||
|
|
||||||
var a = this.datum.ellipsoid.a,
|
|
||||||
b = this.datum.ellipsoid.b,
|
|
||||||
f = this.datum.ellipsoid.f;
|
|
||||||
|
|
||||||
var L = λ2 - λ1;
|
|
||||||
var tanU1 = (1 - f) * Math.tan(φ1),
|
|
||||||
cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)),
|
|
||||||
sinU1 = tanU1 * cosU1;
|
|
||||||
var tanU2 = (1 - f) * Math.tan(φ2),
|
|
||||||
cosU2 = 1 / Math.sqrt((1 + tanU2 * tanU2)),
|
|
||||||
sinU2 = tanU2 * cosU2;
|
|
||||||
|
|
||||||
var λ = L,
|
|
||||||
λʹ, iterations = 0;
|
|
||||||
do {
|
|
||||||
var sinλ = Math.sin(λ),
|
|
||||||
cosλ = Math.cos(λ);
|
|
||||||
var sinSqσ = (cosU2 * sinλ) * (cosU2 * sinλ) + (cosU1 * sinU2 -
|
|
||||||
sinU1 * cosU2 * cosλ) * (cosU1 * sinU2 - sinU1 * cosU2 * cosλ);
|
|
||||||
var sinσ = Math.sqrt(sinSqσ);
|
|
||||||
if (sinσ == 0) return 0; // co-incident points
|
|
||||||
var cosσ = sinU1 * sinU2 + cosU1 * cosU2 * cosλ;
|
|
||||||
var σ = Math.atan2(sinσ, cosσ);
|
|
||||||
var sinα = cosU1 * cosU2 * sinλ / sinσ;
|
|
||||||
var cosSqα = 1 - sinα * sinα;
|
|
||||||
var cos2σM = cosσ - 2 * sinU1 * sinU2 / cosSqα;
|
|
||||||
if (isNaN(cos2σM)) cos2σM = 0; // equatorial line: cosSqα=0 (§6)
|
|
||||||
var C = f / 16 * cosSqα * (4 + f * (4 - 3 * cosSqα));
|
|
||||||
λʹ = λ;
|
|
||||||
λ = L + (1 - C) * f * sinα * (σ + C * sinσ * (cos2σM + C * cosσ * (-
|
|
||||||
1 + 2 * cos2σM * cos2σM)));
|
|
||||||
} while (Math.abs(λ - λʹ) > 1e-12 && ++iterations < 100);
|
|
||||||
if (iterations >= 100) {
|
|
||||||
console.log("Formula failed to converge. Altering target position.")
|
|
||||||
return this._vincenty_inverse(p1, {
|
|
||||||
lat: p2.lat,
|
|
||||||
lng: p2.lng - 0.01
|
|
||||||
})
|
|
||||||
// throw new Error('Formula failed to converge');
|
|
||||||
}
|
|
||||||
|
|
||||||
var uSq = cosSqα * (a * a - b * b) / (b * b);
|
|
||||||
var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 *
|
|
||||||
uSq)));
|
|
||||||
var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
||||||
var Δσ = B * sinσ * (cos2σM + B / 4 * (cosσ * (-1 + 2 * cos2σM *
|
|
||||||
cos2σM) -
|
|
||||||
B / 6 * cos2σM * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σM *
|
|
||||||
cos2σM)));
|
|
||||||
|
|
||||||
var s = b * A * (σ - Δσ);
|
|
||||||
|
|
||||||
var fwdAz = Math.atan2(cosU2 * sinλ, cosU1 * sinU2 - sinU1 * cosU2 *
|
|
||||||
cosλ);
|
|
||||||
var revAz = Math.atan2(cosU1 * sinλ, -sinU1 * cosU2 + cosU1 * sinU2 *
|
|
||||||
cosλ);
|
|
||||||
|
|
||||||
s = Number(s.toFixed(3)); // round to 1mm precision
|
|
||||||
return {
|
|
||||||
distance: s,
|
|
||||||
initialBearing: fwdAz.toDegrees(),
|
|
||||||
finalBearing: revAz.toDegrees()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the point of intersection of two paths defined by point and bearing.
|
|
||||||
* based on the work of Chris Veness (https://github.com/chrisveness/geodesy)
|
|
||||||
*
|
|
||||||
* @param {LatLon} p1 - First point.
|
|
||||||
* @param {number} brng1 - Initial bearing from first point.
|
|
||||||
* @param {LatLon} p2 - Second point.
|
|
||||||
* @param {number} brng2 - Initial bearing from second point.
|
|
||||||
* @returns {Object} containing lat/lng information of intersection.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* var p1 = LatLon(51.8853, 0.2545), brng1 = 108.55;
|
|
||||||
* var p2 = LatLon(49.0034, 2.5735), brng2 = 32.44;
|
|
||||||
* var pInt = LatLon.intersection(p1, brng1, p2, brng2); // pInt.toString(): 50.9078°N, 4.5084°E
|
|
||||||
*/
|
|
||||||
_intersection: function(p1, brng1, p2, brng2) {
|
|
||||||
// see http://williams.best.vwh.net/avform.htm#Intersection
|
|
||||||
|
|
||||||
var φ1 = p1.lat.toRadians(),
|
|
||||||
λ1 = p1.lng.toRadians();
|
|
||||||
var φ2 = p2.lat.toRadians(),
|
|
||||||
λ2 = p2.lng.toRadians();
|
|
||||||
var θ13 = Number(brng1).toRadians(),
|
|
||||||
θ23 = Number(brng2).toRadians();
|
|
||||||
var Δφ = φ2 - φ1,
|
|
||||||
Δλ = λ2 - λ1;
|
|
||||||
|
|
||||||
var δ12 = 2 * Math.asin(Math.sqrt(Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
|
|
||||||
Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ /
|
|
||||||
2)));
|
|
||||||
if (δ12 == 0) return null;
|
|
||||||
|
|
||||||
// initial/final bearings between points
|
|
||||||
var θ1 = Math.acos((Math.sin(φ2) - Math.sin(φ1) * Math.cos(δ12)) /
|
|
||||||
(Math.sin(δ12) * Math.cos(φ1)));
|
|
||||||
if (isNaN(θ1)) θ1 = 0; // protect against rounding
|
|
||||||
var θ2 = Math.acos((Math.sin(φ1) - Math.sin(φ2) * Math.cos(δ12)) /
|
|
||||||
(Math.sin(δ12) * Math.cos(φ2)));
|
|
||||||
|
|
||||||
if (Math.sin(λ2 - λ1) > 0) {
|
|
||||||
var θ12 = θ1;
|
|
||||||
var θ21 = 2 * Math.PI - θ2;
|
|
||||||
} else {
|
|
||||||
var θ12 = 2 * Math.PI - θ1;
|
|
||||||
var θ21 = θ2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var α1 = (θ13 - θ12 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 2-1-3
|
|
||||||
var α2 = (θ21 - θ23 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 1-2-3
|
|
||||||
|
|
||||||
if (Math.sin(α1) == 0 && Math.sin(α2) == 0) return null; // infinite intersections
|
|
||||||
if (Math.sin(α1) * Math.sin(α2) < 0) return null; // ambiguous intersection
|
|
||||||
|
|
||||||
//α1 = Math.abs(α1);
|
|
||||||
//α2 = Math.abs(α2);
|
|
||||||
// ... Ed Williams takes abs of α1/α2, but seems to break calculation?
|
|
||||||
|
|
||||||
var α3 = Math.acos(-Math.cos(α1) * Math.cos(α2) +
|
|
||||||
Math.sin(α1) * Math.sin(α2) * Math.cos(δ12));
|
|
||||||
var δ13 = Math.atan2(Math.sin(δ12) * Math.sin(α1) * Math.sin(α2),
|
|
||||||
Math.cos(α2) + Math.cos(α1) * Math.cos(α3))
|
|
||||||
var φ3 = Math.asin(Math.sin(φ1) * Math.cos(δ13) +
|
|
||||||
Math.cos(φ1) * Math.sin(δ13) * Math.cos(θ13));
|
|
||||||
var Δλ13 = Math.atan2(Math.sin(θ13) * Math.sin(δ13) * Math.cos(φ1),
|
|
||||||
Math.cos(δ13) - Math.sin(φ1) * Math.sin(φ3));
|
|
||||||
var λ3 = λ1 + Δλ13;
|
|
||||||
λ3 = (λ3 + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // normalise to -180..+180º
|
|
||||||
|
|
||||||
return {
|
|
||||||
lat: φ3.toDegrees(),
|
|
||||||
lng: λ3.toDegrees()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
|
|
||||||
* @param obj1
|
|
||||||
* @param obj2
|
|
||||||
* @returns obj3 a new object based on obj1 and obj2
|
|
||||||
*/
|
|
||||||
_merge_options: function(obj1, obj2) {
|
|
||||||
let obj3 = {};
|
|
||||||
for (let attrname in obj1) {
|
|
||||||
obj3[attrname] = obj1[attrname];
|
|
||||||
}
|
|
||||||
for (let attrname in obj2) {
|
|
||||||
obj3[attrname] = obj2[attrname];
|
|
||||||
}
|
|
||||||
return obj3;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.geodesic = function(latlngs, options) {
|
|
||||||
return new L.Geodesic(latlngs, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
// save these original methods before they are overwritten
|
// save these original methods before they are overwritten
|
||||||
var proto_initIcon = L.Marker.prototype._initIcon;
|
var proto_initIcon = L.Marker.prototype._initIcon;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"/assets/admin/vendor/paper-dashboard.css": "/assets/admin/vendor/paper-dashboard.css?id=729efec551211db36219",
|
"/assets/admin/vendor/paper-dashboard.css": "/assets/admin/vendor/paper-dashboard.css?id=729efec551211db36219",
|
||||||
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=58ec3dc768f07fee143a",
|
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=58ec3dc768f07fee143a",
|
||||||
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=152f2c5d0bcfff37513a",
|
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=66957049f4a01c51c68d",
|
||||||
"/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=aa3c49b31b83782ed27d",
|
"/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=eb27f6c829378a084072",
|
||||||
"/assets/system/js/vendor.js": "/assets/system/js/vendor.js?id=022e73793e29fb2c6825",
|
"/assets/system/js/vendor.js": "/assets/system/js/vendor.js?id=434db3f2c9beafd58bae",
|
||||||
"/assets/system/css/vendor.css": "/assets/system/css/vendor.css?id=7bd98a28084fea99e307",
|
"/assets/system/css/vendor.css": "/assets/system/css/vendor.css?id=7bd98a28084fea99e307",
|
||||||
"/assets/system/js/installer-vendor.js": "/assets/system/js/installer-vendor.js?id=b2bca761f222e97bf4ff"
|
"/assets/system/js/installer-vendor.js": "/assets/system/js/installer-vendor.js?id=b2bca761f222e97bf4ff"
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
|
{{--<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
|
||||||
<script src="{!! public_asset('/assets/vendor/bootstrap/bootstrap.min.js') !!}" type="text/javascript"></script>
|
<script src="{!! public_asset('/assets/vendor/bootstrap/bootstrap.min.js') !!}" type="text/javascript"></script>
|
||||||
<script src="{!! public_asset('/assets/vendor/bootstrap/bootstrap-notify.js') !!}"></script>
|
<script src="{!! public_asset('/assets/vendor/bootstrap/bootstrap-notify.js') !!}"></script>
|
||||||
@@ -82,29 +82,16 @@
|
|||||||
<script src="{!! public_asset('/assets/vendor/pjax/jquery.pjax.js') !!}"></script>
|
<script src="{!! public_asset('/assets/vendor/pjax/jquery.pjax.js') !!}"></script>
|
||||||
<script src="{!! public_asset('/assets/vendor/icheck/icheck.js') !!}"></script>
|
<script src="{!! public_asset('/assets/vendor/icheck/icheck.js') !!}"></script>
|
||||||
<script src="{!! public_asset('/assets/vendor/rivets/dist/rivets.bundled.min.js') !!}"></script>
|
<script src="{!! public_asset('/assets/vendor/rivets/dist/rivets.bundled.min.js') !!}"></script>
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
|
|
||||||
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
|
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
|
||||||
|
--}}
|
||||||
|
|
||||||
<script src="{!! public_asset('/assets/admin/js/admin.js') !!}"></script>
|
|
||||||
|
<script src="{!! public_asset('/assets/admin/js/vendor.js') !!}"></script>
|
||||||
<script src="{!! public_asset('/assets/system/js/system.js') !!}"></script>
|
<script src="{!! public_asset('/assets/system/js/system.js') !!}"></script>
|
||||||
|
<script src="{!! public_asset('/assets/admin/js/admin.js') !!}"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
rivets.configure({
|
|
||||||
prefix: 'rv',
|
|
||||||
preloadData: true,
|
|
||||||
rootInterface: '.',
|
|
||||||
templateDelimiters: ['{', '}'],
|
|
||||||
iterationAlias: function (modelName) {
|
|
||||||
return '%' + modelName + '%';
|
|
||||||
},
|
|
||||||
// Augment the event handler of the on-* binder
|
|
||||||
handler: function (target, event, binding) {
|
|
||||||
this.call(target, event, binding.view.models)
|
|
||||||
},
|
|
||||||
executeFunctions: false
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
var getStorage = function(key) {
|
var getStorage = function(key) {
|
||||||
var st = window.localStorage.getItem(key);
|
var st = window.localStorage.getItem(key);
|
||||||
console.log('storage: ', key, st);
|
console.log('storage: ', key, st);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ mix.styles([
|
|||||||
'node_modules/select2/dist/css/select2.css',
|
'node_modules/select2/dist/css/select2.css',
|
||||||
'node_modules/leaflet/dist/leaflet.css',
|
'node_modules/leaflet/dist/leaflet.css',
|
||||||
'node_modules/icheck/skins/flat/orange.css',
|
'node_modules/icheck/skins/flat/orange.css',
|
||||||
|
'node_modules/x-editable/dist/bootstrap3-editable/css/bootstrap-editable.css',
|
||||||
'public/assets/admin/vendor/paper-dashboard.css',
|
'public/assets/admin/vendor/paper-dashboard.css',
|
||||||
], 'public/assets/admin/css/vendor.min.css').version()
|
], 'public/assets/admin/css/vendor.min.css').version()
|
||||||
.sourceMaps();
|
.sourceMaps();
|
||||||
@@ -41,12 +42,14 @@ mix.styles([
|
|||||||
mix.scripts([
|
mix.scripts([
|
||||||
'node_modules/lodash/lodash.js',
|
'node_modules/lodash/lodash.js',
|
||||||
'node_modules/jquery/dist/jquery.js',
|
'node_modules/jquery/dist/jquery.js',
|
||||||
|
'node_modules/bootstrap3/dist/js/bootstrap.js',
|
||||||
'node_modules/popper.js/dist/umd/popper.js',
|
'node_modules/popper.js/dist/umd/popper.js',
|
||||||
'node_modules/popper.js/dist/umd/popper-utils.js',
|
'node_modules/popper.js/dist/umd/popper-utils.js',
|
||||||
'node_modules/select2/dist/js/select2.js',
|
'node_modules/select2/dist/js/select2.js',
|
||||||
'node_modules/leaflet/dist/leaflet.js',
|
'node_modules/leaflet/dist/leaflet.js',
|
||||||
'node_modules/icheck/icheck.js',
|
'node_modules/icheck/icheck.js',
|
||||||
'node_modules/pjax/pjax.js',
|
'node_modules/pjax/pjax.js',
|
||||||
|
'node_modules/x-editable/dist/bootstrap3-editable/js/bootstrap-editable.js',
|
||||||
], 'public/assets/admin/js/vendor.js');
|
], 'public/assets/admin/js/vendor.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user