Merge pull request #1 from goryn-clade/development

Development
This commit is contained in:
Sam
2021-07-12 13:44:00 +02:00
committed by GitHub
354 changed files with 3098 additions and 1773 deletions

View File

@@ -14,7 +14,6 @@ use Exodus4D\Pathfinder\Data\File\FileHandler;
use Exodus4D\Pathfinder\Model\AbstractModel;
use Exodus4D\Pathfinder\Model\Pathfinder;
use Exodus4D\Pathfinder\Model\Universe;
use Exodus4D\Pathfinder\Exception;
/**
* Map controller

View File

@@ -632,7 +632,18 @@ class Route extends AbstractRestController {
// --> don´t filter some systems (e.g. systemFrom, systemTo) even if they are are WH,LS,0.0
$this->filterJumpData($filterData, [$systemFromId, $systemToId]);
$connections = [];
// pre-populate connections array with new connected_pairs from TrailBlazer expansion because
// they have not been added to ESI routes. Can be removed when ESI is updated
$connections = [
[30001721,30001957], // Saminer => F7-ICZ
[30001957,30001721], // F7-ICZ => Saminer
[30003605,30003823], // Kennink => Eggheron
[30003823,30003605], // Eggheron => Kennink
[30003452,30005198], // Pakhshi => Irgrus
[30005198,30003452], // Irgrus => Pakhshi
[30000134,30005196], // Hykkota => Ahbazon
[30005196,30000134], // Ahbazon => Hykkota
];
foreach($this->jumpArray as $systemSourceId => $jumpData){
$count = count($jumpData);
if($count > 1){

View File

@@ -0,0 +1,82 @@
<?php
namespace Exodus4D\Pathfinder\Controller\Api\Rest;
use Exodus4D\Pathfinder\Model;
class SystemSearch extends AbstractRestController {
/**
* system data properties that will be returned
* -> filter system data, save bandwidth
*/
const SYSTEM_DATA_KEYS = ['id', 'name', 'trueSec', 'security', 'effect', 'shattered'];
/**
* max results per page
*/
const PAGE_SIZE_SYSTEMS = 50;
/**
* @param \Base $f3
* @param $params
* @throws \Exception
*/
public function get(\Base $f3, $params){
$requestData = $this->getRequestData($f3);
$morePages = false;
$count = 0;
$result = (object) [];
$result->results = [];
// some "edge cases" for testing trueSec rounding...
//$searchToken = 'H472-N'; // -0.000001 -> 0.0
//$searchToken = 'X1E-OQ'; // -0.099426 -> -0.10
//$searchToken = 'BKK4-H'; // -0.049954 -> -0.05
//$searchToken = 'Uhtafal'; // 0.499612 -> 0.5 (HS)
//$searchToken = 'Oshaima'; // 0.453128 -> 0.5 (HS)
//$searchToken = 'Ayeroilen'; // 0.446568 -> 0.4 (LS)
//$searchToken = 'Enderailen'; // 0.448785 -> 0.4 (LS)
//$searchToken = 'Neziel'; // 0.449943 -> 0.4 (LS)
//$searchToken = 'Naga'; // 0.033684 -> 0.1 (LS)
if(strlen($search = (string)$params['id']) >= 3){
$page = max((int)$requestData['page'],1);
$offset = ($page - 1) * self::PAGE_SIZE_SYSTEMS;
$system = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
$filter = [
'id LIKE :id OR name LIKE :name',
':id' => $search . '%', // -> match first
':name' => '%' . $search . '%' // -> match between
];
$options = [
'order' => 'name',
'offset' => $offset,
'limit' => self::PAGE_SIZE_SYSTEMS
];
$count = $system->count($filter);
$endCount = $offset + self::PAGE_SIZE_SYSTEMS;
$morePages = $endCount < $count;
/**
* @var Model\Universe\SystemModel[] $systems
*/
$systems = $system->find($filter, $options);
if($systems){
$allowedKeys = array_flip(self::SYSTEM_DATA_KEYS);
foreach($systems as $system){
if($systemData = $system->fromIndex()){
$result->results[] = (object)array_intersect_key((array)$systemData, $allowedKeys);
}
}
}
}
$result->pagination = ['more' => $morePages, 'count' => $count];
$this->out($result);
}
}

View File

@@ -363,7 +363,8 @@ class Setup extends Controller\Controller {
':regionIdJove3' => 10000004,
':ns' => '0.0',
':ls' => 'L',
':hs' => 'H'
':hs' => 'H',
':tr' => 'T'
];
if($length){

View File

@@ -37,66 +37,6 @@ class Universe extends Controller\AccessController {
echo json_encode($universeNameData);
}
/**
* search systems by name
* @param \Base $f3
* @param $params
* @throws \Exception
*/
public function systems(\Base $f3, $params){
$getData = (array)$f3->get('GET');
$page = isset($getData['page']) ? (int)max($getData['page'],1) : 1;
$search = isset($params['arg1']) ? (string)$params['arg1'] : '';
$morePages = false;
$count = 0;
$return = (object) [];
$return->results = [];
// some "edge cases" for testing trueSec rounding...
//$searchToken = 'H472-N'; // -0.000001 -> 0.0
//$searchToken = 'X1E-OQ'; // -0.099426 -> -0.10
//$searchToken = 'BKK4-H'; // -0.049954 -> -0.05
//$searchToken = 'Uhtafal'; // 0.499612 -> 0.5 (HS)
//$searchToken = 'Oshaima'; // 0.453128 -> 0.5 (HS)
//$searchToken = 'Ayeroilen'; // 0.446568 -> 0.4 (LS)
//$searchToken = 'Enderailen'; // 0.448785 -> 0.4 (LS)
//$searchToken = 'Neziel'; // 0.449943 -> 0.4 (LS)
//$searchToken = 'Naga'; // 0.033684 -> 0.1 (LS)
if( strlen($search) >= 3 ){
$offset = ($page - 1) * self::PAGE_SIZE_SYSTEMS;
$system = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
$filter = [
'id LIKE :id OR name LIKE :name',
':id' => $search . '%', // -> match first
':name' => '%' . $search . '%' // -> match between
];
$options = [
'order' => 'name',
'offset' => $offset,
'limit' => self::PAGE_SIZE_SYSTEMS
];
$count = $system->count($filter);
$endCount = $offset + self::PAGE_SIZE_SYSTEMS;
$morePages = $endCount < $count;
$systems = $system->find($filter, $options);
if($systems){
foreach($systems as $system){
if($systemData = $system->fromIndex()){
$return->results[] = $systemData;
}
}
}
}
$return->pagination = ['more' => $morePages, 'count' => $count];
echo json_encode($return);
}
/**
* get system data for all systems within a constellation
* @param \Base $f3

View File

@@ -68,8 +68,6 @@ class AppController extends Controller {
$resource = Resource::instance();
$resource->register('script', 'app/login');
$resource->register('script', 'app/mappage', 'prefetch');
$resource->register('image', 'sso/signature.png');
$resource->register('image', 'sso/gameplay.png');
}
}

View File

@@ -914,7 +914,7 @@ class Setup extends Controller {
// -> the DSN format is not the same, convert URL format into DSN
if(
strtolower(session_module_name()) == 'redis' &&
($parts = parse_url(strtolower(session_save_path())))
($parts = parse_url(session_save_path()))
){
// parse URL parameters
parse_str((string)$parts['query'], $params);

View File

@@ -0,0 +1,76 @@
<?php
namespace Exodus4D\Pathfinder\Db\Sql\Mysql;
use DB\SQL;
class Column extends SQL\Column {
/**
* missing table name error
*/
const ERROR_TABLE_NAME_MISSING = 'Table name missing for FOREIGN KEY in `%s`';
/**
* drop constraint from this column
* @param Constraint $constraint
*/
public function dropConstraint(Constraint $constraint){
$this->table->dropConstraint($constraint);
}
/**
* add constraint to this column
* @param Constraint $constraint
*/
public function addConstraint(Constraint $constraint){
$this->table->addConstraint($constraint);
}
/**
* @param Constraint $constraint
* @return mixed
*/
public function constraintExists(Constraint $constraint){
return $this->table->constraintExists($constraint);
}
/**
* get a new column based constraint
* $constraintData['table'] => referenceTable name (required)
* $constraintData['id'] => referenceColumns (optional) default: ['id']
* $constraintData['on-delete'] => ON DELETE action (optional) default: see \DB\SQL\MySQL\Constraint const
* $constraintData['on-update'] => ON UPDATE action (optional) default: see \DB\SQL\MySQL\Constraint const
*
* @param array $constraintData
* @return Constraint
*/
public function newConstraint($constraintData){
$constraint = null;
if(isset($constraintData['table'])){
if(isset($constraintData['column'])){
$constraintData['column'] = (array)$constraintData['column'];
}else{
$constraintData['column'] = ['id'];
}
$constraint = new Constraint($this->table, $this->name, $constraintData['table'], $constraintData['column']);
if(isset($constraintData['on-delete'])){
$constraint->setOnDelete($constraintData['on-delete']);
}
if(isset($constraintData['on-update'])){
$constraint->setOnUpdate($constraintData['on-update']);
}
}else{
trigger_error(sprintf(self::ERROR_TABLE_NAME_MISSING, $this->table->name . '->' . $this->name));
}
return $constraint;
}
}

View File

@@ -0,0 +1,162 @@
<?php
namespace Exodus4D\Pathfinder\Db\Sql\Mysql;
use DB\SQL;
class Constraint {
// available actions
const ACTIONS_DELETE = ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'];
const ACTIONS_UPDATE = ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'];
// default actions
const ACTION_DELETE = 'RESTRICT';
const ACTION_UPDATE = 'RESTRICT';
const ERROR_ACTION_NOT_SUPPORTED = 'Constraint action `%s` is not supported.';
protected $table;
protected $keys = [];
protected $referencedTable = '';
protected $referencedCols = [];
protected $onDelete = self::ACTION_DELETE;
protected $onUpdate = self::ACTION_UPDATE;
/**
* Constraint constructor.
* @param SQL\TableBuilder $table
* @param array $keys
* @param string $referencedTable
* @param array $referencedCols
*/
public function __construct(SQL\TableBuilder $table, $keys = [], $referencedTable = '', $referencedCols = ['id']){
$this->table = &$table;
$this->setKeys($keys);
$this->setReferencedTable($referencedTable);
$this->setReferencedCols($referencedCols);
}
/**
* @param mixed $keys
*/
public function setKeys($keys){
$this->keys = (array)$keys;
}
/**
* @param mixed $referencedTable
*/
public function setReferencedTable($referencedTable){
$this->referencedTable = $referencedTable;
}
/**
* @param mixed $referencedCols
*/
public function setReferencedCols($referencedCols){
$this->referencedCols = (array)$referencedCols;
}
/**
* @param string $onDelete
*/
public function setOnDelete($onDelete){
if( in_array($onDelete, self::ACTIONS_DELETE) ){
$this->onDelete = $onDelete;
}else{
trigger_error(sprintf(self::ERROR_ACTION_NOT_SUPPORTED, $onDelete));
}
}
/**
* @param string $onUpdate
*/
public function setOnUpdate($onUpdate){
if( in_array($onUpdate, self::ACTIONS_UPDATE) ){
$this->onUpdate = $onUpdate;
}else{
trigger_error(sprintf(self::ERROR_ACTION_NOT_SUPPORTED, $onUpdate));
}
}
/**
* @return array
*/
public function getKeys(){
return $this->keys;
}
/**
* @return string
*/
public function getReferencedTable(){
return $this->referencedTable;
}
/**
* @return array
*/
public function getReferencedCols(){
return $this->referencedCols;
}
/**
* @return string
*/
public function getOnDelete(){
return $this->onDelete;
}
/**
* @return string
*/
public function getOnUpdate(){
return $this->onUpdate;
}
/**
* get a constraint name for this table.
* This can either be used to generate unique constraint names for foreign keys in parent tables
* or generate a "part" of a name. e.g. for db-Query all constraints of this table (ignore columns)
* by "LIKE" selecting "information_schema"
* -> To get a certain constraint or generate a unique constraint, ALL params are required!
* @return string
*/
public function getConstraintName(){
$constraintName = 'fk_' . $this->table->name;
if(!empty($this->getKeys())){
$constraintName .= '___' . implode('__', $this->getKeys());
if(!empty($this->getReferencedTable())){
$constraintName .= '___' . $this->getReferencedTable();
if(!empty($this->getReferencedCols())){
$constraintName .= '___' . implode('__', $this->getReferencedCols());
}
}
}
return $constraintName;
}
/**
* checks if constraint is valid
* -> all required members must be set!
* @return bool
*/
public function isValid(){
$valid = false;
if(
!empty($this->getKeys()) &&
!empty($this->getReferencedTable()) &&
!empty($this->getReferencedCols())
){
$valid = true;
}
return $valid;
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 19.12.2015
* Time: 12:47
*
* This is an "on top" extension for "Schema Builder"
* see: https://github.com/ikkez/f3-schema-builder
*
* Features:
* - FOREIGN KEY CONSTRAINTS (single column key)
*/
namespace Exodus4D\Pathfinder\Db\Sql\Mysql;
use DB\SQL;
class TableModifier extends SQL\TableModifier {
/**
* invalid constraint error
*/
const ERROR_CONSTRAINT_NOT_VALID = 'Constraint `%s` is not valid';
/**
* return table foreign key constraints as assoc array
* -> if §constraint is passed, constraints are limited to that column
* @param null| Constraint $constraint
* @return Constraint[]
*/
public function listConstraint($constraint = null){
$constraintName = '%';
$keys = [];
if($constraint instanceof Constraint){
// list constraints for given column in this table
$constraintName = $constraint->getConstraintName() . '%';
$keys = $constraint->getKeys();
}
$this->db->exec("USE information_schema");
$constraintsData = $this->db->exec("
SELECT
*
FROM
referential_constraints
WHERE
constraint_schema = :db AND
table_name = :table AND
constraint_name LIKE :constraint_name
", [
':db' => $this->db->name(),
':table' => $this->name,
':constraint_name' => $constraintName
]);
// switch back to current DB
$this->db->exec("USE " . $this->db->quotekey($this->db->name()));
$constraints = [];
foreach($constraintsData as $data){
$constraints[$data['CONSTRAINT_NAME']] = new Constraint($this, $keys, $data['REFERENCED_TABLE_NAME'] );
}
return $constraints;
}
/**
* checks whether a constraint name exists or not
* -> does not check constraint params
* @param Constraint $constraint
* @return bool
*/
public function constraintExists($constraint){
$constraints = $this->listConstraint();
return array_key_exists($constraint->getConstraintName(), $constraints);
}
/**
* drop foreign key constraint
* @param Constraint $constraint
*/
public function dropConstraint($constraint){
if($constraint->isValid()){
$this->queries[] = "ALTER TABLE " . $this->db->quotekey($this->name) . "
DROP FOREIGN KEY " . $this->db->quotekey($constraint->getConstraintName()) . ";";
}else{
trigger_error(sprintf(self::ERROR_CONSTRAINT_NOT_VALID, 'table: ' . $this->name . ' constraintName: ' . $constraint->getConstraintName()));
}
}
/**
* Add/Update foreign key constraint
* @param Constraint $constraint
*/
public function addConstraint($constraint){
if($constraint->isValid()){
$this->queries[] = "
ALTER TABLE " . $this->db->quotekey($this->name) . "
ADD CONSTRAINT " . $this->db->quotekey($constraint->getConstraintName()) . "
FOREIGN KEY (" . implode(', ', $constraint->getKeys()) . ")
REFERENCES " . $this->db->quotekey($constraint->getReferencedTable()) . " (" . implode(', ', $constraint->getReferencedCols()) . ")
ON DELETE " . $constraint->getOnDelete() . "
ON UPDATE " . $constraint->getOnUpdate() . ";";
}else{
trigger_error(sprintf(self::ERROR_CONSTRAINT_NOT_VALID, 'table: ' . $this->name . ' constraintName: ' . $constraint->getConstraintName()));
}
}
}

View File

@@ -1,337 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 19.12.2015
* Time: 12:47
*
* This is an "on top" extension for "Schema Builder"
* see: https://github.com/ikkez/f3-schema-builder
*
* Features:
* - FOREIGN KEY CONSTRAINTS (single column key)
*/
namespace Exodus4D\Pathfinder\Db\Sql\Mysql;
use DB\SQL;
class TableModifier extends SQL\TableModifier {
const TEXT_ConstraintNotValid = 'Constraint `%s` is not valid';
/**
* return table foreign key constraints as assoc array
* -> if §constraint is passed, constraints are limited to that column
* @param null| Constraint $constraint
* @return Constraint[]
*/
public function listConstraint($constraint = null){
$constraintName = '%';
$keys = [];
if($constraint instanceof Constraint){
// list constraints for given column in this table
$constraintName = $constraint->getConstraintName() . '%';
$keys = $constraint->getKeys();
}
$this->db->exec("USE information_schema");
$constraintsData = $this->db->exec("
SELECT
*
FROM
referential_constraints
WHERE
constraint_schema = :db AND
table_name = :table AND
constraint_name LIKE :constraint_name
", [
':db' => $this->db->name(),
':table' => $this->name,
':constraint_name' => $constraintName
]);
// switch back to current DB
$this->db->exec("USE " . $this->db->quotekey($this->db->name()));
$constraints = [];
foreach($constraintsData as $data){
$constraints[$data['CONSTRAINT_NAME']] = new Constraint($this, $keys, $data['REFERENCED_TABLE_NAME'] );
}
return $constraints;
}
/**
* checks whether a constraint name exists or not
* -> does not check constraint params
* @param Constraint $constraint
* @return bool
*/
public function constraintExists($constraint){
$constraints = $this->listConstraint();
return array_key_exists($constraint->getConstraintName(), $constraints);
}
/**
* drop foreign key constraint
* @param Constraint $constraint
*/
public function dropConstraint($constraint){
if($constraint->isValid()){
$this->queries[] = "ALTER TABLE " . $this->db->quotekey($this->name) . "
DROP FOREIGN KEY " . $this->db->quotekey($constraint->getConstraintName()) . ";";
}else{
trigger_error(sprintf(self::TEXT_ConstraintNotValid, 'table: ' . $this->name . ' constraintName: ' . $constraint->getConstraintName()));
}
}
/**
* Add/Update foreign key constraint
* @param Constraint $constraint
*/
public function addConstraint($constraint){
if($constraint->isValid()){
$this->queries[] = "
ALTER TABLE " . $this->db->quotekey($this->name) . "
ADD CONSTRAINT " . $this->db->quotekey($constraint->getConstraintName()) . "
FOREIGN KEY (" . implode(', ', $constraint->getKeys()) . ")
REFERENCES " . $this->db->quotekey($constraint->getReferencedTable()) . " (" . implode(', ', $constraint->getReferencedCols()) . ")
ON DELETE " . $constraint->getOnDelete() . "
ON UPDATE " . $constraint->getOnUpdate() . ";";
}else{
trigger_error(sprintf(self::TEXT_ConstraintNotValid, 'table: ' . $this->name . ' constraintName: ' . $constraint->getConstraintName()));
}
}
}
/**
* Class Column
* @package DB\SQL\MySQL
*/
class Column extends SQL\Column {
const TEXT_TableNameMissing = 'Table name missing for FOREIGN KEY in `%s`';
/**
* drop constraint from this column
* @param Constraint $constraint
*/
public function dropConstraint(Constraint $constraint){
$this->table->dropConstraint($constraint);
}
/**
* add constraint to this column
* @param Constraint $constraint
*/
public function addConstraint(Constraint $constraint){
$this->table->addConstraint($constraint);
}
/**
* @param Constraint $constraint
* @return mixed
*/
public function constraintExists(Constraint $constraint){
return $this->table->constraintExists($constraint);
}
/**
* get a new column based constraint
* $constraintData['table'] => referenceTable name (required)
* $constraintData['id'] => referenceColumns (optional) default: ['id']
* $constraintData['on-delete'] => ON DELETE action (optional) default: see \DB\SQL\MySQL\Constraint const
* $constraintData['on-update'] => ON UPDATE action (optional) default: see \DB\SQL\MySQL\Constraint const
*
* @param array $constraintData
* @return Constraint
*/
public function newConstraint($constraintData){
$constraint = null;
if(isset($constraintData['table'])){
if(isset($constraintData['column'])){
$constraintData['column'] = (array)$constraintData['column'];
}else{
$constraintData['column'] = ['id'];
}
$constraint = new Constraint($this->table, $this->name, $constraintData['table'], $constraintData['column']);
if(isset($constraintData['on-delete'])){
$constraint->setOnDelete($constraintData['on-delete']);
}
if(isset($constraintData['on-update'])){
$constraint->setOnUpdate($constraintData['on-update']);
}
}else{
trigger_error(sprintf(self::TEXT_TableNameMissing, $this->table->name . '->' . $this->name));
}
return $constraint;
}
}
class Constraint {
// available actions
const ACTIONS_DELETE = ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'];
const ACTIONS_UPDATE = ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'];
// default actions
const ACTION_DELETE = 'RESTRICT';
const ACTION_UPDATE = 'RESTRICT';
const TEXT_ActionNotSupported = 'Constraint action `%s` is not supported.';
protected $table;
protected $keys = [];
protected $referencedTable = '';
protected $referencedCols = [];
protected $onDelete = self::ACTION_DELETE;
protected $onUpdate = self::ACTION_UPDATE;
/**
* Constraint constructor.
* @param SQL\TableBuilder $table
* @param array $keys
* @param string $referencedTable
* @param array $referencedCols
*/
public function __construct(SQL\TableBuilder $table, $keys = [], $referencedTable = '', $referencedCols = ['id']){
$this->table = &$table;
$this->setKeys($keys);
$this->setReferencedTable($referencedTable);
$this->setReferencedCols($referencedCols);
}
/**
* @param mixed $keys
*/
public function setKeys($keys){
$this->keys = (array)$keys;
}
/**
* @param mixed $referencedTable
*/
public function setReferencedTable($referencedTable){
$this->referencedTable = $referencedTable;
}
/**
* @param mixed $referencedCols
*/
public function setReferencedCols($referencedCols){
$this->referencedCols = (array)$referencedCols;
}
/**
* @param string $onDelete
*/
public function setOnDelete($onDelete){
if( in_array($onDelete, self::ACTIONS_DELETE) ){
$this->onDelete = $onDelete;
}else{
trigger_error(sprintf(self::TEXT_ActionNotSupported, $onDelete));
}
}
/**
* @param string $onUpdate
*/
public function setOnUpdate($onUpdate){
if( in_array($onUpdate, self::ACTIONS_UPDATE) ){
$this->onUpdate = $onUpdate;
}else{
trigger_error(sprintf(self::TEXT_ActionNotSupported, $onUpdate));
}
}
/**
* @return array
*/
public function getKeys(){
return $this->keys;
}
/**
* @return string
*/
public function getReferencedTable(){
return $this->referencedTable;
}
/**
* @return array
*/
public function getReferencedCols(){
return $this->referencedCols;
}
/**
* @return string
*/
public function getOnDelete(){
return $this->onDelete;
}
/**
* @return string
*/
public function getOnUpdate(){
return $this->onUpdate;
}
/**
* get a constraint name for this table.
* This can either be used to generate unique constraint names for foreign keys in parent tables
* or generate a "part" of a name. e.g. for db-Query all constraints of this table (ignore columns)
* by "LIKE" selecting "information_schema"
* -> To get a certain constraint or generate a unique constraint, ALL params are required!
* @return string
*/
public function getConstraintName(){
$constraintName = 'fk_' . $this->table->name;
if(!empty($this->getKeys())){
$constraintName .= '___' . implode('__', $this->getKeys());
if(!empty($this->getReferencedTable())){
$constraintName .= '___' . $this->getReferencedTable();
if(!empty($this->getReferencedCols())){
$constraintName .= '___' . implode('__', $this->getReferencedCols());
}
}
}
return $constraintName;
}
/**
* checks if constraint is valid
* -> all required members must be set!
* @return bool
*/
public function isValid(){
$valid = false;
if(
!empty($this->getKeys()) &&
!empty($this->getReferencedTable()) &&
!empty($this->getReferencedCols())
){
$valid = true;
}
return $valid;
}
}

View File

@@ -577,7 +577,7 @@ class Config extends \Prefab {
*/
static function parseDSN(string $dsn, ?array &$conf = []) : bool {
// reset reference
if($matches = (bool)preg_match('/^(\w+)\h*=\h*(.+)/', strtolower(trim($dsn)), $parts)){
if($matches = (bool)preg_match('/^(\w+)\h*=\h*(.+)/', trim($dsn), $parts)){
$conf['type'] = $parts[1];
if($conf['type'] == 'redis'){
[$conf['host'], $conf['port'], $conf['db'], $conf['auth']] = explode(':', $parts[2]) + [1 => 6379, 2 => null, 3 => null];

View File

@@ -38,11 +38,12 @@ abstract class AbstractPathfinderModel extends AbstractModel {
/**
* @param bool $mapper
* @param bool $essentials
* @return NULL|void
*/
public function reset($mapper = true){
public function reset($mapper = true, $essentials = true){
$this->fieldChanges = [];
parent::reset($mapper);
parent::reset($mapper, $essentials);
}
/**

View File

@@ -207,8 +207,6 @@ class SystemModel extends AbstractMapTrackingModel {
$data->name = $this->name;
$data->security = $this->security;
$data->trueSec = $this->trueSec;
$data->effect = $this->effect;
$data->shattered = $this->shattered;
$data->constellation = (object) [];
$data->constellation->id = $this->constellationId;
@@ -218,8 +216,21 @@ class SystemModel extends AbstractMapTrackingModel {
$data->region->id = $this->regionId;
$data->region->name = $this->region;
$data->planets = $this->planets ? : [];
$data->statics = $this->statics ? : [];
if($this->planets){
$data->planets = $this->planets;
}
if($this->statics){
$data->statics = $this->statics;
}
if($this->effect){
$data->effect = $this->effect;
}
if($this->shattered){
$data->shattered = $this->shattered;
}
if(is_object($sovereignty = $this->sovereignty)){
$data->sovereignty = $sovereignty;
@@ -777,6 +788,7 @@ class SystemModel extends AbstractMapTrackingModel {
case 'H':
case 'L':
case '0.0':
case 'T':
$typeId = 2; // k-space
break;
case 'A':

View File

@@ -185,6 +185,8 @@ abstract class AbstractUniverseModel extends AbstractModel {
$security = 'L';
}elseif($id == 9){
$security = '0.0';
}elseif($id == 25){
$security = 'T';
}
return $security;

View File

@@ -148,11 +148,12 @@ class TypeModel extends AbstractUniverseModel {
/**
* @param bool $mapper
* @param bool $essentials
* @return NULL|void
*/
public function reset($mapper = true){
public function reset($mapper = true, $essentials = true){
$this->clearVirtual('dogmaAttributes');
parent::reset($mapper);
parent::reset($mapper, $essentials);
}
/**

View File

@@ -13,8 +13,8 @@ NAME = Pathfinder
; Version is used for CSS/JS cache busting and is part of the URL for static resources:
; e.g. public/js/vX.X.X/app.js
; Syntax: String (current version)
; Default: v2.0.0
VERSION = v2.0.0
; Default: v2.1.0
VERSION = v2.1.0
; Contact information [optional]
; Shown on 'licence', 'contact' page.

View File

@@ -20,6 +20,7 @@
"Exodus4D\\Pathfinder\\": "app/"
}
},
"readme": "README.md",
"repositories": [
{
"type": "vcs",
@@ -36,7 +37,7 @@
"ext-ctype": "*",
"ext-gd": "*",
"bcosca/fatfree-core": "3.7.*",
"ikkez/f3-cortex": "dev-master#0d7754a5897a639e563add6b8d6db53fc0fae677",
"ikkez/f3-cortex": "dev-master#af035616ae8d708776117e05603dac43835f3d9a",
"ikkez/f3-sheet": "0.4.*",
"xfra35/f3-cron": "1.2.*",
"monolog/monolog": "2.*",

View File

@@ -20,6 +20,7 @@
"Exodus4D\\Pathfinder\\": "app/"
}
},
"readme": "README.md",
"require": {
"php-64bit": ">=7.2",
"ext-pdo": "*",
@@ -30,7 +31,7 @@
"ext-ctype": "*",
"ext-gd": "*",
"bcosca/fatfree-core": "3.7.*",
"ikkez/f3-cortex": "dev-master#0d7754a5897a639e563add6b8d6db53fc0fae677",
"ikkez/f3-cortex": "dev-master#af035616ae8d708776117e05603dac43835f3d9a",
"ikkez/f3-sheet": "0.4.*",
"xfra35/f3-cron": "1.2.*",
"monolog/monolog": "2.*",

137
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "335a3680cd2d074fd048b76d16a6f4d2",
"content-hash": "89a2596142e0f45259aabbf695e28de8",
"packages": [
{
"name": "bcosca/fatfree-core",
@@ -1057,12 +1057,12 @@
"source": {
"type": "git",
"url": "https://github.com/ikkez/f3-cortex.git",
"reference": "0d7754a5897a639e563add6b8d6db53fc0fae677"
"reference": "af035616ae8d708776117e05603dac43835f3d9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ikkez/f3-cortex/zipball/0d7754a5897a639e563add6b8d6db53fc0fae677",
"reference": "0d7754a5897a639e563add6b8d6db53fc0fae677",
"url": "https://api.github.com/repos/ikkez/f3-cortex/zipball/af035616ae8d708776117e05603dac43835f3d9a",
"reference": "af035616ae8d708776117e05603dac43835f3d9a",
"shasum": ""
},
"require": {
@@ -1087,7 +1087,7 @@
"orm",
"sql"
],
"time": "2019-10-29T12:10:01+00:00"
"time": "2020-04-07T09:55:52+00:00"
},
{
"name": "ikkez/f3-schema-builder",
@@ -1163,16 +1163,16 @@
},
{
"name": "league/flysystem",
"version": "1.0.66",
"version": "1.0.67",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "021569195e15f8209b1c4bebb78bd66aa4f08c21"
"reference": "5b1f36c75c4bdde981294c2a0ebdb437ee6f275e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/021569195e15f8209b1c4bebb78bd66aa4f08c21",
"reference": "021569195e15f8209b1c4bebb78bd66aa4f08c21",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5b1f36c75c4bdde981294c2a0ebdb437ee6f275e",
"reference": "5b1f36c75c4bdde981294c2a0ebdb437ee6f275e",
"shasum": ""
},
"require": {
@@ -1243,7 +1243,7 @@
"sftp",
"storage"
],
"time": "2020-03-17T18:58:12+00:00"
"time": "2020-04-16T13:21:26+00:00"
},
{
"name": "league/html-to-markdown",
@@ -1488,16 +1488,16 @@
},
{
"name": "psr/log",
"version": "1.1.2",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
@@ -1531,7 +1531,7 @@
"psr",
"psr-3"
],
"time": "2019-11-01T11:05:21+00:00"
"time": "2020-03-23T09:12:05+00:00"
},
{
"name": "psr/simple-cache",
@@ -2059,16 +2059,16 @@
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "926832ce51059bb58211b7b2080a88e0c3b5328e"
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/926832ce51059bb58211b7b2080a88e0c3b5328e",
"reference": "926832ce51059bb58211b7b2080a88e0c3b5328e",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
"shasum": ""
},
"require": {
@@ -2080,7 +2080,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -2114,20 +2114,34 @@
"portable",
"shim"
],
"time": "2020-01-13T11:15:53+00:00"
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "6842f1a39cf7d580655688069a03dd7cd83d244a"
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6842f1a39cf7d580655688069a03dd7cd83d244a",
"reference": "6842f1a39cf7d580655688069a03dd7cd83d244a",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"shasum": ""
},
"require": {
@@ -2141,7 +2155,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -2176,20 +2190,34 @@
"portable",
"shim"
],
"time": "2020-01-17T12:01:36+00:00"
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "34094cfa9abe1f0f14f48f490772db7a775559f2"
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/34094cfa9abe1f0f14f48f490772db7a775559f2",
"reference": "34094cfa9abe1f0f14f48f490772db7a775559f2",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"shasum": ""
},
"require": {
@@ -2201,7 +2229,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -2235,20 +2263,34 @@
"portable",
"shim"
],
"time": "2020-01-13T11:15:53+00:00"
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf"
"reference": "37b0976c78b94856543260ce09b460a7bc852747"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf",
"reference": "46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747",
"reference": "37b0976c78b94856543260ce09b460a7bc852747",
"shasum": ""
},
"require": {
@@ -2257,7 +2299,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@@ -2290,7 +2332,21 @@
"portable",
"shim"
],
"time": "2020-01-13T11:15:53+00:00"
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-02-27T09:26:54+00:00"
},
{
"name": "xfra35/f3-cron",
@@ -2348,5 +2404,6 @@
"ext-ctype": "*",
"ext-gd": "*"
},
"platform-dev": []
"platform-dev": [],
"plugin-api-version": "1.1.0"
}

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

34
img/svg/grid_layout.svg Normal file
View File

@@ -0,0 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
<defs>
<g id="pf-svg-grid-3" fill="currentColor">
<title>3 columns</title>
<rect width="65" height="22" fill="#212c30" />
<rect width="40" height="35" y="25" />
<rect width="22" height="60" x="68" />
<rect width="22" height="35" x="43" y="25" />
</g>
<g id="pf-svg-grid-2" fill="currentColor">
<title>2 columns</title>
<rect width="90" height="22" fill="#212c30" />
<rect width="55" height="35" y="25" />
<rect width="32" height="16" y="25" x="58" />
<rect width="32" height="16" y="44" x="58" />
</g>
</defs>
<symbol id="pf-svg-grid-3-right" viewBox="0 0 90 60" width="100%" height="100%">
<use href="#pf-svg-grid-3" />
</symbol>
<symbol id="pf-svg-grid-3-left" viewBox="0 0 90 60" width="100%" height="100%">
<use href="#pf-svg-grid-3-right" transform="translate(90,0) scale(-1,1)" />
</symbol>
<symbol id="pf-svg-grid-2-right" viewBox="0 0 90 60" width="100%" height="100%">
<use href="#pf-svg-grid-2" />
</symbol>
<symbol id="pf-svg-grid-2-left" viewBox="0 0 90 60" width="100%" height="100%">
<use href="#pf-svg-grid-2-right" transform="translate(90,0) scale(-1,1)" />
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -34,7 +34,7 @@ requirejs.config({
velocity: 'lib/velocity.min', // v1.5.1 animation engine - http://julian.com/research/velocity
velocityUI: 'lib/velocity.ui.min', // v5.2.0 plugin for velocity - http://julian.com/research/velocity/#uiPack
slidebars: 'lib/slidebars', // v2.0.2 Slidebars - side menu plugin https://www.adchsm.com/slidebars/
jsPlumb: 'lib/jsplumb', // v2.9.3 jsPlumb main map draw plugin http://jsplumb.github.io/jsplumb/home.html
jsPlumb: 'lib/jsplumb', // v2.13.1 jsPlumb main map draw plugin http://jsplumb.github.io/jsplumb/home.html
farahey: 'lib/farahey', // v1.1.2 jsPlumb "magnetizing" plugin extension - https://github.com/ThomasChan/farahey
easyTimer: 'lib/easytimer.min', // v4.0.2 EasyTimer - Timer/Chronometer/Countdown library - http://albert-gonzalez.github.io/easytimer.js
customScrollbar: 'lib/jquery.mCustomScrollbar.min', // v3.1.5 Custom scroll bars - http://manos.malihu.gr

View File

@@ -6,7 +6,7 @@
* proofed, signature names (copy & paste from scanning window)
*/
define([], () => {
define([], () => {
'use strict';
// signature sources
@@ -380,7 +380,8 @@ define([], () => {
7: 'B274 - H',
8: 'A239 - L',
9: 'E545 - 0.0',
10: 'F135 - C12 Thera'
10: 'F135 - C12 Thera',
11: 'F216 - T Pochven'
};
// all k-space exits are static or K162
@@ -394,7 +395,8 @@ define([], () => {
7: 'D845 - H',
8: 'U210 - L',
9: 'K346 - 0.0',
10: 'F135 - C12 Thera'
10: 'F135 - C12 Thera',
11: 'F216 - T Pochven'
};
// no *wandering* w-space -> w-space
@@ -483,7 +485,8 @@ define([], () => {
7: 'A641 - H',
8: 'R051 - L',
9: 'V283 - 0.0',
10: 'T458 - C12 Thera'
10: 'T458 - C12 Thera',
11: 'C729 - T Pochven'
};
let lsWH = {
@@ -496,7 +499,8 @@ define([], () => {
7: 'B449 - H',
8: 'N944 - L',
9: 'S199 - 0.0',
10: 'M164 - C12 Thera'
10: 'M164 - C12 Thera',
11: 'C729 - T Pochven'
};
let nullWH = {
@@ -509,7 +513,14 @@ define([], () => {
7: 'B449 - H',
8: 'N944 - L',
9: 'S199 - 0.0',
10: 'L031 - C12 Thera'
10: 'L031 - C12 Thera',
11: 'C729 - T Pochven',
12: 'U372 - T Pochven'
};
let pochWH = {
1: 'R081 - C4',
2: 'X450 - 0.0'
};
// ================================================================================================================
@@ -607,6 +618,9 @@ define([], () => {
},
32: { // 0.0
5: nullWH
},
33: { // Pochven
5: pochWH
}
}
};

View File

@@ -47,7 +47,6 @@ define([], () => {
getStatisticsData: '/api/Statistic/getData', // ajax URL - get statistics data (activity log)
// universe API
searchUniverseData: '/api/Universe/search', // ajax URL - search universe data by category Ids
searchUniverseSystemData: '/api/Universe/systems', // ajax URL - search universe system data by name
getConstellationData: '/api/Universe/constellationData', // ajax URL - get system constellation data
// GitHub API
gitHubReleases: '/api/GitHub/releases' // ajax URL - get release info from GitHub
@@ -237,6 +236,9 @@ define([], () => {
'L': {
class: 'pf-system-sec-lowSec'
},
'T': {
class: 'pf-system-sec-triglav'
},
'0.0': {
class: 'pf-system-sec-nullSec'
},
@@ -367,22 +369,13 @@ define([], () => {
// map connection types
connectionTypes: {
abyssal: {
cssClass: 'pf-map-connection-abyssal',
paintStyle: {
dashstyle: '0.5 2' // dotted line
}
cssClass: 'pf-map-connection-abyssal'
},
jumpbridge: {
cssClass: 'pf-map-connection-jumpbridge',
paintStyle: {
dashstyle: '4 2 1 2'
}
cssClass: 'pf-map-connection-jumpbridge'
},
stargate: {
cssClass: 'pf-map-connection-stargate',
paintStyle: {
dashstyle: '0' // solid line
}
cssClass: 'pf-map-connection-stargate'
},
wh_eol: {
cssClass: 'pf-map-connection-wh-eol'
@@ -398,10 +391,6 @@ define([], () => {
},
wh_jump_mass_s: {
cssClass: 'pf-map-connection-wh-size-s',
paintStyle: {
dashstyle: '0.5 1',
strokeWidth: 3
},
overlays: [
['Label',
{
@@ -414,9 +403,6 @@ define([], () => {
},
wh_jump_mass_m: {
cssClass: 'pf-map-connection-wh-size-m',
paintStyle: {
dashstyle: '3 1'
},
overlays: [
['Label',
{
@@ -441,9 +427,6 @@ define([], () => {
},
wh_jump_mass_xl: {
cssClass: 'pf-map-connection-wh-size-xl',
paintStyle: {
strokeWidth: 6
},
overlays: [
['Label',
{
@@ -471,11 +454,11 @@ define([], () => {
{
id: 'pf-map-connection-arrow-overlay',
cssClass: 'pf-map-connection-arrow-overlay',
location: 0.5,
length: '${arrowlength}',
width: 12,
length: 15,
direction: 1,
foldback: 0.8,
location: 0.5
direction: '${arrowdirection}',
foldback: '${arrowfoldback}'
}]
]
},
@@ -496,28 +479,28 @@ define([], () => {
},
wormholeSizes: {
wh_jump_mass_xl: {
jumpMassMin: 1000000000,
jumpMassMin: 1350000000,
type: 'wh_jump_mass_xl',
class: 'pf-jump-mass-xl',
label: 'XL',
text: 'capital ships'
},
wh_jump_mass_l: {
jumpMassMin: 300000000,
jumpMassMin: 375000000,
type: 'wh_jump_mass_l',
class: 'pf-jump-mass-l',
label: 'L',
text: 'larger ships'
},
wh_jump_mass_m: {
jumpMassMin: 20000000,
jumpMassMin: 62000000,
type: 'wh_jump_mass_m',
class: 'pf-jump-mass-m',
label: 'M',
text: 'medium ships'
},
wh_jump_mass_s: {
jumpMassMin: 1000,
jumpMassMin: 5000,
type: 'wh_jump_mass_s',
class: 'pf-jump-mass-s',
label: 'S',

View File

@@ -87,7 +87,7 @@ define(['app/lib/eventHandler'], (EventHandler) => {
this.setTargetDimensions();
EventHandler.addEventListener(this._config.target, this.getNamespaceEvent('mousedown'), this.onMouseDown.bind(this), {passive: false});
EventHandler.addEventListener(this._config.container, this.getNamespaceEvent('mousemove'), this.onMouseMove.bind(this), {passive: false});
EventHandler.addEventListener(this._config.container, this.getNamespaceEvent('mousemove'), this.onMouseMove.bind(this), {passive: true});
EventHandler.addEventListener(this._config.container, this.getNamespaceEvent('mouseup'), this.onMouseUp.bind(this), {passive: true});
}
@@ -104,6 +104,7 @@ define(['app/lib/eventHandler'], (EventHandler) => {
onMouseMove(e){
if(this._mouseIsDown){
e.preventDefault();
e.stopPropagation();
if(this._animationFrameId){
cancelAnimationFrame(this._animationFrameId);

31
js/app/lib/svg.js Normal file
View File

@@ -0,0 +1,31 @@
define([], () => {
'use strict';
class SVG {
static updateSymbolSvg(svgEl, href){
let useEl = svgEl.getElementsByTagNameNS(this.namespaces.svg, 'use')[0];
if(useEl){
useEl.setAttribute('href', href);
}
}
static newSymbolSvg(href){
let svgEl = this.newEl();
let useEl = this.newEl('use');
useEl.setAttribute('href', href);
svgEl.appendChild(useEl);
return svgEl;
}
static newEl(nodeName = 'svg', namespaceURI = this.namespaces.svg){
return document.createElementNS(namespaceURI, nodeName);
}
}
SVG.namespaces = {
'svg': 'http://www.w3.org/2000/svg'
};
return SVG;
});

View File

@@ -48,8 +48,8 @@ define([
ssoButtonClass: 'pf-sso-login-button', // class for SSO login button
// character select
characterSelectionClass: 'pf-character-selection', // class for character panel wrapper
characterRowAnimateClass: 'pf-character-row-animate', // class for character panel row during animation
characterSelectionClass: 'pf-character-selection', // class for character boxes
characterBoxClass: 'pf-character-box', // class for outer character box
characterImageWrapperClass: 'pf-character-image-wrapper', // class for image wrapper (animated)
characterImageInfoClass: 'pf-character-info', // class for character info layer (visible on hover)
dynamicMessageContainerClass: 'pf-dynamic-message-container', // class for "dynamic" (JS) message container
@@ -489,12 +489,13 @@ define([
let content = Mustache.render(template, data);
$('#' + config.headerId).prepend(content);
let stickyPanelServer = $('#' + config.stickyPanelServerId);
stickyPanelServer.velocity('transition.slideLeftBigIn', {
stickyPanelServer.velocity('transition.slideRightBigIn', {
duration: 240
});
// set observer for api status dialog
stickyPanelServer.on('click', '.' + config.apiStatusTriggerClass, function(){
stickyPanelServer.on('pointerdown', '.' + config.apiStatusTriggerClass, e => {
e.stopPropagation();
$.fn.apiStatusDialog(data.api);
});
});
@@ -550,22 +551,21 @@ define([
* load character data from cookie information
* -> all validation is done server side!
*/
let initCharacterSelect = function(){
let initCharacterSelect = () => {
/**
* init panel animation for an element
* @param imageWrapperElement
*/
let initCharacterAnimation = function(imageWrapperElement){
imageWrapperElement.velocity('stop').velocity('transition.flipBounceXIn', {
display: 'inline-block',
let initCharacterAnimation = imageWrapperElement => {
$(imageWrapperElement).velocity('stop').velocity('transition.flipBounceXIn', {
display: 'block',
drag: true,
duration: 500
});
// Hover effect for character info layer
imageWrapperElement.hoverIntent(function(e){
$(imageWrapperElement).hoverIntent(function(e){
let characterInfoElement = $(this).find('.' + config.characterImageInfoClass);
characterInfoElement.velocity('finish').velocity({
@@ -586,43 +586,14 @@ define([
};
// --------------------------------------------------------------------
/**
* update all character panels -> set CSS class (e.g. after some panels were added/removed,..)
*/
let updateCharacterPanels = function(){
let characterRows = $('.' + config.characterSelectionClass + ' .' + Util.config.dynamicAreaClass).parent();
let rowClassIdentifier = ((12 / characterRows.length ) <= 3) ? 3 : (12 / characterRows.length);
$(characterRows).removeClass().addClass('col-sm-' + rowClassIdentifier);
let removeCharacterPanel = panelElement => {
let charBox = panelElement.closest(`.${config.characterBoxClass}`);
charBox.classList.add('remove');
charBox.addEventListener('animationend', () => charBox.parentNode.removeChild(charBox));
};
// --------------------------------------------------------------------
let removeCharacterPanel = function(panelElement){
$(panelElement).velocity('transition.expandOut', {
duration: 250,
complete: function(){
// lock row for CSS animations while removing...
$(this).parent().addClass(config.characterRowAnimateClass);
$(this).parent().velocity({
width: 0
},{
easing: 'ease',
duration: 300,
complete: function(){
$(this).remove();
// reset column CSS classes for all existing panels
updateCharacterPanels();
}
});
}
});
};
// --------------------------------------------------------------------
let getCharacterAuthLabel = (authStatus) => {
let getCharacterAuthLabel = authStatus => {
let label = '';
switch(authStatus){
case 'UNKNOWN':
@@ -642,15 +613,13 @@ define([
// --------------------------------------------------------------------
// request character data for each character panel
requirejs(['text!templates/ui/character_panel.html', 'mustache'], function(template, Mustache){
requirejs(['text!templates/ui/character_panel.html', 'mustache'], (template, Mustache) => {
$('.' + config.characterSelectionClass + ' .' + Util.config.dynamicAreaClass).each(function(){
let characterElement = $(this);
characterElement.showLoadingAnimation();
[...document.querySelectorAll(`.${config.characterSelectionClass} .${Util.config.dynamicAreaClass}`)].forEach(charEl => {
$(charEl).showLoadingAnimation();
let requestData = {
cookie: characterElement.data('cookie')
cookie: charEl.dataset.cookie
};
$.ajax({
@@ -660,11 +629,11 @@ define([
dataType: 'json',
context: {
cookieName: requestData.cookie,
characterElement: characterElement,
charEl: charEl,
browserTabId: Util.getBrowserTabId()
}
}).done(function(responseData, textStatus, request){
this.characterElement.hideLoadingAnimation();
$(this.charEl).hideLoadingAnimation();
if(
responseData.error &&
@@ -679,9 +648,8 @@ define([
}
if(responseData.hasOwnProperty('character')){
let data = {
link: this.characterElement.data('href'),
link: this.charEl.dataset.href,
cookieName: this.cookieName,
browserTabId: this.browserTabId,
ccpImageServer: responseData.ccpImageServer,
@@ -693,21 +661,19 @@ define([
hasActiveSession: responseData.character.hasActiveSession === true
};
let content = Mustache.render(template, data);
this.characterElement.html(content);
this.charEl.innerHTML = Mustache.render(template, data);
// show character panel (animation settings)
initCharacterAnimation(this.characterElement.find('.' + config.characterImageWrapperClass));
initCharacterAnimation(this.charEl.querySelector(`.${config.characterImageWrapperClass}`));
}else{
// character data not available -> remove panel
removeCharacterPanel(this.characterElement);
removeCharacterPanel(this.charEl);
}
}).fail(function(jqXHR, status, error){
let characterElement = this.characterElement;
characterElement.hideLoadingAnimation();
$(this.charEl).hideLoadingAnimation();
// character data not available -> remove panel
removeCharacterPanel(this.characterElement);
removeCharacterPanel(this.charEl);
});
});
});
@@ -847,7 +813,7 @@ define([
// draw header logo
document.querySelector(`.logo-ploygon-top-right`).addEventListener('animationend', () => {
HeaderLogin.init(document.getElementById(config.headerContainerId));
HeaderLogin.init();
});
});
});

View File

@@ -60,27 +60,34 @@ define([
// map menu options
let mapOptions = {
mapSnapToGrid : {
buttonId: Util.config.menuButtonGridId,
description: 'Grid snapping',
class: 'mapGridClass'
},
mapMagnetizer: {
buttonId: Util.config.menuButtonMagnetizerId,
description: 'Magnetizer',
onEnable: Magnetizer.initMagnetizer,
onDisable: Magnetizer.destroyMagnetizer
},
mapSnapToGrid : {
buttonId: Util.config.menuButtonGridId,
description: 'Grid snapping',
class: 'mapGridClass'
systemRegion : {
buttonId: Util.config.menuButtonRegionId,
description: 'Region names',
class: 'systemRegionClass',
onEnable: MapOverlay.toggleInfoSystemRegion,
onDisable: MapOverlay.toggleInfoSystemRegion,
},
mapSignatureOverlays : {
systemCompact : {
buttonId: Util.config.menuButtonCompactId,
description: 'Compact system layout',
class: 'systemCompactClass'
},
connectionSignatureOverlays : {
buttonId: Util.config.menuButtonEndpointId,
description: 'Endpoint overlay',
onEnable: MapOverlay.showInfoSignatureOverlays,
onDisable: MapOverlay.hideInfoSignatureOverlays,
},
mapCompact : {
buttonId: Util.config.menuButtonCompactId,
description: 'Compact system layout',
class: 'mapCompactClass'
}
};
@@ -930,7 +937,7 @@ define([
connection.setConnector(newConnector);
// we need to "reapply" the types after "Connector" was changed
connection.reapplyTypes();
// connection.reapplyTypes();
}
// add endpoint types ---------------------------------------------------------------------------------
@@ -1203,7 +1210,7 @@ define([
// show static overlay actions
let mapOverlay = MapOverlayUtil.getMapOverlay(mapContainer, 'info');
mapOverlay.updateOverlayIcon('systemRegion', 'show');
mapOverlay.updateOverlayIcon('systemPopover', 'show');
mapOverlay.updateOverlayIcon('connection', 'show');
mapOverlay.updateOverlayIcon('connectionEol', 'show');
@@ -1429,7 +1436,7 @@ define([
*/
let showInfoSignatureOverlays = payload => new Promise(resolve => {
Util.getLocalStore('map').getItem(payload.data.mapConfig.config.id).then(dataStore => {
if(dataStore && dataStore.mapSignatureOverlays){
if(dataStore && dataStore.connectionSignatureOverlays){
MapOverlay.showInfoSignatureOverlays($(payload.data.mapConfig.map.getContainer()));
}
resolve(payload);
@@ -2034,6 +2041,7 @@ define([
// system click events ========================================================================================
let double = function(e){
e.stopPropagation(); // if not xEditable triggers page reload #945
let system = $(this);
let headElement = $(system).find('.' + config.systemHeadNameClass);
@@ -2888,7 +2896,7 @@ define([
}
// compact/small system layout or not
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
let compactView = mapElement.hasClass(MapUtil.config.systemCompactClass);
// get current character log data
let characterLogSystemId = Util.getObjVal(Util.getCurrentCharacterData('log'), 'system.id') || 0;

View File

@@ -80,21 +80,22 @@ define([
* get overlay parameters for connection overlay (type 'diamond' or 'arrow')
* @param overlayType
* @param direction
* @param prefix for obj keys -> for parameterized Overlays
* @returns {{length: number, foldback: number, direction: number}}
*/
let getConnectionArrowOverlayParams = (overlayType, direction = 1) => {
let getConnectionArrowOverlayParams = (overlayType, direction = 1, prefix = 'arrow') => {
switch(overlayType){
case 'arrow':
return {
length: 15,
direction: direction,
foldback: 0.8
[`${prefix}length`]: 15,
[`${prefix}direction`]: direction,
[`${prefix}foldback`]: 0.8
};
default: // diamond
return {
length: 10,
direction: 1,
foldback: 2
[`${prefix}length`]: 10,
[`${prefix}direction`]: 1,
[`${prefix}foldback`]: 2
};
}
};
@@ -109,6 +110,8 @@ define([
connectionsData = Util.arrayToObject(connectionsData);
map.setSuspendDrawing(true);
// ... redraw should be suspended (no repaint until function ends)
let doNotRepaint = map.isSuspendDrawing();
map.getAllConnections().forEach(connection => {
let connectionId = connection.getParameter('connectionId');
@@ -121,6 +124,7 @@ define([
let sizeLockedBySignature = false;
if(connection.scope === 'wh'){
/* TODO check if we still need this, commented out after jsPlumb `v2.9.3` → `v2.13.1` upgrade
if(!connection.hasType(type)){
connection.addType(type);
}
@@ -128,10 +132,11 @@ define([
let overlayArrow = connection.getOverlay(MapOverlayUtil.config.connectionOverlayArrowId);
// Arrow overlay needs to be cleared() (removed) if 'info_signature' gets removed!
// jsPlumb does not handle overlay updates for Arrow overlays... so we need to re-apply the the overlay manually
// jsPlumb does not handle overlay updates for Arrow overlays... so we need to re-apply the overlay manually
if(overlayArrow.path && !overlayArrow.path.isConnected){
connection.canvas.appendChild(overlayArrow.path);
}
*/
// since there "could" be multiple sig labels on each endpoint,
// there can only one "primary label picked up for wormhole jump mass detection!
@@ -187,7 +192,13 @@ define([
);
}
overlayArrow.updateFrom(getConnectionArrowOverlayParams(overlayType, arrowDirection));
let arrowParams = getConnectionArrowOverlayParams(overlayType, arrowDirection);
if(!connection.hasType(type)){
connection.addType(type, arrowParams, doNotRepaint);
}else{
connection.reapplyTypes(arrowParams, doNotRepaint);
}
// update/add endpoint overlays -------------------------------------------------------------------
updateEndpointOverlaySignatureLabel(sourceEndpoint, signatureTypeData.source);
@@ -213,7 +224,7 @@ define([
}else{
// connection is not 'wh' scope
if(connection.hasType(type)){
connection.removeType(type);
connection.removeType(type, undefined, doNotRepaint);
}
}
@@ -277,7 +288,7 @@ define([
let connectionsData = Util.getObjVal(mapData, 'data.connections');
if(connectionsData){
let overlayIcon = getOverlayIcon(mapElement, options.mapSignatureOverlays.class);
let overlayIcon = getOverlayIcon(mapElement, options.connectionSignatureOverlays.class);
showLoading(overlayIcon);
updateInfoSignatureOverlays(map, connectionsData);
hideLoading(overlayIcon);
@@ -312,6 +323,17 @@ define([
map.setSuspendDrawing(false, true);
};
/**
* callback after applying map option "systemRegion"
* -> system dimension changed -> redraw connections
* @param mapElement
*/
let toggleInfoSystemRegion = mapElement => {
let mapId = mapElement.data('id');
let map = MapUtil.getMapInstance(mapId);
map.repaintEverything();
};
/**
* Overlay options (all available map options shown in overlay)
* "active": (active || hover) indicated whether an icon/option
@@ -325,32 +347,50 @@ define([
trigger: 'active',
class: 'pf-map-overlay-filter',
iconClass: ['fas', 'fa-fw', 'fa-filter'],
onClick: function(e){
onClick: function(e){
// clear all filter
let mapElement = MapOverlayUtil.getMapElementFromOverlay(this);
let map = getMapObjectFromOverlayIcon(this);
MapUtil.storeLocalData('map', mapElement.data('id'), 'filterScopes', []);
Util.getLocalStore('map').setItem(`${mapElement.data('id')}.filterScopes`, []);
MapUtil.filterMapByScopes(map, []);
}
},
mapSnapToGrid: {
title: 'active grid',
title: 'grid',
trigger: 'active',
class: 'pf-map-overlay-grid',
iconClass: ['fas', 'fa-fw', 'fa-th']
},
mapMagnetizer: {
title: 'active magnetizer',
title: 'magnetizer',
trigger: 'active',
class: 'pf-map-overlay-magnetizer',
iconClass: ['fas', 'fa-fw', 'fa-magnet']
},
systemRegion: {
title: 'show regions',
trigger: 'hover',
title: 'regions',
trigger: 'active',
class: 'pf-map-overlay-region',
iconClass: ['fas', 'fa-fw', 'fa-tags'],
iconClass: ['fas', 'fa-fw', 'fa-map-marked-alt']
},
systemCompact: {
title: 'compact layout',
trigger: 'active',
class: 'pf-map-overlay-compact',
iconClass: ['fas', 'fa-fw', 'fa-compress']
},
connectionSignatureOverlays: {
title: 'signature overlays',
trigger: 'active',
class: 'pf-map-overlay-endpoint',
iconClass: ['fas', 'fa-fw', 'fa-link']
},
systemPopover: {
title: 'sovereignty',
trigger: 'hover',
class: 'pf-map-overlay-popover',
iconClass: ['fas', 'fa-fw', 'fa-landmark'],
hoverIntent: {
over: function(e){
let mapElement = MapOverlayUtil.getMapElementFromOverlay(this);
@@ -360,17 +400,17 @@ define([
if(!systemHead.data('bs.popover')){
let system = systemHead.parent();
let systemData = system.data();
systemHead.popover({
placement: 'bottom',
html: true,
trigger: 'manual',
container: mapElement,
title: false,
content: Util.getSystemRegionTable(
Util.getObjVal(systemData, 'region'),
Util.getObjVal(systemData, 'sovereignty')
)
});
let sovereignty = Util.getObjVal(systemData, 'sovereignty');
if(sovereignty){
systemHead.popover({
placement: 'bottom',
html: true,
trigger: 'manual',
container: mapElement,
title: false,
content: Util.getSystemSovereigntyTable(sovereignty)
});
}
}
systemHead.setPopoverSmall();
systemHead.popover('show');
@@ -382,18 +422,6 @@ define([
}
}
},
mapSignatureOverlays: {
title: 'active signature overlays',
trigger: 'active',
class: 'pf-map-overlay-endpoint',
iconClass: ['fas', 'fa-fw', 'fa-link']
},
mapCompact: {
title: 'compact layout',
trigger: 'active',
class: 'pf-map-overlay-compact',
iconClass: ['fas', 'fa-fw', 'fa-compress']
},
connection: {
title: 'WH data',
trigger: 'hover',
@@ -445,7 +473,7 @@ define([
}
},
connectionEol: {
title: 'EOL timer',
title: 'EOL',
trigger: 'hover',
class: 'pf-map-overlay-connection-eol',
iconClass: ['fas', 'fa-fw', 'fa-hourglass-end'],
@@ -861,9 +889,10 @@ define([
};
return {
showInfoSignatureOverlays: showInfoSignatureOverlays,
hideInfoSignatureOverlays: hideInfoSignatureOverlays,
updateZoomOverlay: updateZoomOverlay,
initMapDebugOverlays: initMapDebugOverlays
showInfoSignatureOverlays,
hideInfoSignatureOverlays,
toggleInfoSystemRegion,
updateZoomOverlay,
initMapDebugOverlays
};
});

View File

@@ -22,6 +22,7 @@ define([
systemHeadInfoClass: 'pf-system-head-info', // class for system info
systemHeadInfoLeftClass: 'pf-system-head-info-left', // class for left system info
systemHeadInfoRightClass: 'pf-system-head-info-right', // class for right system info
systemHeadRegionClass: 'pf-system-head-region', // class for "region" in system info
systemTooltipInnerIdPrefix: 'pf-system-tooltip-inner-', // id prefix for system tooltip content
systemTooltipInnerClass: 'pf-system-tooltip-inner', // class for system tooltip content
@@ -765,19 +766,32 @@ define([
* get new dom element for systemData that shows "info" data (additional data)
* -> this is show below the system base data on map
* @param data
* @returns {*}
* @returns {HTMLDivElement|undefined}
*/
let getHeadInfoElement = data => {
let headInfo = null;
let infoEl;
let headInfoLeft = [];
let headInfoRight = [];
if(data.drifter){
headInfoLeft.push('<i class="fas fa-fw fa-wave-square ' + Util.getSecurityClassForSystem(data.security) + '" title="drifter"></i>');
headInfoLeft.push(Object.assign(document.createElement('i'), {
className: `fas fa-fw fa-wave-square ${Util.getSecurityClassForSystem(data.security)}`,
title: 'drifter'
}));
}
if(data.shattered){
headInfoLeft.push('<i class="fas fa-fw fa-chart-pie ' + Util.getSecurityClassForSystem('SH') + '" title="shattered"></i>');
headInfoLeft.push(Object.assign(document.createElement('i'), {
className: `fas fa-fw fa-chart-pie ${Util.getSecurityClassForSystem('SH')}`,
title: 'shattered'
}));
}
if(data.type.id === 2){
headInfoLeft.push(Object.assign(document.createElement('span'), {
className: config.systemHeadRegionClass,
textContent: data.region.name
}));
}
// check systemData if headInfo element is needed
@@ -785,31 +799,36 @@ define([
// format wh statics
for(let wormholeName of data.statics){
let staticData = Object.assign({}, Init.wormholes[wormholeName]);
headInfoRight.push(
'<span class="' +
Util.getSecurityClassForSystem(staticData.security) + ' ' +
Util.config.popoverTriggerClass + '" data-name="' + staticData.name +
'">' + staticData.security + '</span>'
);
let staticEl = Object.assign(document.createElement('span'), {
className: [
Util.getSecurityClassForSystem(staticData.security),
Util.config.popoverTriggerClass
].join(' '),
textContent: staticData.security
});
staticEl.dataset.name = staticData.name;
headInfoRight.push(staticEl);
}
}
if(headInfoLeft.length || headInfoRight.length){
headInfo = $('<div>', {
class: config.systemHeadInfoClass
}).append(
$('<div>', {
class: config.systemHeadInfoLeftClass,
html: headInfoLeft.join('&nbsp;&nbsp;')
}),
$('<div>', {
class: config.systemHeadInfoRightClass,
html: headInfoRight.join('&nbsp;&nbsp;')
})
);
let leftEl = Object.assign(document.createElement('div'), {
className: config.systemHeadInfoLeftClass
});
leftEl.append(...headInfoLeft);
let rightEl = Object.assign(document.createElement('div'), {
className: config.systemHeadInfoRightClass
});
rightEl.append(...headInfoRight);
infoEl = Object.assign(document.createElement('div'), {
className: config.systemHeadInfoClass
});
infoEl.append(leftEl, rightEl);
}
return headInfo;
return infoEl;
};
return {

View File

@@ -19,7 +19,8 @@ define([
zoomMin: 0.5,
mapGridClass: 'pf-grid-small', // class for map grid snapping
mapCompactClass: 'pf-compact', // class for map compact system UI
systemRegionClass: 'pf-map-region', // class for systems regions on map
systemCompactClass: 'pf-map-compact', // class for compact systems on map
systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
@@ -1293,8 +1294,10 @@ define([
connection._jsPlumb.instance.setSuspendDrawing(true);
removeConnectionTypes(connection, types.diff(type));
addConnectionTypes(connection, type);
// ... redraw should be suspended (no repaint until function ends)
let doNotRepaint = connection._jsPlumb.instance.isSuspendDrawing();
removeConnectionTypes(connection, types.diff(type), [], doNotRepaint);
addConnectionTypes(connection, type, [], doNotRepaint);
connection._jsPlumb.instance.setSuspendDrawing(false, true);
};
@@ -1443,9 +1446,9 @@ define([
payload: mapConfig
});
// init compact system layout ---------------------------------------------------------------------
// init grid snap ---------------------------------------------------------------------------------
Util.triggerMenuAction(mapElement, 'MapOption', {
option: 'mapCompact',
option: 'mapSnapToGrid',
toggle: false
});
@@ -1455,15 +1458,21 @@ define([
toggle: false
});
// init grid snap ---------------------------------------------------------------------------------
// init compact system layout ---------------------------------------------------------------------
Util.triggerMenuAction(mapElement, 'MapOption', {
option: 'mapSnapToGrid',
option: 'systemRegion',
toggle: false
});
// init compact system layout ---------------------------------------------------------------------
Util.triggerMenuAction(mapElement, 'MapOption', {
option: 'systemCompact',
toggle: false
});
// init endpoint overlay --------------------------------------------------------------------------
Util.triggerMenuAction(mapElement, 'MapOption', {
option: 'mapSignatureOverlays',
option: 'connectionSignatureOverlays',
toggle: false,
skipOnEnable: true, // skip callback -> Otherwise it would run 2 times on map create
skipOnDisable: true // skip callback -> Otherwise it would run 2 times on map create

View File

@@ -5,6 +5,7 @@ define([
'app/map/map',
'app/map/util',
'app/lib/eventHandler',
'app/lib/svg',
'sortable',
'module/base',
'module/system_info',
@@ -23,6 +24,7 @@ define([
Map,
MapUtil,
EventHandler,
Svg,
Sortable,
BaseModule,
SystemInfoModule,
@@ -61,9 +63,13 @@ define([
editableHeadlineClass: 'pf-editable-headline',
editableToggleClass: 'pf-editable-toggle',
editableToggleItemClass: 'pf-editable-toggle-item',
editableToggleSvgClass: 'pf-editable-toggle-svg',
editableToggleBtnClass: 'pf-editable-toggle-btn',
mapTabContentLayoutOptions: ['left', 'right'],
defaultMapTabContentLayout: 'right',
mapTabContentLayoutColumnOptions: ['grid-2', 'grid-3'],
mapTabContentLayoutOrientationOptions: ['left', 'right'],
defaultMapTabContentCols: 'grid-3',
defaultMapTabContentOrientation: 'right',
};
let mapTabChangeBlocked = false; // flag for preventing map tab switch
@@ -1533,7 +1539,12 @@ define([
}
let setMapTabLayout = (tabEl, layoutNew) => {
config.mapTabContentLayoutOptions.forEach(layout => tabEl.classList.toggle(layout, layout === layoutNew));
config.mapTabContentLayoutColumnOptions.forEach(columns => tabEl.classList.toggle(columns, columns === layoutNew.columns));
config.mapTabContentLayoutOrientationOptions.forEach(orientation => tabEl.classList.toggle(orientation, orientation === layoutNew.orientation));
};
let getLayoutSvgLink = (layoutCols = config.defaultMapTabContentCols, orientation = config.defaultMapTabContentOrientation) => {
return `#pf-svg-${layoutCols}-${orientation}`;
};
Promise.all([
@@ -1542,8 +1553,11 @@ define([
]).then(payload => {
let modules = payload[0];
let localDataMap = payload[1];
let layoutCurrent = Util.getObjVal(localDataMap, 'layout') || config.defaultMapTabContentLayout;
let disabledValues = Util.getObjVal(localDataMap, 'modulesDisabled');
let layoutCurrent = Object.assign({}, {
columns: config.defaultMapTabContentCols,
orientation: config.defaultMapTabContentOrientation
}, Util.getObjVal(localDataMap, 'layout'));
// update mapModule with current layout class
setMapTabLayout(tabEl, layoutCurrent);
@@ -1601,40 +1615,98 @@ define([
// add "layout" toggle to popover -----------------------------------------------------------------
let anchorEl = editable.container.$form[0].querySelector(`.${config.editableSettingsClass}`);
let gridEl = Object.assign(document.createElement('div'), {
className: config.editableToggleClass
let toggleGroupEl = Object.assign(document.createElement('div'), {
className: [config.editableToggleClass].join(' ')
});
let gridItemEls = config.mapTabContentLayoutOptions.map(layout => {
let gridItemEl = Object.assign(document.createElement('div'), {
className: config.editableToggleItemClass + (layout === layoutCurrent ? ' active' : '')
let gridItemEls = config.mapTabContentLayoutColumnOptions.map((layoutCols, i) => {
let isActive = layoutCols === layoutCurrent.columns;
let orientation = isActive ? layoutCurrent.orientation : undefined;
let svgEl = Svg.newSymbolSvg(getLayoutSvgLink(layoutCols, orientation));
svgEl.classList.add('btn', 'btn-default', config.editableToggleSvgClass);
svgEl.dataset.value = layoutCols;
if(isActive){
svgEl.classList.add('active');
}
// left/right layout button
let btnEl = Object.assign(document.createElement('div'), {
className: ['btn', 'btn-xs', 'btn-default', config.editableToggleBtnClass].join(' ')
});
gridItemEl.style.setProperty('--bg-image', `url("${Util.imgRoot()}/icons/grid_${layout}.png")`);
gridItemEl.dataset.value = layout;
return gridItemEl;
btnEl.append(Object.assign(document.createElement('i'), {
className: ['fas', 'fa-rotate-90', 'fa-retweet'].join(' ')
}));
btnEl.dataset.value = 'left';
if(!isActive){
btnEl.classList.add('disabled');
}
if(orientation === btnEl.dataset.value){
btnEl.classList.add('active');
}
// btn group
let btnGroupEl = Object.assign(document.createElement('div'), {
className: ['btn-group', config.editableToggleItemClass].join(' ')
});
btnGroupEl.append(...(i % 2) ? [svgEl, btnEl] : [btnEl, svgEl]);
return btnGroupEl;
});
gridItemEls.splice(1, 0, Object.assign(document.createElement('i'), {
className: ['fas', 'fa-lg', 'fa-exchange-alt'].join(' ')
}));
gridEl.append(...gridItemEls);
anchorEl.insertAdjacentElement('beforebegin', gridEl);
toggleGroupEl.append(...gridItemEls);
anchorEl.insertAdjacentElement('beforebegin', toggleGroupEl);
// click event for layout switch -> change layout -> store new layout setting
EventHandler.addEventListener(gridEl, 'click.toggleSelect', e => {
if(e.target.classList.contains(config.editableToggleItemClass)){
let layoutNew = e.target.dataset.value;
if(layoutNew !== layoutCurrent){
gridItemEls.forEach(gridItemEl => gridItemEl.classList.toggle('active'));
let activeMapId = Util.getObjVal(editable, 'options.pk');
Util.getLocalStore('map').setItem(`${activeMapId}.layout`, layoutNew).then(layoutNew => {
setMapTabLayout(tabEl, layoutNew);
// for next "toggle" detection
layoutCurrent = layoutNew;
editable.option('pfLayoutCurrent', layoutNew);
});
}
EventHandler.addEventListener(toggleGroupEl, 'click.toggleSelect', e => {
e.stopPropagation();
// check if "click" bubbles up to .btn and button is not disabled
let btnEl = e.target.closest(`.btn`);
if(!btnEl || btnEl.classList.contains('disabled')){
return;
}
[...e.currentTarget.getElementsByClassName(config.editableToggleItemClass)].forEach(btnGroupEl => {
let svgEl = btnGroupEl.querySelector(`.${config.editableToggleSvgClass}`);
let btnEl = btnGroupEl.querySelector(`.${config.editableToggleBtnClass}`);
if(btnGroupEl === e.target.closest(`.${config.editableToggleItemClass}`)){
if(svgEl === e.target.closest(`.${config.editableToggleSvgClass}`)){
// click on SVG
svgEl.classList.toggle('active', true);
btnEl.classList.toggle('disabled', false);
}
if(btnEl === e.target.closest(`.${config.editableToggleBtnClass}`)){
// click on left/right btn
btnEl.classList.toggle('active');
// toggle SVG left/right
Svg.updateSymbolSvg(svgEl, getLayoutSvgLink(
svgEl.dataset.value,
btnEl.classList.contains('active') ? btnEl.dataset.value : undefined
));
}
// store new values
if(svgEl.classList.contains('active')){
let activeMapId = Util.getObjVal(editable, 'options.pk');
Util.getLocalStore('map').setItem(`${activeMapId}.layout`, {
'columns': svgEl.dataset.value,
'orientation': btnEl.classList.contains('active') ? btnEl.dataset.value : config.defaultMapTabContentOrientation
}).then(layoutNew => {
setMapTabLayout(tabEl, layoutNew);
// for next "toggle" detection
layoutCurrent = layoutNew;
editable.option('pfLayoutCurrent', layoutNew);
});
}
}else{
Svg.updateSymbolSvg(svgEl, getLayoutSvgLink(svgEl.dataset.value));
svgEl.classList.toggle('active', false);
btnEl.classList.toggle('active', false);
btnEl.classList.toggle('disabled', true);
}
});
}, {passive: false});
// add "headlines" to Modules checklist -------------------------------------------------------

View File

@@ -335,15 +335,6 @@ define([
let executor = resolve => {
$(pageMenuRightEl).append(getMenu([
{
type: 'button',
label: 'Information',
icon: 'fa-street-view',
action: 'ShowMapInfo',
data: {tab: 'information'}
},{
type: 'heading',
label: 'Configuration'
},{
type: 'button',
class: 'loading',
label: 'Settings',
@@ -351,6 +342,15 @@ define([
group: 'mapOptions',
action: 'ShowMapSettings',
data: {tab: 'settings'}
},{
type: 'button',
label: 'Information',
icon: 'fa-street-view',
action: 'ShowMapInfo',
data: {tab: 'information'}
},{
type: 'heading',
label: 'Map'
},{
type: 'button',
id: Util.config.menuButtonGridId,
@@ -371,26 +371,42 @@ define([
action: 'MapOption',
target: 'map',
data: {option: 'mapMagnetizer', toggle: true}
},{
type: 'heading',
label: 'System'
},{
type: 'button',
id: Util.config.menuButtonEndpointId,
id: Util.config.menuButtonRegionId,
class: 'loading',
label: 'Signatures',
icon: 'fa-link',
label: 'Region label',
icon: 'fa-map-marked-alt',
group: 'mapOptions',
action: 'MapOption',
target: 'map',
data: {option: 'mapSignatureOverlays', toggle: true}
data: {option: 'systemRegion', toggle: true}
},{
type: 'button',
id: Util.config.menuButtonCompactId,
class: 'loading',
label: 'Compact',
label: 'Compact view',
icon: 'fa-compress',
group: 'mapOptions',
action: 'MapOption',
target: 'map',
data: {option: 'mapCompact', toggle: true}
data: {option: 'systemCompact', toggle: true}
},{
type: 'heading',
label: 'Connection'
},{
type: 'button',
id: Util.config.menuButtonEndpointId,
class: 'loading',
label: 'Signature overlay',
icon: 'fa-link',
group: 'mapOptions',
action: 'MapOption',
target: 'map',
data: {option: 'connectionSignatureOverlays', toggle: true}
},{
type: 'heading',
label: 'Help'
@@ -445,6 +461,7 @@ define([
let executor = resolve => {
let svgPaths = [
'svg/logo_inline.svg',
'svg/grid_layout.svg',
'svg/swords.svg'
].map(path => `text!${Util.imgRoot()}${path}!strip`);

View File

@@ -24,6 +24,7 @@ define([
hiddenByAttributeClass: 'pf-hidden-by-attr', // class for elements that are hidden/shown by [data-attr] value
shownByAttributeClass: 'pf-shown-by-attr', // class for elements that are hidden/shown by [data-attr] value
webSocketSectionId: 'pf-setup-socket', // id for webSocket section
webSocketStatsId: 'pf-setup-webSocket-stats', // id for webSocket "stats" panel
webSocketRefreshStatsId: 'pf-setup-webSocket-stats-refresh', // class for "reload stats" button
@@ -399,8 +400,8 @@ define([
webSocketPanel.showLoadingAnimation();
let removeColorClasses = (el) => {
el.removeClass (function(index, css){
let removeColorClasses = el => {
el.removeClass(function(index, css){
return (css.match (/\btxt-color-\S+/g) || []).join(' ');
});
};
@@ -424,7 +425,7 @@ define([
statusIcon.toggleClass('fa-exclamation-triangle', false).toggleClass('fa-check', true).addClass('txt-color-success');
// update head badge. "Decrease" warning count, default for "URI" connection is "warn + 1"
socketWarningCount--;
socketWarningCount = Math.max(0, --socketWarningCount);
}
}
@@ -436,8 +437,8 @@ define([
// update head badge
switch(data.status.type){
case 'success':
socketWarningCount = '';
socketDangerCount = '';
socketWarningCount = 0;
socketDangerCount = 0;
break;
case 'warning':
break;
@@ -447,8 +448,11 @@ define([
}
}
badgeSocketWarning.text(socketWarningCount ? socketWarningCount : '');
badgeSocketDanger.text(socketDangerCount ? socketDangerCount : '');
badgeSocketWarning.text(socketWarningCount || '');
badgeSocketDanger.text(socketDangerCount || '');
// update section headline badges
document.querySelector(`#${config.webSocketSectionId} h4 .badge-warning`).textContent = socketWarningCount || '';
document.querySelector(`#${config.webSocketSectionId} h4 .badge-danger`).textContent = socketDangerCount || '';
};
// update initial

View File

@@ -357,6 +357,7 @@ define([
className: 'text-center',
searchable: false,
data: 'effect',
defaultContent: '',
render: {
display: (cellData, type, rowData, meta) => {
let value = '';
@@ -376,9 +377,11 @@ define([
render: {
_: (cellData, type, rowData, meta) => {
let statics = [];
for(let wormholeName of cellData){
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
statics.push('<span class="' + wormholeData.class + '">' + wormholeData.security + '</span>');
if(Array.isArray(cellData)) {
for (let wormholeName of cellData) {
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
statics.push('<span class="' + wormholeData.class + '">' + wormholeData.security + '</span>');
}
}
return statics.join('&nbsp;&nbsp;');
}

View File

@@ -51,8 +51,7 @@ define([
// close all modals
$('.modal').modal('hide');
requirejs(['text!templates/dialog/notification.html', 'mustache'], function(template, Mustache){
requirejs(['text!templates/dialog/notification.html', 'mustache'], (template, Mustache) => {
let data = {
id: config.notificationDialogId,
content: dialogData.content

View File

@@ -370,19 +370,14 @@ define([
$.when(
selectElement.select2({
ajax: {
url: function(params){
// add params to URL
return Init.path.searchUniverseSystemData + '/' + params.term.trim();
},
url: params => `${Init.path.api}/SystemSearch/${params.term.trim()}`,
dataType: 'json',
delay: 250,
timeout: 5000,
cache: true,
data: function(params){
return {
page: params.page || 1
};
},
data: params => ({
page: params.page || 1
}),
processResults: function(data, params){
// parse the results into the format expected by Select2.
return {
@@ -392,7 +387,7 @@ define([
let disabled = false;
let trueSec = parseFloat(item.trueSec);
let secClass = Util.getSecurityClassForSystem(item.security);
let trueSecClass = Util.getTrueSecClassForSystem( trueSec );
let trueSecClass = Util.getTrueSecClassForSystem(trueSec);
let effectClass = MapUtil.getEffectInfoForSystem(item.effect, 'class');
// check if system is dialed

View File

@@ -179,12 +179,18 @@ define([
this.resizeWindow();
this._mouse = this._config.startCoordinates(this._canvas);
this._ctx = this._canvas.getContext('2d', {alpha: true, desynchronized: true});
this._ctx = this._canvas.getContext('2d', {
alpha: true,
desynchronized: false,
preserveDrawingBuffer: true
});
this.initHandlers();
// must be bind to this instance -> https://stackoverflow.com/a/46014225/4329969
this.onPointerDown = this.onPointerDown.bind(this);
this.onPointerOver = this.onPointerOver.bind(this);
this.onPointerEnter = this.onPointerEnter.bind(this);
this.onPointerOut = this.onPointerOut.bind(this);
this.onPointerLeave = this.onPointerLeave.bind(this);
this.onPointerMove = this.onPointerMove.bind(this);
@@ -204,6 +210,10 @@ define([
return (typeof this._config.isPaused === 'function') ? this._config.isPaused(this) : this._config.isPaused;
}
eventContainer(){
return this._config.container ? this._config.container : this._canvas;
}
findSiblings(){
let node1, node2, distance;
for(let i = 0; i < this._nodesQty; i++){
@@ -335,8 +345,14 @@ define([
}
initHandlers(){
this._canvas.addEventListener('pointerover', e => this.onPointerEnter(e), {passive: true});
this._canvas.addEventListener('pointermove', e => this.onPointerMove(e), {passive: true});
let passive = true;
this.eventContainer().addEventListener('pointerover', e => this.onPointerOver(e), {passive: passive});
this.eventContainer().addEventListener('pointerenter', e => this.onPointerEnter(e), {passive: passive});
this.eventContainer().addEventListener('pointermove', e => this.onPointerMove(e), {passive: passive});
this.eventContainer().addEventListener('pointerout', e => this.onPointerOut(e), {passive: passive});
this.eventContainer().addEventListener('pointerleave', e => this.onPointerLeave(e), {passive: passive});
}
initPointerLock(){
@@ -345,18 +361,17 @@ define([
}
let lockChange = (e) => {
/*
if(document.pointerLockElement === this._canvas){
this._canvas.addEventListener('pointermove', this.onPointerMove, {passive: true});
this.eventContainer().classList.add(this._config.pointerLockedClass);
//this.eventContainer().addEventListener('pointermove', this.onPointerMove, {passive: true});
}else{
this._canvas.removeEventListener('pointermove', this.onPointerMove, {passive: true});
}*/
this.eventContainer().classList.remove(this._config.pointerLockedClass);
//this.eventContainer().removeEventListener('pointermove', this.onPointerMove, {passive: true});
}
};
//this._canvas.requestPointerLock()
this._canvas.addEventListener('pointerdown', this.onPointerDown, false);
//this._canvas.addEventListener('mouseenter', this.onPointerEnter, false);
//this._canvas.addEventListener('mouseleave', this.onPointerLeave, false);
document.addEventListener('pointerlockchange', lockChange, false);
}
@@ -379,6 +394,7 @@ define([
}
onPointerMove(e){
e.preventDefault();
let x = this._mouse.x + Math.floor(e.movementX);
let y = this._mouse.y + Math.floor(e.movementY);
@@ -403,12 +419,18 @@ define([
}
}
onPointerEnter(e){
onPointerOver(e){
e.preventDefault();
this._mouse.x = e.clientX;
this._mouse.y = e.clientY;
}
onPointerEnter(e){}
onPointerOut(e){}
onPointerLeave(e){
e.preventDefault();
document.exitPointerLock();
}
@@ -445,6 +467,7 @@ define([
StarCanvas.defaultConfig = {
pointerLockedClass: 'pointer-locked',
// limit render interval to max fps
// lower fps == less CPU
fps: 80,
@@ -477,6 +500,9 @@ define([
}),
// callback/boolean to pause canvas updated (e.g. while page scroll). Better scroll performance
isPaused: false,
// wrapper container for pointer events (e.g. document)
container: false,
// enables Pointer Lock API - https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API
pointerLock: true
};
@@ -492,7 +518,8 @@ define([
x: canvas.width / 2 + 500,
y: canvas.height / 2 + 50
}),
isPaused: () => document.body.classList.contains('on-scroll')
isPaused: () => document.body.classList.contains('on-scroll'),
container: document.getElementById(config.headerId)
};
if(navigator.userAgent.indexOf('Chrome') > -1){
@@ -532,34 +559,26 @@ define([
});
}
let init = headerEl => {
let previewEls = headerEl.getElementsByClassName(config.previewElementClass);
let init = () => {
$(previewEls).velocity('transition.bounceIn', {
duration: 600,
stagger: 60,
delay: 120,
complete: function(){
let canvas = document.getElementById(config.canvasId);
// not on mobile
if(canvas){
let starCanvasInstance = new StarCanvas(canvas, defaultConfig);
canvas.classList.add('in');
let canvas = document.getElementById(config.canvasId);
// not on mobile
if(canvas){
let starCanvasInstance = new StarCanvas(canvas, defaultConfig);
canvas.classList.add('in');
// watch for resize
Util.getResizeManager().observe(
canvas.parentNode,
(el, contentRect) => {
// ignore "height" change (css transition) (no canvas repaint)
if(canvas.width !== contentRect.width){
starCanvasInstance.resizeWindow();
}
},
{debounce: true, ms: 260}
);
}
}
});
// watch for resize
Util.getResizeManager().observe(
canvas.parentNode,
(el, contentRect) => {
// ignore "height" change (css transition) (no canvas repaint)
if(canvas.width !== contentRect.width){
starCanvasInstance.resizeWindow();
}
},
{debounce: true, ms: 260}
);
}
};
return {

View File

@@ -46,8 +46,15 @@ define([
]);
iconKbEl.setAttribute('title', 'zkillboard.com');
iconKbEl.onclick = e => this.openKillboardUrl(e);
let iconRegKbEl = this.newIconElement([
'fa-map-marked-alt', 'fa-fw',
this._config.moduleHeadlineIconClass
]);
iconRegKbEl.setAttribute('title', 'zkillboard.com region');
iconRegKbEl.onclick = e => this.openKillboardUrlRegion(e);
toolbarEl.append(iconKbEl, this._iconFilterEl);
toolbarEl.append(iconRegKbEl, iconKbEl, this._iconFilterEl);
headEl.append(wsStatusEl, toolbarEl);
return headEl;
@@ -554,7 +561,7 @@ define([
*/
openKillboardUrl(e){
e.stopPropagation();
window.open(`//zkillboard.com/system/${this._systemData.systemId}`, '_blank');
window.open(`//zkillboard.com/system/${this._systemData.systemId}/`, '_blank');
}
/**
@@ -578,6 +585,26 @@ define([
onWsMessage(zkbData, killmailData){
// check if killmail belongs to current filtered "streams"
if(this.filterKillmailByStreams(killmailData)){
if(!this._killboardEl){
// Remove label which indicates that there are no kills
let noKillsEl = this._bodyEl.querySelector('.label-success');
if(noKillsEl){
this._bodyEl.removeChild(noKillsEl);
}
// Initialize necessary container nodes
this._killboardEl = document.createElement('ul');
this._killboardEl.classList.add(this._config.systemKillboardListClass);
this._bodyEl.append(
this._killboardLabelEl,
this._killboardEl
);
}
// check max limit for WS kill entries
this._countKillsWS = (this._countKillsWS || 0) + 1;
if(this._countKillsWS > this._config.maxCountKillsWS){
@@ -727,7 +754,7 @@ define([
*/
static initWebSocket(){
if(!SystemKillboardModule.ws){
SystemKillboardModule.ws = new WebSocket('wss://zkillboard.com:2096');
SystemKillboardModule.ws = new WebSocket('wss://zkillboard.com/websocket/');
SystemKillboardModule.wsStatus = 1;
}

View File

@@ -33,7 +33,7 @@ define([
});
break;
case 'findRoute':
this.drawRouteTable(this._systemData.mapId, this._systemFromData, [payload.systemToData]);
this.drawRouteTable(this._systemData.mapId, this._systemFromData, [payload.systemToData], this._routeSettings);
break;
}
@@ -211,7 +211,7 @@ define([
// get current row data (important!)
// -> "rowData" param is not current state, values are "on createCell()" state
rowData = tableApi.row( $(cell).parents('tr')).data();
let routeData = module.getRouteRequestDataFromRowData(rowData);
let routeData = module.getRouteRequestDataFromRowData(rowData, module._routeSettings);
// overwrite some params
routeData.skipSearch = 0;
@@ -242,7 +242,7 @@ define([
// get current row data (important!)
// -> "rowData" param is not current state, values are "on createCell()" state
rowData = tableApi.row( $(cell).parents('tr')).data();
let routeData = module.getRouteRequestDataFromRowData(rowData);
let routeData = module.getRouteRequestDataFromRowData(rowData, module._systemData.mapId, module._routeSettings);
// overwrite some params
routeData.skipSearch = 0;
@@ -300,6 +300,9 @@ define([
}
},
initComplete: function(settings, json){
// create global settings object
// fill routesTable with data ---------------------------------------------------------------------
Util.getLocalStore('map').getItem(module._systemData.mapId).then(dataStore => {
// selected systems (if already stored)
@@ -314,12 +317,22 @@ define([
){
systemsTo = dataStore.routes;
}
// set global route settings from store
let routeSettings = {};
if(
dataStore &&
dataStore.routeSettings
){
routeSettings = dataStore.routeSettings
}
module._routeSettings = routeSettings
// add "Rally Point" systems to table
let systemsToData = module.getRallySystemsData(module._systemData.mapId);
systemsToData.push(...systemsTo);
module.drawRouteTable(module._systemData.mapId, module._systemFromData, systemsToData);
module.drawRouteTable(module._systemData.mapId, module._systemFromData, systemsToData, routeSettings);
});
// click on "fake connection" ---------------------------------------------------------------------
@@ -416,7 +429,7 @@ define([
* @param systemFromData
* @param systemsToData
*/
drawRouteTable(mapId, systemFromData, systemsToData){
drawRouteTable(mapId, systemFromData, systemsToData, routeSettings){
let requestRouteData = [];
// Skip some routes from search
@@ -441,7 +454,7 @@ define([
skipSearch: requestRouteData.length >= defaultRoutesCount
};
requestRouteData.push(this.getRouteRequestDataFromRowData(searchData));
requestRouteData.push(this.getRouteRequestDataFromRowData(searchData, routeSettings));
}
}
}
@@ -481,24 +494,25 @@ define([
* @param {Object} rowData
* @returns {Object}
*/
getRouteRequestDataFromRowData(rowData){
getRouteRequestDataFromRowData(rowData, routeSettings){
return {
mapIds: (rowData.hasOwnProperty('mapIds')) ? rowData.mapIds : [],
systemFromData: (rowData.hasOwnProperty('systemFromData')) ? rowData.systemFromData : {},
systemToData: (rowData.hasOwnProperty('systemToData')) ? rowData.systemToData : {},
skipSearch: (rowData.hasOwnProperty('skipSearch')) ? rowData.skipSearch | 0 : 0,
stargates: (rowData.hasOwnProperty('stargates')) ? rowData.stargates | 0 : 1,
jumpbridges: (rowData.hasOwnProperty('jumpbridges')) ? rowData.jumpbridges | 0 : 1,
wormholes: (rowData.hasOwnProperty('wormholes')) ? rowData.wormholes | 0 : 1,
wormholesReduced: (rowData.hasOwnProperty('wormholesReduced')) ? rowData.wormholesReduced | 0 : 1,
wormholesCritical: (rowData.hasOwnProperty('wormholesCritical')) ? rowData.wormholesCritical | 0 : 1,
wormholesEOL: (rowData.hasOwnProperty('wormholesEOL')) ? rowData.wormholesEOL | 0 : 1,
wormholesThera: (rowData.hasOwnProperty('wormholesThera')) ? rowData.wormholesThera | 0 : 1,
wormholesSizeMin: (rowData.hasOwnProperty('wormholesSizeMin')) ? rowData.wormholesSizeMin : '',
excludeTypes: (rowData.hasOwnProperty('excludeTypes')) ? rowData.excludeTypes : [],
endpointsBubble: (rowData.hasOwnProperty('endpointsBubble')) ? rowData.endpointsBubble | 0 : 1,
connections: (rowData.hasOwnProperty('connections')) ? rowData.connections.value | 0 : 0,
flag: (rowData.hasOwnProperty('flag')) ? rowData.flag.value : 'shortest'
mapIds: (rowData.hasOwnProperty('mapIds')) ? rowData.mapIds : [],
systemFromData: (rowData.hasOwnProperty('systemFromData')) ? rowData.systemFromData : {},
systemToData: (rowData.hasOwnProperty('systemToData')) ? rowData.systemToData : {},
skipSearch: (rowData.hasOwnProperty('skipSearch')) ? rowData.skipSearch | 0 : 0,
stargates: (rowData.hasOwnProperty('stargates')) ? rowData.stargates | 0 : routeSettings.stargates,
jumpbridges: (rowData.hasOwnProperty('jumpbridges')) ? rowData.jumpbridges | 0 : routeSettings.jumpbridges,
wormholes: (rowData.hasOwnProperty('wormholes')) ? rowData.wormholes | 0 : routeSettings.wormholes,
wormholesReduced: (rowData.hasOwnProperty('wormholesReduced')) ? rowData.wormholesReduced | 0 : routeSettings.wormholesReduced,
wormholesCritical: (rowData.hasOwnProperty('wormholesCritical')) ? rowData.wormholesCritical | 0 : routeSettings.wormholesCritical,
wormholesEOL: (rowData.hasOwnProperty('wormholesEOL')) ? rowData.wormholesEOL | 0 : routeSettings.wormholesEOL,
wormholesThera: (rowData.hasOwnProperty('wormholesThera')) ? rowData.wormholesThera | 0 : routeSettings.wormholesThera,
wormholesSizeMin: (rowData.hasOwnProperty('wormholesSizeMin')) ? rowData.wormholesSizeMin : routeSettings.wormholesSizeMin,
excludeTypes: (rowData.hasOwnProperty('excludeTypes')) ? rowData.excludeTypes : routeSettings.excludeTypes,
endpointsBubble: (rowData.hasOwnProperty('endpointsBubble')) ? rowData.endpointsBubble | 0 : routeSettings.endpointsBubble,
connections: (rowData.hasOwnProperty('connections')) ? rowData.connections.value | 0 : 0,
flag: (rowData.hasOwnProperty('flag')) ? rowData.flag.value : 'shortest'
};
}
@@ -532,7 +546,7 @@ define([
let routeData = [];
this._tableApi.rows().every(function(){
routeData.push(module.getRouteRequestDataFromRowData(this.data()));
routeData.push(module.getRouteRequestDataFromRowData(this.data(), module._systemData.mapId));
});
this.getRouteData({routeData: routeData}, 'callbackAddRouteRows');
@@ -873,14 +887,21 @@ define([
*/
showSettingsDialog(dialogData){
Util.getLocalStore('map').getItem(dialogData.mapId).then(dataStore => {
// selected systems (if already stored)
// selected systems and options (if already stored)
let systemSelectOptions = [];
let routeSettingsOptions = {};
if(
dataStore &&
dataStore.routes
){
systemSelectOptions = dataStore.routes;
}
if(
dataStore &&
dataStore.routeSettings
){
routeSettingsOptions = dataStore.routeSettings;
}
// max count of "default" target systems
let maxSelectionLength = Init.routeSearch.maxDefaultCount;
@@ -889,9 +910,20 @@ define([
id: this._config.routeSettingsDialogId,
selectClass: this._config.systemDialogSelectClass,
systemSelectOptions: systemSelectOptions,
maxSelectionLength: maxSelectionLength
maxSelectionLength: maxSelectionLength,
// new options
routeSettings: routeSettingsOptions,
select2Class: Util.config.select2Class,
routeDialogSizeSelectId: this._config.routeDialogSizeSelectId,
select2Class: Util.config.select2Class,
sizeOptions: MapUtil.allConnectionJumpMassTypes().map(type => ({
id: type,
name: type,
selected: false
}))
};
console.log(data);
requirejs(['text!templates/dialog/route_settings.html', 'mustache'], (template, Mustache) => {
let content = Mustache.render(template, data);
@@ -910,20 +942,42 @@ define([
callback: e => {
let form = $(e.delegateTarget).find('form');
// get all system data from select2
let systemSelectData = form.find('.' + this._config.systemDialogSelectClass).select2('data');
let systemsToData = [];
if(systemSelectData.length > 0){
systemsToData = SystemRouteModule.formSystemSelectData(systemSelectData);
Util.getLocalStore('map').setItem(`${dialogData.mapId}.routes`, systemsToData);
}else{
Util.getLocalStore('map').removeItem(`${dialogData.mapId}.routes`);
}
// route settings additions
let routeSettingsData = $(form).getFormValues();
if(
routeSettingsData
){
let routeSettings = {
stargates: routeSettingsData.hasOwnProperty('stargates') ? parseInt(routeSettingsData.stargates) : 0,
jumpbridges: routeSettingsData.hasOwnProperty('jumpbridges') ? parseInt(routeSettingsData.jumpbridges) : 0,
wormholes: routeSettingsData.hasOwnProperty('wormholes') ? parseInt(routeSettingsData.wormholes) : 0,
wormholesReduced: routeSettingsData.hasOwnProperty('wormholesReduced') ? parseInt(routeSettingsData.wormholesReduced) : 0,
wormholesCritical: routeSettingsData.hasOwnProperty('wormholesCritical') ? parseInt(routeSettingsData.wormholesCritical) : 0,
wormholesEOL: routeSettingsData.hasOwnProperty('wormholesEOL') ? parseInt(routeSettingsData.wormholesEOL) : 0,
wormholesThera: routeSettingsData.hasOwnProperty('wormholesThera') ? parseInt(routeSettingsData.wormholesThera) : 0,
wormholesSizeMin: routeSettingsData.wormholesSizeMin || '',
excludeTypes: SystemRouteModule.getLowerSizeConnectionTypes(routeSettingsData.wormholesSizeMin),
endpointsBubble: routeSettingsData.hasOwnProperty('endpointsBubble') ? parseInt(routeSettingsData.endpointsBubble) : 0,
};
Util.getLocalStore('map').setItem(`${dialogData.mapId}.routeSettings`, routeSettings);
}
// end route settings additions
this.showNotify({title: 'Route settings stored', type: 'success'});
// (re) draw table
this.drawRouteTable(dialogData.mapId, dialogData.systemFromData, systemsToData);
this.drawRouteTable(dialogData.mapId, dialogData.systemFromData, systemsToData, routeSettingsData);
}
}
}
@@ -935,6 +989,9 @@ define([
// -> add some delay until modal transition has finished
let systemTargetSelect = $(e.target).find('.' + this._config.systemDialogSelectClass);
systemTargetSelect.delay(240).initSystemSelect({key: 'id', maxSelectionLength: maxSelectionLength});
// init connection jump size select -------------------------------------------------------------------
$(e.target).find('#' + this._config.routeDialogSizeSelectId).initConnectionSizeSelect();
});
// show dialog

View File

@@ -3181,7 +3181,7 @@ define([
SystemSignatureModule.defaultConfig = {
className: 'pf-system-signature-module', // class for module
sortTargetAreas: ['a'], // sortable areas where module can be dragged into
sortTargetAreas: ['a', 'b', 'c'], // sortable areas where module can be dragged into
headline: 'Signatures',
// headline toolbar

View File

@@ -59,8 +59,9 @@ define([
menuButtonFullScreenId: 'pf-menu-button-fullscreen', // id for menu button "fullScreen"
menuButtonMagnetizerId: 'pf-menu-button-magnetizer', // id for menu button "magnetizer"
menuButtonGridId: 'pf-menu-button-grid', // id for menu button "grid snap"
menuButtonEndpointId: 'pf-menu-button-endpoint', // id for menu button "endpoint" overlays
menuButtonRegionId: 'pf-menu-button-region', // id for menu button "region" info on systems
menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view
menuButtonEndpointId: 'pf-menu-button-endpoint', // id for menu button "endpoint" overlays
menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map"
// footer
@@ -958,7 +959,7 @@ define([
const supportedPassiveTypes = [
'scroll', 'wheel',
'touchstart', 'touchmove', 'touchenter', 'touchend', 'touchleave',
//'mouseout', 'mouseleave', 'mouseup', 'mousedown', 'mousemove', 'mouseenter', 'mousewheel', 'mouseover'
'mouseout', 'mouseleave', 'mouseup', 'mousedown', 'mousemove', 'mouseenter', 'mousewheel', 'mouseover'
];
const getDefaultPassiveOption = (passive, eventName) => {
if(passive !== undefined) return passive;
@@ -2374,6 +2375,9 @@ define([
case '0.0':
areaId = 32;
break;
case 'T':
areaId = 33;
break;
default:
// w-space
for(let i = 1; i <= 18; i++){
@@ -2543,20 +2547,19 @@ define([
};
/**
* get a HTML table with universe region information
* get a HTML table with universe sovereignty data
* e.g. for popover
* @param regionName
* @param sovereignty
* @returns {string}
*/
let getSystemRegionTable = (regionName, sovereignty) => {
let data = [{label: 'Region', value: regionName}];
let getSystemSovereigntyTable = sovereignty => {
let data = [];
if(sovereignty){
if(sovereignty.faction){
data.push({label: 'Sov. Faction', value: sovereignty.faction.name});
data.push({label: 'Faction', value: sovereignty.faction.name});
}
if(sovereignty.alliance){
data.push({label: 'Sov. Ally', value: sovereignty.alliance.name});
data.push({label: 'Alliance', value: sovereignty.alliance.name});
}
}
@@ -3345,6 +3348,8 @@ define([
}
};
/**
* get ResizeManager instance
* @returns {ResizeManager}
@@ -3717,7 +3722,7 @@ define([
getSystemEffectData: getSystemEffectData,
getSystemEffectTable: getSystemEffectTable,
getSystemPlanetsTable: getSystemPlanetsTable,
getSystemRegionTable: getSystemRegionTable,
getSystemSovereigntyTable: getSystemSovereigntyTable,
getSystemPilotsTable: getSystemPilotsTable,
getSystemsInfoTable: getSystemsInfoTable,
getStatusInfoForCharacter: getStatusInfoForCharacter,

File diff suppressed because it is too large Load Diff

4
node_modules/.gitignore generated vendored
View File

@@ -1,4 +0,0 @@
#ignore all files in this dir...
*
#... except for this one.
!.gitignore

View File

@@ -1,6 +1,6 @@
{
"name": "pathfinder-eve",
"version": "2.0.0",
"version": "2.1.0",
"engines": {
"node": "12.x"
},

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Some files were not shown because too many files have changed in this diff Show More