Merge branch 'release/v1.9.0' of hardi/opt-cc into master
|
@ -45,11 +45,11 @@ Thumbs.db
|
||||||
.directory
|
.directory
|
||||||
|
|
||||||
# Internal Data
|
# Internal Data
|
||||||
public/
|
/public/
|
||||||
mongodb-data/
|
|
||||||
server/resource/
|
server/resource/
|
||||||
server/apib/dredd/data/tmp-resource
|
server/apib/dredd/data/tmp-resource
|
||||||
backup/
|
backup/
|
||||||
|
!backup.sh
|
||||||
|
|
||||||
# System
|
# System
|
||||||
.npm/
|
.npm/
|
||||||
|
@ -59,4 +59,3 @@ backup/
|
||||||
.cache/motd.legal-displayed
|
.cache/motd.legal-displayed
|
||||||
.profile
|
.profile
|
||||||
.ssh/
|
.ssh/
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
|
|
||||||
# array of available collection names
|
# array of available collection names
|
||||||
col=(app_user awarding campaign decoration logBudget logFlag logKill logPoints logRespawn logRevive logTransport logVehicle player promotion rank squad user war )
|
col=(app_user awarding campaign decoration logBudget logFlag logKill logPlayerCount logPoints logRespawn logRevive logServerFps logTransport logVehicle player promotion rank squad user war)
|
||||||
|
|
||||||
if [ -z "$1" ]
|
if [ -z "$1" ]
|
||||||
then
|
then
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<code_scheme name="OPT-CC" version="173">
|
<code_scheme name="OPT-CC" version="173">
|
||||||
<option name="FORMATTER_TAGS_ENABLED" value="true" />
|
<option name="FORMATTER_TAGS_ENABLED" value="true" />
|
||||||
<JSCodeStyleSettings>
|
<JSCodeStyleSettings version="0">
|
||||||
<option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" />
|
<option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" />
|
||||||
</JSCodeStyleSettings>
|
</JSCodeStyleSettings>
|
||||||
<TypeScriptCodeStyleSettings>
|
<TypeScriptCodeStyleSettings version="0">
|
||||||
<option name="USE_DOUBLE_QUOTES" value="false" />
|
<option name="USE_DOUBLE_QUOTES" value="false" />
|
||||||
<option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" />
|
<option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" />
|
||||||
</TypeScriptCodeStyleSettings>
|
</TypeScriptCodeStyleSettings>
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
<option name="RIGHT_MARGIN" value="120" />
|
<option name="RIGHT_MARGIN" value="120" />
|
||||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||||
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
|
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
|
||||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||||
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "opt-cc",
|
"name": "opt-cc",
|
||||||
"version": "1.8.6",
|
"version": "1.9.0",
|
||||||
"author": "Florian Hartwich <hardi@noarch.de>",
|
"author": "Florian Hartwich <hardi@noarch.de>",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -5,10 +5,13 @@ Update an army members signature image
|
||||||
**Permission: 4**
|
**Permission: 4**
|
||||||
|
|
||||||
+ Parameters
|
+ Parameters
|
||||||
|
|
||||||
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - army members unique user id
|
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - army members unique user id
|
||||||
|
|
||||||
+ Request (application/json)
|
+ Request (application/json)
|
||||||
{}
|
|
||||||
|
+ Attributes (object)
|
||||||
|
|
||||||
|
|
||||||
+ Response 200 (application/json; charset=utf-8)
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
### List Users [GET /users{?q,fractFilter,limit,offset}]
|
### List Users [GET /users{?q,fractFilter,squadId,decorationId,limit,offset}]
|
||||||
|
|
||||||
Get single army member information
|
Get single army member information
|
||||||
|
|
||||||
+ Parameters
|
+ Parameters
|
||||||
|
|
||||||
+ q: `hardi` (string, optional) - filter string which filters for partial username
|
+ q: `hardi` (string, optional) - filter string which filters for partial username
|
||||||
|
|
||||||
+ fractFilter: `BLUFOR` (enum[string], optional) - Field to filter by fraction
|
+ fractFilter: `BLUFOR` (enum[string], optional) - Field to filter by fraction
|
||||||
|
@ -12,17 +13,15 @@ Get single army member information
|
||||||
+ `OPFOR`
|
+ `OPFOR`
|
||||||
+ `GLOBAL`
|
+ `GLOBAL`
|
||||||
|
|
||||||
+ squadId: `591470249e9fae286e008e31` (string, optional) - Field to filter by membership of certain squad
|
+ squadId: `5aba54eaeadcce6332c6a774` (string, optional) - Field to filter by membership of certain squad
|
||||||
|
|
||||||
+ decorationId: `5abd3dff6e6a0334d95b8ba0` (string, optional) - Field to filter by ownership of certain decoration
|
+ decorationId: `5abd3dff6e6a0334d95b8ba0` (string, optional) - Field to filter by ownership of certain decoration
|
||||||
|
|
||||||
+ limit: 20 (number, optional)
|
+ limit: 20 (number, optional) - Maximum number of users to return
|
||||||
Maximum number of users to return
|
|
||||||
|
|
||||||
+ Default: Infinity
|
+ Default: Infinity
|
||||||
|
|
||||||
+ offset: 0 (number, optional)
|
+ offset: 0 (number, optional) - Offset into result-set (useful for pagination)
|
||||||
Offset into result-set (useful for pagination)
|
|
||||||
|
|
||||||
+ Default: 0
|
+ Default: 0
|
||||||
|
|
||||||
|
@ -40,6 +39,7 @@ Get single army member information
|
||||||
Get single army member information
|
Get single army member information
|
||||||
|
|
||||||
+ Parameters
|
+ Parameters
|
||||||
|
|
||||||
+ id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of army-member
|
+ id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of army-member
|
||||||
|
|
||||||
+ Response 200 (application/json; charset=utf-8)
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Campaign (object)
|
# Campaign (object)
|
||||||
|
|
||||||
Campaign entity
|
Campaign entity
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
@ -9,8 +10,10 @@ Campaign entity
|
||||||
+ __v: 0 (number, required) - version number
|
+ __v: 0 (number, required) - version number
|
||||||
|
|
||||||
#WarCampaign (object)
|
#WarCampaign (object)
|
||||||
|
|
||||||
Cmpaign entity with attached War collection
|
Cmpaign entity with attached War collection
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
+ _id: `5abd55ea9e30a76bfef747d6` (string, required) - unique id of the campaign
|
+ _id: `5abd55ea9e30a76bfef747d6` (string, required) - unique id of the campaign
|
||||||
+ title: `Ein Kessel Buntes` (string, required) - display title of the campaign
|
+ title: `Ein Kessel Buntes` (string, required) - display title of the campaign
|
||||||
+ wars (array[WarWithPlayers], requied)
|
+ wars: WarWithPlayers (array[WarWithPlayers], required)
|
||||||
|
|
|
@ -14,6 +14,8 @@ Basic player statistic information object
|
||||||
+ respawn: 2 (number, required) - sum of respawns
|
+ respawn: 2 (number, required) - sum of respawns
|
||||||
+ flagTouch: 1 (number, required) - sum of flag captures
|
+ flagTouch: 1 (number, required) - sum of flag captures
|
||||||
+ revive: 0 (number, required) - sum of revives
|
+ revive: 0 (number, required) - sum of revives
|
||||||
|
+ travelDistance: 16535 (number, optional) - sum of transport meters as passenger
|
||||||
|
+ driverDistance: 1250 (number, optional) - sum of transport meters as pilot/driver
|
||||||
|
|
||||||
|
|
||||||
# WarPlayer (BasicPlayer)
|
# WarPlayer (BasicPlayer)
|
||||||
|
@ -22,15 +24,16 @@ A player campaign statistics object
|
||||||
## Properties
|
## Properties
|
||||||
+ _id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of the army member
|
+ _id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of the army member
|
||||||
+ warId: `5abf65ae3fc5fa349ffd5ca3` (string, required) - war in which this player took part
|
+ warId: `5abf65ae3fc5fa349ffd5ca3` (string, required) - war in which this player took part
|
||||||
+ steamUUID: `76561192214911200` (string, required) - unique ID for STEAM platform account
|
+ steamUUID: 76561192214911200 (number, optional) - unique ID for STEAM platform account
|
||||||
+ sort: 1 (number, required) - sorting number calculated by (kill + revive + flagTouch - friendlyFire - death - respawn)
|
+ performance: `5abf65ae3fc5fa349ffd5cs2` (string, optional) - id of corresponding performance log entry
|
||||||
+ timestamp: `2018-02-24T01:01:25.825Z` - the entity creation timestamp
|
+ timestamp: `2018-02-24T01:01:25.825Z` - the entity creation timestamp
|
||||||
+ updatedAt: `2018-02-24T01:01:25.825Z` - the version timestamp
|
+ updatedAt: `2018-02-24T01:01:25.825Z` - the version timestamp
|
||||||
+ __v: 0 (number, required) - the version number of the object
|
+ __v: 0 (number, required) - the version number of the object
|
||||||
|
|
||||||
|
|
||||||
# HighscorePlayer (BasicPlayer)
|
# HighscorePlayer (BasicPlayer)
|
||||||
A player object as resturned for the highscore arrays
|
A player object as returned for the highscore arrays
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
+ warId: War (War, required) - war in which this player took part
|
||||||
+ num: 1
|
+ num: 1
|
||||||
|
|
|
@ -23,4 +23,4 @@ A war as used in statistics
|
||||||
A war response object on creation
|
A war response object on creation
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
+ players (array[WarPlayer], required) - collection of all participating players with their statistics
|
+ players (array[WarPlayer], required, fixed-type) - collection of all participating players with their statistics
|
||||||
|
|
|
@ -16,56 +16,66 @@ FORMAT: 1A
|
||||||
|
|
||||||
# Group Access
|
# Group Access
|
||||||
|
|
||||||
|
## Endpoints [/auth]
|
||||||
|
|
||||||
:[Gists](auth/signup.apib)
|
:[Gists](auth/signup.apib)
|
||||||
|
|
||||||
:[Gists](auth/login.apib)
|
:[Gists](auth/login.apib)
|
||||||
|
|
||||||
# Group Admin
|
# Group Admin
|
||||||
|
|
||||||
|
## Account [/account]
|
||||||
|
|
||||||
:[Gists](admin/account.apib)
|
:[Gists](admin/account.apib)
|
||||||
|
|
||||||
|
## Commands [/cmd]
|
||||||
|
|
||||||
:[Gists](admin/signature.apib)
|
:[Gists](admin/signature.apib)
|
||||||
|
|
||||||
# Group Army Overview
|
# Group Army Management
|
||||||
|
|
||||||
|
## Army [/overview]
|
||||||
|
|
||||||
:[Gists](army-management/army.apib)
|
:[Gists](army-management/army.apib)
|
||||||
|
|
||||||
# Group Awardings
|
## Awardings [/awarding]
|
||||||
|
|
||||||
:[Gists](army-management/awardings.apib)
|
:[Gists](army-management/awardings.apib)
|
||||||
|
|
||||||
# Group Campaigns
|
## Decorations [/decorations]
|
||||||
|
|
||||||
:[Gists](statistics/campaigns.apib)
|
|
||||||
|
|
||||||
# Group Decorations
|
|
||||||
|
|
||||||
:[Gists](army-management/decorations.apib)
|
:[Gists](army-management/decorations.apib)
|
||||||
|
|
||||||
# Group Logs
|
## Promotion [/promotions]
|
||||||
|
|
||||||
:[Gists](statistics/logs.apib)
|
|
||||||
|
|
||||||
# Group Players
|
|
||||||
|
|
||||||
:[Gists](statistics/players.apib)
|
|
||||||
|
|
||||||
# Group Promotion
|
|
||||||
|
|
||||||
:[Gists](army-management/promotions.apib)
|
:[Gists](army-management/promotions.apib)
|
||||||
|
|
||||||
# Group Ranks
|
## Ranks [/ranks]
|
||||||
|
|
||||||
:[Gists](army-management/ranks.apib)
|
:[Gists](army-management/ranks.apib)
|
||||||
|
|
||||||
# Group Squads
|
## Squads [/squads]
|
||||||
|
|
||||||
:[Gists](army-management/squads.apib)
|
:[Gists](army-management/squads.apib)
|
||||||
|
|
||||||
# Group Users
|
## Users [/user]
|
||||||
|
|
||||||
:[Gists](army-management/users.apib)
|
:[Gists](army-management/users.apib)
|
||||||
|
|
||||||
# Group Wars
|
# Group Statistics
|
||||||
|
|
||||||
|
## Campaigns [/campaigns]
|
||||||
|
|
||||||
|
:[Gists](statistics/campaigns.apib)
|
||||||
|
|
||||||
|
## Logs [/logs]
|
||||||
|
|
||||||
|
:[Gists](statistics/logs.apib)
|
||||||
|
|
||||||
|
## Players [/players]
|
||||||
|
|
||||||
|
:[Gists](statistics/players.apib)
|
||||||
|
|
||||||
|
## Wars [/wars]
|
||||||
|
|
||||||
:[Gists](statistics/wars.apib)
|
:[Gists](statistics/wars.apib)
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca4"},"name":"Pumarang","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119805032149e+16,"respawn":1,"kill":0,"vehicle":0,"friendlyFire":0,"death":1,"revive":0,"flagTouch":0,"sort":-2,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca4"},"name":"Pumarang","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119805032149e+16,"respawn":1,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":1,"revive":0,"flagTouch":0,"sort":-2,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca5"},"name":"Mercurat","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611982788425e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca5"},"name":"Mercurat","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611982788425e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca6"},"name":"KalleK","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119797767603e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca6"},"name":"KalleK","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119797767603e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca7"},"name":"MAPster","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119800988213e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca7"},"name":"MAPster","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119800988213e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca8"},"name":"LyrikEmu","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611982189104e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca8"},"name":"LyrikEmu","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611982189104e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca9"},"name":"Philipp","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119804179206e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca9"},"name":"Philipp","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119804179206e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5caa"},"name":"Wiesl","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611980596481e+16,"respawn":0,"kill":1,"vehicle":0,"friendlyFire":1,"death":0,"revive":1,"flagTouch":1,"sort":2,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5caa"},"name":"Wiesl","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611980596481e+16,"respawn":0,"kill":1,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":1,"death":0,"revive":1,"flagTouch":1,"sort":2,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cab"},"name":"Murda]X[","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119797112163e+16,"respawn":0,"kill":0,"vehicle":1,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cab"},"name":"Murda]X[","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119797112163e+16,"respawn":0,"kill":0,"vehicleLight":1,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbc"},"name":"Pumarang","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119805032149e+16,"respawn":1,"kill":0,"vehicle":0,"friendlyFire":0,"death":1,"revive":0,"flagTouch":0,"sort":-2,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbc"},"name":"Pumarang","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119805032149e+16,"respawn":1,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":1,"revive":0,"flagTouch":0,"sort":-2,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbd"},"name":"Mercurat","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611982788425e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbd"},"name":"Mercurat","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611982788425e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbe"},"name":"KalleK","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119797767603e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbe"},"name":"KalleK","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119797767603e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc1"},"name":"Philipp","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119804179206e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc1"},"name":"Philipp","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119804179206e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc0"},"name":"LyrikEmu","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611982189104e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc0"},"name":"LyrikEmu","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611982189104e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc2"},"name":"Wiesl","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611980596481e+16,"respawn":0,"kill":1,"vehicle":0,"friendlyFire":1,"death":0,"revive":1,"flagTouch":1,"sort":2,"timestamp":{"$date":"2018-03-31T10:41:28.460Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.460Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc2"},"name":"Wiesl","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611980596481e+16,"respawn":0,"kill":1,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":1,"death":0,"revive":1,"flagTouch":1,"sort":2,"timestamp":{"$date":"2018-03-31T10:41:28.460Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.460Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc3"},"name":"Murda]X[","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119797112163e+16,"respawn":0,"kill":0,"vehicle":1,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.460Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.460Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc3"},"name":"Murda]X[","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119797112163e+16,"respawn":0,"kill":0,"vehicleLight":1,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.460Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.460Z"},"__v":0}
|
||||||
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbf"},"name":"MAPster","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119800988213e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbf"},"name":"MAPster","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119800988213e+16,"respawn":0,"kill":0,"vehicleLight":0,"vehicleHeavy":0,"vehicleAir":0,"steamUUID":76561192214911200,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
|
|
|
@ -33,4 +33,4 @@ Get statistics for a single player for all wars of a campaign he took part at
|
||||||
+ Attributes
|
+ Attributes
|
||||||
+ name: `Pumarang` (string, required) - latest used playername
|
+ name: `Pumarang` (string, required) - latest used playername
|
||||||
+ campaign (Campaign,required) - campaign reflected from request is
|
+ campaign (Campaign,required) - campaign reflected from request is
|
||||||
+ players (array[WarPlayer],required) - collection of player instances in the campaign
|
+ players (array[HighscorePlayer],required, fixed-type) - collection of player instances in the campaign
|
||||||
|
|
|
@ -32,6 +32,7 @@ const LogBudgetSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logBudget',
|
collection: 'logBudget',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogBudgetSchema.index({war: 1});
|
LogBudgetSchema.index({war: 1});
|
||||||
|
|
|
@ -28,6 +28,7 @@ const LogFlagSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logFlag',
|
collection: 'logFlag',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogFlagSchema.index({war: 1, player: 1});
|
LogFlagSchema.index({war: 1, player: 1});
|
||||||
|
|
|
@ -40,6 +40,7 @@ const LogKillSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logKill',
|
collection: 'logKill',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const LogPlayerCountSchema = new Schema({
|
||||||
|
war: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'War',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
type: Date,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
countBlufor: {
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
countOpfor: {
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
collection: 'logPlayerCount',
|
||||||
|
versionKey: false,
|
||||||
|
});
|
||||||
|
// optional more indices
|
||||||
|
LogPlayerCountSchema.index({war: 1});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('LogPlayerCount', LogPlayerCountSchema);
|
|
@ -32,6 +32,7 @@ const LogKillSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logPoints',
|
collection: 'logPoints',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
|
@ -19,6 +19,7 @@ const LogRespawnSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logRespawn',
|
collection: 'logRespawn',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogRespawnSchema.index({war: 1, player: 1});
|
LogRespawnSchema.index({war: 1, player: 1});
|
||||||
|
|
|
@ -32,6 +32,7 @@ const LogReviveSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logRevive',
|
collection: 'logRevive',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogReviveSchema.index({war: 1, medic: 1});
|
LogReviveSchema.index({war: 1, medic: 1});
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const LogServerFpsSchema = new Schema({
|
||||||
|
war: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'War',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
entityName: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
singleAvgFps: {
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
singleMinFps: {
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
avgFps: [{
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
minFps: [{
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
}, {
|
||||||
|
collection: 'logServerFps',
|
||||||
|
versionKey: false,
|
||||||
|
});
|
||||||
|
// optional more indices
|
||||||
|
LogServerFpsSchema.index({war: 1});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('LogServerFps', LogServerFpsSchema);
|
|
@ -34,6 +34,7 @@ const LogTransportSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logTransport',
|
collection: 'logTransport',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogTransportSchema.index({war: 1, driver: 1});
|
LogTransportSchema.index({war: 1, driver: 1});
|
||||||
|
|
|
@ -41,6 +41,7 @@ const LogVehicleKillSchema = new Schema({
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logVehicle',
|
collection: 'logVehicle',
|
||||||
|
versionKey: false,
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1});
|
LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
|
@ -72,17 +72,30 @@ const PlayerSchema = new Schema({
|
||||||
set: (v) => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
sort: {
|
|
||||||
type: Number,
|
|
||||||
get: (v) => Math.round(v),
|
|
||||||
set: (v) => Math.round(v),
|
|
||||||
},
|
|
||||||
steamUUID: {
|
steamUUID: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: (v) => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: (v) => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
},
|
},
|
||||||
}, {
|
performance: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'LogServerFps',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
travelDistance: {
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
driverDistance: {
|
||||||
|
type: Number,
|
||||||
|
get: (v) => Math.round(v),
|
||||||
|
set: (v) => Math.round(v),
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
collection: 'player',
|
collection: 'player',
|
||||||
timestamps: {createdAt: 'timestamp'},
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,9 +12,22 @@ const checkMT = require('../middleware/permission-check').checkMT;
|
||||||
const routerHandling = require('../middleware/router-handling');
|
const routerHandling = require('../middleware/router-handling');
|
||||||
const idValidator = require('../middleware/validators').idValidator;
|
const idValidator = require('../middleware/validators').idValidator;
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const resourceLocation = require('../middleware/resource-location').resourceLocation().concat('/logs/');
|
||||||
|
|
||||||
// Mongoose Model using mongoDB
|
// Mongoose Model using mongoDB
|
||||||
const CampaignModel = require('../models/campaign');
|
const CampaignModel = require('../models/campaign');
|
||||||
const WarModel = require('../models/war');
|
const WarModel = require('../models/war');
|
||||||
|
const PlayerModel = require('../models/player');
|
||||||
|
const LogKillModel = require('../models/logs/kill');
|
||||||
|
const LogVehicleKillModel = require('../models/logs/vehicle');
|
||||||
|
const LogRespawnModel = require('../models/logs/respawn');
|
||||||
|
const LogReviveModel = require('../models/logs/revive');
|
||||||
|
const LogTransportModel = require('../models/logs/transport');
|
||||||
|
const LogFlagModel = require('../models/logs/flag');
|
||||||
|
const LogBudgetModel = require('../models/logs/budget');
|
||||||
|
const LogPointsModel = require('../models/logs/points');
|
||||||
|
const LogPlayerCountModel = require('../models/logs/player-count');
|
||||||
|
|
||||||
// util
|
// util
|
||||||
const genericGetById = require('./_generic').genericGetById;
|
const genericGetById = require('./_generic').genericGetById;
|
||||||
|
@ -88,20 +101,49 @@ campaigns.route('/:id')
|
||||||
})
|
})
|
||||||
|
|
||||||
.delete((req, res, next) => {
|
.delete((req, res, next) => {
|
||||||
CampaignModel.findByIdAndRemove(req.params.id, (err, item) => {
|
WarModel.find({campaign: req.params.id}, (err, wars) => {
|
||||||
if (err) {
|
wars.forEach((item) => {
|
||||||
err.status = codes.wrongrequest;
|
// delete linked appearances
|
||||||
return next(err);
|
PlayerModel.find({warId: item._id}).remove().exec();
|
||||||
} else if (!item) {
|
LogKillModel.find({war: item._id}).remove().exec();
|
||||||
err = new Error('item not found');
|
LogVehicleKillModel.find({war: item._id}).remove().exec();
|
||||||
err.status = codes.notfound;
|
LogRespawnModel.find({war: item._id}).remove().exec();
|
||||||
return next(err);
|
LogReviveModel.find({war: item._id}).remove().exec();
|
||||||
}
|
LogFlagModel.find({war: item._id}).remove().exec();
|
||||||
WarModel.find({campaign: req.params.id}).remove().exec();
|
LogBudgetModel.find({war: item._id}).remove().exec();
|
||||||
// TODO: remove all the war logs from fs here!!!
|
LogTransportModel.find({war: item._id}).remove().exec();
|
||||||
// TODO: remove all LOG entries from DB!!!
|
LogPointsModel.find({war: item._id}).remove().exec();
|
||||||
res.locals.processed = true;
|
LogPlayerCountModel.find({war: item._id}).remove().exec();
|
||||||
next();
|
|
||||||
|
// check if logfiles exist and delete from fs
|
||||||
|
const warDir = resourceLocation + item.id;
|
||||||
|
if (fs.existsSync(warDir)) {
|
||||||
|
const cleanLog = warDir + '/clean.log';
|
||||||
|
if (fs.existsSync(cleanLog)) {
|
||||||
|
fs.unlink(cleanLog, (err) => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const sourceLog = warDir + '/war.log';
|
||||||
|
if (fs.existsSync(sourceLog)) {
|
||||||
|
fs.unlink(sourceLog, (err) => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fs.rmdir(warDir, (err) => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CampaignModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.wrongrequest;
|
||||||
|
return next(err);
|
||||||
|
} else if (!item) {
|
||||||
|
err = new Error('item not found');
|
||||||
|
err.status = codes.notfound;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.locals.processed = true;
|
||||||
|
next();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
|
||||||
|
// HTTP status codes by name
|
||||||
|
const codes = require('./http-codes');
|
||||||
|
|
||||||
const routerHandling = require('../middleware/router-handling');
|
const routerHandling = require('../middleware/router-handling');
|
||||||
|
|
||||||
// Mongoose Model using mongoDB
|
// Mongoose Model using mongoDB
|
||||||
|
@ -15,6 +18,8 @@ const LogVehicleModel = require('../models/logs/vehicle');
|
||||||
const LogTransportModel = require('../models/logs/transport');
|
const LogTransportModel = require('../models/logs/transport');
|
||||||
const LogFlagModel = require('../models/logs/flag');
|
const LogFlagModel = require('../models/logs/flag');
|
||||||
const LogPointsModel = require('../models/logs/points');
|
const LogPointsModel = require('../models/logs/points');
|
||||||
|
const LogPlayerCountModel = require('../models/logs/player-count');
|
||||||
|
const LogServerFpsModel = require('../models/logs/server-fps');
|
||||||
|
|
||||||
const logsRouter = new express.Router();
|
const logsRouter = new express.Router();
|
||||||
|
|
||||||
|
@ -23,7 +28,7 @@ const processLogRequest = (model, filter, res, next) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
if (!log || log.length === 0) {
|
if (!log || log.length === 0) {
|
||||||
const err = new Error('No logs found');
|
const err = new Error('No logs found');
|
||||||
err.status = require('./http-codes').notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = log;
|
res.locals.items = log;
|
||||||
|
@ -45,6 +50,7 @@ logsRouter.route('/:warId')
|
||||||
const vehicleObjects = LogVehicleModel.find(filter, {}, sort);
|
const vehicleObjects = LogVehicleModel.find(filter, {}, sort);
|
||||||
const transportObjects = LogTransportModel.find(filter, {}, sort);
|
const transportObjects = LogTransportModel.find(filter, {}, sort);
|
||||||
const flagObjects = LogFlagModel.find(filter, {}, sort);
|
const flagObjects = LogFlagModel.find(filter, {}, sort);
|
||||||
|
const playerCountObjects = LogPlayerCountModel.find(filter, {}, sort);
|
||||||
const resources = {
|
const resources = {
|
||||||
points: pointsObjects.exec.bind(pointsObjects),
|
points: pointsObjects.exec.bind(pointsObjects),
|
||||||
budget: budgetObjects.exec.bind(budgetObjects),
|
budget: budgetObjects.exec.bind(budgetObjects),
|
||||||
|
@ -54,6 +60,7 @@ logsRouter.route('/:warId')
|
||||||
vehicle: killObjects.exec.bind(vehicleObjects),
|
vehicle: killObjects.exec.bind(vehicleObjects),
|
||||||
transport: transportObjects.exec.bind(transportObjects),
|
transport: transportObjects.exec.bind(transportObjects),
|
||||||
flag: flagObjects.exec.bind(flagObjects),
|
flag: flagObjects.exec.bind(flagObjects),
|
||||||
|
playerCount: playerCountObjects.exec.bind(playerCountObjects),
|
||||||
};
|
};
|
||||||
|
|
||||||
async.parallel(resources, (error, results) => {
|
async.parallel(resources, (error, results) => {
|
||||||
|
@ -151,6 +158,24 @@ logsRouter.route('/:warId/points')
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logsRouter.route('/:warId/performance')
|
||||||
|
.get((req, res, next) => {
|
||||||
|
const filter = {war: req.params.warId};
|
||||||
|
LogServerFpsModel.find(filter, (err, items) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
if (!items) {
|
||||||
|
const err = new Error('No logs found');
|
||||||
|
err.status = codes.notfound;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.locals.items = items;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
logsRouter.use(routerHandling.emptyResponse);
|
logsRouter.use(routerHandling.emptyResponse);
|
||||||
|
|
||||||
module.exports = logsRouter;
|
module.exports = logsRouter;
|
||||||
|
|
|
@ -33,6 +33,8 @@ const LogTransportModel = require('../models/logs/transport');
|
||||||
const LogFlagModel = require('../models/logs/flag');
|
const LogFlagModel = require('../models/logs/flag');
|
||||||
const LogBudgetModel = require('../models/logs/budget');
|
const LogBudgetModel = require('../models/logs/budget');
|
||||||
const LogPointsModel = require('../models/logs/points');
|
const LogPointsModel = require('../models/logs/points');
|
||||||
|
const LogPlayerCountModel = require('../models/logs/player-count');
|
||||||
|
const LogServerFpsModel = require('../models/logs/server-fps');
|
||||||
|
|
||||||
// util
|
// util
|
||||||
const genericPatch = require('./_generic').genericPatch;
|
const genericPatch = require('./_generic').genericPatch;
|
||||||
|
@ -58,53 +60,79 @@ wars.route('/')
|
||||||
})
|
})
|
||||||
|
|
||||||
.post(apiAuthenticationMiddleware, checkMT, upload.single('log'), (req, res, next) => {
|
.post(apiAuthenticationMiddleware, checkMT, upload.single('log'), (req, res, next) => {
|
||||||
const body = req.body;
|
const body = req.body;
|
||||||
const warBody = new WarModel(body);
|
const warBody = new WarModel(body);
|
||||||
|
|
||||||
if (req.file) {
|
if (req.file) {
|
||||||
fs.readFile(req.file.buffer, (file, err) => {
|
fs.readFile(req.file.buffer, (file, err) => {
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
const lineArray = file.toString().split('\n');
|
|
||||||
const statsResult = parseWarLog(lineArray, warBody);
|
|
||||||
statsResult.war.save((err, war) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
PlayerModel.create(statsResult.players, (err) => {
|
const lineArray = file.toString().split('\n');
|
||||||
|
const statsResult = parseWarLog(lineArray, warBody);
|
||||||
|
statsResult.war.save((err, war) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
LogKillModel.create(statsResult.kills, () => {
|
LogKillModel.create(statsResult.kills, (err) => {
|
||||||
LogVehicleKillModel.create(statsResult.vehicles, () => {
|
if (err) console.log(err);
|
||||||
LogRespawnModel.create(statsResult.respawn, () => {
|
LogVehicleKillModel.create(statsResult.vehicles, (err) => {
|
||||||
LogReviveModel.create(statsResult.revive, () => {
|
if (err) console.log(err);
|
||||||
LogFlagModel.create(statsResult.flag, () => {
|
LogRespawnModel.create(statsResult.respawn, (err) => {
|
||||||
LogBudgetModel.create(statsResult.budget, () => {
|
if (err) console.log(err);
|
||||||
LogTransportModel.create(statsResult.transport, () => {
|
LogReviveModel.create(statsResult.revive, (err) => {
|
||||||
LogPointsModel.create(statsResult.points, () => {
|
if (err) console.log(err);
|
||||||
const folderName = resourceLocation.concat(war._id);
|
LogFlagModel.create(statsResult.flag, (err) => {
|
||||||
mkdirp(folderName, (err) => {
|
if (err) console.log(err);
|
||||||
if (err) return next(err);
|
LogBudgetModel.create(statsResult.budget, (err) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
LogTransportModel.create(statsResult.transport, (err) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
LogPlayerCountModel.create(statsResult.playerCount, (err) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
LogPointsModel.create(statsResult.points, (err) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
LogServerFpsModel.create(statsResult.serverFps, (err, serverPerformanceEntries) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
if (serverPerformanceEntries) {
|
||||||
|
serverPerformanceEntries.forEach((entry) => {
|
||||||
|
const idx = statsResult.players
|
||||||
|
.findIndex((player) => player.name === entry.entityName);
|
||||||
|
if (idx !== -1) {
|
||||||
|
const player = statsResult.players[idx];
|
||||||
|
player['performance'] = entry._id;
|
||||||
|
statsResult.players[idx] = player;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
PlayerModel.create(statsResult.players, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
const folderName = resourceLocation.concat(war._id);
|
||||||
|
mkdirp(folderName, (err) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
|
||||||
// save clean log file
|
// save clean log file
|
||||||
const cleanFile = fs.createWriteStream(folderName + '/clean.log');
|
const cleanFile = fs.createWriteStream(folderName + '/clean.log');
|
||||||
statsResult.clean.forEach((cleanLine) => {
|
statsResult.clean.forEach((cleanLine) => {
|
||||||
cleanFile.write(cleanLine + '\n\n');
|
cleanFile.write(cleanLine + '\n\n');
|
||||||
|
});
|
||||||
|
cleanFile.end();
|
||||||
|
|
||||||
|
// save raw log file
|
||||||
|
const rawFile = fs.createWriteStream(folderName + '/war.log');
|
||||||
|
lineArray.forEach((rawLine) => {
|
||||||
|
rawFile.write(rawLine + '\n');
|
||||||
|
});
|
||||||
|
rawFile.end();
|
||||||
|
|
||||||
|
res.status(codes.created);
|
||||||
|
res.locals.items = war;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
cleanFile.end();
|
|
||||||
|
|
||||||
// save raw log file
|
|
||||||
const rawFile = fs.createWriteStream(folderName + '/war.log');
|
|
||||||
lineArray.forEach((rawLine) => {
|
|
||||||
rawFile.write(rawLine + '\n');
|
|
||||||
});
|
|
||||||
rawFile.end();
|
|
||||||
|
|
||||||
res.status(codes.created);
|
|
||||||
res.locals.items = war;
|
|
||||||
next();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -116,13 +144,13 @@ wars.route('/')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
} else {
|
||||||
} else {
|
const err = new Error('no Logfile provided');
|
||||||
const err = new Error('no Logfile provided');
|
err.status = codes.wrongmediasend;
|
||||||
err.status = codes.wrongmediasend;
|
next(err);
|
||||||
next(err);
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
.all(
|
.all(
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
|
@ -177,6 +205,7 @@ wars.route('/:id')
|
||||||
LogBudgetModel.find({war: item._id}).remove().exec();
|
LogBudgetModel.find({war: item._id}).remove().exec();
|
||||||
LogTransportModel.find({war: item._id}).remove().exec();
|
LogTransportModel.find({war: item._id}).remove().exec();
|
||||||
LogPointsModel.find({war: item._id}).remove().exec();
|
LogPointsModel.find({war: item._id}).remove().exec();
|
||||||
|
LogPlayerCountModel.find({war: item._id}).remove().exec();
|
||||||
|
|
||||||
// check if logfiles exist and delete from fs
|
// check if logfiles exist and delete from fs
|
||||||
const warDir = resourceLocation + req.params.id;
|
const warDir = resourceLocation + req.params.id;
|
||||||
|
|
|
@ -23,6 +23,20 @@ const vehicleRegex = /(vehicle:\s(.*?)\))/;
|
||||||
|
|
||||||
const categoryRegex = /(category:\s(.*?)\))/;
|
const categoryRegex = /(category:\s(.*?)\))/;
|
||||||
|
|
||||||
|
const bluforPlayerCountRegex = /NATO\s(\d*)/;
|
||||||
|
|
||||||
|
const opforPlayerCountRegex = /CSAT\s(\d*)/;
|
||||||
|
|
||||||
|
const timestampRegex = /LOG:\s(\d*:\d*:\d*)\s---/;
|
||||||
|
|
||||||
|
const singleMinFpsRegex = /Single min\. FPS for (.*):\s(\d*.\d*)"/; // group1 = entity name, group2 = value
|
||||||
|
|
||||||
|
const singleAvgFpsRegex = /Single avg\. FPS for (.*):\s(\d*.\d*)"/; // group1 = entity name, group2 = value
|
||||||
|
|
||||||
|
const minFpsRegex = /Min\. FPS for (.*):\s\[(.*)\]"/; // group1 = entity name, group2 = comma separated values
|
||||||
|
|
||||||
|
const avgFpsRegex = /Avg\. FPS for (.*):\s\[(.*)\]"/; // group1 = entity name, group2 = comma separated values
|
||||||
|
|
||||||
const parseWarLog = (lineArray, war) => {
|
const parseWarLog = (lineArray, war) => {
|
||||||
let flagBlufor = true;
|
let flagBlufor = true;
|
||||||
let flagOpfor = true;
|
let flagOpfor = true;
|
||||||
|
@ -41,6 +55,8 @@ const parseWarLog = (lineArray, war) => {
|
||||||
flag: [],
|
flag: [],
|
||||||
transport: [],
|
transport: [],
|
||||||
players: [],
|
players: [],
|
||||||
|
playerCount: [],
|
||||||
|
serverFps: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const VEHICLE_BLACKLIST = [
|
const VEHICLE_BLACKLIST = [
|
||||||
|
@ -111,6 +127,7 @@ const parseWarLog = (lineArray, war) => {
|
||||||
const kill = {
|
const kill = {
|
||||||
war: war._id,
|
war: war._id,
|
||||||
time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]),
|
time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]),
|
||||||
|
friendlyFire: false,
|
||||||
};
|
};
|
||||||
if (shooter) {
|
if (shooter) {
|
||||||
kill.shooter = shooter.name;
|
kill.shooter = shooter.name;
|
||||||
|
@ -245,6 +262,56 @@ const parseWarLog = (lineArray, war) => {
|
||||||
fraction: driver ? driver.fraction : 'NONE',
|
fraction: driver ? driver.fraction : 'NONE',
|
||||||
distance: distance,
|
distance: distance,
|
||||||
});
|
});
|
||||||
|
} else if (line.includes('(Spieleranzahl)')) {
|
||||||
|
stats.clean.push(line);
|
||||||
|
|
||||||
|
const timestamp = (timestampRegex.exec(line))[1];
|
||||||
|
const countBlufor = (bluforPlayerCountRegex.exec(line))[1];
|
||||||
|
const countOpfor = (opforPlayerCountRegex.exec(line))[1];
|
||||||
|
|
||||||
|
stats.playerCount.push({
|
||||||
|
war: war.id,
|
||||||
|
time: getFullTimeDate(war.date, timestamp),
|
||||||
|
countBlufor: countBlufor,
|
||||||
|
countOpfor: countOpfor,
|
||||||
|
});
|
||||||
|
} else if (line.includes('(FPS)')) {
|
||||||
|
stats.clean.push(line);
|
||||||
|
|
||||||
|
const updateServerFpsLogEntry = (entityName, addKey, addValue) => {
|
||||||
|
const idx = stats.serverFps.findIndex((entry) => entry.entityName === entityName);
|
||||||
|
if (idx === -1) {
|
||||||
|
stats.serverFps.push({
|
||||||
|
war: war.id,
|
||||||
|
entityName: entityName,
|
||||||
|
[addKey]: addValue,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const entity = stats.serverFps[idx];
|
||||||
|
entity[addKey] = addValue;
|
||||||
|
stats.serverFps[idx] = entity;
|
||||||
|
};
|
||||||
|
|
||||||
|
const singleMinMatch = singleMinFpsRegex.exec(line);
|
||||||
|
if (singleMinMatch) {
|
||||||
|
updateServerFpsLogEntry(singleMinMatch[1], 'singleMinFps', singleMinMatch[2]);
|
||||||
|
} else {
|
||||||
|
const singleAvgMatch = singleAvgFpsRegex.exec(line);
|
||||||
|
if (singleAvgMatch) {
|
||||||
|
updateServerFpsLogEntry(singleAvgMatch[1], 'singleAvgFps', singleAvgMatch[2]);
|
||||||
|
} else {
|
||||||
|
const minCollectionMatch = minFpsRegex.exec(line);
|
||||||
|
if (minCollectionMatch) {
|
||||||
|
updateServerFpsLogEntry(minCollectionMatch[1], 'minFps', minCollectionMatch[2].split(','));
|
||||||
|
} else {
|
||||||
|
const avgCollectionMatch = avgFpsRegex.exec(line);
|
||||||
|
if (avgCollectionMatch) {
|
||||||
|
updateServerFpsLogEntry(avgCollectionMatch[1], 'avgFps', avgCollectionMatch[2].split(','));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (line.includes('(Fraktionsuebersicht)') || line.includes('Fraktionsübersicht')) {
|
} else if (line.includes('(Fraktionsuebersicht)') || line.includes('Fraktionsübersicht')) {
|
||||||
/**
|
/**
|
||||||
* PLAYERS
|
* PLAYERS
|
||||||
|
@ -287,9 +354,31 @@ const parseWarLog = (lineArray, war) => {
|
||||||
|
|
||||||
stats.players[i]['flagTouch'] = stats.flag.filter((flag) => flag.player === playerName).length;
|
stats.players[i]['flagTouch'] = stats.flag.filter((flag) => flag.player === playerName).length;
|
||||||
|
|
||||||
stats.players[i]['sort'] = stats.players[i]['kill'] + stats.players[i]['revive'] +
|
let playerTravelDistance = stats.transport.filter((transport) => transport.passenger === playerName)
|
||||||
stats.players[i]['flagTouch']
|
.map((transport) => transport.distance)
|
||||||
- stats.players[i]['friendlyFire'] - stats.players[i]['death'] - stats.players[i]['respawn'];
|
.reduce((total, num) => total + Math.round(num), 0);
|
||||||
|
if (playerTravelDistance > 0) {
|
||||||
|
stats.players[i]['travelDistance'] = playerTravelDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
let driverDistance = 0;
|
||||||
|
const driverTransports = stats.transport.filter((transport) => transport.driver === playerName);
|
||||||
|
for (let i = 0; i < driverTransports.length; i++) {
|
||||||
|
const curr = driverTransports[i];
|
||||||
|
if (i < driverTransports.length - 1) {
|
||||||
|
const next = driverTransports[i + 1];
|
||||||
|
if ((next.time.getTime() - curr.time.getTime()) < 2 * 60000) { // only track once in 2 min range
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
driverDistance += curr.distance;
|
||||||
|
} else {
|
||||||
|
driverDistance += curr.distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driverDistance > 0) {
|
||||||
|
stats.players[i]['driverDistance'] = driverDistance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.war.playersBlufor = stats.players.filter((player) => player.fraction === 'BLUFOR').length;
|
stats.war.playersBlufor = stats.players.filter((player) => player.fraction === 'BLUFOR').length;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {SpinnerService} from './services/user-interface/spinner/spinner.service'
|
||||||
import {TranslateService} from '@ngx-translate/core';
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
import {SettingsService} from './services/settings.service';
|
import {SettingsService} from './services/settings.service';
|
||||||
import {environment} from '../environments/environment';
|
import {environment} from '../environments/environment';
|
||||||
|
import {SnackBarService} from './services/user-interface/snack-bar/snack-bar.service';
|
||||||
|
|
||||||
declare function require(url: string);
|
declare function require(url: string);
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ export class AppComponent implements OnInit {
|
||||||
'stats-fraction': 'stats/fraction-btn',
|
'stats-fraction': 'stats/fraction-btn',
|
||||||
'stats-player': 'stats/player-stats-btn',
|
'stats-player': 'stats/player-stats-btn',
|
||||||
'stats-scoreboard': 'stats/scoreboard-btn',
|
'stats-scoreboard': 'stats/scoreboard-btn',
|
||||||
|
'stats-performance': 'stats/performance-stats-btn',
|
||||||
// --SCOREBOARD--
|
// --SCOREBOARD--
|
||||||
'death': 'stats/scoreboard/death',
|
'death': 'stats/scoreboard/death',
|
||||||
'flagTouch': 'stats/scoreboard/flag-touch',
|
'flagTouch': 'stats/scoreboard/flag-touch',
|
||||||
|
@ -63,6 +65,8 @@ export class AppComponent implements OnInit {
|
||||||
'vehicleAir': 'stats/scoreboard/vehicle-air',
|
'vehicleAir': 'stats/scoreboard/vehicle-air',
|
||||||
'vehicleHeavy': 'stats/scoreboard/vehicle-heavy',
|
'vehicleHeavy': 'stats/scoreboard/vehicle-heavy',
|
||||||
'vehicleLight': 'stats/scoreboard/vehicle-light',
|
'vehicleLight': 'stats/scoreboard/vehicle-light',
|
||||||
|
'travelDistance': 'stats/scoreboard/travel-distance',
|
||||||
|
'driverDistance': 'stats/scoreboard/driver-distance',
|
||||||
// --------LOCALE---------
|
// --------LOCALE---------
|
||||||
'flag-de': 'locale/de',
|
'flag-de': 'locale/de',
|
||||||
'flag-en': 'locale/en',
|
'flag-en': 'locale/en',
|
||||||
|
@ -83,6 +87,7 @@ export class AppComponent implements OnInit {
|
||||||
private spinnerService: SpinnerService,
|
private spinnerService: SpinnerService,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
|
private snackBarService: SnackBarService,
|
||||||
@Inject(DOCUMENT) private document) {
|
@Inject(DOCUMENT) private document) {
|
||||||
this.initMaterialSvgIcons();
|
this.initMaterialSvgIcons();
|
||||||
|
|
||||||
|
@ -91,6 +96,7 @@ export class AppComponent implements OnInit {
|
||||||
router.events.subscribe(event => {
|
router.events.subscribe(event => {
|
||||||
if (event instanceof NavigationStart) {
|
if (event instanceof NavigationStart) {
|
||||||
this.spinnerService.activate();
|
this.spinnerService.activate();
|
||||||
|
this.snackBarService.dismiss();
|
||||||
}
|
}
|
||||||
if (event instanceof NavigationEnd) {
|
if (event instanceof NavigationEnd) {
|
||||||
this.spinnerService.deactivate();
|
this.spinnerService.deactivate();
|
||||||
|
|
|
@ -35,6 +35,9 @@ export interface Player {
|
||||||
revive?: number;
|
revive?: number;
|
||||||
respawn?: number;
|
respawn?: number;
|
||||||
flagTouch?: number;
|
flagTouch?: number;
|
||||||
|
performance?: string;
|
||||||
|
travelDistance?: number;
|
||||||
|
driverDistance?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CampaignPlayer {
|
export interface CampaignPlayer {
|
||||||
|
|
|
@ -68,4 +68,8 @@ export class LogsService {
|
||||||
params.append('defend', defendOnly ? 'true' : '');
|
params.append('defend', defendOnly ? 'true' : '');
|
||||||
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/flag', params);
|
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/flag', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPerformanceLogs(warId: string) {
|
||||||
|
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/performance');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,10 @@ export class SnackBarService {
|
||||||
return this.snackbar.open(message, action, config);
|
return this.snackbar.open(message, action, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dismiss() {
|
||||||
|
this.snackbar.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
showSuccess(i18n: string) {
|
showSuccess(i18n: string) {
|
||||||
this.translate.get(i18n).subscribe((translated) => {
|
this.translate.get(i18n).subscribe((translated) => {
|
||||||
return this.show(translated, undefined, 2500, ['custom-snack-bar', 'label-success']);
|
return this.show(translated, undefined, 2500, ['custom-snack-bar', 'label-success']);
|
||||||
|
|
|
@ -53,7 +53,7 @@ export class CampaignPlayerDetailComponent implements OnInit {
|
||||||
respawnDeathRatio = 0;
|
respawnDeathRatio = 0;
|
||||||
maxRespawnDeathRatio = 1;
|
maxRespawnDeathRatio = 1;
|
||||||
|
|
||||||
playerAttributeNameMap = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length);
|
playerAttributeNameMap = PlayerUtils.tmpAttributeDisplayNames.slice(2, PlayerUtils.tmpAttributeDisplayNames.length);
|
||||||
|
|
||||||
constructor(private playerService: PlayerService,
|
constructor(private playerService: PlayerService,
|
||||||
private translate: TranslateService) {
|
private translate: TranslateService) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ export class StatisticHighScoreComponent implements OnInit {
|
||||||
|
|
||||||
playersStored = {};
|
playersStored = {};
|
||||||
|
|
||||||
playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length);
|
playerAttributeDisplayNames = PlayerUtils.tmpAttributeDisplayNames.slice(2, PlayerUtils.tmpAttributeDisplayNames.length);
|
||||||
|
|
||||||
readonly fraction = Fraction;
|
readonly fraction = Fraction;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {WarHeaderComponent} from './war/war-header/war-header.component';
|
||||||
import {LoginGuardMT} from '../login';
|
import {LoginGuardMT} from '../login';
|
||||||
import {CampaignNavigationComponent} from './campaign/campaign-navigation/campaign-navigation.component';
|
import {CampaignNavigationComponent} from './campaign/campaign-navigation/campaign-navigation.component';
|
||||||
import {StatisticOverviewComponent} from './campaign/overview/campaign-overview.component';
|
import {StatisticOverviewComponent} from './campaign/overview/campaign-overview.component';
|
||||||
|
import {ServerStatsComponent} from './war/server-stats/server-stats.component';
|
||||||
|
|
||||||
|
|
||||||
export const statsRoutes: Routes = [
|
export const statsRoutes: Routes = [
|
||||||
|
@ -69,5 +70,6 @@ export const statsRouterModule: ModuleWithProviders = RouterModule.forChild(stat
|
||||||
|
|
||||||
export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, StatisticHighScoreComponent,
|
export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, StatisticHighScoreComponent,
|
||||||
CampaignSubmitComponent, WarListComponent, WarSubmitComponent, WarHeaderComponent, ScoreboardComponent,
|
CampaignSubmitComponent, WarListComponent, WarSubmitComponent, WarHeaderComponent, ScoreboardComponent,
|
||||||
FractionStatsComponent, CampaignPlayerDetailComponent, WarItemComponent, CampaignNavigationComponent];
|
FractionStatsComponent, CampaignPlayerDetailComponent, WarItemComponent, CampaignNavigationComponent,
|
||||||
|
ServerStatsComponent];
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#group="matButtonToggleGroup"
|
#group="matButtonToggleGroup"
|
||||||
[(ngModel)]="activeChartSelect"
|
[(ngModel)]="activeChartSelect"
|
||||||
(change)="selectChart(group.value)">
|
(change)="selectChart(group.value)">
|
||||||
<mat-button-toggle *ngFor="let label of labelsAsString" value="{{label}}">
|
<mat-button-toggle *ngFor="let labelKey of labelsKeys" value="{{labels[labelKey]}}">
|
||||||
{{label | translate}}
|
{{labels[labelKey] | translate}}
|
||||||
</mat-button-toggle>
|
</mat-button-toggle>
|
||||||
</mat-button-toggle-group>
|
</mat-button-toggle-group>
|
||||||
|
|
||||||
|
|
|
@ -39,24 +39,15 @@ export class FractionStatsComponent implements OnInit, OnChanges {
|
||||||
tmpReviveData;
|
tmpReviveData;
|
||||||
tmpStabilizeData;
|
tmpStabilizeData;
|
||||||
tmpFlagCaptureData;
|
tmpFlagCaptureData;
|
||||||
|
tmpPlayerCountData;
|
||||||
|
|
||||||
colorScheme = {
|
colorScheme = {
|
||||||
domain: [Fraction.COLOR_BLUFOR, Fraction.COLOR_OPFOR, Fraction.COLOR_BLUFOR_LIGHT, Fraction.COLOR_OPFOR_LIGHT,
|
domain: [Fraction.COLOR_BLUFOR, Fraction.COLOR_OPFOR, Fraction.COLOR_BLUFOR_LIGHT, Fraction.COLOR_OPFOR_LIGHT,
|
||||||
Fraction.COLOR_BLUFOR_DARK, Fraction.COLOR_OPFOR_DARK, Fraction.COLOR_BLUFOR_GREY, Fraction.COLOR_OPFOR_GREY]
|
Fraction.COLOR_BLUFOR_DARK, Fraction.COLOR_OPFOR_DARK, Fraction.COLOR_BLUFOR_GREY, Fraction.COLOR_OPFOR_GREY]
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly labels = {
|
labels;
|
||||||
points: 'stats.fraction.select.points',
|
labelsKeys;
|
||||||
budget: 'stats.fraction.select.budget',
|
|
||||||
kill: 'stats.fraction.select.kills',
|
|
||||||
friendlyFire: 'stats.fraction.select.friendly.fire',
|
|
||||||
vehicle: 'stats.fraction.select.vehicle.kills',
|
|
||||||
transport: 'stats.fraction.select.air.transport',
|
|
||||||
revive: 'stats.fraction.select.revive',
|
|
||||||
stabilize: 'stats.fraction.select.stabilize',
|
|
||||||
flag: 'stats.fraction.select.flag'
|
|
||||||
};
|
|
||||||
readonly labelsAsString = Object.keys(this.labels).map((key) => this.labels[key]);
|
|
||||||
|
|
||||||
lineChartLabel: string;
|
lineChartLabel: string;
|
||||||
|
|
||||||
|
@ -87,8 +78,12 @@ export class FractionStatsComponent implements OnInit, OnChanges {
|
||||||
kill: false,
|
kill: false,
|
||||||
revive: false,
|
revive: false,
|
||||||
transport: false,
|
transport: false,
|
||||||
flag: false
|
flag: false,
|
||||||
|
playerCount: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.initializeToggleButtons();
|
||||||
|
|
||||||
Object.assign(this, [this.lineChartData, this.areaChartData]);
|
Object.assign(this, [this.lineChartData, this.areaChartData]);
|
||||||
this.activeChartSelect = this.labels.points;
|
this.activeChartSelect = this.labels.points;
|
||||||
|
|
||||||
|
@ -99,6 +94,42 @@ export class FractionStatsComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show only labels for for data that is available,
|
||||||
|
* to not end up with empty charts in old battles
|
||||||
|
*/
|
||||||
|
initializeToggleButtons() {
|
||||||
|
const newLabels = {};
|
||||||
|
if (this.logData.points && this.logData.points.length > 0) {
|
||||||
|
newLabels['points'] = 'stats.fraction.select.points';
|
||||||
|
}
|
||||||
|
if (this.logData.budget && this.logData.budget.length > 0) {
|
||||||
|
newLabels['budget'] = 'stats.fraction.select.budget';
|
||||||
|
}
|
||||||
|
if (this.logData.kill && this.logData.kill.length > 0) {
|
||||||
|
newLabels['kill'] = 'stats.fraction.select.kills';
|
||||||
|
newLabels['friendlyFire'] = 'stats.fraction.select.friendly.fire';
|
||||||
|
}
|
||||||
|
if (this.logData.vehicle && this.logData.vehicle.length > 0) {
|
||||||
|
newLabels['vehicle'] = 'stats.fraction.select.vehicle.kills';
|
||||||
|
}
|
||||||
|
if (this.logData.transport && this.logData.transport.length > 0) {
|
||||||
|
newLabels['transport'] = 'stats.fraction.select.air.transport';
|
||||||
|
}
|
||||||
|
if (this.logData.revive && this.logData.revive.length > 0) {
|
||||||
|
newLabels['revive'] = 'stats.fraction.select.revive';
|
||||||
|
newLabels['stabilize'] = 'stats.fraction.select.stabilize';
|
||||||
|
}
|
||||||
|
if (this.logData.flag && this.logData.flag.length > 0) {
|
||||||
|
newLabels['flag'] = 'stats.fraction.select.flag';
|
||||||
|
}
|
||||||
|
if (this.logData.playerCount && this.logData.playerCount.length > 0) {
|
||||||
|
newLabels['playerCount'] = 'stats.fraction.select.player.count';
|
||||||
|
}
|
||||||
|
this.labels = newLabels;
|
||||||
|
this.labelsKeys = Object.keys(this.labels);
|
||||||
|
}
|
||||||
|
|
||||||
selectChart(newSelection) {
|
selectChart(newSelection) {
|
||||||
this.activeChartSelect = newSelection;
|
this.activeChartSelect = newSelection;
|
||||||
if (this.activeChartSelect !== this.labels.flag) {
|
if (this.activeChartSelect !== this.labels.flag) {
|
||||||
|
@ -136,6 +167,10 @@ export class FractionStatsComponent implements OnInit, OnChanges {
|
||||||
this.initTransportData();
|
this.initTransportData();
|
||||||
this.lineChartData = this.tmpTransportData;
|
this.lineChartData = this.tmpTransportData;
|
||||||
break;
|
break;
|
||||||
|
case this.labels.playerCount:
|
||||||
|
this.initPlayerCountData();
|
||||||
|
this.lineChartData = this.tmpPlayerCountData;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.initFlagHoldData();
|
this.initFlagHoldData();
|
||||||
|
@ -347,6 +382,20 @@ export class FractionStatsComponent implements OnInit, OnChanges {
|
||||||
this.initialized.transport = true;
|
this.initialized.transport = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initPlayerCountData() {
|
||||||
|
if (this.initialized.playerCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.logData.playerCount.forEach(playerCountEntry => {
|
||||||
|
this.tmpPlayerCountData[0].series.push(
|
||||||
|
ChartUtils.getSeriesEntry(new Date(playerCountEntry.time), playerCountEntry.countBlufor));
|
||||||
|
this.tmpPlayerCountData[1].series.push(
|
||||||
|
ChartUtils.getSeriesEntry(new Date(playerCountEntry.time), playerCountEntry.countOpfor));
|
||||||
|
});
|
||||||
|
this.initialized.playerCount = true;
|
||||||
|
this.addFinalTimeData(this.tmpPlayerCountData);
|
||||||
|
}
|
||||||
|
|
||||||
initFlagHoldData() {
|
initFlagHoldData() {
|
||||||
if (this.initialized.flag) {
|
if (this.initialized.flag) {
|
||||||
return;
|
return;
|
||||||
|
@ -387,6 +436,7 @@ export class FractionStatsComponent implements OnInit, OnChanges {
|
||||||
this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
|
this.tmpPlayerCountData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR);
|
||||||
|
|
||||||
[this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData,
|
[this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData,
|
||||||
this.tmpTransportData].forEach(tmp => {
|
this.tmpTransportData].forEach(tmp => {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
.mat-header-row {
|
.mat-header-row {
|
||||||
width: 1058px;
|
width: 1058px;
|
||||||
position: fixed;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-column-kill, .mat-column-friendlyFire, .mat-column-revive, .mat-column-flagTouch, .mat-column-vehicleLight,
|
.mat-column-kill, .mat-column-friendlyFire, .mat-column-revive, .mat-column-flagTouch, .mat-column-vehicleLight,
|
||||||
.mat-column-vehicleHeavy, .mat-column-vehicleAir, .mat-column-death, .mat-column-respawn, .mat-column-interact {
|
.mat-column-vehicleHeavy, .mat-column-vehicleAir, .mat-column-travelDistance, .mat-column-driverDistance,
|
||||||
flex: 0 0 75px;
|
.mat-column-death, .mat-column-respawn, .mat-column-interact {
|
||||||
|
flex: 0 0 62px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .mat-table .mat-icon {
|
:host /deep/ .mat-table .mat-icon {
|
||||||
|
|
|
@ -52,6 +52,12 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (changes.war) {
|
if (changes.war) {
|
||||||
|
this.war.players.forEach(player => {
|
||||||
|
// meters to kilometer or fill with null, since optional
|
||||||
|
player.travelDistance = player.travelDistance ? Math.round(player.travelDistance / 1000) : 0;
|
||||||
|
player.driverDistance = player.driverDistance ? Math.round(player.driverDistance / 1000) : 0;
|
||||||
|
});
|
||||||
|
|
||||||
this.rows = changes.war.currentValue.players;
|
this.rows = changes.war.currentValue.players;
|
||||||
this.currentSort.active = 'kill';
|
this.currentSort.active = 'kill';
|
||||||
this.sortScoreboardData(this.currentSort);
|
this.sortScoreboardData(this.currentSort);
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
.chart-select-group {
|
||||||
|
display: flex;
|
||||||
|
width: fit-content;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ mat-button-toggle {
|
||||||
|
color: #666666;
|
||||||
|
background: #e7e7e7;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ mat-button-toggle:hover {
|
||||||
|
background: #afafaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ mat-button-toggle.mat-button-toggle-checked {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ label.mat-button-toggle-label {
|
||||||
|
margin: 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ div.mat-button-toggle-label-content {
|
||||||
|
line-height: 25px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
width: 95%;
|
||||||
|
margin: 2%;
|
||||||
|
min-width: 900px;
|
||||||
|
height: 50vh;
|
||||||
|
padding: 15px;
|
||||||
|
float: left;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
<div class="fade-in" style="border-top: 1px solid #dadada; padding-top:25px;" xmlns="http://www.w3.org/1999/html">
|
||||||
|
|
||||||
|
<mat-button-toggle-group class="chart-select-group"
|
||||||
|
#group="matButtonToggleGroup"
|
||||||
|
[(ngModel)]="activeChartSelect"
|
||||||
|
(change)="selectChart(group.value)">
|
||||||
|
<mat-button-toggle *ngFor="let label of labelsAsString" value="{{label}}">
|
||||||
|
{{label | translate}}
|
||||||
|
</mat-button-toggle>
|
||||||
|
</mat-button-toggle-group>
|
||||||
|
|
||||||
|
<div class="chart-container" *ngIf="showBarChart">
|
||||||
|
<ngx-charts-bar-vertical
|
||||||
|
[results]="barChartData"
|
||||||
|
[scheme]="colorScheme"
|
||||||
|
[gradient]="gradient"
|
||||||
|
[xAxis]="xAxis"
|
||||||
|
[yAxis]="yAxis"
|
||||||
|
[legend]="legend"
|
||||||
|
[legendTitle]="legendTitle"
|
||||||
|
[showXAxisLabel]="showXAxisLabel"
|
||||||
|
[showYAxisLabel]="showYAxisLabel"
|
||||||
|
[yAxisLabel]="barChartLabel"
|
||||||
|
[barPadding]="2"
|
||||||
|
[roundDomains]="roundDomains">
|
||||||
|
</ngx-charts-bar-vertical>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chart-container" *ngIf="!showBarChart">
|
||||||
|
<ngx-charts-line-chart
|
||||||
|
[results]="lineChartData"
|
||||||
|
[scheme]="colorScheme"
|
||||||
|
[gradient]="gradient"
|
||||||
|
[xAxis]="xAxis"
|
||||||
|
[yAxis]="yAxis"
|
||||||
|
[legend]="legend"
|
||||||
|
[legendTitle]="legendTitle"
|
||||||
|
[showXAxisLabel]="showXAxisLabel"
|
||||||
|
[showYAxisLabel]="showYAxisLabel"
|
||||||
|
[yAxisLabel]="lineChartLabel"
|
||||||
|
[autoScale]="autoscale"
|
||||||
|
[timeline]="timeline"
|
||||||
|
[roundDomains]="roundDomains">
|
||||||
|
</ngx-charts-line-chart>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,203 @@
|
||||||
|
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
|
||||||
|
import {War} from '../../../models/model-interfaces';
|
||||||
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
|
import {ChartUtils} from '../../../utils/chart-utils';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'cc-server-statistics',
|
||||||
|
templateUrl: './server-stats.component.html',
|
||||||
|
styleUrls: ['./server-stats.component.css', '../../../style/list-entry.css', '../../../style/hide-scrollbar.css']
|
||||||
|
})
|
||||||
|
export class ServerStatsComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
|
@ViewChild('overview') private overviewContainer: ElementRef;
|
||||||
|
|
||||||
|
@Input() war: War;
|
||||||
|
|
||||||
|
@Input() performanceData: any;
|
||||||
|
|
||||||
|
startDateObj: Date;
|
||||||
|
|
||||||
|
public activeChartSelect: string;
|
||||||
|
|
||||||
|
showBarChart = true;
|
||||||
|
barChartData: any[] = [];
|
||||||
|
lineChartData: any[] = [];
|
||||||
|
|
||||||
|
tmpSingleAvg;
|
||||||
|
tmpSingleMin;
|
||||||
|
tmpAvgTimeline;
|
||||||
|
tmpMinTimeline;
|
||||||
|
tmpServerTimeline;
|
||||||
|
|
||||||
|
barChartLabel: string;
|
||||||
|
lineChartLabel: string;
|
||||||
|
readonly labels = {
|
||||||
|
singleAvg: 'stats.performance.select.single.avg',
|
||||||
|
singleMin: 'stats.performance.select.single.min',
|
||||||
|
avgTimeline: 'stats.performance.select.timeline.avg',
|
||||||
|
minTimeline: 'stats.performance.select.timeline.min',
|
||||||
|
serverFps: 'stats.performance.select.timeline.server',
|
||||||
|
};
|
||||||
|
readonly labelsAsString = Object.keys(this.labels)
|
||||||
|
.map((key) => this.labels[key]);
|
||||||
|
lineChartSeriesLabels: string[];
|
||||||
|
|
||||||
|
gradient = false;
|
||||||
|
yAxis = true;
|
||||||
|
xAxis = true;
|
||||||
|
legend = false;
|
||||||
|
legendTitle = false;
|
||||||
|
showXAxisLabel = false;
|
||||||
|
showYAxisLabel = true;
|
||||||
|
autoscale = true;
|
||||||
|
timeline = false;
|
||||||
|
roundDomains = true;
|
||||||
|
colorScheme = {
|
||||||
|
name: 'nightLights',
|
||||||
|
selectable: false,
|
||||||
|
group: 'Ordinal',
|
||||||
|
domain: [
|
||||||
|
'#4e31a5', '#9c25a7', '#3065ab', '#57468b', '#904497', '#46648b',
|
||||||
|
'#32118d', '#a00fb3', '#1052a2', '#6e51bd', '#b63cc3', '#6c97cb', '#8671c1', '#b455be', '#7496c3'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private translate: TranslateService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.setBarChartLabel(this.labels.singleAvg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if ((changes.war || changes.performanceData) && this.performanceData) {
|
||||||
|
this.translate.get(['stats.performance.select.timeline.label.minimum',
|
||||||
|
'stats.performance.select.timeline.label.average',
|
||||||
|
'stats.performance.select.timeline.label.maximum']).subscribe((res) => {
|
||||||
|
const resValues = Object.keys(res).map(val => res[val]);
|
||||||
|
this.initializeChartData(resValues[2], resValues[0], resValues[1]);
|
||||||
|
});
|
||||||
|
Object.assign(this, [this.barChartData]);
|
||||||
|
this.activeChartSelect = this.labels.singleAvg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectChart(newSelection) {
|
||||||
|
this.activeChartSelect = newSelection;
|
||||||
|
if (this.activeChartSelect === this.labels.singleAvg || this.activeChartSelect === this.labels.singleMin) {
|
||||||
|
this.showBarChart = true;
|
||||||
|
this.setBarChartLabel(this.activeChartSelect);
|
||||||
|
switch (this.activeChartSelect) {
|
||||||
|
case this.labels.singleAvg:
|
||||||
|
this.barChartData = this.tmpSingleAvg;
|
||||||
|
break;
|
||||||
|
case this.labels.singleMin:
|
||||||
|
this.barChartData = this.tmpSingleMin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.showBarChart = false;
|
||||||
|
this.setLineChartLabel(this.activeChartSelect);
|
||||||
|
switch (this.activeChartSelect) {
|
||||||
|
case this.labels.avgTimeline:
|
||||||
|
this.lineChartData = this.tmpAvgTimeline;
|
||||||
|
break;
|
||||||
|
case this.labels.minTimeline:
|
||||||
|
this.lineChartData = this.tmpMinTimeline;
|
||||||
|
break;
|
||||||
|
case this.labels.serverFps:
|
||||||
|
this.lineChartData = this.tmpServerTimeline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeChartData(labelMax: string, labelMin: string, labelAvg: string) {
|
||||||
|
this.tmpAvgTimeline = ChartUtils.getMultiDataArray(labelMax, labelAvg, labelMin);
|
||||||
|
this.tmpMinTimeline = ChartUtils.getMultiDataArray(labelMax, labelAvg, labelMin);
|
||||||
|
this.tmpServerTimeline = ChartUtils.getMultiDataArray(labelAvg, labelMin);
|
||||||
|
|
||||||
|
const diffMs = (new Date(this.war.endDate).getTime() - new Date(this.war.date).getTime());
|
||||||
|
const warDurationMinutes = Math.round(diffMs / 60000);
|
||||||
|
|
||||||
|
const dateObj = new Date(this.war.date);
|
||||||
|
dateObj.setHours(0);
|
||||||
|
dateObj.setMinutes(1);
|
||||||
|
|
||||||
|
this.tmpSingleAvg = [];
|
||||||
|
this.tmpSingleMin = [];
|
||||||
|
const maxAvgIdx = Math.min(this.performanceData.map(p => p.avgFps.length)
|
||||||
|
.sort((a, b) => b - a)[0], warDurationMinutes);
|
||||||
|
const maxMinIdx = Math.min(this.performanceData.map(p => p.avgFps.length)
|
||||||
|
.sort((a, b) => b - a)[0], warDurationMinutes);
|
||||||
|
let tmpAvgArray = new Array(maxAvgIdx).fill(0);
|
||||||
|
const tmpAvgMin = new Array(maxAvgIdx).fill(1000);
|
||||||
|
const tmpAvgMax = new Array(maxAvgIdx).fill(0);
|
||||||
|
let tmpMinArray = new Array(maxMinIdx).fill(0);
|
||||||
|
const tmpMinMin = new Array(maxMinIdx).fill(1000);
|
||||||
|
const tmpMinMax = new Array(maxMinIdx).fill(0);
|
||||||
|
|
||||||
|
this.performanceData.forEach((entry) => {
|
||||||
|
if (entry.entityName !== 'SERVER') {
|
||||||
|
// PLAYER AVERAGE TIMELINE DATA
|
||||||
|
for (let i = 0; i < entry.avgFps.length && i < tmpAvgArray.length; i++) {
|
||||||
|
tmpAvgArray[i] = tmpAvgArray[i] + entry.avgFps[i];
|
||||||
|
tmpAvgMin[i] = Math.round(Math.min(tmpAvgMin[i], entry.avgFps[i]));
|
||||||
|
tmpAvgMax[i] = Math.round(Math.max(tmpAvgMax[i], entry.avgFps[i]));
|
||||||
|
}
|
||||||
|
// PLAYER MINIMUM TIMELINE DATA
|
||||||
|
for (let i = 0; i < entry.minFps.length && i < tmpMinArray.length; i++) {
|
||||||
|
tmpMinArray[i] = tmpMinArray[i] + entry.minFps[i];
|
||||||
|
tmpMinMin[i] = Math.round(Math.min(tmpMinMin[i], entry.minFps[i]));
|
||||||
|
tmpMinMax[i] = Math.round(Math.max(tmpMinMax[i], entry.minFps[i]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// SERVER TIMELINE DATA
|
||||||
|
for (let i = 0; i < entry.avgFps.length && i < warDurationMinutes; i++) {
|
||||||
|
const currDate = new Date(dateObj.getTime() + i * 60000);
|
||||||
|
this.tmpServerTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, entry.avgFps[i]));
|
||||||
|
this.tmpServerTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, entry.minFps[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tmpSingleAvg.push({
|
||||||
|
name: entry.entityName,
|
||||||
|
value: entry.singleAvgFps
|
||||||
|
});
|
||||||
|
this.tmpSingleMin.push({
|
||||||
|
name: entry.entityName,
|
||||||
|
value: entry.singleMinFps
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tmpAvgArray = tmpAvgArray.map(x => Math.round(x / this.performanceData.length));
|
||||||
|
for (let i = 0; i < tmpAvgArray.length; i++) {
|
||||||
|
const currDate = new Date(dateObj.getTime() + i * 60000);
|
||||||
|
this.tmpAvgTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgMax[i]));
|
||||||
|
this.tmpAvgTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgArray[i]));
|
||||||
|
this.tmpAvgTimeline[2].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgMin[i]));
|
||||||
|
}
|
||||||
|
tmpMinArray = tmpMinArray.map(x => Math.round(x / this.performanceData.length));
|
||||||
|
for (let i = 0; i < tmpMinArray.length; i++) {
|
||||||
|
const currDate = new Date(dateObj.getTime() + i * 60000);
|
||||||
|
this.tmpMinTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinMax[i]));
|
||||||
|
this.tmpMinTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinArray[i]));
|
||||||
|
this.tmpMinTimeline[2].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinMin[i]));
|
||||||
|
}
|
||||||
|
this.tmpSingleAvg.sort((a, b) => a.value - b.value);
|
||||||
|
this.tmpSingleMin.sort((a, b) => a.value - b.value);
|
||||||
|
this.barChartData = this.tmpSingleAvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLineChartLabel(i18n: string) {
|
||||||
|
this.translate.get(i18n).subscribe((translated) => {
|
||||||
|
this.lineChartLabel = translated;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setBarChartLabel(i18n: string) {
|
||||||
|
this.translate.get(i18n).subscribe((translated) => {
|
||||||
|
this.barChartLabel = translated;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ form.tab-control {
|
||||||
}
|
}
|
||||||
|
|
||||||
span.tab-control {
|
span.tab-control {
|
||||||
margin: 4px 67px;
|
margin: 4px 30px 4px 55px;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +39,21 @@ span.tab-control {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host/deep/.mat-icon-stats-performance g {
|
||||||
|
stroke: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
width: 920px;
|
width: 1000px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
clear: both;
|
clear: both;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-tab-hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-tabs > li > a {
|
.nav-tabs > li > a {
|
||||||
background: #e7e7e7;
|
background: #e7e7e7;
|
||||||
border: 1px solid #dadada;
|
border: 1px solid #dadada;
|
||||||
|
@ -56,7 +64,7 @@ span.tab-control {
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs > li:last-child {
|
.nav-tabs > li:last-child {
|
||||||
margin-left: 70px;
|
margin-left: 65px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link {
|
.nav-link {
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
<div class="war-header-container">
|
<div class="war-header-container">
|
||||||
<div class="pull-left head-field" style="width: 250px">
|
<div class="pull-left head-field" style="width: 250px">
|
||||||
<h4>{{'stats.scoreboard.standings' | translate}}</h4>
|
<h4>{{'stats.scoreboard.standings' | translate}}</h4>
|
||||||
<span [style.color]="fraction.COLOR_BLUFOR" style="font-weight: bold; margin-right: 10px">{{fraction.BLUFOR}} {{war.ptBlufor}}</span>
|
<span [style.color]="fraction.COLOR_BLUFOR"
|
||||||
|
style="font-weight: bold; margin-right: 10px">{{fraction.BLUFOR}} {{war.ptBlufor}}</span>
|
||||||
<span style="font-size: x-large">|</span>
|
<span style="font-size: x-large">|</span>
|
||||||
<span [style.color]="fraction.COLOR_OPFOR" style="font-weight: bold; margin-left: 10px;">{{war.ptOpfor}} {{fraction.OPFOR}}</span>
|
<span [style.color]="fraction.COLOR_OPFOR"
|
||||||
|
style="font-weight: bold; margin-left: 10px;">{{war.ptOpfor}} {{fraction.OPFOR}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pull-left head-field " style="padding-left: 100px;">
|
<div class="pull-left head-field " style="padding-left: 100px;">
|
||||||
|
@ -48,6 +50,14 @@
|
||||||
{{'stats.scoreboard.tab.player' | translate}}
|
{{'stats.scoreboard.tab.player' | translate}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item"
|
||||||
|
[ngClass]="{active : tab === 3,'nav-tab-hidden' : war && war.players[0] && !war.players[0].performance}"
|
||||||
|
(click)="switchTab(3)">
|
||||||
|
<a class="nav-link">
|
||||||
|
<mat-icon svgIcon="stats-performance" class="mat-icon-stats-performance"></mat-icon>
|
||||||
|
{{'stats.scoreboard.tab.performance' | translate}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div *ngIf="tab === 0">
|
<div *ngIf="tab === 0">
|
||||||
<form class="pull-left tab-control">
|
<form class="pull-left tab-control">
|
||||||
|
@ -100,6 +110,11 @@
|
||||||
[playerName]="playerDetailName"
|
[playerName]="playerDetailName"
|
||||||
(switchTab)="switchTab($event)">
|
(switchTab)="switchTab($event)">
|
||||||
</campaign-player-detail>
|
</campaign-player-detail>
|
||||||
|
<cc-server-statistics
|
||||||
|
*ngIf="tab === 3"
|
||||||
|
[war]="war"
|
||||||
|
[performanceData]="performanceData">
|
||||||
|
</cc-server-statistics>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,14 +23,18 @@ export class WarHeaderComponent implements OnInit {
|
||||||
|
|
||||||
logData;
|
logData;
|
||||||
|
|
||||||
|
fractionStatsInitialized: boolean;
|
||||||
|
|
||||||
|
performanceData;
|
||||||
|
|
||||||
|
performanceStatsInitialized: boolean;
|
||||||
|
|
||||||
singlePlayerView: number;
|
singlePlayerView: number;
|
||||||
|
|
||||||
playerDetailName: string;
|
playerDetailName: string;
|
||||||
|
|
||||||
tab: number;
|
tab: number;
|
||||||
|
|
||||||
fractionStatsInitialized: boolean;
|
|
||||||
|
|
||||||
fractionFilterSelected: string;
|
fractionFilterSelected: string;
|
||||||
|
|
||||||
playerChart: any[] = [];
|
playerChart: any[] = [];
|
||||||
|
@ -70,6 +74,12 @@ export class WarHeaderComponent implements OnInit {
|
||||||
this.fractionStatsInitialized = true;
|
this.fractionStatsInitialized = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (index === 3 && !this.performanceStatsInitialized) {
|
||||||
|
this.logsService.getPerformanceLogs(this.war._id).subscribe(log => {
|
||||||
|
this.performanceData = log;
|
||||||
|
this.performanceStatsInitialized = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,21 @@
|
||||||
export class PlayerUtils {
|
export class PlayerUtils {
|
||||||
|
|
||||||
|
// TODO: drop this tmp collection, excluding player transport stats from campaign detail page and highscore page,
|
||||||
|
// adding valid processing there
|
||||||
|
public static readonly tmpAttributeDisplayNames = [
|
||||||
|
{prop: 'name', head: 'stats.scoreboard.header.player'},
|
||||||
|
{prop: 'fraction', head: 'stats.scoreboard.header.fraction'},
|
||||||
|
{prop: 'kill', head: 'stats.scoreboard.header.kill'},
|
||||||
|
{prop: 'friendlyFire', head: 'stats.scoreboard.header.friendly.fire'},
|
||||||
|
{prop: 'revive', head: 'stats.scoreboard.header.revive'},
|
||||||
|
{prop: 'flagTouch', head: 'stats.scoreboard.header.capture'},
|
||||||
|
{prop: 'vehicleLight', head: 'stats.scoreboard.header.vehicle.light'},
|
||||||
|
{prop: 'vehicleHeavy', head: 'stats.scoreboard.header.vehicle.heavy'},
|
||||||
|
{prop: 'vehicleAir', head: 'stats.scoreboard.header.vehicle.air'},
|
||||||
|
{prop: 'death', head: 'stats.scoreboard.header.death'},
|
||||||
|
{prop: 'respawn', head: 'stats.scoreboard.header.respawn'},
|
||||||
|
];
|
||||||
|
|
||||||
public static readonly attributeDisplayNames = [
|
public static readonly attributeDisplayNames = [
|
||||||
{prop: 'name', head: 'stats.scoreboard.header.player'},
|
{prop: 'name', head: 'stats.scoreboard.header.player'},
|
||||||
{prop: 'fraction', head: 'stats.scoreboard.header.fraction'},
|
{prop: 'fraction', head: 'stats.scoreboard.header.fraction'},
|
||||||
|
@ -10,8 +26,10 @@ export class PlayerUtils {
|
||||||
{prop: 'vehicleLight', head: 'stats.scoreboard.header.vehicle.light'},
|
{prop: 'vehicleLight', head: 'stats.scoreboard.header.vehicle.light'},
|
||||||
{prop: 'vehicleHeavy', head: 'stats.scoreboard.header.vehicle.heavy'},
|
{prop: 'vehicleHeavy', head: 'stats.scoreboard.header.vehicle.heavy'},
|
||||||
{prop: 'vehicleAir', head: 'stats.scoreboard.header.vehicle.air'},
|
{prop: 'vehicleAir', head: 'stats.scoreboard.header.vehicle.air'},
|
||||||
|
{prop: 'travelDistance', head: 'stats.scoreboard.header.travel.distance'},
|
||||||
|
{prop: 'driverDistance', head: 'stats.scoreboard.header.driver.distance'},
|
||||||
{prop: 'death', head: 'stats.scoreboard.header.death'},
|
{prop: 'death', head: 'stats.scoreboard.header.death'},
|
||||||
{prop: 'respawn', head: 'stats.scoreboard.header.respawn'}
|
{prop: 'respawn', head: 'stats.scoreboard.header.respawn'},
|
||||||
];
|
];
|
||||||
|
|
||||||
public static isSteamUUID(input: string): boolean {
|
public static isSteamUUID(input: string): boolean {
|
||||||
|
|
|
@ -27,6 +27,17 @@
|
||||||
"stats.fraction.select.revive": "Revive",
|
"stats.fraction.select.revive": "Revive",
|
||||||
"stats.fraction.select.stabilize": "Stabilisiert",
|
"stats.fraction.select.stabilize": "Stabilisiert",
|
||||||
"stats.fraction.select.flag": "Flaggenbesitz",
|
"stats.fraction.select.flag": "Flaggenbesitz",
|
||||||
|
"stats.fraction.select.player.count": "Spieleranzahl",
|
||||||
|
|
||||||
|
"stats.performance.select.single.avg": "Spieler FPS Durchschnitt",
|
||||||
|
"stats.performance.select.single.min": "Spieler FPS Minimum",
|
||||||
|
"stats.performance.select.timeline.avg": "Verlauf FPS Durchschnitt",
|
||||||
|
"stats.performance.select.timeline.min": "Verlauf FPS Minimum",
|
||||||
|
"stats.performance.select.timeline.server": "Server FPS",
|
||||||
|
"stats.performance.select.timeline.label.minimum": "Minimum",
|
||||||
|
"stats.performance.select.timeline.label.average": "Mittelwert",
|
||||||
|
"stats.performance.select.timeline.label.maximum": "Maximum",
|
||||||
|
|
||||||
|
|
||||||
"stats.player.detail.headline": "Kampagnendetails - {{name}}",
|
"stats.player.detail.headline": "Kampagnendetails - {{name}}",
|
||||||
"stats.player.detail.button.back": "Zurück",
|
"stats.player.detail.button.back": "Zurück",
|
||||||
|
@ -41,6 +52,7 @@
|
||||||
"stats.scoreboard.tab.scoreboard": "Scoreboard",
|
"stats.scoreboard.tab.scoreboard": "Scoreboard",
|
||||||
"stats.scoreboard.tab.fractions": "Fraktionen",
|
"stats.scoreboard.tab.fractions": "Fraktionen",
|
||||||
"stats.scoreboard.tab.player": "Spieler",
|
"stats.scoreboard.tab.player": "Spieler",
|
||||||
|
"stats.scoreboard.tab.performance": "Performance",
|
||||||
"stats.scoreboard.fraction.filter.all": "Alle",
|
"stats.scoreboard.fraction.filter.all": "Alle",
|
||||||
"stats.scoreboard.header.player": "Spieler",
|
"stats.scoreboard.header.player": "Spieler",
|
||||||
"stats.scoreboard.header.fraction": "Fraktion",
|
"stats.scoreboard.header.fraction": "Fraktion",
|
||||||
|
@ -53,6 +65,8 @@
|
||||||
"stats.scoreboard.header.vehicle.air": "Fahrzeug (Luft)",
|
"stats.scoreboard.header.vehicle.air": "Fahrzeug (Luft)",
|
||||||
"stats.scoreboard.header.death": "Tode",
|
"stats.scoreboard.header.death": "Tode",
|
||||||
"stats.scoreboard.header.respawn": "Respawn",
|
"stats.scoreboard.header.respawn": "Respawn",
|
||||||
|
"stats.scoreboard.header.travel.distance": "Passagier Flugdistanz (km)",
|
||||||
|
"stats.scoreboard.header.driver.distance": "Pilot Flugdistanz (km)",
|
||||||
"stats.scoreboard.button.detail": "Kampagnenstatistik für {{name}}",
|
"stats.scoreboard.button.detail": "Kampagnenstatistik für {{name}}",
|
||||||
|
|
||||||
"stats.highscore.filter.placholder": "Spielername (mehrere mit '&' trennen)",
|
"stats.highscore.filter.placholder": "Spielername (mehrere mit '&' trennen)",
|
||||||
|
|
|
@ -35,6 +35,16 @@
|
||||||
"stats.fraction.select.revive": "Revive",
|
"stats.fraction.select.revive": "Revive",
|
||||||
"stats.fraction.select.stabilize": "Stabilized",
|
"stats.fraction.select.stabilize": "Stabilized",
|
||||||
"stats.fraction.select.flag": "Flag Possession",
|
"stats.fraction.select.flag": "Flag Possession",
|
||||||
|
"stats.fraction.select.player.count": "Player Count",
|
||||||
|
|
||||||
|
"stats.performance.select.single.avg": "Player FPS Average",
|
||||||
|
"stats.performance.select.single.min": "Player FPS Minimum",
|
||||||
|
"stats.performance.select.timeline.avg": "Timeline FPS Average",
|
||||||
|
"stats.performance.select.timeline.min": "Timeline FPS Minimum",
|
||||||
|
"stats.performance.select.timeline.server": "Server FPS",
|
||||||
|
"stats.performance.select.timeline.label.minimum": "Minimum",
|
||||||
|
"stats.performance.select.timeline.label.average": "Average",
|
||||||
|
"stats.performance.select.timeline.label.maximum": "Maximum",
|
||||||
|
|
||||||
"stats.player.detail.headline": "Campaign Details - {{name}}",
|
"stats.player.detail.headline": "Campaign Details - {{name}}",
|
||||||
"stats.player.detail.button.back": "Back",
|
"stats.player.detail.button.back": "Back",
|
||||||
|
@ -49,6 +59,7 @@
|
||||||
"stats.scoreboard.tab.scoreboard": "Scoreboard",
|
"stats.scoreboard.tab.scoreboard": "Scoreboard",
|
||||||
"stats.scoreboard.tab.fractions": "Fractions",
|
"stats.scoreboard.tab.fractions": "Fractions",
|
||||||
"stats.scoreboard.tab.player": "Player",
|
"stats.scoreboard.tab.player": "Player",
|
||||||
|
"stats.scoreboard.tab.performance": "Performance",
|
||||||
"stats.scoreboard.fraction.filter.all": "All",
|
"stats.scoreboard.fraction.filter.all": "All",
|
||||||
"stats.scoreboard.header.player": "Player",
|
"stats.scoreboard.header.player": "Player",
|
||||||
"stats.scoreboard.header.fraction": "Fraction",
|
"stats.scoreboard.header.fraction": "Fraction",
|
||||||
|
@ -61,6 +72,8 @@
|
||||||
"stats.scoreboard.header.vehicle.air": "Vehicle (Air)",
|
"stats.scoreboard.header.vehicle.air": "Vehicle (Air)",
|
||||||
"stats.scoreboard.header.death": "Death",
|
"stats.scoreboard.header.death": "Death",
|
||||||
"stats.scoreboard.header.respawn": "Respawn",
|
"stats.scoreboard.header.respawn": "Respawn",
|
||||||
|
"stats.scoreboard.header.travel.distance": "Passenger Travel Distance (km)",
|
||||||
|
"stats.scoreboard.header.driver.distance": "Pilot Travel Distance (km)",
|
||||||
"stats.scoreboard.button.detail": "Campaign statistics for {{name}}",
|
"stats.scoreboard.button.detail": "Campaign statistics for {{name}}",
|
||||||
|
|
||||||
"stats.highscore.filter.placholder": "Player Name (separate multiple using '&')",
|
"stats.highscore.filter.placholder": "Player Name (separate multiple using '&')",
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="5.3327in" height="5in" version="1.1" viewBox="0 0 512 490" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="none" stroke="#000" stroke-width="20">
|
||||||
|
<path id="outline"
|
||||||
|
d="m328.5 435.5 71.5 0.5 3.5 28.5-289-1.5 10-28.5 62.5 0.5s11-37.5 12.72-53.36c-82.82 0.2-152.22 0.36-152.22 0.36-39.96-4.54-37-34.5-37-34.5l-2-282.5s-0.32-18.24 7-26c9-9.55 26-9 26-9s426.5-1 426.5-1c39.96 4.54 37 34.5 37 34.5l2 282.5s-1.22 15.25-9 23.5c-8.67 9.2-24 11.5-24 11.5s-71.37 0.17-155.73 0.37c8.23 38.63 10.23 54.13 10.23 54.13z"/>
|
||||||
|
</g>
|
||||||
|
<g fill="none" stroke="#000" stroke-width="14">
|
||||||
|
<path id="inline" d="m457 79v230h-400v-233h400z"/>
|
||||||
|
</g>
|
||||||
|
<g fill="none" stroke="#000" stroke-width="30">
|
||||||
|
<path id="arrow"
|
||||||
|
d="m133.68 258.51 59.2-52.57 54.05 49.13 131.67-131.18m-47.66-0.98s38.33-4.18 48.64-0.49c5.9 5.65-0.24 49.62-0.24 49.62"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 909 B |
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="6.9in"
|
||||||
|
height="6.9in"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 500 500"
|
||||||
|
id="svg9"
|
||||||
|
sodipodi:docname="driver-distance.svg"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||||
|
<metadata
|
||||||
|
id="metadata15">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs13" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1053"
|
||||||
|
id="namedview11"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.71256038"
|
||||||
|
inkscape:cx="128.73924"
|
||||||
|
inkscape:cy="570.81484"
|
||||||
|
inkscape:window-x="425"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg9" />
|
||||||
|
<path
|
||||||
|
id="Selection"
|
||||||
|
d="m46 299c-1.8 0.83-2.8 1.1-4.2 2.8-3.4 3.8-4 11-0.42 16 2.4 3.3 6.3 4.9 7.7 6.2 2.3 2.3 3.4 7.3 1.2 9.8-3.6 4.1-12-0.85-14-14-2.3-14 1.5-22 8-30l1.8 9.5zm410 84-23-12s-142-49-145-51c0 0-14-7.5-16-9.5-2.8-2.8-4.8-7.9-9.9-10-5.5-2.2-12 1.4-19-2.8l-111-105s-5.5-0.74-5-2.5l-0.9 4.4c6.1 3.8 106 95 112 103l-150-78c2 6.1 3.1 6.4 7.5 8.6l137 72c5.7 3 13 7.3 17 13l-4.9-3.3c-4-2-20-5.5-24-4.3-2.8 0.91-21 14-22 14-1.9 0.14-7.8-3.2-9.9-4.3-2.6 9.5-3.6 8.2-10 10l-29 7s-28-6.8-31-9c-14-8.3-15-2.3-27-5.3-2.6-0.91-8.6-2.5-11-5.3-1.7-1.9-2.1-6.2-2.6-9 0 0-17-98-20-102-1.8-2.6-22-14-22-14s1.4 74 0.23 77c-0.82 2.5-23 34-22 40 2.1 11 14 30 20 37 3 2.9 32 19 36 18 2.6-0.88 7.2-11 8.7-14 6.2 3.1 22 11 27 17 3.8 4.9 2.5 13 5 18 1.7 3.4 12 8.2 14 7.1 4.7-2.5 3.5-10 11-5.8l58 41 79 37s69 23 77 23c2.4 0.018 10-2.8 11-4.1 11-9.4-4.3-25-6.2-29 0 0-26-51-34-59-6.9-6.6-19-12-27-16 1.8-9-17-32-17-32-1.7-2.8-1.3-7.1-2.5-11-1.2-3.4-3.1-4.9-5.4-6.8 2.7-9.9 8.4-2.9 14-0.4l64 26 0.45-2.2s-42-17-47-22l142 52 14 2.5z" />
|
||||||
|
<g
|
||||||
|
id="g7"
|
||||||
|
style="fill-rule:evenodd">
|
||||||
|
<path
|
||||||
|
d="m 360,0 v 70 l 70,68 -70,68 v 69 L 502,137 Z"
|
||||||
|
id="path3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccc" />
|
||||||
|
<path
|
||||||
|
d="m 262,2.7 v 70 l 70,68 -70,68 v 69 l 142,-138 z"
|
||||||
|
id="path5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1 @@
|
||||||
|
<svg width="19in" height="19in" version="1.1" viewBox="0 0 1368 1368" xmlns="http://www.w3.org/2000/svg"><path id="Auswahl" transform="scale(.75)" d="m1375 0c-11 7.3-22 14-32 17-456 101-935 160-1344 256v57c354-82 743-156 1074-209 138-18 276-53 363-47 2.5-0.16 6.8-0.39 9.1 0 8.5 3.5 9.5 13 19 16 4.1 2 11 0.36 16 0l33-6.5c3.7-0.69 13-2.6 16-1.3 10 4 2.7 20 7.9 29 2.9 6 11 7.2 13 13 2.1 5.5-1.6 14-3.3 19-4 11-12 37-19 45-8 9.3-39 23-52 31-20 11-51 39-69 55-16 14-18 10-24 17-11 15-14 33-21 48-19 30-30 55-40 88-11 28-18 57-24 87-1.6 5.9-2.9 15-8.3 19-6.7 6.3-21-1.3-23 16-0.4 6.4 1.1 12 5.7 16 5.2 4.4 13 2.4 13 12-11 52-6.3 104-12 151-5.3 0-21 0.93-27-1.9-5.3-4-17-22-21-28-16-21-33-43-52-61-9.7-10-6.1-14-11-20-4-5.7-13-6.2-20-6.4v11l-29-4.3-25 6c-8 0.27-16-6.7-28-5.2-15 2-17 17-27 11-12-6.7-6.6-15-6.3-24 0.27-6.4-3-9.5-3.3-15l1.5-11-2.7-17c-1.9-5.1-7.5-4-12-10l-4.7-9.9c-2.7-4-21-17-25-17-5.5-0.67-10 4.8-16 6l-1.8-0.18-3.3 1.3c-7.1 2.2-9.3 3.6-13 7.8l-31 5.5c-1.6-3.2-2.9-6.8-7.2-7.5-4-0.67-8.3 3.6-11 5.9-11 8.9-10 8.8-20 19-2.8 2.8-7.1 6.4-9.1 9.9-5.3 8.9 4.1 12 2.7 21-1.3 6.7-19 35-17 44 1.9 13 14 21 13 36 9.3 3.5 8 5.7 15 9.2 4.7 2.3 7.5 1.3 15 5.2 14 7.7 13 11 20 17 5.2 4.3 11 5.7 13 13 1.9 6.7-3.6 14-5.9 21l9.2 1.9 3.6-33 33 19h20l11-13c-1.6 8-6.7 22-4.7 29 2 6.8 7.1 7.6 9.7 16l3.7 25c1.9 6.1 6 10 4.3 16-2.7 6.7-17 18-23 23-25 22-21 14-36 24l-20 17c-9.3 5.5-8-3.6-24 11 0.35-3.2 0.45-8 0-11-8-25-40 3.5-48 4.8-5.6 1.1-10-4.2-16-3.9-3.3 0.13-6.4 2-9.1 4-19 15-2.4 24 5.5 37 6.7 12 13 8.3 25 9.2l-6.8 15-49 45c-7.5-10-16-0.67-20 7.3-11 2.7-9.7 13-11 21l-2.5 13c0.13 4.3 2.3 7.3 1.5 11-1.3 6.7-12 13-8 20 6.7 10 20-15 28-4.4 3.3 5.3 7.2 23 4.3 28-3.2 4.5-11 8.8-13 17-2.7 10 8 23 19 23 8-0.13 9.1-5.6 19-6.5-4.9 15-4.8 24-3.5 39v15l17 64 2.3 33c-2.4 19-6.7 11-4.9 36 0.93 13-9.4 19-10 29-0.67 6.7 8.1 17 8.4 33v21c0.53 11 5.2 25 1.9 35-10 21-29 27-46 36-21 9.2-19 17-21 38-12-0.8-19 5.3-28 11 0.27 13-4.5 17 3.6 29 8 11 21 15 33 17 27 4.7 44 5.5 69-6.1 13-6.7 27-23 40-25 6.8-0.93 9.9 2.3 15 3.2 6.7 1.1 14-3.5 20-6.1 19-9.3 31-11 29-35 0.13-5.9-2-14 0-19 1.6-5.2 6.5-6.9 9.1-11 1.7-4 0.75-13 0-17-1.5-15-15-37-15-44 0.4-6.7 6.9-11 9.9-20l5.2-25 8.1-28 4.3-25v-19l3.5-19-2.9-35c0.27-17-6.7-36-9.9-53 28 1.3 35 15 55 16 41-6.7 78-10 121-15 67-3.6 114-12 169-43 4-2 13-7.7 17-6.9 8 1.3 16 25 21 33l43 59c8 8 27 23 31 32l-24 10c-37 17-61 33-92 60-20 14-32 35-52 45-4-21-27-19-32-11-10 17 10 39 2.4 53l-48 65c-9.3 16-29 48-37 64l-16 33-8.1 19c-9.3 16-16 13-25 29l-43 95c-8 19-15 37-27 53-60-2.4-51-6.4-76 13-5.5 11-10 17-12 28l0.99 39h113c3.7 0 10 0.4 13-1.9 3.7-2.7 11-29 13-35l16-43c8-15 38-52 49-65l47-55 16-20 15-15 48-56c16-16 29-25 32-28l7.3-10c3.6-5.1 8.8-10 13-15 17-17 35-31 53-45 32-27 45-36 83-55 62-31 49-30 104-40 48-9.6 44-3.8 88-3.3 55 23 119 26 174 28v-1279c1.2-64-0.46-76 0-94zm-3.1 431c4.6 30-12 55-19 81l-10 17c-2.1 8 8.2 14 8.7 24 0.53 13-10 24-7.6 43-16-0.27-12 1.2-25 7.3l4.3-29c7.6-18 29-144 49-143zm-51 182c7.7 9.3 13 8.4 15 13 1.2 15-3.9 30-6.7 44-1.5 3.7-4.1 7.7-8.5 7.9-7.3 0-7.5-9.6-7.1-15l0.68-1.2c1.1-15 0.8-37 6.9-49zm-296 241c1.5 21 7.5 19 10 29 1.2 3.9 0.8 8.5-3.5 10-6.1 2.7-9.6-4.5-16-7.7-7.6-3.3-15-3.1-22-2.7 5.3-20 12-24 31-29zm-66 104c7.6 9.3 20 18 0 24zm508 303c1.1 0 2.1 0.076 3 0.24 8 1.3 35 19 44 24 5.3 3.6 22 11 24 16 5.3 13-12 17-20 20-53 20-104 49-143 81v-1.1c-11 9.3-59 47-69 52-6.7-11-17-33-21-45-1.7-5.3-5-15-4-20 0.67-6.1 8.4-13 13-17l53-48c28-23 60-43 95-56 7-2.3 17-5.9 25-5.8zm-218 163c7.1 16 9.1 22 12 35 2.8 9.3 9.2 25 7.2 35-2.7 8-21 27-28 35l-67 76c-9.3 9.3-20 27-32 31 2.1-8 6.9-16 7.7-24v-11c1.3-11 16-42 21-53l45-79z"/></svg>
|
After Width: | Height: | Size: 3.5 KiB |
|
@ -1,130 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<svg enable-background="new 0 0 100 67.1" version="1.0" viewBox="0 0 100 67" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<path d="m68 22c-0.55 0.6-0.25-0.091 0 0z"/>
|
||||||
<svg version="1.0" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<path d="m100 5.6c-4.6 1.5-9 4.1-14 6.1-5.1 2.4-10 5.1-15 7.3-3.1-0.24-6.5 0.8-9.7 1.2-4.6 0.59-9 2-13 3.1 2.2-3.1 5.7-4.4 8.2-7.2 5.8-5.5 12-11 18-16-3.4-1.3-7.4 2.2-9.8 4.8-5.9 5.3-12 11-17 16-2.2 1.2-0.53-3.6-3.2-1.2-3.1 0.92 1 2.2-0.84 3.5 1.4 1.3-3.2 2.5-3.5 3.7-7 4.1-14 8.2-21 13-6.4 3.9-13 8.1-19 12 2.1 1.2 6.1-3.3 8.8-4.5 8.1-5.3 16-10 25-15 3.7-1.8 7-4.5 11-5.9 3.2-1.3 0.19 2.1 2.4 3.4 1.5 3.4-4.7 2.1-6.8 3.9-11 4.7-22 9.5-32 15-4 4.7 3.7-0.086 5.9-0.94 8.5-4.1 20-9.6 27-13 1.7-1.2 6.2-2.7 6.6-2.6-2.4 3.1-5.9 5.7-8.1 8.4 0.21 4.1-5 4.4-5.1 8.4-0.48 0.72-2.6-0.39-3.1 1.1 2.9-1-3.4 1.9-4.1 2.3-5.3 0.41-2.3 8.3 1.8 5 1.8 0.38 2.8 3.2 5.1 2.1 0.71 5.5 6.5-1.1 8.4 1.6-2 2.5-6.1 2.2-9.3 3-2.8 1.1 0.19 2.7 2 1.5 3.4-1.9 6.1-0.28 9.3-0.2 3.1-0.39 6.4-2.2 8.4 0.9 4.2 0.45 1.4-4.4 1.6-5.3 2.9-2-2.2-2.6-2.1-3.6 2.9-3 6-1 9.3 0.052 2.3 0.32 4.2 5.1 6.4 1.4 1.5-3.5-4.8-6.6-5.1-2.2-2.2 0.11-2.9-4.4-0.85-1.1 1.6-1.1-3-3.5 0.75-3.5 1.1-1.7 3.4-2.1 5.2-2.5 1.7-2.6 4.2-1.9 4.2-0.25-1.1 0.92 1 4.2 2.2 1.8 2.9 0.21 0.52-3.9-1.2-2.3-3-1.3 2.2-3.3 0.96-3.2-1.1-1.2 2.5-1.6 2.9-3.2 0.32-2 3.9-1.7 5.3-3.4-1.7-2.2 1.8-2.7 4-3.3 2.6 3.7 2.3-6.3 0.24-5.3-1.3 1.2 0.97 4.8-1.3 4.9-3 0.72 0.47-3.5 0.76-5.2 0.82-2.6 4-7 3.3-8.6-1.9 3.3-3.8 6.7-5.6 10-1.2-5-4.4 0.66-6.9-0.2-2.4-3-7.3-4.4-10-1.5-3.5 1.3-8.3 1.5-12 2.5-2 1.5-2.7 0.062-0.65-0.48-2.2-1.8-1.8-2.5 0.65-3.9 3.1-1.5 6.2-3.6 9.5-5.1 5.9-2.7 12-6 18-8.7 5.7-3.1 12-5.4 18-8.5 0.15-0.38 2.1-0.033 1.5-0.9zm-51 30c-1.8 1.2-3.9 2.2-1.1-0.22 0.97-0.65-0.5-2 0.95-0.57zm0.2-1.2c-0.78-1.2-0.0042-1.9 0 0zm0.5-1.6c0.69 2-1.4 0.34 0 0zm-2.4-3.7c1.6 1.2 1.5 3.6 0 1.2-1.5-1.3 0.54-3 0-1.2zm-0.7-2.3c-1.2-0.63-0.83-2.3 0 0zm1.2-1.5c0.93 1.8-1-0.95 0 0zm3 4.8c-0.53 1.1-1.5-2.4-1.9-2.7 0.66-0.18 2 2.2 1.9 2.7zm1.6 2.1c-0.62-0.79-0.21-0.8 0 0zm0.9 0.1c-0.84-0.18-1.1-1.1 0 0zm13-10c-3.7 1.9-7.4 4-11 5.8-2.3 1.6-4.8 2.6-5.7-1.2-2.8-2.1 1.6-2.7 3-2.8 1.5 0.74 6.1-1.3 8.6-1.3 1-0.048 9.3-2.1 5.1-0.5z"/>
|
||||||
viewBox="0 0 100 67.1" style="enable-background:new 0 0 100 67.1;" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<path d="M68.5,21.6c-0.1,0-0.2,0.1-0.3,0.2C68.3,21.6,68.4,21.6,68.5,21.6z"/>
|
|
||||||
<path d="M99.9,5.6c-0.4-0.1-0.6,0-0.9,0.2c-0.9,0.4-1.8,0.8-2.8,1.2c-0.9,0.4-1.8,0.8-2.7,1.3c-0.8,0.4-1.7,0.8-2.5,1.1
|
|
||||||
c-0.9,0.5-1.7,0.8-2.6,1.3c-0.9,0.5-1.8,0.8-2.7,1.3c-0.7,0.3-1.3,0.6-2,1c-0.8,0.4-1.7,0.8-2.5,1.2c-0.8,0.4-1.7,0.8-2.5,1.2
|
|
||||||
c-0.8,0.3-1.6,0.8-2.4,1.2c-0.8,0.4-1.7,0.8-2.5,1.2c-0.7,0.3-1.4,0.6-2.1,1c-0.3,0.2-0.6,0.4-0.9,0c-0.1-0.1-0.2,0-0.3,0
|
|
||||||
c-0.5,0.1-1,0.2-1.5,0.2c-0.8,0.1-1.5,0.2-2.2,0.3c-1,0.2-1.9,0.3-2.8,0.4c-0.8,0.1-1.4,0.3-2.2,0.4c-0.7,0.1-1.4,0.2-2.1,0.3
|
|
||||||
c-1.4,0.3-2.7,0.5-4.1,0.9c-0.7,0.2-1.5,0.3-2.3,0.5C52,22.2,51,22.6,50,22.7c-0.1,0-0.1,0-0.2,0.1l0,0c-0.1,0-0.3,0.1-0.4,0.2
|
|
||||||
c-0.5,0.2-1,0.3-1.5,0.3c0.2-0.2,0.1-0.4,0.3-0.4c0.4-0.2,0.7-0.4,0.9-0.8c0.5-0.7,1-1.2,1.6-1.8c0.2-0.4,0.7-0.5,1.1-0.7
|
|
||||||
c0.4-0.1,0.9-0.2,1.2-0.6c0.8-0.8,1.6-1.6,2.4-2.2c0.9-0.9,1.9-1.9,2.8-2.7c1.1-1,2.3-2,3.4-3s2.2-2,3.3-2.9c0.7-0.7,1.6-1.3,2.3-2
|
|
||||||
c0.7-0.5,1.2-1,1.9-1.5s1.3-1.1,1.9-1.7c0.4-0.3,0.7-0.7,1.1-1c0.7-0.5,1.2-1,1.8-1.4c0.2-0.2,0.4-0.2,0.3-0.4
|
|
||||||
c-0.1-0.2-0.3,0-0.6-0.1c-0.8,0.1-1.6,0.1-2.5,0.1c-0.1,0-0.3,0.1-0.4,0.1c-0.4,0.2-0.7,0.5-1.1,0.7c-0.5,0.2-1,0.6-1.6,1
|
|
||||||
c-0.2,0.2-0.5,0.2-0.7,0.4c-0.8,0.7-1.7,1.5-2.5,2.2c-0.5,0.8-1.2,1.5-2,2c-0.8,0.7-1.7,1.5-2.6,2.3c-0.7,0.5-1.2,1.1-1.7,1.6
|
|
||||||
c-1,1-2,1.9-3,2.7c-0.6,0.6-1.3,1.1-1.9,1.8c-1,1-1.9,2-2.9,2.8c-1.2,1.1-2.2,2.3-3.4,3.5c-0.2,0.2-0.4,0.6-0.8,0.5
|
|
||||||
c-0.2,0-0.6,0.2-0.7-0.1c-0.1-0.2-0.2-0.3-0.2-0.5c-0.1-0.2-0.1-0.3,0-0.5c0.2-0.2,0.1-0.4,0-0.6c-0.2-0.2-0.3-0.3-0.5-0.2
|
|
||||||
c-1,0.3-1.8,0.7-2.5,1.2c-0.2,0.2-0.3,0.4-0.3,0.6c0.1,0.3,0.4,0.3,0.6,0.3c0.2-0.1,0.2,0,0.4,0.2c0.1,0.2,0.2,0.3,0.2,0.5
|
|
||||||
c0,0.1,0.1,0.2,0,0.2c-0.3,0.2-0.4,0.5-0.7,0.7c-0.2,0.2-0.2,0.3,0.1,0.3s0.3,0.3,0.5,0.4c0.1,0.1,0.2,0.2,0,0.2c0,0-0.1,0-0.2,0.1
|
|
||||||
c-0.5,0.4-1.1,0.7-1.6,1.1c-0.3,0.2-0.7,0.3-0.8,0.8l-0.2,0.2c-0.3,0-0.7,0.3-1,0.4c-0.2,0.1-0.4,0.1-0.2,0.4c0,0,0,0.2-0.2,0.2
|
|
||||||
l0,0c-0.1,0-0.2,0.1-0.3,0.2c-2,1.1-3.9,2.3-5.8,3.4l0,0c-0.1,0-0.2,0.1-0.3,0.2c-0.8,0.4-1.6,1-2.4,1.4c-0.6,0.4-1.2,0.8-1.7,1
|
|
||||||
c-0.4,0.2-0.9,0.6-1.3,0.8c-0.8,0.4-1.5,1-2.2,1.4c-0.8,0.4-1.6,1-2.3,1.5c-1,0.6-1.9,1.3-2.9,1.9c-0.5,0.4-1.1,0.7-1.7,1
|
|
||||||
c-1,0.6-1.8,1.3-2.9,1.8c-0.1,0-0.2,0.1-0.3,0.2l0,0c-0.4,0.2-0.8,0.5-1.2,0.8c-0.1,0-0.2,0.1-0.3,0.2c-0.3,0.2-0.6,0.4-0.9,0.6
|
|
||||||
c-0.3,0.2-0.6,0.4-0.9,0.6c-0.9,0.6-1.7,1.2-2.6,1.7c-0.5,0.2-0.9,0.6-1.3,0.9c-0.9,0.6-1.6,1.1-2.5,1.7c-0.3,0.2-0.6,0.4-1,0.6
|
|
||||||
c-0.8,0.5-1.5,1.1-2.4,1.7l0,0c-0.1,0.1-0.3,0.1-0.4,0.3l0,0c-0.5,0.4-1,0.6-1.5,1C0.1,52.8,0,53,0,53.1c0.5,0.2,0.6,0.2,0.7,0.1
|
|
||||||
c0.4-0.1,0.7-0.3,1.1-0.5l0,0c0.1,0,0.3-0.1,0.4-0.3l0,0c0.6-0.4,1.2-0.7,1.8-1c0.9-0.6,1.8-1.2,2.7-1.9c0.3-0.2,0.7-0.4,1-0.6
|
|
||||||
c0.8-0.5,1.5-1.1,2.3-1.5c0.6-0.4,1.3-0.8,1.8-1.2c1.1-0.7,2.1-1.4,3.2-2.1c0.9-0.6,1.6-1.1,2.5-1.6c0.8-0.4,1.5-1.1,2.4-1.4l0,0
|
|
||||||
l0,0c0.1,0,0.2-0.1,0.3-0.2c0.4-0.2,0.8-0.5,1.1-0.7c0.3-0.2,0.7-0.4,1-0.6c0.9-0.6,1.7-1.2,2.6-1.7c0.8-0.4,1.5-1,2.2-1.4
|
|
||||||
c0.8-0.4,1.6-1,2.4-1.4c0.8-0.4,1.6-1,2.4-1.4c0.7-0.4,1.3-0.9,2.1-1.2l0,0l0,0c0.1,0,0.3-0.1,0.3-0.2c0.7-0.4,1.3-0.7,2-1.1l0,0
|
|
||||||
l0,0c0.2-0.2,0.4-0.1,0.5-0.4l0,0l0,0c0.8-0.4,1.7-0.9,2.5-1.5c0.3-0.2,0.6-0.4,1-0.5s0.8-0.4,1.1-0.7c0.1-0.1,0.2-0.2,0.3-0.2
|
|
||||||
c0.3,0,0.6-0.2,0.9-0.2c0.5-0.2,0.9-0.5,1.4-0.7l0,0l0,0c0.1,0.1,0.2-0.1,0.3-0.1c0.4-0.2,0.8-0.3,1.1-0.5c0.1,0,0.2-0.1,0.2,0
|
|
||||||
c0.2,0.3,0.4,0.5,0.5,0.8c0,0.1,0.2,0.2,0.1,0.4c-0.1,0.1-0.3,0.3-0.4,0.2l0,0l0,0c-0.2-0.2-0.2,0.1-0.3,0.2l0,0l0,0
|
|
||||||
c0,0.3,0.2,0.4,0.4,0.6c0.5,1.1,1.1,2.2,1.4,3.3c-0.1,0-0.2,0.1-0.3,0.2l0,0c-0.3,0.1-0.6,0-0.9,0.1c-0.1,0-0.3,0-0.4,0.1
|
|
||||||
c-0.4,0.5-1,0.5-1.5,0.6c-0.5-0.1-0.9-0.1-1.3,0.1c-0.6,0.3-1.2,0.4-1.9,0.7c-0.7,0.3-1.4,0.6-2.1,0.9c-0.5,0.2-1,0.5-1.5,0.6
|
|
||||||
c-0.7,0.3-1.3,0.6-2,0.9c-0.5,0.2-0.9,0.4-1.4,0.6c-0.9,0.4-1.7,0.8-2.7,1.2c-0.4,0.2-0.8,0.4-1.2,0.6c-0.9,0.4-1.8,0.8-2.8,1.2
|
|
||||||
c-0.6,0.3-1.1,0.5-1.7,0.8c-0.9,0.4-1.8,0.8-2.7,1.2c-0.7,0.3-1.4,0.7-2.2,1.1c-0.9,0.5-1.7,0.9-2.6,1.3c-0.7,0.3-1.4,0.7-2.2,1.1
|
|
||||||
c-1.2,0.6-2.4,1.1-3.6,1.8c-1,0.5-2,1.1-3,1.7c-0.1,0-0.3,0.1-0.4,0.2c-0.1,0-0.3,0.2-0.4,0.2c-0.5,0.2-1,0.5-1.3,1
|
|
||||||
c-0.2,0.3-0.3,0.6-0.4,0.9C6.3,51,6.4,51.7,6.3,52c0.9-0.2,32.6-15.8,33.9-16.5c-0.2,0.1-0.3,0.2-0.5,0.2c0.2-0.1,0.4-0.1,0.5-0.2
|
|
||||||
c0.1,0,1.3-0.9,2-1.1s1.1-0.4,1.8-0.6c0.5-0.1,0.9-0.5,1.5-0.5c0.3,0,0.5-0.1,0.7-0.3c0.3-0.2,0.6-0.5,0.9-0.5l0,0
|
|
||||||
c-0.2,0.1-0.2,0.3-0.3,0.4c-0.3,0.3-0.5,0.6-0.9,0.8c-0.6,0.6-1,1.2-1.5,1.8c-0.7,0.9-1.5,1.7-2.2,2.5c-0.1,0.1-0.2,0.3-0.3,0.4
|
|
||||||
c-0.5,0.4-0.8,0.7-1.3,0.9c-0.6,0.4-1.1,0.7-1.7,1c-0.1,0-0.1,0.1-0.1,0.1c-0.2,0.6-0.1,1.2-0.1,1.7c0,0.1,0,0.3-0.1,0.4
|
|
||||||
c-0.3,0.3-0.4,0.7-0.7,1c-0.1,0.1-0.4,0.3-0.2,0.5c0.1,0.2,0.1,0.4,0.2,0.5c-0.2,0.2-0.4,0.2-0.6,0.4c-0.8,0.7-1.8,1.3-2.7,2
|
|
||||||
c-0.2,0.2-0.5,0.2-0.6,0.5c0,0.3-0.1,0.7-0.1,1.2c0,0.8-0.5,1.5-1.3,1.6c0.1-0.1,0.3-0.2,0.1-0.4c-0.2-0.2-0.3,0-0.5,0
|
|
||||||
s-0.1,0-0.2,0.1c-0.4,0.1-0.9,0.4-1.4,0.5c-0.1,0-0.3,0.1-0.3,0.3c0.1,0.2,0.2,0,0.3,0c0.3-0.1,0.5-0.1,0.8-0.3
|
|
||||||
c0.1,0,0.2-0.1,0.2,0c0,0.1-0.1,0.1-0.1,0.1c-0.4,0.2-0.8,0.4-1.2,0.6c-1.1,0.5-2.2,1.1-3.2,1.6c-0.5,0.2-1,0.5-1.5,0.6
|
|
||||||
c-0.6,0.3-1.1,0.4-1.6,1c-0.4,0.6-0.6,1.1-0.7,1.8c0,0.7,0.3,1.4,0.9,1.9c0.2,0.2,0.4,0.2,0.7,0.4c0.6,0.4,1.3,0.5,1.9,0.2
|
|
||||||
c0.5-0.1,0.9-0.4,1.4-0.6c0.1,0,0.2-0.1,0.3,0c0.2,0.4,0.5,0.2,0.8,0.3c0.1,0,0.1,0,0.1,0.1c0.2,0.3,0.4,0.6,0.5,0.8
|
|
||||||
c0.6,1,1.9,1.4,3,0.8c0.2-0.1,0.3-0.1,0.4,0.1c0.1,0.5,0.4,1,0.7,1.6c0.3,0.6,0.7,0.9,1.3,0.8c0.6-0.2,1.4-0.5,2-0.6
|
|
||||||
c0.5-0.1,1-0.4,1.5-0.6c0.3-0.1,0.6,0.1,0.8,0c0.4-0.1,1-0.3,1.4-0.4c0.2-0.1,0.3-0.1,0.4,0.2c0.1,0.2,0.1,0.4,0.3,0.6
|
|
||||||
c0.1,0.1,0.1,0.2,0,0.2c-0.5,0.2-0.9,0.5-1.4,0.7c-0.1,0-0.2,0.2-0.3,0.3c0,0.2,0,0.5-0.3,0.5c-1,0.2-1.9,0.3-2.8,0.5
|
|
||||||
c-1,0.3-1.9,0.3-2.8,0.5c-0.7,0.2-1.5,0.2-2.3,0.4c-0.2,0.1-0.4,0.1-0.4,0.2c-0.1,0.5-0.1,0.8-0.1,1.3c0,0.3,0.1,0.5,0.6,0.4
|
|
||||||
c0.6-0.2,1.3-0.3,1.9-0.5c0.2-0.1,0.3,0,0.6,0c0.6-0.3,1.3-0.3,1.9-0.5c1.1-0.2,2.3-0.5,3.4-0.7c0.2-0.1,0.2,0,0.4,0.1
|
|
||||||
c0.4,0.6,0.8,0.9,1.6,0.9l0.1,0c0.3,0.3,0.6,0.1,0.9,0c0.3-0.1,0.7-0.2,1,0c0.4,0.2,0.7,0,1.1-0.2c0.2-0.2,0.5-0.4,0.8-0.3
|
|
||||||
c1,0,2.1-0.1,3.1-0.2c0.1,0.1,0.2-0.1,0.3-0.1l0,0l0,0c0.2-0.2,0.5-0.2,0.7-0.4c0.1,0,0.2-0.1,0.2,0c0.1,0.3,0.3,0.6,0.5,0.9
|
|
||||||
c0.2,0.4,0.5,0.7,0.9,0.9c0.5,0.3,1,0.4,1.6,0.3c0.5-0.1,1-0.4,1.3-0.9c0.5-0.8,0.5-1.7,0.1-2.5c-0.2-0.5-0.5-1-1-1.5
|
|
||||||
c0-0.1-0.2-0.2-0.1-0.2c0.3,0,0.6-0.3,0.9-0.4c0.2-0.1,0.3-0.2,0.4-0.3c0.1-0.4,0-0.7-0.2-1.1s-0.7-0.6-1-1.1c0-0.1,0-0.1-0.1-0.1
|
|
||||||
c-0.6,0-1.1,0-1.7,0c0-0.8,0-0.8,0.6-1.1c0.7-0.3,1.3-0.6,2-1c0.3-0.2,0.6-0.3,0.9-0.5c0.2-0.1,0.3-0.1,0.5,0
|
|
||||||
c0.2,0,0.5,0.3,0.8,0.4c0.6,0.2,1.1,0.4,1.7,0.6c1.3,0.5,2.5,0.8,3.9,1.2c0.5,0.2,0.9,0.3,1.1,0.8c0.1,0.3,0.3,0.7,0.6,1
|
|
||||||
c0.6,0.5,1.2,0.9,2,0.7c0.7-0.2,1.4-0.6,1.7-1.4c0.1-0.4,0.1-0.8,0-1.3c0-0.6-0.2-1.1-0.5-1.6c-0.2-0.4-0.6-0.9-1-1.1
|
|
||||||
c-0.4-0.2-0.7-0.5-1.2-0.5c-0.5,0-0.9,0.1-1.3,0.3l0,0c-0.1,0-0.2,0.1-0.3,0.2l0,0c-0.7,0.4-0.7,1.1-0.8,1.8
|
|
||||||
c-0.5-0.1-0.9-0.3-1.3-0.5s-0.6-0.4-0.5-0.9c0-0.2-0.1-0.3-0.1-0.4c-0.3-0.3-0.2-0.5-0.3-0.8c0.4,0.5,0.8,0.8,1.1,1.3
|
|
||||||
c0.2,0.2,0.3,0.3,0.5,0.1c0.1-0.1,0.5-0.2,0.3-0.5c-0.2-0.2-0.2-0.4-0.4-0.6c-0.4-0.5-0.7-1.1-1.1-1.5c0-0.1-0.2-0.2-0.1-0.2
|
|
||||||
c0.2-0.2,0.4-0.3,0.6-0.2c0.1,0.1,0.2,0,0.3,0c0.6-0.3,1.3-0.3,1.5-1.1c0.1-0.1,0.1-0.1,0.2-0.2c0.6-0.3,1.2-0.6,1.8-0.9
|
|
||||||
c0.1,0.1,0.3-0.1,0.4-0.1c0.4-0.2,0.7-0.4,1.3-0.3c0.7,0,1.3-0.3,1.6-1l0.1-0.1c0.6-0.2,1.1-0.6,1.7-0.9c0.3-0.2,0.7-0.5,0.9-0.5
|
|
||||||
c0.3,0.2,0.4,0.6,0.6,0.9c0.1,0.2-0.2,0.5,0.1,0.7c0,0,0,0-0.1,0c-0.2,0.1-0.2,0.2-0.2,0.3c0.1,0.2,0.2,0.2,0.3,0.2
|
|
||||||
s0.2-0.2,0.4-0.1c-0.1,0.1-0.2,0.2-0.3,0.3c-0.4,0.5-0.3,0.9-0.1,1.4l0,0l0,0c0.1,0.2,0.1,0.3,0.2,0.4l0,0.1
|
|
||||||
c0.2,0.4,0.6,0.5,1.1,0.5c0.5,0,0.7-0.3,0.8-0.8c0-0.2,0.2-0.2,0.3-0.1c0.5,0.3,1.3-0.1,1.4-0.7c0-0.5-0.1-0.9-0.3-1.3
|
|
||||||
c-0.5-0.6-1.1-1-1.8-0.2c-0.1,0.1-0.1,0-0.2,0.1c-0.2,0-0.3-0.4-0.6-0.4c-0.2-0.2-0.2-0.3-0.1-0.4s0-0.3-0.1-0.3
|
|
||||||
c-0.3,0-0.4-0.2-0.5-0.4c-0.2-0.2-0.1-0.4,0.1-0.5c0.6-0.3,1.2-0.7,1.8-1c0.2-0.1,0.4-0.2,0.5-0.2c0.1,0,0.3-0.2,0.1-0.4
|
|
||||||
c-0.1-0.1-0.2,0-0.3,0c-0.1,0-0.1,0-0.2,0.2c-0.1,0-0.2,0.2-0.3,0.1c-0.1-0.1,0.1-0.1,0-0.2l0-0.1c0.1-0.6,0.2-1.1,0.8-1.1
|
|
||||||
c0.1,0,0.3-0.3,0.4-0.2c0.3,0.2,0.5,0,0.7-0.1c0.2-0.1,0.1-0.4,0.2-0.4c0.5-0.2,0.5-0.8,1-1.1c0.1,0,0.1-0.1,0-0.2
|
|
||||||
c-0.1-0.2-0.2-0.4,0.1-0.5c0.2-0.2,0.3-0.3,0.5-0.4c0.1,0,0.5,0.1,0.4-0.3c0-0.1,0.2-0.1,0.2,0c0.2,0.2,0.2,0,0.3,0
|
|
||||||
c0.7-0.3,1.4-0.7,2.1-1c0.5-0.2,1-0.6,1.6-0.8c0.1,0,0.2-0.3,0.2-0.3c-0.3-0.2-0.2-0.3-0.2-0.5c-0.2-0.2-0.3-0.4-0.4-0.7
|
|
||||||
c0-0.1,0-0.1,0-0.2c0.1,0,0.3-0.2,0.3,0c0,0.1,0.2,0.2,0.2,0c0.1,0,0.1-0.1,0-0.2c0-0.6,0-0.6,0.5-0.7c0.7-0.2,1.5-0.4,2.2-0.6
|
|
||||||
c0.4-0.1,0.9-0.2,1.4-0.4c0.1,0,0.2-0.1,0.2,0c0.1,0.3,0.3,0.6,0.3,0.8c0.1,0.2,0.2,0.3,0.3,0.2c0.3-0.2,0.7-0.3,1-0.5
|
|
||||||
c0.1,0,0.1-0.1,0-0.2c0-0.7,0-1.3-0.1-1.9c-0.1-1.2-0.3-2.4-0.5-3.6c0-0.5-0.1-0.5-0.5-0.3c-0.3,0.1-0.7,0.2-0.7,0.7
|
|
||||||
c0,0.5-0.1,0.9-0.1,1.5c0,0.8,0,1.7,0,2.5c0,0.1,0.1,0.2,0,0.2c-0.2,0.1-0.3,0.1-0.5,0.1c-0.7,0.1-1.3,0.2-1.9,0.4
|
|
||||||
c-0.1-0.2,0.2-0.3,0.1-0.4c0.1-0.1,0.2-0.3,0.2-0.3c-0.1-0.3,0.1-0.6,0-0.9c-0.1-0.2,0-0.2,0.3-0.3c0.3-0.1,0.5-0.4,0.3-0.6
|
|
||||||
c-0.2-0.2-0.1-0.2,0-0.3c0.4-0.8,0.6-1.4,1-2.2c0.7-1.3,1.2-2.7,1.9-4c0.3-0.6,0.7-1.3,0.9-2.1c0.4-0.9,0.8-1.8,1.2-2.6
|
|
||||||
c0.1-0.1,0.2-0.4,0.1-0.5c-0.1-0.1-0.3,0-0.5,0.1c-0.1,0-0.1,0.1-0.2,0.2c-0.2,0.3-0.2,0.5-0.4,0.8c-0.5,0.8-0.9,1.6-1.4,2.5
|
|
||||||
c-0.6,1.2-1.3,2.4-2,3.6c-0.3,0.6-0.7,1.2-1,1.9c-0.1,0.4-0.5,0.8-0.6,1.2c0-0.3-0.2-0.4-0.4-0.7c-0.1-0.2-0.1-0.5-0.4-0.6
|
|
||||||
c-0.1-0.1-0.3-0.2-0.3-0.3c-0.2-0.2-0.3-0.4-0.4-0.7c-0.2-0.2-0.3-0.3-0.5-0.1c-0.7,0.5-1.4,0.8-1.9,1.3c-0.6,0.5-1.3,0.7-2,1.2
|
|
||||||
c-0.1,0-0.1,0-0.2,0.1c-0.2,0-0.6-0.1-0.8-0.4c-0.4-0.6-1-1-1.5-1.4c-0.7-0.6-1.5-1-2.4-1.3c-0.3-0.2-0.6-0.2-1-0.2
|
|
||||||
c-0.9-0.2-1.8-0.3-2.6-0.2c-0.9,0.1-1.6,0.9-2.4,1.3c-0.3,0.2-0.6,0.3-0.7,0.7c-0.1,0.1-0.2,0.2-0.3,0.2c-0.3,0-0.7,0-1-0.1
|
|
||||||
c-0.7,0.1-1.3,0.1-1.9,0.3c-1,0.2-2,0.3-3,0.5c-0.7,0.2-1.6,0.5-2.3,0.6c-1.2,0.1-2.3,0.3-3.5,0.6c-0.1,0-0.2,0.1-0.3,0.2
|
|
||||||
c0,0.1-0.1,0.1-0.2,0.2s-0.2,0.1-0.4,0.1c-0.3,0.2-0.6,0.2-0.8,0.3c-0.1,0-0.1,0-0.2,0c-0.1-0.2-0.3-0.4-0.3-0.6
|
|
||||||
c0-0.2,0.3-0.1,0.5-0.1c0.1,0,0.2-0.1,0.2,0c0.2,0,0.3-0.1,0.3-0.2c-0.1-0.2,0.2-0.2,0.3-0.2c0.3-0.1,0.3-0.2,0.2-0.5
|
|
||||||
c-0.1-0.2-0.3-0.4-0.5-0.4c-0.5-0.4-0.9-0.9-1.5-1.3c0.7-0.5,1.4-0.8,2-1.3c0.2-0.2,0.5-0.2,0.6-0.6l0.1,0c0.5,0,0.9-0.2,1.2-0.4
|
|
||||||
c0.2-0.1,0.3-0.3,0.4-0.5c2.8-1.5,5.6-3.1,8.4-4.5c0,0,0,0,0.1,0c0.1,0.1,0.3-0.1,0.4-0.1l0,0l0,0c1.9-1,3.8-2,5.8-3l0,0l0,0
|
|
||||||
c0.1,0.1,0.2-0.1,0.3-0.1c0.4-0.2,0.8-0.4,1.3-0.7c0.1,0.1,0.3-0.1,0.4-0.2c0.9-0.5,1.8-0.9,2.7-1.4c0.8-0.4,1.6-0.8,2.4-1.2
|
|
||||||
c0.1,0.1,0.3-0.1,0.4-0.1l0,0l0,0c1.7-0.9,3.5-1.7,5.2-2.7l0,0l0,0c0.1,0.1,0.2-0.1,0.4-0.1l0,0l0,0c0.3-0.2,0.6-0.4,0.9-0.5
|
|
||||||
c1-0.4,2-1,3-1.4c0.6-0.3,1.2-0.6,1.8-0.8c0.9-0.5,1.9-1,2.8-1.3c0.8-0.3,1.6-0.8,2.5-1.2l0,0l0,0c0.1,0.1,0.2-0.1,0.3-0.1l0,0l0,0
|
|
||||||
c0.2-0.1,0.4-0.2,0.6-0.3l0,0l0,0c0.1,0.1,0.2-0.1,0.3-0.1c1-0.6,2.1-1.1,3.1-1.6C100,6.1,100,6,100,6C100,5.7,100,5.7,99.9,5.6z
|
|
||||||
M48.7,35.2c0,0.1-0.1,0.1-0.2,0.2c-0.7,0.4-1.4,0.7-2.1,1c-0.1,0-0.1,0.1-0.2,0.2c-0.1,0-0.2,0.2-0.2,0.1c0.7-0.8,1.4-1.5,2.1-2.3
|
|
||||||
c0.1,0,0.1-0.1,0-0.2s-0.1-0.1-0.2,0c-0.2,0.1-0.3,0-0.5,0c0.2-0.1,0.2-0.4,0.6-0.5c0.1,0,0.2-0.2,0.2,0
|
|
||||||
C48.4,34.2,48.7,34.6,48.7,35.2z M48.9,34c-0.3-0.4-0.5-0.8-0.2-1.3C48.6,33.3,49.1,33.5,48.9,34z M49.4,32.4
|
|
||||||
c0.1,0.2,0.1,0.5,0.1,0.8c0,0.1-0.1,0.1-0.2,0.2c-0.1,0-0.1-0.1-0.2-0.2c0-0.1-0.1-0.3-0.2-0.4C48.9,32.6,49.2,32.5,49.4,32.4
|
|
||||||
C49.3,32.3,49.4,32.3,49.4,32.4z M47,28.7c0.2,0.4,0.4,0.9,0.8,1.3l0,0.1c0,0.2,0.2,0.4,0.4,0.3c0.2-0.1,0.2,0,0.3,0.2
|
|
||||||
c0.1,0.2-0.1,0.1-0.2,0.2c-0.1,0-0.3,0.2-0.4,0.2c-0.5,0.2-0.5,0.2-0.6-0.3c-0.1-0.5-0.5-1-0.6-1.5c-0.1-0.3-0.3-0.7-0.4-1
|
|
||||||
c0.2,0,0.4-0.2,0.6-0.2c0.1,0,0.2-0.2,0.2,0c0,0.1,0.2,0.2,0.1,0.3C46.8,28.4,47,28.6,47,28.7z M46.3,26.4
|
|
||||||
c-0.2,0.1-0.3-0.2-0.3-0.3c-0.2-0.2-0.2-0.4-0.4-0.6c0,0-0.2-0.2-0.1-0.2c0.1-0.1,0.2-0.1,0.2,0C45.9,25.8,46.1,26.1,46.3,26.4z
|
|
||||||
M47.5,24.9c0.1,0.2,0.1,0.4,0.3,0.6c0,0.1,0,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1s-0.2-0.3-0.2-0.4l0,0c0-0.1-0.1-0.2-0.2-0.3
|
|
||||||
c0-0.1-0.1-0.2,0-0.2C47.4,24.7,47.4,24.7,47.5,24.9z M50.5,29.7c-0.1,0-0.3,0.1-0.2,0.3c0,0.1,0,0.2-0.2,0.2
|
|
||||||
c-0.2,0-0.4-0.5-0.2-0.6c0.1-0.1,0.2-0.3,0-0.3c-0.2-0.2-0.2-0.3-0.2-0.5c-0.2-0.4-0.4-0.7-0.6-1.1c-0.1-0.2-0.3-0.3-0.4-0.2
|
|
||||||
c-0.1,0-0.2,0-0.3-0.2c0-0.1,0-0.2,0.2-0.3c0.2-0.2,0.4-0.2,0.5,0.1c0.1,0.2,0.3,0.4,0.4,0.7c0.4,0.5,0.7,1.1,1.1,1.6
|
|
||||||
C50.7,29.6,50.7,29.7,50.5,29.7z M52.1,31.8c-0.3-0.2-0.2-0.4-0.3-0.6C52,31.4,52,31.6,52.1,31.8z M53,31.9c-0.5,0-0.5-0.3-0.7-0.6
|
|
||||||
C52.6,31.4,52.6,31.8,53,31.9z M65.9,21.8c-0.1,0-0.2,0.1-0.3,0.2c-3.1,1.6-6.3,3.3-9.4,5c-0.1,0-0.2,0.2-0.2,0.1
|
|
||||||
c-0.4-0.1-0.5,0.1-0.8,0.3c-0.2,0.2-0.5,0.2-0.6,0.5l-0.1,0c-0.6-0.1-1,0.4-1.5,0.6c-0.6,0.3-1.1,0.5-1.7,0.8c-0.1,0-0.2,0.1-0.2,0
|
|
||||||
c-0.3-0.4-0.6-0.9-0.9-1.3c-0.4-0.5-0.6-1.1-1-1.6c-0.1-0.2-0.2-0.3-0.1-0.5s-0.2-0.3-0.3-0.3c-0.3,0.1-0.5-0.1-0.5-0.3
|
|
||||||
c0-0.1-0.1-0.3-0.2-0.4c-0.2-0.3-0.1-0.3,0.2-0.4s0.5-0.1,0.8-0.3c0.2-0.1,0.5,0.1,0.7,0c0.1,0,0.2,0,0.3-0.1
|
|
||||||
c0.7-0.4,1.5-0.5,2.2-0.7c0,0.2-0.2,0.3-0.2,0.4c0,0.1-0.2,0.2,0,0.2c0,0.1,0.2,0,0.2,0c0.3-0.1,0.6-0.2,0.9-0.2
|
|
||||||
c1.3-0.2,2.5-0.5,3.8-0.8c1.3-0.3,2.5-0.4,3.8-0.7c1-0.2,2.1-0.3,3-0.6c1-0.2,2.1-0.3,3.1-0.5c0.1,0,0.3-0.2,0.5,0
|
|
||||||
C66.7,21.4,66.4,21.7,65.9,21.8z"/>
|
|
||||||
</g>
|
|
||||||
<image style="overflow:visible;" width="32" height="32" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAAmJLR0QA/4ePzL8AAAKFSURBVEjH
|
|
||||||
nZVdaM1hHMc/z3HYdrY5hNm8v9vWhLzlJYriBldWw4VSpBTJrShJ3LghpLzEBSkhipILJW8lUlpL
|
|
||||||
S9hwgUVi2M7HxTlnc7a/M87v4v+/eb6/7/f5/l4e+I8w/U3Yj0IiAz/hqQITgHW+94YxM8n+k929
|
|
||||||
fnJFgdIt97QvjNGLO9Y3POA0WmlkakhJ6OFJH2AB19phXU+AMSuc5fZ4PuYAeJbxVIRPWW4JGGMp
|
|
||||||
SRp5FR7/nb3MXVZ6wy0AFjvYSsc41Qk2uNmh2UuEvyao5B4prvGLGZST4iMljOUhB3gZvmW1QDxK
|
|
||||||
OjiQ5bTznYu08Y0PFDMHeBA+d3sRAEujSjbAZe52srPsdAE41x3OdXCEypj1oQdzkulM4H5oAgMX
|
|
||||||
GEILV8PlrlMl/Ogupgt5ldvnS13nMABne9LbttrhTeP2s9TJVrvbZp84H8C4w90JIcNcxkRqeEor
|
|
||||||
s1lBLfe5wlHeso7nFDOUZI72tcxjI0do5nSaeZL1Jqz2ug9tcLyY8LW/bDdfrPKO8bgjmclo2jnP
|
|
||||||
T/aHewCu4gqBQDxPm75BEgTc5jv3WWfZH+42qinzx3AHWAF4vEdpyt3UB/Srx5wSMUyZSmy1KS+8
|
|
||||||
xUURs2i6++d4Li+40/duyQXHuybsBIsZTSKPbU1sYD3BRHoWchXU5uFtt80nFgN4yMdWRU9fg6t9
|
|
||||||
FgE/Y7NXrfWwSTBhf6J2UsbAIg+qX2yxI8O90rSxd9X6iI3Vex043xr3+KNLwUQAB/nIJb1sz10o
|
|
||||||
QjWXeE0by0nynU6KKGFEeJc9mP4LEAupKB+KrLIUrLLGcY5yjbdM5N7WkF62/utT1i02C7OAZwUw
|
|
||||||
SKEvYoxCmPlH0b8BF043R6DlbZIAAAAASUVORK5CYII=" transform="matrix(1 0 0 1 -36.7427 22.4514)">
|
|
||||||
</image>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 2.1 KiB |
|
@ -1,39 +1,3 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<svg enable-background="new 0 0 100 43" version="1.0" viewBox="0 0 100 43" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<path d="m45 15c-3.9-1.6 5.3-3.7-0.33-3.6-4.5-0.48-9-1.7-14-1.7-4.2-0.72-8.5-1.2-13-2.2-5.1-0.71-10-1.7-15-2.6-3.6 0.87-4.5-5.3-0.59-4.3 3.4-0.26 6.8 0.75 10 1.3 2.9 0.34 6.6 1.1 9.8 1.6 5.6 0.97 11 2.2 17 3.1 3 0.53 6.5 1.1 9.7 2 2 0.77 6 0.35 5.6-2.5 0.3-1.2 4-1.7 0.64-1.3-0.87-1.4-4.7 0.48-4.8-0.98 3.5 0.03 5.5-1.2 8.9-1.4 2.4-1.7 6.3 1 3 3 0.79 0.58 2.9-0.18 4.1-0.12 2-0.75 6.4 0.57 9.4 0.33 2.4-1.4 4.6 0.64 7.6 0.21 2.8 0.09 5.7 0.28 8.5 0.24 2.1 2-0.53 6.6-0.19 6.6 2.6 1 8.4-1.4 8 3.1-0.33 2.8-1.2 5-2 7.8-1.8 3.3-2.6 8-7 8.5-8.1 3.5-16 7-24 10-3.2-0.19-6.9-0.27-9.7-2.2-1.9-1.1-3.6-2.9-6-2.6-0.42 3.4-4.3 0.65-6.5 0.68-3.7-0.81-7.5-0.85-11-0.88-3.2-0.34-6.1-1.5-8.7-3.3-3-1.1-4.5-3.8-7.4-4.3 0.2-3.5 1.6-7 5.1-8.3 4-1.7 8.2-3 12-4.4 3.6-0.53 7-1.6 10-2.3z"/>
|
||||||
<svg version="1.0" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 100 43" style="enable-background:new 0 0 100 43;" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<path d="M45.1,14.9c-0.2-0.2-0.5-0.3-0.7-0.4c-0.5-0.4-0.5-0.7-0.1-1.2c0.6-0.6,1.3-0.9,2-1.3c0.2-0.1,0.4-0.2,0.6-0.3
|
|
||||||
c-0.4-0.3-0.9-0.2-1.3-0.3c-2.2-0.4-4.4-0.7-6.7-1c-2.1-0.3-4.1-0.6-6.2-0.9c-0.1,0-0.3-0.1-0.4,0c-0.7,0.3-1.4,0-2-0.1
|
|
||||||
c-1.7-0.2-3.4-0.5-5-0.7c-1.1-0.2-2.2-0.4-3.3-0.5c-0.6-0.1-1.1-0.3-1.7-0.5c-0.5-0.2-1.1-0.2-1.7-0.3c-1.1-0.2-2.2-0.3-3.2-0.5
|
|
||||||
c-1.4-0.2-2.7-0.4-4.1-0.6C10.5,6,9.7,5.9,8.9,5.8C8.1,5.6,7.2,5.5,6.3,5.3C5.5,5.2,4.8,5.1,4,5C3.8,5,3.6,4.9,3.5,4.8
|
|
||||||
C3,4.4,2.3,4.5,1.7,4.4C0.8,4.2,0.4,3.9,0.3,3.1c-0.2-0.8,0-1.5,0.5-2.2c0.5-0.6,1.1-0.6,1.7-0.5C3,0.6,3.7,0.8,4.2,0.6
|
|
||||||
c0.7-0.3,1.4-0.1,2.1,0c1.7,0.3,3.3,0.6,5,0.9c0.4,0.1,0.8,0.2,1.2,0.2c0.3,0,0.6,0,0.7,0.3c0.1,0.2,0.4,0.2,0.5,0.1
|
|
||||||
c0.3-0.3,0.7-0.1,1.1-0.1c1.9,0.3,3.9,0.7,5.8,1.1c1.2,0.2,2.5,0.4,3.7,0.6C25.2,3.9,26,4,26.8,4.2c1.8,0.3,3.5,0.6,5.3,1
|
|
||||||
c2.5,0.5,4.9,0.9,7.4,1.3c0.2,0,0.4,0.1,0.6,0.3C40.2,7,40.5,7,40.7,6.9c0.6-0.3,1.1,0,1.7,0.1C44,7.3,45.7,7.6,47.4,8
|
|
||||||
c0.4,0.1,0.7,0.4,1.1,0.4c1.3,0.1,2.5,0.6,3.9,0.5c0.3,0,0.5-0.1,0.7-0.3c0.2-0.2,0.6-0.3,0.9-0.4c0.1,0,0.2,0,0.2-0.1
|
|
||||||
c0.9-0.4,0.9-0.4,0.9-1.4c0-0.3,0-0.6,0-1c0-0.3,0.1-0.5,0.5-0.5c0.4,0,0.8,0.1,1.1-0.3c0.1-0.1,0.3-0.1,0.5-0.1
|
|
||||||
c0.1,0,0.1,0,0.2-0.1c0-0.1,0-0.1-0.1-0.2c-0.3-0.2-0.5-0.2-0.7,0.1c-0.1,0.1-0.2,0.1-0.4,0.2c-0.3,0-0.6-0.1-1,0
|
|
||||||
c-0.1,0-0.2-0.1-0.2-0.2c0-0.5-0.4-0.5-0.7-0.5c-0.7,0-1.5,0.1-2.2,0.2c-0.3,0.1-0.6,0.1-0.9,0.1c-0.2,0-0.5-0.1-0.4-0.3
|
|
||||||
c0-0.3,0.3-0.4,0.5-0.4c1.2,0,2.3-0.1,3.4-0.2c0.1,0,0.3,0,0.3-0.2C54.8,3,55,3,55.2,3c0.4,0,0.9,0,1.3,0.1c0.2,0,0.4,0,0.5-0.2
|
|
||||||
c0.3-0.5,0.8-0.4,1.3-0.4c0.5-0.1,1.1-0.1,1.6-0.1c0.3,0,0.6-0.1,0.8-0.3c0.2-0.1,0.4-0.2,0.6-0.1c0.7,0.1,1.4,0,2.1,0.2
|
|
||||||
C63.8,2.2,64,2.3,64,2.7c0,0.3,0.2,0.4,0.2,0.7c0.1,0.7-0.4,1.1-0.8,1.5c-0.1,0.1-0.1,0.1-0.1,0.2c0,0.2-0.1,0.3-0.3,0.3
|
|
||||||
c-0.1,0-0.2,0-0.2,0.2c0,0.1,0.1,0.1,0.2,0.1c0.3,0,0.7-0.1,1-0.1c1-0.1,2-0.2,3-0.3c0.2,0,0.3-0.1,0.3-0.3c0-0.2,0.1-0.3,0.3-0.3
|
|
||||||
C67.8,4.7,68,4.8,68,5c0,0.3,0.2,0.3,0.4,0.3c1.1-0.1,2.2,0,3.3,0.1c0.8,0,1.5,0,2.3,0.1c1.1,0,2.1,0.2,3.2,0.1
|
|
||||||
c0.2,0,0.4,0,0.4-0.3c0-0.2,0.2-0.2,0.4-0.3c0.7-0.4,1.6-0.2,2,0.5c0.1,0.2,0.3,0.2,0.5,0.2c0.9,0,1.7,0.1,2.6,0.1
|
|
||||||
c2.6,0.1,5.2,0.2,7.8,0.3C91.2,6,91.7,6,92.1,6c0.3,0,0.4,0.1,0.5,0.3c0.5,1.7,1,3.4,0.1,5.1c0,0,0,0.1,0,0.1c-0.1,0.6-0.3,1-1,1
|
|
||||||
c0,0-0.1,0-0.2,0.1c0.5,0,1,0.1,1.4,0.1c1.8,0.2,3.5,0.3,5.3,0.4c0.3,0,0.6,0,0.9,0c0.4,0,0.6,0.2,0.8,0.6c0.5,0.9,0.4,1.8,0.2,2.8
|
|
||||||
c0,0.1,0,0.3,0,0.4c0,0.2-0.1,0.4-0.2,0.4c-0.3,0-0.3,0.2-0.3,0.5c0.1,0.5,0.1,0.9,0.2,1.4c0,0.5-0.1,1-0.5,1.3
|
|
||||||
c-0.5,0.4-0.7,1-0.8,1.6c0,1.4-0.7,2.6-1.3,3.7c-0.7,1.3-1.4,2.7-2,4.1c-0.3,0.5-0.7,0.9-1.2,1.1c-0.9,0.4-1.8,0.8-2.8,1.1
|
|
||||||
c-1.1,0.4-2.1,1-3.2,1.4c-1.2,0.5-2.4,1-3.6,1.5c-1.4,0.6-2.8,1.2-4.2,1.8c-0.8,0.3-1.5,0.7-2.3,1c-1.8,0.8-3.6,1.5-5.5,2.3
|
|
||||||
c-1.7,0.7-3.3,1.5-5,2.2c-0.9,0.4-1.7,0.5-2.7,0.2c-0.8-0.2-1.6-0.2-2.3-0.4c-0.9-0.2-1.8-0.3-2.6-0.4c-0.8-0.1-1.4-0.5-2-0.9
|
|
||||||
c-1.4-0.9-2.8-1.8-4.2-2.7c-0.2-0.2-0.5-0.2-0.8-0.2c-0.5,0-1-0.1-1.5-0.2c-0.2,0-0.3,0-0.4,0.2c-0.1,0.4-0.2,0.8-0.3,1.2
|
|
||||||
c-0.1,0.4-0.3,0.5-0.7,0.4c-0.7-0.2-1.5-0.2-2.2-0.4c-0.7-0.2-1.5-0.4-2.2-0.6c-0.6-0.1-1.2-0.1-1.8-0.2c-0.8-0.1-1.6-0.3-2.4-0.4
|
|
||||||
c-0.7-0.1-1.5-0.2-2.2-0.3c-0.6,0-1.1-0.2-1.6-0.2c-0.3,0-0.6,0.1-0.9,0.2c-0.9,0.2-1.7,0.2-2.6,0c-0.8-0.1-1.6-0.2-2.4-0.4
|
|
||||||
c-1.3-0.2-2.5-0.5-3.6-1.2C28,36.1,28,36,27.9,36c-1.3-0.2-2-1.3-3.2-1.8c-1-0.4-1.9-1.1-2.9-1.5c-0.6-0.3-1-0.8-1.2-1.4
|
|
||||||
c-0.1-0.4-0.4-0.6-0.9-0.6c-0.7-0.1-1.4-0.3-2.1-0.4c-0.2-0.1-0.3-0.2-0.3-0.4c0.1-0.7,0.2-1.5,0.4-2.2c0.1-0.4,0.2-0.8,0.2-1.2
|
|
||||||
c0-0.6,0.4-1.1,0.7-1.6c0.1-0.1,0.2-0.2,0.2-0.4c0.3-0.7,0.9-1.2,1.5-1.6c0.9-0.6,1.8-1.2,2.8-1.7c0.7-0.3,1.4-0.5,2.1-0.8
|
|
||||||
c1.4-0.5,2.8-0.9,4.2-1.4c1.2-0.5,2.4-0.9,3.6-1.3c1.1-0.4,2.2-0.7,3.3-0.9c1.6-0.3,3.2-0.6,4.9-0.8c0.2,0,0.4-0.2,0.6-0.3
|
|
||||||
c0.4-0.4,0.8-0.6,1.4-0.6C43.9,15,44.5,14.9,45.1,14.9z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 911 B |
|
@ -1,51 +1,3 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<svg enable-background="new 0 0 100 79" version="1.0" viewBox="0 0 100 79" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<path d="m100 64c0.053-3.8-0.045-7.8 0.012-12-3-2 0.34-7.4-3.9-7.5-2-1.8-0.78-5-1.1-7.4-0.18-2.1 0.36-4.3-0.3-6.3-3.1-2.7-7.3-2-11-2.9 2.2-0.62-0.63-3.8-2.5-1.5-2.2 1.6-7.2-1.4-10-1.3-1.9 0.45-3.5-1.7-3.8-1.6 1.9-2 6.4 0.24 6.5-4 0.72-2.7-1.1-6.6-4.6-5.7-3.1-1.7-8-0.42-10-1.7-0.067-4.4 0.13-8.9-0.1-13-0.23 4.6-0.034 9.2-0.1 14-1.4 2.1-6.7-1.7-6 1.3 2.2 0.61 4.5-0.2 2.6 2.4 0.79 2.7 3.7 3.7 3.1 6.6 0.67 2.6-2.9 0.96-4.2 2.7-2.3 0.2-4.6 0.12-6.6 0.78-1.9-0.021-6.1 1.9-5.9-0.76-1.2-2.2-4.4-0.72-3.3 1.1-1.4 0.24 1.1 3.1-1.6 4-1.5 1.9-2.9 3.8-3.8 0.86-1.5 0.92 0.17 5.3-2.9 2.7-3-0.82 0.15 3.9-3.2 2.7-5.6-0.037-11 1.2-16 3.1-3 1.8-9.3 1.4-9.6 5.6 1.5 2.6-1.6 7.1 2 7.8 3.3-0.55 3.5 2.1 0.11 1.2-3.1-0.88-3.8 1.6-2.9 4.3 3.9-8.5e-4 6.6 1.7 4.2 5.6 2 3.3 3.2 9.5 8.8 9.9 4.9 1.4 11-0.21 13-5.2 1.4-2.1 5.4-0.56 7.9-0.93 4.4 0.26 2.5 7.1 6.6 8.7 3 2.2 7 2 11 1.6 3.8-0.56 6-4.6 7-8-0.065-3.6 2.8-1.5 5.1-1.8 3.3 0.64 5.4-2.6 6.5-5.2 3.8-0.52 7.9-0.34 12 0.23 3.7 0.11 1.9 7.2 6.5 7.2 4.8 1.5 9.2-1.3 9.7-6.3 1-0.39 3.2 0.9 2.4-1.3zm-61-30c1.9-1.6 5.8-1.5 2-0.025-0.67 0.081-1.3 0.014-2 0.025zm3.8-2c-1.9 0.79-6 2.3-2.3-0.5 0.32-0.54 3.6-0.35 2.3 0.5zm10 1.5c-1.5 0.22-0.68-1.7 0 0zm1.2-0.7c0.47 1.9-3.5-1 0 0z"/>
|
||||||
<svg version="1.0" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 100 79" style="enable-background:new 0 0 100 79;" xml:space="preserve">
|
|
||||||
<path d="M99.9,64.5c0-0.1,0.1-0.2,0.1-0.2c0-1.2-0.1-2.3-0.1-3.5c0-2.4,0-4.9,0-7.3c0-0.1,0-0.2,0-0.3c0.2-0.3-0.1-0.5-0.2-0.7
|
|
||||||
c-0.3-0.4-1.1-0.5-0.9-1.3c0-0.1-0.1-0.2-0.1-0.4c-0.1-0.6-0.3-1.3-0.4-1.9c0-0.7,0-1.4,0.1-2c0-0.3,0.1-0.7-0.1-0.8
|
|
||||||
c-0.2-0.2-0.5-0.1-0.8-0.1c-0.3,0-0.5,0.1-0.7,0.1c-0.5-0.5-1.1-1-1.6-1.5c-0.1-0.1-0.2-0.3-0.2-0.4c0-1.1-0.1-2.1-0.1-3.2
|
|
||||||
c0-2.2,0-4.4,0-6.5c0-0.7,0-1.4,0-2.1c0-0.3-0.1-0.6-0.3-0.8c-0.7-0.5-1.4-0.8-2.1-1.2c-0.9-0.6-1.9-0.9-3-0.9
|
|
||||||
c-0.5,0-1.1-0.1-1.7-0.1c-1-0.1-2-0.3-3-0.4c-0.5-0.1-1-0.2-1.5-0.3c0.2-0.1,0.4-0.1,0.5-0.1c0.4,0,0.5-0.2,0.5-0.5c0-0.3,0-0.7,0-1
|
|
||||||
c0-0.4-0.2-0.5-0.5-0.5c-0.5,0-1,0-1.5,0.1C81.4,26.6,81,27,81,27.8c0,0.1,0,0.1,0,0.2c-0.2,0-0.4-0.1-0.6-0.1
|
|
||||||
c-0.3-0.1-0.6-0.3-1-0.3c-1.3-0.2-2.6-0.3-3.8-0.5c-0.5-0.1-1-0.1-1.4-0.3c-0.4-0.1-0.8-0.3-1.2-0.4c-0.2-0.1-0.5-0.1-0.5-0.4
|
|
||||||
c0,0-0.2-0.2-0.4-0.1c-0.4,0-0.9,0.1-1.3,0.1c-0.8-0.1-1.7-0.2-2.5-0.3c0-0.4-0.1-0.7-0.1-1c-0.6-0.1-1-0.2-1.5-0.2c0,0,0-0.1,0-0.1
|
|
||||||
c0.5,0.1,0.7-0.2,0.8-0.5c0-0.1,0.1-0.2,0.2-0.2c0.2-0.4,0.5-0.5,0.9-0.3c0.2,0.1,0.5,0.1,0.7,0.1c0.9,0,1.7-0.1,2.6-0.2
|
|
||||||
c0.1,0,0.4-0.1,0.5-0.2c0.2-0.2,0.3-0.4,0.5-0.6c-0.1-0.8-0.1-1.5,0.6-2.1c0.4-0.4,0.6-0.9,0.2-1.5c-0.3-0.4-0.4-0.9-0.6-1.3
|
|
||||||
c-0.1-0.2-0.1-0.4-0.2-0.7c0-0.4,0.1-0.9-0.4-1.2c0,0-0.1-0.1-0.1-0.1c0-0.4-0.3-0.4-0.6-0.5c-0.1,0-0.3-0.1-0.4-0.1
|
|
||||||
c-0.7-0.1-1.4-0.5-2.1-0.2c-0.1,0-0.3,0-0.4-0.1c-0.7-0.2-1.3-0.3-2-0.5c-0.3-0.1-0.6-0.3-0.9-0.3c-1-0.2-2-0.5-3-0.4
|
|
||||||
c-1.3,0.1-2.6,0-4,0c-0.1,0-0.2,0-0.4,0V0c0-0.4-0.2-0.5-0.2,0c0,2.5,0,10.6,0,13.1c0,0.1,0,0.2,0,0.3c0,0.1-0.1,0.1-0.2,0.2
|
|
||||||
c-0.6,0.2-1.3,0-1.8,0.5c0,0-0.1,0-0.2,0c-0.5-0.1-1-0.2-1.5-0.3c-0.5-0.1-1.1-0.3-1.6-0.4c-0.5-0.1-0.9,0.2-1,0.7
|
|
||||||
c0,0.3,0.2,0.7,0.6,0.7c0.7,0.1,1.4,0.2,2.1,0.3c0.4,0.1,0.8,0.2,1.4,0.3c-0.2,0.1-0.2,0.1-0.3,0.1c-0.5,0-0.7,0.3-0.8,0.8
|
|
||||||
c-0.1,0.6-0.2,1.1,0.2,1.6c0.4,0.5,0.8,1.1,1.2,1.7c0.3,0.4,0.6,0.7,0.6,1.2c0,0.3,0.2,0.4,0.5,0.5c0.2,0,0.4,0.1,0.5,0.1v3.9
|
|
||||||
c-0.2-0.1-0.5-0.1-0.7-0.2c-0.1,0-0.2,0-0.3-0.1c-0.6-0.1-1,0.3-1.5,0.6c-0.4,0.2-0.7,0.7-1.2,0.8c-1.5,0.1-3,0.2-4.5,0.3
|
|
||||||
c-0.6,0-1.2-0.2-1.7,0.4c0,0-0.1,0-0.2,0c-1.3,0.2-2.6,0.4-3.9,0.6c-1,0.2-2,0.2-2.9-0.1c0.2-0.3,0.3-1.2,0-1.4
|
|
||||||
c-0.6-0.4-1.1-1-1.9-0.8c-0.3,0.1-0.6,0-0.9,0.1c-0.1,0-0.3,0.1-0.3,0.2c-0.1,0.4-0.1,0.8-0.1,1.2c0,0.2,0.2,0.4,0.3,0.7
|
|
||||||
c-0.2,0-0.5,0-0.7,0c-0.1,0-0.3,0.1-0.4,0.2c0,0.1,0,0.3,0.1,0.4c0.2,0.3,0.4,0.5,0.6,0.8c0.1,0.1,0.2,0.2,0.1,0.3
|
|
||||||
c-0.1,0.3-0.2,0.7-0.4,1c-1,1.2-2,2.4-3,3.5c-0.2,0.2-0.4,0.5-0.6,0.7c-0.1-0.3-0.1-0.7-0.6-0.5c0-0.1-0.1-0.1,0-0.2
|
|
||||||
c0.1-0.5-0.4-0.8-0.5-1.2c0,0-0.1-0.1-0.2-0.1c-0.4,0-0.7,0.3-0.7,0.7c0,0.6,0,1.2,0,1.8c0,0.3-0.1,0.6-0.1,1c-0.4,0-0.7,0-1-0.1
|
|
||||||
c-0.4-0.2-0.8-0.5-1.1-0.7c-0.4-0.3-0.7-0.3-1.1-0.1c-0.4,0.2-0.6,0.8-0.5,1.2c0.1,0.5,0.2,1,0.4,1.6c-0.5,0-0.9,0-1.4,0
|
|
||||||
c-1.7,0.1-3.5,0.2-5.2,0.3c-0.9,0.1-1.9,0.1-2.8,0.3c-1.5,0.3-3,0.7-4.5,1.2c-1.1,0.3-2.1,0.6-3.2,1c-1.5,0.5-2.9,1-4.4,1.5
|
|
||||||
c-0.9,0.3-1.9,0.7-2.8,1.1c-0.8,0.3-1.5,0.6-2.3,0.9c-0.9,0.3-1.2,0.7-1.2,1.7c0,1,0.2,2,0.3,3c0.1,0.6,0.2,1.3,0.2,1.9
|
|
||||||
c0,0.4,0.2,0.8-0.2,1.1c-0.3,0.2-0.5,0.5-0.1,0.8c0,0,0,0.1,0,0.2c0.1,0.2,0.2,0.5,0.3,0.7c0.1,0.1,0.3,0.2,0.3,0.4
|
|
||||||
c0,0.4,0.3,0.4,0.6,0.4c0.8,0.1,1.7,0.1,2.5,0.2c0.4,0,0.7,0.1,1.1,0.2c-0.1,0.3-0.2,0.5-0.2,0.7c0,0.3-0.3,0.3-0.5,0.3
|
|
||||||
c-0.5,0-1-0.1-1.4-0.1c-1.1,0-2.2,0-3.3,0c-0.3,0-0.4,0.1-0.5,0.4c0,0.1,0,0.2,0,0.4c0,1.1-0.1,2.1,0,3.2c0,0.2,0.2,0.4,0.3,0.5
|
|
||||||
c0.2,0.1,0.4,0.1,0.6,0.1c1.3,0.2,2.5,0.4,3.7,0.6c0.2,0.3,0.4,0.6,0.6,0.9c0,0.1,0.1,0.1,0.1,0.2c0,0.3-0.1,0.7-0.2,1
|
|
||||||
c-0.2,0.6-0.5,1.3-0.8,1.9c-0.2,0.5,0.1,1,0.6,1c0.3,0,0.4,0.2,0.4,0.5c0.1,0.6,0.1,1.1,0.3,1.7c0.1,0.3,0.2,0.5,0.3,0.8
|
|
||||||
c0.4,1.1,0.6,2.2,1.5,3c0.7,0.7,1.2,1.6,2.1,2.1c1.1,0.7,2.3,1.3,3.6,1.5c1.3,0.2,2.7,0.2,4,0.4c0.4,0,0.9,0.1,1.3,0.1
|
|
||||||
c0.8-0.2,1.7-0.4,2.5-0.7c0.5-0.2,0.9-0.5,1.3-0.8c0.7-0.5,1.5-0.9,2-1.7c0.7-1.1,1.7-2.1,2.1-3.4c0-0.1,0.2-0.2,0.3-0.2
|
|
||||||
c0.6,0,1.1,0.1,1.7,0.1c0.8,0,1.6,0,2.5,0c0.8,0,1.5-0.1,2.3,0c0.9,0.1,1.8,0.3,2.7,0.6c0.2,0,0.4,0.2,0.4,0.4
|
|
||||||
c0,0.8,0.3,1.4,0.5,2.1c0.4,1.2,0.7,2.4,1.5,3.4c0.5,0.5,0.7,1.3,1.3,1.7c1.1,0.8,2.2,1.7,3.7,2c1.1,0.2,2.1,0.5,3.2,0.4
|
|
||||||
c0.2,0,0.5,0,0.8,0c1,0.2,2,0.1,3-0.1c0.4-0.1,0.9-0.1,1.3-0.3c0.5-0.1,1.2-0.1,1.6-0.5c0.5-0.5,1-1,1.6-1.5
|
|
||||||
c0.5-0.4,0.8-0.8,1.1-1.3c0.1-0.2,0.3-0.4,0.4-0.7c0.3-0.6,0.7-1.2,1-1.8c0.3-0.6,0.5-1.3,0.7-2c0.3-0.8,0.5-1.6,0.7-2.4
|
|
||||||
c0.4,0.1,0.8,0.2,1.3,0.3c0.6,0.1,1.2,0.2,1.8,0.3c1,0,1.9,0,2.9,0c0.1,0,0.2,0,0.3,0c1.3-0.4,2.2-1.3,3-2.3c0.4-0.6,0.8-1.3,1.1-2
|
|
||||||
c0.3-0.8,0.6-1.2,1.5-1.1c0.9,0,1.7-0.1,2.6-0.1c1.2,0,2.4,0.1,3.5,0.2c0.7,0,1.4-0.1,2.1-0.1c1.4,0.2,2.8,0.5,4.2,0.7
|
|
||||||
c0.3,0,0.3,0.2,0.3,0.4c0,0.3,0.1,0.7,0.2,1c0.1,0.3,0.2,0.6,0.3,1c0.5,1.6,1.1,3,2.5,3.9c0.3,0.2,0.5,0.5,0.8,0.5
|
|
||||||
c1.1,0.2,2.3,0.3,3.4,0.3c1,0,2-0.1,2.9-0.2c0.7-0.1,1.3-0.3,1.7-0.9c1.2-1.5,2-3.2,2.4-5.1c0.1-0.3,0.2-0.4,0.5-0.4
|
|
||||||
c0.4,0,0.9,0.1,1.3,0.1c0.3,0,0.6,0,0.8-0.1C100,65.1,99.9,64.8,99.9,64.5z M38.7,34.7c1.2-0.5,2.4-1,3.7-1.6c0,0.3,0.1,0.5,0.1,0.8
|
|
||||||
C40.8,34.9,40.7,34.7,38.7,34.7z M42.5,32.7c-0.8,0.3-1.6,0.6-2.4,0.9c-0.4,0.1-0.8,0.3-1.3,0.4c-0.1,0-0.2,0-0.4,0
|
|
||||||
c0.7-0.7,1.2-1.3,1.8-1.8c0.2-0.2,0.4-0.3,0.7-0.3c0.6,0.1,1.2,0.1,1.8,0.2C42.9,32.4,42.8,32.6,42.5,32.7z M52.6,34.2
|
|
||||||
c-0.2,0-0.5,0-0.7,0c-0.1-0.3-0.1-0.6-0.2-0.9c0.3,0.3,0.6,0.5,0.9,0.7C52.6,34.2,52.6,34.2,52.6,34.2z M53.8,33.5
|
|
||||||
c-0.1,0.3-0.1,0.5-0.1,0.7h-0.7c0,0,0,0,0,0c0,0,0,0,0,0c0.1-0.1,0.1-0.1,0.2-0.2l-0.9-0.4c0,0,0,0,0,0c0,0,0,0-0.1,0
|
|
||||||
c0,0,0.1-0.1,0.1-0.1C52.8,33.4,53.3,33.4,53.8,33.5C53.8,33.5,53.8,33.5,53.8,33.5L53.8,33.5z"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 1.3 KiB |